Bug #109923 Writeset-based Dependency Tracking will cause error HA_ERR_NO_REFERENCED_ROW.
Description:
The parent table has no primary key, unique key, only secondary index.
The child table has a primary key, and the foreign key reference to the secondary index of the parent table.
When inserting rows, the last_committed of the child table's row will be smaller than it should be, causing SQL thread aborted.
How to repeat:
=============================================================================
1. SQL
=============================================================================
SET GLOBAL binlog_transaction_dependency_tracking = COMMIT_ORDER;
SET GLOBAL transaction_write_set_extraction = XXHASH64;
SET SESSION transaction_write_set_extraction = XXHASH64;
SET GLOBAL binlog_transaction_dependency_tracking = WRITESET;
create database test;
use test;
CREATE TABLE parent (
did INT,
KEY (did)
) ENGINE=INNODB;
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES parent(did)
) ENGINE=INNODB;
RESET MASTER;
INSERT INTO parent VALUES (1);
INSERT INTO child VALUES (1, 1);
INSERT INTO parent VALUES (2);
INSERT INTO child VALUES (2, 2);
=============================================================================
2. Binary log
=============================================================================
#230203 22:04:30 server id 1 end_log_pos 236 CRC32 0x597571ab GTID last_committed=0 sequence_number=1 rbr_only=yes original_committed_timestamp=1675433070628397 immediate_commit_timestamp=1675433070628397 transaction_length=279
#230203 22:04:30 server id 1 end_log_pos 515 CRC32 0x26d1be0b GTID last_committed=1 sequence_number=2 rbr_only=yes original_committed_timestamp=1675433070636099 immediate_commit_timestamp=1675433070636099 transaction_length=281
#230203 22:04:30 server id 1 end_log_pos 796 CRC32 0x6a2d870c GTID last_committed=2 sequence_number=3 rbr_only=yes original_committed_timestamp=1675433070638930 immediate_commit_timestamp=1675433070638930 transaction_length=279
#230203 22:04:30 server id 1 end_log_pos 1075 CRC32 0xdff67731 GTID last_committed=1 sequence_number=4 rbr_only=yes original_committed_timestamp=1675433070882021 immediate_commit_timestamp=1675433070882021 transaction_length=281
=============================================================================
3. Analysis
=============================================================================
'INSERT INTO child VALUES (2, 2);' Its 'last_committed' is equal to 1 which should greater than 3.
=============================================================================
4. SQL thread Error
Note: This error requires inserting multiple rows quickly.
=============================================================================
Last_SQL_Errno: 1452
Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 2 failed executing transaction '029dde77-7630-11ed-bfda-b8599f2ff098:6' at master log mysql-bin.000001, end_log_pos 1811. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
================
master-error.log
================
[ERROR] [MY-010584] [Repl] Slave SQL for channel '': Worker 2 failed executing transaction '029dde77-7630-11ed-bfda-b8599f2ff098:6' at master log mysql-bin.000001, end_log_pos 1811; Could not execute Write_rows event on table test.child; Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENC
ES `parent` (`did`)), Error_code: 1452; handler error HA_ERR_NO_REFERENCED_ROW; the event's master log mysql-bin.000001, end_log_pos 1811
, Error_code: MY-001452
Suggested fix:
diff --git a/sql/rpl_write_set_handler.cc b/sql/rpl_write_set_handler.cc
index 33a9049414e..e3656f0f65a 100644
--- a/sql/rpl_write_set_handler.cc
+++ b/sql/rpl_write_set_handler.cc
@@ -776,14 +776,14 @@ bool add_pke(TABLE *table, THD *thd, const uchar *record) {
}
}
- if (table->s->foreign_key_parents > 0)
- ws_ctx->set_has_related_foreign_keys();
-
#ifndef NDEBUG
debug_check_for_write_sets(write_sets, hash_list);
#endif
}
+ if (table->s->foreign_key_parents > 0)
+ ws_ctx->set_has_related_foreign_keys();
+
if (!writeset_hashes_added) ws_ctx->set_has_missing_keys();
return false;
}
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.058 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: The parent table has no primary key, unique key, only secondary index. The child table has a primary key, and the foreign key reference to the secondary index of the parent table. When inserting rows, the last_committed of the child table's row will be smaller than it should be, causing SQL thread aborted. How to repeat: ============================================================================= 1. SQL ============================================================================= SET GLOBAL binlog_transaction_dependency_tracking = COMMIT_ORDER; SET GLOBAL transaction_write_set_extraction = XXHASH64; SET SESSION transaction_write_set_extraction = XXHASH64; SET GLOBAL binlog_transaction_dependency_tracking = WRITESET; create database test; use test; CREATE TABLE parent ( did INT, KEY (did) ) ENGINE=INNODB; CREATE TABLE child ( id INT PRIMARY KEY, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(did) ) ENGINE=INNODB; RESET MASTER; INSERT INTO parent VALUES (1); INSERT INTO child VALUES (1, 1); INSERT INTO parent VALUES (2); INSERT INTO child VALUES (2, 2); ============================================================================= 2. Binary log ============================================================================= #230203 22:04:30 server id 1 end_log_pos 236 CRC32 0x597571ab GTID last_committed=0 sequence_number=1 rbr_only=yes original_committed_timestamp=1675433070628397 immediate_commit_timestamp=1675433070628397 transaction_length=279 #230203 22:04:30 server id 1 end_log_pos 515 CRC32 0x26d1be0b GTID last_committed=1 sequence_number=2 rbr_only=yes original_committed_timestamp=1675433070636099 immediate_commit_timestamp=1675433070636099 transaction_length=281 #230203 22:04:30 server id 1 end_log_pos 796 CRC32 0x6a2d870c GTID last_committed=2 sequence_number=3 rbr_only=yes original_committed_timestamp=1675433070638930 immediate_commit_timestamp=1675433070638930 transaction_length=279 #230203 22:04:30 server id 1 end_log_pos 1075 CRC32 0xdff67731 GTID last_committed=1 sequence_number=4 rbr_only=yes original_committed_timestamp=1675433070882021 immediate_commit_timestamp=1675433070882021 transaction_length=281 ============================================================================= 3. Analysis ============================================================================= 'INSERT INTO child VALUES (2, 2);' Its 'last_committed' is equal to 1 which should greater than 3. ============================================================================= 4. SQL thread Error Note: This error requires inserting multiple rows quickly. ============================================================================= Last_SQL_Errno: 1452 Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 2 failed executing transaction '029dde77-7630-11ed-bfda-b8599f2ff098:6' at master log mysql-bin.000001, end_log_pos 1811. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any. ================ master-error.log ================ [ERROR] [MY-010584] [Repl] Slave SQL for channel '': Worker 2 failed executing transaction '029dde77-7630-11ed-bfda-b8599f2ff098:6' at master log mysql-bin.000001, end_log_pos 1811; Could not execute Write_rows event on table test.child; Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENC ES `parent` (`did`)), Error_code: 1452; handler error HA_ERR_NO_REFERENCED_ROW; the event's master log mysql-bin.000001, end_log_pos 1811 , Error_code: MY-001452 Suggested fix: diff --git a/sql/rpl_write_set_handler.cc b/sql/rpl_write_set_handler.cc index 33a9049414e..e3656f0f65a 100644 --- a/sql/rpl_write_set_handler.cc +++ b/sql/rpl_write_set_handler.cc @@ -776,14 +776,14 @@ bool add_pke(TABLE *table, THD *thd, const uchar *record) { } } - if (table->s->foreign_key_parents > 0) - ws_ctx->set_has_related_foreign_keys(); - #ifndef NDEBUG debug_check_for_write_sets(write_sets, hash_list); #endif } + if (table->s->foreign_key_parents > 0) + ws_ctx->set_has_related_foreign_keys(); + if (!writeset_hashes_added) ws_ctx->set_has_missing_keys(); return false; }