summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2023-03-26 00:26:05 +0300
committerNikita Malyavin <nikitamalyavin@gmail.com>2023-05-05 16:12:01 +0300
commit20c104e00c007f3ef6896872237574976483141d (patch)
treecb7073399a2f683182d1226551b2b47c1020507b
parent843872f1dd435629172dcdc055ff53647fa7822b (diff)
downloadmariadb-git-20c104e00c007f3ef6896872237574976483141d.tar.gz
MDEV-30925 Assertion failed in translog_write_record in ONLINE ALTER + Aria
This is the corner case of ONLINE ALTER vs ha_maria vs App-time Periods. When a Delete_rows_event (or update) is executed, a lookup handler may be created, normally to serve long unique index needs, by a call of handler::prepare_for_insert. This function also creates a lookup handler if an application-time period exists in a table. A difference with a usual call of prepare_for_insert is that transactions are disabled for this table during ALTER TABLE. See mysql_trans_prepare_alter_copy_data call in copy_data_between_tables. Then, ha_maria calls _ma_tmp_disable_logging_for_table during ha_maria::external_lock. It never happened so before, that two handlers would be created for write to a single ha_maria table under transactions disabled. Hence, the fix handles this scenario. It could be done otherwise, by not creating this lookup handler (since it's not used anyway during ONLINE ALTER), but architecturally, two handlers should be supported. Avoiding the creation of lookup handler could be done here additionally, but with a cost of slowing down other more generic cases, with an additional check of online alter table active.
-rw-r--r--mysql-test/main/alter_table_online_debug.result14
-rw-r--r--mysql-test/main/alter_table_online_debug.test19
-rw-r--r--storage/maria/ha_maria.cc7
3 files changed, 38 insertions, 2 deletions
diff --git a/mysql-test/main/alter_table_online_debug.result b/mysql-test/main/alter_table_online_debug.result
index c1ffcfb9c31..c4c1cf67504 100644
--- a/mysql-test/main/alter_table_online_debug.result
+++ b/mysql-test/main/alter_table_online_debug.result
@@ -1176,5 +1176,19 @@ drop table t1;
drop procedure p;
set debug_sync=reset;
#
+# MDEV-30902 Server crash in LEX::first_lists_tables_same
+#
+create table t (id int, s date, e date, period for p(s,e),
+unique(id, p without overlaps)) engine=aria;
+insert into t values (1,'1971-01-01','1971-01-02');
+set debug_sync= 'alter_table_online_before_lock signal lock wait_for goon';
+alter table t force;
+connection con1;
+set debug_sync= 'now wait_for lock';
+delete from t;
+set debug_sync= 'now signal goon';
+connection default;
+drop table t;
+#
# End of 10.10 tests
#
diff --git a/mysql-test/main/alter_table_online_debug.test b/mysql-test/main/alter_table_online_debug.test
index a2daea080f0..9e118d73996 100644
--- a/mysql-test/main/alter_table_online_debug.test
+++ b/mysql-test/main/alter_table_online_debug.test
@@ -1352,5 +1352,24 @@ drop procedure p;
set debug_sync=reset;
--echo #
+--echo # MDEV-30902 Server crash in LEX::first_lists_tables_same
+--echo #
+create table t (id int, s date, e date, period for p(s,e),
+ unique(id, p without overlaps)) engine=aria;
+insert into t values (1,'1971-01-01','1971-01-02');
+
+set debug_sync= 'alter_table_online_before_lock signal lock wait_for goon';
+send alter table t force;
+
+--connection con1
+set debug_sync= 'now wait_for lock';
+delete from t;
+set debug_sync= 'now signal goon';
+
+--connection default
+--reap
+drop table t;
+
+--echo #
--echo # End of 10.10 tests
--echo #
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index f82823dba2b..3fd742955fc 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -2958,8 +2958,11 @@ int ha_maria::external_lock(THD *thd, int lock_type)
tons of archived logs to roll-forward, we could then not disable
REDOs/UNDOs in this case.
*/
- DBUG_PRINT("info", ("Disabling logging for table"));
- _ma_tmp_disable_logging_for_table(file, TRUE);
+ if (likely(file->s->now_transactional))
+ {
+ DBUG_PRINT("info", ("Disabling logging for table"));
+ _ma_tmp_disable_logging_for_table(file, TRUE);
+ }
file->autocommit= 0;
}
else