你所不知道的sql

    xiaoxiao2021-03-25  114

          如果你使用过mysql主从架构,那么你很有可能就使用过sql_slave_skip_counter来处理从库异常的问题。如果你没有启用GTID,遇到从库因为执行某个语句报错,你可以通过如下方式来恢复从库复制线程

    stop slave sql_thread; >>此步可以忽略(因为从库报错执行语句失败,此时sql_thread线程已经停止)

    set global sql_slave_skip_counter=N;

    start slave;

          我们可能对上面的处理方法烂熟于心,但是我们真的了解sql_slave_skip_counter吗?下面就来仔细的学习一下sql_slave_skip_counter:

    关于sql_slave_skip_counter官方文档中有如下描述:

    SET GLOBAL sql_slave_skip_counter = N This statement skips the next N events from the master. This is useful for recovering from replication stops caused by a statement. >>执行该命令后从库会从当前位置跳过N个events。这对恢复因为某个语句在从库无法执行导致从库复制暂停的故障很有用。 This statement is valid only when the slave threads are not running. Otherwise, it produces an error. >>只有当从库的sql_thread线程停止时,才能执行 set global sql_slave_skip_counter=n;语句,否则会报错。 When using this statement, it is important to understand that the binary log is actually organized as a sequence of groups known as event groups. Each event group consists of a sequence of events. >>想要更好的理解sql_slave_skip_counter你需要明白mysql 的binlog是由一系列的event group组成的。每个event group由一系列的event组成。 For transactional tables, an event group corresponds to a transaction. >>对于事物表而言,一个event group对应一个事物。 For nontransactional tables, an event group corresponds to a single SQL statement. >>对于非事物表而言,一个event group对应一个单独的sql Note A single transaction can contain changes to both transactional and nontransactional tables. >> When you use SET GLOBAL sql_slave_skip_counter to skip events and the result is in the middle of a group, the slave continues to skip events until it reaches the end of the group. Execution then starts with the next event group. >>当你使用set global sql_slave_skip_counter 来跳过events,如果最后你处在一组event group中,那么会接着跳过该event group剩下的event,直到下个event group的开始

    ### comment ###      Setting this variable isn't like setting other server variables: you can't read the variable back again as @@sql_slave_skip_counter, and it isn't really a "global variable." Rather, it's a variable that only the slave thread reads.  >>sql_slave_skip_counter参数不像其他参数,你无法通过@@sql_slave_skip_counter来查看该查参数。实际上它并不是真正意义上的global参数,只有设置它的线程能看到。     When you restart the slave threads again with START SLAVE, the slave skips statements and decrements the variable until it reaches 0, at which point it begins executing statements again. You can watch this happening by executing SHOW SLAVE STATUS, where the variable's value appears in the Skip_Counter column. This is the only place you can see its value.  >>你设置过sql_slave_skip_counter=N,重启slave 复制线程后,从库开始跳过event,每跳过一个event,N就减去1,直到N变成0,当N变成0后从库就开始执行当前的语句。你可以查看show slave status;中的Skip_Counter列观察该过程。     The effect is that the setting isn't persistent. If you set it to 1, start the slave, and the slave has an error in replication sometime later, the variable won't still be set to 1. It'll be 0. At that point, if you want the slave to skip the statement that caused the error, you'll have to set it to 1 again.  >>sql_slave_skip_counter的设置不是持久的,如果你设置该参数为1,然后重启sql_thread线程,在这之后你的从库因为某个sql无法执行导致报错,你还需要再次设置sql_slave_skip_counter。

    NOTE:

    1. 设置sql_slave_skip_counter=N后,从当前执行位置开始跳过event,每跳过一个event,N会减去1,直到N变成0,开始重新执行语句。当N减小到1时,如果此时处理一个事务中(假设该事务有多个sql语句组成),其跳过事务中下一个event(非commit event)时N依然为1(不会变为0)。直到跳过这个事物所有event,N变为0,然后从当前位置开始执行复制。

    2. 简单的说就是不论你怎么设置sql_slave_skip_counter=N参数,mysql都会跳过多个完整个事务然后开始执行,不会从某个事物中的某个event开始执行复制。这就保证事物的原子性

    参考:http://dinglin.iteye.com/blog/1236330

    转载请注明原文地址: https://ju.6miu.com/read-14152.html

    最新回复(0)