2014-02-26 19:11:54 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
|
2016-06-21 14:21:03 +02:00
|
|
|
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
2019-04-03 15:10:20 +02:00
|
|
|
Copyright (c) 2017, 2019, MariaDB Corporation.
|
2014-02-26 19:11:54 +01:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
|
|
Foundation; version 2 of the License.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
2019-05-11 18:25:02 +02:00
|
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
2014-02-26 19:11:54 +01:00
|
|
|
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
/**************************************************//**
|
|
|
|
@file include/dict0load.h
|
|
|
|
Loads to the memory cache database object definitions
|
|
|
|
from dictionary tables
|
|
|
|
|
|
|
|
Created 4/24/1996 Heikki Tuuri
|
|
|
|
*******************************************************/
|
|
|
|
|
|
|
|
#ifndef dict0load_h
|
|
|
|
#define dict0load_h
|
|
|
|
|
|
|
|
#include "dict0types.h"
|
|
|
|
#include "trx0types.h"
|
|
|
|
#include "ut0byte.h"
|
|
|
|
#include "mem0mem.h"
|
|
|
|
#include "btr0types.h"
|
2016-08-12 10:17:45 +02:00
|
|
|
|
|
|
|
#include <deque>
|
|
|
|
|
|
|
|
/** A stack of table names related through foreign key constraints */
|
|
|
|
typedef std::deque<const char*, ut_allocator<const char*> > dict_names_t;
|
2014-02-26 19:11:54 +01:00
|
|
|
|
|
|
|
/** enum that defines all system table IDs. @see SYSTEM_TABLE_NAME[] */
|
|
|
|
enum dict_system_id_t {
|
|
|
|
SYS_TABLES = 0,
|
|
|
|
SYS_INDEXES,
|
|
|
|
SYS_COLUMNS,
|
|
|
|
SYS_FIELDS,
|
|
|
|
SYS_FOREIGN,
|
|
|
|
SYS_FOREIGN_COLS,
|
|
|
|
SYS_TABLESPACES,
|
|
|
|
SYS_DATAFILES,
|
2016-08-12 10:17:45 +02:00
|
|
|
SYS_VIRTUAL,
|
2014-02-26 19:11:54 +01:00
|
|
|
|
|
|
|
/* This must be last item. Defines the number of system tables. */
|
|
|
|
SYS_NUM_SYSTEM_TABLES
|
|
|
|
};
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
/** Check each tablespace found in the data dictionary.
|
|
|
|
Look at each table defined in SYS_TABLES that has a space_id > 0.
|
|
|
|
If the tablespace is not yet in the fil_system cache, look up the
|
|
|
|
tablespace in SYS_DATAFILES to ensure the correct path.
|
2014-02-26 19:11:54 +01:00
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
In a crash recovery we already have some tablespace objects created from
|
|
|
|
processing the REDO log. Any other tablespace in SYS_TABLESPACES not
|
|
|
|
previously used in recovery will be opened here. We will compare the
|
|
|
|
space_id information in the data dictionary to what we find in the
|
|
|
|
tablespace file. In addition, more validation will be done if recovery
|
|
|
|
was needed and force_recovery is not set.
|
|
|
|
|
2019-04-03 15:10:20 +02:00
|
|
|
We also scan the biggest space id, and store it to fil_system. */
|
|
|
|
void dict_check_tablespaces_and_store_max_id();
|
2016-08-12 10:17:45 +02:00
|
|
|
|
2014-02-26 19:11:54 +01:00
|
|
|
/********************************************************************//**
|
|
|
|
Finds the first table name in the given database.
|
|
|
|
@return own: table name, NULL if does not exist; the caller must free
|
|
|
|
the memory in the string! */
|
|
|
|
char*
|
|
|
|
dict_get_first_table_name_in_db(
|
|
|
|
/*============================*/
|
|
|
|
const char* name); /*!< in: database name which ends to '/' */
|
2016-08-12 10:17:45 +02:00
|
|
|
|
2016-09-06 08:43:16 +02:00
|
|
|
/** Get the first filepath from SYS_DATAFILES for a given space_id.
|
|
|
|
@param[in] space_id Tablespace ID
|
|
|
|
@return First filepath (caller must invoke ut_free() on it)
|
|
|
|
@retval NULL if no SYS_DATAFILES entry was found. */
|
|
|
|
char*
|
|
|
|
dict_get_first_path(
|
|
|
|
ulint space_id);
|
|
|
|
|
2016-08-12 10:17:45 +02:00
|
|
|
/** Make sure the data_file_name is saved in dict_table_t if needed.
|
|
|
|
Try to read it from the fil_system first, then from SYS_DATAFILES.
|
|
|
|
@param[in] table Table object
|
|
|
|
@param[in] dict_mutex_own true if dict_sys->mutex is owned already */
|
2014-02-26 19:11:54 +01:00
|
|
|
void
|
|
|
|
dict_get_and_save_data_dir_path(
|
2016-08-12 10:17:45 +02:00
|
|
|
dict_table_t* table,
|
|
|
|
bool dict_mutex_own);
|
|
|
|
|
|
|
|
/** Loads a table definition and also all its index definitions, and also
|
2014-02-26 19:11:54 +01:00
|
|
|
the cluster definition if the table is a member in a cluster. Also loads
|
|
|
|
all foreign key constraints where the foreign key is in the table or where
|
|
|
|
a foreign key references columns in this table.
|
2016-08-12 10:17:45 +02:00
|
|
|
@param[in] name Table name in the dbname/tablename format
|
|
|
|
@param[in] cached true=add to cache, false=do not
|
|
|
|
@param[in] ignore_err Error to be ignored when loading
|
|
|
|
table and its index definition
|
2014-02-26 19:11:54 +01:00
|
|
|
@return table, NULL if does not exist; if the table is stored in an
|
2017-05-05 09:25:29 +02:00
|
|
|
.ibd file, but the file does not exist, then we set the file_unreadable
|
2016-08-12 10:17:45 +02:00
|
|
|
flag in the table object we return. */
|
2014-02-26 19:11:54 +01:00
|
|
|
dict_table_t*
|
|
|
|
dict_load_table(
|
2016-08-12 10:17:45 +02:00
|
|
|
const char* name,
|
|
|
|
bool cached,
|
2014-02-26 19:11:54 +01:00
|
|
|
dict_err_ignore_t ignore_err);
|
2016-08-12 10:17:45 +02:00
|
|
|
|
2014-02-26 19:11:54 +01:00
|
|
|
/***********************************************************************//**
|
|
|
|
Loads a table object based on the table id.
|
2016-08-12 10:17:45 +02:00
|
|
|
@return table; NULL if table does not exist */
|
2014-02-26 19:11:54 +01:00
|
|
|
dict_table_t*
|
|
|
|
dict_load_table_on_id(
|
|
|
|
/*==================*/
|
|
|
|
table_id_t table_id, /*!< in: table id */
|
|
|
|
dict_err_ignore_t ignore_err); /*!< in: errors to ignore
|
|
|
|
when loading the table */
|
|
|
|
/********************************************************************//**
|
|
|
|
This function is called when the database is booted.
|
|
|
|
Loads system table index definitions except for the clustered index which
|
|
|
|
is added to the dictionary cache at booting before calling this function. */
|
|
|
|
void
|
|
|
|
dict_load_sys_table(
|
|
|
|
/*================*/
|
|
|
|
dict_table_t* table); /*!< in: system table */
|
|
|
|
/***********************************************************************//**
|
|
|
|
Loads foreign key constraints where the table is either the foreign key
|
|
|
|
holder or where the table is referenced by a foreign key. Adds these
|
2016-08-12 10:17:45 +02:00
|
|
|
constraints to the data dictionary.
|
|
|
|
|
|
|
|
The foreign key constraint is loaded only if the referenced table is also
|
|
|
|
in the dictionary cache. If the referenced table is not in dictionary
|
|
|
|
cache, then it is added to the output parameter (fk_tables).
|
|
|
|
|
|
|
|
@return DB_SUCCESS or error code */
|
2014-02-26 19:11:54 +01:00
|
|
|
dberr_t
|
|
|
|
dict_load_foreigns(
|
|
|
|
/*===============*/
|
|
|
|
const char* table_name, /*!< in: table name */
|
|
|
|
const char** col_names, /*!< in: column names, or NULL
|
|
|
|
to use table->col_names */
|
|
|
|
bool check_recursive,/*!< in: Whether to check
|
|
|
|
recursive load of tables
|
|
|
|
chained by FK */
|
|
|
|
bool check_charsets, /*!< in: whether to check
|
|
|
|
charset compatibility */
|
2016-08-12 10:17:45 +02:00
|
|
|
dict_err_ignore_t ignore_err, /*!< in: error to be ignored */
|
|
|
|
dict_names_t& fk_tables) /*!< out: stack of table names
|
|
|
|
which must be loaded
|
|
|
|
subsequently to load all the
|
|
|
|
foreign key constraints. */
|
2016-09-06 08:43:16 +02:00
|
|
|
MY_ATTRIBUTE((nonnull(1), warn_unused_result));
|
2014-02-26 19:11:54 +01:00
|
|
|
|
|
|
|
/********************************************************************//**
|
|
|
|
This function opens a system table, and return the first record.
|
2016-08-12 10:17:45 +02:00
|
|
|
@return first record of the system table */
|
2014-02-26 19:11:54 +01:00
|
|
|
const rec_t*
|
|
|
|
dict_startscan_system(
|
|
|
|
/*==================*/
|
|
|
|
btr_pcur_t* pcur, /*!< out: persistent cursor to
|
|
|
|
the record */
|
|
|
|
mtr_t* mtr, /*!< in: the mini-transaction */
|
|
|
|
dict_system_id_t system_id); /*!< in: which system table to open */
|
|
|
|
/********************************************************************//**
|
|
|
|
This function get the next system table record as we scan the table.
|
2016-08-12 10:17:45 +02:00
|
|
|
@return the record if found, NULL if end of scan. */
|
2014-02-26 19:11:54 +01:00
|
|
|
const rec_t*
|
|
|
|
dict_getnext_system(
|
|
|
|
/*================*/
|
|
|
|
btr_pcur_t* pcur, /*!< in/out: persistent cursor
|
|
|
|
to the record */
|
|
|
|
mtr_t* mtr); /*!< in: the mini-transaction */
|
|
|
|
/********************************************************************//**
|
|
|
|
This function processes one SYS_TABLES record and populate the dict_table_t
|
2017-12-08 15:31:54 +01:00
|
|
|
struct for the table.
|
2014-02-26 19:11:54 +01:00
|
|
|
@return error message, or NULL on success */
|
|
|
|
const char*
|
|
|
|
dict_process_sys_tables_rec_and_mtr_commit(
|
|
|
|
/*=======================================*/
|
|
|
|
mem_heap_t* heap, /*!< in: temporary memory heap */
|
|
|
|
const rec_t* rec, /*!< in: SYS_TABLES record */
|
|
|
|
dict_table_t** table, /*!< out: dict_table_t to fill */
|
MDEV-12266: Change dict_table_t::space to fil_space_t*
InnoDB always keeps all tablespaces in the fil_system cache.
The fil_system.LRU is only for closing file handles; the
fil_space_t and fil_node_t for all data files will remain
in main memory. Between startup to shutdown, they can only be
created and removed by DDL statements. Therefore, we can
let dict_table_t::space point directly to the fil_space_t.
dict_table_t::space_id: A numeric tablespace ID for the corner cases
where we do not have a tablespace. The most prominent examples are
ALTER TABLE...DISCARD TABLESPACE or a missing or corrupted file.
There are a few functional differences; most notably:
(1) DROP TABLE will delete matching .ibd and .cfg files,
even if they were not attached to the data dictionary.
(2) Some error messages will report file names instead of numeric IDs.
There still are many functions that use numeric tablespace IDs instead
of fil_space_t*, and many functions could be converted to fil_space_t
member functions. Also, Tablespace and Datafile should be merged with
fil_space_t and fil_node_t. page_id_t and buf_page_get_gen() could use
fil_space_t& instead of a numeric ID, and after moving to a single
buffer pool (MDEV-15058), buf_pool_t::page_hash could be moved to
fil_space_t::page_hash.
FilSpace: Remove. Only few calls to fil_space_acquire() will remain,
and gradually they should be removed.
mtr_t::set_named_space_id(ulint): Renamed from set_named_space(),
to prevent accidental calls to this slower function. Very few
callers remain.
fseg_create(), fsp_reserve_free_extents(): Take fil_space_t*
as a parameter instead of a space_id.
fil_space_t::rename(): Wrapper for fil_rename_tablespace_check(),
fil_name_write_rename(), fil_rename_tablespace(). Mariabackup
passes the parameter log=false; InnoDB passes log=true.
dict_mem_table_create(): Take fil_space_t* instead of space_id
as parameter.
dict_process_sys_tables_rec_and_mtr_commit(): Replace the parameter
'status' with 'bool cached'.
dict_get_and_save_data_dir_path(): Avoid copying the fil_node_t::name.
fil_ibd_open(): Return the tablespace.
fil_space_t::set_imported(): Replaces fil_space_set_imported().
truncate_t: Change many member function parameters to fil_space_t*,
and remove page_size parameters.
row_truncate_prepare(): Merge to its only caller.
row_drop_table_from_cache(): Assert that the table is persistent.
dict_create_sys_indexes_tuple(): Write SYS_INDEXES.SPACE=FIL_NULL
if the tablespace has been discarded.
row_import_update_discarded_flag(): Remove a constant parameter.
2018-03-27 15:31:10 +02:00
|
|
|
bool cached, /*!< in: whether to load from cache */
|
2014-02-26 19:11:54 +01:00
|
|
|
mtr_t* mtr); /*!< in/out: mini-transaction,
|
|
|
|
will be committed */
|
|
|
|
/********************************************************************//**
|
|
|
|
This function parses a SYS_INDEXES record and populate a dict_index_t
|
|
|
|
structure with the information from the record. For detail information
|
|
|
|
about SYS_INDEXES fields, please refer to dict_boot() function.
|
|
|
|
@return error message, or NULL on success */
|
|
|
|
const char*
|
|
|
|
dict_process_sys_indexes_rec(
|
|
|
|
/*=========================*/
|
|
|
|
mem_heap_t* heap, /*!< in/out: heap memory */
|
|
|
|
const rec_t* rec, /*!< in: current SYS_INDEXES rec */
|
|
|
|
dict_index_t* index, /*!< out: dict_index_t to be
|
|
|
|
filled */
|
|
|
|
table_id_t* table_id); /*!< out: table id */
|
|
|
|
/********************************************************************//**
|
|
|
|
This function parses a SYS_COLUMNS record and populate a dict_column_t
|
|
|
|
structure with the information from the record.
|
|
|
|
@return error message, or NULL on success */
|
|
|
|
const char*
|
|
|
|
dict_process_sys_columns_rec(
|
|
|
|
/*=========================*/
|
|
|
|
mem_heap_t* heap, /*!< in/out: heap memory */
|
|
|
|
const rec_t* rec, /*!< in: current SYS_COLUMNS rec */
|
|
|
|
dict_col_t* column, /*!< out: dict_col_t to be filled */
|
|
|
|
table_id_t* table_id, /*!< out: table id */
|
2016-08-12 10:17:45 +02:00
|
|
|
const char** col_name, /*!< out: column name */
|
|
|
|
ulint* nth_v_col); /*!< out: if virtual col, this is
|
|
|
|
records its sequence number */
|
|
|
|
|
|
|
|
/** This function parses a SYS_VIRTUAL record and extract virtual column
|
|
|
|
information
|
|
|
|
@param[in,out] heap heap memory
|
|
|
|
@param[in] rec current SYS_COLUMNS rec
|
|
|
|
@param[in,out] table_id table id
|
|
|
|
@param[in,out] pos virtual column position
|
|
|
|
@param[in,out] base_pos base column position
|
|
|
|
@return error message, or NULL on success */
|
|
|
|
const char*
|
|
|
|
dict_process_sys_virtual_rec(
|
|
|
|
const rec_t* rec,
|
|
|
|
table_id_t* table_id,
|
|
|
|
ulint* pos,
|
|
|
|
ulint* base_pos);
|
2014-02-26 19:11:54 +01:00
|
|
|
/********************************************************************//**
|
|
|
|
This function parses a SYS_FIELDS record and populate a dict_field_t
|
|
|
|
structure with the information from the record.
|
|
|
|
@return error message, or NULL on success */
|
|
|
|
const char*
|
|
|
|
dict_process_sys_fields_rec(
|
|
|
|
/*========================*/
|
|
|
|
mem_heap_t* heap, /*!< in/out: heap memory */
|
|
|
|
const rec_t* rec, /*!< in: current SYS_FIELDS rec */
|
|
|
|
dict_field_t* sys_field, /*!< out: dict_field_t to be
|
|
|
|
filled */
|
|
|
|
ulint* pos, /*!< out: Field position */
|
|
|
|
index_id_t* index_id, /*!< out: current index id */
|
|
|
|
index_id_t last_id); /*!< in: previous index id */
|
|
|
|
/********************************************************************//**
|
|
|
|
This function parses a SYS_FOREIGN record and populate a dict_foreign_t
|
|
|
|
structure with the information from the record. For detail information
|
|
|
|
about SYS_FOREIGN fields, please refer to dict_load_foreign() function
|
|
|
|
@return error message, or NULL on success */
|
|
|
|
const char*
|
|
|
|
dict_process_sys_foreign_rec(
|
|
|
|
/*=========================*/
|
|
|
|
mem_heap_t* heap, /*!< in/out: heap memory */
|
|
|
|
const rec_t* rec, /*!< in: current SYS_FOREIGN rec */
|
|
|
|
dict_foreign_t* foreign); /*!< out: dict_foreign_t to be
|
|
|
|
filled */
|
|
|
|
/********************************************************************//**
|
|
|
|
This function parses a SYS_FOREIGN_COLS record and extract necessary
|
|
|
|
information from the record and return to caller.
|
|
|
|
@return error message, or NULL on success */
|
|
|
|
const char*
|
|
|
|
dict_process_sys_foreign_col_rec(
|
|
|
|
/*=============================*/
|
|
|
|
mem_heap_t* heap, /*!< in/out: heap memory */
|
|
|
|
const rec_t* rec, /*!< in: current SYS_FOREIGN_COLS rec */
|
|
|
|
const char** name, /*!< out: foreign key constraint name */
|
|
|
|
const char** for_col_name, /*!< out: referencing column name */
|
|
|
|
const char** ref_col_name, /*!< out: referenced column name
|
|
|
|
in referenced table */
|
|
|
|
ulint* pos); /*!< out: column position */
|
|
|
|
/********************************************************************//**
|
|
|
|
This function parses a SYS_TABLESPACES record, extracts necessary
|
|
|
|
information from the record and returns to caller.
|
|
|
|
@return error message, or NULL on success */
|
|
|
|
const char*
|
|
|
|
dict_process_sys_tablespaces(
|
|
|
|
/*=========================*/
|
|
|
|
mem_heap_t* heap, /*!< in/out: heap memory */
|
|
|
|
const rec_t* rec, /*!< in: current SYS_TABLESPACES rec */
|
|
|
|
ulint* space, /*!< out: pace id */
|
|
|
|
const char** name, /*!< out: tablespace name */
|
|
|
|
ulint* flags); /*!< out: tablespace flags */
|
|
|
|
/********************************************************************//**
|
|
|
|
This function parses a SYS_DATAFILES record, extracts necessary
|
|
|
|
information from the record and returns to caller.
|
|
|
|
@return error message, or NULL on success */
|
|
|
|
const char*
|
|
|
|
dict_process_sys_datafiles(
|
|
|
|
/*=======================*/
|
|
|
|
mem_heap_t* heap, /*!< in/out: heap memory */
|
|
|
|
const rec_t* rec, /*!< in: current SYS_DATAFILES rec */
|
|
|
|
ulint* space, /*!< out: pace id */
|
|
|
|
const char** path); /*!< out: datafile path */
|
2016-08-12 10:17:45 +02:00
|
|
|
|
|
|
|
/** Update the record for space_id in SYS_TABLESPACES to this filepath.
|
|
|
|
@param[in] space_id Tablespace ID
|
|
|
|
@param[in] filepath Tablespace filepath
|
|
|
|
@return DB_SUCCESS if OK, dberr_t if the insert failed */
|
2014-02-26 19:11:54 +01:00
|
|
|
dberr_t
|
|
|
|
dict_update_filepath(
|
2016-08-12 10:17:45 +02:00
|
|
|
ulint space_id,
|
|
|
|
const char* filepath);
|
|
|
|
|
|
|
|
/** Replace records in SYS_TABLESPACES and SYS_DATAFILES associated with
|
|
|
|
the given space_id using an independent transaction.
|
|
|
|
@param[in] space_id Tablespace ID
|
|
|
|
@param[in] name Tablespace name
|
|
|
|
@param[in] filepath First filepath
|
|
|
|
@param[in] fsp_flags Tablespace flags
|
|
|
|
@return DB_SUCCESS if OK, dberr_t if the insert failed */
|
2014-02-26 19:11:54 +01:00
|
|
|
dberr_t
|
2016-08-12 10:17:45 +02:00
|
|
|
dict_replace_tablespace_and_filepath(
|
|
|
|
ulint space_id,
|
|
|
|
const char* name,
|
|
|
|
const char* filepath,
|
|
|
|
ulint fsp_flags);
|
2014-02-26 19:11:54 +01:00
|
|
|
|
|
|
|
#endif
|