summaryrefslogtreecommitdiff
path: root/storage/innobase/include/dict0dict.h
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/include/dict0dict.h')
-rw-r--r--storage/innobase/include/dict0dict.h534
1 files changed, 243 insertions, 291 deletions
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 65b88a65185..e54a138cc02 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -31,11 +31,11 @@ Created 1/8/1996 Heikki Tuuri
#include "data0data.h"
#include "dict0mem.h"
#include "fsp0fsp.h"
+#include "srw_lock.h"
+#include <my_sys.h>
#include <deque>
class MDL_ticket;
-extern bool innodb_table_stats_not_found;
-extern bool innodb_index_stats_not_found;
/** the first table or index ID for other than hard-coded system tables */
constexpr uint8_t DICT_HDR_FIRST_ID= 10;
@@ -132,7 +132,7 @@ enum dict_table_op_t {
@param[in] table_op operation to perform when opening
@return table object after locking MDL shared
@retval NULL if the table is not readable, or if trylock && MDL blocked */
-template<bool trylock>
+template<bool trylock, bool purge_thd= false>
dict_table_t*
dict_acquire_mdl_shared(dict_table_t *table,
THD *thd,
@@ -140,7 +140,6 @@ dict_acquire_mdl_shared(dict_table_t *table,
dict_table_op_t table_op= DICT_TABLE_OP_NORMAL);
/** Look up a table by numeric identifier.
-@tparam purge_thd Whether the function is called by purge thread
@param[in] table_id table identifier
@param[in] dict_locked data dictionary locked
@param[in] table_op operation to perform when opening
@@ -154,11 +153,12 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked,
MDL_ticket **mdl= nullptr)
MY_ATTRIBUTE((warn_unused_result));
+/** Decrement the count of open handles */
+void dict_table_close(dict_table_t *table);
+
/** Decrements the count of open handles of a table.
@param[in,out] table table
-@param[in] dict_locked data dictionary locked
-@param[in] try_drop try to drop any orphan indexes after
- an aborted online index creation
+@param[in] dict_locked whether dict_sys.latch is being held
@param[in] thd thread to release MDL
@param[in] mdl metadata lock or NULL if the thread is a
foreground one. */
@@ -166,22 +166,10 @@ void
dict_table_close(
dict_table_t* table,
bool dict_locked,
- bool try_drop,
THD* thd = NULL,
MDL_ticket* mdl = NULL);
/*********************************************************************//**
-Closes the only open handle to a table and drops a table while assuring
-that dict_sys.mutex is held the whole time. This assures that the table
-is not evicted after the close when the count of open handles goes to zero.
-Because dict_sys.mutex is held, we do not need to call prevent_eviction(). */
-void
-dict_table_close_and_drop(
-/*======================*/
- trx_t* trx, /*!< in: data dictionary transaction */
- dict_table_t* table); /*!< in/out: table */
-
-/*********************************************************************//**
Gets the minimum number of bytes per character.
@return minimum multi-byte char size, in bytes */
UNIV_INLINE
@@ -381,12 +369,8 @@ dberr_t
dict_table_rename_in_cache(
/*=======================*/
dict_table_t* table, /*!< in/out: table */
- const char* new_name, /*!< in: new name */
- bool rename_also_foreigns,
- /*!< in: in ALTER TABLE we want
- to preserve the original table name
- in constraints which reference it */
- bool replace_new_file = false)
+ span<const char> new_name, /*!< in: new name */
+ bool replace_new_file)
/*!< in: whether to replace the
file with the new name
(as part of rolling back TRUNCATE) */
@@ -437,14 +421,6 @@ dict_foreign_add_to_cache(
dict_err_ignore_t ignore_err)
/*!< in: error to be ignored */
MY_ATTRIBUTE((nonnull(1), warn_unused_result));
-/*********************************************************************//**
-Checks if a table is referenced by foreign keys.
-@return TRUE if table is referenced by a foreign key */
-ibool
-dict_table_is_referenced_by_foreign_key(
-/*====================================*/
- const dict_table_t* table) /*!< in: InnoDB table */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
/**********************************************************************//**
Replace the index passed in with another equivalent index in the
foreign key lists of the table.
@@ -480,16 +456,14 @@ NOTE! This is a high-level function to be used mainly from outside the
'dict' directory. Inside this directory dict_table_get_low
is usually the appropriate function.
@param[in] table_name Table name
-@param[in] dict_locked TRUE=data dictionary locked
-@param[in] try_drop TRUE=try to drop any orphan indexes after
- an aborted online index creation
+@param[in] dict_locked whether dict_sys.latch is being held exclusively
@param[in] ignore_err error to be ignored when loading the table
-@return table, NULL if does not exist */
+@return table
+@retval nullptr if does not exist */
dict_table_t*
dict_table_open_on_name(
const char* table_name,
- ibool dict_locked,
- ibool try_drop,
+ bool dict_locked,
dict_err_ignore_t ignore_err)
MY_ATTRIBUTE((warn_unused_result));
@@ -656,19 +630,6 @@ dict_table_get_next_index(
# define dict_table_get_next_index(index) UT_LIST_GET_NEXT(indexes, index)
#endif /* UNIV_DEBUG */
-/* Skip corrupted index */
-#define dict_table_skip_corrupt_index(index) \
- while (index && index->is_corrupted()) { \
- index = dict_table_get_next_index(index); \
- }
-
-/* Get the next non-corrupt index */
-#define dict_table_next_uncorrupted_index(index) \
-do { \
- index = dict_table_get_next_index(index); \
- dict_table_skip_corrupt_index(index); \
-} while (0)
-
#define dict_index_is_clust(index) (index)->is_clust()
#define dict_index_is_auto_gen_clust(index) (index)->is_gen_clust()
#define dict_index_is_unique(index) (index)->is_unique()
@@ -946,17 +907,6 @@ dict_table_copy_types(
dtuple_t* tuple, /*!< in/out: data tuple */
const dict_table_t* table) /*!< in: table */
MY_ATTRIBUTE((nonnull));
-/**********************************************************************//**
-Make room in the table cache by evicting an unused table. The unused table
-should not be part of FK relationship and currently not used in any user
-transaction. There is no guarantee that it will remove a table.
-@return number of tables evicted. */
-ulint
-dict_make_room_in_cache(
-/*====================*/
- ulint max_tables, /*!< in: max tables allowed in cache */
- ulint pct_check); /*!< in: max percent to check */
-
/** Adds an index to the dictionary cache, with possible indexing newly
added column.
@param[in,out] index index; NOTE! The index memory
@@ -1159,7 +1109,6 @@ dict_field_get_col(
/**********************************************************************//**
Returns an index object if it is found in the dictionary cache.
-Assumes that dict_sys.mutex is already being held.
@return index, NULL if not found */
dict_index_t*
dict_index_get_if_in_cache_low(
@@ -1246,15 +1195,6 @@ dict_index_get_page(
/*================*/
const dict_index_t* tree) /*!< in: index */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/*********************************************************************//**
-Gets the read-write lock of the index tree.
-@return read-write lock */
-UNIV_INLINE
-rw_lock_t*
-dict_index_get_lock(
-/*================*/
- const dict_index_t* index) /*!< in: index */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
/********************************************************************//**
Returns free space reserved for future updates of records. This is
relevant only in the case of many consecutive inserts, as updates
@@ -1306,9 +1246,6 @@ dict_index_calc_min_rec_len(
const dict_index_t* index) /*!< in: index */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-#define dict_mutex_enter_for_mysql() mutex_enter(&dict_sys.mutex)
-#define dict_mutex_exit_for_mysql() mutex_exit(&dict_sys.mutex)
-
/********************************************************************//**
Checks if the database name in two table names is the same.
@return TRUE if same db name */
@@ -1372,105 +1309,134 @@ constraint */
/* Buffers for storing detailed information about the latest foreign key
and unique key errors */
extern FILE* dict_foreign_err_file;
-extern ib_mutex_t dict_foreign_err_mutex; /* mutex protecting the
- foreign key error messages */
+extern mysql_mutex_t dict_foreign_err_mutex;
/** InnoDB data dictionary cache */
class dict_sys_t
{
+ /** The my_hrtime_coarse().val of the oldest lock_wait() start, or 0 */
+ std::atomic<ulonglong> latch_ex_wait_start;
+
+ /** the rw-latch protecting the data dictionary cache */
+ alignas(CPU_LEVEL1_DCACHE_LINESIZE) srw_lock latch;
+#ifdef UNIV_DEBUG
+ /** whether latch is being held in exclusive mode (by any thread) */
+ Atomic_relaxed<pthread_t> latch_ex;
+ /** number of S-latch holders */
+ Atomic_counter<uint32_t> latch_readers;
+#endif
public:
- DictSysMutex mutex; /*!< mutex protecting the data
- dictionary; protects also the
- disk-based dictionary system tables;
- this mutex serializes CREATE TABLE
- and DROP TABLE, as well as reading
- the dictionary data for a table from
- system tables */
- /** @brief the data dictionary rw-latch protecting dict_sys
-
- Table create, drop, etc. reserve this in X-mode; implicit or
- backround operations purge, rollback, foreign key checks reserve this
- in S-mode; not all internal InnoDB operations are covered by MDL.
-
- This latch also prevents lock waits when accessing the InnoDB
- data dictionary tables. @see trx_t::dict_operation_lock_mode */
- rw_lock_t latch;
- row_id_t row_id; /*!< the next row id to assign;
- NOTE that at a checkpoint this
- must be written to the dict system
- header and flushed to a file; in
- recovery this must be derived from
- the log records */
- hash_table_t table_hash; /*!< hash table of the tables, based
- on name */
- /** hash table of persistent table IDs */
- hash_table_t table_id_hash;
- dict_table_t* sys_tables; /*!< SYS_TABLES table */
- dict_table_t* sys_columns; /*!< SYS_COLUMNS table */
- dict_table_t* sys_indexes; /*!< SYS_INDEXES table */
- dict_table_t* sys_fields; /*!< SYS_FIELDS table */
- dict_table_t* sys_virtual; /*!< SYS_VIRTUAL table */
-
- /*=============================*/
- UT_LIST_BASE_NODE_T(dict_table_t)
- table_LRU; /*!< List of tables that can be evicted
- from the cache */
- UT_LIST_BASE_NODE_T(dict_table_t)
- table_non_LRU; /*!< List of tables that can't be
- evicted from the cache */
+ /** Indexes of SYS_TABLE[] */
+ enum
+ {
+ SYS_TABLES= 0,
+ SYS_INDEXES,
+ SYS_COLUMNS,
+ SYS_FIELDS,
+ SYS_FOREIGN,
+ SYS_FOREIGN_COLS,
+ SYS_VIRTUAL
+ };
+ /** System table names */
+ static const span<const char> SYS_TABLE[];
+
+ /** all tables (persistent and temporary), hashed by name */
+ hash_table_t table_hash;
+ /** hash table of persistent table IDs */
+ hash_table_t table_id_hash;
+
+ /** the SYS_TABLES table */
+ dict_table_t *sys_tables;
+ /** the SYS_COLUMNS table */
+ dict_table_t *sys_columns;
+ /** the SYS_INDEXES table */
+ dict_table_t *sys_indexes;
+ /** the SYS_FIELDS table */
+ dict_table_t *sys_fields;
+ /** the SYS_FOREIGN table */
+ dict_table_t *sys_foreign;
+ /** the SYS_FOREIGN_COLS table */
+ dict_table_t *sys_foreign_cols;
+ /** the SYS_VIRTUAL table */
+ dict_table_t *sys_virtual;
+
+ /** @return whether all non-hard-coded system tables exist */
+ bool sys_tables_exist() const
+ { return UNIV_LIKELY(sys_foreign && sys_foreign_cols && sys_virtual); }
+
+ /** list of persistent tables that can be evicted */
+ UT_LIST_BASE_NODE_T(dict_table_t) table_LRU;
+ /** list of persistent tables that cannot be evicted */
+ UT_LIST_BASE_NODE_T(dict_table_t) table_non_LRU;
+
private:
- bool m_initialised;
- /** the sequence of temporary table IDs */
- std::atomic<table_id_t> temp_table_id;
- /** hash table of temporary table IDs */
- hash_table_t temp_id_hash;
+ bool m_initialised= false;
+ /** the sequence of temporary table IDs */
+ std::atomic<table_id_t> temp_table_id{DICT_HDR_FIRST_ID};
+ /** hash table of temporary table IDs */
+ hash_table_t temp_id_hash;
+ /** the next value of DB_ROW_ID, backed by DICT_HDR_ROW_ID
+ (FIXME: remove this, and move to dict_table_t) */
+ Atomic_relaxed<row_id_t> row_id;
+ /** The synchronization interval of row_id */
+ static constexpr size_t ROW_ID_WRITE_MARGIN= 256;
public:
- /** @return a new temporary table ID */
- table_id_t get_temporary_table_id() {
- return temp_table_id.fetch_add(1, std::memory_order_relaxed);
- }
+ /** Diagnostic message for exceeding the lock_wait() timeout */
+ static const char fatal_msg[];
- /** Look up a temporary table.
- @param id temporary table ID
- @return temporary table
- @retval NULL if the table does not exist
- (should only happen during the rollback of CREATE...SELECT) */
- dict_table_t* get_temporary_table(table_id_t id)
- {
- ut_ad(mutex_own(&mutex));
- dict_table_t* table;
- ulint fold = ut_fold_ull(id);
- HASH_SEARCH(id_hash, &temp_id_hash, fold, dict_table_t*, table,
- ut_ad(table->cached), table->id == id);
- if (UNIV_LIKELY(table != NULL)) {
- DBUG_ASSERT(table->is_temporary());
- DBUG_ASSERT(table->id >= DICT_HDR_FIRST_ID);
- table->acquire();
- }
- return table;
- }
+ /** @return A new value for GEN_CLUST_INDEX(DB_ROW_ID) */
+ inline row_id_t get_new_row_id();
- /** Look up a persistent table.
- @param id table ID
- @return table
- @retval NULL if not cached */
- dict_table_t* get_table(table_id_t id)
- {
- ut_ad(mutex_own(&mutex));
- dict_table_t* table;
- ulint fold = ut_fold_ull(id);
- HASH_SEARCH(id_hash, &table_id_hash, fold, dict_table_t*,
- table,
- ut_ad(table->cached), table->id == id);
- DBUG_ASSERT(!table || !table->is_temporary());
- return table;
- }
+ /** Ensure that row_id is not smaller than id, on IMPORT TABLESPACE */
+ inline void update_row_id(row_id_t id);
- /**
- Constructor. Further initialisation happens in create().
- */
+ /** Recover the global DB_ROW_ID sequence on database startup */
+ void recover_row_id(row_id_t id)
+ {
+ row_id= ut_uint64_align_up(id, ROW_ID_WRITE_MARGIN) + ROW_ID_WRITE_MARGIN;
+ }
- dict_sys_t() : m_initialised(false), temp_table_id(DICT_HDR_FIRST_ID) {}
+ /** @return a new temporary table ID */
+ table_id_t acquire_temporary_table_id()
+ {
+ return temp_table_id.fetch_add(1, std::memory_order_relaxed);
+ }
+
+ /** Look up a temporary table.
+ @param id temporary table ID
+ @return temporary table
+ @retval nullptr if the table does not exist
+ (should only happen during the rollback of CREATE...SELECT) */
+ dict_table_t *acquire_temporary_table(table_id_t id)
+ {
+ ut_ad(frozen());
+ dict_table_t *table;
+ ulint fold = ut_fold_ull(id);
+ HASH_SEARCH(id_hash, &temp_id_hash, fold, dict_table_t*, table,
+ ut_ad(table->cached), table->id == id);
+ if (UNIV_LIKELY(table != nullptr))
+ {
+ DBUG_ASSERT(table->is_temporary());
+ DBUG_ASSERT(table->id >= DICT_HDR_FIRST_ID);
+ table->acquire();
+ }
+ return table;
+ }
+
+ /** Look up a persistent table.
+ @param id table ID
+ @return table
+ @retval nullptr if not cached */
+ dict_table_t *find_table(table_id_t id)
+ {
+ ut_ad(frozen());
+ dict_table_t *table;
+ ulint fold= ut_fold_ull(id);
+ HASH_SEARCH(id_hash, &table_id_hash, fold, dict_table_t*, table,
+ ut_ad(table->cached), table->id == id);
+ DBUG_ASSERT(!table || !table->is_temporary());
+ return table;
+ }
bool is_initialised() const { return m_initialised; }
@@ -1493,14 +1459,13 @@ public:
#ifdef UNIV_DEBUG
/** Find a table */
- template <bool in_lru> bool find(dict_table_t* table)
+ template <bool in_lru> bool find(const dict_table_t *table)
{
ut_ad(table);
ut_ad(table->can_be_evicted == in_lru);
- ut_ad(mutex_own(&mutex));
- for (const dict_table_t* t = UT_LIST_GET_FIRST(in_lru
- ? table_LRU : table_non_LRU);
- t; t = UT_LIST_GET_NEXT(table_LRU, t))
+ ut_ad(frozen());
+ for (const dict_table_t* t= in_lru ? table_LRU.start : table_non_LRU.start;
+ t; t = UT_LIST_GET_NEXT(table_LRU, t))
{
if (t == table) return true;
ut_ad(t->can_be_evicted == in_lru);
@@ -1508,128 +1473,146 @@ public:
return false;
}
/** Find a table */
- bool find(dict_table_t* table)
+ bool find(const dict_table_t *table)
{
return table->can_be_evicted ? find<true>(table) : find<false>(table);
}
#endif
/** Move a table to the non-LRU list from the LRU list. */
- void prevent_eviction(dict_table_t* table)
+ void prevent_eviction(dict_table_t *table)
{
+ ut_d(locked());
ut_ad(find(table));
- if (table->can_be_evicted)
- {
- table->can_be_evicted = FALSE;
- UT_LIST_REMOVE(table_LRU, table);
- UT_LIST_ADD_LAST(table_non_LRU, table);
- }
+ if (!table->can_be_evicted)
+ return;
+ table->can_be_evicted= false;
+ UT_LIST_REMOVE(table_LRU, table);
+ UT_LIST_ADD_LAST(table_non_LRU, table);
}
- /** Acquire a reference to a cached table. */
- inline void acquire(dict_table_t* table);
#ifdef UNIV_DEBUG
- /** Assert that the data dictionary is locked */
- void assert_locked()
- {
- ut_ad(mutex_own(&mutex));
- ut_ad(rw_lock_own(&latch, RW_LOCK_X));
- }
+ /** @return whether any thread (not necessarily the current thread)
+ is holding the latch; that is, this check may return false
+ positives */
+ bool frozen() const { return latch_readers || latch_ex; }
+ /** @return whether any thread (not necessarily the current thread)
+ is holding a shared latch */
+ bool frozen_not_locked() const { return latch_readers; }
+ /** @return whether the current thread holds the exclusive latch */
+ bool locked() const { return latch_ex == pthread_self(); }
#endif
- /** Lock the data dictionary cache. */
- void lock(const char* file, unsigned line)
+private:
+ /** Acquire the exclusive latch */
+ ATTRIBUTE_NOINLINE
+ void lock_wait(SRW_LOCK_ARGS(const char *file, unsigned line));
+public:
+ /** @return the my_hrtime_coarse().val of the oldest lock_wait() start,
+ assuming that requests are served on a FIFO basis */
+ ulonglong oldest_wait() const
+ { return latch_ex_wait_start.load(std::memory_order_relaxed); }
+
+ /** Exclusively lock the dictionary cache. */
+ void lock(SRW_LOCK_ARGS(const char *file, unsigned line))
{
- rw_lock_x_lock_func(&latch, 0, file, line);
- mutex_enter_loc(&mutex, file, line);
+ if (latch.wr_lock_try())
+ {
+ ut_ad(!latch_readers);
+ ut_ad(!latch_ex);
+ ut_d(latch_ex= pthread_self());
+ }
+ else
+ lock_wait(SRW_LOCK_ARGS(file, line));
}
+#ifdef UNIV_PFS_RWLOCK
+ /** Unlock the data dictionary cache. */
+ ATTRIBUTE_NOINLINE void unlock();
+ /** Acquire a shared lock on the dictionary cache. */
+ ATTRIBUTE_NOINLINE void freeze(const char *file, unsigned line);
+ /** Release a shared lock on the dictionary cache. */
+ ATTRIBUTE_NOINLINE void unfreeze();
+#else
/** Unlock the data dictionary cache. */
void unlock()
{
- mutex_exit(&mutex);
- rw_lock_x_unlock(&latch);
+ ut_ad(latch_ex == pthread_self());
+ ut_ad(!latch_readers);
+ ut_d(latch_ex= 0);
+ latch.wr_unlock();
}
+ /** Acquire a shared lock on the dictionary cache. */
+ void freeze()
+ {
+ latch.rd_lock();
+ ut_ad(!latch_ex);
+ ut_d(latch_readers++);
+ }
+ /** Release a shared lock on the dictionary cache. */
+ void unfreeze()
+ {
+ ut_ad(!latch_ex);
+ ut_ad(latch_readers--);
+ latch.rd_unlock();
+ }
+#endif
/** Estimate the used memory occupied by the data dictionary
table and index objects.
@return number of bytes occupied */
- ulint rough_size() const
+ TPOOL_SUPPRESS_TSAN ulint rough_size() const
{
- /* No mutex; this is a very crude approximation anyway */
+ /* No latch; this is a very crude approximation anyway */
ulint size = UT_LIST_GET_LEN(table_LRU) + UT_LIST_GET_LEN(table_non_LRU);
size *= sizeof(dict_table_t)
+ sizeof(dict_index_t) * 2
+ (sizeof(dict_col_t) + sizeof(dict_field_t)) * 10
+ sizeof(dict_field_t) * 5 /* total number of key fields */
+ 200; /* arbitrary, covering names and overhead */
- size += (table_hash.n_cells + table_id_hash.n_cells
- + temp_id_hash.n_cells) * sizeof(hash_cell_t);
+ size += (table_hash.n_cells + table_id_hash.n_cells +
+ temp_id_hash.n_cells) * sizeof(hash_cell_t);
return size;
}
-};
-/** the data dictionary cache */
-extern dict_sys_t dict_sys;
+ /** Evict unused, unlocked tables from table_LRU.
+ @param half whether to consider half the tables only (instead of all)
+ @return number of tables evicted */
+ ulint evict_table_LRU(bool half);
-#define dict_table_prevent_eviction(table) dict_sys.prevent_eviction(table)
-#define dict_sys_lock() dict_sys.lock(__FILE__, __LINE__)
-#define dict_sys_unlock() dict_sys.unlock()
-
-/* Auxiliary structs for checking a table definition @{ */
-
-/* This struct is used to specify the name and type that a column must
-have when checking a table's schema. */
-struct dict_col_meta_t {
- const char* name; /* column name */
- ulint mtype; /* required column main type */
- ulint prtype_mask; /* required column precise type mask;
- if this is non-zero then all the
- bits it has set must also be set
- in the column's prtype */
- ulint len; /* required column length */
-};
+ /** Look up a table in the dictionary cache.
+ @param name table name
+ @return table handle
+ @retval nullptr if not found */
+ dict_table_t *find_table(const span<const char> &name) const
+ {
+ ut_ad(frozen());
+ for (dict_table_t *table= static_cast<dict_table_t*>
+ (HASH_GET_FIRST(&table_hash, table_hash.calc_hash
+ (my_crc32c(0, name.data(), name.size()))));
+ table; table= table->name_hash)
+ if (strlen(table->name.m_name) == name.size() &&
+ !memcmp(table->name.m_name, name.data(), name.size()))
+ return table;
+ return nullptr;
+ }
-/* This struct is used for checking whether a given table exists and
-whether it has a predefined schema (number of columns and column names
-and types) */
-struct dict_table_schema_t {
- const char* table_name; /* the name of the table whose
- structure we are checking */
- ulint n_cols; /* the number of columns the
- table must have */
- dict_col_meta_t* columns; /* metadata for the columns;
- this array has n_cols
- elements */
- ulint n_foreign; /* number of foreign keys this
- table has, pointing to other
- tables (where this table is
- FK child) */
- ulint n_referenced; /* number of foreign keys other
- tables have, pointing to this
- table (where this table is
- parent) */
+ /** Look up or load a table definition
+ @param name table name
+ @param ignore errors to ignore when loading the table definition
+ @return table handle
+ @retval nullptr if not found */
+ dict_table_t *load_table(const span<const char> &name,
+ dict_err_ignore_t ignore= DICT_ERR_IGNORE_NONE);
+
+ /** Attempt to load the system tables on startup
+ @return whether any discrepancy with the expected definition was found */
+ bool load_sys_tables();
+ /** Create or check system tables on startup */
+ dberr_t create_or_check_sys_tables();
};
-/* @} */
-/*********************************************************************//**
-Checks whether a table exists and whether it has the given structure.
-The table must have the same number of columns with the same names and
-types. The order of the columns does not matter.
-The caller must own the dictionary mutex.
-dict_table_schema_check() @{
-@return DB_SUCCESS if the table exists and contains the necessary columns */
-dberr_t
-dict_table_schema_check(
-/*====================*/
- dict_table_schema_t* req_schema, /*!< in/out: required table
- schema */
- char* errstr, /*!< out: human readable error
- message if != DB_SUCCESS and
- != DB_TABLE_NOT_FOUND is
- returned */
- size_t errstr_sz) /*!< in: errstr size */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-/* @} */
+/** the data dictionary cache */
+extern dict_sys_t dict_sys;
/*********************************************************************//**
Converts a database and table name from filesystem encoding
@@ -1647,43 +1630,12 @@ dict_fs2utf8(
size_t table_utf8_size)/*!< in: table_utf8 size */
MY_ATTRIBUTE((nonnull));
-/**********************************************************************//**
-Check whether the table is corrupted.
-@return nonzero for corrupted table, zero for valid tables */
-UNIV_INLINE
-ulint
-dict_table_is_corrupted(
-/*====================*/
- const dict_table_t* table) /*!< in: table */
- MY_ATTRIBUTE((nonnull, warn_unused_result));
-
-/**********************************************************************//**
-Flags an index and table corrupted both in the data dictionary cache
-and in the system table SYS_INDEXES. */
-void
-dict_set_corrupted(
-/*===============*/
- dict_index_t* index, /*!< in/out: index */
- trx_t* trx, /*!< in/out: transaction */
- const char* ctx) /*!< in: context */
- ATTRIBUTE_COLD __attribute__((nonnull));
-
-/** Flags an index corrupted in the data dictionary cache only. This
-is used mostly to mark a corrupted index when index's own dictionary
-is corrupted, and we force to load such index for repair purpose
-@param[in,out] index index that is corrupted */
-void
-dict_set_corrupted_index_cache_only(
- dict_index_t* index);
-
-/**********************************************************************//**
-Flags a table with specified space_id corrupted in the table dictionary
-cache.
-@return TRUE if successful */
-bool dict_set_corrupted_by_space(const fil_space_t* space);
-
-/** Flag a table encrypted in the data dictionary cache. */
-void dict_set_encrypted_by_space(const fil_space_t* space);
+/** Flag an index corrupted both in the data dictionary cache
+and in the system table SYS_INDEXES.
+@param index index to be flagged as corrupted
+@param ctx context (for error log reporting) */
+void dict_set_corrupted(dict_index_t *index, const char *ctx)
+ ATTRIBUTE_COLD __attribute__((nonnull));
/** Sets merge_threshold in the SYS_INDEXES
@param[in,out] index index