Репликация MariaDB slave зависает без видимой причины.

Вопрос или проблема

У меня простая репликация 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-потоки, которые управляют чтением и применением изменений.

Проблемы в репликации могут возникнуть по множеству причин:

  1. Зависание SQL-потока: Зачастую это связано с блокировкой на уровне транзакций или мертвых зависимостях (deadlock).

  2. Проблемы с сетевым соединением: Например, потеря пакетов или повреждение данных может приводить к сбоям в репликации.

  3. Повреждение релейных логов: Нарушения в записи релейных логов могут помешать репликации завершить свои операции.

  4. Баги в версии MariaDB: Иногда проблема может быть вызвана ошибкой в самой программе, которая решается обновлением до последних патчей.

  5. Ограничения ресурсов: Недостаток ресурсов (ЦП, ОЗУ или Диск) может тормозить репликацию, особенно если происходит блокировка соединений.

Пример

Согласно приведенным статусам, обе репликации (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. Это может быть вызвано ошибками в транзакциях или специфическим шаблоном рекурсивных изменений данных.

Применение (решение)

  1. Проверка и тестирование блокировок:

    • Используйте команду SHOW ENGINE INNODB STATUS; для проверки блокировок транзакций.
    • Если проблема заключена в блокировке транзакции, это может быть частично решено с помощью оптимизации индексов в проблемной таблице sessions.
  2. Анализ релейных логов:

    • Проверьте целостность релейных логов и убедитесь, что повреждения не помешали репликации. Возможно, стоит очистить существующие релейные логи и начать с новой позиции лога.
  3. Обновление MariaDB:

    • Проверьте наличие обновлений MariaDB, так как ваша проблема может быть решена в свежих патчах.
  4. Проверка сетевых подключений:

    • Убедитесь, что проблем с сетевыми подключениями нет; они могут быть причиной потери пакетов и, как следствие, зависания репликации.
  5. Анализ таблицы sessions:

    • Возможен сценарий, когда удалить или оптимизировать эти строки будет более эффективно за пределами репликации.
  6. Увеличение ресурсов:

    • Если вы находитесь на сервере с ограниченными ресурсами, составьте план по увеличению доступных ресурсов, чтобы избежать проблем с ресурсами в будущем.

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

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

Оцените материал
Добавить комментарий

Капча загружается...