美文网首页
MySQL复制相关(持续更新)

MySQL复制相关(持续更新)

作者: Hz37 | 来源:发表于2018-08-05 21:03 被阅读58次

    一、异步复制

    异步复制原理图

    after commit
    • master:
      • Dump_Thread,通知IO_Thread数据变更
    • slave:
      • IO_Thread,拉取binlog增量
      • SQL_Thread,SQL逻辑重放

    异步复制流程

    1. master 写undo、redo
    2. master 发起commit,写binlog(filename,position)
    3. master 完成提交事务
    4. slave 通过IO_Thread拉取binlog的filename,position,并写入到本地的relaylog中
    5. slave 通过SQL_Thread逻辑重放relaylog中的SQL(单线程)

    两种场景

    1. 实时同步(IO_Thread主从没有延迟),写数据之前通知IO_Thread有变更,IO_Thread拉取binlog增量
    2. 主从长时间延迟(全备恢复),IO_Thread直接去主库本地磁盘拉取binlog增量

    复制中的坑

    1. row模式下,表最好是有主键,其次要有普通索引。否则sql_thread重放需要全表扫描匹配,速度非常慢(mysql5.7中做了优化)


      sql_thread重放

    二、半同步复制(MySQL 5.5 after commit)

    半同步复制流程图

    after commit

    半同步复制流程

    1. master 写undo、redo
    2. master 发起commit,sync binlog(filename,position)
    3. master 存储引擎commit完成
    4. master_sender_thread 等待slave_reciver_thread返回ack(等待过程中会阻塞下一个事务)
    5. master_sender_thread接收到slave_reciver_thread返回的ack,并返回给客户端,客户端才可以继续操作

    after带来的三个问题

    1. 性能问题:AFTER_COMMIT半同步是单线程处理的,master把事务发送完毕后,要接受和处理slave的ack应答,处理完ack后才能继续发送下一个事务,对性能影响比较大
    2. master commit完成后才开始等待slave的ACK,其实这个时候在master上事务已经提交完成并且其他客户端已经可以读到,只是提交该事物的客户端处于等待状态。
    3. 如果master等待ack时master crash,而slave又未接收到该事务的话,那么切换到从库后就会出现读取的结果不一致的情况(因为主库已commit而从库未收到该事务binlog)

    三、增强半同步复制(MySQL 5.7 after sync)

    增强半同步复制流程图

    after sync

    增强半同步复制流程

    1. master 写undo、redo
    2. master 发起commit,sync binlog(filename,position)
    3. master 通过单独的semisync_reciver_thread等待slave_reciver_thread返回ack,此过程中master_sender_thread可以处理其他事务的请求
    4. semisync_reciver_thread接收到slave_reciver_thread返回的ack,并返回给客户端
    5. master 存储引擎层commit

    增强半同步解决的问题

    1. AFTER_SYNC采用双工处理,master采用单独semisync_reciver_thread处理ack应答,不阻塞其他事务,提升性能
    2. AFTER_SYNC等待ack的操作是在引擎层commit之前处理,避免了其他客户端脏读
    3. 在等待ack的期间master crash,由于master引擎层未commit,如果slave未接受到该事务,那么数据是一致的

    增强半同步带来的新问题

    极端情况:在master sync binlog(写入xid)后,且在发送日志之前,这个时间master crash了。那么slave是没有拿到master的binlog增量的,而master重启后的crash recovery会认为该事务已写到binlog中,然后进行重做。这样就会导致主从不一致

    5.7增强半同步配置

    1. master
    SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%semi%';
    INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
    set global rpl_semi_sync_master_enabled=ON;
    
    1. slave
     install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
      set global rpl_semi_sync_slave_enabled=ON;
    
    1. 主要参数
    • mster:
      • rpl_semi_sync_master_enabled=ON 表示在master上已经开启半同步复制模式。
      • rpl_semi_sync_master_timeout=10000 该参数默认为10000毫秒,即10秒,可以调整,表示如果主库在某次事务中等待事件超过10秒,则降级为异步复制模式,不再等待slave,如果master探测到slave恢复,则会自动回到半同步模式。
      • rpl_semi_sync_master_wait_no_slave=ON 表示是否允许master每个事务提交后都要等待slave的确认信号,默认是ON,即每一个事务都会等待,如果是OFF,则slave追赶上之后,也不会回到半同步模式。
      • rpl_semi_sync_master_trace_level=32 表示开启半同步复制模式时的调试级别,默认是32
    • slave:
      • rpl_semi_sync_slave_enabled=ON
      • rpl_semi_sync_master_trace_level=32

    四、并行复制

    并行复制的演变

    • MySQL 5.6 是基于库级别的并行复制(适用于单实例多库而且库之间的写入分布比较平均的情况,比较鸡肋,可以忽略)
    • MySQL 5.7 是基于事务级别的并行复制(主要介绍)
    • MySQL 8.0 是基于行级别的并行复制(太新还没来得及研究,后面补上)

    MySQL 5.7基于行的并行复制

    原理:
    与组提交结合,一个组提交的事务都是可以并行回放,因为这些事务都已进入到事务的prepare阶段,则说明事务之间没有任何冲突(否则就不可能提交)。

    复制中的重要参数

    • log-bin = /binlog_dir
    • binlog_format = row
    • binlog_row_image = full //默认full
    • gtid_mode = on
    • enforce_gtid_consistency = on //打开gtid之前必须打开此选项,服务器通过允许仅执行可使用GTID安全记录的语句来强制执行GTID一致性(开启后强制检测gtid一致性,在事务中更改非事务表将会报错)
    • binlog_group_commit_sync_delay = 100 //单位(微秒)。如果不启用组提交,则每次提交一个事务,binlog做一次fsync。如果启用了binlog-group-commit,此时sync_binlog=N代表每N组事务,而不是每N个事务。建议设置sync_binlog=1
    • binlog_group_commit_sync_no_delay_count = 10
    • binlog_order_commit = off //开启后事务提交顺序与binlog顺序一致,默认on,设置为off则事务可并行提交,对数据一致性可能产生影响。如果启用了binlog-group-commit,则设置为off
    • transaction_write_set_extraction = on //8.0特性,5.7默认off
    • binlog_transation_dependency_tracking = COMMIT_ORDER //等同于打开binlog_order_commit,基于行级别并行复制配置成writeset_session
    • binlog_transation_dependency_history_size = 25000 //控制队列长度
    • slave_net_timeout = 20|30 //io_thread超时时间
    • log_slave_updates
    • slave_parallel_type = LOGICAL_CLOCK //从库开启并行复制
    • slave_parallel_type = 4|8
    • slave_preserve_commit_order = on //保证从库提交顺序与主库一致,前置条件log-bin,log_slave_update,slave_parallel_type = LOGICAL_CLOCK
    • slave_rows_search_algorithms = TABLE_SCAN,INDEX_SCAN //配置成INDEX_SCAN,HASH_SCAN,当没主键的表复制中可以用hash索引
    • relay_log_info_reposity = table //crash-safe replication
    • sync_relay_log_info = 1
    • relay_log_recovery = 1

    相关文章

      网友评论

          本文标题:MySQL复制相关(持续更新)

          本文链接:https://www.haomeiwen.com/subject/ipkivftx.html