Commit a1e41e32 authored by Jan Lindström's avatar Jan Lindström

MDEV-6470: Restrict number of error messages about persistent statictic tables not found

If mysql.innodb_table_stats or mysql.innodb_index_stats is not found or has
unexpected structure output that error only once and no other error for
every table trying to use them. If they do exists, then print fetch or
recalculation errors only once / table or index.
parent 15a529e1
......@@ -121,6 +121,11 @@ UNIV_INTERN mysql_pfs_key_t dict_foreign_err_mutex_key;
/** Identifies generated InnoDB foreign key names */
static char dict_ibfk[] = "_ibfk_";
bool innodb_table_stats_not_found = false;
bool innodb_index_stats_not_found = false;
static bool innodb_table_stats_not_found_reported = false;
static bool innodb_index_stats_not_found_reported = false;
/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
index.
......@@ -5994,14 +5999,34 @@ dict_table_schema_check(
table = dict_table_get_low(req_schema->table_name);
if (table == NULL) {
bool should_print=true;
/* no such table */
ut_snprintf(errstr, errstr_sz,
"Table %s not found.",
ut_format_name(req_schema->table_name,
TRUE, buf, sizeof(buf)));
if (innobase_strcasecmp(req_schema->table_name, "mysql/innodb_table_stats") == 0) {
if (innodb_table_stats_not_found_reported == false) {
innodb_table_stats_not_found = true;
innodb_table_stats_not_found_reported = true;
} else {
should_print = false;
}
} else if (innobase_strcasecmp(req_schema->table_name, "mysql/innodb_index_stats") == 0 ) {
if (innodb_index_stats_not_found_reported == false) {
innodb_index_stats_not_found = true;
innodb_index_stats_not_found_reported = true;
} else {
should_print = false;
}
}
return(DB_TABLE_NOT_FOUND);
if (should_print) {
ut_snprintf(errstr, errstr_sz,
"Table %s not found.",
ut_format_name(req_schema->table_name,
TRUE, buf, sizeof(buf)));
return(DB_TABLE_NOT_FOUND);
} else {
return(DB_STATS_DO_NOT_EXIST);
}
}
if (table->ibd_file_missing) {
......
......@@ -268,10 +268,12 @@ dict_stats_persistent_storage_check(
mutex_exit(&(dict_sys->mutex));
}
if (ret != DB_SUCCESS) {
if (ret != DB_SUCCESS && ret != DB_STATS_DO_NOT_EXIST) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Error: %s\n", errstr);
return(false);
} else if (ret == DB_STATS_DO_NOT_EXIST) {
return false;
}
/* else */
......@@ -2201,17 +2203,21 @@ dict_stats_save_index_stat(
"END;", trx);
if (ret != DB_SUCCESS) {
char buf_table[MAX_FULL_NAME_LEN];
char buf_index[MAX_FULL_NAME_LEN];
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Cannot save index statistics for table "
"%s, index %s, stat name \"%s\": %s\n",
ut_format_name(index->table->name, TRUE,
buf_table, sizeof(buf_table)),
ut_format_name(index->name, FALSE,
buf_index, sizeof(buf_index)),
stat_name, ut_strerr(ret));
if (innodb_index_stats_not_found == false &&
index->stats_error_printed == false) {
char buf_table[MAX_FULL_NAME_LEN];
char buf_index[MAX_FULL_NAME_LEN];
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Cannot save index statistics for table "
"%s, index %s, stat name \"%s\": %s\n",
ut_format_name(index->table->name, TRUE,
buf_table, sizeof(buf_table)),
ut_format_name(index->name, FALSE,
buf_index, sizeof(buf_index)),
stat_name, ut_strerr(ret));
index->stats_error_printed = true;
}
}
return(ret);
......@@ -2900,20 +2906,24 @@ dict_stats_update_for_index(
}
/* else */
/* Fall back to transient stats since the persistent
storage is not present or is corrupted */
char buf_table[MAX_FULL_NAME_LEN];
char buf_index[MAX_FULL_NAME_LEN];
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Recalculation of persistent statistics "
"requested for table %s index %s but the required "
"persistent statistics storage is not present or is "
"corrupted. Using transient stats instead.\n",
ut_format_name(index->table->name, TRUE,
buf_table, sizeof(buf_table)),
ut_format_name(index->name, FALSE,
buf_index, sizeof(buf_index)));
if (innodb_index_stats_not_found == false &&
index->stats_error_printed == false) {
/* Fall back to transient stats since the persistent
storage is not present or is corrupted */
char buf_table[MAX_FULL_NAME_LEN];
char buf_index[MAX_FULL_NAME_LEN];
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Recalculation of persistent statistics "
"requested for table %s index %s but the required "
"persistent statistics storage is not present or is "
"corrupted. Using transient stats instead.\n",
ut_format_name(index->table->name, TRUE,
buf_table, sizeof(buf_table)),
ut_format_name(index->name, FALSE,
buf_index, sizeof(buf_index)));
index->stats_error_printed = false;
}
}
dict_table_stats_lock(index->table, RW_X_LATCH);
......@@ -2998,13 +3008,17 @@ dict_stats_update(
/* Fall back to transient stats since the persistent
storage is not present or is corrupted */
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Recalculation of persistent statistics "
"requested for table %s but the required persistent "
"statistics storage is not present or is corrupted. "
"Using transient stats instead.\n",
ut_format_name(table->name, TRUE, buf, sizeof(buf)));
if (innodb_table_stats_not_found == false &&
table->stats_error_printed == false) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Recalculation of persistent statistics "
"requested for table %s but the required persistent "
"statistics storage is not present or is corrupted. "
"Using transient stats instead.\n",
ut_format_name(table->name, TRUE, buf, sizeof(buf)));
table->stats_error_printed = true;
}
goto transient;
......@@ -3048,17 +3062,21 @@ dict_stats_update(
/* persistent statistics storage does not exist
or is corrupted, calculate the transient stats */
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: Fetch of persistent "
"statistics requested for table %s but the "
"required system tables %s and %s are not "
"present or have unexpected structure. "
"Using transient stats instead.\n",
ut_format_name(table->name, TRUE,
buf, sizeof(buf)),
TABLE_STATS_NAME_PRINT,
INDEX_STATS_NAME_PRINT);
if (innodb_table_stats_not_found == false &&
table->stats_error_printed == false) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: Fetch of persistent "
"statistics requested for table %s but the "
"required system tables %s and %s are not "
"present or have unexpected structure. "
"Using transient stats instead.\n",
ut_format_name(table->name, TRUE,
buf, sizeof(buf)),
TABLE_STATS_NAME_PRINT,
INDEX_STATS_NAME_PRINT);
table->stats_error_printed = true;
}
goto transient;
}
......@@ -3128,16 +3146,19 @@ dict_stats_update(
dict_stats_table_clone_free(t);
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error fetching persistent statistics "
"for table %s from %s and %s: %s. "
"Using transient stats method instead.\n",
ut_format_name(table->name, TRUE, buf,
sizeof(buf)),
TABLE_STATS_NAME,
INDEX_STATS_NAME,
ut_strerr(err));
if (innodb_table_stats_not_found == false &&
table->stats_error_printed == false) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error fetching persistent statistics "
"for table %s from %s and %s: %s. "
"Using transient stats method instead.\n",
ut_format_name(table->name, TRUE, buf,
sizeof(buf)),
TABLE_STATS_NAME,
INDEX_STATS_NAME,
ut_strerr(err));
}
goto transient;
}
......
......@@ -43,6 +43,9 @@ Created 1/8/1996 Heikki Tuuri
#include "trx0types.h"
#include "row0types.h"
extern bool innodb_table_stats_not_found;
extern bool innodb_index_stats_not_found;
#ifndef UNIV_HOTBACKUP
# include "sync0sync.h"
# include "sync0rw.h"
......
......@@ -624,6 +624,9 @@ struct dict_index_t{
ulint stat_n_leaf_pages;
/*!< approximate number of leaf pages in the
index tree */
bool stats_error_printed;
/*!< has persistent statistics error printed
for this index ? */
/* @} */
rw_lock_t lock; /*!< read-write lock protecting the
upper levels of the index tree */
......@@ -947,6 +950,9 @@ struct dict_table_t{
/*!< see BG_STAT_* above.
Writes are covered by dict_sys->mutex.
Dirty reads are possible. */
bool stats_error_printed;
/*!< Has persistent stats error beein
already printed for this table ? */
/* @} */
/*----------------------*/
/**!< The following fields are used by the
......
......@@ -121,6 +121,11 @@ UNIV_INTERN mysql_pfs_key_t dict_foreign_err_mutex_key;
/** Identifies generated InnoDB foreign key names */
static char dict_ibfk[] = "_ibfk_";
bool innodb_table_stats_not_found = false;
bool innodb_index_stats_not_found = false;
static bool innodb_table_stats_not_found_reported = false;
static bool innodb_index_stats_not_found_reported = false;
/*******************************************************************//**
Tries to find column names for the index and sets the col field of the
index.
......@@ -6037,14 +6042,34 @@ dict_table_schema_check(
table = dict_table_get_low(req_schema->table_name);
if (table == NULL) {
bool should_print=true;
/* no such table */
ut_snprintf(errstr, errstr_sz,
"Table %s not found.",
ut_format_name(req_schema->table_name,
TRUE, buf, sizeof(buf)));
if (innobase_strcasecmp(req_schema->table_name, "mysql/innodb_table_stats") == 0) {
if (innodb_table_stats_not_found_reported == false) {
innodb_table_stats_not_found = true;
innodb_table_stats_not_found_reported = true;
} else {
should_print = false;
}
} else if (innobase_strcasecmp(req_schema->table_name, "mysql/innodb_index_stats") == 0 ) {
if (innodb_index_stats_not_found_reported == false) {
innodb_index_stats_not_found = true;
innodb_index_stats_not_found_reported = true;
} else {
should_print = false;
}
}
return(DB_TABLE_NOT_FOUND);
if (should_print) {
ut_snprintf(errstr, errstr_sz,
"Table %s not found.",
ut_format_name(req_schema->table_name,
TRUE, buf, sizeof(buf)));
return(DB_TABLE_NOT_FOUND);
} else {
return(DB_STATS_DO_NOT_EXIST);
}
}
if (table->ibd_file_missing) {
......
......@@ -268,10 +268,12 @@ dict_stats_persistent_storage_check(
mutex_exit(&(dict_sys->mutex));
}
if (ret != DB_SUCCESS) {
if (ret != DB_SUCCESS && ret != DB_STATS_DO_NOT_EXIST) {
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Error: %s\n", errstr);
return(false);
} else if (ret == DB_STATS_DO_NOT_EXIST) {
return false;
}
/* else */
......@@ -2201,17 +2203,21 @@ dict_stats_save_index_stat(
"END;", trx);
if (ret != DB_SUCCESS) {
char buf_table[MAX_FULL_NAME_LEN];
char buf_index[MAX_FULL_NAME_LEN];
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Cannot save index statistics for table "
"%s, index %s, stat name \"%s\": %s\n",
ut_format_name(index->table->name, TRUE,
buf_table, sizeof(buf_table)),
ut_format_name(index->name, FALSE,
buf_index, sizeof(buf_index)),
stat_name, ut_strerr(ret));
if (innodb_index_stats_not_found == false &&
index->stats_error_printed == false) {
char buf_table[MAX_FULL_NAME_LEN];
char buf_index[MAX_FULL_NAME_LEN];
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Cannot save index statistics for table "
"%s, index %s, stat name \"%s\": %s\n",
ut_format_name(index->table->name, TRUE,
buf_table, sizeof(buf_table)),
ut_format_name(index->name, FALSE,
buf_index, sizeof(buf_index)),
stat_name, ut_strerr(ret));
index->stats_error_printed = true;
}
}
return(ret);
......@@ -2900,20 +2906,24 @@ dict_stats_update_for_index(
}
/* else */
/* Fall back to transient stats since the persistent
storage is not present or is corrupted */
char buf_table[MAX_FULL_NAME_LEN];
char buf_index[MAX_FULL_NAME_LEN];
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Recalculation of persistent statistics "
"requested for table %s index %s but the required "
"persistent statistics storage is not present or is "
"corrupted. Using transient stats instead.\n",
ut_format_name(index->table->name, TRUE,
buf_table, sizeof(buf_table)),
ut_format_name(index->name, FALSE,
buf_index, sizeof(buf_index)));
if (innodb_index_stats_not_found == false &&
index->stats_error_printed == false) {
/* Fall back to transient stats since the persistent
storage is not present or is corrupted */
char buf_table[MAX_FULL_NAME_LEN];
char buf_index[MAX_FULL_NAME_LEN];
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Recalculation of persistent statistics "
"requested for table %s index %s but the required "
"persistent statistics storage is not present or is "
"corrupted. Using transient stats instead.\n",
ut_format_name(index->table->name, TRUE,
buf_table, sizeof(buf_table)),
ut_format_name(index->name, FALSE,
buf_index, sizeof(buf_index)));
index->stats_error_printed = false;
}
}
dict_table_stats_lock(index->table, RW_X_LATCH);
......@@ -2998,13 +3008,17 @@ dict_stats_update(
/* Fall back to transient stats since the persistent
storage is not present or is corrupted */
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Recalculation of persistent statistics "
"requested for table %s but the required persistent "
"statistics storage is not present or is corrupted. "
"Using transient stats instead.\n",
ut_format_name(table->name, TRUE, buf, sizeof(buf)));
if (innodb_table_stats_not_found == false &&
table->stats_error_printed == false) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Recalculation of persistent statistics "
"requested for table %s but the required persistent "
"statistics storage is not present or is corrupted. "
"Using transient stats instead.\n",
ut_format_name(table->name, TRUE, buf, sizeof(buf)));
table->stats_error_printed = true;
}
goto transient;
......@@ -3048,17 +3062,21 @@ dict_stats_update(
/* persistent statistics storage does not exist
or is corrupted, calculate the transient stats */
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: Fetch of persistent "
"statistics requested for table %s but the "
"required system tables %s and %s are not "
"present or have unexpected structure. "
"Using transient stats instead.\n",
ut_format_name(table->name, TRUE,
buf, sizeof(buf)),
TABLE_STATS_NAME_PRINT,
INDEX_STATS_NAME_PRINT);
if (innodb_table_stats_not_found == false &&
table->stats_error_printed == false) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: Fetch of persistent "
"statistics requested for table %s but the "
"required system tables %s and %s are not "
"present or have unexpected structure. "
"Using transient stats instead.\n",
ut_format_name(table->name, TRUE,
buf, sizeof(buf)),
TABLE_STATS_NAME_PRINT,
INDEX_STATS_NAME_PRINT);
table->stats_error_printed = true;
}
goto transient;
}
......@@ -3128,16 +3146,19 @@ dict_stats_update(
dict_stats_table_clone_free(t);
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error fetching persistent statistics "
"for table %s from %s and %s: %s. "
"Using transient stats method instead.\n",
ut_format_name(table->name, TRUE, buf,
sizeof(buf)),
TABLE_STATS_NAME,
INDEX_STATS_NAME,
ut_strerr(err));
if (innodb_table_stats_not_found == false &&
table->stats_error_printed == false) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error fetching persistent statistics "
"for table %s from %s and %s: %s. "
"Using transient stats method instead.\n",
ut_format_name(table->name, TRUE, buf,
sizeof(buf)),
TABLE_STATS_NAME,
INDEX_STATS_NAME,
ut_strerr(err));
}
goto transient;
}
......
......@@ -43,6 +43,9 @@ Created 1/8/1996 Heikki Tuuri
#include "trx0types.h"
#include "row0types.h"
extern bool innodb_table_stats_not_found;
extern bool innodb_index_stats_not_found;
#ifndef UNIV_HOTBACKUP
# include "sync0sync.h"
# include "sync0rw.h"
......
......@@ -638,6 +638,9 @@ struct dict_index_t{
ulint stat_n_leaf_pages;
/*!< approximate number of leaf pages in the
index tree */
bool stats_error_printed;
/*!< has persistent statistics error printed
for this index ? */
/* @} */
prio_rw_lock_t lock; /*!< read-write lock protecting the
upper levels of the index tree */
......@@ -962,6 +965,9 @@ struct dict_table_t{
/*!< see BG_STAT_* above.
Writes are covered by dict_sys->mutex.
Dirty reads are possible. */
bool stats_error_printed;
/*!< Has persistent stats error beein
already printed for this table ? */
/* @} */
/*----------------------*/
/**!< The following fields are used by the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment