美文网首页
第三十二节、主库出问题了,从库怎么办?

第三十二节、主库出问题了,从库怎么办?

作者: 小母牛不生产奶 | 来源:发表于2020-06-17 15:42 被阅读0次

    一主多重的切换正确性:

    1、基于位点的主备切换

    通常情况下,在切换任务的时候,要先主动跳过这些错误,有两种常用的方法:

    1、主动跳过一个事物,跳过的命令的写法是:

    set global sql_slave_skip_counter=1;

    start slave;

    因为切换过程中,可能会不止重复执行一个事物,所以需要在从库持续观察,每次碰到这些错误就停下来,执行一次跳过命令,直到不再出现停下来的情况,以此来跳过可能涉及的所有事务。

    2、通过设置slave_skip_errors参数,直接设置跳过指定的错误:

    在执行主备切换时,有这么两类错误,是经常会遇到的:

    1062 错误是插入数据时唯一键冲突;

    1032错误是删除数据时找不到行。

    因此,可以把slave_skip_errors设置为“1032,1062”,这样中间碰到这两个错误时就直接跳过


    2、GTID

    通过sql_slave_skip_counter跳过事务和通过slave_skip_errors 忽略错误的方法,虽然都最终可以建立从库B和主库A'的主备关系,但这两种操作都很复杂,而且容易出错,所以MySQL5.6版本引入了GTID,彻底解决了这个困难。

    GTID的全程是Global Transaction Identifier,也就是全局事务ID,是一个事务在提交的时候生成的,是这个事务的唯一标识。它由两部分组成,格式是:GTID=server_uuid:gno.

    其中:server_uuid是一个实例第一次启动时自动生成的,是一个全局唯一的值;

    gno是一个整数,初始值是1,每次提交事务的时候分配给这个事务,并加1.

    在MySQL的官方文档里,GTID格式是这么定义的:

    GTID=source_id:transaction_id

    GTID模式的启动:在启动一个MySQL实例的时候,加上参数gtid_mode=on 和enforce_gtid_consistency=on。

    在GTID模式下,每个事务都会跟一个GTID——对应。这个GTID有两种生成方式,而使用哪种方式取决于session变量gtid_next的值。

    1、如果gtid_next=automatic,代表使用默认值。这时,MySQL就会把server_uuid:gno分配给这个事务   。

        a、记录binlog的时候,先记录一行 SET @@SESSION.GTID_NEXT='server_uuid:gno';

        b、把这个GTID加入本实例的GTID集合。

    2、 如果gtid_next是一个指定的GTID的值,比如通过set gtid_next='current_gtid'指定为current_gtid,那么就有两种可能:

        a、如果current_gtid已经存在于实例的GTID集合中,接下来执行的这个事务会直接被系统忽略;

        b、如果current_gtid没有存在于实例的GTID集合中,就将这个current_gtid分配给接下来要执行的事务,也就是说系统不需要给这个事务生成新的GTID,因此gno也不用加1

    GTID实例:

    CREATE TABLE `t` (

      `id` int(11) NOT NULL,

      `c` int(11) DEFAULT NULL,

      PRIMARY KEY (`id`)

    ) ENGINE=InnoDB;

    insert into t values(1,1);

    假设,现在这个实例X是另外一个实例Y的从库,并且此时在实例Y上执行了下面这条语句:

    insert into t values(1,1);

    并且,这条语句在实例Y上的GTID是: aaaaaaaa-cccc-dddd-eeee-ffffffffffff:10.

    那么,实例X作为Y的从库,就要同步这个事务过来执行,显然会出现主键冲突,导致实例X的同步线程停止。

    处理方法就是,可以执行下面的这个语句序列:

    set gtid_next='aaaaaaaa-cccc-dddd-eeee-ffffffffffff:10'; 

    begin; commit; 

    set gtid_next=automatic; 

    start slave;   

    其中,前三条语句的作用,是通过提交一个空事务,把这个GTID加到实例X的GTID集合中。这样,再执行start slave命令让同步县城执行起来的时候,虽然实例X上还是会继续执行实例Y传过来的事务,但是由于 'aaaaaaaa-cccc-dddd-eeee-ffffffffffff:10'已经存在于实例X的GTID集合中了,所以实例X就会直接跳过这个事务,就不会再出现主键冲突的错误。

    在上面的这个语句序列中,start slave命令之前还有一句 set gtid_next=automatic。这句话的作用是“恢复GTID的默认分配行为”,也就是说如果之后有新的事务再执行,就还是按照原来的分配方式,继续分配gno=3.

    相关文章

      网友评论

          本文标题:第三十二节、主库出问题了,从库怎么办?

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