Вопрос или проблема
У меня простая репликация MySQL (master-slave) с использованием MariaDB 10.11.6-MariaDB-0+deb12u1-log
. Настройка работает без проблем около 1 года, но последние несколько дней у меня серьезные проблемы на слейве. Репликация просто останавливается. На сервере нет нагрузки, и я не могу найти ошибок в syslog. Ниже приведены несколько выходных данных статуса:
MariaDB [(none)]> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: dbx.example.com
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: dbx-bin.000006
Read_Master_Log_Pos: 941533811
Relay_Log_File: mysqld-relay-bin.000008
Relay_Log_Pos: 359698695
Relay_Master_Log_File: dbx-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Rewrite_DB:
Replicate_Do_DB:
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: 385969315
Relay_Log_Space: 2649744375
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: 15560
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: 1
Master_SSL_Crl:
Master_SSL_Crlpath:
Using_Gtid: Slave_Pos
Gtid_IO_Pos: 0-1-5319587
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: optimistic
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Waiting for room in worker thread event queue
Slave_DDL_Groups: 0
Slave_Non_Transactional_Groups: 0
Slave_Transactional_Groups: 3623998
1 row in set (0.000 sec)
MariaDB [(none)]> SHOW FULL PROCESSLIST;
+-------+-------------+-----------+--------------+--------------+-------+---------------------------------------------------------+-----------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+-------+-------------+-----------+--------------+--------------+-------+---------------------------------------------------------+-----------------------+----------+
| 40 | system user | | NULL | Slave_IO | 33807 | Waiting for master to send event | NULL | 0.000 |
| 42 | system user | | NULL | Slave_worker | 16416 | Waiting for prior transaction to commit | NULL | 0.000 |
| 43 | system user | | NULL | Slave_worker | 16416 | Waiting for prior transaction to commit | NULL | 0.000 |
| 44 | system user | | NULL | Slave_worker | 16416 | Waiting for prior transaction to commit | NULL | 0.000 |
| 45 | system user | | NULL | Slave_worker | 16416 | Waiting for prior transaction to commit | NULL | 0.000 |
| 46 | system user | | NULL | Slave_worker | 16416 | Waiting for prior transaction to commit | NULL | 0.000 |
| 47 | system user | | NULL | Slave_worker | 16416 | Waiting for prior transaction to commit | NULL | 0.000 |
| 48 | system user | | my_database | Slave_worker | 16416 | Delete_rows_log_event::find_row(-1) on table `sessions` | NULL | 0.000 |
| 49 | system user | | NULL | Slave_worker | 16416 | Waiting for prior transaction to commit | NULL | 0.000 |
| 41 | system user | | NULL | Slave_SQL | 16469 | Waiting for room in worker thread event queue | NULL | 0.000 |
| 58753 | root | localhost | NULL | Sleep | 194 | | NULL | 0.000 |
| 58766 | root | localhost | NULL | Query | 0 | starting | show full processlist | 0.000 |
+-------+-------------+-----------+--------------+--------------+-------+---------------------------------------------------------+-----------------------+----------+
12 rows in set (0.000 sec)
MariaDB [(none)]> SHOW RELAYLOG EVENTS IN 'mysqld-relay-bin.000008' FROM 359698695 LIMIT 10;
+-------------------------+-----------+----------------+-----------+-------------+----------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+-------------------------+-----------+----------------+-----------+-------------+----------------------------------------+
| mysqld-relay-bin.000008 | 359698695 | Gtid | 1 | 385969357 | BEGIN GTID 0-1-3691915 |
| mysqld-relay-bin.000008 | 359698737 | Table_map | 1 | 385981485 | table_id: 9014 (my_database.sessions) |
| mysqld-relay-bin.000008 | 359698809 | Delete_rows_v1 | 1 | 385989539 | table_id: 9014 |
| mysqld-relay-bin.000008 | 359706863 | Delete_rows_v1 | 1 | 385997628 | table_id: 9014 |
| mysqld-relay-bin.000008 | 359714952 | Delete_rows_v1 | 1 | 386005693 | table_id: 9014 |
| mysqld-relay-bin.000008 | 359723017 | Delete_rows_v1 | 1 | 386013869 | table_id: 9014 |
| mysqld-relay-bin.000008 | 359731193 | Delete_rows_v1 | 1 | 386021988 | table_id: 9014 |
| mysqld-relay-bin.000008 | 359739312 | Delete_rows_v1 | 1 | 386030079 | table_id: 9014 |
| mysqld-relay-bin.000008 | 359747403 | Delete_rows_v1 | 1 | 386038287 | table_id: 9014 |
| mysqld-relay-bin.000008 | 359755611 | Delete_rows_v1 | 1 | 386046395 | table_id: 9014 |
+-------------------------+-----------+----------------+-----------+-------------+----------------------------------------+
10 rows in set (0.000 sec)
Я уже несколько раз перезапускал репликацию mariabackup, как я обычно это делаю, но в конце концов она всегда останавливается снова. Это происходит с различными типами DML-запросов в разных базах данных и разных таблицах. Есть у кого-нибудь идеи?
Ответ или решение
Конечно, давайте разберемся с проблемой, когда репликация на слейве MariaDB зависает без видимых причин. Мы имеем дело с версией MariaDB 10.11.6, и система работала стабильно около года. Однако в последние дни возникают проблемы, когда репликация останавливается на слейве, несмотря на отсутствие нагрузки на сервер и отсутствие ошибок в системных логах.
Теория
Репликация в MariaDB — это процесс, позволяющий передавать данные с основного сервера (мастера) на подчиненный сервер (слейв), обеспечивая актуальность копий данных на нескольких серверах. Основные компоненты репликации включают IO-потоки и SQL-потоки, которые управляют чтением и применением изменений.
Проблемы в репликации могут возникнуть по множеству причин:
-
Зависание SQL-потока: Зачастую это связано с блокировкой на уровне транзакций или мертвых зависимостях (deadlock).
-
Проблемы с сетевым соединением: Например, потеря пакетов или повреждение данных может приводить к сбоям в репликации.
-
Повреждение релейных логов: Нарушения в записи релейных логов могут помешать репликации завершить свои операции.
-
Баги в версии MariaDB: Иногда проблема может быть вызвана ошибкой в самой программе, которая решается обновлением до последних патчей.
-
Ограничения ресурсов: Недостаток ресурсов (ЦП, ОЗУ или Диск) может тормозить репликацию, особенно если происходит блокировка соединений.
Пример
Согласно приведенным статусам, обе репликации (I/O и SQL) по состоянию выполняются, однако SQL-поток отчего-то зависает, особенное состояние заметно для рабочей нити (Worker Thread), которая ждет завершения предыдущей транзакции. Настораживает и параметр Seconds_Behind_Master
, который показывает значительное отставание в 15560 секунд. Настоящее торможение сконцентрировано вокруг работы системы с таблицей sessions
.
Логи показывают множество Delete_rows_v1
событий для указанной таблицы sessions
, но важно, что процесс Slave_worker
останавливливается на шаге Delete_rows_log_event::find_row(-1)
на таблице sessions
. Это может быть вызвано ошибками в транзакциях или специфическим шаблоном рекурсивных изменений данных.
Применение (решение)
-
Проверка и тестирование блокировок:
- Используйте команду
SHOW ENGINE INNODB STATUS;
для проверки блокировок транзакций. - Если проблема заключена в блокировке транзакции, это может быть частично решено с помощью оптимизации индексов в проблемной таблице
sessions
.
- Используйте команду
-
Анализ релейных логов:
- Проверьте целостность релейных логов и убедитесь, что повреждения не помешали репликации. Возможно, стоит очистить существующие релейные логи и начать с новой позиции лога.
-
Обновление MariaDB:
- Проверьте наличие обновлений MariaDB, так как ваша проблема может быть решена в свежих патчах.
-
Проверка сетевых подключений:
- Убедитесь, что проблем с сетевыми подключениями нет; они могут быть причиной потери пакетов и, как следствие, зависания репликации.
-
Анализ таблицы
sessions
:- Возможен сценарий, когда удалить или оптимизировать эти строки будет более эффективно за пределами репликации.
-
Увеличение ресурсов:
- Если вы находитесь на сервере с ограниченными ресурсами, составьте план по увеличению доступных ресурсов, чтобы избежать проблем с ресурсами в будущем.
Рекомендуется также внимательно следить за журнальными файлами и искать в них несоответствия или странные моменты, сигнализирующие о возможных проблемах. Восстановление полной штатной работы репликации может потребовать массового тестирования конфигурации и понимания глубинных аспектов работы с вашей системой.
Удачи в решении! Если описанные рекомендации не решат проблему, можно рассмотреть возможность привлечения сторонних экспертов для детального анализа на уровне базы данных и сетевых подключений.