• MySQL之主从半同步复制


    默认情况下,MySQL的复制功能是异步的,异步复制可以提供最佳的性能,主库把binlog日志发送给从
    库即结束,并不验证从库是否接收完毕。这意味着当主服务器或从服务器端发生故障时,有可能从服务
    器没有接收到主服务器发送过来的binlog日志,这就会造成主服务器和从服务器的数据不一致,甚至在
    恢复时造成数据的丢失

    半同步复制实现:
    官方文档:

    https://dev.mysql.com/doc/refman/8.0/en/replication-semisync.html
    https://dev.mysql.com/doc/refman/5.7/en/replication-semisync.html
    https://mariadb.com/kb/en/library/semisynchronous-replication/
    

    范例: CentOS8 在MySQL8.0 在主从同步环境下实现半同步复制

    # 查看插件文件
    [root@centos8 ~]# rpm -ql mysql-server | grep semisync
    /usr/lib64/mysql/plugin/semisync_master.so
    /usr/lib64/mysql/plugin/semisync_slave.so
    
    ## master
    [root@centos8 ~]# vim /etc/my.cnf
    [mysqld]
    server-id=28
    log-bin=/data/mysql/mysql-bin
    rpl_semi_sync_master_enabled=ON   #修改此行,需要先安装semisync_master.so插件后,再重启,否
    则无法启动
    rpl_semi_sync_master_timeout=3000  #设置3s内无法同步,也将返回成功信息给客户端
    
    # 创建用户管理主从复制
    mysql> create user 'repluser'@'172.31.0.%' identified by '123456';
    Query OK, 0 rows affected (0.00 sec)
    # 授权
    mysql> grant replication slave on *.* to repluser@'172.31.0.%';
    Query OK, 0 rows affected (0.00 sec)
    
    ## slave1
    [root@centos8 ~]# vim /etc/my.cnf
    [mysqld]
    server-id=38
    rpl_semi_slave_enabled=ON  #修改此行,需要先安装semisync_slave.so插件后,再重启,否则
    无法启动
    
    mysql> CHANGE MASTER TO
     MASTER_HOST='172.31.0.28',
     MASTER_USER='repluser',
     MASTER_PASSWORD='123456',
     MASTER_PORT=3306,
     MASTER_LOG_FILE='mysql-bin.000002',
     MASTER_LOG_POS=685;
     
    mysql> start slave;
    Query OK, 0 rows affected (0.00 sec)
    
    ## slave2
    [root@centos8 ~]# vim /etc/my.cnf
    [mysqld]
    server-id=48
    rpl_semi_sync_slave_enabled=ON  #修改此行,需要先安装semisync_slave.so插件后,再重启,否则
    无法启动
    
    mysql> CHANGE MASTER TO
     MASTER_HOST='172.31.0.28',
     MASTER_USER='repluser',
     MASTER_PASSWORD='123456',
     MASTER_PORT=3306,
     MASTER_LOG_FILE='mysql-bin.000002',
     MASTER_LOG_POS=685;
    
    mysql> start slave;
    Query OK, 0 rows affected (0.00 sec)
    
    ## master#永久安装插件
    mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
    Query OK, 0 rows affected (0.00 sec)
    
    # 查看插件
    mysql> show plugins;
    
    # 临时修改变量
    mysql> set global rpl_semi_sync_master_enabled=1;
    Query OK, 0 rows affected (0.00 sec)
    
    # 超时长1s,默认值为10s
    mysql> set global rpl_semi_sync_master_timeout = 3000;
    Query OK, 0 rows affected (0.00 sec)
    
    ### 重置master的logs,需要再使用
    mysql> RESET MASTER;
    
    # 查看当前修改的
    mysql> show global variables like '%semi%';
    +-------------------------------------------+------------+
    | Variable_name                             | Value      |
    +-------------------------------------------+------------+
    | rpl_semi_sync_master_enabled              | ON         |
    | rpl_semi_sync_master_timeout              | 3000       |
    | rpl_semi_sync_master_trace_level          | 32         |
    | rpl_semi_sync_master_wait_for_slave_count | 1          |
    | rpl_semi_sync_master_wait_no_slave        | ON         |
    | rpl_semi_sync_master_wait_point           | AFTER_SYNC |
    +-------------------------------------------+------------+
    6 rows in set (0.00 sec)
    
    # 第一次查看semi状态
    mysql> show global status like '%semi%';
    +--------------------------------------------+-------+
    | Variable_name                              | Value |
    +--------------------------------------------+-------+
    | Rpl_semi_sync_master_clients               | 0     |
    | Rpl_semi_sync_master_net_avg_wait_time     | 0     |
    | Rpl_semi_sync_master_net_wait_time         | 0     |
    | Rpl_semi_sync_master_net_waits             | 0     |
    | Rpl_semi_sync_master_no_times              | 0     |
    | Rpl_semi_sync_master_no_tx                 | 0     |
    | Rpl_semi_sync_master_status                | ON    |
    | Rpl_semi_sync_master_timefunc_failures     | 0     |
    | Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
    | Rpl_semi_sync_master_tx_wait_time          | 0     |
    | Rpl_semi_sync_master_tx_waits              | 0     |
    | Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
    | Rpl_semi_sync_master_wait_sessions         | 0     |
    | Rpl_semi_sync_master_yes_tx                | 0     |
    +--------------------------------------------+-------+
    14 rows in set (0.01 sec)
    
    ## slave1永久安装插件
    mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
    Query OK, 0 rows affected (0.00 sec)
    
    # 临时修改变量
    mysql> set global rpl_semi_sync_slave_enabled=1;
    Query OK, 0 rows affected (0.00 sec)
    
    # 查看当前修改的数据信息
    mysql> show global variables like '%semi%';
    +---------------------------------+-------+
    | Variable_name                   | Value |
    +---------------------------------+-------+
    | rpl_semi_sync_slave_enabled     | ON    |
    | rpl_semi_sync_slave_trace_level | 32    |
    +---------------------------------+-------+
    2 rows in set (0.00 sec)
    
    #注意:如果已经实现主从复制,需要stop slave;start slave;
    
    # 查看semi状态
    mysql> show global status like '%semi%';
    +----------------------------+-------+
    | Variable_name              | Value |
    +----------------------------+-------+
    | Rpl_semi_sync_slave_status | OFF   |
    +----------------------------+-------+
    1 row in set (0.00 sec)
    
    # 上面的操作完再次查看master的 semi状态
    mysql> show global status like '%semi%';
    +--------------------------------------------+-------+
    | Variable_name                              | Value |
    +--------------------------------------------+-------+
    | Rpl_semi_sync_master_clients               | 2     |
    | Rpl_semi_sync_master_net_avg_wait_time     | 0     |
    | Rpl_semi_sync_master_net_wait_time         | 0     |
    | Rpl_semi_sync_master_net_waits             | 0     |
    | Rpl_semi_sync_master_no_times              | 1     |
    | Rpl_semi_sync_master_no_tx                 | 2     |
    | Rpl_semi_sync_master_status                | ON    |
    | Rpl_semi_sync_master_timefunc_failures     | 0     |
    | Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
    | Rpl_semi_sync_master_tx_wait_time          | 0     |
    | Rpl_semi_sync_master_tx_waits              | 0     |
    | Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
    | Rpl_semi_sync_master_wait_sessions         | 0     |
    | Rpl_semi_sync_master_yes_tx                | 0     |
    +--------------------------------------------+-------+
    14 rows in set (0.00 sec)
    

    主从问题汇总

    # 从服务器是否落后于主服务
    Seconds_Behind_Master:0
    
    # 如何确定主从节点数据是否一致
    percona-toolkit
    
    # 数据不一致如何修复
    删除从数据库,重新复制
    
    # 复制的问题和解决方案
    数据损坏或丢失
    Master:MHA + semisync replication
    Slave: 重新复制
    
    # 不惟一的 server id
    重新复制
    
    # 复制延迟
    需要额外的监控工具的辅助
    一从多主:mariadb10 版后支持
    多线程复制:对多个数据库复制
    
    ##  MySQL 主从数据不一致
    造成主从不一致的原因
    主库binlog格式为Statement,同步到从库执行后可能造成主从不一致。
    主库执行更改前有执行set sql_log_bin=0,会使主库不记录binlog,从库也无法变更这部分数据。
    从节点未设置只读,误操作写入数据
    主库或从库意外宕机,宕机可能会造成binlog或者relaylog文件出现损坏,导致主从不一致
    主从实例版本不一致,特别是高版本是主,低版本为从的情况下,主数据库上面支持的功能,从数
    据库上面可能不支持该功能
    MySQL自身bug导致
    
    主从不一致修复方法
    将从库重新实现
    虽然这也是一种解决方法,但是这个方案恢复时间比较慢,而且有时候从库也是承担一部分的查询操作的,不能贸然重建。
    
    使用percona-toolkit工具辅助
    PT工具包中包含pt-table-checksum和pt-table-sync两个工具,主要用于检测主从是否一致以及修复数据不一致情况。这种方案优点是修复速度快,不需要停止主从辅助,缺点是需要知识积累,需要时间去学习,去测试,特别是在生产环境,还是要小心使用
    关于使用方法,可以参考下面链接:https://www.cnblogs.com/feiren/p/7777218.html
    
    手动重建不一致的表
    在从库发现某几张表与主库数据不一致,而这几张表数据量也比较大,手工比对数据不现实,并且重做整个库也比较慢,这个时候可以只重做这几张表来修复主从不一致
    
    这种方案缺点是在执行导入期间需要暂时停止从库复制,不过也是可以接受的
    

    如何避免主从不一致

    主库binlog采用ROW格式
    主从实例数据库版本保持一致
    主库做好账号权限把控,不可以执行set sql_log_bin=0
    从库开启只读,不允许人为写入
    定期进行主从一致性检验
    

    范例:A,B,C这三张表主从数据不一致

    1、从库停止Slave复制
    mysql> stop slave;
    
    2、在主库上dump这三张表,并记录下同步的binlog和POS点
    [root@centos8 ~]# mysqldump -uroot -p123456 -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.666666', MASTERLOGPOS=666666;
    #以下指令是为了保障其他表的数据不丢失,一直同步直到那个点结束,A,B,C表的数据在之前的备份已
    经生成了一份快照,只需要导入进入,然后开启同步即可
    
    4、把A_B_C.sql拷贝到Slave机器上,并做指向新位置
    mysql> start slave until MASTERLOGFILE='mysql-bin.666666',
    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;
    
  • 相关阅读:
    Charles
    HttpRunner 接口自动化测试进阶
    HttpRunner 接口自动化简单实践
    Extract
    PyCharm配置gitHub远程仓储
    Python Unittest与数据驱动
    WEB接口测试之Jmeter接口测试自动化 (三)(数据驱动测试)
    ARTS-S golang goroutines and channels
    ARTS-S golang goroutines and channels
    ARTS-S c语言统计程序运行时间
  • 原文地址:https://www.cnblogs.com/xuanlv-0413/p/14797338.html
Copyright © 2020-2023  润新知