[MDEV-19486] Server crashes in row_upd or row_upd_del_mark_clust_rec on REPLACE into a versioned table Created: 2019-05-15  Updated: 2019-07-23  Resolved: 2019-05-20

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB, Versioned Tables
Affects Version/s: 10.3, 10.4
Fix Version/s: 10.3.16, 10.4.6

Type: Bug Priority: Major
Reporter: Elena Stepanova Assignee: Eugene Kosov (Inactive)
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-19955 make argument of handler::ha_write_ro... Closed
relates to MDEV-17005 ASAN heap-use-after-free in innobase_... Closed
relates to MDEV-17890 Server crash on DELETE with YEAR fiel... Closed
relates to MDEV-18870 Server crashes in row_upd or in row_u... Closed
relates to MDEV-19814 Assertion `update->n_fields < ulint(t... Closed

 Description   

NOTE: There are several (too many) open bugs which look somewhat similar, e.g. MDEV-17890, MDEV-18870, MDEV-17005, but none seems to be the exact match, so I'm once again filing this one separately.

--source include/have_innodb.inc
 
CREATE TABLE t1 ( 
    pk INT AUTO_INCREMENT,
    f INT,
    s BIGINT UNSIGNED AS ROW START,
    e BIGINT UNSIGNED AS ROW END,
    PRIMARY KEY(pk),
    UNIQUE(f),
    PERIOD FOR SYSTEM_TIME(s,e)
) ENGINE=InnoDB WITH SYSTEM VERSIONING;
REPLACE INTO t1 () VALUES (),(),(),();
UPDATE IGNORE t1 SET f = 1;
REPLACE t1 SELECT * FROM t1;
REPLACE t1 SELECT * FROM t1;
 
# Cleanup
DROP TABLE t1;

10.3 debug

#3  <signal handler called>
#4  0x0000558844753c7f in row_upd (node=0x7fed280a85b8, thr=0x7fed280a8920) at /data/src/10.3/storage/innobase/row/row0upd.cc:3272
#5  0x0000558844754331 in row_upd_step (thr=0x7fed280a8920) at /data/src/10.3/storage/innobase/row/row0upd.cc:3443
#6  0x00005588446f8a61 in row_update_for_mysql (prebuilt=0x7fed280a7a08) at /data/src/10.3/storage/innobase/row/row0mysql.cc:1889
#7  0x000055884459e981 in ha_innobase::delete_row (this=0x7fed2800ad58, record=0x7fed28033410 "\377\003") at /data/src/10.3/storage/innobase/handler/ha_innodb.cc:8999
#8  0x00005588443984e0 in handler::ha_delete_row (this=0x7fed2800ad58, buf=0x7fed28033410 "\377\003") at /data/src/10.3/sql/handler.cc:6508
#9  0x0000558844053392 in write_record (thd=0x7fed28000b00, table=0x7fed280a6dc0, info=0x7fed280137b0) at /data/src/10.3/sql/sql_insert.cc:1981
#10 0x0000558844058934 in select_insert::send_data (this=0x7fed28013768, values=...) at /data/src/10.3/sql/sql_insert.cc:3874
#11 0x0000558844106a13 in end_send (join=0x7fed28013818, join_tab=0x7fed28016248, end_of_records=false) at /data/src/10.3/sql/sql_select.cc:20582
#12 0x00005588441041f9 in evaluate_join_record (join=0x7fed28013818, join_tab=0x7fed28015e98, error=0) at /data/src/10.3/sql/sql_select.cc:19618
#13 0x000055884411943e in AGGR_OP::end_send (this=0x7fed28016888) at /data/src/10.3/sql/sql_select.cc:27453
#14 0x0000558844103555 in sub_select_postjoin_aggr (join=0x7fed28013818, join_tab=0x7fed28015e98, end_of_records=true) at /data/src/10.3/sql/sql_select.cc:19114
#15 0x000055884410388b in sub_select (join=0x7fed28013818, join_tab=0x7fed28015ae8, end_of_records=true) at /data/src/10.3/sql/sql_select.cc:19349
#16 0x0000558844103046 in do_select (join=0x7fed28013818, procedure=0x0) at /data/src/10.3/sql/sql_select.cc:18940
#17 0x00005588440dc08d in JOIN::exec_inner (this=0x7fed28013818) at /data/src/10.3/sql/sql_select.cc:4042
#18 0x00005588440db4d0 in JOIN::exec (this=0x7fed28013818) at /data/src/10.3/sql/sql_select.cc:3836
#19 0x00005588440dc771 in mysql_select (thd=0x7fed28000b00, tables=0x7fed28013098, wild_num=1, fields=..., conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=3489925888, result=0x7fed28013768, unit=0x7fed280049c8, select_lex=0x7fed28005140) at /data/src/10.3/sql/sql_select.cc:4241
#20 0x00005588440ce6d4 in handle_select (thd=0x7fed28000b00, lex=0x7fed28004900, result=0x7fed28013768, setup_tables_done_option=1073741824) at /data/src/10.3/sql/sql_select.cc:373
#21 0x0000558844092969 in mysql_execute_command (thd=0x7fed28000b00) at /data/src/10.3/sql/sql_parse.cc:4844
#22 0x000055884409d1b8 in mysql_parse (thd=0x7fed28000b00, rawbuf=0x7fed28012808 "REPLACE t1 SELECT * FROM t1", length=27, parser_state=0x7fed76b065f0, is_com_multi=false, is_next_command=false) at /data/src/10.3/sql/sql_parse.cc:8098
#23 0x000055884408a1fa in dispatch_command (command=COM_QUERY, thd=0x7fed28000b00, packet=0x7fed281600f1 "REPLACE t1 SELECT * FROM t1", packet_length=27, is_com_multi=false, is_next_command=false) at /data/src/10.3/sql/sql_parse.cc:1858
#24 0x0000558844088c1d in do_command (thd=0x7fed28000b00) at /data/src/10.3/sql/sql_parse.cc:1403
#25 0x00005588441f0d65 in do_handle_one_connection (connect=0x5588480392b0) at /data/src/10.3/sql/sql_connect.cc:1402
#26 0x00005588441f0adc in handle_one_connection (arg=0x5588480392b0) at /data/src/10.3/sql/sql_connect.cc:1308
#27 0x0000558844ac6650 in pfs_spawn_thread (arg=0x558847f819b0) at /data/src/10.3/storage/perfschema/pfs.cc:1862
#28 0x00007fed833124a4 in start_thread (arg=0x7fed76b07700) at pthread_create.c:456
#29 0x00007fed8185ad0f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:97

10.3 ASAN

==11592==ERROR: AddressSanitizer: SEGV on unknown address 0x01013fff8ae0 (pc 0x55dd8d4bccd6 bp 0x7f992987f490 sp 0x7f992987f3b0 T27)
    #0 0x55dd8d4bccd5 in row_upd /data/src/10.3/storage/innobase/row/row0upd.cc:3272
    #1 0x55dd8d4bde4f in row_upd_step(que_thr_t*) /data/src/10.3/storage/innobase/row/row0upd.cc:3443
    #2 0x55dd8d40b469 in row_update_for_mysql(row_prebuilt_t*) /data/src/10.3/storage/innobase/row/row0mysql.cc:1889
    #3 0x55dd8d1595b6 in ha_innobase::delete_row(unsigned char const*) /data/src/10.3/storage/innobase/handler/ha_innodb.cc:8999
    #4 0x55dd8cc5ff9d in handler::ha_delete_row(unsigned char const*) /data/src/10.3/sql/handler.cc:6508
    #5 0x55dd8c4d718b in write_record(THD*, TABLE*, st_copy_info*) /data/src/10.3/sql/sql_insert.cc:1981
    #6 0x55dd8c4e579b in select_insert::send_data(List<Item>&) /data/src/10.3/sql/sql_insert.cc:3874
    #7 0x55dd8c680d71 in end_send /data/src/10.3/sql/sql_select.cc:20582
    #8 0x55dd8c679274 in evaluate_join_record /data/src/10.3/sql/sql_select.cc:19618
    #9 0x55dd8c6b1629 in AGGR_OP::end_send() /data/src/10.3/sql/sql_select.cc:27453
    #10 0x55dd8c676ffa in sub_select_postjoin_aggr(JOIN*, st_join_table*, bool) /data/src/10.3/sql/sql_select.cc:19114
    #11 0x55dd8c677797 in sub_select(JOIN*, st_join_table*, bool) /data/src/10.3/sql/sql_select.cc:19349
    #12 0x55dd8c676338 in do_select /data/src/10.3/sql/sql_select.cc:18940
    #13 0x55dd8c614be4 in JOIN::exec_inner() /data/src/10.3/sql/sql_select.cc:4042
    #14 0x55dd8c612887 in JOIN::exec() /data/src/10.3/sql/sql_select.cc:3836
    #15 0x55dd8c615cf6 in mysql_select(THD*, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) /data/src/10.3/sql/sql_select.cc:4241
    #16 0x55dd8c5f0b3f in handle_select(THD*, LEX*, select_result*, unsigned long) /data/src/10.3/sql/sql_select.cc:373
    #17 0x55dd8c569e71 in mysql_execute_command(THD*) /data/src/10.3/sql/sql_parse.cc:4844
    #18 0x55dd8c57ea5f in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /data/src/10.3/sql/sql_parse.cc:8098
    #19 0x55dd8c559211 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /data/src/10.3/sql/sql_parse.cc:1858
    #20 0x55dd8c5561c8 in do_command(THD*) /data/src/10.3/sql/sql_parse.cc:1403
    #21 0x55dd8c8ba33e in do_handle_one_connection(CONNECT*) /data/src/10.3/sql/sql_connect.cc:1402
    #22 0x55dd8c8b9d1a in handle_one_connection /data/src/10.3/sql/sql_connect.cc:1308
    #23 0x55dd8dc605b5 in pfs_spawn_thread /data/src/10.3/storage/perfschema/pfs.cc:1862
    #24 0x7f9940fb84a3 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x74a3)
    #25 0x7f993f500d0e in __clone (/lib/x86_64-linux-gnu/libc.so.6+0xe8d0e)
 
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /data/src/10.3/storage/innobase/row/row0upd.cc:3272 in row_upd
Thread T27 created by T0 here:
    #0 0x7f99411fef59 in __interceptor_pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.3+0x30f59)
    #1 0x55dd8dc609f1 in spawn_thread_v1 /data/src/10.3/storage/perfschema/pfs.cc:1912
    #2 0x55dd8c2d0590 in inline_mysql_thread_create /data/src/10.3/include/mysql/psi/mysql_thread.h:1268
    #3 0x55dd8c2e5506 in create_thread_to_handle_connection(CONNECT*) /data/src/10.3/sql/mysqld.cc:6605
    #4 0x55dd8c2e5bfd in create_new_thread /data/src/10.3/sql/mysqld.cc:6675
    #5 0x55dd8c2e6c24 in handle_connections_sockets() /data/src/10.3/sql/mysqld.cc:6950
    #6 0x55dd8c2e49be in mysqld_main(int, char**) /data/src/10.3/sql/mysqld.cc:6227
    #7 0x55dd8c2cecaf in main /data/src/10.3/sql/main.cc:25
    #8 0x7f993f4382e0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202e0)
 
==11592==ABORTING

10.3 non-debug

#3  <signal handler called>
#4  row_upd_del_mark_clust_rec (mtr=0x7f28dc3f85a0, foreign=false, referenced=0, thr=0x7f2890073170, offsets=0x7f28dc3f7c80, index=0x7f2890070ad0, node=0x7f2890072e18) at /data/src/10.3/storage/innobase/row/row0upd.cc:2987
#5  row_upd_clust_step (node=node@entry=0x7f2890072e18, thr=thr@entry=0x7f2890073170) at /data/src/10.3/storage/innobase/row/row0upd.cc:3172
#6  0x0000555cf50d7534 in row_upd (thr=0x7f2890073170, node=0x7f2890072e18) at /data/src/10.3/storage/innobase/row/row0upd.cc:3299
#7  row_upd_step (thr=thr@entry=0x7f2890073170) at /data/src/10.3/storage/innobase/row/row0upd.cc:3443
#8  0x0000555cf50ac98c in row_update_for_mysql (prebuilt=0x7f28900722a0) at /data/src/10.3/storage/innobase/row/row0mysql.cc:1889
#9  0x0000555cf4fff3fe in ha_innobase::delete_row (this=0x7f28900817b0, record=0x7f2890070008 "\377\003") at /data/src/10.3/storage/innobase/handler/ha_innodb.cc:8999
#10 0x0000555cf4e99914 in handler::ha_delete_row (this=0x7f28900817b0, buf=0x7f2890070008 "\377\003") at /data/src/10.3/sql/handler.cc:6508
#11 0x0000555cf4c9e832 in write_record (thd=0x7f28900009a8, table=0x7f2890080bd8, info=info@entry=0x7f28900103f8) at /data/src/10.3/sql/sql_insert.cc:1981
#12 0x0000555cf4c9f0ff in select_insert::send_data (this=0x7f28900103b0, values=...) at /data/src/10.3/sql/sql_insert.cc:3874
#13 0x0000555cf4d0d77f in end_send (join=0x7f2890010460, join_tab=0x7f2890012e90, end_of_records=<optimized out>) at /data/src/10.3/sql/sql_select.cc:20582
#14 0x0000555cf4cf4fcd in evaluate_join_record (join=join@entry=0x7f2890010460, join_tab=0x7f2890012ae0, error=error@entry=0) at /data/src/10.3/sql/sql_select.cc:19618
#15 0x0000555cf4d1bcc4 in AGGR_OP::end_send (this=0x7f28900133d0) at /data/src/10.3/sql/sql_select.cc:27453
#16 0x0000555cf4d1be0d in sub_select_postjoin_aggr (join=0x7f2890010460, join_tab=0x7f2890012ae0, end_of_records=<optimized out>) at /data/src/10.3/sql/sql_select.cc:19114
#17 0x0000555cf4d1ca32 in do_select (procedure=<optimized out>, join=0x7f2890010460) at /data/src/10.3/sql/sql_select.cc:18940
#18 JOIN::exec_inner (this=this@entry=0x7f2890010460) at /data/src/10.3/sql/sql_select.cc:4042
#19 0x0000555cf4d1cae9 in JOIN::exec (this=this@entry=0x7f2890010460) at /data/src/10.3/sql/sql_select.cc:3836
#20 0x0000555cf4d1cc42 in mysql_select (thd=thd@entry=0x7f28900009a8, tables=0x7f289000fce0, wild_num=<optimized out>, fields=..., conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=3489925888, result=0x7f28900103b0, unit=0x7f28900046b0, select_lex=0x7f2890004e28) at /data/src/10.3/sql/sql_select.cc:4241
#21 0x0000555cf4d1d597 in handle_select (thd=thd@entry=0x7f28900009a8, lex=lex@entry=0x7f28900045e8, result=result@entry=0x7f28900103b0, setup_tables_done_option=setup_tables_done_option@entry=1073741824) at /data/src/10.3/sql/sql_select.cc:373
#22 0x0000555cf4cd1891 in mysql_execute_command (thd=thd@entry=0x7f28900009a8) at /data/src/10.3/sql/sql_parse.cc:4844
#23 0x0000555cf4cd22b9 in mysql_parse (thd=thd@entry=0x7f28900009a8, rawbuf=<optimized out>, length=27, parser_state=parser_state@entry=0x7f28dc3fa630, is_com_multi=<optimized out>, is_next_command=<optimized out>) at /data/src/10.3/sql/sql_parse.cc:8098
#24 0x0000555cf4cd4b05 in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x7f28900009a8, packet=packet@entry=0x7f28900070a9 "REPLACE t1 SELECT * FROM t1", packet_length=packet_length@entry=27, is_com_multi=is_com_multi@entry=false, is_next_command=is_next_command@entry=false) at /data/src/10.3/sql/sql_parse.cc:1858
#25 0x0000555cf4cd5776 in do_command (thd=0x7f28900009a8) at /data/src/10.3/sql/sql_parse.cc:1403
#26 0x0000555cf4d9ac14 in do_handle_one_connection (connect=connect@entry=0x555cf77d4708) at /data/src/10.3/sql/sql_connect.cc:1402
#27 0x0000555cf4d9ad94 in handle_one_connection (arg=arg@entry=0x555cf77d4708) at /data/src/10.3/sql/sql_connect.cc:1308
#28 0x0000555cf5305424 in pfs_spawn_thread (arg=0x555cf7795288) at /data/src/10.3/storage/perfschema/pfs.cc:1862
#29 0x00007f28e4ba34a4 in start_thread (arg=0x7f28dc3fb700) at pthread_create.c:456
#30 0x00007f28e30ebd0f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:97



 Comments   
Comment by Marko Mäkelä [ 2019-05-16 ]

I wrote a debug check that catches the problem. I think that something like this should be part of the final fix:

diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 234a33b844e..b0c3ed81403 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -3485,13 +3485,19 @@ void upd_node_t::make_versioned_helper(const trx_t* trx, ulint idx)
 
 	dict_index_t* clust_index = dict_table_get_first_index(table);
 
+	ut_ad(update->n_fields < table->n_cols + table->n_v_cols);
 	update->n_fields++;
-	upd_field_t* ufield =
-		upd_get_nth_field(update, upd_get_n_fields(update) - 1);
+	upd_field_t* ufield = upd_get_nth_field(update, update->n_fields - 1);
 	const dict_col_t* col = dict_table_get_nth_col(table, idx);
 
 	upd_field_set_field_no(ufield, dict_col_get_clust_pos(col, clust_index),
 			       clust_index);
+#ifdef UNIV_DEBUG
+	for (ulint i = update->n_fields - 1; i--; ) {
+		ut_ad(upd_get_nth_field(update, i)->field_no
+		      != ufield->field_no);
+	}
+#endif
 
 	char* where = reinterpret_cast<char*>(update->vers_sys_value);
 	if (col->vers_native()) {

The problem is we are adding duplicated field numbers in the update vector, causing the vector to grow beyond its allocated capacity. Here is the stack trace for the assertion failure:

#4  0x00005555564a6f32 in upd_node_t::make_versioned_helper (this=0x7fff8c028868, trx=0x7ffff0bcd0f0, idx=2) at /mariadb/10.3/storage/innobase/row/row0upd.cc:3497
#5  0x00005555564a706a in upd_node_t::make_versioned_update (this=0x7fff8c028868, trx=0x7ffff0bcd0f0) at /mariadb/10.3/storage/innobase/row/row0upd.cc:3516
#6  0x0000555556434dfa in row_update_for_mysql (prebuilt=0x7fff8c027cb8) at /mariadb/10.3/storage/innobase/row/row0mysql.cc:1880
#7  0x000055555627cda4 in ha_innobase::delete_row (this=0x7fff8c01dd80, record=0x7fff8c0130a0 "\375\001") at /mariadb/10.3/storage/innobase/handler/ha_innodb.cc:8999

This occurs during the execution of the second (last-but-one) REPLACE statement.

Comment by Eugene Kosov (Inactive) [ 2019-05-19 ]

A silly bug in upd_node_t::make_versioned_helper(): forget to allocate bigger array before appending a new record to the end. But this is not related to this MDEVs problem.

The real bug was about ha_innobase::write_row() which changed table->record[0] buffer when it was not needed. Well, I guess it's never needed because it's against handler::write_row() specification.

I'm not sure that this bug is related to ones mentioned in the description.

Generated at Thu Feb 08 08:52:03 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.