暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL半同步复制数据最终一致性验证

IT小Chen 2022-12-30
628

所谓半同步,是指从库完全接收到主库传来的binlog数据,并将数据写入到realy log后,主库才能提交完成事务,那么理论上,在主库执行大事务并正常提交事务后出现宕机,这时从库虽然接收到了全部的binlog,但是realy log可能还没有解析重放完成,导致从库查询的数据是滞后的,等realy log解析重放完成后,数据才会一致,也就是半同步复制在某些场景下,数据不是强一致性的,而是弱一致性或最终一致性。

下面通过实验来验证这个猜想:

    主库:192.168.1.100  MySQL 5.7.22  Redhat7.5
    从库:192.168.1.200 MySQL 5.7.22 Redhat7.5
    启用半同步复制

    主库

    准备测试数据

      mysql> use cjc
      Database changed
      mysql> select count(*) from t1;
      +----------+
      | count(*) |
      +----------+
      | 11534336 |
      +----------+
      1 row in set (5.88 sec)
      mysql> create table t2 like t1;
      Query OK, 0 rows affected (0.33 sec)

      从库

      检查半同步状态

        mysql> show global status like '%semi%';
        +----------------------------+-------+
        | Variable_name | Value |
        +----------------------------+-------+
        | Rpl_semi_sync_slave_status | ON |
        +----------------------------+-------+
        1 row in set (0.62 sec)

        主从同步状态

          mysql> show slave status\G;

          主库、从库执行脚本,查看t2表数据量和时间

          准备脚本

            [mysql@cjc-db-01 ~]$ head -n 2 1.sh 
            mysql -uroot -p1 -e "select now(),count(*) from cjc.t2;"
            mysql -uroot -p1 -e "select now(),count(*) from cjc.t2;"
            [mysql@cjc-db-01 ~]$ cat 1.sh |wc -l
            12312

            执行脚本

              [mysql@dcs02 ~]$ sh 1.sh > 1.log
              [mysql@dcs02 ~]$ tail -10f 1.log

              主库:模拟大事务

                mysql> insert into t2 select * from t1;
                Query OK, 11534336 rows affected (6 min 57.18 sec)
                Records: 11534336 Duplicates: 0 Warnings: 0

                主库:在10:39:40事务结束,查询t2表数据量为11534336

                  2022-12-29 10:36:58  0
                  now() count(*)
                  2022-12-29 10:38:11 0
                  now() count(*)
                  2022-12-29 10:39:40 11534336
                  now() count(*)
                  2022-12-29 10:39:47 11534336
                  now() count(*)
                  2022-12-29 10:39:54 11534336
                  now() count(*)

                  强制关闭主库,模拟意外宕机

                    [root@cjc-db-01 ~]# ps -ef|grep mysql
                    mysql 2318 1 5 09:10 pts/0 00:04:25 mysqld --defaults-file=/etc/my.cnf --user=mysql
                    [root@cjc-db-01 ~]# kill -9 2318

                    从库:

                    在10:45:51查询t2表数据量为11534336,比主库慢了6分11秒,也就是主库10:40:00宕机后,从库切换为主库,在10:40:00到10:45:50期间,t2表数据量和真实数据量不一致,数据量为0,实际是11534336,5分钟后,relay log完全解析入库后,数据一致。

                      [mysql@dcs02 ~]$ sh 1.sh > 1.log
                      [mysql@dcs02 ~]$ tail -10f 1.log
                      now() count(*)
                      2022-12-29 10:43:00 0
                      now() count(*)
                      2022-12-29 10:43:51 0
                      now() count(*)
                      2022-12-29 10:44:52 0
                      now() count(*)
                      2022-12-29 10:45:51 11534336
                      now() count(*)
                      2022-12-29 10:45:58  11534336

                      文章转载自IT小Chen,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                      评论