您的位置:首页 > 运维架构 > Linux

MySQL InnoDB Cluster搭建高可用数据库集群(centos7.x)

2017-10-31 10:57 1461 查看
MySQL官方在4月终于推出了一套完整的、高可用的Mysql解决方案--MySQL InnoDB Cluster。这绝对是程序员的福音。以往做mysql主从高可用非常繁琐,很多坑。现在利用官方的解决方案--MySQL
InnoDB Cluster可以比较方便的搭建mysql高可用集群,虽然也挺多坑的。

至于--MySQL InnoDB Cluster有什么优点缺点,这里不比较了,可以到官网直接看就好。

最近刚好项目需要搭建数据库高可用,于是便尝试使用官方推荐的方案--MySQL InnoDB
Cluster。

因为这个是新推出的,网上这方面的资料比较少,官方的文档也介绍太简单,我在搭建过程中也遇到很多问题。

最后还是成功搭建,这里把搭建过程给大家分享一下,希望对需要的朋友有所帮助。

开始:

1、准备需要的环境

我使用的系统版本:centos7.x

首先下载搭建需要的软件:

mysql 下载地址:
https://dev.mysql.com/downloads/mysql/


mysql-shell 下载地址:
https://dev.mysql.com/downloads/shell/


mysql-router 下载地址:
https://dev.mysql.com/downloads/router/


都选择 Linux Generic 版本即可
准备3台服务器,node01、node02、node03 

node01作为 cluster 节点,负责创建 cluster,并作为 cluster
的路由

2、环境配置

在各台服务器中配置好 hosts,这一步很重要,否则可能会出现无法同步的情况,因为数据库需要根据member_host同步,如果不配置,默认就是localhost,这样时无法通信的。

# vim /etc/hosts


如:

172.30.12.20 node03
172.30.12.17 node02
172.30.12.14 node01


让hosts文件生效

# source /etc/hosts


然后重启服务器:

# reboot -f


通过命令 hostnamectl  查看瞬态主机名称是否是设置的名称

Static hostname: localhost.localdomain
Transient hostname: node01  #这个就是瞬态主机名称,mysql会根据这个来设置host
Icon name: computer-desktop
Chassis: desktop
Machine ID: 9ac67df3c56f4ff18f0a7855490589bc
Boot ID: f6f4356539884b8ba2ee79774b918359
Operating System: CentOS Linux 7 (Core)
CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-514.el7.x86_64
Architecture: x86-64


如果你不想重启服务器,也可以通过下面的命令动态设置:

hostnamectl --transient set-hostname node01


(1)安装基础软件

node 01、02、03 上安装好 
mysql
 与 
mysql-shell


node01 上安装 
mysql-router

mysql怎么安装这里不介绍了,请移步另外一篇博文:http://blog.csdn.net/kokjuis/article/details/78215020

2. shell

# 直接解压即可
tar zxf mysql-shell-1.0.9-linux-glibc2.12-x86-64bit.tar.gz mysql-shell


3. router

# 直接解压即可
tar zxf mysql-router-2.1.3-linux-glibc2.12-x86-64bit.tar.gz mysql-router


在node01的mysql配置文件加入高可用和集群配置(根据自己的情况设置目录):

[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
socket=/usr/mysql/mysql/lib/mysql.sock

[mysqld]
#skip-name-resolve
#设置3306端口
port = 3306
socket=/usr/mysql/mysql/lib/mysql.sock
# 设置mysql的安装目录
basedir=/usr/mysql/mysql
# 设置mysql数据库的数据的存放目录
datadir=/usr/mysql/mysql/data
# 允许最大连接数
max_connections=200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB

max_allowed_packet=16M

#高可用
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
log_bin=binlog
binlog_format=ROW

transaction_write_set_extraction=XXHASH64

#主从复制配置
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
#注意:这里的地址不能用 node01:24901 这种写法,要用IP,否则无法通信
loose-group_replication_local_address= "172.30.12.14:24901"
loose-group_replication_group_seeds= "172.30.12.14:24901,172.30.12.17:24901,172.30.12.20:24901"
loose-group_replication_single_primary_mode=TRUE

#loose-group_replication_bootstrap_group= off
#loose-group_replication_enforce_update_everywhere_checks= FALSE
#loose-group_replication_start_on_boot=off

disabled_storage_engines = MyISAM,BLACKHOLE,FEDERATED,CSV,ARCHIVE
report_port = 3306


然后重启mysql。

进到 mysql-shell 的安装目录,登录 shell ,执行配置
bin/mysqlsh


连接到本机MySQL,执行配置命令
# 连接,需要输入密码(123456)
mysql-js> shell.connect('root@localhost:3306');

# 执行配置命令,也需要密码
mysql-js> dba.configureLocalInstance();
Please provide the password for 'root@localhost:3306':

Detecting the configuration file...
Default file not found at the standard locations.
Please specify the path to the MySQL configuration file: /etc/my.cnf
MySQL user 'root' cannot be verified to have access to other hosts in the network.
Detecting the configuration file...
Found configuration file at standard location: /etc/my.cnf
Do you want to modify this file? [Y|n]:  [Y|n]: y
Validating instance...

The instance 'localhost:3306' is valid for Cluster usage
You can now use it in an InnoDB Cluster.

{
   "status": "ok"
}


status
 为 
ok
 说明配置没问题了,可以用来创建cluster

通过 mysql-shell 连接 node01 创建 cluster

登录 shell,连接 node01,创建 cluster

bin/mysqlsh

# 连接01
mysql-js> shell.connect('root@node01:3306');

# 创建一个 cluster,命名为 'myCluster'
mysql-js> var cluster = dba.createCluster('myCluster');

# 创建成功后,查看cluster状态
mysql-js> cluster.status();


{
"clusterName": "myCluster",
"defaultReplicaSet": {
"name": "default",
"primary": "node01:3306",
"status": "OK_NO_TOLERANCE",
"statusText": "Cluster is NOT tolerant to any failures. 1 member is not active",
"topology": {
"node01:3306": {
"address": "node01:3306",
"mode": "R/W",
"readReplicas": {},
"role": "HA",
"status": "ONLINE"
}
}
}
}


(3)添加实例节点 node02

配置 node02 的 mysql 并启动

编辑配置文件 
my.cnf
,内容与
node01 上的一样,只有2行不同
server_id=2

改成本机的IP:loose-group_replication_local_address= "172.30.12.17:24901"


通过本机 mysql-shell 对 mysql 进行配置

登录 shell ,执行配置
bin/mysqlsh

mysql-js> shell.connect('root@localhost:3306');
mysql-js> dba.configureLocalInstance();


停掉 mysql,修改 my.cnf,添加配置项

# 在末尾添加
group_replication_allow_local_disjoint_gtids_join=ON


重启MySQL

通过 node01 的 mysql-shell 添加 node02 到 cluster

# 添加实例
cluster.addInstance('root@node02:3306');

# 创建成功后,查看cluster状态
mysql-js> cluster.status();


(4)添加实例节点 node03

过程与 node02 完全相同,只需要注意 my.cnf 中的 'server_id' 值改为 3,
也是改成node03的ip:loose-group_replication_local_address= "172.30.12.20:24901"


重启MySQL

通过 node01 的 mysql-shell 添加 node03 到 cluster

# 添加实例
cluster.addInstance('root@node03:3306');

# 创建成功后,查看cluster状态
mysql-js> cluster.status();



(5)安装 router

进入 node01 中 mysql-router 安装目录执行命令

./bin/mysqlrouter --bootstrap root@node01:3306 -d myrouter --user=root


这里会在mysql-router 目录生成router配置文件,我们把配置文件修改一下:

# File automatically generated during MySQL Router bootstrap
[DEFAULT]
user=root
logging_folder=/usr/mysql/mysql-router/myrouter/log
runtime_folder=/usr/mysql/mysql-router/myrouter/run
data_folder=/usr/mysql/mysql-router/myrouter/data
keyring_path=/usr/mysql/mysql-router/myrouter/data/keyring
master_key_path=/usr/mysql/mysql-router/myrouter/mysqlrouter.key

[logger]
level = INFO

[routing:read_write]
#指定mysql router绑定的服务器
bind_address = 172.30.12.14
#指定绑定的端口
bind_port = 7001
#读写模式(read-write, read_only)
mode = read-write
#指定mysql server 列表 (ip:port 格式,使用逗号分隔)
destinations = 172.30.12.14:3306
#最大连接数
max_connections = 1000
#最大错误连接数
#max_connect_errors = 100
#连接超时时间
connect_timeout = 9

[routing:read_only]
bind_address = 172.30.12.14
bind_port = 7002
mode = read-only
destinations = 172.30.12.17:3306,172.30.12.20:3306
max_connections = 1000
#max_connect_errors = 100
connect_timeout = 9


然后启动

mysqlrouter --config /usr/mysql/mysql-router/myrouter/mysqlrouter.conf &


然后把mysql连接端口改成7001(配置文件中配置的读写端口)即可。

可能遇到的问题:

一般可以这样解决,停止集群:

在数据库上执行:

STOP GROUP_REPLICATION;

RESET MASTER;

RESET SLAVE;

登录 shell ,执行
bin/mysqlsh

mysql-js> shell.connect('root@localhost:3306');
mysql-js> dba.rebootClusterFromCompleteOutage('myCluster');#上面配置的名称

一般就会恢复,然后重新

cluster.addInstance('root@node02:3306');
cluster.addInstance('root@node03:3306');


在数据库中查看:

SELECT * FROM performance_schema.replication_group_members;




这样就表示集群成功了。

如果你的主从不同步,一般可以这样解决:

从master中导出数据库,到slave中导入数据。

在master通过命令:SHOW MASTER STATUS; 

记下 file 和 position

在slave中执行:

CHANGE MASTER TO MASTER_HOST = '172.30.12.14',MASTER_PORT = 3306,MASTER_USER = 'root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='master-bin.000001',MASTER_LOG_POS=1172;


然后从新enjoin一下即可。

添加一个新的从机,可以有两种方式:从 master 机器复制; 另一种是直接从 slave 复制.

复制主库要步骤:

====================

1.将内存中的数据同步到表中.

2.锁定表,不让出现脏数据

3.备份

4.解锁

5.在另一台机器上同步数据,并且设置 master_log_file 和 master-log_pos

命令:

a.同步数据,并锁表: mysql> flush tables with read lock;

b.记住当前 binlog 的偏移值,后面设置 slave 上的值. show master status; 记下 file 和 position

c.备份:.参照 http://blog.sina.com.cn/s/blog_5f54f0be0100vp6m.html

命令: [root@li387-161 ~] mysqldump --all-databases --host=master-1 > backup.sql

d.解锁 mysql> unlock tables;

e.同步从机.将 backup.sql 复制到从机上.[root@li387-161 ~] mysql --host=slave-1 < backup.sql

设置从机: 

mysql>change master to master_host = '192.168.3.119',master_port = 3306,master_user = 'repl_user',master_password='root',master_log_file='master-bin.000005',master_log_pos=194244;

这里的 master_log_file 和 master_log_pos 就是前面第 2 步中记下来的两个值.

开启从机

start slave;

复制从库要步骤:

====================

可以看到,从主库复制会有段时间锁表,这段时间会影响主库的使用。如果我们能直接从从库进行复制,就不会对主库产生影响了。但是,从从库复制要保证的是复制过程中从库上的数据不会发生变化,所以要先停掉从库。

1.停止从库: mysql> stop slave;

2.看当前从库的状态。和前面的看主库状态一样。但现在是从从库复制,所以查看从库状态:mysql> show slave status;

记下 Relay_Master_Log_file 和 Exec_Master_Log_Pos, 用处和前面一样.

3.备份从库数据.用 mysqldump

4.在新的从库上还原数据

5.设置新从库的 slave 参数.change master to master_host = '192.168.3.119',master_port = 3306,master_user = 'repl_user',master_password='root',master_log_file='master-bin.000005',master_log_pos=194244;

可以看到,虽然新从库是从从库复制的数据,但实际上 binlog 的 master 还是指向的主库。

另外,这里将 master_log_file 和 master_log_pos 设置成第 2 步中的 Relay_Master_Log_file 和 Exec_Master_Log_Pos

start slave;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: