summaryrefslogtreecommitdiff
path: root/storage/innobase/handler/handler0alter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/handler/handler0alter.cc')
-rw-r--r--storage/innobase/handler/handler0alter.cc56
1 files changed, 42 insertions, 14 deletions
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index e4e84521e8d..5a03ad49875 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -1914,10 +1914,15 @@ innobase_fts_check_doc_id_col(
}
/** Check whether the table is empty.
-@param[in] table table to be checked
+@param[in] table table to be checked
+@param[in] ignore_delete_marked Ignore the delete marked
+ flag record
@return true if table is empty */
-static bool innobase_table_is_empty(const dict_table_t *table)
+static bool innobase_table_is_empty(const dict_table_t *table,
+ bool ignore_delete_marked=true)
{
+ if (!table->space)
+ return false;
dict_index_t *clust_index= dict_table_get_first_index(table);
mtr_t mtr;
btr_pcur_t pcur;
@@ -1955,12 +1960,16 @@ next_page:
}
rec= page_cur_get_rec(cur);
- if (rec_get_deleted_flag(rec, dict_table_is_comp(table)));
- else if (!page_rec_is_supremum(rec))
+ if (rec_get_deleted_flag(rec, dict_table_is_comp(table)))
{
+ if (ignore_delete_marked)
+ goto scan_leaf;
+non_empty:
mtr.commit();
return false;
}
+ else if (!page_rec_is_supremum(rec))
+ goto non_empty;
else
{
next_page= true;
@@ -5816,8 +5825,8 @@ add_all_virtual:
btr_pcur_move_to_next_on_page(&pcur);
buf_block_t* block = btr_pcur_get_block(&pcur);
- ut_ad(page_is_leaf(block->frame));
- ut_ad(!page_has_prev(block->frame));
+ ut_ad(page_is_leaf(block->page.frame));
+ ut_ad(!page_has_prev(block->page.frame));
ut_ad(!buf_block_get_page_zip(block));
const rec_t* rec = btr_pcur_get_rec(&pcur);
que_thr_t* thr = pars_complete_graph_for_exec(
@@ -5830,8 +5839,8 @@ add_all_virtual:
if (is_root
&& !rec_is_alter_metadata(rec, *index)
&& !index->table->instant
- && !page_has_next(block->frame)
- && page_rec_is_last(rec, block->frame)) {
+ && !page_has_next(block->page.frame)
+ && page_rec_is_last(rec, block->page.frame)) {
goto empty_table;
}
@@ -5843,7 +5852,8 @@ add_all_virtual:
buf_block_t* root = btr_root_block_get(index, RW_X_LATCH,
&mtr);
DBUG_ASSERT(root);
- if (fil_page_get_type(root->frame) != FIL_PAGE_TYPE_INSTANT) {
+ if (fil_page_get_type(root->page.frame)
+ != FIL_PAGE_TYPE_INSTANT) {
DBUG_ASSERT("wrong page type" == 0);
err = DB_CORRUPTION;
goto func_exit;
@@ -5914,8 +5924,8 @@ add_all_virtual:
&& !index->table->instant) {
empty_table:
/* The table is empty. */
- ut_ad(fil_page_index_page_check(block->frame));
- ut_ad(!page_has_siblings(block->frame));
+ ut_ad(fil_page_index_page_check(block->page.frame));
+ ut_ad(!page_has_siblings(block->page.frame));
ut_ad(block->page.id().page_no() == index->page);
/* MDEV-17383: free metadata BLOBs! */
btr_page_empty(block, NULL, index, 0, &mtr);
@@ -5933,7 +5943,7 @@ empty_table:
mtr.start();
index->set_modified(mtr);
if (buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH, &mtr)) {
- if (fil_page_get_type(root->frame) != FIL_PAGE_INDEX) {
+ if (fil_page_get_type(root->page.frame) != FIL_PAGE_INDEX) {
DBUG_ASSERT("wrong page type" == 0);
goto err_exit;
}
@@ -6753,6 +6763,7 @@ wrong_column_name:
DBUG_ASSERT(num_fts_index <= 1);
DBUG_ASSERT(!ctx->online || num_fts_index == 0);
DBUG_ASSERT(!ctx->online
+ || !ha_alter_info->mdl_exclusive_after_prepare
|| ctx->add_autoinc == ULINT_UNDEFINED);
DBUG_ASSERT(!ctx->online
|| !innobase_need_rebuild(ha_alter_info, old_table)
@@ -7548,6 +7559,20 @@ ha_innobase::prepare_inplace_alter_table(
DBUG_RETURN(false);
}
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ if (table->part_info == NULL) {
+#endif
+ /* Ignore the MDL downgrade when table is empty.
+ This optimization is disabled for partition table. */
+ ha_alter_info->mdl_exclusive_after_prepare =
+ innobase_table_is_empty(m_prebuilt->table, false);
+ if (ha_alter_info->online
+ && ha_alter_info->mdl_exclusive_after_prepare) {
+ ha_alter_info->online = false;
+ }
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+ }
+#endif
indexed_table = m_prebuilt->table;
/* ALTER TABLE will not implicitly move a table from a single-table
@@ -8344,7 +8369,9 @@ ha_innobase::inplace_alter_table(
DEBUG_SYNC(m_user_thd, "innodb_inplace_alter_table_enter");
- if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA)) {
+ /* Ignore the inplace alter phase when table is empty */
+ if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA)
+ || ha_alter_info->mdl_exclusive_after_prepare) {
ok_exit:
DEBUG_SYNC(m_user_thd, "innodb_after_inplace_alter_table");
DBUG_RETURN(false);
@@ -10467,7 +10494,8 @@ commit_cache_norebuild(
space->zip_size(),
RW_X_LATCH, &mtr)) {
byte* f = FSP_HEADER_OFFSET
- + FSP_SPACE_FLAGS + b->frame;
+ + FSP_SPACE_FLAGS
+ + b->page.frame;
const auto sf = space->flags
& ~FSP_FLAGS_MEM_MASK;
if (mach_read_from_4(f) != sf) {