1、复制过滤器
让从节点仅复制指定的数据库,或指定数据库的指定表
复制过滤器有两种实现方式
(1)服务器选项:主服务器仅向二进制日志中记录与特定数据库相关的事件
- 缺点:基于二进制还原将无法实现;不建议使用
- 优点:只需要在主节点配置一次即可
- 此项和 binlog_format相关
vim /etc/my.cnf
binlog-do-db=db1 #数据库白名单列表,不支持同时指定多个值,如果想实现多
个数据库需多行实现
binlog-do-db=db2
binlog-ignore-db= #数据库黑名单列表
(2)从服务器SQL_THREAD在relay log中的事件时,仅读取与特定数据库(特定表)相关的事件并应用于本地
- 缺点:会造成网络及磁盘IO浪费,在所有从节点都要配置
- 优点:不影响二进制备份还原
# 从服务器上的复制过滤器相关变量
replicate_do_db="db1,db2,db3" #指定复制库的白名单,变量可以指定逗号分隔的多个
值,选项不支持多值,只能分别写多行实现
replicate_ignore_db= #指定复制库黑名单
replicate_do_table= #指定复制表的白名单
replicate_ignore_table= #指定复制表的黑名单
replicate_wild_do_table= foo%.bar% #支持通配符
replicate_wild_ignore_table=
2、GTID复制
GTID(Global Transaction ID 全局事务标识符) MySQL 5.6 版本开始支持,但不太成熟,建议使用MySQL5.7以上版本的GTID功能。
MySQL5.6版本出现没有默认开启,5.7中即使不开启也有匿名的GTID记录。
开启GTID功能可以支持多DUMP线程的并发复制,而且在MySQL5.6实现了基于库级别多SQL线程并发。
在MySQL5.7利用 GTID的 Logic clock 逻辑时钟。保证了同库级别下的事务顺序问题。即可以实现基于事务级别的并发回放。从而大大减少了同步的延迟。
同时GTID具有幂等性特性,即多次执行结果是一样的
利用 GTID复制不像传统的复制方式(异步复制、半同步复制)需要找到binlog文件名和POS点,只需知道master的IP、端口、账号、密码即可。开启GTID后,执行change master to master_auto_postion=1即可,它会自动寻找到相应的位置开始同步。
GTID 优点:
- 保证事务全局统一
- 截取日志更加方便。跨多文件,判断起点终点更加方便
- 判断主从工作状态更加方便
- 传输日志,可以并发传输。SQL回放可以更高并发
- 主从复制构建更加方便
![图片[1]-复制过滤器及其他复制-李佳程的个人主页](http://www.lijiach.com/wp-content/uploads/2022/11/image-126.png)
GTID = server_uuid:transaction_id,在一组复制中,全局唯一
server_uuid 来源于 /var/lib/mysql/auto.cnf
# GTID服务器相关选项
gtid_mode #gtid模式
enforce_gtid_consistency #保证GTID安全的参数
# GTID配置范例
# 主服务器
vim /etc/my.cnf
server-id=1
gtid_mode=ON
enforce_gtid_consistency
log-bin=mysql-bin #可选
systemctl restart mysqld
mysql> grant replication slave on *.* to 'repluser'@'10.0.0.%' identified by '123456';
# 从服务器
vim /etc/my.cnf
server-id=2
gtid_mode=ON
enforce_gtid_consistency
systemctl restart mysqld
# 如果主服务器和从服务器数据不一致,需要先将主库数据备份还原至从库,再执行下面操作
mysqldump -A --master-data=2 > /backup/full.sql
mysql>CHANGE MASTER TO MASTER_HOST='192.168.1.21',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_AUTO_POSITION=1; #使用GTID
mysql>start slave;
# 注意观察:Retrieved_Gtid_set和Executed_Gtid_Set这两个值,对比主节点执行show master
status的值,如果相同表示同步完成。
3、复制的监控和维护
# 清理日志
PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }
RESET MASTER TO # #mysql 不支持
RESET SLAVE [ALL]
# 复制监控
SHOW MASTER STATUS
SHOW BINARY LOGS
SHOW BINLOG EVENTS
SHOW SLAVE STATUS
SHOW PROCESSLIST
# 从服务器是否落后于主服务
Seconds_Behind_Master:0
# 如何确定主从节点数据是否一致
percona-toolkit
# 数据不一致如何修复
删除从数据库,重新复制
3、复制的问题和解决方案
数据损坏或丢失
- Master:MHA + semisync replication
- Slave: 重新复制
不惟一的 server id
- 重新复制
复制延迟
- 利用GTID(MySQL5.6需要手动开启,MySQL5.7以上默认开启)支持并发传输binlog及并行多个SQLl线程
- 减少大事务,将大事务拆分成小事务
- 减少锁
- sync_binlog=1 加快binlog更新时间,从而加快日志复制
- 升级到MySQL5.7以上版本(5.7之前的版本,没有开GTID之前,主库可以并发事务,但是dump传输时是串行)
- 需要额外的监控工具的辅助
- 一从多主:Mariadb10 版后支持
- 多线程复制:对多个数据库复制
MySQL 主从数据不一致
- 造成主从不一致的原因
- 主库binlog格式为Statement,同步到从库执行后可能造成主从不一致。
- 主库执行更改前有执行set sql_log_bin=0,会使主库不记录binlog,从库也无法变更这部分数据。
- 从节点未设置只读,误操作写入数据
- 主库或从库意外宕机,宕机可能会造成binlog或者relaylog文件出现损坏,导致主从不一致
- 主从实例版本不一致,特别是高版本是主,低版本为从的情况下,主数据库上面支持的功能,从数据库上面可能不支持该功能
- 主从sql_mode 不一致
- MySQL自身bug导致
- 主从不一致修复方法
- 将从库重新实现,虽然这也是一种解决方法,但是这个方案恢复时间比较慢,而且有时候从库也是承担一部分的查询操作的,不能贸然重建。
- 使用percona-toolkit工具辅助,PT工具包中包含pt-table-checksum和pt-table-sync两个工具,主要用于检测主从是否一致以及修复数据不一致情况。这种方案优点是修复速度快,不需要停止主从辅助,缺点是需要知识积累,需要时间去学习,去测试,特别是在生产环境,还是要小心使用
- 手动重建不一致的表,在从库发现某几张表与主库数据不一致,而这几张表数据量也比较大,手工比对数据不现实,并且重做整个库也比较慢,这个时候可以只重做这几张表来修复主从不一致这种方案缺点是在执行导入期间需要暂时停止从库复制,不过也是可以接受的
- 如何避免主从不一致
- 主库binlog采用ROW格式
- 主从实例数据库版本保持一致
- 主库做好账号权限把控,不可以执行set sql_log_bin=0
- 从库开启只读,不允许人为写入
- 定期进行主从一致性检验
# 手动重建不一致的表
1、从库停止Slave复制
mysql>stop slave;
2、在主库上dump这三张表,并记录下同步的binlog和POS点
mysqldump -uroot -pmagedu -q --single-transaction --master-data=2 testdb A B
C >/backup/A_B_C.sql
3、查看A_B_C.sql文件,找出记录的binlog和POS点
head A_B_C.sql
例如:MASTERLOGFILE='mysql-bin.888888', MASTERLOGPOS=666666;
#以下指令是为了保障其他表的数据不丢失,一直同步直到那个点结束,A,B,C表的数据在之前的备份已经生成了一份快照,只需要导入进入,然后开启同步即可
4、把A_B_C.sql拷贝到Slave机器上,并做指向新位置
mysql>start slave until MASTERLOGFILE='mysql-bin.888888',
MASTERLOGPOS=666666;
5、在Slave机器上导入A_B_C.sql
mysql -uroot -p123456 testdb
mysql>set sql_log_bin=0;
mysql>source /backup/A_B_C.sql
mysql>set sql_log_bin=1;
6、导入完毕后,从库开启同步即可。
mysql>start slave;
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END