MySQL · 3 min read · Nov 02, 2025

Как восстановить репликацию MySQL

Если вы настроили репликацию MySQL, вы, вероятно, знаете эту проблему: иногда возникают недействительные запросы MySQL, которые приводят к тому, что репликация больше не работает. В этом кратком руководстве я объясняю, как вы можете восстановить репликацию на слейве MySQL без необходимости настраивать её с нуля. Это руководство предназначено для MySQL и MariaDB.

1 Определение проблемы

Чтобы выяснить, работает ли репликация или нет, и что привело к её остановке, вы можете взглянуть на логи. На Debian, например, MySQL записывает логи в /var/log/syslog:

grep mysql /var/log/syslog
server1:/home/admin# grep mysql /var/log/syslog  
MAR 19 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Slave: Error 'Table 'mydb.taggregate_temp_1212047760' doesn't exist' on query. Default database: 'mydb'. Query: 'UPDATE thread AS thread,taggregate_temp_1212047760 AS aggregate  
MAR 19 09:56:08 http2 mysqld[1380]: ^ISET thread.views = thread.views + aggregate.views  
MAR 19 09:56:08 http2 mysqld[1380]: ^IWHERE thread.threadid = aggregate.threadid', Error_code: 1146  
MAR 19 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.001079' position 203015142  
server1:/home/admin#

Вы можете увидеть, какой запрос вызвал ошибку и на какой позиции в логе остановилась репликация.

Чтобы убедиться, что репликация действительно не работает, войдите в MySQL:

mysql -u root -p

В оболочке MySQL выполните:

mysql> SHOW SLAVE STATUS \G

Если одно из значений Slave_IO_Running или Slave_SQL_Running установлено в No, то репликация сломана:

mysql> SHOW SLAVE STATUS \G  
************************* 1. row ***********************  
             Slave_IO_State: Waiting for master to send event  
                Master_Host: 1.2.3.4  
                Master_User: slave_user  
                Master_Port: 3306  
              Connect_Retry: 60  
            Master_Log_File: mysql-bin.001079  
        Read_Master_Log_Pos: 269214454  
             Relay_Log_File: slave-relay.000130  
              Relay_Log_Pos: 100125935  
      Relay_Master_Log_File: mysql-bin.001079  
           Slave_IO_Running: Yes  
          Slave_SQL_Running: No  
            Replicate_Do_DB: mydb  
        Replicate_Ignore_DB:  
         Replicate_Do_Table:  
      Replicate_Ignore_Table:  
    Replicate_Wild_Do_Table:  
Replicate_Wild_Ignore_Table:  
                 Last_Errno: 1146  
                 Last_Error: Error 'Table 'mydb.taggregate_temp_1212047760' doesn't exist' on query. Default database: 'mydb'.  
Query: 'UPDATE thread AS thread,taggregate_temp_1212047760 AS aggregate  
        SET thread.views = thread.views + aggregate.views  
        WHERE thread.threadid = aggregate.threadid'  
               Skip_Counter: 0  
        Exec_Master_Log_Pos: 203015142  
            Relay_Log_Space: 166325247  
            Until_Condition: None  
             Until_Log_File:  
              Until_Log_Pos: 0  
         Master_SSL_Allowed: No  
         Master_SSL_CA_File:  
         Master_SSL_CA_Path:  
            Master_SSL_Cert:  
          Master_SSL_Cipher:  
             Master_SSL_Key:  
      Seconds_Behind_Master: NULL  
1 row in set (0.00 sec)  
   
mysql>

2 Восстановление репликации MySQL

Просто для уверенности, мы останавливаем слейв:

mysql> STOP SLAVE;

Исправить проблему на самом деле довольно просто. Мы говорим слейву просто пропустить недействительный SQL-запрос:

mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;

Это говорит слейву пропустить один запрос (который является недействительным и вызвал остановку репликации). Если вы хотите пропустить два запроса, вы можете использовать SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 2; вместо этого и так далее.

Вот и всё. Теперь мы можем снова запустить слейв…

mysql> START SLAVE;

… и проверить, работает ли репликация снова:

mysql> SHOW SLAVE STATUS \G
mysql> SHOW SLAVE STATUS \G  
*********************** 1. row *************************  
             Slave_IO_State: Waiting for master to send event  
                Master_Host: 1.2.3.4  
                Master_User: slave_user  
                Master_Port: 3306  
              Connect_Retry: 60  
            Master_Log_File: mysql-bin.001079  
        Read_Master_Log_Pos: 447560366  
             Relay_Log_File: slave-relay.000130  
              Relay_Log_Pos: 225644062  
      Relay_Master_Log_File: mysql-bin.001079  
           Slave_IO_Running: Yes  
          Slave_SQL_Running: Yes  
            Replicate_Do_DB: mydb  
        Replicate_Ignore_DB:  
         Replicate_Do_Table:  
      Replicate_Ignore_Table:  
    Replicate_Wild_Do_Table:  
Replicate_Wild_Ignore_Table:  
                 Last_Errno: 0  
                 Last_Error:  
               Skip_Counter: 0  
        Exec_Master_Log_Pos: 447560366  
            Relay_Log_Space: 225644062  
            Until_Condition: None  
             Until_Log_File:  
              Until_Log_Pos: 0  
         Master_SSL_Allowed: No  
         Master_SSL_CA_File:  
         Master_SSL_CA_Path:  
            Master_SSL_Cert:  
          Master_SSL_Cipher:  
             Master_SSL_Key:  
      Seconds_Behind_Master: 0  
1 row in set (0.00 sec)  
   
mysql>

Как видите, оба значения Slave_IO_Running и Slave_SQL_Running теперь установлены в Yes.

Теперь покиньте оболочку MySQL…

mysql> quit;

… и снова проверьте лог:

grep mysql /var/log/syslog
server1:/home/admin# grep mysql /var/log/syslog  
MAR 19 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Slave: Error 'Table 'mydb.taggregate_temp_1212047760' doesn't exist' on query. Default database: 'mydb'. Query: 'UPDATE thread AS thread,taggregate_temp_1212047760 AS aggregate  
MAR 19 09:56:08 http2 mysqld[1380]: ^ISET thread.views = thread.views + aggregate.views  
MAR 19 09:56:08 http2 mysqld[1380]: ^IWHERE thread.threadid = aggregate.threadid', Error_code: 1146  
MAR 19 09:56:08 http2 mysqld[1380]: 080529 9:56:08 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.001079' position 203015142  
MAR 19 11:42:13 http2 mysqld[1380]: 080529 11:42:13 [Note] Slave SQL thread initialized, starting replication in log 'mysql-bin.001079' at position 203015142, relay log '/var/lib/mysql/slave-relay.000130' position: 100125935  
server1:/home/admin#

Последняя строка говорит о том, что репликация снова началась, и если вы не видите ошибок после этой строки, всё в порядке.

3 Ссылки

Share: X/Twitter LinkedIn

Get new posts in your inbox

No spam. Unsubscribe anytime.