summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2022-07-05 01:19:12 +0300
committerNikita Malyavin <nikitamalyavin@gmail.com>2022-07-05 15:20:04 +0300
commit3e2d297830bca8921f1f24d03372bc0bc787dba0 (patch)
treea8cb80ad5f2d74f043f6d2b2eabca9cbf82df601 /sql/sql_table.cc
parentc1feb8c3c32ff9029d3d7905c14f525e78282d19 (diff)
downloadmariadb-git-bb-10.10-MDEV-29021.tar.gz
MDEV-29013 ER_KEY_NOT_FOUND/lock timeout upon online alter with long uniquebb-10.10-MDEV-29021
1. ER_KEY_NOT_FOUND Some virtual columns were not updated because were not included in read_set to the moment of calculation. In Row_logs_event::do_apply_event some fields are excluded based on m_cols value, the number of replicated rows. We can't rely on this. Basically, we'd be satisfied, if all columns were just set, at least for now. 2. ER_LOCK_WAIT_TIMEOUT This is a long unique specific problem. Sometimes, lookup_handler is created for to->file. To properly free it, ha_reset should be called. It is usually done by calling close_thread_table, but ALTER TABLE makes it differently. Hence, a single ha_reset call is added to mysql_alter_table. Also, the lifetime of lookup_handler is corrected: it's been allocated on thd->mem_root, which in case of online alter is event's mem_root, and can vary other ways. It is changed to table->mem_root, which is more appropriate: ha_reset is called only when table is closed, or in a few additional cases, which correspond to a statement end. So memory leaks are unlikely here.
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc8
1 files changed, 7 insertions, 1 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 29c4d09cd39..a3efcdd9785 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -11011,6 +11011,9 @@ do_continue:;
!(table->file->ha_table_flags() & HA_REUSES_FILE_NAMES) &&
!(new_table->file->ha_table_flags() &
HA_REUSES_FILE_NAMES));
+
+ // Close lookup_handler.
+ new_table->file->ha_reset();
/*
Close the intermediate table that will be the new table, but do
not delete it! Even though MERGE tables do not have their children
@@ -11854,8 +11857,11 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
// We'll be filling from->record[0] from row events
bitmap_set_all(from->write_set);
- // We restore bitmaps, because update event is going to mess up with them.
+ // Use all columns. UPDATE/DELETE events reset read_set and write_set to
+ // def_*_set after each row operation, so using all_set won't work.
to->default_column_bitmaps();
+ bitmap_set_all(&to->def_read_set);
+ bitmap_set_all(&to->def_write_set);
end_read_record(&info);
init_read_record_done= false;