Последнее обновление на 27.02.2025
Баг применим для MySQL InnoDB Cluster 8.0.24 — 8.0.29
UPD: на 04.05.2022 баг остался в 8.0.29 версии.
Баг существует уже 3 версии, начиная с 8.0.24 (2021-04-20, General Availability). SR по багу создавались раннее другими пользователями, но почему-то воспроизвести и подтвердить баг смогли только в моем случае. Мне попался отличный инженер.
Репликация на Secondary нодах InnoDB Cluster ломается при обновлении таблицы, которая содержит GENERATED столбец. При условии, что binlog_row_image=minimal
. Не обязательно обновлять запись в GENERATED столбце, можно обновить любой столбей.
2021-09-22T15:25:08.223501Z 22 [ERROR] [MY-010584] [Repl] Slave SQL for channel 'group_replication_applier': Worker 1 failed executing transaction 'c9afa728-1ac9-11ec-bfa0-0050568125f4:55'; Could not execute Update_rows event on table bug.sample; Can't find record in 'sample', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND, Error_code: MY-001032
Мы используем binlog_row_image=minimal, чтобы избежать дополнительной утилизации сети, памяти и дисков для binlogs. Если не тюнить кластер и не трогать настройки, то всё будет работать, по умолчанию binlog_row_image=FULL
.
Восроизведем баг.
На Primary ноде создаем таблицу sample в БД bug и добавляем в таблицу строку:
mysql> CREATE TABLE sample(
-> ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
-> CREATE_TIME DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
-> PARTITION_DATE DATE GENERATED ALWAYS AS (date(CREATE_TIME)) STORED,
-> PRIMARY KEY (ID,PARTITION_DATE)
-> );
Query OK, 0 rows affected, 1 warning (0.05 sec)
mysql> INSERT INTO sample(CREATE_TIME) values(NOW());
Query OK, 1 row affected (0.02 sec)
mysql> select * from sample;
+----+----------------------------+--------------------------+
| ID | CREATE_TIME | PARTITION_DATE |
+----+----------------------------+--------------------------+
| 1 | 2021-09-22 20:30:40 | 2021-09-22 |
+----+----------------------------+--------------------------+
1 row in set (0.00 sec)
#1: Следующий UPDATE реплицируется на secondary ноду без проблем.
mysql> set binlog_row_image=full;
Query OK, 0 rows affected (0.00 sec)
mysql> update sample set id=2 WHERE CREATE_TIME='2021-09-22 20:30:40';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
#2: Следующий UPDATE не может быть реплицирован на secondary ноду и ломается с ошибкой HA_ERR_KEY_NOT_FOUND.
mysql> set binlog_row_image=minimal;
Query OK, 0 rows affected (0.00 sec)
mysql> update sample set id=3 WHERE CREATE_TIME='2021-09-22 20:30:40';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
Workaround: Использовать binlog_row_image=full (по-умолчанию full).
Вообще ошибка HA_ERR_KEY_NOT_FOUND
редкая в InnoDB Cluster, если вы только специально не ломаете кластер или не возникают внештатные ситуации в работе кластера. Так как репликация в кластере основана на строках, то в кластере вы не сможете создать таблицу без Primary Key и соответсвенно получить ошибку HA_ERR_KEY_NOT_FOUND шансы не велики.
На основе моего кейса появилась нота на металинке — GR Secondary Nodes Fails With HA_ERR_KEY_NOT_FOUND Error On Tables With GENERATED Column (Doc ID 2808533.1). Но в ней неверно указаны версии, на которых воспроизводится баг, т.к. в рамках SR я протестировал на 8.0.25 и 8.0.26, то так и указали. После закрытия SR проверил на всех версиях выше 8.0.21 и выяснил, что баг тянется с 8.0.24. Думаю поправят, сообщил о неточности.