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:
parent
7587b0ec84
commit
f1d7e0c17e
@ -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;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user