|
At the time of the assertion failure:
|
10.3 4e9206736c403206915c09db1c9d8e3cd0fd0c5b
|
2022-11-28 15:03:28 0x7fb80c05f6c0 InnoDB: Assertion failure in file /mariadb/10.3/storage/innobase/row/row0ins.cc line 220
|
InnoDB: Failing assertion: update->n_fields == 0
|
we have the following records in the buffer pool pages:
Secondary index (c,b)=('',0x0001050001),('x',0x0000)
Clustered index (b,c,DB_TRX_ID,DB_ROLL_PTR,a)=('','',39,(insert),0),(0x0000,'x',0,1<<55,0),(0x0001050001,'',0,1<<55,0).
The length of each field b or c is encoded explicitly; column c is 8 bytes, space-padded). No record is delete-marked.
Updating the PRIMARY KEY should delete-mark the old key (in all indexes) and then insert a new key into each index.
The crash occurs on the 2nd row that was processed by the UPDATE statement. At the start of that statement, the index entries are as follows:
Secondary index: (b,c)=('',0x000105001),('x',0x0000)
Clustered index: (c,b,DB_TRX_ID,DB_ROLL_PTR,a)=(0x0000,0,1<<55,2),(0x0001050001,'',0,1<<55,1)
That looks correct. DB_TRX_ID=0 means that all history has been purged (the record is visible in all read views). After the UPDATE…SET a=0 of the first row, we have the following:
Secondary index: (b,c)=('',0x000105001),('x',0x0000) (no change from previous)
Clustered index: (c,b,DB_TRX_ID,DB_ROLL_PTR,a)=(0x0000,'x',37,(update),0),(0x0001050001,'',0,1<<55,1)
After the UPDATE…SET a=0 of the second row, we have the following:
Secondary index: (b,c)=('',0x000105001),('x',0x0000) (no change from previous)
Clustered index: (c,b,DB_TRX_ID,DB_ROLL_PTR,a)=(0x0000,'x',37,(update),0),(0x0001050001,'',37,(update),0)
This is as I would expect.
The crash occurs on the INSERT by transaction ID 39. It had already successfully inserted a record into the clustered index (see the first dump) but not to the secondary index record. The comment before the failing assertion explains the problem:
/* We should never insert in place of a record that
|
has not been delete-marked. The only exception is when
|
online CREATE INDEX copied the changes that we already
|
made to the clustered index, and completed the
|
secondary index creation before we got here. In this
|
case, the change would already be there. The CREATE
|
INDEX should be waiting for a MySQL meta-data lock
|
upgrade at least until this INSERT or UPDATE
|
returns. After that point, set_committed(true)
|
would be invoked in commit_inplace_alter_table(). */
|
ut_a(update->n_fields == 0);
|
It appears that we failed to notice a duplicate in the PRIMARY KEY during the INSERT, or the collation function is delivering inconsistent results. I see the following calls during the execution of the crashing INSERT statement:
(rr) finish
|
Run till exit from #0 my_strnncollsp_utf8_general_nopad_ci (
|
cs=0x55bbf2b612c0 <my_charset_utf8_general_nopad_ci>, a=0x7fb8080a701e "",
|
a_length=0, b=0x7fb81dd4c0a6 "", b_length=2)
|
at /mariadb/10.3/strings/strcoll.inl:221
|
0x000055bbf27517c3 in innobase_mysql_cmp (prtype=prtype@entry=69271823, a=a@entry=0x7fb8080a701e "", a_length=a_length@entry=0, b=b@entry=0x7fb81dd4c0a6 "", b_length=b_length@entry=2) at /mariadb/10.3/storage/innobase/rem/rem0cmp.cc:94
|
94 }
|
Value returned is $10 = 0
|
This claims that '' is equal to 0x0000, while inserting into the clustered index.
(rr) finish
|
Run till exit from #0 my_strnncollsp_utf8_general_nopad_ci (
|
cs=0x55bbf2b612c0 <my_charset_utf8_general_nopad_ci>,
|
a=0x7fb8080a704e ' ' <repeats 24 times>, "\245\245\376\001", a_length=8,
|
b=0x7fb81dd4c0a8 "x ", b_length=8)
|
at /mariadb/10.3/strings/strcoll.inl:221
|
0x000055bbf27517c3 in innobase_mysql_cmp (prtype=prtype@entry=69272062, a=a@entry=0x7fb8080a704e ' ' <repeats 24 times>, "\245\245\376\001", a_length=a_length@entry=8, b=b@entry=0x7fb81dd4c0a8 "x ", b_length=b_length@entry=8) at /mariadb/10.3/storage/innobase/rem/rem0cmp.cc:94
|
94 }
|
Value returned is $11 = -56
|
This claims that 'x' is less than ''. So, the record was inserted at the start of the clustered index.
There were 2 more calls for debug assertions for the clustered index. For the secondary index, the next call is:
(rr) finish
|
Run till exit from #0 my_strnncollsp_utf8_general_nopad_ci (
|
cs=0x55bbf2b612c0 <my_charset_utf8_general_nopad_ci>,
|
a=0x7fb8080a704e ' ' <repeats 24 times>, "\245\245\376\001", a_length=8,
|
b=0x7fb81dd5007f " ", b_length=8)
|
at /mariadb/10.3/strings/strcoll.inl:221
|
0x000055bbf27517c3 in innobase_mysql_cmp (prtype=prtype@entry=69272062, a=a@entry=0x7fb8080a704e ' ' <repeats 24 times>, "\245\245\376\001", a_length=a_length@entry=8, b=b@entry=0x7fb81dd5007f " ", b_length=b_length@entry=8) at /mariadb/10.3/storage/innobase/rem/rem0cmp.cc:94
|
94 }
|
Value returned is $14 = 0
|
According to this, the empty string (padded with 8 spaces) is equal to itself. I can agree with that.
(rr) finish
|
Run till exit from #0 my_strnncollsp_utf8_general_nopad_ci (
|
cs=0x55bbf2b612c0 <my_charset_utf8_general_nopad_ci>, a=0x7fb8080a701e "",
|
a_length=0, b=0x7fb81dd50087 "", b_length=5)
|
at /mariadb/10.3/strings/strcoll.inl:221
|
0x000055bbf27517c3 in innobase_mysql_cmp (prtype=prtype@entry=69271823, a=a@entry=0x7fb8080a701e "", a_length=a_length@entry=0, b=b@entry=0x7fb81dd50087 "", b_length=b_length@entry=5) at /mariadb/10.3/storage/innobase/rem/rem0cmp.cc:94
|
94 }
|
Value returned is $15 = 0
|
This claims that the empty string is equal to 0x0001050001. It looks wrong to me!
Finally, there is a comparison of ''<'x', which looks correct to me, and then the assertion failure.
|