文章目录
- 前言
- 一、MySQL 主从是什么?
- 二、通过 Docker 部署
- 三、配置主从关系
- 四、实际情况分析&解决方案
- 五、常见问题处理
- 1、CLONE需要版本不同
- 2、CLONE需要参数相同
- 总结
前言
MySQL 主从搭建
操作系统:CentOS Linux release 7.9.2009 (Core)
操作系统镜像:CentOS-7-x86_64-Minimal-2009.iso
MySQL 版本:8.0.32
测试方式:Docker
Docker 版本:24.0.2 (Docker Engine - Community)
Docker 相关说明可以参考之前的文章
一、MySQL 主从是什么?
关于 MySQL 主从是什么,请参考这篇文章,感觉大神介绍的非常详尽!手动点赞!!!
二、通过 Docker 部署
# master 主节点
docker run -p 10001:3306 --name mysql_master --restart=always -e MYSQL_ROOT_PASSWORD='master' -d mysql:8.0.32 --server-id=100 --log_bin=master-bin --binlog_format=row --expire_logs_days=7 --max_binlog_size=100M --binlog_cache_size=4m --max_binlog_cache_size=512m
# slave 从节点
docker run -p 10002:3306 --name mysql_slave --restart=always -e MYSQL_ROOT_PASSWORD='slave' -d mysql:8.0.32 --server-id=101 --log_bin=slave-bin --binlog_format=row --expire_logs_days=7 --max_binlog_size=100M --binlog_cache_size=4m --max_binlog_cache_size=512m
说明:
- 仅为示例,生产环境不推荐使用 Docker 环境部署 MySQL。频繁重启容易导致数据异常
- 搭建主从,需要开启 binlog,主从关系是通过 binlog 进行数据同步的
- binlog 会比较大,所以需要设置保存时长,文件大小等相关参数(应根据实际情况进行配置)
三、配置主从关系
1、主节点
# 进入容器
docker exec -it mysql_master bash
# 连接
mysql -uroot -pmaster
-- 创建账户,提供给从节点进行数据同步
CREATE USER 'master_user_sync'@'%' IDENTIFIED WITH mysql_native_password BY 'sync';
FLUSH PRIVILEGES;
GRANT REPLICATION SLAVE ON *.* TO 'master_user_sync'@'%';
GRANT REPLICATION CLIENT ON *.* TO 'master_user_sync'@'%';
GRANT BACKUP_ADMIN ON *.* TO 'master_user_sync'@'%';
FLUSH PRIVILEGES;
2、从节点
# 进入容器
docker exec -it mysql_slave bash
# 连接
mysql -uroot -pslave
-- 设置为只读
mysql> set global read_only=1;
Query OK, 0 rows affected (0.00 sec)-- 设置 Master
change master to master_host='master_ip',master_port=10001,master_user='master_user_sync',master_password='sync',master_log_file='master-bin.000001', -- 开始的文件master_log_pos=0; -- 开始的位置
-- 示例
mysql> change master to master_host='master_ip',-> master_port=10001,-> master_user='master_user_sync',-> master_password='sync',-> master_log_file='master-bin.000003', -- CLONE 到的文件-> master_log_pos=1478; -- CLONE 到的位置
Query OK, 0 rows affected, 9 warnings (0.05 sec)-- 启动 Slave
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.17 sec)-- 查看状态
mysql> show slave status\G
*************************** 1. row ***************************Slave_IO_State: Waiting for source to send eventMaster_Host: master_ipMaster_User: master_user_syncMaster_Port: 10001Connect_Retry: 60Master_Log_File: master-bin.000003Read_Master_Log_Pos: 1478Relay_Log_File: 0e3d59342a9e-relay-bin.000002Relay_Log_Pos: 327Relay_Master_Log_File: master-bin.000003Slave_IO_Running: Yes -- 正常连接Slave_SQL_Running: Yes -- 正常运行Replicate_Do_DB:Replicate_Ignore_DB:Replicate_Do_Table:Replicate_Ignore_Table:Replicate_Wild_Do_Table:Replicate_Wild_Ignore_Table:Last_Errno: 0Last_Error:Skip_Counter: 0Exec_Master_Log_Pos: 1478Relay_Log_Space: 544Until_Condition: NoneUntil_Log_File:Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File:Master_SSL_CA_Path:Master_SSL_Cert:Master_SSL_Cipher:Master_SSL_Key:Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 0Last_IO_Error:Last_SQL_Errno: 0Last_SQL_Error:Replicate_Ignore_Server_Ids:Master_Server_Id: 100Master_UUID: 3f9a8fa7-2694-11ee-bf3c-0242ac110003Master_Info_File: mysql.slave_master_infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Replica has read all relay log; waiting for more updatesMaster_Retry_Count: 86400Master_Bind:Last_IO_Error_Timestamp:Last_SQL_Error_Timestamp:Master_SSL_Crl:Master_SSL_Crlpath:Retrieved_Gtid_Set:Executed_Gtid_Set:Auto_Position: 0Replicate_Rewrite_DB:Channel_Name:Master_TLS_Version:Master_public_key_path:Get_master_public_key: 0Network_Namespace:
1 row in set, 1 warning (0.00 sec)
四、实际情况分析&解决方案
实际情况:生产环境中,可能最开始并未建立主从关系,并且主节点已使用一段时间,已存在历史数据。
问题:binlog 会定期清理,历史数据不全。也可能主节点并未开启 binlog。无法直接建立主从管理。
推荐方案:先不要着急建立主从关系。从节点搭建好,需要先完成数据同步,推荐使用 CLONE 方法。然后再建立主从关系,并启用数据同步(CLONE 会返回位置信息)。
# CLONE 需要先启用插件,Docker 部署可以通过增加参数实现
# --plugin-load-add=mysql_clone.so
-- 通过此 SQL 可以确认是否启用 CLONE 插件
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'clone';
+-------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+-------------+---------------+
| clone | ACTIVE |
+-------------+---------------+
1 row in set (0.00 sec)
-- CLONE 方法
mysql> set global clone_valid_donor_list="master_ip:10001";
mysql> CLONE INSTANCE FROM 'master_user_sync'@'master_ip':10001 IDENTIFIED BY 'sync';
-- CLONE 完成后,容器会自动重启
特别注意
:CLONE 把账号、密码也同步了。因此从节点的 root 密码会变更为主节点的 root 密码。
-- 验证是否 CLONE 成功
mysql> select * from performance_schema.clone_status\G
*************************** 1. row ***************************ID: 1PID: 0STATE: Completed -- Completed 数据同步已完成BEGIN_TIME: 2023-07-20 00:31:12.592END_TIME: 2023-07-20 00:31:20.192SOURCE: master_ip:10001DESTINATION: LOCAL INSTANCEERROR_NO: 0ERROR_MESSAGE:BINLOG_FILE: master-bin.000003 -- 从节点配置参数 master_log_file
BINLOG_POSITION: 1478 -- 从节点配置参数 master_log_posGTID_EXECUTED:
1 row in set (0.01 sec)
五、常见问题处理
1、CLONE需要版本不同
问题:不同版本 CLONE 有异常,相同版本正常(都是 8.0.32 没有问题)。但是,可以正常建立主从关系。
解决方案:统一版本(不用 CLONE ,也建议主从统一版本)
示例:
master 8.0.32
slave 8.0.29
mysql> set global clone_valid_donor_list="master_ip:10001";
mysql> CLONE INSTANCE FROM 'master_user_sync'@'master_ip':10001 IDENTIFIED BY 'sync';
ERROR 3867 (HY000): Clone Donor collation: utf8mb4_nb_0900_ai_ci is unavailable in Recipient.
2、CLONE需要参数相同
问题:因为参数不同,导致 CLONE 之后服务启动报错,导致服务无法启动
解决方案:统一参数
示例:lower_case_table_names 一个节点配置为 0,另一个节点配置为 1
MySQL 启动异常信息如下
[ERROR] *** Different lower_case_table_names settings for server ('0') and data dictionary ('1')
[ERROR] *** Data Dictiongary initialization failed.s
总结
以上即为全部内容。至于测试部分,就不磨叽了,直接在主节点操作,从节点可以直观看出变化。
总体上来说,配置并不算复杂,但是需要思路比较清晰!不过故障处理起来,会稍微麻烦一点,需要注意数据一致性的问题!