[MDEV-25872] InnoDB: Assertion failure in row_merge_read_clustered_index upon ALTER on table with indexed virtual columns Created: 2021-06-07  Updated: 2021-06-22  Resolved: 2021-06-15

Status: Closed
Project: MariaDB Server
Component/s: Virtual Columns
Affects Version/s: 10.2, 10.3, 10.4, 10.5, 10.6
Fix Version/s: 10.2.40, 10.3.31, 10.4.21, 10.5.12, 10.6.3

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Thirunarayanan Balathandayuthapani
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-25971 Instant ADD COLUMN fails to issue tru... Closed

 Description   

--source include/have_innodb.inc
--source include/have_sequence.inc
 
CREATE TABLE t1 (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  a INT,
  va INT ZEROFILL AS (a) VIRTUAL,
  b TIMESTAMP,
  c CHAR(204),
  vc CHAR(8),
  KEY(vc,c(64),b,va)
) ENGINE=InnoDB CHARACTER SET utf32;
INSERT INTO t1 (id) SELECT NULL FROM seq_1_to_75;
INSERT IGNORE INTO t1 (id, a) VALUES (NULL, -1);
ALTER TABLE t1 FORCE;
 
# CLeanup
DROP TABLE t1;

Run with --mysqld=--innodb-sort-buffer-size=64K

10.3 b1b4d67b

2021-06-08 02:36:35 0x7f3bf5354700  InnoDB: Assertion failure in file /data/src/10.3/storage/innobase/row/row0merge.cc line 2697
 
#6  0x000055839690fa33 in ut_dbg_assertion_failed (expr=0x0, file=0x558396fc16f0 "/data/src/10.3/storage/innobase/row/row0merge.cc", line=2697) at /data/src/10.3/storage/innobase/ut/ut0dbg.cc:60
#7  0x000055839680b6b8 in row_merge_read_clustered_index (trx=0x7f3bf5e520d0, table=0x7f3b9c0abb60, old_table=0x7f3b9c1901c0, new_table=0x7f3b9c0af1c0, online=false, index=0x7f3b9c0aeef0, fts_sort_idx=0x0, psort_info=0x0, files=0x7f3b9c033340, key_numbers=0x7f3b9c0aef00, n_index=2, defaults=0x0, add_v=0x0, col_map=0x7f3b9c0aef98, add_autoinc=18446744073709551615, sequence=..., block=0x7f3bf52da000 "\002\a`\276\255\203\200", skip_pk_sort=true, tmpfd=0x7f3bf53504e0, stage=0x7f3b9c1805d0, pct_cost=33.333333333333336, crypt_block=0x0, eval_table=0x7f3b9c0abb60, allow_not_null=false) at /data/src/10.3/storage/innobase/row/row0merge.cc:2697
#8  0x0000558396812361 in row_merge_build_indexes (trx=0x7f3bf5e520d0, old_table=0x7f3b9c1901c0, new_table=0x7f3b9c0af1c0, online=false, indexes=0x7f3b9c0aeef0, key_numbers=0x7f3b9c0aef00, n_indexes=2, table=0x7f3b9c0abb60, defaults=0x0, col_map=0x7f3b9c0aef98, add_autoinc=18446744073709551615, sequence=..., skip_pk_sort=true, stage=0x7f3b9c1805d0, add_v=0x0, eval_table=0x7f3b9c0abb60, allow_not_null=false) at /data/src/10.3/storage/innobase/row/row0merge.cc:4721
#9  0x00005583966ced27 in ha_innobase::inplace_alter_table (this=0x7f3b9c036398, altered_table=0x7f3b9c0abb60, ha_alter_info=0x7f3bf5351170) at /data/src/10.3/storage/innobase/handler/handler0alter.cc:7221
#10 0x00005583962084d7 in handler::ha_inplace_alter_table (this=0x7f3b9c036398, altered_table=0x7f3b9c0abb60, ha_alter_info=0x7f3bf5351170) at /data/src/10.3/sql/handler.h:4212
#11 0x00005583961fc782 in mysql_inplace_alter_table (thd=0x7f3b9c000d90, table_list=0x7f3b9c012bb8, table=0x7f3b9c0bbc10, altered_table=0x7f3b9c0abb60, ha_alter_info=0x7f3bf5351170, target_mdl_request=0x7f3bf53512f0, alter_ctx=0x7f3bf53518a0) at /data/src/10.3/sql/sql_table.cc:7744
#12 0x000055839620353f in mysql_alter_table (thd=0x7f3b9c000d90, new_db=0x7f3b9c005488, new_name=0x7f3b9c005870, create_info=0x7f3bf5352490, table_list=0x7f3b9c012bb8, alter_info=0x7f3bf53523d0, order_num=0, order=0x0, ignore=false) at /data/src/10.3/sql/sql_table.cc:10049
#13 0x0000558396294416 in Sql_cmd_alter_table::execute (this=0x7f3b9c013220, thd=0x7f3b9c000d90) at /data/src/10.3/sql/sql_alter.cc:512
#14 0x000055839611dc3f in mysql_execute_command (thd=0x7f3b9c000d90) at /data/src/10.3/sql/sql_parse.cc:6075
#15 0x00005583961232fe in mysql_parse (thd=0x7f3b9c000d90, rawbuf=0x7f3b9c012ae8 "ALTER TABLE t1 FORCE", length=20, parser_state=0x7f3bf5353530, is_com_multi=false, is_next_command=false) at /data/src/10.3/sql/sql_parse.cc:7870
#16 0x000055839610f9bb in dispatch_command (command=COM_QUERY, thd=0x7f3b9c000d90, packet=0x7f3b9c008f41 "ALTER TABLE t1 FORCE", packet_length=20, is_com_multi=false, is_next_command=false) at /data/src/10.3/sql/sql_parse.cc:1852
#17 0x000055839610e35b in do_command (thd=0x7f3b9c000d90) at /data/src/10.3/sql/sql_parse.cc:1398
#18 0x000055839628e2ac in do_handle_one_connection (connect=0x55839a0cd420) at /data/src/10.3/sql/sql_connect.cc:1403
#19 0x000055839628e008 in handle_one_connection (arg=0x55839a0cd420) at /data/src/10.3/sql/sql_connect.cc:1308
#20 0x0000558396c63f69 in pfs_spawn_thread (arg=0x55839a0b0260) at /data/src/10.3/storage/perfschema/pfs.cc:1869
#21 0x00007f3bfc4a7609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#22 0x00007f3bfc3ce293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Reproducible on 10.3+, debug- and non-debug alike.



 Comments   
Comment by Thirunarayanan Balathandayuthapani [ 2021-06-09 ]

InnoDB fails to check the error condition DB_COMPUTE_VALUE_FAILED in row_merge_read_clustered_index(). So the following
patch could fix this issue.

diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 9e84f9db033..07ccb5fcfe4 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -2692,6 +2692,12 @@ row_merge_read_clustered_index(
                                                new_table, psort_info, row, ext,
                                                &doc_id, conv_heap,
                                                &err, &v_heap, eval_table, trx)))) {
+
+                                       if (err == DB_COMPUTE_VALUE_FAILED) {
+                                               trx->error_key_num = i;
+                                               goto func_exit;
+                                       }
+
                                        /* An empty buffer should have enough
                                        room for at least one record. */
                                        ut_error;

Comment by Marko Mäkelä [ 2021-06-10 ]

Would the following work? It should avoid a crash in a non-debug server for any errors here, and report the problematic index:

diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index e3b3f2c2762..7d3693e8bbc 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -2569,15 +2569,15 @@ row_merge_read_clustered_index(
 						&err, &v_heap, eval_table, trx)))) {
 					/* An empty buffer should have enough
 					room for at least one record. */
-					ut_error;
+					ut_ad(err == DB_COMPUTE_VALUE_FAILED);
+				} else if (err == DB_SUCCESS) {
+					file->n_rec += rows_added;
+					continue;
 				}
 
-				if (err != DB_SUCCESS) {
+				trx->error_key_num = i;
 				break;
 			}
-
-				file->n_rec += rows_added;
-			}
 		}
 
 		if (row == NULL) {

I think that this variant would require stress testing.

Generated at Thu Feb 08 09:41:02 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.