Статьи

Синхронизируйте данные MySQL при использовании вольфрамового репликатора

[Эта статья была написана Франциско Борденаве]

Репликация MySQL не идеальна, и иногда наши данные не синхронизируются из-за сбоя в репликации или вмешательства человека. Мы все знакомы с pt-таблицей-контрольной суммой Percona Toolkit и pt-table-sync, чтобы помочь нам проверить и исправить несоответствия данных, но представьте себе следующий сценарий, в котором мы смешиваем регулярную репликацию с  Tungsten Replicator :

вольфрам

У нас есть регулярная репликация от главного (db1) до 4 подчиненных (db2, db3, db4 и db5), но мы также обнаруживаем, что db3 также является ведущим для db4 и db5, используя вольфрамовую репликацию для 1 базы данных, называемой test. Эта настройка в настоящее время работает таким образом, потому что она была развернута некоторое время назад, когда репликация с несколькими источниками была невозможна с использованием обычной репликации MySQL. Это теперь рабочая функция в  MariaDB 10,  а также функция, поставляемая с новым  MySQL 5.7  (еще не выпущена)… в нашем случае это то, что есть :)

Итак, как мы проверяем контрольную сумму и синхронизируем данные, когда у нас есть этот сценарий? Что ж, мы все еще можем достичь этого с помощью этих инструментов, но нам нужно рассмотреть некоторые дополнительные действия:

пт-таблицы контрольной суммы  

Прежде всего, нам нужно понять, что этот инструмент был разработан для проверки таблиц контрольных сумм в обычной среде репликации MySQL, поэтому нам нужно уделить особое внимание тому, как избежать ошибок контрольных сумм, учитывая задержку репликации (да, репликация вольфрама все еще может страдать от задержки репликации). Нам также нужно указать инструменту для обнаружения рабов через dsn, потому что инструмент предназначен для обнаружения реплик с использованием регулярной репликации. Это можно сделать с помощью   функции –plugin .

Мой коллега  Кенни  уже написал  статью  об этом некоторое время назад, но давайте вернемся к ней, чтобы добавить немного графики к нашему делу. Чтобы заставить pt-table-checkum работать должным образом в среде репликатора Tungsten, нам необходимо:
— С помощью этого плагина настроить флаг –plugin   для проверки задержки репликации.
— Используйте  –recursion-method = dsn,  чтобы избежать автоматического обнаружения рабов.

[root@db3]$ pt-table-checksum --replicate=percona.cksums 
            --create-replicate-table
            --no-check-replication-filters 
            --no-check-binlog-format
            --recursion-method=dsn=h=db1,D=percona,t=dsns 
            --plugin=/home/mysql/bin/pt-plugin-tungsten_replicator.pl
            --check-interval=5 
            --max-lag=10 
            -d test
Created plugin from /home/mysql/bin/pt-plugin-tungsten_replicator.pl.
PLUGIN get_slave_lag: Using Tungsten Replicator to check replication lag
Checksumming test.table1: 2% 18:14 remain
Checksumming test.table1: 5% 16:25 remain
Checksumming test.table1: 9% 15:06 remain
Checksumming test.table1: 12% 14:25 remain
Replica lag is 2823 seconds on db5 Waiting.
Checksumming test.table1: 99% 14:25 remain
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
04-28T14:17:19 0 13 279560873 4178 0 9604.892 test.table1

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

пт-таблицы синхронизации

pt-table-sync — это инструмент, который нам нужен для исправления различий в данных, но в этом случае у нас есть две проблемы:
1-pt-table-sync не поддерживает –recursion-method = dsn, поэтому нам нужно передать имена хостов для синхронизации как параметр. Запрос на добавление этого метода рекурсии можно найти  здесь  (надеюсь, он будет добавлен в ближайшее время). Это означает, что нам нужно синхронизировать каждого ведомого отдельно.
2- Из-за 1 мы не можем использовать флаги –replicate, поэтому pt-table-sync потребуется повторно запустить контрольные суммы, чтобы найти и исправить различия. Если контрольная сумма обнаружила различия в более чем 1 таблице, я бы порекомендовал запустить синхронизацию в несколько шагов, pt-table-sync изменяет данные. Мы не хотим слепо просить это исправить наши серверы, верно?

При этом я рекомендую сначала запустить pt-table-sync с флагом –print, чтобы убедиться, что процесс синхронизации будет делать то, что мы хотим, следующим образом:

[root@db3]$ pt-table-sync
           --print
           --verbose
           --databases test -t table1
           --no-foreign-key-checks h=db3 h=db4
# Syncing h=db4
# DELETE REPLACE INSERT UPDATE ALGORITHM START END EXIT DATABASE.TABLE
....
UPDATE `test`.`table1` SET `id`='2677', `status`='open', `created`='2015-04-27 02:22:33', `created_by`='8', `updated`='2015-04-27 02:22:33', WHERE `ix_id`='9585' LIMIT 1 /*percona-toolkit src_db:test src_tbl:table1 src_dsn:h=db3 dst_db:test dst_tbl:table1 dst_dsn:h=db4 lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:16135 user:mysql host:db3*/;
UPDATE `test`.`table1` SET `id`='10528', `status`='open', `created`='2015-04-27 08:22:21', `created_by`='8', `updated`='2015-04-28 10:22:55', WHERE `ix_id`='9586' LIMIT 1 /*percona-toolkit src_db:test src_tbl:table1 src_dsn:h=db3 dst_db:test dst_tbl:table1 dst_dsn:h=db4 lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:16135 user:mysql host:db3*/;
UPDATE `test`.`table1` SET `id`='8118', `status`='open', `created`='2015-04-27 18:22:20', `created_by`='8', `updated`='2015-04-28 10:22:55', WHERE `ix_id`='9587' LIMIT 1 /*percona-toolkit src_db:test src_tbl:table1 src_dsn:h=db3 dst_db:test dst_tbl:table1 dst_dsn:h=db4 lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:16135 user:mysql host:db3*/;
UPDATE `test`.`table1` SET `id`='1279', `status`='open', `created`='2015-04-28 06:22:16', `created_by`='8', `updated`='2015-04-28 10:22:55', WHERE `ix_id`='9588' LIMIT 1 /*percona-toolkit src_db:test src_tbl:table1 src_dsn:h=db3 dst_db:test dst_tbl:table1 dst_dsn:h=db4 lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:16135 user:mysql host:db3*/;
....
# 0 0 0 31195 Chunk 11:11:11 11:11:12 2 test.table1

Теперь, когда все готово, мы переключим –print на –execute

[root@db3]$ pt-table-sync
           --execute
           --verbose
           --databases test -t table1
           --no-foreign-key-checks h=db3 h=db4
# Syncing h=db4
# DELETE REPLACE INSERT UPDATE ALGORITHM START END EXIT DATABASE.TABLE
# 0 0 0 31195 Nibble 13:26:19 14:48:54 2 test.table1

И вуаля: данные синхронизированы сейчас.

Выводы

Tungsten Replicator — это полезный инструмент для развертывания подобных сценариев, без необходимости обновлять / изменять версию MySQL, но у него все еще есть некоторые приемы, позволяющие избежать несоответствия данных. Общие рекомендации по хорошей практике репликации все еще применяются здесь, то есть не позволяют пользователям запускать команды записи на ведомых устройствах и так далее.

Имея это в виду, у нас все еще могут быть проблемы с нашими данными, но теперь, приложив небольшие усилия, мы сможем сохранить здоровье без особой боли.