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
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一下即可。