MySQL Replication-ведомое отставание от ведущего

У меня есть репликация master/slave на моей БД MySql.

мой подчиненный DB был отключен в течение нескольких часов и снова вернулся (мастер был все время), при выдаче show slave status Я вижу, что раб X секунд позади хозяина.

проблема в том, что раб, похоже, не догоняет хозяина, X секунд позади мастера, похоже, не падает...

любые идеи о том, как я могу помочь рабу догнать?

8 ответов


вот идея

для того, чтобы вы знали, что MySQL полностью обрабатывает SQL из журналов ретрансляции. Попробуйте следующее:

STOP SLAVE IO_THREAD;

это остановит репликацию от загрузки новых записей из Мастера в его журналы ретрансляции.

другой поток, известный как поток SQL, продолжит обработку инструкций SQL, загруженных из Мастера.

при выполнении SHOW SLAVE STATUS\G, следите за Exec_Master_Log_Pos. Запустить SHOW SLAVE STATUS\G еще раз. Если Exec_Master_Log_Pos не двигается через минуту, вы можете идти вперед run START SLAVE IO_THREAD;. Это может уменьшить количество Seconds_Behind_Master.

кроме этого, вы действительно ничего не можете сделать, кроме как:

  • Репликация Доверия
  • монитор Seconds_Behind_Master
  • монитор Exec_Master_Log_Pos
  • выполнить SHOW PROCESSLIST;, обратите внимание на поток SQL, чтобы узнать, обрабатывает ли он длительные запросы.

имейте в виду, что при выполнении SHOW PROCESSLIST; при работающей репликации должно быть два подключения к БД с именем пользователя system user. Одно из этих подключений к БД будет иметь текущую инструкцию SQL, обрабатываемую репликацией. До тех пор, пока при каждом запуске SHOW PROCESSLIST;, вы можете доверять mysql, все еще реплицируется должным образом.


какой формат двоичного журнала вы используете ? Вы используете строку или оператор ?

SHOW GLOBAL VARIABLES LIKE 'binlog_format';

Если вы используете строку в качестве формата 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;

Если вы выполняете, например, один оператор delete на ведущем устройстве для удаления 1 миллиона записей в таблице без ПК или уникального ключа, то только одно полное сканирование таблицы будет происходить на стороне ведущего устройства, чего не происходит на ведомом устройстве.

когда строка binlog_format используется MySQL пишет строки изменения в двоичные журналы (не заявление, как заявление binlog_format) и эти изменения будут применены на ведомой стороне построчно, что означает 1 млн полное сканирование таблицы будет происходить на раба, чтобы он отражал только одну удалить заявление на учителя и что вызывает рабом отстает проблему.


"секунды позади" - не очень хороший инструмент, чтобы узнать, насколько вы отстаете от мастера. Что он говорит: "запрос, который я только что выполнил, был выполнен X секунд назад на мастере". Это не значит, что в следующую секунду вы догоните мастера и окажетесь прямо за ним.

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


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


Если вы используете таблицы INNODB, проверьте, что у вас есть innodb_flush_log_at_trx_commit к значению, отличному от 0 на ведомом устройстве.

http://dev.mysql.com/doc/refman/4.1/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit


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

мы изменили конфигурацию нашего раба, чтобы быть более безопасным для сбоев:

sync_binlog = 1
sync_master_info = 1
relay_log_info_repository = TABLE
relay_log_recovery = 1

Я думаю, что особенно sync_binlog = 1 вызывает проблему, так как спецификации этого ведомого устройства не так быстры, как в master. Этот параметр конфигурации заставляет ведомого хранить каждую транзакцию в двоичном lo до их выполнения (вместо транзакций по умолчанию каждые 10k).

после отключения этих параметров конфигурации снова к их значениям по умолчанию я вижу, что ведомый снова догоняет.


просто добавить выводы в моем подобном случае.

было несколько массовых временных таблиц insert/update / delete происходили в master, которые занимали большую часть пространства от Relay log in slave. И в Mysql 5.5, поскольку он однопоточный, CPU всегда был в 100% и занял много времени для обработки этих записей.

все, что я сделал, это добавил эту строку в mysql cnf file

replicate-ignore-table=<dbname>.<temptablename1>
replicate-ignore-table=<dbname>.<temptablename2>

и все снова стало гладким.

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

cd /var/lib/mysql
mysqlbinlog relay-bin.000010 > /root/RelayQueries.txt
less /root/RelayQueries.txt

Если у вас есть несколько схем, рассмотрите использование многопоточной подчиненной репликации.Это относительно новая функция.

Это можно сделать динамически без остановки сервера.Просто остановите ведомый поток sql.

STOP SLAVE SQL_THREAD;
SET GLOBAL slave_parallel_threads = 4;
START SLAVE SQL_THREAD;