设为首页 收藏本站
查看: 805|回复: 0

[经验分享] mysql GTID 主从复制模式

[复制链接]

尚未签到

发表于 2017-12-12 11:05:10 | 显示全部楼层 |阅读模式
  GTID与crash safe salve
  crash safe slave是MySQL 5.6提供的功能,意思是说在slave crash后,把slave重新拉起来可以继续从Master进行复制,不会出现复制错误也不会出现数据不一致。
  1、基于binlog文件位置的复制
  在基于binlog文件位置的复制下,要保证crash safe slave,配置下面的参数即可。
  relay_log_info_repository      = TABLE
  relay_log_recovery               = ON
  这样可行的原因是,relay_log_info_repository = TABLE时,apply event和更新relay_log_info表的操作被包含在同一个事务里,innodb要么让它们同时生效,要么同时不生效,保证位点信息和已经应用的事务精确匹配。同时relay_log_recovery = ON时,会抛弃master_log_info中记录的复制位点,根据relay_log_info的执行位置重新从Master获取binlog,这就回避了由于未同步刷盘导致的binlog文件接受位置和实际不一致以及relay log文件被截断的问题。
  在同时使用MTS(multi-threaded slave)时,为保证crash safe slave基于binlog文件位置的复制还需要设置sync_relay_log=1,因为MySQL在Crash恢复时必须先通过读取relay log补齐MTS导致的事务空洞。
  2、基于GTID的复制
  上面的设置并不适用于基于GTID的复制。在基于GTID的复制下,crash的Slave重启后,从binlog中解析的gtid_executed决定了要apply哪些binlog记录,所以binlog必须和innodb存储引擎的数据保持一致。要做到这一点,需要把sync_binlog和innodb_flush_log_at_trx_commit都设置为1,即所谓的"双1"。
  另外MySQL启动时,会从relay log文件中获取已接收的GTIDs并更新Retrieved_Gtid_Set。由于relay log文件可能不完整,所以需要抛弃已接收的relay log文件。因此relay_log_recovery = ON也是必须的。
  这样,对于基于GTID的复制,保证crash safe slave的设置就是下面这样。
  sync_binlog                               = 1
  innodb_flush_log_at_trx_commit  = 1
  relay_log_recovery                     = ON
  关于如何设置以确保crash safe slave,官方文档有明确记载,见 17.3.2 Handling an Unexpected Halt of a Replication Slave。
  但是其中关于GTID的记载中存在笔误,将relay_log_recovery=1写成了relay_log_recovery=0 (#83711)。同时也没有提到必须设置"双1",但是"双1"是必要的,否则crash的Slave重启后,可能会重复应用binlog event也可能会遗漏应用binlog event(#70659)。其中遗漏应用binlog event的情况更可怕,因为Slave在不触发SQL错误的情况下就默默的和Master不一致了。
  3、设置"双1"对性能的影响
  出于安全考虑,强烈推荐设置"双1"。"双1"会增大每个事务的RT,但得益于MySQL的组提交机制,高并发下"双1"对系统整体tps的影响在可接受范围内。
  sysbench oltp.lua 10张表每张表100w记录(qps/并发数)
  对更新同一行这样无法有效并行的场景,"双1"对性能的影响非常大。
  sysbench update_non_index.lua 1张表1条记录(qps/并发数)
  对不能有效并行的Slave replay,存在同样的问题。
  通过指定tx-rate执行sysbench的update_non_index.lua脚本压测30秒,完成后检查主备延迟。
  可以发现在Slave被配置为"双1"的情况下,延迟非常严重,1000以上的QPS就会出现延迟,非"双1"下QPS到5000以上才会出现延迟(主库配置为"双1")。
  sysbench update_non_index.lua 1张表100w条记录 128并发(延迟/qps)
  以上测试环境是Percona Server 5.6运行在配置HDD的8 core虚机,由于测试结果和系统IO能力有很大关系,仅供参考。
  4、如何在非"双1"下保证crash safe slave
  如果是MySQL 5.7可以关闭log_slave_updates,这样MySQL会将已执行的GTIDs实时记录到系统表mysql.gtid_executed中,mysql.gtid_executed是和用户事务一起提交的,因此可以保证和实际的数据一致。
  log_slave_updates              = OFF
  relay_log_recovery             = ON
  如果是MySQL 5.6可以采用如下变通的方式。
  按照基于binlog文件复制时crash safe slave的要求设置relay_log_info_repository = TABLE
  relay_log_info_repository      = TABLE
  relay_log_recovery               = ON
  在Slave crash后,根据relay_log_info_repository设置相应的gitd_purged再开启复制,步骤如下。
  1.启动MySQL,但不开启复制
  mysqld --skip-slave-start
  2.在Slave上修改为基于binlog文件位置的复制
  change master to MASTER_AUTO_POSITION = 0
  3.启动slave IO线程
  start slave io_thread
  这里不能启动SQL线程,如果接受到的GTID已经在Slave的gtid_executed里了,会被Slave skip掉。
  4.检查binlog传输的开始位置(即Retrieved_Gtid_Set的值)
  show slave status\G
  假设输出的Retrieved_Gtid_Set值为e10c75be-5c1b-11e6-ab7c-000c296078ae:7-10
  5.在Master上检查gtid_executed
  show master status
  假设输出的Executed_Gtid_Set值为e10c75be-5c1b-11e6-ab7c-000c296078ae:1-10
  6.在Slave上设置gitd_purged为binlog传输位置的前面的GTID的集合
  reset master;
  set global gitd_purged='e10c75be-5c1b-11e6-ab7c-000c296078ae:1-6';  
  7.修改回auto position的复制
  change master to MASTER_AUTO_POSITION = 1
  8.启动slave SQL线程
  start slave sql_thread
  但是,这种变通的方法不适合多线程复制。因为多线程复制可能产生gtid gap和Gap-free low-watermark position,这会导致Salve上重复apply已经apply过的event。后果就是数据不一致或者复制中断,除非设置binlog格式为row模式并且slave_exec_mode=IDEMPOTENT,slave_exec_mode=IDEMPOTENT允许Slave回放binlog时忽略重复键和找不到键的错误,使得binlog回放具有幂等性,但这也意味着如果真的出现了主备数据不一致也会被它忽略。
  5、MTS下特有的问题
  在同时使用MTS(slave_parallel_workers > 1)时,即使按上面crash safe slave的要求设置了基于GTID的复制,Slave crash后再重启还是会导致复制中断。
  通过强制杀掉MySQL所在虚机的方式模拟Slave宕机,然后再启动MySQL,MySQL日志中有如下错误消息:
  启动slave时也会报错
  mysql> start slave;

  ERROR 1872 (HY000): Slave failed to initialize>  出现这种现象的原因在于,relay_log_recovery=1 且 slave_parallel_workers>1的情况下,mysql启动时会进入MTS Group恢复流程,即读取relay log,尝试填补由于多线程复制导致的gap。然后relay log文件由于不是实时刷新的,在relay log文件中找不到gap对应的relay log记录(覆盖了gap的relay log起始和结束位置分别被称为低水位和高水位,低水位点即slave_relay_log_info.Relay_log_pos的值)就会报这个错。
  实际上,在GTID模式下,slave在apply event的时候可以跳过重复事件,所以可以安全的从低水位点应用日志,没必要解析relay log文件。 这看上去是一个bug,于是提交了一个bug报告#83713,目前还没有收到回复。
  作为回避方法,可以通过清除relay log文件,跳过这个错误。执行步骤如下:
  reset slave;
  change master to MASTER_AUTO_POSITION = 1
  start slave;
  在这里,单纯的调reset slave不能把状态清理干净,内部的Relay_log_info.inited标志位仍然处于未被初始化状态,此时调用start slave仍然会失败。因此需要补一刀change master。
  6、Master的crash safe
  前面一直在讲crash safe slave,Master的crash safe同样重要。 要想Master保持crash safe需要按下面的参数进行设置,否则不仅会丢失事务,gtid_executed还可能和实际的innodb存储引擎中的数据不一致。
  sync_binlog                              = 1
  innodb_flush_log_at_trx_commit = 1
  在Master配置为"双1"的情况下,Master crash后,如果没有发生failover,可以继续作为Master。 如果发生了failover,可以检查旧Master和新Master上由旧Master执行的事务集合是否一致。
  show master status
  如果一致,可以按MASTER_AUTO_POSITION = 1的方式将旧Master作为Slave和新Master建立复制关系。否则,考虑做事务补偿或从新Master上拉取备份进行恢复。
  在Master配置不是"双1"的情况下,在Master crash后由于难以准确知道旧Master上究竟执行了哪些事务,安全的做法是实施主备切换,并从新Master上拉取备份,把旧Master作为新Master的Slave进行恢复。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-423287-1-1.html 上篇帖子: Python远程连接MySQL数据库 下篇帖子: Spring Boot:在Spring Boot中使用Mysql和JPA
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表