1
0
mirror of https://github.com/MariaDB/server.git synced 2025-04-18 21:44:20 +03:00

MDEV-35436 dict_stats_fetch_from_ps() unnecessarily holds exclusive dict_sys.latch

dict_stats_fetch_from_ps(): Acquire dict_sys.latch as few times as
possible, and release dict_sys.latch after invoking pars_sql(),
so that we will not be unnecessarily holding dict_sys.latch while
possibly waiting for data to be read into the buffer pool.
This commit is contained in:
Marko Mäkelä 2025-02-13 12:18:03 +02:00 committed by Sergei Golubchik
parent 7587b0ec84
commit f1d7e0c17e
2 changed files with 85 additions and 85 deletions

View File

@ -3485,9 +3485,7 @@ dict_stats_fetch_from_ps(
dict_table_t* table) /*!< in/out: table */
{
index_fetch_t index_fetch_arg;
trx_t* trx;
pars_info_t* pinfo;
dberr_t ret;
char db_utf8[MAX_DB_UTF8_LEN];
char table_utf8[MAX_TABLE_UTF8_LEN];
@ -3501,34 +3499,36 @@ dict_stats_fetch_from_ps(
MDL_ticket *mdl_table = nullptr, *mdl_index = nullptr;
dict_table_t* table_stats = dict_table_open_on_name(
TABLE_STATS_NAME, false, DICT_ERR_IGNORE_NONE);
if (table_stats) {
dict_sys.freeze(SRW_LOCK_CALL);
table_stats = dict_acquire_mdl_shared<false>(table_stats, thd,
&mdl_table);
dict_sys.unfreeze();
if (!table_stats) {
return DB_STATS_DO_NOT_EXIST;
}
dict_table_t* index_stats = dict_table_open_on_name(
INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE);
if (!index_stats) {
dict_table_close(table_stats);
return DB_STATS_DO_NOT_EXIST;
}
dict_sys.freeze(SRW_LOCK_CALL);
table_stats = dict_acquire_mdl_shared<false>(table_stats, thd,
&mdl_table);
if (!table_stats
|| strcmp(table_stats->name.m_name, TABLE_STATS_NAME)) {
release_and_exit:
if (table_stats) {
dict_table_close(table_stats, false, thd, mdl_table);
dict_table_close(table_stats, true, thd, mdl_table);
}
if (index_stats) {
dict_table_close(index_stats, true, thd, mdl_index);
}
dict_sys.unfreeze();
return DB_STATS_DO_NOT_EXIST;
}
dict_table_t* index_stats = dict_table_open_on_name(
INDEX_STATS_NAME, false, DICT_ERR_IGNORE_NONE);
if (index_stats) {
dict_sys.freeze(SRW_LOCK_CALL);
index_stats = dict_acquire_mdl_shared<false>(index_stats, thd,
&mdl_index);
dict_sys.unfreeze();
}
if (!index_stats) {
goto release_and_exit;
}
if (strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) {
dict_table_close(index_stats, false, thd, mdl_index);
index_stats = dict_acquire_mdl_shared<false>(index_stats, thd,
&mdl_index);
if (!index_stats
|| strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) {
goto release_and_exit;
}
@ -3536,10 +3536,6 @@ release_and_exit:
DEBUG_SYNC(thd, "dict_stats_mdl_acquired");
#endif /* ENABLED_DEBUG_SYNC */
trx = trx_create();
trx_start_internal_read_only(trx);
dict_fs2utf8(table->name.m_name, db_utf8, sizeof(db_utf8),
table_utf8, sizeof(table_utf8));
@ -3560,76 +3556,85 @@ release_and_exit:
"fetch_index_stats_step",
dict_stats_fetch_index_stats_step,
&index_fetch_arg);
dict_sys.lock(SRW_LOCK_CALL); /* FIXME: remove this */
ret = que_eval_sql(pinfo,
"PROCEDURE FETCH_STATS () IS\n"
"found INT;\n"
"DECLARE FUNCTION fetch_table_stats_step;\n"
"DECLARE FUNCTION fetch_index_stats_step;\n"
"DECLARE CURSOR table_stats_cur IS\n"
" SELECT\n"
/* if you change the selected fields, be
sure to adjust
dict_stats_fetch_table_stats_step() */
" n_rows,\n"
" clustered_index_size,\n"
" sum_of_other_index_sizes\n"
" FROM \"" TABLE_STATS_NAME "\"\n"
" WHERE\n"
" database_name = :database_name AND\n"
" table_name = :table_name;\n"
"DECLARE CURSOR index_stats_cur IS\n"
" SELECT\n"
/* if you change the selected fields, be
sure to adjust
dict_stats_fetch_index_stats_step() */
" index_name,\n"
" stat_name,\n"
" stat_value,\n"
" sample_size\n"
" FROM \"" INDEX_STATS_NAME "\"\n"
" WHERE\n"
" database_name = :database_name AND\n"
" table_name = :table_name;\n"
dict_sys.unfreeze();
dict_sys.lock(SRW_LOCK_CALL);
que_t* graph = pars_sql(
pinfo,
"PROCEDURE FETCH_STATS () IS\n"
"found INT;\n"
"DECLARE FUNCTION fetch_table_stats_step;\n"
"DECLARE FUNCTION fetch_index_stats_step;\n"
"DECLARE CURSOR table_stats_cur IS\n"
" SELECT\n"
/* if you change the selected fields, be
sure to adjust
dict_stats_fetch_table_stats_step() */
" n_rows,\n"
" clustered_index_size,\n"
" sum_of_other_index_sizes\n"
" FROM \"" TABLE_STATS_NAME "\"\n"
" WHERE\n"
" database_name = :database_name AND\n"
" table_name = :table_name;\n"
"DECLARE CURSOR index_stats_cur IS\n"
" SELECT\n"
/* if you change the selected fields, be
sure to adjust
dict_stats_fetch_index_stats_step() */
" index_name,\n"
" stat_name,\n"
" stat_value,\n"
" sample_size\n"
" FROM \"" INDEX_STATS_NAME "\"\n"
" WHERE\n"
" database_name = :database_name AND\n"
" table_name = :table_name;\n"
"BEGIN\n"
"BEGIN\n"
"OPEN table_stats_cur;\n"
"FETCH table_stats_cur INTO\n"
" fetch_table_stats_step();\n"
"IF (SQL % NOTFOUND) THEN\n"
" CLOSE table_stats_cur;\n"
" RETURN;\n"
"END IF;\n"
"CLOSE table_stats_cur;\n"
"OPEN table_stats_cur;\n"
"FETCH table_stats_cur INTO\n"
" fetch_table_stats_step();\n"
"IF (SQL % NOTFOUND) THEN\n"
" CLOSE table_stats_cur;\n"
" RETURN;\n"
"END IF;\n"
"CLOSE table_stats_cur;\n"
"OPEN index_stats_cur;\n"
"found := 1;\n"
"WHILE found = 1 LOOP\n"
" FETCH index_stats_cur INTO\n"
" fetch_index_stats_step();\n"
" IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n"
" END IF;\n"
"END LOOP;\n"
"CLOSE index_stats_cur;\n"
"OPEN index_stats_cur;\n"
"found := 1;\n"
"WHILE found = 1 LOOP\n"
" FETCH index_stats_cur INTO\n"
" fetch_index_stats_step();\n"
" IF (SQL % NOTFOUND) THEN\n"
" found := 0;\n"
" END IF;\n"
"END LOOP;\n"
"CLOSE index_stats_cur;\n"
"END;", trx);
/* pinfo is freed by que_eval_sql() */
"END;");
dict_sys.unlock();
trx_t* trx = trx_create();
trx->graph = nullptr;
graph->trx = trx;
trx_start_internal_read_only(trx);
que_run_threads(que_fork_start_command(graph));
que_graph_free(graph);
dict_table_close(table_stats, false, thd, mdl_table);
dict_table_close(index_stats, false, thd, mdl_index);
trx_commit_for_mysql(trx);
dberr_t ret = trx->error_state;
trx->free();
if (!index_fetch_arg.stats_were_modified) {
return(DB_STATS_DO_NOT_EXIST);
return DB_STATS_DO_NOT_EXIST;
}
return(ret);
return ret;
}
/*********************************************************************//**

View File

@ -783,11 +783,6 @@ pars_retrieve_table_list_defs(
{
ulint count = 0;
if (sym_node == NULL) {
return(count);
}
while (sym_node) {
pars_retrieve_table_def(sym_node);