想必从库异常中断的情况不在少数, 其中报错信息中 1032 及 1062 的错误占了不少的比重
错误 1032 指的是从库中找不到对应行的记录
错误 1062 指的是主键冲突
遇到此报错时, 大多 DBA 会使用如下方法进行处理
1 手动处理
方法一: 找出引起异常的数据然后手动在从库处理后重启 SQL 线程继续观察;
根据报错的信息, 通过 mysqlbinlog 解析 binlog 日志, 找到对应的数据, 然后查看从库是否缺失数据或者已存在对应主键的数据, 然后手动在从库处理对应记录的数据. 处理完毕后再次开启同步.
但是, 后续还得观察是否再次出现错误
方法二: 手动跳过 1 个或更多个事务, 然后继续观察.
- /* 传统点位模式复制 */
- SQL>set global sql_slave_skip_counter=1;
- SQL>start sql_thread;
- /* GTID 模式复制 */
- SQL>set gtid_next='e29d3917-9dbb-11e9-8b64-e4434b6e2c80:11103335-16054791';
- SQL>begin;commit;
- SQL>set gtid_next='AUTOMATIC';
注意, 手动跳过事务的方式存在一个很大的缺点: 1 个事务中存在多个 sql, 用此方式, 本事务中的其他 SQL 也会被跳过(具体的和 binlog-format 有关, 对于当前常用的 ROW 格式均有影响).
2 持续跳过错误
但是, 如果一直报错, 但是, 这些报错又可以忽略可以怎么处理, 此时也有很多方法, 通常使用的是如下几种:
方法一: 使用 pt-slave-restart 工具跳过对应错误
但是使用 pt-slave-restart 工具跳过报错时, 必须关闭多线程复制, 因为工具分不清到底哪个线程复制出了问题, 然后会报类似如下的报错:
Cannot skip transactions properly because GTID is enabled and slave_parallel_workers> 0. See 'GLOBAL TRANSACTION IDS' in the tool's documentation
处理步骤为:
- /* 暂停并行复制 */
- SQL> set global slave_parallel_workers=0;
- /* 使用 pt-slave-restart 工具跳过错误(填写错误号)*/
- pt-slave-restart --user=root --password='Admin@123' --socket=/data/mysql3306/tmp/MySQL.sock --error-numbers=1062
- /* 不再报错时, 再开启并行复制 */
- MySQL> set global slave_parallel_workers=8;
方法二: 在配置文件里配置跳过指定错误
在配置文件 [mysqld] 项里加入参数 slave-skip-errors
slave-skip-errors=1032,1062
但是, 此方法存在一个致命缺点: 该参数是静态参数, 无法动态修改, 需要修改配置文件后重启数据库方可生效.
3 幂等模式
因为手动跳过事务时, 会忽略相同事务下的其他正常的 SQL 在从库的应用; pt-slave-restart 工具需要停止多线程复制, 影响从库应用速度; 配置 slave-skip-errors 又需要重启数据库方可生效. 那么有没有一种方式既不会跳过多余的 SQL, 又无需重启数据库也不影响从库应用 SQL 的速度呢? 答案是有的, 也就是将 slave_exec_mode 参数设置为 IDEMPOTENT, 即幂等模式(默认为严格模式 STRICT).
- /* 在线动态修改 */
- SQL> set global slave_exec_mode='IDEMPOTENT';
改为幂等模式后, 可以忽略 1032 及 1062 的错误, 对同一事务内的其他 SQL 无影响, 依旧能正常执行.
4. 结语
本文中没有举具体案例进行实战演示, 不过建议大家还是自行搭建环境进行场景复现的演示(在从库先插入部分数据或先更新部分数据), 然后再在主库执行, 即可出现 1062 或 1032 的错误.
很多初学者或实战经验不足的同学可能不知道该参数, 因此, 更加建议在多种场景下测试.
如想和更多的数据库技术爱好者及时交流, 可以关注公众号: 数据库干货铺 回复 "加群", 进入技术交流群进行沟通.
来源: https://www.cnblogs.com/gjc592/p/12679326.html