[MDEV-31777] ER_GET_ERRNO upon online alter with concurrent DML on CONNECT table Created: 2023-07-25  Updated: 2023-08-16  Resolved: 2023-08-16

Status: Closed
Project: MariaDB Server
Component/s: Data Definition - Alter Table, Storage Engine - Connect
Affects Version/s: None
Fix Version/s: 11.2.1

Type: Bug Priority: Critical
Reporter: Elena Stepanova Assignee: Nikita Malyavin
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Problem/Incident
is caused by MDEV-16329 Engine-independent online ALTER TABLE Closed

 Description   

Note: Some Connect table types don't support the copy algorithm (MDEV-30909) and there are legacy failures with others (MDEV-30914, MDEV-30915, MDEV-30907); but ALTER like the one this report, on a DOS table type, seems to work when no concurrency is involved.

--source include/have_debug_sync.inc
 
install soname 'ha_connect';
 
create table t (a int) engine=Connect table_type=DOS;
insert into t values (1),(2);
--send set debug_sync= 'now wait_for go_dml'
 
--connect (con1,localhost,root,,)
set debug_sync='alter_table_online_progress signal go_dml wait_for go_alter';
--send alter table t add b int, algorithm=copy, lock=none
 
--connection default
--reap
delete from t where a = 2;
set debug_sync= 'now signal go_alter';
 
--connection con1
--reap
select * from t;
 
# Cleanup
drop table t;
uninstall soname 'ha_connect';

bb-11.2-oalter b0484157ecd33e153e181d9ca4c055b82046ffea

At line 19: query 'reap' failed: ER_GET_ERRNO (1030): Got error 174 "Fatal error during initialization of handler" from storage engine CONNECT



 Comments   
Comment by Nikita Malyavin [ 2023-07-28 ]

Apparently, CONNECT has never supported any access to the new table other that insert. First, during the first wite_row:

l
  // This is not tested yet
  if (xmod == MODE_ALTER) {
     ...
 
    xmod= MODE_INSERT;
  }
 
bt
#0  ha_connect::write_row (this=0x61e0000624b8, buf=0x6190000d25c8 "\375\001") at /home/nik/mariadb/storage/connect/ha_connect.cc:3694
#1  0x0000564da8f9ea89 in handler::ha_write_row (this=0x61e0000624b8, buf=0x6190000d25c8 "\375\001") at /home/nik/mariadb/sql/handler.cc:7828
#2  0x0000564da9e981f9 in copy_data_between_tables (thd=0x62b0001ab218, from=0x6190000c0d98, to=0x6190000d2098, create=..., ignore=false, order_num=0, order=0x0, copied=0x7fe2373d38b0, deleted=0x7fe2373d38d0, keys_onoff=Alter_info::LEAVE_AS_IS, alter_ctx=0x7fe2373d44f0, online=true, start_alter_id=0) at /home/nik/mariadb/sql/sql_table.cc:12024
#3  0x0000564da9e78de5 in mysql_alter_table (thd=0x62b0001ab218, new_db=0x62b0001aff18, new_name=0x62b0001b0368, create_info=0x7fe2373d8380, table_list=0x6290002b7378, recreate_info=0x7fe2373d8fc0, alter_info=0x7fe2373d8680, order_num=0, order=0x0, ignore=false, if_exists=false) at /home/nik/mariadb/sql/sql_table.cc:11172
#4  0x0000564daa12fe6e in Sql_cmd_alter_table::execute (this=0x6290002b7bf0, thd=0x62b0001ab218) at /home/nik/mariadb/sql/sql_alter.cc:571
#5  0x0000564da9acb659 in mysql_execute_command (thd=0x62b0001ab218, is_called_from_prepared_stmt=false) at /home/nik/mariadb/sql/sql_parse.cc:5764
#6  0x0000564da9aaa31b in mysql_parse (thd=0x62b0001ab218, rawbuf=0x6290002b7238 "alter table t add b int, algorithm=copy, lock=none", length=50, parser_state=0x7fe2373dccf0) at /home/nik/mariadb/sql/sql_parse.cc:7772
#7  0x0000564da9aa3d40 in dispatch_command (command=COM_QUERY, thd=0x62b0001ab218, packet=0x6290002ad219 "alter table t add b int, algorithm=copy, lock=none", packet_length=50, blocking=true) at /home/nik/mariadb/sql/sql_parse.cc:1892
...

Then, in ha_connect::rnd_init:

  if (!g || !table || xmod == MODE_INSERT)
    DBUG_RETURN(HA_ERR_INITIALIZATION);
 
#0  ha_connect::rnd_init (this=0x61e0000624b8, scan=true) at /home/nik/mariadb/storage/connect/ha_connect.cc:4134
#1  0x0000564da8fb10bf in handler::ha_rnd_init (this=0x61e0000624b8, scan=true) at /home/nik/mariadb/sql/handler.h:3464
#2  0x0000564da8f758f9 in handler::ha_rnd_init_with_error (this=0x61e0000624b8, scan=true) at /home/nik/mariadb/sql/handler.cc:3824
#3  0x0000564da954d445 in Rows_log_event::find_row (this=0x6130000a0258, rgi=0x7fe2373d1730) at /home/nik/mariadb/sql/log_event_server.cc:7628
#4  0x0000564da954f187 in Delete_rows_log_event::do_exec_row (this=0x6130000a0258, rgi=0x7fe2373d1730) at /home/nik/mariadb/sql/log_event_server.cc:7759
#5  0x0000564da9531435 in Rows_log_event::do_apply_event (this=0x6130000a0258, rgi=0x7fe2373d1730) at /home/nik/mariadb/sql/log_event_server.cc:5112
#6  0x0000564da94d85bf in Log_event::apply_event (this=0x6130000a0258, rgi=0x7fe2373d1730) at /home/nik/mariadb/sql/log_event.cc:3867
#7  0x0000564da9eaebe8 in online_alter_read_from_binlog (thd=0x62b0001ab218, rgi=0x7fe2373d1730, log=0x61d0002b2080, found_rows=0x7fe2373ccd20) at /home/nik/mariadb/sql/sql_table.cc:11717
#8  0x0000564da9e9a0e0 in copy_data_between_tables (thd=0x62b0001ab218, from=0x6190000c0d98, to=0x6190000d2098, create=..., ignore=false, order_num=0, order=0x0, copied=0x7fe2373d38b0, deleted=0x7fe2373d38d0, keys_onoff=Alter_info::LEAVE_AS_IS, alter_ctx=0x7fe2373d44f0, online=true, start_alter_id=0) at /home/nik/mariadb/sql/sql_table.cc:12175
#9  0x0000564da9e78de5 in mysql_alter_table (thd=0x62b0001ab218, new_db=0x62b0001aff18, new_name=0x62b0001b0368, create_info=0x7fe2373d8380, table_list=0x6290002b7378, recreate_info=0x7fe2373d8fc0, alter_info=0x7fe2373d8680, order_num=0, order=0x0, ignore=false, if_exists=false) at /home/nik/mariadb/sql/sql_table.cc:11172
#10 0x0000564daa12fe6e in Sql_cmd_alter_table::execute (this=0x6290002b7bf0, thd=0x62b0001ab218) at /home/nik/mariadb/sql/sql_alter.cc:571
#11 0x0000564da9acb659 in mysql_execute_command (thd=0x62b0001ab218, is_called_from_prepared_stmt=false) at /home/nik/mariadb/sql/sql_parse.cc:5764
#12 0x0000564da9aaa31b in mysql_parse (thd=0x62b0001ab218, rawbuf=0x6290002b7238 "alter table t add b int, algorithm=copy, lock=none", length=50, parser_state=0x7fe2373dccf0) at /home/nik/mariadb/sql/sql_parse.cc:7772
...

For now I'm going to try to reinit xmod by HA_EXTRA_END_ALTER_COPY.

Comment by Nikita Malyavin [ 2023-07-28 ]

CONNECT won't be able to support Online alter. It can only support a single-type command statements, like simple DELETEs or UPDATEs.
REPLACE doesn't work by design:

create table t (a int) engine=Connect table_type=DOS;
insert into t values (1),(2);
set @a=0;
create trigger trt after delete on t FOR EACH ROW set @a=@a+1;
replace t values (1);

results in

ER_NOT_ALLOWED_COMMAND (1148): CONNECT Unsupported command

System versioning never worked for it:

create table t (a int) engine=Connect table_type=DOS with system versioning;
insert into t values (1),(2);
delete from t;

mysqltest: At line 11: query 'delete from t' failed: ER_CRASHED_ON_USAGE (1194): Table 't' is marked as crashed and should be repaired

Application-time periods will also never work for it (since UPDATE can delete and insert, and DELETE can update and insert)

EDIT system versioning also will never work for CONNECT since UPDATEs can also make an insert

I suppose it also can't be replicated in the IDEMPOTENT mode

Generated at Thu Feb 08 10:26:23 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.