diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2022-10-29 19:22:04 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2022-10-29 19:22:04 +0200 |
commit | 1ebfa2af62246b98e17cd255a9ccd858151b355a (patch) | |
tree | f9cf4670ebe96b46f8e0107acc31f7235ec4c554 /storage/innobase/dict | |
parent | dd9da61dcfd7f5e675ed876cf38886b29d0ddc57 (diff) | |
parent | 64143741789a3e1c2bb8c6bf627eaec3751af0c6 (diff) | |
download | mariadb-git-1ebfa2af62246b98e17cd255a9ccd858151b355a.tar.gz |
Merge branch '10.6' into 10.7
Diffstat (limited to 'storage/innobase/dict')
-rw-r--r-- | storage/innobase/dict/dict0defrag_bg.cc | 6 | ||||
-rw-r--r-- | storage/innobase/dict/dict0stats.cc | 80 | ||||
-rw-r--r-- | storage/innobase/dict/dict0stats_bg.cc | 7 |
3 files changed, 65 insertions, 28 deletions
diff --git a/storage/innobase/dict/dict0defrag_bg.cc b/storage/innobase/dict/dict0defrag_bg.cc index 9abe6a20589..ea2914e52dc 100644 --- a/storage/innobase/dict/dict0defrag_bg.cc +++ b/storage/innobase/dict/dict0defrag_bg.cc @@ -297,7 +297,7 @@ btr_get_size_and_reserved( { ulint dummy; - ut_ad(mtr->memo_contains(index->lock, MTR_MEMO_S_LOCK)); + ut_ad(mtr->memo_contains(index->lock, MTR_MEMO_SX_LOCK)); ut_a(flag == BTR_N_LEAF_PAGES || flag == BTR_TOTAL_SIZE); if (index->page == FIL_NULL @@ -314,7 +314,7 @@ btr_get_size_and_reserved( return ULINT_UNDEFINED; } - mtr->x_lock_space(index->table->space); + mtr->s_lock_space(index->table->space); ulint n = fseg_n_reserved_pages(*root, PAGE_HEADER + PAGE_BTR_SEG_LEAF + root->page.frame, used, mtr); @@ -345,7 +345,7 @@ dict_stats_save_defrag_stats( mtr_t mtr; ulint n_leaf_pages; mtr.start(); - mtr_s_lock_index(index, &mtr); + mtr_sx_lock_index(index, &mtr); ulint n_leaf_reserved= btr_get_size_and_reserved(index, BTR_N_LEAF_PAGES, &n_leaf_pages, &mtr); mtr.commit(); diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 631c704693d..64e3ddb91e4 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -1036,6 +1036,12 @@ struct index_field_stats_t n_non_null_key_vals(n_non_null_key_vals) { } + + bool is_bulk_operation() const + { + return n_diff_key_vals == UINT64_MAX && + n_sample_sizes == UINT64_MAX && n_non_null_key_vals == UINT64_MAX; + } }; /*******************************************************************//** @@ -1377,13 +1383,16 @@ relatively quick and is used to calculate transient statistics that are not saved on disk. This was the only way to calculate statistics before the Persistent Statistics feature was introduced. This function doesn't update the defragmentation related stats. -Only persistent statistics supports defragmentation stats. */ +Only persistent statistics supports defragmentation stats. +@return error code +@retval DB_SUCCESS_LOCKED_REC if the table under bulk insert operation */ static -void +dberr_t dict_stats_update_transient_for_index( /*==================================*/ dict_index_t* index) /*!< in/out: index */ { + dberr_t err = DB_SUCCESS; if (srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO && (srv_force_recovery >= SRV_FORCE_NO_LOG_REDO || !dict_index_is_clust(index))) { @@ -1397,6 +1406,7 @@ dummy_empty: index->table->stats_mutex_lock(); dict_stats_empty_index(index, false); index->table->stats_mutex_unlock(); + return err; #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG } else if (ibuf_debug && !dict_index_is_clust(index)) { goto dummy_empty; @@ -1408,7 +1418,8 @@ dummy_empty: mtr_t mtr; mtr.start(); - mtr_s_lock_index(index, &mtr); + mtr_sx_lock_index(index, &mtr); + dberr_t err; buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH, &mtr, &err); @@ -1420,10 +1431,11 @@ invalid: const auto bulk_trx_id = index->table->bulk_trx_id; if (bulk_trx_id && trx_sys.find(nullptr, bulk_trx_id, false)) { + err= DB_SUCCESS_LOCKED_REC; goto invalid; } - mtr.x_lock_space(index->table->space); + mtr.s_lock_space(index->table->space); ulint dummy, size; index->stat_index_size @@ -1461,6 +1473,8 @@ invalid: } } } + + return err; } /*********************************************************************//** @@ -1468,9 +1482,11 @@ Calculates new estimates for table and index statistics. This function is relatively quick and is used to calculate transient statistics that are not saved on disk. This was the only way to calculate statistics before the -Persistent Statistics feature was introduced. */ +Persistent Statistics feature was introduced. +@return error code +@retval DB_SUCCESS_LOCKED REC if the table under bulk insert operation */ static -void +dberr_t dict_stats_update_transient( /*========================*/ dict_table_t* table) /*!< in/out: table */ @@ -1479,6 +1495,7 @@ dict_stats_update_transient( dict_index_t* index; ulint sum_of_index_sizes = 0; + dberr_t err = DB_SUCCESS; /* Find out the sizes of the indexes and how many different values for the key they approximately have */ @@ -1487,15 +1504,15 @@ dict_stats_update_transient( if (!table->space) { /* Nothing to do. */ +empty_table: dict_stats_empty_table(table, true); - return; + return err; } else if (index == NULL) { /* Table definition is corrupt */ ib::warn() << "Table " << table->name << " has no indexes. Cannot calculate statistics."; - dict_stats_empty_table(table, true); - return; + goto empty_table; } for (; index != NULL; index = dict_table_get_next_index(index)) { @@ -1507,14 +1524,15 @@ dict_stats_update_transient( } if (dict_stats_should_ignore_index(index) - || !index->is_readable()) { + || !index->is_readable() + || err == DB_SUCCESS_LOCKED_REC) { index->table->stats_mutex_lock(); dict_stats_empty_index(index, false); index->table->stats_mutex_unlock(); continue; } - dict_stats_update_transient_for_index(index); + err = dict_stats_update_transient_for_index(index); sum_of_index_sizes += index->stat_index_size; } @@ -1538,6 +1556,8 @@ dict_stats_update_transient( table->stat_initialized = TRUE; table->stats_mutex_unlock(); + + return err; } /* @{ Pseudo code about the relation between the following functions @@ -2420,6 +2440,19 @@ struct index_stats_t for (ulint i= 0; i < n_uniq; ++i) stats.push_back(index_field_stats_t{0, 1, 0}); } + + void set_bulk_operation() + { + memset((void*) &stats[0], 0xff, stats.size() * sizeof stats[0]); + } + + bool is_bulk_operation() const + { + for (auto &s : stats) + if (!s.is_bulk_operation()) + return false; + return true; + } }; /** Set dict_index_t::stat_n_diff_key_vals[] and stat_n_sample_sizes[]. @@ -2527,9 +2560,9 @@ static index_stats_t dict_stats_analyze_index(dict_index_t* index) DEBUG_PRINTF(" %s(index=%s)\n", __func__, index->name()); mtr.start(); - mtr_s_lock_index(index, &mtr); + mtr_sx_lock_index(index, &mtr); dberr_t err; - buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH, &mtr, &err); + buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH, &mtr, &err); if (!root) { empty_index: mtr.commit(); @@ -2538,7 +2571,7 @@ empty_index: } uint16_t root_level = btr_page_get_level(root->page.frame); - mtr.x_lock_space(index->table->space); + mtr.s_lock_space(index->table->space); ulint dummy, size; result.index_size = fseg_n_reserved_pages(*root, PAGE_HEADER + PAGE_BTR_SEG_LEAF @@ -2549,8 +2582,7 @@ empty_index: const auto bulk_trx_id = index->table->bulk_trx_id; if (bulk_trx_id && trx_sys.find(nullptr, bulk_trx_id, false)) { - result.index_size = 1; - result.n_leaf_pages = 1; + result.set_bulk_operation(); goto empty_index; } @@ -2812,7 +2844,8 @@ found_level: Calculates new estimates for table and index statistics. This function is relatively slow and is used to calculate persistent statistics that will be saved on disk. -@return DB_SUCCESS or error code */ +@return DB_SUCCESS or error code +@retval DB_SUCCESS_LOCKED_REC if the table under bulk insert operation */ static dberr_t dict_stats_update_persistent( @@ -2846,6 +2879,10 @@ dict_stats_update_persistent( index_stats_t stats = dict_stats_analyze_index(index); + if (stats.is_bulk_operation()) { + return DB_SUCCESS_LOCKED_REC; + } + table->stats_mutex_lock(); index->stat_index_size = stats.index_size; index->stat_n_leaf_pages = stats.n_leaf_pages; @@ -3846,7 +3883,8 @@ dict_stats_update_for_index( /*********************************************************************//** Calculates new estimates for table and index statistics. The statistics are used in query optimization. -@return DB_SUCCESS or error code */ +@return DB_SUCCESS or error code +@retval DB_SUCCESS_LOCKED_REC if the table under bulk insert operation */ dberr_t dict_stats_update( /*==============*/ @@ -3872,7 +3910,7 @@ dict_stats_update( if (trx_id_t bulk_trx_id = table->bulk_trx_id) { if (trx_sys.find(nullptr, bulk_trx_id, false)) { dict_stats_empty_table(table, false); - return DB_SUCCESS; + return DB_SUCCESS_LOCKED_REC; } } @@ -4066,9 +4104,7 @@ dict_stats_update( } transient: - dict_stats_update_transient(table); - - return(DB_SUCCESS); + return dict_stats_update_transient(table); } /** Execute DELETE FROM mysql.innodb_table_stats diff --git a/storage/innobase/dict/dict0stats_bg.cc b/storage/innobase/dict/dict0stats_bg.cc index 833d99cdaee..a66aac226a3 100644 --- a/storage/innobase/dict/dict0stats_bg.cc +++ b/storage/innobase/dict/dict0stats_bg.cc @@ -339,8 +339,9 @@ invalid_table_id: const bool update_now= difftime(time(nullptr), table->stats_last_recalc) >= MIN_RECALC_INTERVAL; - if (update_now) - dict_stats_update(table, DICT_STATS_RECALC_PERSISTENT); + const dberr_t err= update_now + ? dict_stats_update(table, DICT_STATS_RECALC_PERSISTENT) + : DB_SUCCESS_LOCKED_REC; dict_table_close(table, false, thd, mdl); @@ -361,7 +362,7 @@ done: ut_ad(i->state == recalc::IN_PROGRESS); recalc_pool.erase(i); const bool reschedule= !update_now && recalc_pool.empty(); - if (!update_now) + if (err == DB_SUCCESS_LOCKED_REC) recalc_pool.emplace_back(recalc{table_id, recalc::IDLE}); mysql_mutex_unlock(&recalc_pool_mutex); if (reschedule) |