Репликация MySQL - ведомый постоянно отстает от хозяина


12

Я использую MySQL-5.1.50 с настройкой репликации Master-Slave.

Большую часть времени раб отстает от хозяина.

Когда я бегу show processlist;, нет запроса, который занимает много времени. Я включил slow_logтакже. Тем не менее, он не находит медленный запрос.

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

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

Мне нужна срочная помощь, так как эта проблема сохраняется в течение последних 20 дней.


Ответы:


20

Seconds_Behind_Master действительно похож на просмотр прошлого через путешествие во времени.

Думайте об этом так:

  • Солнце в 93 000 000 миль от Земли
  • Скорость света 186 000 миль / с
  • Простое деление показывает, что свет Солнца достигает Земли примерно за 500 секунд (8 минут 20 секунд)
  • Когда вы смотрите на Солнце, вы на самом деле не видите Солнца. Вы видите, где это было 8 минут 20 секунд назад.

Аналогичным образом, кажется, что Мастер обрабатывает много запросов одновременно.

Вы оглядываетесь на Раба, бежите, SHOW SLAVE STATUS\Gи он говорит 200 для Seconds_Behind_Master. Как рассчитывается это число? Время часов ведомого (UNIX_TIMESTAMP (NOW ()) - TIMESTAMP запроса, когда он был выполнен и записан в двоичном журнале мастера.

Есть еще один показатель, на который стоит обратить внимание Seconds_Behind_Master. Эта метрика называется Relay_Log_Space. Это представляет сумму всех байтов для всех файлов реле на ведомом устройстве. По умолчанию самый большой одиночный релейный журнал ограничен 1 ГБ. Если Relay_Log_Spaceэто менее 1 ГБ, это означает, что многие длительные запросы выполняются на Master параллельно. К сожалению, из-за однопоточного SQL-потока репликации запросы выполняются один за другим.

Например, предположим, что у вас есть следующий сценарий на Master:

  • Журнал медленных запросов включен
  • 20 запросов выполняются параллельно на Мастер
  • Каждый запрос занял 3 секунды
  • Каждый запрос записывается в основной двоичный журнал с одной и той же отметкой времени.

Когда ведомый читает эти запросы из своего журнала ретрансляции и обрабатывает их один за другим

  • Часы Раба будут двигаться
  • TIMESTAMP для каждого из 20 запросов будет идентичным
  • разница будет увеличиваться за 3 секунды до завершения запроса
  • это приводит к 60 секундам для Seconds_Behind_Master

Что касается Slow Log, по умолчанию long_query_time составляет 10 секунд. Если все ваши запросы в журналах ретрансляции меньше 10 секунд, вы никогда ничего не поймаете в журнале медленных запросов.

У меня есть следующие рекомендации для главного и подчиненного серверов

ДАЛЬНЕЙШЕЕ УСТРАНЕНИЕ НЕИСПРАВНОСТЕЙ

Если вы хотите увидеть запросы, вызывающие задержку воспроизведения, сделайте следующее:

  • SHOW SLAVE STATUS\G
  • Получить имя релейного журнала от Relay_Log_File
  • STOP SLAVE;
  • START SLAVE;
  • В ОС cd /var/lib/mysqlили везде , где записываются логи ретрансляции
  • Сбросить релейный журнал в текстовый файл

Например, давайте сделаем SHOW SLAVE STATUS\G

               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.64.51.149
                  Master_User: replicant
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000009
          Read_Master_Log_Pos: 1024035856
               Relay_Log_File: relay-bin.000030
                Relay_Log_Pos: 794732078
        Relay_Master_Log_File: mysql-bin.000009
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB: search_cache
           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: 1024035856
              Relay_Log_Space: 794732271
              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
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 106451149

Если я запускаю STOP SLAVE; START SLAVE;, журнал реле закрывается и открывается новый. Тем не менее, вы хотите relay-bin.000030.

Сбросьте содержимое следующим образом:

cd /var/lib/mysql
mysqlbinlog relay-bin.000030 > /root/RelayLogQueries.txt
less /root/RelayLogQueries.txt

Теперь вы можете видеть запросы, которые Slave пытается обработать. Вы можете использовать эти запросы в качестве отправной точки для настройки.


Начиная с версии 5.7 MySQL может применять изменения к ведомым устройствам многопоточным способом. Соответствующую документацию можно найти здесь: dev.mysql.com/doc/refman/5.7/en/replication-options-slave.html
edigu

2

Какой двоичный формат журнала вы используете? Вы используете ROW или ЗАЯВЛЕНИЕ?
" SHOW GLOBAL VARIABLES LIKE 'binlog_format';"

Если вы используете ROW в качестве формата binlog, убедитесь, что все ваши таблицы имеют первичный или уникальный ключ:
SELECT t.table_schema,t.table_name,engine FROM information_schema.tables t INNER JOIN information_schema .columns c on t.table_schema=c.table_schema and t.table_name=c.table_name and t.table_schema not in ('performance_schema','information_schema','mysql') GROUP BY t.table_schema,t.table_name HAVING sum(if(column_key in ('PRI','UNI'), 1,0)) =0;

Если вы выполняете, например, одну инструкцию удаления на главном сервере, чтобы удалить 1 миллион записей в таблице без PK или уникального ключа, то только одна полная проверка таблицы будет выполняться на стороне главного устройства, что не имеет места на ведомом устройстве.
Когда используется ROW binlog_format, MySQL записывает изменения строк в двоичные журналы (а не как оператор, такой как STATEMENT binlog_format), и это изменение будет применяться к боковой строке ведомого устройства, что означает, что будет выполнено полное сканирование таблицы на 1 миллион на подчиненном устройстве, чтобы отразить только один оператор удаления на ведущем устройстве, и это вызывает проблему отставания подчиненного устройства.


0

Значение seconds_behind_master в SHOW SLAVE STATUS представляет собой разницу между системным временем на ведущем устройстве, которое было сохранено, когда событие было первоначально выполнено и записано в двоичном журнале ..., и системным временем на ведомом устройстве, когда событие выполняется там.

Секунды позади мастера будут давать неправильные значения, если часы двух систем не синхронизированы.


В MySQL 5.5 и более ранних версиях выполнение событий репликации является однопоточным на ведомой стороне. В «SHOW FULL PROCESSLIST» должно быть два потока, работающих как «системный пользователь» - один получает события от мастера, другой выполняет запросы. Если ведомое устройство отстает, этот поток должен показать, какой запрос выполняется в данный момент. Взгляните на это, а также посмотрите на статистику вашего диска / памяти / процессора на предмет нехватки ресурсов.
Майкл - sqlbot
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.