Назад | Перейти на главную страницу

Спорадический сбой процесса репликации MySQL ведущий-ведомый

Мне было интересно, сталкивался ли кто-нибудь с этим и, возможно, может дать некоторое представление об этой проблеме.

У нас есть плановая репликация MySQL master-slave. Таблицы - это MyISAM, и мастер может стать достаточно активным для чтения / записи. Мы используем подчиненный экземпляр для выполнения полных ежедневных резервных копий, чтобы избежать остановки главного сервера. В процессе резервного копирования выполняется следующее:

STOP SLAVE SQL_THREAD 
mysqlhotcopy all tables 
START SLAVE SQL_THREAD

Время от времени (примерно раз в месяц) репликация прерывается с различными сообщениями об ошибках, указывающими на поврежденный запрос или файл журнала. Вот то, что произошло вчера вечером:

mysql> show slave status \G
*************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: server8
                Master_User: nexus8
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: bin.000045
        Read_Master_Log_Pos: 581644327
             Relay_Log_File: relay.000086
              Relay_Log_Pos: 94131
      Relay_Master_Log_File: bin.000045
           Slave_IO_Running: Yes
          Slave_SQL_Running: No
            Replicate_Do_DB:
        Replicate_Ignore_DB:
         Replicate_Do_Table:
     Replicate_Ignore_Table:
    Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
                 Last_Errno: 1064
                 Last_Error: Error 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '138070603'£' at line 1' on query. Default database: 'wtsdb'. Query: 'UPDATE fill SET clearing_fee='0.0E id='138070603'£'
               Skip_Counter: 0
        Exec_Master_Log_Pos: 4164743
            Relay_Log_Space: 577574251
            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

Я следую следующей процедуре, чтобы исправить указанную выше ошибку и возобновить репликацию:

stop slave;
change master to MASTER_LOG_POS = 4164743, MASTER_LOG_FILE = 'bin.000045';
start slave;

У нас есть несколько серверов, настроенных таким образом, и все они время от времени прекращают репликацию с аналогичной ошибкой. Мы будем очень благодарны за любые советы о том, как решить эту проблему.

Обновить:

Читая отличная статья, предложенная pQd (в частности, раздел 3.5), мне кажется вполне возможным, что я столкнулся с повреждением журнала реле, которое может «сделать операторы не анализируемыми». По-видимому, это может произойти, но тогда это укажет на ошибку в коде репликации MySQL. Я не могу воспроизвести эту проблему, но это происходит не реже одного раза в месяц для каждого ведомого устройства в нашей производственной среде.

Вот еще две ошибки для справки:

*************************** 1. row *************************** 
             Slave_IO_State: Waiting for master to send event 
                Master_Host: server10
                Master_User: nexus10 
                Master_Port: 3306 
              Connect_Retry: 60 
            Master_Log_File: bin.000008 
        Read_Master_Log_Pos: 1034654844 
             Relay_Log_File: relay.001392 
              Relay_Log_Pos: 109929 
      Relay_Master_Log_File: bin.000008 
           Slave_IO_Running: Yes 
          Slave_SQL_Running: No 
            Replicate_Do_DB: 
        Replicate_Ignore_DB: 
         Replicate_Do_Table: 
     Replicate_Ignore_Table: 
    Replicate_Wild_Do_Table: 
Replicate_Wild_Ignore_Table: 
                 Last_Errno: 1064 
                 Last_Error: Error 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server versio n for the right syntax to use near '' at line 1' on query. Default database: 'avidb'. Query: 'DELETE FROM reconciliat' 
               Skip_Counter: 0 
        Exec_Master_Log_Pos: 1026067551 
            Relay_Log_Space: 8697758 
            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 *************************** 
             Slave_IO_State: Waiting for master to send event 
                Master_Host: server8
                Master_User: nexus8 
                Master_Port: 3306 
              Connect_Retry: 60 
            Master_Log_File: bin.000019 
        Read_Master_Log_Pos: 476189428 
             Relay_Log_File: relay.000163 
              Relay_Log_Pos: 98576 
      Relay_Master_Log_File: bin.000019 
           Slave_IO_Running: Yes 
          Slave_SQL_Running: No 
            Replicate_Do_DB: 
        Replicate_Ignore_DB: 
         Replicate_Do_Table: 
     Replicate_Ignore_Table: 
    Replicate_Wild_Do_Table: 
Replicate_Wild_Ignore_Table: 
                 Last_Errno: 1064 
                 Last_Error: Error 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1' on query. Default database: 'wtsdb'. Query: 'UPDATE requestlog SET id='2173589',start_time='2009-08-18 04:59:10',end_time='2009-08-18 04:59:10',ip='X.X.X.X',session='hkacn7d54',lock_wait_time='0',unmarshal_time='0.00057435035705566',unmarshaled_objects='30',data_sync_time='0',page_process_time='0',memory_used='1572864',memory_used_peak='1572864',method='GET',request='/report.php',request_parameters='
groupId = -4 
startDate = 2009-08-17 
reportType = trades 
accountId = 2409 
endDate = 2009-08-17',progress_percent='0',progress_text='' WHERE id='2173588'' 
               Skip_Counter: 0 
        Exec_Master_Log_Pos: 186172755 
            Relay_Log_Space: 290116589 
            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 

Дважды проверьте, что ваши наборы символов в базах данных и соединениях соответствуют вашим ожиданиям - ваша репликация, задушенная оператором с символом, отличным от ASCII, сразу вызывает подозрение.

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

К сожалению, вы также должны убедиться, что версии сервера для ведущего и ведомого одинаковы. Недавно я столкнулся со странным случаем, когда у нас был плохой SQL, пытающийся обновить числовой столбец, не равный NULL, до NULL. В версии, в которой работал мастер, MySQL молча преобразовал его в 0, но в версии, в которой выполнялась реплика, это было ошибкой.

Кроме того, вместо того, чтобы делать CHANGE MASTER чтобы исправить реплику, вы должны сделать

STOP SLAVE;
[correct and execute whatever statement is the problem]
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;

http://dev.mysql.com/doc/refman/5.1/en/set-global-sql-slave-skip-counter.html

Возможно ли, что некоторые из ваших запросов на обновление небезопасны для репликации? посмотрите, например Вот - пункт 3.1.

это хорошая привычка время от времени сравнивать ваши данные между ведущим и ведомым [неудачно, вы используете myisam, а не innodb] - например, с mk-table-контрольная сумма из мааткит.

ps: еще две ссылки: 1 и 2.