准备
- CentOS安装 可以虚拟机安装,目前最新版本CentOS9
- docker安装 yum install docker-ce (或者 dnf install docker-ce CentOS9以后包管理工具使用dnf)
- MySQL镜像拉取 docker pull mysql
1、 MySQL主从复制集群部署
1.1 主节点:
主节点部署
bash
$ sudo docker run -p 3307:3306 \
--name mysql-master \
# 日志目录挂载
-v /opt/mysqlmscluster/master/log:/var/log/mysql \
# 数据文件目录挂载
-v /opt/mysqlmscluster/master/data:/var/lib/mysql \
# 配置目录挂载
-v /opt/mysqlmscluster/master/conf:/etc/mysql/conf.d \
# root密码设置
-e MYSQL_ROOT_PASSWORD=root \
-d mysql
容器启动
bash
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c009495dbc75 mysql "docker-entrypoint.s..." 7 hours ago Up 2 hours 33060/tcp, 0.0.0.0:3307->3306/tcp, [::]:3307->3306/tcp mysql-master
主节点配置文件:
bash
$ vim /opt/mysqlmscluster/master/conf/my.cnf
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-name-resolve
#Server的实例ID,必须全局唯一
server_id=1
# 开启binlog
log-bin=mysql-bin
#是否只读,主节点可以读写
read-only=0
#需要记录binlog的数据库
binlog-do-db=shibing_test
#忽略的数据库
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
重启主节点:
设置好配置文件后重启主节点:
bash
$ sudo docker restart mysql-master
连接到主节点:
bash
$ mysql -h 10.211.55.5 -uroot -proot -P3307
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 9.0.1 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
创建用户backup,只有relication slave权限,用于从节点做主从同步数据
关于下面的两条命令,请查阅官方文档
bash
MySQL [(none)]> create user 'backup'@'%' identified by '123456';
Query OK, 0 rows affected, 2 warnings (0.018 sec)
MySQL [(none)]> grant replication slave on *.* to 'backup'@'%';
Query OK, 0 rows affected, 2 warnings (0.018 sec)
MySQL [(none)]> flush privileges;
查看主节点状态:
这里注意在8.0以前的版本是show master status,后续版本改成了show binary log status;自8.0版本后master 和slave参数都有变化,slave基本上改成了replica。(这里不得不吐槽一下,改了很多很不方便,都是欧美种族歧视问题闹得)
bash
MySQL [(none)]> SHOW BINARY LOG STATUS\G
*************************** 1. row ***************************
File: mysql-bin.000004
Position: 367
Binlog_Do_DB: shibing_test
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.001 sec)
在主节点创建数据库并创建表:
bash
MySQL [shibing_test]> create database shibing_test;
MySQL [shibing_test]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| shibing_test |
| sys |
+--------------------+
5 rows in set (0.002 sec)
MySQL [shibing_test]> CREATE TABLE IF NOT EXISTS `example_table` (
-> `id` INT NOT NULL AUTO_INCREMENT,
-> `name` VARCHAR(255) NOT NULL,
-> `email` VARCHAR(255) NOT NULL,
-> `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-> PRIMARY KEY (`id`)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Query OK, 0 rows affected (0.022 sec)
MySQL [shibing_test]> show tables;
+------------------------+
| Tables_in_shibing_test |
+------------------------+
| example_table |
+------------------------+
1 row in set (0.006 sec)
1.2 从节点:
从节点部署:
bash
$ sudo docker run -d -p 3308:3306 \
--name mysql-replica \
-v /opt/mysqlmscluster/replica/log:/var/log/mysql \
-v /opt/mysqlmscluster/replica/data:/var/lib/mysql \
-v /opt/mysqlmscluster/replica/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=root \
# 关联主节点
--link mysql-master:mysql-master \
mysql
#从节点容器启动
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fd9ecf27cfbc mysql "docker-entrypoint.s..." 6 hours ago Up About an hour 33060/tcp, 0.0.0.0:3308->3306/tcp, [::]:3308->3306/tcp mysql-replica
从节点配置:
bash
$ vim /opt/mysqlmscluster/replica/conf/my.cnf
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-name-resolve
server_id=2
# 这里从节点没有他自己的从节点(A->B->C这样的关系,B是A的从节点,同时是C的主节点),可以不开启binlog
log-bin=mysql-bin
# 从节点设为只读
read-only=1
binlog-do-db=shibing_test
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
重启从节点:
bash
$ sudo docker restart mysql-replica
连接到从节点
bash
$ mysql -h 10.211.55.5 -uroot -proot -P 3308
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 9.0.1 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
从节点复制主节点信息配置:
bash
MySQL [(none)]> change replication source to source_host='mysql-master',
source_user='backup',
source_password='123456',
source_log_file='mysql-bin.000001',
source_log_pos=0,
source_port=3306,
get_source_public_key=1;
# 重启复制进程, mysql8以前的版本replica换成slave
MySQL [(none)]> stop replica;
MySQL [(none)]> start replica;
- 从MySQL9.0以后,change replication source to命令为从节点设置主节点复制信息的命令(MySQL9.0以前是change master to)
From MySQL 8.0.23, use CHANGE REPLICATION SOURCE TO in place of CHANGE
MASTER TO, which is deprecated from that release. In releases before
MySQL 8.0.23
来自参考文档(2)
- source_host: 主节点名称,这里直接用容器名称即可
- source_user,source_password:主节点创建的用户名密码,用户从节点复制日志使用,授予replication slave权限
- source_log_file:开始同步的binlog文件(初始从000001号文件开始)
- source_log_pos:开始同步的文件位置(初始从0开始)
- source_port:主机端口,我们是直接连接容器,使用容器开放的端口
- get_source_public_key: 获取master的公钥。mysql8 以后加密默认使用 caching_sha2_password 插件,需要添加 get_master_public_key=1 选项,8以下版本或者指定加密插件为 mysql_native_password 不需要加
In MySQL 9.0, caching_sha2_password is the default authentication
plugin; mysql_native_password is no longer available.
On the server side, two system variables name the RSA private and
public key-pair files: caching_sha2_password_private_key_path and
caching_sha2_password_public_key_path. The database administrator must
set these variables at server startup if the key files to use have
names that differ from the system variable default values.
For replicas, use the CHANGE REPLICATION SOURCE TO statement with the SOURCE_PUBLIC_KEY_PATH option to specify the RSA public key file,
or the GET_SOURCE_PUBLIC_KEY option to request the public key from the
source. For Group Replication, the
group_replication_recovery_public_key_path and
group_replication_recovery_get_public_key system variables serve the
same purpose.
来自参考文档(3)
查看从节点状态:
bash
MySQL [performance_schema]> show replica status\G
*************************** 1. row ***************************
Replica_IO_State: Waiting for source to send event
Source_Host: mysql-master
Source_User: backup
Source_Port: 3306
Connect_Retry: 60
Source_Log_File: mysql-bin.000006
Read_Source_Log_Pos: 768
Relay_Log_File: fd9ecf27cfbc-relay-bin.000007
Relay_Log_Pos: 985
Relay_Source_Log_File: mysql-bin.000006
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql,sys,information_schema,performance_schema
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Source_Log_Pos: 768
Relay_Log_Space: 1420
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Source_SSL_Allowed: No
Source_SSL_CA_File:
Source_SSL_CA_Path:
Source_SSL_Cert:
Source_SSL_Cipher:
Source_SSL_Key:
Seconds_Behind_Source: 0
Source_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Source_Server_Id: 1
Source_UUID: 62573dca-88ce-11ef-a9fd-0242ac110005
Source_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Replica_SQL_Running_State: Replica has read all relay log; waiting for more updates
Source_Retry_Count: 10
Source_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Source_SSL_Crl:
Source_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Source_TLS_Version:
Source_public_key_path: public_key.pem
Get_Source_public_key: 1
Network_Namespace:
1 row in set (0.003 sec)
只要Replica_IO_Running 和 Replica_SQL_Running 都是 yes ,则主从同步就是正常的,只要有一个不是yes则主从同步失败。
错误处理
如果失败可以查看Last_Error、Last_IO_Error、Last_SQL_Error中的错误信息,
该错误信息表示连接主节点错误
Last_IO_Error: Error connecting to source 'backup@mysql-master:3306'.
This was attempt 1/10, with a delay of 60 seconds between attempts.
Message: Access denied for user 'backup'@'172.17.0.6' (using password:
YES)
下面的错误信息表示sql执行错误 Last_SQL_Error: Coordinator stopped because there
were error(s) in the worker(s). The most recent failure being: Worker
1 failed executing transaction 'ANONYMOUS' at source log
mysql-bin.000006, end_log_pos 768. See error log and/or
performance_schema.replication_applier_status_by_worker table for more
details about this failure or others, if any.
详细错误信息可以查看容器日志:
sudo docker logs --tail 50 --follow --timestamps {这里是容器名称}
1.3 验证集群可用性
查看从节点是否已同步主节点的表:
如下从节点已经同步我们在主节点创建的库shibing_test和表example_table
bash
MySQL [performance_schema]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| shibing_test |
| sys |
+--------------------+
5 rows in set (0.006 sec)
MySQL [performance_schema]> use shibing_test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MySQL [shibing_test]> show tables;
+------------------------+
| Tables_in_shibing_test |
+------------------------+
| example_table |
+------------------------+
1 row in set (0.009 sec)
总结
我这里使用的是MySQL最新镜像,MySQL版本9.0.1,该版本很新,很多操作命令和配置参数都有变化,搭建集群的过程中碰到很多问题。解决问题过程查阅了很多官方文档,下面是列出了我参考的官方文档。
参考
1 https://dev.mysql.com/doc/refman/8.4/en/added-deprecated-removed.html
2 CHANGE REPLICATION SOURCE TO Statement