summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2019-09-23 13:25:11 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2019-09-23 13:46:24 +0530
commitdff55817cd868eedffe6ce0539764568df1d614f (patch)
treeabba5259e0677342835b1c22c322a71ea978dc26
parent66376a9be217eba20944e9ca2161a7f492a71398 (diff)
downloadmariadb-git-10.5-MDEV-16678.tar.gz
- Reverted 2c4844c9e76427525e8c39a2d72686085efe89c3. The scenario10.5-MDEV-16678
become useless after purge thread uses MDL
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_purge.result22
-rw-r--r--mysql-test/suite/innodb/r/purge_thread_shutdown.result2
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_purge.test38
-rw-r--r--storage/innobase/handler/ha_innodb.cc8
-rw-r--r--storage/innobase/handler/handler0alter.cc62
-rw-r--r--storage/innobase/row/row0purge.cc8
6 files changed, 7 insertions, 133 deletions
diff --git a/mysql-test/suite/innodb/r/instant_alter_purge.result b/mysql-test/suite/innodb/r/instant_alter_purge.result
index a3643610f04..1179ff62ecc 100644
--- a/mysql-test/suite/innodb/r/instant_alter_purge.result
+++ b/mysql-test/suite/innodb/r/instant_alter_purge.result
@@ -21,26 +21,4 @@ ALTER TABLE t1 DROP extra;
disconnect prevent_purge;
InnoDB 0 transactions not purged
DROP TABLE t1;
-#
-# MDEV-17813 Crash in instant ALTER TABLE due to purge
-# concurrently emptying table
-#
-CREATE TABLE t1 (f2 INT) ENGINE=InnoDB;
-INSERT INTO t1 SET f2=1;
-ALTER TABLE t1 ADD COLUMN f1 INT;
-connect purge_control,localhost,root;
-START TRANSACTION WITH CONSISTENT SNAPSHOT;
-connection default;
-DELETE FROM t1;
-SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL go WAIT_FOR do';
-ALTER TABLE t1 ADD COLUMN f3 INT;
-connection purge_control;
-SET DEBUG_SYNC='now WAIT_FOR go';
-COMMIT;
-InnoDB 0 transactions not purged
-SET DEBUG_SYNC='now SIGNAL do';
-disconnect purge_control;
-connection default;
-SET DEBUG_SYNC=RESET;
-DROP TABLE t1;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/mysql-test/suite/innodb/r/purge_thread_shutdown.result b/mysql-test/suite/innodb/r/purge_thread_shutdown.result
index a87cba89917..f1b0cb07ce8 100644
--- a/mysql-test/suite/innodb/r/purge_thread_shutdown.result
+++ b/mysql-test/suite/innodb/r/purge_thread_shutdown.result
@@ -6,6 +6,7 @@ select user,state from information_schema.processlist order by 2;
user state
root
root Filling schema table
+system user InnoDB fts optimize thread
system user InnoDB purge coordinator
system user InnoDB purge worker
system user InnoDB purge worker
@@ -19,6 +20,7 @@ disconnect con1;
select user,state from information_schema.processlist order by 2;
user state
root Filling schema table
+system user InnoDB fts optimize thread
system user InnoDB purge coordinator
system user InnoDB purge worker
system user InnoDB purge worker
diff --git a/mysql-test/suite/innodb/t/instant_alter_purge.test b/mysql-test/suite/innodb/t/instant_alter_purge.test
index 152d200d977..9ccf3347d7b 100644
--- a/mysql-test/suite/innodb/t/instant_alter_purge.test
+++ b/mysql-test/suite/innodb/t/instant_alter_purge.test
@@ -34,42 +34,4 @@ disconnect prevent_purge;
let $wait_all_purged= 0;
--source include/wait_all_purged.inc
DROP TABLE t1;
-
---echo #
---echo # MDEV-17813 Crash in instant ALTER TABLE due to purge
---echo # concurrently emptying table
---echo #
-CREATE TABLE t1 (f2 INT) ENGINE=InnoDB;
-INSERT INTO t1 SET f2=1;
-ALTER TABLE t1 ADD COLUMN f1 INT;
-
-connect (purge_control,localhost,root);
-START TRANSACTION WITH CONSISTENT SNAPSHOT;
-
-connection default;
-DELETE FROM t1;
-
-if ($have_debug) {
-SET DEBUG_SYNC='innodb_commit_inplace_alter_table_enter SIGNAL go WAIT_FOR do';
-}
-send ALTER TABLE t1 ADD COLUMN f3 INT;
-
-connection purge_control;
-if ($have_debug) {
-SET DEBUG_SYNC='now WAIT_FOR go';
-}
-COMMIT;
---source include/wait_all_purged.inc
-if ($have_debug) {
-SET DEBUG_SYNC='now SIGNAL do';
-}
-disconnect purge_control;
-
-connection default;
-reap;
-if ($have_debug) {
-SET DEBUG_SYNC=RESET;
-}
-DROP TABLE t1;
-
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 63236ea2342..b78a103ed5b 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -5931,14 +5931,6 @@ initialize_auto_increment(dict_table_t* table, const Field* field)
int
ha_innobase::open(const char* name, int, uint)
{
- /* TODO: If trx_rollback_recovered(bool all=false) is ever
- removed, the first-time open() must hold (or acquire and release)
- a table lock that conflicts with trx_resurrect_table_locks(),
- to ensure that any recovered incomplete ALTER TABLE will have been
- rolled back. Otherwise, dict_table_t::instant could be cleared by
- the rollback invoking dict_index_t::clear_instant_alter() while
- open table handles exist in client connections. */
-
char norm_name[FN_REFLEN];
DBUG_ENTER("ha_innobase::open");
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 2c8328a42bb..b4e269f7a94 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -140,30 +140,6 @@ static const alter_table_operations INNOBASE_ALTER_INSTANT
| ALTER_RENAME_INDEX
| ALTER_DROP_VIRTUAL_COLUMN;
-/** Acquire a page latch on the possible metadata record,
-to prevent concurrent invocation of dict_index_t::clear_instant_alter()
-by purge when the table turns out to be empty.
-@param[in,out] index clustered index
-@param[in,out] mtr mini-transaction */
-static void instant_metadata_lock(dict_index_t& index, mtr_t& mtr)
-{
- DBUG_ASSERT(index.is_primary());
-
- if (!index.is_instant()) {
- /* dict_index_t::clear_instant_alter() cannot be called.
- No need for a latch. */
- return;
- }
-
- btr_cur_t btr_cur;
- btr_cur_open_at_index_side(true, &index, BTR_SEARCH_LEAF,
- &btr_cur, 0, &mtr);
- ut_ad(page_cur_is_before_first(btr_cur_get_page_cur(&btr_cur)));
- ut_ad(page_is_leaf(btr_cur_get_page(&btr_cur)));
- ut_ad(!page_has_prev(btr_cur_get_page(&btr_cur)));
- ut_ad(!buf_block_get_page_zip(btr_cur_get_block(&btr_cur)));
-}
-
/** Initialize instant->field_map.
@tparam replace_dropped whether to point clustered index fields
to instant->dropped[]
@@ -242,16 +218,10 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old,
If that is the case, the instant ALTER TABLE would keep
the InnoDB table in its current format. */
- dict_index_t& oindex = *old.indexes.start;
+ const dict_index_t& oindex = *old.indexes.start;
dict_index_t& index = *indexes.start;
first_alter_pos = 0;
- mtr_t mtr;
- mtr.start();
- /* Protect oindex.n_core_fields and others, so that
- purge cannot invoke dict_index_t::clear_instant_alter(). */
- instant_metadata_lock(oindex, mtr);
-
for (unsigned i = 0; i + DATA_N_SYS_COLS < old.n_cols; i++) {
if (col_map[i] != i) {
first_alter_pos = 1 + i;
@@ -424,7 +394,6 @@ found_j:
DBUG_ASSERT(n_dropped() >= old.n_dropped());
DBUG_ASSERT(index.n_core_fields == oindex.n_core_fields);
DBUG_ASSERT(index.n_core_null_bytes == oindex.n_core_null_bytes);
- mtr.commit();
}
/** Adjust index metadata for instant ADD/DROP/reorder COLUMN.
@@ -444,15 +413,8 @@ inline void dict_index_t::instant_add_field(const dict_index_t& instant)
DBUG_ASSERT(n_uniq == instant.n_uniq);
DBUG_ASSERT(instant.n_fields >= n_fields);
DBUG_ASSERT(instant.n_nullable >= n_nullable);
- /* dict_table_t::prepare_instant() initialized n_core_fields
- to be equal. However, after that purge could have emptied the
- table and invoked dict_index_t::clear_instant_alter(). */
- DBUG_ASSERT(instant.n_core_fields <= n_core_fields);
- DBUG_ASSERT(instant.n_core_null_bytes <= n_core_null_bytes);
- DBUG_ASSERT(instant.n_core_fields == n_core_fields
- || (!is_instant() && instant.is_instant()));
- DBUG_ASSERT(instant.n_core_null_bytes == n_core_null_bytes
- || (!is_instant() && instant.is_instant()));
+ DBUG_ASSERT(instant.n_core_fields == n_core_fields);
+ DBUG_ASSERT(instant.n_core_null_bytes == n_core_null_bytes);
/* instant will have all fields (including ones for columns
that have been or are being instantly dropped) in the same position
@@ -755,11 +717,6 @@ inline void dict_table_t::rollback_instant(
{
ut_d(dict_sys.assert_locked());
dict_index_t* index = indexes.start;
- mtr_t mtr;
- mtr.start();
- /* Prevent concurrent execution of dict_index_t::clear_instant_alter()
- by acquiring a latch on the leftmost leaf page. */
- instant_metadata_lock(*index, mtr);
/* index->is_instant() does not necessarily hold here, because
the table may have been emptied */
DBUG_ASSERT(old_n_cols >= DATA_N_SYS_COLS);
@@ -814,7 +771,6 @@ inline void dict_table_t::rollback_instant(
}
index->fields = old_fields;
- mtr.commit();
while ((index = dict_table_get_next_index(index)) != NULL) {
if (index->to_be_dropped) {
@@ -5628,12 +5584,6 @@ static bool innobase_instant_try(
dict_table_t* user_table = ctx->old_table;
dict_index_t* index = dict_table_get_first_index(user_table);
- mtr_t mtr;
- mtr.start();
- /* Prevent purge from calling dict_index_t::clear_instant_alter(),
- to protect index->n_core_fields, index->table->instant and others
- from changing during ctx->instant_column(). */
- instant_metadata_lock(*index, mtr);
const unsigned n_old_fields = index->n_fields;
const dict_col_t* old_cols = user_table->cols;
DBUG_ASSERT(user_table->n_cols == ctx->old_n_cols);
@@ -5641,11 +5591,6 @@ static bool innobase_instant_try(
const bool metadata_changed = ctx->instant_column();
DBUG_ASSERT(index->n_fields >= n_old_fields);
- /* Release the page latch. Between this and the next
- btr_pcur_open_at_index_side(), data fields such as
- index->n_core_fields and index->table->instant could change,
- but we would handle that in empty_table: below. */
- mtr.commit();
/* The table may have been emptied and may have lost its
'instantness' during this ALTER TABLE. */
@@ -5801,6 +5746,7 @@ add_all_virtual:
memset(roll_ptr, 0, sizeof roll_ptr);
dtuple_t* entry = index->instant_metadata(*row, ctx->heap);
+ mtr_t mtr;
mtr.start();
index->set_modified(mtr);
btr_pcur_t pcur;
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 1e8cd1ada71..d072affa11b 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -108,6 +108,7 @@ row_purge_remove_clust_if_poss_low(
mtr_t mtr;
mtr.start();
+ index->set_modified(mtr);
if (!row_purge_reposition_pcur(mode, node, &mtr)) {
/* The record was already removed. */
@@ -115,9 +116,6 @@ row_purge_remove_clust_if_poss_low(
return true;
}
- ut_d(const bool was_instant = !!index->table->instant);
- index->set_modified(mtr);
-
rec_t* rec = btr_pcur_get_rec(&node->pcur);
ulint offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_);
@@ -157,10 +155,6 @@ row_purge_remove_clust_if_poss_low(
}
}
- /* Prove that dict_index_t::clear_instant_alter() was
- not called with index->table->instant != NULL. */
- ut_ad(!was_instant || index->table->instant);
-
func_exit:
if (heap) {
mem_heap_free(heap);