文章目录
- 前言
- [一、MySQL 主从是什么?](#一、MySQL 主从是什么?)
- [二、通过 Docker 部署](#二、通过 Docker 部署)
- 三、配置主从关系
- 四、实际情况分析&解决方案
- 五、常见问题处理
- 总结
前言
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 部署
shell
# 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、主节点
shell
# 进入容器
docker exec -it mysql_master bash
# 连接
mysql -uroot -pmaster
sql
-- 创建账户,提供给从节点进行数据同步
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、从节点
shell
# 进入容器
docker exec -it mysql_slave bash
# 连接
mysql -uroot -pslave
sql
-- 设置为只读
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 event
Master_Host: master_ip
Master_User: master_user_sync
Master_Port: 10001
Connect_Retry: 60
Master_Log_File: master-bin.000003
Read_Master_Log_Pos: 1478
Relay_Log_File: 0e3d59342a9e-relay-bin.000002
Relay_Log_Pos: 327
Relay_Master_Log_File: master-bin.000003
Slave_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: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1478
Relay_Log_Space: 544
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_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: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 100
Master_UUID: 3f9a8fa7-2694-11ee-bf3c-0242ac110003
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
四、实际情况分析&解决方案
实际情况:生产环境中,可能最开始并未建立主从关系,并且主节点已使用一段时间,已存在历史数据。
问题:binlog 会定期清理,历史数据不全。也可能主节点并未开启 binlog。无法直接建立主从管理。
推荐方案:先不要着急建立主从关系。从节点搭建好,需要先完成数据同步,推荐使用 CLONE 方法。然后再建立主从关系,并启用数据同步(CLONE 会返回位置信息)。
shell
# CLONE 需要先启用插件,Docker 部署可以通过增加参数实现
# --plugin-load-add=mysql_clone.so
sql
-- 通过此 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)
sql
-- 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 密码。
sql
-- 验证是否 CLONE 成功
mysql> select * from performance_schema.clone_status\G
*************************** 1. row ***************************
ID: 1
PID: 0
STATE: Completed -- Completed 数据同步已完成
BEGIN_TIME: 2023-07-20 00:31:12.592
END_TIME: 2023-07-20 00:31:20.192
SOURCE: master_ip:10001
DESTINATION: LOCAL INSTANCE
ERROR_NO: 0
ERROR_MESSAGE:
BINLOG_FILE: master-bin.000003 -- 从节点配置参数 master_log_file
BINLOG_POSITION: 1478 -- 从节点配置参数 master_log_pos
GTID_EXECUTED:
1 row in set (0.01 sec)
五、常见问题处理
1、CLONE需要版本不同
问题:不同版本 CLONE 有异常,相同版本正常(都是 8.0.32 没有问题)。但是,可以正常建立主从关系。
解决方案:统一版本(不用 CLONE ,也建议主从统一版本)
示例:
master 8.0.32
slave 8.0.29
sql
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 启动异常信息如下
shell
[ERROR] *** Different lower_case_table_names settings for server ('0') and data dictionary ('1')
[ERROR] *** Data Dictiongary initialization failed.s
总结
以上即为全部内容。至于测试部分,就不磨叽了,直接在主节点操作,从节点可以直观看出变化。
总体上来说,配置并不算复杂,但是需要思路比较清晰!不过故障处理起来,会稍微麻烦一点,需要注意数据一致性的问题!