summaryrefslogtreecommitdiff
path: root/storage/innobase/dict
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2022-10-29 19:22:04 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2022-10-29 19:22:04 +0200
commit1ebfa2af62246b98e17cd255a9ccd858151b355a (patch)
treef9cf4670ebe96b46f8e0107acc31f7235ec4c554 /storage/innobase/dict
parentdd9da61dcfd7f5e675ed876cf38886b29d0ddc57 (diff)
parent64143741789a3e1c2bb8c6bf627eaec3751af0c6 (diff)
downloadmariadb-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.cc6
-rw-r--r--storage/innobase/dict/dict0stats.cc80
-rw-r--r--storage/innobase/dict/dict0stats_bg.cc7
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)