Skip to content

Commit 0202e47

Browse files
committed
MDEV-12827 Assertion failure when reporting duplicate key error in online table rebuild
row_log_table_apply_insert_low(), row_log_table_apply_update(): When reporting the error_key_num, only count the clustered index if it corresponds to a key in the SQL layer. The assertion failure was probably introduced by the (incomplete) MySQL 5.6.28 bug fix Bug #21364096 THE BOGUS DUPLICATE KEY ERROR IN ONLINE DDL WITH INCORRECT KEY NAME which we are improving. Side note: the fix was incorrectly merged to MySQL 5.7.10; incorrect key names will continue to be reported in MySQL 5.7.
1 parent 042f763 commit 0202e47

File tree

4 files changed

+92
-38
lines changed

4 files changed

+92
-38
lines changed

mysql-test/suite/innodb/r/innodb-index-debug.result

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,25 @@ alter table t1 force, algorithm=inplace;
6767
ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space
6868
SET DEBUG_DBUG = @saved_debug_dbug;
6969
drop table t1, t480;
70+
#
71+
# MDEV-12827 Assertion failure when reporting duplicate key error
72+
# in online table rebuild
73+
#
74+
CREATE TABLE t1 (j INT UNIQUE, i INT UNIQUE) ENGINE=InnoDB;
75+
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built WAIT_FOR log';
76+
ALTER TABLE t1 DROP j, FORCE;
77+
SET DEBUG_SYNC='now WAIT_FOR built';
78+
INSERT INTO t1 (i) VALUES (0),(0);
79+
ERROR 23000: Duplicate entry '0' for key 'i'
80+
SET DEBUG_SYNC='now SIGNAL log';
81+
ERROR 23000: Duplicate entry '0' for key 'i'
82+
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built2 WAIT_FOR log2';
83+
ALTER TABLE t1 DROP j, FORCE;
84+
SET DEBUG_SYNC='now WAIT_FOR built2';
85+
INSERT INTO t1 (i) VALUES (0),(1);
86+
UPDATE t1 SET i=0;
87+
ERROR 23000: Duplicate entry '0' for key 'i'
88+
SET DEBUG_SYNC='now SIGNAL log2';
89+
ERROR 23000: Duplicate entry '0' for key 'i'
90+
SET DEBUG_SYNC='RESET';
91+
DROP TABLE t1;

mysql-test/suite/innodb/t/innodb-index-debug.test

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
-- source include/have_debug.inc
22
-- source include/have_innodb.inc
3-
4-
let $MYSQLD_DATADIR= `select @@datadir`;
3+
-- source include/have_debug_sync.inc
54

65
let $per_table=`select @@innodb_file_per_table`;
76
let $format=`select @@innodb_file_format`;
@@ -82,3 +81,42 @@ SET DEBUG_DBUG = '+d,innobase_tmpfile_creation_failure';
8281
alter table t1 force, algorithm=inplace;
8382
SET DEBUG_DBUG = @saved_debug_dbug;
8483
drop table t1, t480;
84+
85+
--echo #
86+
--echo # MDEV-12827 Assertion failure when reporting duplicate key error
87+
--echo # in online table rebuild
88+
--echo #
89+
90+
CREATE TABLE t1 (j INT UNIQUE, i INT UNIQUE) ENGINE=InnoDB;
91+
--connect (con1,localhost,root,,test)
92+
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built WAIT_FOR log';
93+
--send
94+
ALTER TABLE t1 DROP j, FORCE;
95+
96+
--connection default
97+
SET DEBUG_SYNC='now WAIT_FOR built';
98+
--error ER_DUP_ENTRY
99+
INSERT INTO t1 (i) VALUES (0),(0);
100+
SET DEBUG_SYNC='now SIGNAL log';
101+
102+
--connection con1
103+
--error ER_DUP_ENTRY
104+
reap;
105+
SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL built2 WAIT_FOR log2';
106+
--send
107+
ALTER TABLE t1 DROP j, FORCE;
108+
109+
--connection default
110+
SET DEBUG_SYNC='now WAIT_FOR built2';
111+
INSERT INTO t1 (i) VALUES (0),(1);
112+
--error ER_DUP_ENTRY
113+
UPDATE t1 SET i=0;
114+
SET DEBUG_SYNC='now SIGNAL log2';
115+
116+
--connection con1
117+
--error ER_DUP_ENTRY
118+
reap;
119+
--disconnect con1
120+
--connection default
121+
SET DEBUG_SYNC='RESET';
122+
DROP TABLE t1;

storage/innobase/row/row0log.cc

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,13 +1520,10 @@ row_log_table_apply_insert_low(
15201520
return(error);
15211521
}
15221522

1523-
do {
1524-
n_index++;
1525-
1526-
if (!(index = dict_table_get_next_index(index))) {
1527-
break;
1528-
}
1523+
ut_ad(dict_index_is_clust(index));
15291524

1525+
for (n_index += index->type != DICT_CLUSTERED;
1526+
(index = dict_table_get_next_index(index)); n_index++) {
15301527
if (index->type & DICT_FTS) {
15311528
continue;
15321529
}
@@ -1536,12 +1533,13 @@ row_log_table_apply_insert_low(
15361533
flags, BTR_MODIFY_TREE,
15371534
index, offsets_heap, heap, entry, trx_id, thr);
15381535

1539-
/* Report correct index name for duplicate key error. */
1540-
if (error == DB_DUPLICATE_KEY) {
1541-
thr_get_trx(thr)->error_key_num = n_index;
1536+
if (error != DB_SUCCESS) {
1537+
if (error == DB_DUPLICATE_KEY) {
1538+
thr_get_trx(thr)->error_key_num = n_index;
1539+
}
1540+
break;
15421541
}
1543-
1544-
} while (error == DB_SUCCESS);
1542+
}
15451543

15461544
return(error);
15471545
}
@@ -2120,17 +2118,16 @@ row_log_table_apply_update(
21202118
dtuple_big_rec_free(big_rec);
21212119
}
21222120

2123-
while ((index = dict_table_get_next_index(index)) != NULL) {
2124-
if (error != DB_SUCCESS) {
2125-
break;
2126-
}
2127-
2128-
n_index++;
2129-
2121+
for (n_index += index->type != DICT_CLUSTERED;
2122+
(index = dict_table_get_next_index(index)); n_index++) {
21302123
if (index->type & DICT_FTS) {
21312124
continue;
21322125
}
21332126

2127+
if (error != DB_SUCCESS) {
2128+
break;
2129+
}
2130+
21342131
if (!row_upd_changes_ord_field_binary(
21352132
index, update, thr, old_row, NULL)) {
21362133
continue;

storage/xtradb/row/row0log.cc

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,13 +1520,10 @@ row_log_table_apply_insert_low(
15201520
return(error);
15211521
}
15221522

1523-
do {
1524-
n_index++;
1525-
1526-
if (!(index = dict_table_get_next_index(index))) {
1527-
break;
1528-
}
1523+
ut_ad(dict_index_is_clust(index));
15291524

1525+
for (n_index += index->type != DICT_CLUSTERED;
1526+
(index = dict_table_get_next_index(index)); n_index++) {
15301527
if (index->type & DICT_FTS) {
15311528
continue;
15321529
}
@@ -1536,12 +1533,13 @@ row_log_table_apply_insert_low(
15361533
flags, BTR_MODIFY_TREE,
15371534
index, offsets_heap, heap, entry, trx_id, thr);
15381535

1539-
/* Report correct index name for duplicate key error. */
1540-
if (error == DB_DUPLICATE_KEY) {
1541-
thr_get_trx(thr)->error_key_num = n_index;
1536+
if (error != DB_SUCCESS) {
1537+
if (error == DB_DUPLICATE_KEY) {
1538+
thr_get_trx(thr)->error_key_num = n_index;
1539+
}
1540+
break;
15421541
}
1543-
1544-
} while (error == DB_SUCCESS);
1542+
}
15451543

15461544
return(error);
15471545
}
@@ -2120,17 +2118,16 @@ row_log_table_apply_update(
21202118
dtuple_big_rec_free(big_rec);
21212119
}
21222120

2123-
while ((index = dict_table_get_next_index(index)) != NULL) {
2124-
if (error != DB_SUCCESS) {
2125-
break;
2126-
}
2127-
2128-
n_index++;
2129-
2121+
for (n_index += index->type != DICT_CLUSTERED;
2122+
(index = dict_table_get_next_index(index)); n_index++) {
21302123
if (index->type & DICT_FTS) {
21312124
continue;
21322125
}
21332126

2127+
if (error != DB_SUCCESS) {
2128+
break;
2129+
}
2130+
21342131
if (!row_upd_changes_ord_field_binary(
21352132
index, update, thr, old_row, NULL)) {
21362133
continue;

0 commit comments

Comments
 (0)