Нажмите "Enter" для перехода к содержанию

MySQL InnoDB Cluster 8. HA_ERR_KEY_NOT_FOUND. Баг длинной в полтора года (6 версий).

Последнее обновление на 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. Думаю поправят, сообщил о неточности.