23人参与 • 2026-04-27 • Mysql
mysql 主从复制是实现数据高可用、横向扩展、离线数据分析的核心技术,通过日志传输与重放机制实现多节点数据同步。本文将从复制核心原理入手,结合实操步骤讲解基础主从复制配置、新增从库部署、gtid 模式开启及环形复制拓扑搭建,覆盖从单主单从到多节点环形同步的完整实操流程。
在进行实操配置前,先掌握 mysql 复制的核心概念与关键知识点,是理解后续操作的基础。
mysql 默认采用异步复制模式,主库将数据变更写入二进制日志(binary log),从库通过两个核心线程实现数据同步:
log-bin,用于记录所有数据变更操作,是复制的核心数据源;relay-log,用于暂存从主库拉取的二进制日志内容;replication slave权限的专用用户,供从库拉取日志使用。rand()/uuid()/now())会导致主从数据不一致,建议使用基于行的复制(rbr)。本次实操基于单服务器部署 mysql 多实例(server1/server2/server3/server4,端口 3311-3314),模拟多节点复制集群,核心步骤为实例配置、服务管理与核心参数配置。
# 停止系统默认mysqld服务 systemctl stop mysqld # 验证服务状态 systemctl status mysqld
创建多实例配置文件,指定每个实例的端口、数据目录、套接字文件等基础参数:
cat > /labs/multi.cnf << 'eof' [mysqld@server1] user=mysql socket=/mysql/server1.sock port=3311 datadir=/mysql/data1 log-error=/mysql/server1.err mysqlx=off [mysqld@server2] user=mysql socket=/mysql/server2.sock port=3312 datadir=/mysql/data2 log-error=/mysql/server2.err mysqlx=off [mysqld@server3] user=mysql socket=/mysql/server3.sock port=3313 datadir=/mysql/data3 log-error=/mysql/server3.err mysqlx=off [mysqld@server4] user=mysql socket=/mysql/server4.sock port=3314 datadir=/mysql/data4 log-error=/mysql/server4.err mysqlx=off eof
编辑复制专用配置文件/labs/repl.cnf,开启二进制日志、中继日志,配置唯一server-id,开启 gtid 模式(后续使用):
# server1 核心配置 [mysqld@server1] server-id=11 log-bin=server1-bin relay-log=server1-relay-bin gtid-mode=on enforce-gtid-consistency=on # server2 核心配置 [mysqld@server2] server-id=12 log-bin=server2-bin relay-log=server2-relay-bin gtid-mode=on enforce-gtid-consistency=on # server3 核心配置 [mysqld@server3] server-id=13 log-bin=server3-bin relay-log=server3-relay-bin gtid-mode=on enforce-gtid-consistency=on # server4 核心配置 [mysqld@server4] server-id=14 log-bin=server4-bin relay-log=server4-relay-bin gtid-mode=on enforce-gtid-consistency=on
通过系统服务管理多实例,重新加载服务配置并启动所有实例:
# 编辑多实例服务配置(按需调整) vim /usr/lib/systemd/system/mysqld@.service # 重新加载系统服务 systemctl daemon-reload # 启动所有mysql实例 systemctl start mysqld@server1 systemctl start mysqld@server2 systemctl start mysqld@server3 systemctl start mysqld@server4
注:所有实例通过
--defaults-file=/labs/repl.cnf --defaults-group-suffix=@serverx启动,分别加载对应实例的配置。
实现单主单从基础复制拓扑,主库为 server1(3311),从库为 server2(3312),核心步骤为主库配置、从库配置、复制启动与验证。
mysql -uroot -h127.0.0.1 -p3311 # 设置提示符为1>,标识主库 1> prompt 1>;
记录日志文件名与位置,作为从库同步的起始点:
1> show master status\g # 关键输出 file: server1-bin.000001 # 二进制日志文件名 position: 155 # 日志写入位置 executed_gtid_set: # 未开启gtid时为空
创建repl用户,授予replication slave权限,仅允许本地访问(生产环境建议限制从库 ip):
1> create user 'repl'@'127.0.0.1' identified with mysql_native_password by 'oracle'; 1> grant replication slave on *.* to 'repl'@'127.0.0.1'; 1> flush privileges;
创建业务数据库并导入数据,作为同步测试源:
1> source /path/to/world.sql; # 导入world测试库 1> show databases; # 验证数据库创建成功
mysql -uroot -h127.0.0.1 -p3312 # 设置提示符为2>,标识从库 2> prompt 2>;
指定主库地址、端口、同步起始日志位点,与主库show master status输出保持一致:
2> change master to master_host='127.0.0.1', master_port=3311, master_log_file='server1-bin.000001', master_log_pos=155;
启动 io_thread 和 sql_thread,开始从主库拉取并重放日志:
2> start slave user='repl' password='oracle';
主库执行show processlist,查看是否有从库的 binlog dump 连接:
1> show processlist\g # 关键输出:state为master has sent all binlog to slave; waiting for more updates
从库执行show processlist,查看 io/sql 线程运行状态:
2> show processlist\g # 关键输出:state为slave has read all relay log; waiting for more updates
从库查看是否同步到主库的world数据库,确认数据一致:
# 主库查看数据 1> select id, name from world.city order by id desc limit 5; # 从库查看数据,与主库完全一致即为同步成功 2> show databases; # 可见world库 2> select id, name from world.city order by id desc limit 5;
在已有主从拓扑(server1→server2)基础上,新增 server3 作为 server2 的从库,核心难点为从库数据初始化与同步位点获取,需通过备份实现数据一致性。
在 server2 上执行 mysqldump 备份,通过--master-data=2记录当前同步位点,仅备份业务库world:
mysqldump -uroot -h127.0.0.1 -p3312 --master-data=2 -b world > /tmp/server2.sql
注:
--master-data=2会在备份文件中以注释形式记录当前二进制日志位点,-b指定备份的数据库,此备份仅包含 world 库,不包含 mysql 系统库中的复制用户信息。
编辑备份文件,找到change master to注释行,记录日志文件名与位置:
vim /tmp/server2.sql # 关键注释行,记录同步起始位点 -- change master to master_log_file='server2-bin.000001', master_log_pos=736159;
mysql -uroot -h127.0.0.1 -p3313 3> prompt 3>;
恢复 server2 的 world 库数据,保证新从库与主库数据基础一致:
3> source /tmp/server2.sql;
基于备份文件中的位点,配置主库为 server2,启动复制线程:
# 配置复制参数 3> change master to master_host='127.0.0.1', master_port=3312, master_log_file='server2-bin.000001', master_log_pos=736159; # 启动复制线程 3> start slave user='repl' password='oracle';
3> show slave status\g # 关键输出:slave_io_running=yes、slave_sql_running=yes
主库 server1 执行数据变更,验证 server2、server3 是否逐级同步:
# 主库server1删除数据 1> delete from world.city where id>4070; # server2验证数据已删除 2> select id, name from world.city order by id desc limit 5; # server3验证数据已同步删除,与server2一致 3> select id, name from world.city order by id desc limit 5;
gtid(global transaction identifier,全局事务标识符)为每个事务分配唯一标识,替代传统的「文件 + 位点」同步方式,实现自动定位同步位点,简化复制配置与故障切换。在此基础上搭建环形复制,实现多节点互相同步。
# 停止所有mysql多实例 systemctl stop mysqld@server* # 登录各节点,停止复制线程(若未停止) 1> stop slave; 2> stop slave; 3> stop slave;
检查/labs/repl.cnf中已配置以下 gtid 核心参数(实操二已配置):
gtid-mode=on enforce-gtid-consistency=on # 强制gtid一致性,防止非gtid事务
systemctl start mysqld@server1 systemctl start mysqld@server2 systemctl start mysqld@server3
将原有「文件 + 位点」复制升级为 gtid 复制,核心为清空旧日志历史与开启自动定位。
2> stop slave; # 停止传统复制线程 2> reset master; # 清空旧的二进制日志与gtid历史 2> change master to master_auto_position=1; # 开启gtid自动定位 2> start slave user='repl' password='oracle'; # 启动gtid复制线程
2> show slave status\g # 关键输出:master_auto_position=1、slave_io_running=yes、slave_sql_running=yes
配置环形复制:server1→server2→server3→server1,所有节点均为主库同时也是从库,核心为每个节点配置上游主库并开启 gtid 自动定位。
# 登录server3,停止旧复制线程并重置 3> stop slave; 3> reset master; # 配置主库为server2,开启gtid自动定位 3> change master to master_host='127.0.0.1', master_port=3312, master_auto_position=1; # 启动复制线程 3> start slave user='repl' password='oracle';
# 登录server1,停止旧复制线程并重置 1> stop slave; 1> reset master; # 配置主库为server3,开启gtid自动定位 1> change master to master_host='127.0.0.1', master_port=3313, master_auto_position=1; # 启动复制线程 1> start slave user='repl' password='oracle';
每个节点执行show slave status\g,确保slave_io_running=yes、slave_sql_running=yes、master_auto_position=1。
任意节点执行数据变更,验证其他节点是否同步更新,实现环形互通:
# server2执行数据插入/更新
2> insert into world.city (name, countrycode, district, population) values ('testcity', 'usa', 'california', 10000);
# server3验证数据已同步
3> select * from world.city where name='testcity';
# server1验证数据已同步
1> select * from world.city where name='testcity';# 查看节点uuid,唯一标识gtid集群中的节点 2> select @@server_uuid; # 查看已执行的gtid事务 2> show master status\g;
mysqldump 备份时通过-b world仅指定了业务库 world,而复制用户repl存储在mysql 系统库中,因此不会被包含在备份文件中;且复制用户是在主库创建后通过复制同步到从库,并非备份文件自带。
server-id是否唯一,无重复;replication slave;log-bin);master_log_file和master_log_pos是否与主库一致。master_auto_position=1实现自动定位,简化配置与故障切换,提升复制可靠性。server-id唯一是集群配置的前提;mysqldump --master-data=2实现数据初始化 + 同步位点记录,保证新从库与主库数据基础一致;gtid-mode=on+master_auto_position=1;slave_io_running=yes、slave_sql_running=yes,且各节点数据完全一致。到此这篇关于mysql主从复制与gtid环形复制的文章就介绍到这了,更多相关mysql主从复制与 gtid内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论