mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-25743: Unnecessary copying of table names in InnoDB dictionary
Many InnoDB data dictionary cache operations require that the table name be copied so that it will be NUL terminated. (For example, SYS_TABLES.NAME is not guaranteed to be NUL-terminated.) dict_table_t::is_garbage_name(): Check if a name belongs to the background drop table queue. dict_check_if_system_table_exists(): Remove. dict_sys_t::load_sys_tables(): Load the non-hard-coded system tables SYS_FOREIGN, SYS_FOREIGN_COLS, SYS_VIRTUAL on startup. dict_sys_t::create_or_check_sys_tables(): Replaces dict_create_or_check_foreign_constraint_tables() and dict_create_or_check_sys_virtual(). dict_sys_t::load_table(): Replaces dict_table_get_low() and dict_load_table(). dict_sys_t::find_table(): Renamed from get_table(). dict_sys_t::sys_tables_exist(): Check whether all the non-hard-coded tables SYS_FOREIGN, SYS_FOREIGN_COLS, SYS_VIRTUAL exist. trx_t::has_stats_table_lock(): Moved to dict0stats.cc. Some error messages will now report table names in the internal databasename/tablename format, instead of `databasename`.`tablename`.
This commit is contained in:
@@ -71,7 +71,6 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|||||||
|
|
||||||
|
|
||||||
#include <btr0sea.h>
|
#include <btr0sea.h>
|
||||||
#include <dict0priv.h>
|
|
||||||
#include <lock0lock.h>
|
#include <lock0lock.h>
|
||||||
#include <log0recv.h>
|
#include <log0recv.h>
|
||||||
#include <log0crypt.h>
|
#include <log0crypt.h>
|
||||||
@@ -3315,19 +3314,18 @@ static void xb_load_single_table_tablespace(const char *dirname,
|
|||||||
name[pathlen - 5] = 0;
|
name[pathlen - 5] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fil_space_t::name_type n{name, pathlen - 5};
|
||||||
Datafile *file;
|
Datafile *file;
|
||||||
|
|
||||||
if (is_remote) {
|
if (is_remote) {
|
||||||
RemoteDatafile* rf = new RemoteDatafile();
|
RemoteDatafile* rf = new RemoteDatafile();
|
||||||
if (!rf->open_link_file(name)) {
|
if (!rf->open_link_file(n)) {
|
||||||
die("Can't open datafile %s", name);
|
die("Can't open datafile %s", name);
|
||||||
}
|
}
|
||||||
file = rf;
|
file = rf;
|
||||||
} else {
|
} else {
|
||||||
file = new Datafile();
|
file = new Datafile();
|
||||||
file->make_filepath(".",
|
file->make_filepath(".", n, IBD);
|
||||||
fil_space_t::name_type{name, strlen(name)},
|
|
||||||
IBD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file->open_read_only(true) != DB_SUCCESS) {
|
if (file->open_read_only(true) != DB_SUCCESS) {
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
call mtr.add_suppression("\\[ERROR\\] InnoDB: Tablespace flags are invalid in datafile: .*test.t[rcd]\\.ibd");
|
call mtr.add_suppression("\\[ERROR\\] InnoDB: Tablespace flags are invalid in datafile: .*test.t[rcd]\\.ibd");
|
||||||
call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\.");
|
call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\.");
|
||||||
call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\.");
|
call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\.");
|
||||||
call mtr.add_suppression("\\[Warning\\] InnoDB: Ignoring tablespace for `test`\\.`td` because it could not be opened\\.");
|
call mtr.add_suppression("\\[Warning\\] InnoDB: Ignoring tablespace for test/td because it could not be opened\\.");
|
||||||
CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
|
CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
|
||||||
CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT
|
CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT
|
||||||
PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9;
|
PAGE_COMPRESSED=1 PAGE_COMPRESSION_LEVEL=9;
|
||||||
|
@@ -75,7 +75,7 @@ DROP TABLE t1;
|
|||||||
Warnings:
|
Warnings:
|
||||||
Warning 1932 Table 'test.t1' doesn't exist in engine
|
Warning 1932 Table 'test.t1' doesn't exist in engine
|
||||||
DROP TABLE t2,t3;
|
DROP TABLE t2,t3;
|
||||||
FOUND 5 /\[ERROR\] InnoDB: Table `test`\.`t1` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b/ in mysqld.1.err
|
FOUND 5 /\[ERROR\] InnoDB: Table test/t1 in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b/ in mysqld.1.err
|
||||||
# restart
|
# restart
|
||||||
ib_buffer_pool
|
ib_buffer_pool
|
||||||
ib_logfile0
|
ib_logfile0
|
||||||
|
@@ -122,8 +122,8 @@ a
|
|||||||
42
|
42
|
||||||
SHOW CREATE TABLE tp;
|
SHOW CREATE TABLE tp;
|
||||||
ERROR 42S02: Table 'test.tp' doesn't exist in engine
|
ERROR 42S02: Table 'test.tp' doesn't exist in engine
|
||||||
FOUND 5 /InnoDB: Table `test`.`t[cp]` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649/ in mysqld.1.err
|
FOUND 5 /InnoDB: Table test/t[cp] in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649/ in mysqld.1.err
|
||||||
FOUND 2 /InnoDB: Table `test`\.`tr` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=65 SYS_TABLES\.MIX_LEN=4294967295\b/ in mysqld.1.err
|
FOUND 2 /InnoDB: Table test/tr in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=65 SYS_TABLES\.MIX_LEN=4294967295\b/ in mysqld.1.err
|
||||||
Restoring SYS_TABLES clustered index root page (8)
|
Restoring SYS_TABLES clustered index root page (8)
|
||||||
# restart: with restart_parameters
|
# restart: with restart_parameters
|
||||||
SHOW CREATE TABLE tr;
|
SHOW CREATE TABLE tr;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
call mtr.add_suppression("InnoDB: Operating system error number ");
|
call mtr.add_suppression("InnoDB: Operating system error number ");
|
||||||
call mtr.add_suppression("InnoDB: (The error means|If you are|Cannot open datafile) ");
|
call mtr.add_suppression("InnoDB: (The error means|If you are|Cannot open datafile) ");
|
||||||
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`\.`t`");
|
call mtr.add_suppression("InnoDB: Ignoring tablespace for test/t ");
|
||||||
call mtr.add_suppression("InnoDB: Table test/t .* does not exist");
|
call mtr.add_suppression("InnoDB: Table test/t .* does not exist");
|
||||||
CREATE TABLE t (a SERIAL) ENGINE=InnoDB;
|
CREATE TABLE t (a SERIAL) ENGINE=InnoDB;
|
||||||
INSERT INTO t() VALUES();
|
INSERT INTO t() VALUES();
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
call mtr.add_suppression("InnoDB: Cannot open datafile for read-only: ");
|
call mtr.add_suppression("InnoDB: Cannot open datafile for read-only: ");
|
||||||
call mtr.add_suppression("InnoDB: Operating system error number .* in a file operation");
|
call mtr.add_suppression("InnoDB: Operating system error number .* in a file operation");
|
||||||
call mtr.add_suppression("InnoDB: The error means the system cannot find the path specified");
|
call mtr.add_suppression("InnoDB: The error means the system cannot find the path specified");
|
||||||
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`.`\(t\|x\.\.d\)` because it could not be opened");
|
call mtr.add_suppression("InnoDB: Ignoring tablespace for test/\(t\|x@002e@002ed\) because it could not be opened");
|
||||||
call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing");
|
call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing");
|
||||||
call mtr.add_suppression("Could not find a valid tablespace file for");
|
call mtr.add_suppression("Could not find a valid tablespace file for");
|
||||||
call mtr.add_suppression("InnoDB: Failed to find tablespace for table `test`\.`\(t\|x\.\.d\)` in the cache");
|
call mtr.add_suppression("InnoDB: Failed to find tablespace for table `test`\.`\(t\|x\.\.d\)` in the cache");
|
||||||
|
@@ -164,7 +164,7 @@ call mtr.add_suppression("InnoDB: The error means the system cannot find the pat
|
|||||||
call mtr.add_suppression("InnoDB: .*you must create directories");
|
call mtr.add_suppression("InnoDB: .*you must create directories");
|
||||||
call mtr.add_suppression("InnoDB: Cannot open datafile for read-only: '.*u[1-5]\.ibd'");
|
call mtr.add_suppression("InnoDB: Cannot open datafile for read-only: '.*u[1-5]\.ibd'");
|
||||||
call mtr.add_suppression("InnoDB: Could not find a valid tablespace file for `test/u[1-5]`");
|
call mtr.add_suppression("InnoDB: Could not find a valid tablespace file for `test/u[1-5]`");
|
||||||
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`.`u[1-3]` because it could not be opened.");
|
call mtr.add_suppression("InnoDB: Ignoring tablespace for test/u[1-3] because it could not be opened\\.");
|
||||||
call mtr.add_suppression("InnoDB: Failed to find tablespace for table .* in the cache. Attempting to load the tablespace with space id");
|
call mtr.add_suppression("InnoDB: Failed to find tablespace for table .* in the cache. Attempting to load the tablespace with space id");
|
||||||
call mtr.add_suppression("InnoDB: Plugin initialization aborted");
|
call mtr.add_suppression("InnoDB: Plugin initialization aborted");
|
||||||
call mtr.add_suppression("Plugin 'InnoDB' \(init function returned error\|registration as a STORAGE ENGINE failed\)");
|
call mtr.add_suppression("Plugin 'InnoDB' \(init function returned error\|registration as a STORAGE ENGINE failed\)");
|
||||||
|
@@ -18,7 +18,7 @@ let page_size= `select @@innodb_page_size`;
|
|||||||
call mtr.add_suppression("\\[ERROR\\] InnoDB: Tablespace flags are invalid in datafile: .*test.t[rcd]\\.ibd");
|
call mtr.add_suppression("\\[ERROR\\] InnoDB: Tablespace flags are invalid in datafile: .*test.t[rcd]\\.ibd");
|
||||||
call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\.");
|
call mtr.add_suppression("\\[ERROR\\] InnoDB: Operating system error number .* in a file operation\\.");
|
||||||
call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\.");
|
call mtr.add_suppression("\\[ERROR\\] InnoDB: The error means the system cannot find the path specified\\.");
|
||||||
call mtr.add_suppression("\\[Warning\\] InnoDB: Ignoring tablespace for `test`\\.`td` because it could not be opened\\.");
|
call mtr.add_suppression("\\[Warning\\] InnoDB: Ignoring tablespace for test/td because it could not be opened\\.");
|
||||||
|
|
||||||
CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
|
CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
|
||||||
CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT
|
CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
--disable_query_log
|
--disable_query_log
|
||||||
call mtr.add_suppression("InnoDB: Table `mysql`\\.`innodb_table_stats` not found");
|
call mtr.add_suppression("InnoDB: Table `mysql`\\.`innodb_table_stats` not found");
|
||||||
call mtr.add_suppression("InnoDB: Table `test`.`t1` in InnoDB data dictionary contains invalid flags. SYS_TABLES\\.TYPE=1 SYS_TABLES\\.MIX_LEN=511\\r?$");
|
call mtr.add_suppression("InnoDB: Table test/t1 in InnoDB data dictionary contains invalid flags. SYS_TABLES\\.TYPE=1 SYS_TABLES\\.MIX_LEN=511\\r?$");
|
||||||
call mtr.add_suppression("InnoDB: Parent table of FTS auxiliary table test/FTS_.* not found");
|
call mtr.add_suppression("InnoDB: Parent table of FTS auxiliary table test/FTS_.* not found");
|
||||||
call mtr.add_suppression("InnoDB: Cannot open table test/t1 from the internal data dictionary");
|
call mtr.add_suppression("InnoDB: Cannot open table test/t1 from the internal data dictionary");
|
||||||
call mtr.add_suppression("InnoDB: Table `test`.`t1` does not exist in the InnoDB internal data dictionary though MariaDB is trying to (rename|drop)");
|
call mtr.add_suppression("InnoDB: Table `test`.`t1` does not exist in the InnoDB internal data dictionary though MariaDB is trying to (rename|drop)");
|
||||||
@@ -153,7 +153,7 @@ RENAME TABLE t1 TO tee_one;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP TABLE t2,t3;
|
DROP TABLE t2,t3;
|
||||||
|
|
||||||
--let SEARCH_PATTERN= \[ERROR\] InnoDB: Table `test`\.`t1` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b
|
--let SEARCH_PATTERN= \[ERROR\] InnoDB: Table test/t1 in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b
|
||||||
--source include/search_pattern_in_file.inc
|
--source include/search_pattern_in_file.inc
|
||||||
|
|
||||||
--let $restart_parameters=
|
--let $restart_parameters=
|
||||||
|
@@ -6,8 +6,8 @@
|
|||||||
--disable_query_log
|
--disable_query_log
|
||||||
call mtr.add_suppression("InnoDB: Table `mysql`\\.`innodb_table_stats` not found");
|
call mtr.add_suppression("InnoDB: Table `mysql`\\.`innodb_table_stats` not found");
|
||||||
call mtr.add_suppression("InnoDB: incorrect flags in SYS_TABLES");
|
call mtr.add_suppression("InnoDB: incorrect flags in SYS_TABLES");
|
||||||
call mtr.add_suppression("InnoDB: Table `test`.`t[cp]` in InnoDB data dictionary contains invalid flags\\. SYS_TABLES\\.TYPE=(129|289|3873|1232[31]) SYS_TABLES\\.N_COLS=2147483649\\r?$");
|
call mtr.add_suppression("InnoDB: Table test/t[cp] in InnoDB data dictionary contains invalid flags\\. SYS_TABLES\\.TYPE=(129|289|3873|1232[31]) SYS_TABLES\\.N_COLS=2147483649\\r?$");
|
||||||
call mtr.add_suppression("InnoDB: Table `test`\\.`tr` in InnoDB data dictionary contains invalid flags\\. SYS_TABLES\\.TYPE=65 SYS_TABLES\\.MIX_LEN=4294967295\\r?$");
|
call mtr.add_suppression("InnoDB: Table test/tr in InnoDB data dictionary contains invalid flags\\. SYS_TABLES\\.TYPE=65 SYS_TABLES\\.MIX_LEN=4294967295\\r?$");
|
||||||
call mtr.add_suppression("InnoDB: Refusing to load '\\..test.td\\.ibd' \\(id=3, flags=0x([2e]1)\\); dictionary contains id=3, flags=0x100\\1\\r?$");
|
call mtr.add_suppression("InnoDB: Refusing to load '\\..test.td\\.ibd' \\(id=3, flags=0x([2e]1)\\); dictionary contains id=3, flags=0x100\\1\\r?$");
|
||||||
call mtr.add_suppression("InnoDB: Refusing to load '\\..test.td\\.ibd' \\(id=3, flags=0x(1[2ae]1)\\); dictionary contains id=3, flags=0x10\\1\\r?$");
|
call mtr.add_suppression("InnoDB: Refusing to load '\\..test.td\\.ibd' \\(id=3, flags=0x(1[2ae]1)\\); dictionary contains id=3, flags=0x10\\1\\r?$");
|
||||||
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`.`td` because it could not be opened\\.");
|
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`.`td` because it could not be opened\\.");
|
||||||
@@ -170,9 +170,9 @@ SHOW CREATE TABLE tp;
|
|||||||
--source include/shutdown_mysqld.inc
|
--source include/shutdown_mysqld.inc
|
||||||
|
|
||||||
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
|
let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err;
|
||||||
--let SEARCH_PATTERN= InnoDB: Table `test`.`t[cp]` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649
|
--let SEARCH_PATTERN= InnoDB: Table test/t[cp] in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649
|
||||||
--source include/search_pattern_in_file.inc
|
--source include/search_pattern_in_file.inc
|
||||||
--let SEARCH_PATTERN= InnoDB: Table `test`\.`tr` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=65 SYS_TABLES\.MIX_LEN=4294967295\b
|
--let SEARCH_PATTERN= InnoDB: Table test/tr in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=65 SYS_TABLES\.MIX_LEN=4294967295\b
|
||||||
--source include/search_pattern_in_file.inc
|
--source include/search_pattern_in_file.inc
|
||||||
|
|
||||||
# Restore the backup of the corrupted SYS_TABLES clustered index root page
|
# Restore the backup of the corrupted SYS_TABLES clustered index root page
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
call mtr.add_suppression("InnoDB: Operating system error number ");
|
call mtr.add_suppression("InnoDB: Operating system error number ");
|
||||||
call mtr.add_suppression("InnoDB: (The error means|If you are|Cannot open datafile) ");
|
call mtr.add_suppression("InnoDB: (The error means|If you are|Cannot open datafile) ");
|
||||||
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`\.`t`");
|
call mtr.add_suppression("InnoDB: Ignoring tablespace for test/t ");
|
||||||
call mtr.add_suppression("InnoDB: Table test/t .* does not exist");
|
call mtr.add_suppression("InnoDB: Table test/t .* does not exist");
|
||||||
|
|
||||||
CREATE TABLE t (a SERIAL) ENGINE=InnoDB;
|
CREATE TABLE t (a SERIAL) ENGINE=InnoDB;
|
||||||
|
@@ -252,7 +252,7 @@ if (!$have_debug)
|
|||||||
call mtr.add_suppression("InnoDB: Cannot (read first page of|open datafile for read-only:) '\\./test/(FTS_|#sql-(alter|backup)-).*\\.ibd'");
|
call mtr.add_suppression("InnoDB: Cannot (read first page of|open datafile for read-only:) '\\./test/(FTS_|#sql-(alter|backup)-).*\\.ibd'");
|
||||||
call mtr.add_suppression("InnoDB: Datafile '\\./test/(FTS_|#sql-(alter|backup)-).*\\.ibd' is corrupted");
|
call mtr.add_suppression("InnoDB: Datafile '\\./test/(FTS_|#sql-(alter|backup)-).*\\.ibd' is corrupted");
|
||||||
call mtr.add_suppression("InnoDB: (The error means|Operating system error)");
|
call mtr.add_suppression("InnoDB: (The error means|Operating system error)");
|
||||||
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`\\.`(FTS_|#sql-(backup|alter)-).*` because it could not be opened\\.");
|
call mtr.add_suppression("InnoDB: Ignoring tablespace for test/(FTS_|#sql-(backup|alter)-).* because it could not be opened\\.");
|
||||||
call mtr.add_suppression("InnoDB: Expected tablespace id [1-9][0-9]* but found 0 in the file .*/test/(FTS_|#sql-(alter|backup)-).*\\.ibd");
|
call mtr.add_suppression("InnoDB: Expected tablespace id [1-9][0-9]* but found 0 in the file .*/test/(FTS_|#sql-(alter|backup)-).*\\.ibd");
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@ call mtr.add_suppression("InnoDB: Unknown index id .* on page");
|
|||||||
call mtr.add_suppression("InnoDB: Operating system error number");
|
call mtr.add_suppression("InnoDB: Operating system error number");
|
||||||
call mtr.add_suppression("InnoDB: The error means");
|
call mtr.add_suppression("InnoDB: The error means");
|
||||||
call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd");
|
call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd");
|
||||||
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`\\.`t1`");
|
call mtr.add_suppression("InnoDB: Ignoring tablespace for test/t1 ");
|
||||||
FLUSH TABLES;
|
FLUSH TABLES;
|
||||||
SET SESSION innodb_strict_mode=1;
|
SET SESSION innodb_strict_mode=1;
|
||||||
CREATE TABLE t1 (c1 INT) ENGINE = Innodb
|
CREATE TABLE t1 (c1 INT) ENGINE = Innodb
|
||||||
|
@@ -23,7 +23,7 @@ call mtr.add_suppression("InnoDB: Unknown index id .* on page");
|
|||||||
call mtr.add_suppression("InnoDB: Operating system error number");
|
call mtr.add_suppression("InnoDB: Operating system error number");
|
||||||
call mtr.add_suppression("InnoDB: The error means");
|
call mtr.add_suppression("InnoDB: The error means");
|
||||||
call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd");
|
call mtr.add_suppression("InnoDB: Cannot open datafile .*t1\\.ibd");
|
||||||
call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`\\.`t1`");
|
call mtr.add_suppression("InnoDB: Ignoring tablespace for test/t1 ");
|
||||||
FLUSH TABLES;
|
FLUSH TABLES;
|
||||||
|
|
||||||
let MYSQLD_DATADIR =`SELECT @@datadir`;
|
let MYSQLD_DATADIR =`SELECT @@datadir`;
|
||||||
|
@@ -12,7 +12,7 @@ call mtr.add_suppression("InnoDB: Cannot open datafile for read-only: '.*test.t1
|
|||||||
call mtr.add_suppression('InnoDB: Operating system error number');
|
call mtr.add_suppression('InnoDB: Operating system error number');
|
||||||
call mtr.add_suppression('InnoDB: The error means the system cannot find the path specified\.');
|
call mtr.add_suppression('InnoDB: The error means the system cannot find the path specified\.');
|
||||||
call mtr.add_suppression('InnoDB: Table test/t1 in the InnoDB data dictionary has tablespace id .*, but tablespace with that id or name does not exist');
|
call mtr.add_suppression('InnoDB: Table test/t1 in the InnoDB data dictionary has tablespace id .*, but tablespace with that id or name does not exist');
|
||||||
call mtr.add_suppression('InnoDB: Ignoring tablespace for `test`\.`t1` because it could not be opened\.');
|
call mtr.add_suppression('InnoDB: Ignoring tablespace for test/t1 because it could not be opened\.');
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
|
|
||||||
--source include/shutdown_mysqld.inc
|
--source include/shutdown_mysqld.inc
|
||||||
|
@@ -115,8 +115,6 @@ SET(INNOBASE_SOURCES
|
|||||||
include/dict0mem.ic
|
include/dict0mem.ic
|
||||||
include/dict0pagecompress.h
|
include/dict0pagecompress.h
|
||||||
include/dict0pagecompress.ic
|
include/dict0pagecompress.ic
|
||||||
include/dict0priv.h
|
|
||||||
include/dict0priv.ic
|
|
||||||
include/dict0stats.h
|
include/dict0stats.h
|
||||||
include/dict0stats.ic
|
include/dict0stats.ic
|
||||||
include/dict0stats_bg.h
|
include/dict0stats_bg.h
|
||||||
|
@@ -96,45 +96,41 @@ void dict_hdr_flush_row_id(row_id_t id)
|
|||||||
mtr.commit();
|
mtr.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************//**
|
/** Create the DICT_HDR page on database initialization.
|
||||||
Creates the file page for the dictionary header. This function is
|
@return whether the operation failed */
|
||||||
called only at the database creation.
|
static bool dict_hdr_create()
|
||||||
@return TRUE if succeed */
|
|
||||||
static
|
|
||||||
ibool
|
|
||||||
dict_hdr_create(
|
|
||||||
/*============*/
|
|
||||||
mtr_t* mtr) /*!< in: mtr */
|
|
||||||
{
|
{
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
ulint root_page_no;
|
ulint root_page_no;
|
||||||
|
|
||||||
ut_ad(mtr);
|
bool fail = false;
|
||||||
|
mtr_t mtr;
|
||||||
|
mtr.start();
|
||||||
compile_time_assert(DICT_HDR_SPACE == 0);
|
compile_time_assert(DICT_HDR_SPACE == 0);
|
||||||
|
|
||||||
/* Create the dictionary header file block in a new, allocated file
|
/* Create the dictionary header file block in a new, allocated file
|
||||||
segment in the system tablespace */
|
segment in the system tablespace */
|
||||||
block = fseg_create(fil_system.sys_space,
|
block = fseg_create(fil_system.sys_space,
|
||||||
DICT_HDR + DICT_HDR_FSEG_HEADER, mtr);
|
DICT_HDR + DICT_HDR_FSEG_HEADER, &mtr);
|
||||||
|
|
||||||
ut_a(block->page.id() == page_id_t(DICT_HDR_SPACE, DICT_HDR_PAGE_NO));
|
ut_a(block->page.id() == page_id_t(DICT_HDR_SPACE, DICT_HDR_PAGE_NO));
|
||||||
|
|
||||||
buf_block_t* d = dict_hdr_get(mtr);
|
buf_block_t* d = dict_hdr_get(&mtr);
|
||||||
|
|
||||||
/* Start counting row, table, index, and tree ids from
|
/* Start counting row, table, index, and tree ids from
|
||||||
DICT_HDR_FIRST_ID */
|
DICT_HDR_FIRST_ID */
|
||||||
mtr->write<8>(*d, DICT_HDR + DICT_HDR_ROW_ID + d->frame,
|
mtr.write<8>(*d, DICT_HDR + DICT_HDR_ROW_ID + d->frame,
|
||||||
DICT_HDR_FIRST_ID);
|
DICT_HDR_FIRST_ID);
|
||||||
mtr->write<8>(*d, DICT_HDR + DICT_HDR_TABLE_ID + d->frame,
|
mtr.write<8>(*d, DICT_HDR + DICT_HDR_TABLE_ID + d->frame,
|
||||||
DICT_HDR_FIRST_ID);
|
DICT_HDR_FIRST_ID);
|
||||||
mtr->write<8>(*d, DICT_HDR + DICT_HDR_INDEX_ID + d->frame,
|
mtr.write<8>(*d, DICT_HDR + DICT_HDR_INDEX_ID + d->frame,
|
||||||
DICT_HDR_FIRST_ID);
|
DICT_HDR_FIRST_ID);
|
||||||
|
|
||||||
ut_ad(!mach_read_from_4(DICT_HDR + DICT_HDR_MAX_SPACE_ID + d->frame));
|
ut_ad(!mach_read_from_4(DICT_HDR + DICT_HDR_MAX_SPACE_ID + d->frame));
|
||||||
|
|
||||||
/* Obsolete, but we must initialize it anyway. */
|
/* Obsolete, but we must initialize it anyway. */
|
||||||
mtr->write<4>(*d, DICT_HDR + DICT_HDR_MIX_ID_LOW + d->frame,
|
mtr.write<4>(*d, DICT_HDR + DICT_HDR_MIX_ID_LOW + d->frame,
|
||||||
DICT_HDR_FIRST_ID);
|
DICT_HDR_FIRST_ID);
|
||||||
|
|
||||||
/* Create the B-tree roots for the clustered indexes of the basic
|
/* Create the B-tree roots for the clustered indexes of the basic
|
||||||
system tables */
|
system tables */
|
||||||
@@ -142,59 +138,55 @@ dict_hdr_create(
|
|||||||
/*--------------------------*/
|
/*--------------------------*/
|
||||||
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
||||||
fil_system.sys_space, DICT_TABLES_ID,
|
fil_system.sys_space, DICT_TABLES_ID,
|
||||||
nullptr, mtr);
|
nullptr, &mtr);
|
||||||
if (root_page_no == FIL_NULL) {
|
if (root_page_no == FIL_NULL) {
|
||||||
|
failed:
|
||||||
return(FALSE);
|
fail = true;
|
||||||
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr->write<4>(*d, DICT_HDR + DICT_HDR_TABLES + d->frame, root_page_no);
|
mtr.write<4>(*d, DICT_HDR + DICT_HDR_TABLES + d->frame, root_page_no);
|
||||||
/*--------------------------*/
|
/*--------------------------*/
|
||||||
root_page_no = btr_create(DICT_UNIQUE,
|
root_page_no = btr_create(DICT_UNIQUE,
|
||||||
fil_system.sys_space, DICT_TABLE_IDS_ID,
|
fil_system.sys_space, DICT_TABLE_IDS_ID,
|
||||||
nullptr, mtr);
|
nullptr, &mtr);
|
||||||
if (root_page_no == FIL_NULL) {
|
if (root_page_no == FIL_NULL) {
|
||||||
|
goto failed;
|
||||||
return(FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr->write<4>(*d, DICT_HDR + DICT_HDR_TABLE_IDS + d->frame,
|
mtr.write<4>(*d, DICT_HDR + DICT_HDR_TABLE_IDS + d->frame,
|
||||||
root_page_no);
|
root_page_no);
|
||||||
/*--------------------------*/
|
/*--------------------------*/
|
||||||
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
||||||
fil_system.sys_space, DICT_COLUMNS_ID,
|
fil_system.sys_space, DICT_COLUMNS_ID,
|
||||||
nullptr, mtr);
|
nullptr, &mtr);
|
||||||
if (root_page_no == FIL_NULL) {
|
if (root_page_no == FIL_NULL) {
|
||||||
|
goto failed;
|
||||||
return(FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr->write<4>(*d, DICT_HDR + DICT_HDR_COLUMNS + d->frame,
|
mtr.write<4>(*d, DICT_HDR + DICT_HDR_COLUMNS + d->frame,
|
||||||
root_page_no);
|
root_page_no);
|
||||||
/*--------------------------*/
|
/*--------------------------*/
|
||||||
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
||||||
fil_system.sys_space, DICT_INDEXES_ID,
|
fil_system.sys_space, DICT_INDEXES_ID,
|
||||||
nullptr, mtr);
|
nullptr, &mtr);
|
||||||
if (root_page_no == FIL_NULL) {
|
if (root_page_no == FIL_NULL) {
|
||||||
|
goto failed;
|
||||||
return(FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr->write<4>(*d, DICT_HDR + DICT_HDR_INDEXES + d->frame,
|
mtr.write<4>(*d, DICT_HDR + DICT_HDR_INDEXES + d->frame, root_page_no);
|
||||||
root_page_no);
|
|
||||||
/*--------------------------*/
|
/*--------------------------*/
|
||||||
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
root_page_no = btr_create(DICT_CLUSTERED | DICT_UNIQUE,
|
||||||
fil_system.sys_space, DICT_FIELDS_ID,
|
fil_system.sys_space, DICT_FIELDS_ID,
|
||||||
nullptr, mtr);
|
nullptr, &mtr);
|
||||||
if (root_page_no == FIL_NULL) {
|
if (root_page_no == FIL_NULL) {
|
||||||
|
goto failed;
|
||||||
return(FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr->write<4>(*d, DICT_HDR + DICT_HDR_FIELDS + d->frame, root_page_no);
|
mtr.write<4>(*d, DICT_HDR + DICT_HDR_FIELDS + d->frame, root_page_no);
|
||||||
/*--------------------------*/
|
func_exit:
|
||||||
|
mtr.commit();
|
||||||
return(TRUE);
|
return fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
@@ -210,23 +202,21 @@ dict_boot(void)
|
|||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
/* Be sure these constants do not ever change. To avoid bloat,
|
static_assert(DICT_NUM_COLS__SYS_TABLES == 8, "compatibility");
|
||||||
only check the *NUM_FIELDS* in each table */
|
static_assert(DICT_NUM_FIELDS__SYS_TABLES == 10, "compatibility");
|
||||||
|
static_assert(DICT_NUM_FIELDS__SYS_TABLE_IDS == 2, "compatibility");
|
||||||
ut_ad(DICT_NUM_COLS__SYS_TABLES == 8);
|
static_assert(DICT_NUM_COLS__SYS_COLUMNS == 7, "compatibility");
|
||||||
ut_ad(DICT_NUM_FIELDS__SYS_TABLES == 10);
|
static_assert(DICT_NUM_FIELDS__SYS_COLUMNS == 9, "compatibility");
|
||||||
ut_ad(DICT_NUM_FIELDS__SYS_TABLE_IDS == 2);
|
static_assert(DICT_NUM_COLS__SYS_INDEXES == 8, "compatibility");
|
||||||
ut_ad(DICT_NUM_COLS__SYS_COLUMNS == 7);
|
static_assert(DICT_NUM_FIELDS__SYS_INDEXES == 10, "compatibility");
|
||||||
ut_ad(DICT_NUM_FIELDS__SYS_COLUMNS == 9);
|
static_assert(DICT_NUM_COLS__SYS_FIELDS == 3, "compatibility");
|
||||||
ut_ad(DICT_NUM_COLS__SYS_INDEXES == 8);
|
static_assert(DICT_NUM_FIELDS__SYS_FIELDS == 5, "compatibility");
|
||||||
ut_ad(DICT_NUM_FIELDS__SYS_INDEXES == 10);
|
static_assert(DICT_NUM_COLS__SYS_FOREIGN == 4, "compatibility");
|
||||||
ut_ad(DICT_NUM_COLS__SYS_FIELDS == 3);
|
static_assert(DICT_NUM_FIELDS__SYS_FOREIGN == 6, "compatibility");
|
||||||
ut_ad(DICT_NUM_FIELDS__SYS_FIELDS == 5);
|
static_assert(DICT_NUM_FIELDS__SYS_FOREIGN_FOR_NAME == 2,
|
||||||
ut_ad(DICT_NUM_COLS__SYS_FOREIGN == 4);
|
"compatibility");
|
||||||
ut_ad(DICT_NUM_FIELDS__SYS_FOREIGN == 6);
|
static_assert(DICT_NUM_COLS__SYS_FOREIGN_COLS == 4, "compatibility");
|
||||||
ut_ad(DICT_NUM_FIELDS__SYS_FOREIGN_FOR_NAME == 2);
|
static_assert(DICT_NUM_FIELDS__SYS_FOREIGN_COLS == 6, "compatibility");
|
||||||
ut_ad(DICT_NUM_COLS__SYS_FOREIGN_COLS == 4);
|
|
||||||
ut_ad(DICT_NUM_FIELDS__SYS_FOREIGN_COLS == 6);
|
|
||||||
|
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
@@ -260,9 +250,9 @@ dict_boot(void)
|
|||||||
/* Insert into the dictionary cache the descriptions of the basic
|
/* Insert into the dictionary cache the descriptions of the basic
|
||||||
system tables */
|
system tables */
|
||||||
/*-------------------------*/
|
/*-------------------------*/
|
||||||
table = dict_mem_table_create("SYS_TABLES", fil_system.sys_space,
|
table = dict_table_t::create(dict_sys.SYS_TABLE[dict_sys.SYS_TABLES],
|
||||||
8, 0, 0, 0);
|
fil_system.sys_space,
|
||||||
|
DICT_NUM_COLS__SYS_TABLES, 0, 0, 0);
|
||||||
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0,
|
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0,
|
||||||
MAX_FULL_NAME_LEN);
|
MAX_FULL_NAME_LEN);
|
||||||
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 8);
|
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 8);
|
||||||
@@ -308,9 +298,9 @@ dict_boot(void)
|
|||||||
ut_a(error == DB_SUCCESS);
|
ut_a(error == DB_SUCCESS);
|
||||||
|
|
||||||
/*-------------------------*/
|
/*-------------------------*/
|
||||||
table = dict_mem_table_create("SYS_COLUMNS", fil_system.sys_space,
|
table = dict_table_t::create(dict_sys.SYS_TABLE[dict_sys.SYS_COLUMNS],
|
||||||
7, 0, 0, 0);
|
fil_system.sys_space,
|
||||||
|
DICT_NUM_COLS__SYS_COLUMNS, 0, 0, 0);
|
||||||
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 8);
|
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 8);
|
||||||
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
|
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
|
||||||
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
|
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
|
||||||
@@ -341,8 +331,9 @@ dict_boot(void)
|
|||||||
UT_BITS_IN_BYTES(unsigned(table->indexes.start->n_nullable)));
|
UT_BITS_IN_BYTES(unsigned(table->indexes.start->n_nullable)));
|
||||||
|
|
||||||
/*-------------------------*/
|
/*-------------------------*/
|
||||||
table = dict_mem_table_create("SYS_INDEXES", fil_system.sys_space,
|
table = dict_table_t::create(dict_sys.SYS_TABLE[dict_sys.SYS_INDEXES],
|
||||||
DICT_NUM_COLS__SYS_INDEXES, 0, 0, 0);
|
fil_system.sys_space,
|
||||||
|
DICT_NUM_COLS__SYS_INDEXES, 0, 0, 0);
|
||||||
|
|
||||||
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 8);
|
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 8);
|
||||||
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 8);
|
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 8);
|
||||||
@@ -383,9 +374,9 @@ dict_boot(void)
|
|||||||
UT_BITS_IN_BYTES(unsigned(table->indexes.start->n_nullable)));
|
UT_BITS_IN_BYTES(unsigned(table->indexes.start->n_nullable)));
|
||||||
|
|
||||||
/*-------------------------*/
|
/*-------------------------*/
|
||||||
table = dict_mem_table_create("SYS_FIELDS", fil_system.sys_space,
|
table = dict_table_t::create(dict_sys.SYS_TABLE[dict_sys.SYS_FIELDS],
|
||||||
3, 0, 0, 0);
|
fil_system.sys_space,
|
||||||
|
DICT_NUM_COLS__SYS_FIELDS, 0, 0, 0);
|
||||||
dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 8);
|
dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 8);
|
||||||
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
|
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
|
||||||
dict_mem_table_add_col(table, heap, "COL_NAME", DATA_BINARY, 0, 0);
|
dict_mem_table_add_col(table, heap, "COL_NAME", DATA_BINARY, 0, 0);
|
||||||
@@ -413,10 +404,6 @@ dict_boot(void)
|
|||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
|
|
||||||
/*-------------------------*/
|
|
||||||
|
|
||||||
/* Initialize the insert buffer table and index for each tablespace */
|
|
||||||
|
|
||||||
dberr_t err = ibuf_init_at_db_start();
|
dberr_t err = ibuf_init_at_db_start();
|
||||||
|
|
||||||
if (err == DB_SUCCESS) {
|
if (err == DB_SUCCESS) {
|
||||||
@@ -426,44 +413,19 @@ dict_boot(void)
|
|||||||
dict_load_sys_table(dict_sys.sys_columns);
|
dict_load_sys_table(dict_sys.sys_columns);
|
||||||
dict_load_sys_table(dict_sys.sys_indexes);
|
dict_load_sys_table(dict_sys.sys_indexes);
|
||||||
dict_load_sys_table(dict_sys.sys_fields);
|
dict_load_sys_table(dict_sys.sys_fields);
|
||||||
|
dict_sys.mutex_unlock();
|
||||||
|
dict_sys.load_sys_tables();
|
||||||
|
} else {
|
||||||
|
dict_sys.mutex_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
dict_sys.mutex_unlock();
|
|
||||||
|
|
||||||
return(err);
|
return(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************//**
|
|
||||||
Inserts the basic system table data into themselves in the database
|
|
||||||
creation. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
dict_insert_initial_data(void)
|
|
||||||
/*==========================*/
|
|
||||||
{
|
|
||||||
/* Does nothing yet */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
Creates and initializes the data dictionary at the server bootstrap.
|
Creates and initializes the data dictionary at the server bootstrap.
|
||||||
@return DB_SUCCESS or error code. */
|
@return DB_SUCCESS or error code. */
|
||||||
dberr_t
|
dberr_t dict_create()
|
||||||
dict_create(void)
|
|
||||||
/*=============*/
|
|
||||||
{
|
{
|
||||||
mtr_t mtr;
|
return dict_hdr_create() ? DB_ERROR : dict_boot();
|
||||||
|
|
||||||
mtr_start(&mtr);
|
|
||||||
|
|
||||||
dict_hdr_create(&mtr);
|
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
|
||||||
|
|
||||||
dberr_t err = dict_boot();
|
|
||||||
|
|
||||||
if (err == DB_SUCCESS) {
|
|
||||||
dict_insert_initial_data();
|
|
||||||
}
|
|
||||||
|
|
||||||
return(err);
|
|
||||||
}
|
}
|
||||||
|
@@ -41,9 +41,9 @@ Created 1/8/1996 Heikki Tuuri
|
|||||||
#include "trx0rseg.h"
|
#include "trx0rseg.h"
|
||||||
#include "trx0undo.h"
|
#include "trx0undo.h"
|
||||||
#include "ut0vec.h"
|
#include "ut0vec.h"
|
||||||
#include "dict0priv.h"
|
|
||||||
#include "fts0priv.h"
|
#include "fts0priv.h"
|
||||||
#include "srv0start.h"
|
#include "srv0start.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
Based on a table object, this function builds the entry to be inserted
|
Based on a table object, this function builds the entry to be inserted
|
||||||
@@ -897,6 +897,17 @@ rec_corrupted:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return whether SYS_TABLES.NAME is for a '#sql-ib' table */
|
||||||
|
bool dict_table_t::is_garbage_name(const void *data, size_t size)
|
||||||
|
{
|
||||||
|
constexpr size_t suffix= sizeof TEMP_FILE_PREFIX_INNODB;
|
||||||
|
if (size <= suffix)
|
||||||
|
return false;
|
||||||
|
const char *f= static_cast<const char*>(memchr(data, '/', size - suffix));
|
||||||
|
return f && !memcmp(f + 1, TEMP_FILE_PREFIX_INNODB,
|
||||||
|
(sizeof TEMP_FILE_PREFIX_INNODB) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Creates a table create graph.
|
Creates a table create graph.
|
||||||
@return own: table create node */
|
@return own: table create node */
|
||||||
@@ -1315,259 +1326,196 @@ function_exit:
|
|||||||
return(thr);
|
return(thr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
bool dict_sys_t::load_sys_tables()
|
||||||
Check whether a system table exists. Additionally, if it exists,
|
|
||||||
move it to the non-LRU end of the table LRU list. This is only used
|
|
||||||
for system tables that can be upgraded or added to an older database,
|
|
||||||
which include SYS_FOREIGN and SYS_FOREIGN_COLS.
|
|
||||||
@return DB_SUCCESS if the sys table exists, DB_CORRUPTION if it exists
|
|
||||||
but is not current, DB_TABLE_NOT_FOUND if it does not exist*/
|
|
||||||
static
|
|
||||||
dberr_t
|
|
||||||
dict_check_if_system_table_exists(
|
|
||||||
/*==============================*/
|
|
||||||
const char* tablename, /*!< in: name of table */
|
|
||||||
ulint num_fields, /*!< in: number of fields */
|
|
||||||
ulint num_indexes) /*!< in: number of indexes */
|
|
||||||
{
|
{
|
||||||
dict_table_t* sys_table;
|
ut_ad(!srv_any_background_activity());
|
||||||
dberr_t error = DB_SUCCESS;
|
bool mismatch= false;
|
||||||
|
mutex_lock();
|
||||||
ut_ad(!srv_any_background_activity());
|
if (!(sys_foreign= load_table(SYS_TABLE[SYS_FOREIGN],
|
||||||
|
DICT_ERR_IGNORE_FK_NOKEY)));
|
||||||
dict_sys.mutex_lock();
|
else if (UT_LIST_GET_LEN(sys_foreign->indexes) == 3 &&
|
||||||
|
sys_foreign->n_cols == DICT_NUM_COLS__SYS_FOREIGN + DATA_N_SYS_COLS)
|
||||||
sys_table = dict_table_get_low(tablename);
|
prevent_eviction(sys_foreign);
|
||||||
|
else
|
||||||
if (sys_table == NULL) {
|
{
|
||||||
error = DB_TABLE_NOT_FOUND;
|
sys_foreign= nullptr;
|
||||||
|
mismatch= true;
|
||||||
} else if (UT_LIST_GET_LEN(sys_table->indexes) != num_indexes
|
ib::error() << "Invalid definition of SYS_FOREIGN";
|
||||||
|| sys_table->n_cols != num_fields) {
|
}
|
||||||
error = DB_CORRUPTION;
|
if (!(sys_foreign_cols= load_table(SYS_TABLE[SYS_FOREIGN_COLS],
|
||||||
|
DICT_ERR_IGNORE_FK_NOKEY)));
|
||||||
} else {
|
else if (UT_LIST_GET_LEN(sys_foreign_cols->indexes) == 1 &&
|
||||||
/* This table has already been created, and it is OK.
|
sys_foreign_cols->n_cols ==
|
||||||
Ensure that it can't be evicted from the table LRU cache. */
|
DICT_NUM_COLS__SYS_FOREIGN_COLS + DATA_N_SYS_COLS)
|
||||||
|
prevent_eviction(sys_foreign_cols);
|
||||||
dict_table_prevent_eviction(sys_table);
|
else
|
||||||
}
|
{
|
||||||
|
sys_foreign_cols= nullptr;
|
||||||
dict_sys.mutex_unlock();
|
mismatch= true;
|
||||||
|
ib::error() << "Invalid definition of SYS_FOREIGN_COLS";
|
||||||
return(error);
|
}
|
||||||
|
if (!(sys_virtual= load_table(SYS_TABLE[SYS_VIRTUAL],
|
||||||
|
DICT_ERR_IGNORE_FK_NOKEY)));
|
||||||
|
else if (UT_LIST_GET_LEN(sys_virtual->indexes) == 1 &&
|
||||||
|
sys_virtual->n_cols == DICT_NUM_COLS__SYS_VIRTUAL + DATA_N_SYS_COLS)
|
||||||
|
prevent_eviction(sys_virtual);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sys_virtual= nullptr;
|
||||||
|
mismatch= true;
|
||||||
|
ib::error() << "Invalid definition of SYS_VIRTUAL";
|
||||||
|
}
|
||||||
|
mutex_unlock();
|
||||||
|
return mismatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
dberr_t dict_sys_t::create_or_check_sys_tables()
|
||||||
Creates the foreign key constraints system tables inside InnoDB
|
|
||||||
at server bootstrap or server start if they are not found or are
|
|
||||||
not of the right form.
|
|
||||||
@return DB_SUCCESS or error code */
|
|
||||||
dberr_t
|
|
||||||
dict_create_or_check_foreign_constraint_tables(void)
|
|
||||||
/*================================================*/
|
|
||||||
{
|
{
|
||||||
trx_t* trx;
|
if (sys_tables_exist())
|
||||||
my_bool srv_file_per_table_backup;
|
return DB_SUCCESS;
|
||||||
dberr_t err;
|
|
||||||
dberr_t sys_foreign_err;
|
|
||||||
dberr_t sys_foreign_cols_err;
|
|
||||||
|
|
||||||
ut_ad(!srv_any_background_activity());
|
if (srv_read_only_mode || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO)
|
||||||
|
return DB_READ_ONLY;
|
||||||
|
|
||||||
sys_foreign_err = dict_check_if_system_table_exists(
|
if (load_sys_tables())
|
||||||
"SYS_FOREIGN", DICT_NUM_FIELDS__SYS_FOREIGN + 1, 3);
|
{
|
||||||
sys_foreign_cols_err = dict_check_if_system_table_exists(
|
ib::info() << "Set innodb_read_only=1 or innodb_force_recovery=3"
|
||||||
"SYS_FOREIGN_COLS", DICT_NUM_FIELDS__SYS_FOREIGN_COLS + 1, 1);
|
" to start up";
|
||||||
|
return DB_CORRUPTION;
|
||||||
|
}
|
||||||
|
|
||||||
if (sys_foreign_err == DB_SUCCESS
|
if (sys_tables_exist())
|
||||||
&& sys_foreign_cols_err == DB_SUCCESS) {
|
return DB_SUCCESS;
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (srv_read_only_mode
|
trx_t *trx= trx_create();
|
||||||
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO) {
|
trx->dict_operation = true;
|
||||||
return(DB_READ_ONLY);
|
row_mysql_lock_data_dictionary(trx);
|
||||||
}
|
|
||||||
|
|
||||||
trx = trx_create();
|
DBUG_EXECUTE_IF("create_and_drop_garbage",
|
||||||
|
ut_ad(DB_SUCCESS == que_eval_sql(
|
||||||
|
nullptr,
|
||||||
|
"PROCEDURE CREATE_GARBAGE_TABLE_PROC () IS\n"
|
||||||
|
"BEGIN\n"
|
||||||
|
"CREATE TABLE\n"
|
||||||
|
"\"test/" TEMP_FILE_PREFIX_INNODB "-garbage\""
|
||||||
|
"(ID CHAR);\n"
|
||||||
|
"CREATE UNIQUE CLUSTERED INDEX PRIMARY ON "
|
||||||
|
"\"test/" TEMP_FILE_PREFIX_INNODB
|
||||||
|
"-garbage\"(ID);\n"
|
||||||
|
"END;\n", false, trx));
|
||||||
|
row_drop_table_for_mysql("test/"
|
||||||
|
TEMP_FILE_PREFIX_INNODB "-garbage",
|
||||||
|
trx, SQLCOM_DROP_DB, true););
|
||||||
|
|
||||||
trx->dict_operation = true;
|
/* NOTE: when designing InnoDB's foreign key support in 2001, Heikki Tuuri
|
||||||
|
made a mistake defined table names and the foreign key id to be of type
|
||||||
|
'CHAR' (internally, really a VARCHAR).
|
||||||
|
The type should have been VARBINARY. */
|
||||||
|
|
||||||
trx->op_info = "creating foreign key sys tables";
|
const auto srv_file_per_table_backup= srv_file_per_table;
|
||||||
|
|
||||||
row_mysql_lock_data_dictionary(trx);
|
/* We always want SYSTEM tables to be created inside the system
|
||||||
|
tablespace. */
|
||||||
|
srv_file_per_table= 0;
|
||||||
|
dberr_t error;
|
||||||
|
const char *tablename;
|
||||||
|
|
||||||
DBUG_EXECUTE_IF(
|
if (!sys_foreign)
|
||||||
"create_and_drop_garbage",
|
{
|
||||||
err = que_eval_sql(
|
error= que_eval_sql(nullptr, "PROCEDURE CREATE_FOREIGN() IS\n"
|
||||||
NULL,
|
"BEGIN\n"
|
||||||
"PROCEDURE CREATE_GARBAGE_TABLE_PROC () IS\n"
|
"CREATE TABLE\n"
|
||||||
"BEGIN\n"
|
"SYS_FOREIGN(ID CHAR, FOR_NAME CHAR,"
|
||||||
"CREATE TABLE\n"
|
" REF_NAME CHAR, N_COLS INT);\n"
|
||||||
"\"test/" TEMP_FILE_PREFIX_INNODB "-garbage\""
|
"CREATE UNIQUE CLUSTERED INDEX ID_IND"
|
||||||
"(ID CHAR);\n"
|
" ON SYS_FOREIGN (ID);\n"
|
||||||
"CREATE UNIQUE CLUSTERED INDEX PRIMARY ON "
|
"CREATE INDEX FOR_IND"
|
||||||
"\"test/" TEMP_FILE_PREFIX_INNODB "-garbage\"(ID);\n"
|
" ON SYS_FOREIGN (FOR_NAME);\n"
|
||||||
"END;\n", FALSE, trx);
|
"CREATE INDEX REF_IND"
|
||||||
ut_ad(err == DB_SUCCESS);
|
" ON SYS_FOREIGN (REF_NAME);\n"
|
||||||
row_drop_table_for_mysql("test/"
|
"END;\n", false, trx);
|
||||||
TEMP_FILE_PREFIX_INNODB "-garbage",
|
if (UNIV_UNLIKELY(error != DB_SUCCESS))
|
||||||
trx, SQLCOM_DROP_DB, true););
|
{
|
||||||
|
tablename= SYS_TABLE[SYS_FOREIGN].data();
|
||||||
|
err_exit:
|
||||||
|
ib::error() << "Creation of " << tablename << " failed: " << error;
|
||||||
|
trx->rollback();
|
||||||
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
|
trx->free();
|
||||||
|
srv_file_per_table= srv_file_per_table_backup;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!sys_foreign_cols)
|
||||||
|
{
|
||||||
|
error= que_eval_sql(nullptr, "PROCEDURE CREATE_FOREIGN_COLS() IS\n"
|
||||||
|
"BEGIN\n"
|
||||||
|
"CREATE TABLE\n"
|
||||||
|
"SYS_FOREIGN_COLS(ID CHAR, POS INT,"
|
||||||
|
" FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n"
|
||||||
|
"CREATE UNIQUE CLUSTERED INDEX ID_IND"
|
||||||
|
" ON SYS_FOREIGN_COLS (ID, POS);\n"
|
||||||
|
"END;\n", false, trx);
|
||||||
|
if (UNIV_UNLIKELY(error != DB_SUCCESS))
|
||||||
|
{
|
||||||
|
tablename= SYS_TABLE[SYS_FOREIGN_COLS].data();
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!sys_virtual)
|
||||||
|
{
|
||||||
|
error= que_eval_sql(nullptr, "PROCEDURE CREATE_VIRTUAL() IS\n"
|
||||||
|
"BEGIN\n"
|
||||||
|
"CREATE TABLE\n"
|
||||||
|
"SYS_VIRTUAL(TABLE_ID BIGINT,POS INT,BASE_POS INT);\n"
|
||||||
|
"CREATE UNIQUE CLUSTERED INDEX BASE_IDX"
|
||||||
|
" ON SYS_VIRTUAL(TABLE_ID, POS, BASE_POS);\n"
|
||||||
|
"END;\n", false, trx);
|
||||||
|
if (UNIV_UNLIKELY(error != DB_SUCCESS))
|
||||||
|
{
|
||||||
|
tablename= SYS_TABLE[SYS_VIRTUAL].data();
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ib::info() << "Creating foreign key constraint system tables.";
|
trx->commit();
|
||||||
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
|
trx->free();
|
||||||
|
srv_file_per_table= srv_file_per_table_backup;
|
||||||
|
|
||||||
/* NOTE: in dict_load_foreigns we use the fact that
|
mutex_lock();
|
||||||
there are 2 secondary indexes on SYS_FOREIGN, and they
|
if (sys_foreign);
|
||||||
are defined just like below */
|
else if (!(sys_foreign= load_table(SYS_TABLE[SYS_FOREIGN])))
|
||||||
|
{
|
||||||
|
tablename= SYS_TABLE[SYS_FOREIGN].data();
|
||||||
|
load_fail:
|
||||||
|
mutex_unlock();
|
||||||
|
ib::error() << "Failed to CREATE TABLE " << tablename;
|
||||||
|
return DB_TABLE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
prevent_eviction(sys_foreign);
|
||||||
|
|
||||||
/* NOTE: when designing InnoDB's foreign key support in 2001, we made
|
if (sys_foreign_cols);
|
||||||
an error and made the table names and the foreign key id of type
|
else if (!(sys_foreign_cols= load_table(SYS_TABLE[SYS_FOREIGN_COLS])))
|
||||||
'CHAR' (internally, really a VARCHAR). We should have made the type
|
{
|
||||||
VARBINARY, like in other InnoDB system tables, to get a clean
|
tablename= SYS_TABLE[SYS_FOREIGN_COLS].data();
|
||||||
design. */
|
goto load_fail;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
prevent_eviction(sys_foreign_cols);
|
||||||
|
|
||||||
srv_file_per_table_backup = srv_file_per_table;
|
if (sys_virtual);
|
||||||
|
else if (!(sys_virtual= load_table(SYS_TABLE[SYS_VIRTUAL])))
|
||||||
|
{
|
||||||
|
tablename= SYS_TABLE[SYS_VIRTUAL].data();
|
||||||
|
goto load_fail;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
prevent_eviction(sys_virtual);
|
||||||
|
|
||||||
/* We always want SYSTEM tables to be created inside the system
|
mutex_unlock();
|
||||||
tablespace. */
|
return DB_SUCCESS;
|
||||||
|
|
||||||
srv_file_per_table = 0;
|
|
||||||
|
|
||||||
err = que_eval_sql(
|
|
||||||
NULL,
|
|
||||||
"PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
|
|
||||||
"BEGIN\n"
|
|
||||||
"CREATE TABLE\n"
|
|
||||||
"SYS_FOREIGN(ID CHAR, FOR_NAME CHAR,"
|
|
||||||
" REF_NAME CHAR, N_COLS INT);\n"
|
|
||||||
"CREATE UNIQUE CLUSTERED INDEX ID_IND"
|
|
||||||
" ON SYS_FOREIGN (ID);\n"
|
|
||||||
"CREATE INDEX FOR_IND"
|
|
||||||
" ON SYS_FOREIGN (FOR_NAME);\n"
|
|
||||||
"CREATE INDEX REF_IND"
|
|
||||||
" ON SYS_FOREIGN (REF_NAME);\n"
|
|
||||||
"CREATE TABLE\n"
|
|
||||||
"SYS_FOREIGN_COLS(ID CHAR, POS INT,"
|
|
||||||
" FOR_COL_NAME CHAR, REF_COL_NAME CHAR);\n"
|
|
||||||
"CREATE UNIQUE CLUSTERED INDEX ID_IND"
|
|
||||||
" ON SYS_FOREIGN_COLS (ID, POS);\n"
|
|
||||||
"END;\n",
|
|
||||||
FALSE, trx);
|
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
|
|
||||||
ib::error() << "Creation of SYS_FOREIGN and SYS_FOREIGN_COLS"
|
|
||||||
" failed: " << err;
|
|
||||||
|
|
||||||
ut_ad(err == DB_OUT_OF_FILE_SPACE
|
|
||||||
|| err == DB_TOO_MANY_CONCURRENT_TRXS);
|
|
||||||
trx->rollback();
|
|
||||||
} else {
|
|
||||||
trx_commit_for_mysql(trx);
|
|
||||||
}
|
|
||||||
|
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
|
||||||
|
|
||||||
trx->free();
|
|
||||||
|
|
||||||
srv_file_per_table = srv_file_per_table_backup;
|
|
||||||
|
|
||||||
/* Note: The master thread has not been started at this point. */
|
|
||||||
/* Confirm and move to the non-LRU part of the table LRU list. */
|
|
||||||
sys_foreign_err = dict_check_if_system_table_exists(
|
|
||||||
"SYS_FOREIGN", DICT_NUM_FIELDS__SYS_FOREIGN + 1, 3);
|
|
||||||
ut_a(sys_foreign_err == DB_SUCCESS);
|
|
||||||
|
|
||||||
sys_foreign_cols_err = dict_check_if_system_table_exists(
|
|
||||||
"SYS_FOREIGN_COLS", DICT_NUM_FIELDS__SYS_FOREIGN_COLS + 1, 1);
|
|
||||||
ut_a(sys_foreign_cols_err == DB_SUCCESS);
|
|
||||||
|
|
||||||
return(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Creates the virtual column system table (SYS_VIRTUAL) inside InnoDB
|
|
||||||
at server bootstrap or server start if the table is not found or is
|
|
||||||
not of the right form.
|
|
||||||
@return DB_SUCCESS or error code */
|
|
||||||
dberr_t
|
|
||||||
dict_create_or_check_sys_virtual()
|
|
||||||
{
|
|
||||||
trx_t* trx;
|
|
||||||
my_bool srv_file_per_table_backup;
|
|
||||||
dberr_t err;
|
|
||||||
|
|
||||||
ut_ad(!srv_any_background_activity());
|
|
||||||
|
|
||||||
err = dict_check_if_system_table_exists(
|
|
||||||
"SYS_VIRTUAL", DICT_NUM_FIELDS__SYS_VIRTUAL + 1, 1);
|
|
||||||
|
|
||||||
if (err == DB_SUCCESS) {
|
|
||||||
dict_sys.mutex_lock();
|
|
||||||
dict_sys.sys_virtual = dict_table_get_low("SYS_VIRTUAL");
|
|
||||||
dict_sys.mutex_unlock();
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (srv_read_only_mode
|
|
||||||
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO) {
|
|
||||||
return(DB_READ_ONLY);
|
|
||||||
}
|
|
||||||
|
|
||||||
trx = trx_create();
|
|
||||||
|
|
||||||
trx->dict_operation = true;
|
|
||||||
|
|
||||||
trx->op_info = "creating sys_virtual tables";
|
|
||||||
|
|
||||||
row_mysql_lock_data_dictionary(trx);
|
|
||||||
|
|
||||||
ib::info() << "Creating sys_virtual system tables.";
|
|
||||||
|
|
||||||
srv_file_per_table_backup = srv_file_per_table;
|
|
||||||
|
|
||||||
/* We always want SYSTEM tables to be created inside the system
|
|
||||||
tablespace. */
|
|
||||||
|
|
||||||
srv_file_per_table = 0;
|
|
||||||
|
|
||||||
err = que_eval_sql(
|
|
||||||
NULL,
|
|
||||||
"PROCEDURE CREATE_SYS_VIRTUAL_TABLES_PROC () IS\n"
|
|
||||||
"BEGIN\n"
|
|
||||||
"CREATE TABLE\n"
|
|
||||||
"SYS_VIRTUAL(TABLE_ID BIGINT, POS INT,"
|
|
||||||
" BASE_POS INT);\n"
|
|
||||||
"CREATE UNIQUE CLUSTERED INDEX BASE_IDX"
|
|
||||||
" ON SYS_VIRTUAL(TABLE_ID, POS, BASE_POS);\n"
|
|
||||||
"END;\n",
|
|
||||||
FALSE, trx);
|
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
|
|
||||||
ib::error() << "Creation of SYS_VIRTUAL failed: " << err;
|
|
||||||
|
|
||||||
ut_ad(err == DB_OUT_OF_FILE_SPACE
|
|
||||||
|| err == DB_TOO_MANY_CONCURRENT_TRXS);
|
|
||||||
trx->rollback();
|
|
||||||
} else {
|
|
||||||
trx_commit_for_mysql(trx);
|
|
||||||
}
|
|
||||||
|
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
|
||||||
|
|
||||||
trx->free();
|
|
||||||
|
|
||||||
srv_file_per_table = srv_file_per_table_backup;
|
|
||||||
|
|
||||||
/* Note: The master thread has not been started at this point. */
|
|
||||||
/* Confirm and move to the non-LRU part of the table LRU list. */
|
|
||||||
dberr_t sys_virtual_err = dict_check_if_system_table_exists(
|
|
||||||
"SYS_VIRTUAL", DICT_NUM_FIELDS__SYS_VIRTUAL + 1, 1);
|
|
||||||
ut_a(sys_virtual_err == DB_SUCCESS);
|
|
||||||
dict_sys.mutex_lock();
|
|
||||||
dict_sys.sys_virtual = dict_table_get_low("SYS_VIRTUAL");
|
|
||||||
dict_sys.mutex_unlock();
|
|
||||||
|
|
||||||
return(err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
@@ -1959,35 +1907,19 @@ dict_create_add_foreigns_to_dictionary(
|
|||||||
const dict_table_t* table,
|
const dict_table_t* table,
|
||||||
trx_t* trx)
|
trx_t* trx)
|
||||||
{
|
{
|
||||||
dict_foreign_t* foreign;
|
dict_sys.assert_locked();
|
||||||
dberr_t error;
|
|
||||||
|
|
||||||
dict_sys.assert_locked();
|
if (!dict_sys.sys_foreign)
|
||||||
|
{
|
||||||
|
sql_print_error("InnoDB: Table SYS_FOREIGN not found"
|
||||||
|
" in internal data dictionary");
|
||||||
|
return DB_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL == dict_table_get_low("SYS_FOREIGN")) {
|
for (auto fk : local_fk_set)
|
||||||
|
if (dberr_t error=
|
||||||
|
dict_create_add_foreign_to_dictionary(table->name.m_name, fk, trx))
|
||||||
|
return error;
|
||||||
|
|
||||||
ib::error() << "Table SYS_FOREIGN not found"
|
return DB_SUCCESS;
|
||||||
" in internal data dictionary";
|
|
||||||
|
|
||||||
return(DB_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
error = DB_SUCCESS;
|
|
||||||
|
|
||||||
for (dict_foreign_set::const_iterator it = local_fk_set.begin();
|
|
||||||
it != local_fk_set.end();
|
|
||||||
++it) {
|
|
||||||
|
|
||||||
foreign = *it;
|
|
||||||
ut_ad(foreign->id != NULL);
|
|
||||||
|
|
||||||
error = dict_create_add_foreign_to_dictionary(
|
|
||||||
table->name.m_name, foreign, trx);
|
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
@@ -51,9 +51,9 @@ extern uint ibuf_debug;
|
|||||||
#include "buf0buf.h"
|
#include "buf0buf.h"
|
||||||
#include "data0type.h"
|
#include "data0type.h"
|
||||||
#include "dict0boot.h"
|
#include "dict0boot.h"
|
||||||
|
#include "dict0load.h"
|
||||||
#include "dict0crea.h"
|
#include "dict0crea.h"
|
||||||
#include "dict0mem.h"
|
#include "dict0mem.h"
|
||||||
#include "dict0priv.h"
|
|
||||||
#include "dict0stats.h"
|
#include "dict0stats.h"
|
||||||
#include "fts0fts.h"
|
#include "fts0fts.h"
|
||||||
#include "fts0types.h"
|
#include "fts0types.h"
|
||||||
@@ -80,6 +80,15 @@ extern uint ibuf_debug;
|
|||||||
/** the dictionary system */
|
/** the dictionary system */
|
||||||
dict_sys_t dict_sys;
|
dict_sys_t dict_sys;
|
||||||
|
|
||||||
|
/** System table names; @see dict_system_id_t */
|
||||||
|
const span<const char> dict_sys_t::SYS_TABLE[]=
|
||||||
|
{
|
||||||
|
{C_STRING_WITH_LEN("SYS_TABLES")},{C_STRING_WITH_LEN("SYS_INDEXES")},
|
||||||
|
{C_STRING_WITH_LEN("SYS_COLUMNS")},{C_STRING_WITH_LEN("SYS_FIELDS")},
|
||||||
|
{C_STRING_WITH_LEN("SYS_FOREIGN")},{C_STRING_WITH_LEN("SYS_FOREIGN_COLS")},
|
||||||
|
{C_STRING_WITH_LEN("SYS_VIRTUAL")}
|
||||||
|
};
|
||||||
|
|
||||||
/** Diagnostic message for exceeding the mutex_lock_wait() timeout */
|
/** Diagnostic message for exceeding the mutex_lock_wait() timeout */
|
||||||
const char dict_sys_t::fatal_msg[]=
|
const char dict_sys_t::fatal_msg[]=
|
||||||
"innodb_fatal_semaphore_wait_threshold was exceeded for dict_sys.mutex. "
|
"innodb_fatal_semaphore_wait_threshold was exceeded for dict_sys.mutex. "
|
||||||
@@ -216,7 +225,7 @@ static dict_table_t* dict_table_open_on_id_low(
|
|||||||
dict_err_ignore_t ignore_err,
|
dict_err_ignore_t ignore_err,
|
||||||
bool cached_only)
|
bool cached_only)
|
||||||
{
|
{
|
||||||
dict_table_t* table = dict_sys.get_table(table_id);
|
dict_table_t* table = dict_sys.find_table(table_id);
|
||||||
|
|
||||||
if (!table && !cached_only) {
|
if (!table && !cached_only) {
|
||||||
table = dict_load_table_on_id(table_id, ignore_err);
|
table = dict_load_table_on_id(table_id, ignore_err);
|
||||||
@@ -1097,17 +1106,11 @@ dict_table_open_on_name(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(table_name);
|
ut_ad(table_name);
|
||||||
dict_sys.assert_locked();
|
table = dict_sys.load_table({table_name, strlen(table_name)},
|
||||||
|
ignore_err);
|
||||||
|
|
||||||
table = dict_table_check_if_in_cache_low(table_name);
|
if (table) {
|
||||||
|
ut_ad(table->cached);
|
||||||
if (table == NULL) {
|
|
||||||
table = dict_load_table(table_name, ignore_err);
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(!table || table->cached);
|
|
||||||
|
|
||||||
if (table != NULL) {
|
|
||||||
|
|
||||||
/* If table is encrypted or corrupted */
|
/* If table is encrypted or corrupted */
|
||||||
if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY)
|
if (!(ignore_err & ~DICT_ERR_IGNORE_FK_NOKEY)
|
||||||
@@ -2984,11 +2987,13 @@ dict_foreign_add_to_cache(
|
|||||||
|
|
||||||
dict_sys.assert_locked();
|
dict_sys.assert_locked();
|
||||||
|
|
||||||
for_table = dict_table_check_if_in_cache_low(
|
for_table = dict_sys.find_table(
|
||||||
foreign->foreign_table_name_lookup);
|
{foreign->foreign_table_name_lookup,
|
||||||
|
strlen(foreign->foreign_table_name_lookup)});
|
||||||
|
|
||||||
ref_table = dict_table_check_if_in_cache_low(
|
ref_table = dict_sys.find_table(
|
||||||
foreign->referenced_table_name_lookup);
|
{foreign->referenced_table_name_lookup,
|
||||||
|
strlen(foreign->referenced_table_name_lookup)});
|
||||||
ut_a(for_table || ref_table);
|
ut_a(for_table || ref_table);
|
||||||
|
|
||||||
if (for_table) {
|
if (for_table) {
|
||||||
@@ -3384,8 +3389,8 @@ dict_get_referenced_table(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Copy database_name, '/', table_name, '\0' */
|
/* Copy database_name, '/', table_name, '\0' */
|
||||||
ref = static_cast<char*>(mem_heap_alloc(
|
const size_t len = database_name_len + table_name_len + 1;
|
||||||
heap, database_name_len + table_name_len + 2));
|
ref = static_cast<char*>(mem_heap_alloc(heap, len + 1));
|
||||||
memcpy(ref, database_name, database_name_len);
|
memcpy(ref, database_name, database_name_len);
|
||||||
ref[database_name_len] = '/';
|
ref[database_name_len] = '/';
|
||||||
memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
|
memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
|
||||||
@@ -3395,7 +3400,7 @@ dict_get_referenced_table(
|
|||||||
2 = Store as given, compare in lower; case semi-sensitive */
|
2 = Store as given, compare in lower; case semi-sensitive */
|
||||||
if (lower_case_table_names == 2) {
|
if (lower_case_table_names == 2) {
|
||||||
innobase_casedn_str(ref);
|
innobase_casedn_str(ref);
|
||||||
*table = dict_table_get_low(ref);
|
*table = dict_sys.load_table({ref, len});
|
||||||
memcpy(ref, database_name, database_name_len);
|
memcpy(ref, database_name, database_name_len);
|
||||||
ref[database_name_len] = '/';
|
ref[database_name_len] = '/';
|
||||||
memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
|
memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
|
||||||
@@ -3408,7 +3413,7 @@ dict_get_referenced_table(
|
|||||||
#else
|
#else
|
||||||
innobase_casedn_str(ref);
|
innobase_casedn_str(ref);
|
||||||
#endif /* !_WIN32 */
|
#endif /* !_WIN32 */
|
||||||
*table = dict_table_get_low(ref);
|
*table = dict_sys.load_table({ref, len});
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ref);
|
return(ref);
|
||||||
@@ -5031,9 +5036,3 @@ dict_tf_to_row_format_string(
|
|||||||
ut_error;
|
ut_error;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dict_table_t::is_stats_table() const
|
|
||||||
{
|
|
||||||
return !strcmp(name.m_name, TABLE_STATS_NAME) ||
|
|
||||||
!strcmp(name.m_name, INDEX_STATS_NAME);
|
|
||||||
}
|
|
||||||
|
@@ -27,14 +27,13 @@ Created 4/24/1996 Heikki Tuuri
|
|||||||
|
|
||||||
#include "dict0load.h"
|
#include "dict0load.h"
|
||||||
|
|
||||||
#include "mysql_version.h"
|
#include "log.h"
|
||||||
#include "btr0pcur.h"
|
#include "btr0pcur.h"
|
||||||
#include "btr0btr.h"
|
#include "btr0btr.h"
|
||||||
#include "dict0boot.h"
|
#include "dict0boot.h"
|
||||||
#include "dict0crea.h"
|
#include "dict0crea.h"
|
||||||
#include "dict0dict.h"
|
#include "dict0dict.h"
|
||||||
#include "dict0mem.h"
|
#include "dict0mem.h"
|
||||||
#include "dict0priv.h"
|
|
||||||
#include "dict0stats.h"
|
#include "dict0stats.h"
|
||||||
#include "fsp0file.h"
|
#include "fsp0file.h"
|
||||||
#include "fts0priv.h"
|
#include "fts0priv.h"
|
||||||
@@ -45,18 +44,6 @@ Created 4/24/1996 Heikki Tuuri
|
|||||||
#include "srv0srv.h"
|
#include "srv0srv.h"
|
||||||
#include "fts0opt.h"
|
#include "fts0opt.h"
|
||||||
|
|
||||||
/** Following are the InnoDB system tables. The positions in
|
|
||||||
this array are referenced by enum dict_system_table_id. */
|
|
||||||
static const char* SYSTEM_TABLE_NAME[] = {
|
|
||||||
"SYS_TABLES",
|
|
||||||
"SYS_INDEXES",
|
|
||||||
"SYS_COLUMNS",
|
|
||||||
"SYS_FIELDS",
|
|
||||||
"SYS_FOREIGN",
|
|
||||||
"SYS_FOREIGN_COLS",
|
|
||||||
"SYS_VIRTUAL"
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Loads a table definition and also all its index definitions.
|
/** Loads a table definition and also all its index definitions.
|
||||||
|
|
||||||
Loads those foreign key constraints whose referenced table is already in
|
Loads those foreign key constraints whose referenced table is already in
|
||||||
@@ -71,26 +58,11 @@ key constraints are loaded into memory.
|
|||||||
@param[out] fk_tables Related table names that must also be
|
@param[out] fk_tables Related table names that must also be
|
||||||
loaded to ensure that all foreign key
|
loaded to ensure that all foreign key
|
||||||
constraints are loaded.
|
constraints are loaded.
|
||||||
@return table, NULL if does not exist; if the table is stored in an
|
@return table, possibly with file_unreadable flag set
|
||||||
.ibd file, but the file does not exist, then we set the
|
@retval nullptr if the table does not exist */
|
||||||
file_unreadable flag in the table object we return */
|
static dict_table_t *dict_load_table_one(const span<const char> &name,
|
||||||
static
|
dict_err_ignore_t ignore_err,
|
||||||
dict_table_t*
|
dict_names_t &fk_tables);
|
||||||
dict_load_table_one(
|
|
||||||
const table_name_t& name,
|
|
||||||
dict_err_ignore_t ignore_err,
|
|
||||||
dict_names_t& fk_tables);
|
|
||||||
|
|
||||||
/** Load a table definition from a SYS_TABLES record to dict_table_t.
|
|
||||||
Do not load any columns or indexes.
|
|
||||||
@param[in] name Table name
|
|
||||||
@param[in] rec SYS_TABLES record
|
|
||||||
@param[out,own] table table, or NULL
|
|
||||||
@return error message
|
|
||||||
@retval NULL on success */
|
|
||||||
static const char* dict_load_table_low(const table_name_t& name,
|
|
||||||
const rec_t* rec, dict_table_t** table)
|
|
||||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
|
||||||
|
|
||||||
/** Load an index definition from a SYS_INDEXES record to dict_index_t.
|
/** Load an index definition from a SYS_INDEXES record to dict_index_t.
|
||||||
If allocate=TRUE, we will create a dict_index_t structure and fill it
|
If allocate=TRUE, we will create a dict_index_t structure and fill it
|
||||||
@@ -239,24 +211,11 @@ dict_startscan_system(
|
|||||||
btr_pcur_t* pcur, /*!< out: persistent cursor to
|
btr_pcur_t* pcur, /*!< out: persistent cursor to
|
||||||
the record */
|
the record */
|
||||||
mtr_t* mtr, /*!< in: the mini-transaction */
|
mtr_t* mtr, /*!< in: the mini-transaction */
|
||||||
dict_system_id_t system_id) /*!< in: which system table to open */
|
dict_table_t* table) /*!< in: system table */
|
||||||
{
|
{
|
||||||
dict_table_t* system_table;
|
btr_pcur_open_at_index_side(true, table->indexes.start,
|
||||||
dict_index_t* clust_index;
|
BTR_SEARCH_LEAF, pcur, true, 0, mtr);
|
||||||
const rec_t* rec;
|
return dict_getnext_system_low(pcur, mtr);
|
||||||
|
|
||||||
ut_a(system_id < SYS_NUM_SYSTEM_TABLES);
|
|
||||||
|
|
||||||
system_table = dict_table_get_low(SYSTEM_TABLE_NAME[system_id]);
|
|
||||||
|
|
||||||
clust_index = UT_LIST_GET_FIRST(system_table->indexes);
|
|
||||||
|
|
||||||
btr_pcur_open_at_index_side(true, clust_index, BTR_SEARCH_LEAF, pcur,
|
|
||||||
true, 0, mtr);
|
|
||||||
|
|
||||||
rec = dict_getnext_system_low(pcur, mtr);
|
|
||||||
|
|
||||||
return(rec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
@@ -280,46 +239,6 @@ dict_getnext_system(
|
|||||||
return(rec);
|
return(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
|
||||||
This function processes one SYS_TABLES record and populate the dict_table_t
|
|
||||||
struct for the table.
|
|
||||||
@return error message, or NULL on success */
|
|
||||||
const char*
|
|
||||||
dict_process_sys_tables_rec_and_mtr_commit(
|
|
||||||
/*=======================================*/
|
|
||||||
mem_heap_t* heap, /*!< in/out: temporary memory heap */
|
|
||||||
const rec_t* rec, /*!< in: SYS_TABLES record */
|
|
||||||
dict_table_t** table, /*!< out: dict_table_t to fill */
|
|
||||||
bool cached, /*!< in: whether to load from cache */
|
|
||||||
mtr_t* mtr) /*!< in/out: mini-transaction,
|
|
||||||
will be committed */
|
|
||||||
{
|
|
||||||
ulint len;
|
|
||||||
const char* field;
|
|
||||||
|
|
||||||
field = (const char*) rec_get_nth_field_old(
|
|
||||||
rec, DICT_FLD__SYS_TABLES__NAME, &len);
|
|
||||||
|
|
||||||
ut_a(!rec_get_deleted_flag(rec, 0));
|
|
||||||
|
|
||||||
ut_ad(mtr->memo_contains_page_flagged(rec, MTR_MEMO_PAGE_S_FIX));
|
|
||||||
|
|
||||||
/* Get the table name */
|
|
||||||
table_name_t table_name(mem_heap_strdupl(heap, field, len));
|
|
||||||
|
|
||||||
if (cached) {
|
|
||||||
/* Commit before load the table again */
|
|
||||||
mtr_commit(mtr);
|
|
||||||
|
|
||||||
*table = dict_table_get_low(table_name.m_name);
|
|
||||||
return *table ? NULL : "Table not found in cache";
|
|
||||||
} else {
|
|
||||||
const char* err = dict_load_table_low(table_name, rec, table);
|
|
||||||
mtr_commit(mtr);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
This function parses a SYS_INDEXES record and populate a dict_index_t
|
This function parses a SYS_INDEXES record and populate a dict_index_t
|
||||||
structure with the information from the record. For detail information
|
structure with the information from the record. For detail information
|
||||||
@@ -724,7 +643,7 @@ dict_sys_tables_type_to_tf(ulint type, bool not_redundant)
|
|||||||
|
|
||||||
/** Read and return 5 integer fields from a SYS_TABLES record.
|
/** Read and return 5 integer fields from a SYS_TABLES record.
|
||||||
@param[in] rec A record of SYS_TABLES
|
@param[in] rec A record of SYS_TABLES
|
||||||
@param[in] name Table Name, the same as SYS_TABLES.NAME
|
@param[in] name SYS_TABLES.NAME
|
||||||
@param[out] table_id Pointer to the table_id for this table
|
@param[out] table_id Pointer to the table_id for this table
|
||||||
@param[out] space_id Pointer to the space_id for this table
|
@param[out] space_id Pointer to the space_id for this table
|
||||||
@param[out] n_cols Pointer to number of columns for this table.
|
@param[out] n_cols Pointer to number of columns for this table.
|
||||||
@@ -736,7 +655,7 @@ static
|
|||||||
bool
|
bool
|
||||||
dict_sys_tables_rec_read(
|
dict_sys_tables_rec_read(
|
||||||
const rec_t* rec,
|
const rec_t* rec,
|
||||||
const table_name_t& table_name,
|
const span<const char>& name,
|
||||||
table_id_t* table_id,
|
table_id_t* table_id,
|
||||||
ulint* space_id,
|
ulint* space_id,
|
||||||
ulint* n_cols,
|
ulint* n_cols,
|
||||||
@@ -850,10 +769,11 @@ dict_sys_tables_rec_read(
|
|||||||
const bool not_redundant = 0 != (*n_cols & DICT_N_COLS_COMPACT);
|
const bool not_redundant = 0 != (*n_cols & DICT_N_COLS_COMPACT);
|
||||||
|
|
||||||
if (!dict_sys_tables_type_valid(type, not_redundant)) {
|
if (!dict_sys_tables_type_valid(type, not_redundant)) {
|
||||||
ib::error() << "Table " << table_name << " in InnoDB"
|
sql_print_error("InnoDB: Table %.*s in InnoDB"
|
||||||
" data dictionary contains invalid flags."
|
" data dictionary contains invalid flags."
|
||||||
" SYS_TABLES.TYPE=" << type <<
|
" SYS_TABLES.TYPE=" ULINTPF
|
||||||
" SYS_TABLES.N_COLS=" << *n_cols;
|
" SYS_TABLES.N_COLS=" ULINTPF,
|
||||||
|
name.size(), name.data(), type, *n_cols);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,10 +793,13 @@ dict_sys_tables_rec_read(
|
|||||||
*flags2 = mach_read_from_4(field);
|
*flags2 = mach_read_from_4(field);
|
||||||
|
|
||||||
if (!dict_tf2_is_valid(*flags, *flags2)) {
|
if (!dict_tf2_is_valid(*flags, *flags2)) {
|
||||||
ib::error() << "Table " << table_name << " in InnoDB"
|
sql_print_error("InnoDB: Table %.*s in InnoDB"
|
||||||
" data dictionary contains invalid flags."
|
" data dictionary"
|
||||||
" SYS_TABLES.TYPE=" << type
|
" contains invalid flags."
|
||||||
<< " SYS_TABLES.MIX_LEN=" << *flags2;
|
" SYS_TABLES.TYPE=" ULINTPF
|
||||||
|
" SYS_TABLES.MIX_LEN=" ULINTPF,
|
||||||
|
name.size(), name.data(),
|
||||||
|
type, *flags2);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,7 +824,6 @@ static ulint dict_check_sys_tables()
|
|||||||
{
|
{
|
||||||
ulint max_space_id = 0;
|
ulint max_space_id = 0;
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
const rec_t* rec;
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
DBUG_ENTER("dict_check_sys_tables");
|
DBUG_ENTER("dict_check_sys_tables");
|
||||||
@@ -910,11 +832,9 @@ static ulint dict_check_sys_tables()
|
|||||||
|
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
for (rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
|
for (const rec_t *rec = dict_startscan_system(&pcur, &mtr,
|
||||||
rec != NULL;
|
dict_sys.sys_tables);
|
||||||
mtr.commit(), mtr.start(),
|
rec; rec = dict_getnext_system(&pcur, &mtr)) {
|
||||||
rec = dict_getnext_system(&pcur, &mtr)) {
|
|
||||||
const byte* field;
|
|
||||||
ulint len;
|
ulint len;
|
||||||
table_id_t table_id;
|
table_id_t table_id;
|
||||||
ulint space_id;
|
ulint space_id;
|
||||||
@@ -924,39 +844,40 @@ static ulint dict_check_sys_tables()
|
|||||||
|
|
||||||
/* If a table record is not useable, ignore it and continue
|
/* If a table record is not useable, ignore it and continue
|
||||||
on to the next record. Error messages were logged. */
|
on to the next record. Error messages were logged. */
|
||||||
if (dict_sys_tables_rec_check(rec) != NULL) {
|
if (dict_sys_tables_rec_check(rec)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the table name from rec */
|
/* Copy the table name from rec */
|
||||||
field = rec_get_nth_field_old(
|
const char *field = reinterpret_cast<const char*>(
|
||||||
rec, DICT_FLD__SYS_TABLES__NAME, &len);
|
rec_get_nth_field_old(rec, DICT_FLD__SYS_TABLES__NAME,
|
||||||
|
&len));
|
||||||
|
|
||||||
table_name_t table_name(mem_strdupl((char*) field, len));
|
if (len == UNIV_SQL_NULL
|
||||||
DBUG_PRINT("dict_check_sys_tables",
|
|| dict_table_t::is_garbage_name(field, len)) {
|
||||||
("name: %p, '%s'", table_name.m_name,
|
/* This table will be dropped by
|
||||||
table_name.m_name));
|
dict_table_t::drop_garbage().
|
||||||
|
We do not care if the file exists. */
|
||||||
if (!dict_sys_tables_rec_read(rec, table_name,
|
|
||||||
&table_id, &space_id,
|
|
||||||
&n_cols, &flags, &flags2)
|
|
||||||
|| space_id == TRX_SYS_SPACE) {
|
|
||||||
next:
|
|
||||||
ut_free(table_name.m_name);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strstr(table_name.m_name, "/" TEMP_FILE_PREFIX_INNODB)) {
|
DBUG_PRINT("dict_check_sys_tables",
|
||||||
/* This table will be dropped by
|
("name: %*.s", static_cast<int>(len), field));
|
||||||
row_mysql_drop_garbage_tables().
|
|
||||||
We do not care if the file exists. */
|
const span<const char> name{field, len};
|
||||||
goto next;
|
|
||||||
|
if (!dict_sys_tables_rec_read(rec, name, &table_id, &space_id,
|
||||||
|
&n_cols, &flags, &flags2)
|
||||||
|
|| space_id == TRX_SYS_SPACE) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags2 & DICT_TF2_DISCARDED) {
|
if (flags2 & DICT_TF2_DISCARDED) {
|
||||||
ib::info() << "Ignoring tablespace for " << table_name
|
sql_print_information("InnoDB: Ignoring tablespace"
|
||||||
<< " because the DISCARD flag is set .";
|
" for %.*s because "
|
||||||
goto next;
|
"the DISCARD flag is set",
|
||||||
|
static_cast<int>(len), field);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For tables or partitions using .ibd files, the flag
|
/* For tables or partitions using .ibd files, the flag
|
||||||
@@ -968,10 +889,10 @@ next:
|
|||||||
will otherwise ignore the flag. */
|
will otherwise ignore the flag. */
|
||||||
|
|
||||||
if (fil_space_for_table_exists_in_mem(space_id, flags)) {
|
if (fil_space_for_table_exists_in_mem(space_id, flags)) {
|
||||||
goto next;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* filepath = fil_make_filepath(nullptr, table_name,
|
char* filepath = fil_make_filepath(nullptr, name,
|
||||||
IBD, false);
|
IBD, false);
|
||||||
|
|
||||||
/* Check that the .ibd file exists. */
|
/* Check that the .ibd file exists. */
|
||||||
@@ -979,16 +900,17 @@ next:
|
|||||||
false,
|
false,
|
||||||
FIL_TYPE_TABLESPACE,
|
FIL_TYPE_TABLESPACE,
|
||||||
space_id, dict_tf_to_fsp_flags(flags),
|
space_id, dict_tf_to_fsp_flags(flags),
|
||||||
table_name, filepath)) {
|
name, filepath)) {
|
||||||
ib::warn() << "Ignoring tablespace for "
|
sql_print_warning("InnoDB: Ignoring tablespace for"
|
||||||
<< table_name
|
" %.*s because it"
|
||||||
<< " because it could not be opened.";
|
" could not be opened.",
|
||||||
|
static_cast<int>(name.size()),
|
||||||
|
name.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
max_space_id = ut_max(max_space_id, space_id);
|
max_space_id = ut_max(max_space_id, space_id);
|
||||||
|
|
||||||
ut_free(filepath);
|
ut_free(filepath);
|
||||||
goto next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
@@ -1307,8 +1229,6 @@ dict_load_columns(
|
|||||||
mem_heap_t* heap) /*!< in/out: memory heap
|
mem_heap_t* heap) /*!< in/out: memory heap
|
||||||
for temporary storage */
|
for temporary storage */
|
||||||
{
|
{
|
||||||
dict_table_t* sys_columns;
|
|
||||||
dict_index_t* sys_index;
|
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
dtuple_t* tuple;
|
dtuple_t* tuple;
|
||||||
dfield_t* dfield;
|
dfield_t* dfield;
|
||||||
@@ -1322,13 +1242,12 @@ dict_load_columns(
|
|||||||
|
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
sys_columns = dict_table_get_low("SYS_COLUMNS");
|
dict_index_t* sys_index = dict_sys.sys_columns->indexes.start;
|
||||||
sys_index = UT_LIST_GET_FIRST(sys_columns->indexes);
|
ut_ad(!dict_sys.sys_columns->not_redundant());
|
||||||
ut_ad(!dict_table_is_comp(sys_columns));
|
|
||||||
|
|
||||||
ut_ad(name_of_col_is(sys_columns, sys_index,
|
ut_ad(name_of_col_is(dict_sys.sys_columns, sys_index,
|
||||||
DICT_FLD__SYS_COLUMNS__NAME, "NAME"));
|
DICT_FLD__SYS_COLUMNS__NAME, "NAME"));
|
||||||
ut_ad(name_of_col_is(sys_columns, sys_index,
|
ut_ad(name_of_col_is(dict_sys.sys_columns, sys_index,
|
||||||
DICT_FLD__SYS_COLUMNS__PREC, "PREC"));
|
DICT_FLD__SYS_COLUMNS__PREC, "PREC"));
|
||||||
|
|
||||||
tuple = dtuple_create(heap, 1);
|
tuple = dtuple_create(heap, 1);
|
||||||
@@ -1423,7 +1342,6 @@ dict_load_virtual_one_col(
|
|||||||
dict_v_col_t* v_col,
|
dict_v_col_t* v_col,
|
||||||
mem_heap_t* heap)
|
mem_heap_t* heap)
|
||||||
{
|
{
|
||||||
dict_table_t* sys_virtual;
|
|
||||||
dict_index_t* sys_virtual_index;
|
dict_index_t* sys_virtual_index;
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
dtuple_t* tuple;
|
dtuple_t* tuple;
|
||||||
@@ -1442,11 +1360,10 @@ dict_load_virtual_one_col(
|
|||||||
|
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
sys_virtual = dict_table_get_low("SYS_VIRTUAL");
|
sys_virtual_index = dict_sys.sys_virtual->indexes.start;
|
||||||
sys_virtual_index = UT_LIST_GET_FIRST(sys_virtual->indexes);
|
ut_ad(!dict_sys.sys_virtual->not_redundant());
|
||||||
ut_ad(!dict_table_is_comp(sys_virtual));
|
|
||||||
|
|
||||||
ut_ad(name_of_col_is(sys_virtual, sys_virtual_index,
|
ut_ad(name_of_col_is(dict_sys.sys_virtual, sys_virtual_index,
|
||||||
DICT_FLD__SYS_VIRTUAL__POS, "POS"));
|
DICT_FLD__SYS_VIRTUAL__POS, "POS"));
|
||||||
|
|
||||||
tuple = dtuple_create(heap, 2);
|
tuple = dtuple_create(heap, 2);
|
||||||
@@ -1656,8 +1573,6 @@ dict_load_fields(
|
|||||||
dict_index_t* index, /*!< in/out: index whose fields to load */
|
dict_index_t* index, /*!< in/out: index whose fields to load */
|
||||||
mem_heap_t* heap) /*!< in: memory heap for temporary storage */
|
mem_heap_t* heap) /*!< in: memory heap for temporary storage */
|
||||||
{
|
{
|
||||||
dict_table_t* sys_fields;
|
|
||||||
dict_index_t* sys_index;
|
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
dtuple_t* tuple;
|
dtuple_t* tuple;
|
||||||
dfield_t* dfield;
|
dfield_t* dfield;
|
||||||
@@ -1671,10 +1586,9 @@ dict_load_fields(
|
|||||||
|
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
sys_fields = dict_table_get_low("SYS_FIELDS");
|
dict_index_t* sys_index = dict_sys.sys_fields->indexes.start;
|
||||||
sys_index = UT_LIST_GET_FIRST(sys_fields->indexes);
|
ut_ad(!dict_sys.sys_fields->not_redundant());
|
||||||
ut_ad(!dict_table_is_comp(sys_fields));
|
ut_ad(name_of_col_is(dict_sys.sys_fields, sys_index,
|
||||||
ut_ad(name_of_col_is(sys_fields, sys_index,
|
|
||||||
DICT_FLD__SYS_FIELDS__COL_NAME, "COL_NAME"));
|
DICT_FLD__SYS_FIELDS__COL_NAME, "COL_NAME"));
|
||||||
|
|
||||||
tuple = dtuple_create(heap, 1);
|
tuple = dtuple_create(heap, 1);
|
||||||
@@ -1889,7 +1803,6 @@ dict_load_indexes(
|
|||||||
/*!< in: error to be ignored when
|
/*!< in: error to be ignored when
|
||||||
loading the index definition */
|
loading the index definition */
|
||||||
{
|
{
|
||||||
dict_table_t* sys_indexes;
|
|
||||||
dict_index_t* sys_index;
|
dict_index_t* sys_index;
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
dtuple_t* tuple;
|
dtuple_t* tuple;
|
||||||
@@ -1903,12 +1816,11 @@ dict_load_indexes(
|
|||||||
|
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
sys_indexes = dict_table_get_low("SYS_INDEXES");
|
sys_index = dict_sys.sys_indexes->indexes.start;
|
||||||
sys_index = UT_LIST_GET_FIRST(sys_indexes->indexes);
|
ut_ad(!dict_sys.sys_indexes->not_redundant());
|
||||||
ut_ad(!dict_table_is_comp(sys_indexes));
|
ut_ad(name_of_col_is(dict_sys.sys_indexes, sys_index,
|
||||||
ut_ad(name_of_col_is(sys_indexes, sys_index,
|
|
||||||
DICT_FLD__SYS_INDEXES__NAME, "NAME"));
|
DICT_FLD__SYS_INDEXES__NAME, "NAME"));
|
||||||
ut_ad(name_of_col_is(sys_indexes, sys_index,
|
ut_ad(name_of_col_is(dict_sys.sys_indexes, sys_index,
|
||||||
DICT_FLD__SYS_INDEXES__PAGE_NO, "PAGE_NO"));
|
DICT_FLD__SYS_INDEXES__PAGE_NO, "PAGE_NO"));
|
||||||
|
|
||||||
tuple = dtuple_create(heap, 1);
|
tuple = dtuple_create(heap, 1);
|
||||||
@@ -2156,11 +2068,11 @@ func_exit:
|
|||||||
Do not load any columns or indexes.
|
Do not load any columns or indexes.
|
||||||
@param[in] name Table name
|
@param[in] name Table name
|
||||||
@param[in] rec SYS_TABLES record
|
@param[in] rec SYS_TABLES record
|
||||||
@param[out,own] table table, or NULL
|
@param[out,own] table table, or nullptr
|
||||||
@return error message
|
@return error message
|
||||||
@retval NULL on success */
|
@retval nullptr on success */
|
||||||
static const char* dict_load_table_low(const table_name_t& name,
|
const char *dict_load_table_low(const span<const char> &name,
|
||||||
const rec_t* rec, dict_table_t** table)
|
const rec_t *rec, dict_table_t **table)
|
||||||
{
|
{
|
||||||
table_id_t table_id;
|
table_id_t table_id;
|
||||||
ulint space_id;
|
ulint space_id;
|
||||||
@@ -2183,8 +2095,8 @@ static const char* dict_load_table_low(const table_name_t& name,
|
|||||||
|
|
||||||
dict_table_decode_n_col(t_num, &n_cols, &n_v_col);
|
dict_table_decode_n_col(t_num, &n_cols, &n_v_col);
|
||||||
|
|
||||||
*table = dict_mem_table_create(
|
*table = dict_table_t::create(name, nullptr, n_cols + n_v_col,
|
||||||
name.m_name, NULL, n_cols + n_v_col, n_v_col, flags, flags2);
|
n_v_col, flags, flags2);
|
||||||
(*table)->space_id = space_id;
|
(*table)->space_id = space_id;
|
||||||
(*table)->id = table_id;
|
(*table)->id = table_id;
|
||||||
(*table)->file_unreadable = !!(flags2 & DICT_TF2_DISCARDED);
|
(*table)->file_unreadable = !!(flags2 & DICT_TF2_DISCARDED);
|
||||||
@@ -2271,44 +2183,6 @@ dict_get_and_save_data_dir_path(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Loads a table definition and also all its index definitions, and also
|
|
||||||
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.
|
|
||||||
@param[in] name Table name in the dbname/tablename format
|
|
||||||
@param[in] ignore_err Error to be ignored when loading
|
|
||||||
table and its index definition
|
|
||||||
@return table, NULL if does not exist; if the table is stored in an
|
|
||||||
.ibd file, but the file does not exist, then we set the file_unreadable
|
|
||||||
flag in the table object we return. */
|
|
||||||
dict_table_t* dict_load_table(const char* name, dict_err_ignore_t ignore_err)
|
|
||||||
{
|
|
||||||
dict_names_t fk_list;
|
|
||||||
dict_table_t* result;
|
|
||||||
dict_names_t::iterator i;
|
|
||||||
|
|
||||||
DBUG_ENTER("dict_load_table");
|
|
||||||
DBUG_PRINT("dict_load_table", ("loading table: '%s'", name));
|
|
||||||
|
|
||||||
dict_sys.assert_locked();
|
|
||||||
|
|
||||||
result = dict_table_check_if_in_cache_low(name);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
result = dict_load_table_one(const_cast<char*>(name),
|
|
||||||
ignore_err, fk_list);
|
|
||||||
while (!fk_list.empty()) {
|
|
||||||
if (!dict_table_check_if_in_cache_low(fk_list.front()))
|
|
||||||
dict_load_table_one(
|
|
||||||
const_cast<char*>(fk_list.front()),
|
|
||||||
ignore_err, fk_list);
|
|
||||||
fk_list.pop_front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_RETURN(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Opens a tablespace for dict_load_table_one()
|
/** Opens a tablespace for dict_load_table_one()
|
||||||
@param[in,out] table A table that refers to the tablespace to open
|
@param[in,out] table A table that refers to the tablespace to open
|
||||||
@param[in] ignore_err Whether to ignore an error. */
|
@param[in] ignore_err Whether to ignore an error. */
|
||||||
@@ -2368,12 +2242,10 @@ dict_load_tablespace(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to open the tablespace. We set the 2nd param (fix_dict) to
|
|
||||||
false because we do not have an x-lock on dict_sys.latch */
|
|
||||||
table->space = fil_ibd_open(
|
table->space = fil_ibd_open(
|
||||||
true, FIL_TYPE_TABLESPACE, table->space_id,
|
true, FIL_TYPE_TABLESPACE, table->space_id,
|
||||||
dict_tf_to_fsp_flags(table->flags),
|
dict_tf_to_fsp_flags(table->flags),
|
||||||
table->name, filepath);
|
{table->name.m_name, strlen(table->name.m_name)}, filepath);
|
||||||
|
|
||||||
if (!table->space) {
|
if (!table->space) {
|
||||||
/* We failed to find a sensible tablespace file */
|
/* We failed to find a sensible tablespace file */
|
||||||
@@ -2397,20 +2269,14 @@ key constraints are loaded into memory.
|
|||||||
@param[out] fk_tables Related table names that must also be
|
@param[out] fk_tables Related table names that must also be
|
||||||
loaded to ensure that all foreign key
|
loaded to ensure that all foreign key
|
||||||
constraints are loaded.
|
constraints are loaded.
|
||||||
@return table, NULL if does not exist; if the table is stored in an
|
@return table, possibly with file_unreadable flag set
|
||||||
.ibd file, but the file does not exist, then we set the
|
@retval nullptr if the table does not exist */
|
||||||
file_unreadable flag in the table object we return */
|
static dict_table_t *dict_load_table_one(const span<const char> &name,
|
||||||
static
|
dict_err_ignore_t ignore_err,
|
||||||
dict_table_t*
|
dict_names_t &fk_tables)
|
||||||
dict_load_table_one(
|
|
||||||
const table_name_t& name,
|
|
||||||
dict_err_ignore_t ignore_err,
|
|
||||||
dict_names_t& fk_tables)
|
|
||||||
{
|
{
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
dict_table_t* sys_tables;
|
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
dict_index_t* sys_index;
|
|
||||||
dtuple_t* tuple;
|
dtuple_t* tuple;
|
||||||
mem_heap_t* heap;
|
mem_heap_t* heap;
|
||||||
dfield_t* dfield;
|
dfield_t* dfield;
|
||||||
@@ -2420,7 +2286,8 @@ dict_load_table_one(
|
|||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
DBUG_ENTER("dict_load_table_one");
|
DBUG_ENTER("dict_load_table_one");
|
||||||
DBUG_PRINT("dict_load_table_one", ("table: %s", name.m_name));
|
DBUG_PRINT("dict_load_table_one",
|
||||||
|
("table: %.*s", name.size(), name.data()));
|
||||||
|
|
||||||
dict_sys.assert_locked();
|
dict_sys.assert_locked();
|
||||||
|
|
||||||
@@ -2428,24 +2295,23 @@ dict_load_table_one(
|
|||||||
|
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
sys_tables = dict_table_get_low("SYS_TABLES");
|
dict_index_t *sys_index = dict_sys.sys_tables->indexes.start;
|
||||||
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
|
ut_ad(!dict_sys.sys_tables->not_redundant());
|
||||||
ut_ad(!dict_table_is_comp(sys_tables));
|
ut_ad(name_of_col_is(dict_sys.sys_tables, sys_index,
|
||||||
ut_ad(name_of_col_is(sys_tables, sys_index,
|
|
||||||
DICT_FLD__SYS_TABLES__ID, "ID"));
|
DICT_FLD__SYS_TABLES__ID, "ID"));
|
||||||
ut_ad(name_of_col_is(sys_tables, sys_index,
|
ut_ad(name_of_col_is(dict_sys.sys_tables, sys_index,
|
||||||
DICT_FLD__SYS_TABLES__N_COLS, "N_COLS"));
|
DICT_FLD__SYS_TABLES__N_COLS, "N_COLS"));
|
||||||
ut_ad(name_of_col_is(sys_tables, sys_index,
|
ut_ad(name_of_col_is(dict_sys.sys_tables, sys_index,
|
||||||
DICT_FLD__SYS_TABLES__TYPE, "TYPE"));
|
DICT_FLD__SYS_TABLES__TYPE, "TYPE"));
|
||||||
ut_ad(name_of_col_is(sys_tables, sys_index,
|
ut_ad(name_of_col_is(dict_sys.sys_tables, sys_index,
|
||||||
DICT_FLD__SYS_TABLES__MIX_LEN, "MIX_LEN"));
|
DICT_FLD__SYS_TABLES__MIX_LEN, "MIX_LEN"));
|
||||||
ut_ad(name_of_col_is(sys_tables, sys_index,
|
ut_ad(name_of_col_is(dict_sys.sys_tables, sys_index,
|
||||||
DICT_FLD__SYS_TABLES__SPACE, "SPACE"));
|
DICT_FLD__SYS_TABLES__SPACE, "SPACE"));
|
||||||
|
|
||||||
tuple = dtuple_create(heap, 1);
|
tuple = dtuple_create(heap, 1);
|
||||||
dfield = dtuple_get_nth_field(tuple, 0);
|
dfield = dtuple_get_nth_field(tuple, 0);
|
||||||
|
|
||||||
dfield_set_data(dfield, name.m_name, strlen(name.m_name));
|
dfield_set_data(dfield, name.data(), name.size());
|
||||||
dict_index_copy_types(tuple, sys_index, 1);
|
dict_index_copy_types(tuple, sys_index, 1);
|
||||||
|
|
||||||
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
|
btr_pcur_open_on_user_rec(sys_index, tuple, PAGE_CUR_GE,
|
||||||
@@ -2467,9 +2333,7 @@ err_exit:
|
|||||||
rec, DICT_FLD__SYS_TABLES__NAME, &len);
|
rec, DICT_FLD__SYS_TABLES__NAME, &len);
|
||||||
|
|
||||||
/* Check if the table name in record is the searched one */
|
/* Check if the table name in record is the searched one */
|
||||||
if (len != strlen(name.m_name)
|
if (len != name.size() || memcmp(name.data(), field, len)) {
|
||||||
|| memcmp(name.m_name, field, len)) {
|
|
||||||
|
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2645,6 +2509,25 @@ func_exit:
|
|||||||
DBUG_RETURN(table);
|
DBUG_RETURN(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dict_table_t *dict_sys_t::load_table(const span<const char> &name,
|
||||||
|
dict_err_ignore_t ignore)
|
||||||
|
{
|
||||||
|
if (dict_table_t *table= find_table(name))
|
||||||
|
return table;
|
||||||
|
dict_names_t fk_list;
|
||||||
|
dict_table_t *table= dict_load_table_one(name, ignore, fk_list);
|
||||||
|
while (!fk_list.empty())
|
||||||
|
{
|
||||||
|
const char *f= fk_list.front();
|
||||||
|
const span<const char> name{f, strlen(f)};
|
||||||
|
if (!find_table(name))
|
||||||
|
dict_load_table_one(name, ignore, fk_list);
|
||||||
|
fk_list.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************//**
|
/***********************************************************************//**
|
||||||
Loads a table object based on the table id.
|
Loads a table object based on the table id.
|
||||||
@return table; NULL if table does not exist */
|
@return table; NULL if table does not exist */
|
||||||
@@ -2657,48 +2540,41 @@ dict_load_table_on_id(
|
|||||||
{
|
{
|
||||||
byte id_buf[8];
|
byte id_buf[8];
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
mem_heap_t* heap;
|
|
||||||
dtuple_t* tuple;
|
|
||||||
dfield_t* dfield;
|
|
||||||
dict_index_t* sys_table_ids;
|
|
||||||
dict_table_t* sys_tables;
|
|
||||||
const rec_t* rec;
|
|
||||||
const byte* field;
|
const byte* field;
|
||||||
ulint len;
|
ulint len;
|
||||||
dict_table_t* table;
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
dict_sys.assert_locked();
|
dict_sys.assert_locked();
|
||||||
|
|
||||||
table = NULL;
|
|
||||||
|
|
||||||
/* NOTE that the operation of this function is protected by
|
/* NOTE that the operation of this function is protected by
|
||||||
the dictionary mutex, and therefore no deadlocks can occur
|
the dictionary mutex, and therefore no deadlocks can occur
|
||||||
with other dictionary operations. */
|
with other dictionary operations. */
|
||||||
|
|
||||||
mtr_start(&mtr);
|
mtr.start();
|
||||||
/*---------------------------------------------------*/
|
/*---------------------------------------------------*/
|
||||||
/* Get the secondary index based on ID for table SYS_TABLES */
|
/* Get the secondary index based on ID for table SYS_TABLES */
|
||||||
sys_tables = dict_sys.sys_tables;
|
dict_index_t *sys_table_ids =
|
||||||
sys_table_ids = dict_table_get_next_index(
|
dict_sys.sys_tables->indexes.start->indexes.next;
|
||||||
dict_table_get_first_index(sys_tables));
|
|
||||||
ut_ad(!dict_table_is_comp(sys_tables));
|
|
||||||
ut_ad(!dict_index_is_clust(sys_table_ids));
|
|
||||||
heap = mem_heap_create(256);
|
|
||||||
|
|
||||||
tuple = dtuple_create(heap, 1);
|
dfield_t dfield;
|
||||||
dfield = dtuple_get_nth_field(tuple, 0);
|
dtuple_t tuple{
|
||||||
|
0,1,1,&dfield,0,nullptr
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
|
, DATA_TUPLE_MAGIC_N
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
/* Write the table id in byte format to id_buf */
|
/* Write the table id in byte format to id_buf */
|
||||||
mach_write_to_8(id_buf, table_id);
|
mach_write_to_8(id_buf, table_id);
|
||||||
|
dfield_set_data(&dfield, id_buf, 8);
|
||||||
|
dict_index_copy_types(&tuple, sys_table_ids, 1);
|
||||||
|
|
||||||
dfield_set_data(dfield, id_buf, 8);
|
btr_pcur_open_on_user_rec(sys_table_ids, &tuple, PAGE_CUR_GE,
|
||||||
dict_index_copy_types(tuple, sys_table_ids, 1);
|
|
||||||
|
|
||||||
btr_pcur_open_on_user_rec(sys_table_ids, tuple, PAGE_CUR_GE,
|
|
||||||
BTR_SEARCH_LEAF, &pcur, &mtr);
|
BTR_SEARCH_LEAF, &pcur, &mtr);
|
||||||
|
|
||||||
rec = btr_pcur_get_rec(&pcur);
|
|
||||||
|
const rec_t* rec = btr_pcur_get_rec(&pcur);
|
||||||
|
dict_table_t* table = nullptr;
|
||||||
|
|
||||||
if (page_rec_is_user_rec(rec)) {
|
if (page_rec_is_user_rec(rec)) {
|
||||||
/*---------------------------------------------------*/
|
/*---------------------------------------------------*/
|
||||||
@@ -2727,17 +2603,15 @@ check_rec:
|
|||||||
/* Now we get the table name from the record */
|
/* Now we get the table name from the record */
|
||||||
field = rec_get_nth_field_old(rec,
|
field = rec_get_nth_field_old(rec,
|
||||||
DICT_FLD__SYS_TABLE_IDS__NAME, &len);
|
DICT_FLD__SYS_TABLE_IDS__NAME, &len);
|
||||||
/* Load the table definition to memory */
|
table = dict_sys.load_table(
|
||||||
char* table_name = mem_heap_strdupl(
|
{reinterpret_cast<const char*>(field),
|
||||||
heap, (char*) field, len);
|
len}, ignore_err);
|
||||||
table = dict_load_table(table_name, ignore_err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
btr_pcur_close(&pcur);
|
btr_pcur_close(&pcur);
|
||||||
mtr_commit(&mtr);
|
mtr.commit();
|
||||||
mem_heap_free(heap);
|
|
||||||
|
|
||||||
return(table);
|
return(table);
|
||||||
}
|
}
|
||||||
@@ -2778,8 +2652,6 @@ dict_load_foreign_cols(
|
|||||||
/*===================*/
|
/*===================*/
|
||||||
dict_foreign_t* foreign)/*!< in/out: foreign constraint object */
|
dict_foreign_t* foreign)/*!< in/out: foreign constraint object */
|
||||||
{
|
{
|
||||||
dict_table_t* sys_foreign_cols;
|
|
||||||
dict_index_t* sys_index;
|
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
dtuple_t* tuple;
|
dtuple_t* tuple;
|
||||||
dfield_t* dfield;
|
dfield_t* dfield;
|
||||||
@@ -2804,10 +2676,8 @@ dict_load_foreign_cols(
|
|||||||
|
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
sys_foreign_cols = dict_table_get_low("SYS_FOREIGN_COLS");
|
dict_index_t* sys_index = dict_sys.sys_foreign_cols->indexes.start;
|
||||||
|
ut_ad(!dict_sys.sys_foreign_cols->not_redundant());
|
||||||
sys_index = UT_LIST_GET_FIRST(sys_foreign_cols->indexes);
|
|
||||||
ut_ad(!dict_table_is_comp(sys_foreign_cols));
|
|
||||||
|
|
||||||
tuple = dtuple_create(foreign->heap, 1);
|
tuple = dtuple_create(foreign->heap, 1);
|
||||||
dfield = dtuple_get_nth_field(tuple, 0);
|
dfield = dtuple_get_nth_field(tuple, 0);
|
||||||
@@ -2918,9 +2788,7 @@ dict_load_foreign(
|
|||||||
stack. */
|
stack. */
|
||||||
{
|
{
|
||||||
dict_foreign_t* foreign;
|
dict_foreign_t* foreign;
|
||||||
dict_table_t* sys_foreign;
|
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
dict_index_t* sys_index;
|
|
||||||
dtuple_t* tuple;
|
dtuple_t* tuple;
|
||||||
mem_heap_t* heap2;
|
mem_heap_t* heap2;
|
||||||
dfield_t* dfield;
|
dfield_t* dfield;
|
||||||
@@ -2944,10 +2812,8 @@ dict_load_foreign(
|
|||||||
|
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
sys_foreign = dict_table_get_low("SYS_FOREIGN");
|
dict_index_t* sys_index = dict_sys.sys_foreign->indexes.start;
|
||||||
|
ut_ad(!dict_sys.sys_foreign->not_redundant());
|
||||||
sys_index = UT_LIST_GET_FIRST(sys_foreign->indexes);
|
|
||||||
ut_ad(!dict_table_is_comp(sys_foreign));
|
|
||||||
|
|
||||||
tuple = dtuple_create(heap2, 1);
|
tuple = dtuple_create(heap2, 1);
|
||||||
dfield = dtuple_get_nth_field(tuple, 0);
|
dfield = dtuple_get_nth_field(tuple, 0);
|
||||||
@@ -2965,7 +2831,7 @@ dict_load_foreign(
|
|||||||
|
|
||||||
ib::error() << "Cannot load foreign constraint " << id
|
ib::error() << "Cannot load foreign constraint " << id
|
||||||
<< ": could not find the relevant record in "
|
<< ": could not find the relevant record in "
|
||||||
<< "SYS_FOREIGN";
|
"SYS_FOREIGN";
|
||||||
|
|
||||||
btr_pcur_close(&pcur);
|
btr_pcur_close(&pcur);
|
||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
@@ -3033,10 +2899,12 @@ dict_load_foreign(
|
|||||||
|
|
||||||
dict_load_foreign_cols(foreign);
|
dict_load_foreign_cols(foreign);
|
||||||
|
|
||||||
ref_table = dict_table_check_if_in_cache_low(
|
ref_table = dict_sys.find_table(
|
||||||
foreign->referenced_table_name_lookup);
|
{foreign->referenced_table_name_lookup,
|
||||||
for_table = dict_table_check_if_in_cache_low(
|
strlen(foreign->referenced_table_name_lookup)});
|
||||||
foreign->foreign_table_name_lookup);
|
for_table = dict_sys.find_table(
|
||||||
|
{foreign->foreign_table_name_lookup,
|
||||||
|
strlen(foreign->foreign_table_name_lookup)});
|
||||||
|
|
||||||
if (!for_table) {
|
if (!for_table) {
|
||||||
/* To avoid recursively loading the tables related through
|
/* To avoid recursively loading the tables related through
|
||||||
@@ -3101,8 +2969,6 @@ dict_load_foreigns(
|
|||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
dtuple_t* tuple;
|
dtuple_t* tuple;
|
||||||
dfield_t* dfield;
|
dfield_t* dfield;
|
||||||
dict_index_t* sec_index;
|
|
||||||
dict_table_t* sys_foreign;
|
|
||||||
const rec_t* rec;
|
const rec_t* rec;
|
||||||
const byte* field;
|
const byte* field;
|
||||||
ulint len;
|
ulint len;
|
||||||
@@ -3113,24 +2979,21 @@ dict_load_foreigns(
|
|||||||
|
|
||||||
dict_sys.assert_locked();
|
dict_sys.assert_locked();
|
||||||
|
|
||||||
sys_foreign = dict_table_get_low("SYS_FOREIGN");
|
if (!dict_sys.sys_foreign || !dict_sys.sys_foreign_cols) {
|
||||||
|
if (ignore_err & DICT_ERR_IGNORE_FK_NOKEY) {
|
||||||
if (sys_foreign == NULL) {
|
DBUG_RETURN(DB_SUCCESS);
|
||||||
/* No foreign keys defined yet in this database */
|
}
|
||||||
|
sql_print_information("InnoDB: No foreign key system tables"
|
||||||
ib::info() << "No foreign key system tables in the database";
|
" in the database");
|
||||||
DBUG_RETURN(DB_ERROR);
|
DBUG_RETURN(DB_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
ut_ad(!dict_table_is_comp(sys_foreign));
|
ut_ad(!dict_sys.sys_foreign->not_redundant());
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
/* Get the secondary index based on FOR_NAME from table
|
dict_index_t *sec_index = dict_table_get_next_index(
|
||||||
SYS_FOREIGN */
|
dict_table_get_first_index(dict_sys.sys_foreign));
|
||||||
|
ut_ad(!strcmp(sec_index->fields[0].name, "FOR_NAME"));
|
||||||
sec_index = dict_table_get_next_index(
|
|
||||||
dict_table_get_first_index(sys_foreign));
|
|
||||||
ut_ad(!dict_index_is_clust(sec_index));
|
|
||||||
start_load:
|
start_load:
|
||||||
|
|
||||||
tuple = dtuple_create_from_mem(tuple_buf, sizeof(tuple_buf), 1, 0);
|
tuple = dtuple_create_from_mem(tuple_buf, sizeof(tuple_buf), 1, 0);
|
||||||
|
@@ -123,85 +123,73 @@ bool dict_col_t::same_encoding(uint16_t a, uint16_t b)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Create a table memory object.
|
/** Create metadata.
|
||||||
@param name table name
|
@param name table name
|
||||||
@param space tablespace
|
@param space tablespace
|
||||||
@param n_cols total number of columns (both virtual and non-virtual)
|
@param n_cols total number of columns (both virtual and non-virtual)
|
||||||
@param n_v_cols number of virtual columns
|
@param n_v_cols number of virtual columns
|
||||||
@param flags table flags
|
@param flags table flags
|
||||||
@param flags2 table flags2
|
@param flags2 table flags2
|
||||||
@return own: table object */
|
@return newly allocated table object */
|
||||||
dict_table_t *dict_mem_table_create(const char *name, fil_space_t *space,
|
dict_table_t *dict_table_t::create(const span<const char> &name,
|
||||||
ulint n_cols, ulint n_v_cols, ulint flags,
|
fil_space_t *space,
|
||||||
ulint flags2)
|
ulint n_cols, ulint n_v_cols, ulint flags,
|
||||||
|
ulint flags2)
|
||||||
{
|
{
|
||||||
dict_table_t* table;
|
ut_ad(!space || space->purpose == FIL_TYPE_TABLESPACE ||
|
||||||
mem_heap_t* heap;
|
space->purpose == FIL_TYPE_TEMPORARY ||
|
||||||
|
space->purpose == FIL_TYPE_IMPORT);
|
||||||
|
ut_a(dict_tf2_is_valid(flags, flags2));
|
||||||
|
ut_a(!(flags2 & DICT_TF2_UNUSED_BIT_MASK));
|
||||||
|
|
||||||
ut_ad(name);
|
mem_heap_t *heap= mem_heap_create(DICT_HEAP_SIZE);
|
||||||
ut_ad(!space
|
|
||||||
|| space->purpose == FIL_TYPE_TABLESPACE
|
|
||||||
|| space->purpose == FIL_TYPE_TEMPORARY
|
|
||||||
|| space->purpose == FIL_TYPE_IMPORT);
|
|
||||||
ut_a(dict_tf2_is_valid(flags, flags2));
|
|
||||||
ut_a(!(flags2 & DICT_TF2_UNUSED_BIT_MASK));
|
|
||||||
|
|
||||||
heap = mem_heap_create(DICT_HEAP_SIZE);
|
dict_table_t *table= static_cast<dict_table_t*>
|
||||||
|
(mem_heap_zalloc(heap, sizeof(*table)));
|
||||||
|
|
||||||
table = static_cast<dict_table_t*>(
|
lock_table_lock_list_init(&table->locks);
|
||||||
mem_heap_zalloc(heap, sizeof(*table)));
|
UT_LIST_INIT(table->indexes, &dict_index_t::indexes);
|
||||||
|
|
||||||
lock_table_lock_list_init(&table->locks);
|
|
||||||
|
|
||||||
UT_LIST_INIT(table->indexes, &dict_index_t::indexes);
|
|
||||||
#ifdef BTR_CUR_HASH_ADAPT
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
UT_LIST_INIT(table->freed_indexes, &dict_index_t::indexes);
|
UT_LIST_INIT(table->freed_indexes, &dict_index_t::indexes);
|
||||||
#endif /* BTR_CUR_HASH_ADAPT */
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
|
table->heap= heap;
|
||||||
|
|
||||||
table->heap = heap;
|
ut_d(table->magic_n= DICT_TABLE_MAGIC_N);
|
||||||
|
|
||||||
ut_d(table->magic_n = DICT_TABLE_MAGIC_N);
|
table->flags= static_cast<unsigned>(flags) & ((1U << DICT_TF_BITS) - 1);
|
||||||
|
table->flags2= static_cast<unsigned>(flags2) & ((1U << DICT_TF2_BITS) - 1);
|
||||||
|
table->name.m_name= mem_strdupl(name.data(), name.size());
|
||||||
|
table->is_system_db= dict_mem_table_is_system(table->name.m_name);
|
||||||
|
table->space= space;
|
||||||
|
table->space_id= space ? space->id : ULINT_UNDEFINED;
|
||||||
|
table->n_t_cols= static_cast<unsigned>(n_cols + DATA_N_SYS_COLS) &
|
||||||
|
dict_index_t::MAX_N_FIELDS;
|
||||||
|
table->n_v_cols= static_cast<unsigned>(n_v_cols) &
|
||||||
|
dict_index_t::MAX_N_FIELDS;
|
||||||
|
table->n_cols= static_cast<unsigned>(table->n_t_cols - table->n_v_cols) &
|
||||||
|
dict_index_t::MAX_N_FIELDS;
|
||||||
|
table->cols= static_cast<dict_col_t*>
|
||||||
|
(mem_heap_alloc(heap, table->n_cols * sizeof *table->cols));
|
||||||
|
table->v_cols= static_cast<dict_v_col_t*>
|
||||||
|
(mem_heap_alloc(heap, n_v_cols * sizeof *table->v_cols));
|
||||||
|
for (ulint i = n_v_cols; i--; )
|
||||||
|
new (&table->v_cols[i]) dict_v_col_t();
|
||||||
|
table->autoinc_lock= static_cast<ib_lock_t*>
|
||||||
|
(mem_heap_alloc(heap, sizeof *table->autoinc_lock));
|
||||||
|
/* If the table has an FTS index or we are in the process
|
||||||
|
of building one, create the table->fts */
|
||||||
|
if (dict_table_has_fts_index(table) ||
|
||||||
|
DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID |
|
||||||
|
DICT_TF2_FTS_ADD_DOC_ID))
|
||||||
|
{
|
||||||
|
table->fts= fts_create(table);
|
||||||
|
table->fts->cache= fts_cache_create(table);
|
||||||
|
}
|
||||||
|
|
||||||
table->flags = static_cast<unsigned>(flags)
|
new (&table->foreign_set) dict_foreign_set();
|
||||||
& ((1U << DICT_TF_BITS) - 1);
|
new (&table->referenced_set) dict_foreign_set();
|
||||||
table->flags2 = static_cast<unsigned>(flags2)
|
|
||||||
& ((1U << DICT_TF2_BITS) - 1);
|
|
||||||
table->name.m_name = mem_strdup(name);
|
|
||||||
table->is_system_db = dict_mem_table_is_system(table->name.m_name);
|
|
||||||
table->space = space;
|
|
||||||
table->space_id = space ? space->id : ULINT_UNDEFINED;
|
|
||||||
table->n_t_cols = static_cast<unsigned>(n_cols + DATA_N_SYS_COLS)
|
|
||||||
& dict_index_t::MAX_N_FIELDS;
|
|
||||||
table->n_v_cols = static_cast<unsigned>(n_v_cols)
|
|
||||||
& dict_index_t::MAX_N_FIELDS;
|
|
||||||
table->n_cols = static_cast<unsigned>(
|
|
||||||
table->n_t_cols - table->n_v_cols)
|
|
||||||
& dict_index_t::MAX_N_FIELDS;
|
|
||||||
|
|
||||||
table->cols = static_cast<dict_col_t*>(
|
return table;
|
||||||
mem_heap_alloc(heap, table->n_cols * sizeof(dict_col_t)));
|
|
||||||
table->v_cols = static_cast<dict_v_col_t*>(
|
|
||||||
mem_heap_alloc(heap, n_v_cols * sizeof(*table->v_cols)));
|
|
||||||
for (ulint i = n_v_cols; i--; ) {
|
|
||||||
new (&table->v_cols[i]) dict_v_col_t();
|
|
||||||
}
|
|
||||||
|
|
||||||
table->autoinc_lock = static_cast<ib_lock_t*>(
|
|
||||||
mem_heap_alloc(heap, sizeof *table->autoinc_lock));
|
|
||||||
|
|
||||||
/* If the table has an FTS index or we are in the process
|
|
||||||
of building one, create the table->fts */
|
|
||||||
if (dict_table_has_fts_index(table)
|
|
||||||
|| DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_HAS_DOC_ID)
|
|
||||||
|| DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS_ADD_DOC_ID)) {
|
|
||||||
table->fts = fts_create(table);
|
|
||||||
table->fts->cache = fts_cache_create(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
new(&table->foreign_set) dict_foreign_set();
|
|
||||||
new(&table->referenced_set) dict_foreign_set();
|
|
||||||
|
|
||||||
return(table);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
|
@@ -25,7 +25,6 @@ Created Jan 06, 2010 Vasil Dimov
|
|||||||
*******************************************************/
|
*******************************************************/
|
||||||
|
|
||||||
#include "dict0stats.h"
|
#include "dict0stats.h"
|
||||||
#include "dict0priv.h"
|
|
||||||
#include "ut0ut.h"
|
#include "ut0ut.h"
|
||||||
#include "ut0rnd.h"
|
#include "ut0rnd.h"
|
||||||
#include "dyn0buf.h"
|
#include "dyn0buf.h"
|
||||||
@@ -143,6 +142,20 @@ typedef ut_allocator<std::pair<const char* const, dict_index_t*> >
|
|||||||
typedef std::map<const char*, dict_index_t*, ut_strcmp_functor,
|
typedef std::map<const char*, dict_index_t*, ut_strcmp_functor,
|
||||||
index_map_t_allocator> index_map_t;
|
index_map_t_allocator> index_map_t;
|
||||||
|
|
||||||
|
inline bool dict_table_t::is_stats_table() const
|
||||||
|
{
|
||||||
|
return !strcmp(name.m_name, TABLE_STATS_NAME) ||
|
||||||
|
!strcmp(name.m_name, INDEX_STATS_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool trx_t::has_stats_table_lock() const
|
||||||
|
{
|
||||||
|
for (const lock_t *l : lock.table_locks)
|
||||||
|
if (l && l->un_member.tab_lock.table->is_stats_table())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Checks whether an index should be ignored in stats manipulations:
|
Checks whether an index should be ignored in stats manipulations:
|
||||||
* stats fetch
|
* stats fetch
|
||||||
@@ -179,7 +192,7 @@ struct dict_col_meta_t
|
|||||||
struct dict_table_schema_t
|
struct dict_table_schema_t
|
||||||
{
|
{
|
||||||
/** table name */
|
/** table name */
|
||||||
const char *table_name;
|
span<const char> table_name;
|
||||||
/** table name in SQL */
|
/** table name in SQL */
|
||||||
const char *table_name_sql;
|
const char *table_name_sql;
|
||||||
/** number of columns */
|
/** number of columns */
|
||||||
@@ -190,7 +203,7 @@ struct dict_table_schema_t
|
|||||||
|
|
||||||
static const dict_table_schema_t table_stats_schema =
|
static const dict_table_schema_t table_stats_schema =
|
||||||
{
|
{
|
||||||
TABLE_STATS_NAME, TABLE_STATS_NAME_PRINT, 6,
|
{C_STRING_WITH_LEN(TABLE_STATS_NAME)}, TABLE_STATS_NAME_PRINT, 6,
|
||||||
{
|
{
|
||||||
{"database_name", DATA_VARMYSQL, DATA_NOT_NULL, 192},
|
{"database_name", DATA_VARMYSQL, DATA_NOT_NULL, 192},
|
||||||
{"table_name", DATA_VARMYSQL, DATA_NOT_NULL, 597},
|
{"table_name", DATA_VARMYSQL, DATA_NOT_NULL, 597},
|
||||||
@@ -203,7 +216,7 @@ static const dict_table_schema_t table_stats_schema =
|
|||||||
|
|
||||||
static const dict_table_schema_t index_stats_schema =
|
static const dict_table_schema_t index_stats_schema =
|
||||||
{
|
{
|
||||||
INDEX_STATS_NAME, INDEX_STATS_NAME_PRINT, 8,
|
{C_STRING_WITH_LEN(INDEX_STATS_NAME)}, INDEX_STATS_NAME_PRINT, 8,
|
||||||
{
|
{
|
||||||
{"database_name", DATA_VARMYSQL, DATA_NOT_NULL, 192},
|
{"database_name", DATA_VARMYSQL, DATA_NOT_NULL, 192},
|
||||||
{"table_name", DATA_VARMYSQL, DATA_NOT_NULL, 597},
|
{"table_name", DATA_VARMYSQL, DATA_NOT_NULL, 597},
|
||||||
@@ -327,7 +340,7 @@ dict_table_schema_check(
|
|||||||
returned */
|
returned */
|
||||||
size_t errstr_sz) /*!< in: errstr size */
|
size_t errstr_sz) /*!< in: errstr size */
|
||||||
{
|
{
|
||||||
const dict_table_t* table = dict_table_get_low(req_schema->table_name);
|
const dict_table_t* table= dict_sys.load_table(req_schema->table_name);
|
||||||
|
|
||||||
if (!table) {
|
if (!table) {
|
||||||
if (req_schema == &table_stats_schema) {
|
if (req_schema == &table_stats_schema) {
|
||||||
|
@@ -47,6 +47,7 @@ Created 10/25/1995 Heikki Tuuri
|
|||||||
#include "buf0lru.h"
|
#include "buf0lru.h"
|
||||||
#include "ibuf0ibuf.h"
|
#include "ibuf0ibuf.h"
|
||||||
#include "buf0flu.h"
|
#include "buf0flu.h"
|
||||||
|
#include "log.h"
|
||||||
#ifdef UNIV_LINUX
|
#ifdef UNIV_LINUX
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# include <sys/sysmacros.h>
|
# include <sys/sysmacros.h>
|
||||||
@@ -2195,7 +2196,7 @@ statement to update the dictionary tables if they are incorrect.
|
|||||||
@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_TEMPORARY
|
@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_TEMPORARY
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@param[in] flags expected FSP_SPACE_FLAGS
|
@param[in] flags expected FSP_SPACE_FLAGS
|
||||||
@param[in] space_name tablespace name of the datafile
|
@param[in] name table name
|
||||||
If file-per-table, it is the table name in the databasename/tablename format
|
If file-per-table, it is the table name in the databasename/tablename format
|
||||||
@param[in] path_in expected filepath, usually read from dictionary
|
@param[in] path_in expected filepath, usually read from dictionary
|
||||||
@param[out] err DB_SUCCESS or error code
|
@param[out] err DB_SUCCESS or error code
|
||||||
@@ -2207,37 +2208,40 @@ fil_ibd_open(
|
|||||||
fil_type_t purpose,
|
fil_type_t purpose,
|
||||||
ulint id,
|
ulint id,
|
||||||
ulint flags,
|
ulint flags,
|
||||||
const table_name_t tablename,
|
fil_space_t::name_type name,
|
||||||
const char* path_in,
|
const char* path_in,
|
||||||
dberr_t* err)
|
dberr_t* err)
|
||||||
{
|
{
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
if (fil_space_t* space = fil_space_get_by_id(id)) {
|
fil_space_t* space = fil_space_get_by_id(id);
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
|
if (space) {
|
||||||
if (space && validate && !srv_read_only_mode) {
|
if (validate && !srv_read_only_mode) {
|
||||||
fsp_flags_try_adjust(space,
|
fsp_flags_try_adjust(space,
|
||||||
flags & ~FSP_FLAGS_MEM_MASK);
|
flags & ~FSP_FLAGS_MEM_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
return space;
|
return space;
|
||||||
}
|
}
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
|
||||||
|
dberr_t local_err = DB_SUCCESS;
|
||||||
|
|
||||||
|
/* Table flags can be ULINT_UNDEFINED if
|
||||||
|
dict_tf_to_fsp_flags_failure is set. */
|
||||||
|
if (flags == ULINT_UNDEFINED) {
|
||||||
|
corrupted:
|
||||||
|
local_err = DB_CORRUPTION;
|
||||||
|
func_exit:
|
||||||
|
if (err) *err = local_err;
|
||||||
|
return space;
|
||||||
|
}
|
||||||
|
|
||||||
|
ut_ad(fil_space_t::is_valid_flags(flags & ~FSP_FLAGS_MEM_MASK, id));
|
||||||
|
|
||||||
Datafile df_default; /* default location */
|
Datafile df_default; /* default location */
|
||||||
RemoteDatafile df_remote; /* remote location */
|
RemoteDatafile df_remote; /* remote location */
|
||||||
ulint tablespaces_found = 0;
|
ulint tablespaces_found = 0;
|
||||||
ulint valid_tablespaces_found = 0;
|
ulint valid_tablespaces_found = 0;
|
||||||
|
|
||||||
/* Table flags can be ULINT_UNDEFINED if
|
|
||||||
dict_tf_to_fsp_flags_failure is set. */
|
|
||||||
if (flags == ULINT_UNDEFINED) {
|
|
||||||
corrupted:
|
|
||||||
if (err) *err = DB_CORRUPTION;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(fil_space_t::is_valid_flags(flags & ~FSP_FLAGS_MEM_MASK, id));
|
|
||||||
df_default.init(flags);
|
df_default.init(flags);
|
||||||
df_remote.init(flags);
|
df_remote.init(flags);
|
||||||
|
|
||||||
@@ -2245,12 +2249,11 @@ corrupted:
|
|||||||
while avoiding unecessary effort. */
|
while avoiding unecessary effort. */
|
||||||
|
|
||||||
/* We will always look for an ibd in the default location. */
|
/* We will always look for an ibd in the default location. */
|
||||||
df_default.make_filepath(nullptr, {tablename.m_name,
|
df_default.make_filepath(nullptr, name, IBD);
|
||||||
strlen(tablename.m_name)}, IBD);
|
|
||||||
|
|
||||||
/* Look for a filepath embedded in an ISL where the default file
|
/* Look for a filepath embedded in an ISL where the default file
|
||||||
would be. */
|
would be. */
|
||||||
if (df_remote.open_link_file(tablename)) {
|
if (df_remote.open_link_file(name)) {
|
||||||
validate = true;
|
validate = true;
|
||||||
if (df_remote.open_read_only(true) == DB_SUCCESS) {
|
if (df_remote.open_read_only(true) == DB_SUCCESS) {
|
||||||
ut_ad(df_remote.is_open());
|
ut_ad(df_remote.is_open());
|
||||||
@@ -2314,8 +2317,10 @@ corrupted:
|
|||||||
First, bail out if no tablespace files were found. */
|
First, bail out if no tablespace files were found. */
|
||||||
if (valid_tablespaces_found == 0) {
|
if (valid_tablespaces_found == 0) {
|
||||||
os_file_get_last_error(true);
|
os_file_get_last_error(true);
|
||||||
ib::error() << "Could not find a valid tablespace file for `"
|
sql_print_error("InnoDB: Could not find a valid tablespace"
|
||||||
<< tablename << "`. " << TROUBLESHOOT_DATADICT_MSG;
|
" file for %.*s. %s",
|
||||||
|
static_cast<int>(name.size()), name.data(),
|
||||||
|
TROUBLESHOOT_DATADICT_MSG);
|
||||||
goto corrupted;
|
goto corrupted;
|
||||||
}
|
}
|
||||||
if (!validate) {
|
if (!validate) {
|
||||||
@@ -2324,22 +2329,19 @@ corrupted:
|
|||||||
|
|
||||||
/* Do not open any tablespaces if more than one tablespace with
|
/* Do not open any tablespaces if more than one tablespace with
|
||||||
the correct space ID and flags were found. */
|
the correct space ID and flags were found. */
|
||||||
if (tablespaces_found > 1) {
|
if (df_default.is_open() && df_remote.is_open()) {
|
||||||
ib::error() << "A tablespace for `" << tablename
|
ib::error()
|
||||||
<< "` has been found in multiple places;";
|
<< "A tablespace has been found in multiple places: "
|
||||||
|
<< df_default.filepath()
|
||||||
if (df_default.is_open()) {
|
<< "(Space ID=" << df_default.space_id()
|
||||||
ib::error() << "Default location: "
|
<< ", Flags=" << df_default.flags()
|
||||||
<< df_default.filepath()
|
<< ") and "
|
||||||
<< ", Space ID=" << df_default.space_id()
|
<< df_remote.filepath()
|
||||||
<< ", Flags=" << df_default.flags();
|
<< "(Space ID=" << df_remote.space_id()
|
||||||
}
|
<< ", Flags=" << df_remote.flags()
|
||||||
if (df_remote.is_open()) {
|
<< (valid_tablespaces_found > 1 || srv_force_recovery
|
||||||
ib::error() << "Remote location: "
|
? "); will not open"
|
||||||
<< df_remote.filepath()
|
: ")");
|
||||||
<< ", Space ID=" << df_remote.space_id()
|
|
||||||
<< ", Flags=" << df_remote.flags();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Force-recovery will allow some tablespaces to be
|
/* Force-recovery will allow some tablespaces to be
|
||||||
skipped by REDO if there was more than one file found.
|
skipped by REDO if there was more than one file found.
|
||||||
@@ -2349,9 +2351,6 @@ corrupted:
|
|||||||
recovery and there is only one good tablespace, ignore
|
recovery and there is only one good tablespace, ignore
|
||||||
any bad tablespaces. */
|
any bad tablespaces. */
|
||||||
if (valid_tablespaces_found > 1 || srv_force_recovery > 0) {
|
if (valid_tablespaces_found > 1 || srv_force_recovery > 0) {
|
||||||
ib::error() << "Will not open tablespace `"
|
|
||||||
<< tablename << "`";
|
|
||||||
|
|
||||||
/* If the file is not open it cannot be valid. */
|
/* If the file is not open it cannot be valid. */
|
||||||
ut_ad(df_default.is_open() || !df_default.is_valid());
|
ut_ad(df_default.is_open() || !df_default.is_valid());
|
||||||
ut_ad(df_remote.is_open() || !df_remote.is_valid());
|
ut_ad(df_remote.is_open() || !df_remote.is_valid());
|
||||||
@@ -2363,8 +2362,8 @@ corrupted:
|
|||||||
goto corrupted;
|
goto corrupted;
|
||||||
}
|
}
|
||||||
error:
|
error:
|
||||||
if (err) *err = DB_ERROR;
|
local_err = DB_ERROR;
|
||||||
return NULL;
|
goto func_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There is only one valid tablespace found and we did
|
/* There is only one valid tablespace found and we did
|
||||||
@@ -2395,8 +2394,7 @@ skip_validate:
|
|||||||
first_page)
|
first_page)
|
||||||
: NULL;
|
: NULL;
|
||||||
|
|
||||||
fil_space_t* space = fil_space_t::create(
|
space = fil_space_t::create(id, flags, purpose, crypt_data);
|
||||||
id, flags, purpose, crypt_data);
|
|
||||||
if (!space) {
|
if (!space) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@@ -2420,8 +2418,7 @@ skip_validate:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) *err = DB_SUCCESS;
|
goto func_exit;
|
||||||
return space;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Discover the correct IBD file to open given a remote or missing
|
/** Discover the correct IBD file to open given a remote or missing
|
||||||
@@ -2485,14 +2482,11 @@ fil_ibd_discover(
|
|||||||
case SRV_OPERATION_RESTORE:
|
case SRV_OPERATION_RESTORE:
|
||||||
break;
|
break;
|
||||||
case SRV_OPERATION_NORMAL:
|
case SRV_OPERATION_NORMAL:
|
||||||
char* name = const_cast<char*>(db);
|
size_t len= strlen(db);
|
||||||
size_t len= strlen(name);
|
if (len <= 4 || strcmp(db + len - 4, dot_ext[IBD])) {
|
||||||
if (len <= 4 || strcmp(name + len - 4, dot_ext[IBD])) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
name[len - 4] = '\0';
|
df_rem_per.open_link_file({db, len - 4});
|
||||||
df_rem_per.open_link_file(table_name_t{name});
|
|
||||||
name[len - 4] = *dot_ext[IBD];
|
|
||||||
|
|
||||||
if (!df_rem_per.filepath()) {
|
if (!df_rem_per.filepath()) {
|
||||||
break;
|
break;
|
||||||
|
@@ -837,7 +837,7 @@ open that file, and read the contents into m_filepath.
|
|||||||
@param name table name
|
@param name table name
|
||||||
@return filepath()
|
@return filepath()
|
||||||
@retval nullptr if the .isl file does not exist or cannot be read */
|
@retval nullptr if the .isl file does not exist or cannot be read */
|
||||||
const char *RemoteDatafile::open_link_file(const table_name_t &name)
|
const char *RemoteDatafile::open_link_file(const fil_space_t::name_type name)
|
||||||
{
|
{
|
||||||
if (!m_link_filepath)
|
if (!m_link_filepath)
|
||||||
m_link_filepath= fil_make_filepath(nullptr, name, ISL, false);
|
m_link_filepath= fil_make_filepath(nullptr, name, ISL, false);
|
||||||
|
@@ -34,7 +34,6 @@ Full Text Search interface
|
|||||||
#include "fts0types.ic"
|
#include "fts0types.ic"
|
||||||
#include "fts0vlc.ic"
|
#include "fts0vlc.ic"
|
||||||
#include "fts0plugin.h"
|
#include "fts0plugin.h"
|
||||||
#include "dict0priv.h"
|
|
||||||
#include "dict0stats.h"
|
#include "dict0stats.h"
|
||||||
#include "btr0pcur.h"
|
#include "btr0pcur.h"
|
||||||
|
|
||||||
@@ -1675,8 +1674,9 @@ fts_create_in_mem_aux_table(
|
|||||||
const dict_table_t* table,
|
const dict_table_t* table,
|
||||||
ulint n_cols)
|
ulint n_cols)
|
||||||
{
|
{
|
||||||
dict_table_t* new_table = dict_mem_table_create(
|
dict_table_t* new_table = dict_table_t::create(
|
||||||
aux_table_name, NULL, n_cols, 0, table->flags,
|
{aux_table_name,strlen(aux_table_name)},
|
||||||
|
nullptr, n_cols, 0, table->flags,
|
||||||
table->space_id == TRX_SYS_SPACE
|
table->space_id == TRX_SYS_SPACE
|
||||||
? 0 : table->space_id == SRV_TMP_SPACE_ID
|
? 0 : table->space_id == SRV_TMP_SPACE_ID
|
||||||
? DICT_TF2_TEMPORARY : DICT_TF2_USE_FILE_PER_TABLE);
|
? DICT_TF2_TEMPORARY : DICT_TF2_USE_FILE_PER_TABLE);
|
||||||
@@ -5645,7 +5645,8 @@ fts_valid_stopword_table(
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
table = dict_table_get_low(stopword_table_name);
|
table = dict_sys.load_table(
|
||||||
|
{stopword_table_name, strlen(stopword_table_name)});
|
||||||
|
|
||||||
if (!table) {
|
if (!table) {
|
||||||
ib::error() << "User stopword table " << stopword_table_name
|
ib::error() << "User stopword table " << stopword_table_name
|
||||||
|
@@ -2554,7 +2554,7 @@ void fts_optimize_add_table(dict_table_t* table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure table with FTS index cannot be evicted */
|
/* Make sure table with FTS index cannot be evicted */
|
||||||
dict_table_prevent_eviction(table);
|
dict_sys.prevent_eviction(table);
|
||||||
|
|
||||||
msg = fts_optimize_create_msg(FTS_MSG_ADD_TABLE, table);
|
msg = fts_optimize_create_msg(FTS_MSG_ADD_TABLE, table);
|
||||||
|
|
||||||
|
@@ -80,7 +80,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "btr0defragment.h"
|
#include "btr0defragment.h"
|
||||||
#include "dict0crea.h"
|
#include "dict0crea.h"
|
||||||
#include "dict0dict.h"
|
#include "dict0dict.h"
|
||||||
#include "dict0priv.h"
|
|
||||||
#include "dict0stats.h"
|
#include "dict0stats.h"
|
||||||
#include "dict0stats_bg.h"
|
#include "dict0stats_bg.h"
|
||||||
#include "fil0fil.h"
|
#include "fil0fil.h"
|
||||||
@@ -148,7 +147,6 @@ void close_thread_tables(THD* thd);
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
#include "dict0priv.h"
|
|
||||||
#include <mysql/service_md5.h>
|
#include <mysql/service_md5.h>
|
||||||
#include "wsrep_sst.h"
|
#include "wsrep_sst.h"
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
@@ -1277,7 +1275,7 @@ static ibool innodb_drop_database_ignore_fk(void*,void*) { return false; }
|
|||||||
struct innodb_drop_database_fk_report
|
struct innodb_drop_database_fk_report
|
||||||
{
|
{
|
||||||
/** database name, with trailing '/' */
|
/** database name, with trailing '/' */
|
||||||
const st_::span<char> name;
|
const span<const char> name;
|
||||||
/** whether errors were found */
|
/** whether errors were found */
|
||||||
bool violated;
|
bool violated;
|
||||||
};
|
};
|
||||||
@@ -9798,8 +9796,11 @@ wsrep_append_foreign_key(
|
|||||||
|
|
||||||
if (referenced) {
|
if (referenced) {
|
||||||
foreign->referenced_table =
|
foreign->referenced_table =
|
||||||
dict_table_get_low(
|
dict_sys.load_table(
|
||||||
foreign->referenced_table_name_lookup);
|
{foreign->referenced_table_name_lookup,
|
||||||
|
strlen(foreign->
|
||||||
|
referenced_table_name_lookup)
|
||||||
|
});
|
||||||
if (foreign->referenced_table) {
|
if (foreign->referenced_table) {
|
||||||
foreign->referenced_index =
|
foreign->referenced_index =
|
||||||
dict_foreign_find_index(
|
dict_foreign_find_index(
|
||||||
@@ -9811,8 +9812,10 @@ wsrep_append_foreign_key(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
foreign->foreign_table =
|
foreign->foreign_table =
|
||||||
dict_table_get_low(
|
dict_sys.load_table(
|
||||||
foreign->foreign_table_name_lookup);
|
{foreign->foreign_table_name_lookup,
|
||||||
|
strlen(foreign->
|
||||||
|
foreign_table_name_lookup)});
|
||||||
|
|
||||||
if (foreign->foreign_table) {
|
if (foreign->foreign_table) {
|
||||||
foreign->foreign_index =
|
foreign->foreign_index =
|
||||||
@@ -10478,8 +10481,8 @@ create_table_info_t::create_table_def()
|
|||||||
const ulint actual_n_cols = n_cols
|
const ulint actual_n_cols = n_cols
|
||||||
+ (m_flags2 & DICT_TF2_FTS && !has_doc_id_col);
|
+ (m_flags2 & DICT_TF2_FTS && !has_doc_id_col);
|
||||||
|
|
||||||
table = dict_mem_table_create(m_table_name, NULL,
|
table = dict_table_t::create({m_table_name,table_name_len}, nullptr,
|
||||||
actual_n_cols, num_v, m_flags, m_flags2);
|
actual_n_cols, num_v, m_flags, m_flags2);
|
||||||
|
|
||||||
/* Set the hidden doc_id column. */
|
/* Set the hidden doc_id column. */
|
||||||
if (m_flags2 & DICT_TF2_FTS) {
|
if (m_flags2 & DICT_TF2_FTS) {
|
||||||
@@ -10696,7 +10699,7 @@ err_col:
|
|||||||
"temporary table creation.");
|
"temporary table creation.");
|
||||||
}
|
}
|
||||||
|
|
||||||
table->id = dict_sys.get_temporary_table_id();
|
table->id = dict_sys.acquire_temporary_table_id();
|
||||||
ut_ad(dict_tf_get_rec_format(table->flags)
|
ut_ad(dict_tf_get_rec_format(table->flags)
|
||||||
!= REC_FORMAT_COMPRESSED);
|
!= REC_FORMAT_COMPRESSED);
|
||||||
table->space_id = SRV_TMP_SPACE_ID;
|
table->space_id = SRV_TMP_SPACE_ID;
|
||||||
@@ -12140,7 +12143,7 @@ create_table_info_t::create_foreign_keys()
|
|||||||
ut_ad(alter_info);
|
ut_ad(alter_info);
|
||||||
List_iterator_fast<Key> key_it(alter_info->key_list);
|
List_iterator_fast<Key> key_it(alter_info->key_list);
|
||||||
|
|
||||||
dict_table_t* table = dict_table_get_low(name);
|
dict_table_t* table = dict_sys.find_table({name,strlen(name)});
|
||||||
if (!table) {
|
if (!table) {
|
||||||
ib_foreign_warn(m_trx, DB_CANNOT_ADD_CONSTRAINT, create_name,
|
ib_foreign_warn(m_trx, DB_CANNOT_ADD_CONSTRAINT, create_name,
|
||||||
"%s table %s foreign key constraint"
|
"%s table %s foreign key constraint"
|
||||||
@@ -12630,13 +12633,12 @@ int create_table_info_t::create_table(bool create_fk)
|
|||||||
if (err == DB_SUCCESS) {
|
if (err == DB_SUCCESS) {
|
||||||
/* Check that also referencing constraints are ok */
|
/* Check that also referencing constraints are ok */
|
||||||
dict_names_t fk_tables;
|
dict_names_t fk_tables;
|
||||||
err = dict_load_foreigns(m_table_name, NULL,
|
err = dict_load_foreigns(m_table_name, NULL, false, true,
|
||||||
false, true,
|
DICT_ERR_IGNORE_NONE, fk_tables);
|
||||||
DICT_ERR_IGNORE_NONE,
|
|
||||||
fk_tables);
|
|
||||||
while (err == DB_SUCCESS && !fk_tables.empty()) {
|
while (err == DB_SUCCESS && !fk_tables.empty()) {
|
||||||
dict_load_table(fk_tables.front(),
|
dict_sys.load_table(
|
||||||
DICT_ERR_IGNORE_NONE);
|
{fk_tables.front(), strlen(fk_tables.front())},
|
||||||
|
DICT_ERR_IGNORE_NONE);
|
||||||
fk_tables.pop_front();
|
fk_tables.pop_front();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -35,7 +35,7 @@ Smart ALTER TABLE
|
|||||||
#include "btr0sea.h"
|
#include "btr0sea.h"
|
||||||
#include "dict0crea.h"
|
#include "dict0crea.h"
|
||||||
#include "dict0dict.h"
|
#include "dict0dict.h"
|
||||||
#include "dict0priv.h"
|
#include "dict0load.h"
|
||||||
#include "dict0stats.h"
|
#include "dict0stats.h"
|
||||||
#include "dict0stats_bg.h"
|
#include "dict0stats_bg.h"
|
||||||
#include "log0log.h"
|
#include "log0log.h"
|
||||||
@@ -56,11 +56,9 @@ Smart ALTER TABLE
|
|||||||
#include "row0sel.h"
|
#include "row0sel.h"
|
||||||
#include "ha_innodb.h"
|
#include "ha_innodb.h"
|
||||||
#include "ut0stage.h"
|
#include "ut0stage.h"
|
||||||
#include "span.h"
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
using st_::span;
|
|
||||||
/** File format constraint for ALTER TABLE */
|
/** File format constraint for ALTER TABLE */
|
||||||
extern ulong innodb_instant_alter_column_allowed;
|
extern ulong innodb_instant_alter_column_allowed;
|
||||||
|
|
||||||
@@ -2054,6 +2052,12 @@ ha_innobase::check_if_supported_inplace_alter(
|
|||||||
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
|
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dict_sys.sys_tables_exist()) {
|
||||||
|
ha_alter_info->unsupported_reason
|
||||||
|
= "missing InnoDB system tables";
|
||||||
|
DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
/* Only support online add foreign key constraint when
|
/* Only support online add foreign key constraint when
|
||||||
check_foreigns is turned off */
|
check_foreigns is turned off */
|
||||||
if ((ha_alter_info->handler_flags & ALTER_ADD_FOREIGN_KEY)
|
if ((ha_alter_info->handler_flags & ALTER_ADD_FOREIGN_KEY)
|
||||||
@@ -6397,9 +6401,9 @@ new_clustered_failed:
|
|||||||
|
|
||||||
DBUG_ASSERT(!add_fts_doc_id_idx || (flags2 & DICT_TF2_FTS));
|
DBUG_ASSERT(!add_fts_doc_id_idx || (flags2 & DICT_TF2_FTS));
|
||||||
|
|
||||||
ctx->new_table = dict_mem_table_create(
|
ctx->new_table = dict_table_t::create(
|
||||||
new_table_name, NULL, n_cols + n_v_cols, n_v_cols,
|
{new_table_name, tablen + partlen}, nullptr,
|
||||||
flags, flags2);
|
n_cols + n_v_cols, n_v_cols, flags, flags2);
|
||||||
|
|
||||||
/* The rebuilt indexed_table will use the renamed
|
/* The rebuilt indexed_table will use the renamed
|
||||||
column names. */
|
column names. */
|
||||||
@@ -6796,7 +6800,9 @@ wrong_column_name:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dict_table_get_low(ctx->new_table->name.m_name)) {
|
if (dict_sys.find_table(
|
||||||
|
{ctx->new_table->name.m_name,
|
||||||
|
strlen(ctx->new_table->name.m_name)})) {
|
||||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0),
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0),
|
||||||
ctx->new_table->name.m_name);
|
ctx->new_table->name.m_name);
|
||||||
goto new_clustered_failed;
|
goto new_clustered_failed;
|
||||||
@@ -9731,17 +9737,14 @@ innobase_update_foreign_cache(
|
|||||||
/* For complete loading of foreign keys, all associated tables must
|
/* For complete loading of foreign keys, all associated tables must
|
||||||
also be loaded. */
|
also be loaded. */
|
||||||
while (err == DB_SUCCESS && !fk_tables.empty()) {
|
while (err == DB_SUCCESS && !fk_tables.empty()) {
|
||||||
dict_table_t* table = dict_load_table(
|
const char *f = fk_tables.front();
|
||||||
fk_tables.front(), DICT_ERR_IGNORE_NONE);
|
if (!dict_sys.load_table({f, strlen(f)})) {
|
||||||
|
|
||||||
if (table == NULL) {
|
|
||||||
err = DB_TABLE_NOT_FOUND;
|
err = DB_TABLE_NOT_FOUND;
|
||||||
ib::error()
|
ib::error()
|
||||||
<< "Failed to load table '"
|
<< "Failed to load table "
|
||||||
<< table_name_t(const_cast<char*>
|
<< table_name_t(const_cast<char*>(f))
|
||||||
(fk_tables.front()))
|
<< " which has a foreign key constraint with"
|
||||||
<< "' which has a foreign key constraint with"
|
<< user_table->name;
|
||||||
<< " table '" << user_table->name << "'.";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4820,6 +4820,41 @@ i_s_dict_fill_sys_tables(
|
|||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Convert one SYS_TABLES record to dict_table_t.
|
||||||
|
@param pcur persistent cursor position on SYS_TABLES record
|
||||||
|
@param rec record to read from (nullptr=use the dict_sys cache)
|
||||||
|
@param table the converted dict_table_t
|
||||||
|
@return error message
|
||||||
|
@retval nullptr on success */
|
||||||
|
static const char *i_s_sys_tables_rec(const btr_pcur_t &pcur, const rec_t *rec,
|
||||||
|
dict_table_t **table)
|
||||||
|
{
|
||||||
|
static_assert(DICT_FLD__SYS_TABLES__NAME == 0, "compatibility");
|
||||||
|
size_t len;
|
||||||
|
if (rec_get_1byte_offs_flag(pcur.old_rec))
|
||||||
|
{
|
||||||
|
len= rec_1_get_field_end_info(pcur.old_rec, 0);
|
||||||
|
if (len & REC_1BYTE_SQL_NULL_MASK)
|
||||||
|
return "corrupted SYS_TABLES.NAME";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
len= rec_2_get_field_end_info(pcur.old_rec, 0);
|
||||||
|
static_assert(REC_2BYTE_EXTERN_MASK == 16384, "compatibility");
|
||||||
|
if (len >= REC_2BYTE_EXTERN_MASK)
|
||||||
|
return "corrupted SYS_TABLES.NAME";
|
||||||
|
}
|
||||||
|
|
||||||
|
const span<const char>name{reinterpret_cast<const char*>(pcur.old_rec), len};
|
||||||
|
|
||||||
|
if (rec)
|
||||||
|
return dict_load_table_low(name, rec, table);
|
||||||
|
|
||||||
|
*table= dict_sys.load_table(name);
|
||||||
|
return *table ? nullptr : "Table not found in cache";
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************//**
|
/*******************************************************************//**
|
||||||
Function to go through each record in SYS_TABLES table, and fill the
|
Function to go through each record in SYS_TABLES table, and fill the
|
||||||
information_schema.innodb_sys_tables table with related table information
|
information_schema.innodb_sys_tables table with related table information
|
||||||
@@ -4833,8 +4868,6 @@ i_s_sys_tables_fill_table(
|
|||||||
Item* ) /*!< in: condition (not used) */
|
Item* ) /*!< in: condition (not used) */
|
||||||
{
|
{
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
const rec_t* rec;
|
|
||||||
mem_heap_t* heap;
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
DBUG_ENTER("i_s_sys_tables_fill_table");
|
DBUG_ENTER("i_s_sys_tables_fill_table");
|
||||||
@@ -4845,21 +4878,23 @@ i_s_sys_tables_fill_table(
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
heap = mem_heap_create(1000);
|
|
||||||
dict_sys.mutex_lock();
|
dict_sys.mutex_lock();
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
|
for (const rec_t *rec = dict_startscan_system(&pcur, &mtr,
|
||||||
|
dict_sys.sys_tables);
|
||||||
|
rec; rec = dict_getnext_system(&pcur, &mtr)) {
|
||||||
|
if (rec_get_deleted_flag(rec, 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
while (rec) {
|
|
||||||
const char* err_msg;
|
const char* err_msg;
|
||||||
dict_table_t* table_rec;
|
dict_table_t* table_rec;
|
||||||
|
|
||||||
/* Create and populate a dict_table_t structure with
|
/* Create and populate a dict_table_t structure with
|
||||||
information from SYS_TABLES row */
|
information from SYS_TABLES row */
|
||||||
err_msg = dict_process_sys_tables_rec_and_mtr_commit(
|
err_msg = i_s_sys_tables_rec(pcur, rec, &table_rec);
|
||||||
heap, rec, &table_rec, false, &mtr);
|
mtr.commit();
|
||||||
|
|
||||||
dict_sys.mutex_unlock();
|
dict_sys.mutex_unlock();
|
||||||
|
|
||||||
if (!err_msg) {
|
if (!err_msg) {
|
||||||
@@ -4875,17 +4910,13 @@ i_s_sys_tables_fill_table(
|
|||||||
dict_mem_table_free(table_rec);
|
dict_mem_table_free(table_rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_heap_empty(heap);
|
|
||||||
|
|
||||||
/* Get the next record */
|
/* Get the next record */
|
||||||
dict_sys.mutex_lock();
|
dict_sys.mutex_lock();
|
||||||
mtr_start(&mtr);
|
mtr.start();
|
||||||
rec = dict_getnext_system(&pcur, &mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr_commit(&mtr);
|
mtr.commit();
|
||||||
dict_sys.mutex_unlock();
|
dict_sys.mutex_unlock();
|
||||||
mem_heap_free(heap);
|
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@@ -5078,7 +5109,6 @@ i_s_sys_tables_fill_table_stats(
|
|||||||
{
|
{
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
const rec_t* rec;
|
const rec_t* rec;
|
||||||
mem_heap_t* heap;
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
DBUG_ENTER("i_s_sys_tables_fill_table_stats");
|
DBUG_ENTER("i_s_sys_tables_fill_table_stats");
|
||||||
@@ -5089,30 +5119,24 @@ i_s_sys_tables_fill_table_stats(
|
|||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
heap = mem_heap_create(1000);
|
|
||||||
dict_sys.freeze();
|
dict_sys.freeze();
|
||||||
dict_sys.mutex_lock();
|
dict_sys.mutex_lock();
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
rec = dict_startscan_system(&pcur, &mtr, SYS_TABLES);
|
rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_tables);
|
||||||
|
|
||||||
while (rec) {
|
while (rec) {
|
||||||
const char* err_msg;
|
const char* err_msg;
|
||||||
dict_table_t* table_rec;
|
dict_table_t* table_rec;
|
||||||
|
|
||||||
|
mtr.commit();
|
||||||
/* Fetch the dict_table_t structure corresponding to
|
/* Fetch the dict_table_t structure corresponding to
|
||||||
this SYS_TABLES record */
|
this SYS_TABLES record */
|
||||||
err_msg = dict_process_sys_tables_rec_and_mtr_commit(
|
err_msg = i_s_sys_tables_rec(pcur, nullptr, &table_rec);
|
||||||
heap, rec, &table_rec, true, &mtr);
|
|
||||||
|
|
||||||
ulint ref_count = table_rec ? table_rec->get_ref_count() : 0;
|
ulint ref_count = table_rec ? table_rec->get_ref_count() : 0;
|
||||||
dict_sys.mutex_unlock();
|
dict_sys.mutex_unlock();
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("test_sys_tablestats", {
|
|
||||||
if (strcmp("test/t1", table_rec->name.m_name) == 0 ) {
|
|
||||||
DEBUG_SYNC_C("dict_table_not_protected");
|
|
||||||
}});
|
|
||||||
|
|
||||||
if (table_rec != NULL) {
|
if (table_rec != NULL) {
|
||||||
ut_ad(err_msg == NULL);
|
ut_ad(err_msg == NULL);
|
||||||
i_s_dict_fill_sys_tablestats(thd, table_rec, ref_count,
|
i_s_dict_fill_sys_tablestats(thd, table_rec, ref_count,
|
||||||
@@ -5125,7 +5149,6 @@ i_s_sys_tables_fill_table_stats(
|
|||||||
}
|
}
|
||||||
|
|
||||||
dict_sys.unfreeze();
|
dict_sys.unfreeze();
|
||||||
mem_heap_empty(heap);
|
|
||||||
|
|
||||||
/* Get the next record */
|
/* Get the next record */
|
||||||
dict_sys.freeze();
|
dict_sys.freeze();
|
||||||
@@ -5138,7 +5161,6 @@ i_s_sys_tables_fill_table_stats(
|
|||||||
mtr_commit(&mtr);
|
mtr_commit(&mtr);
|
||||||
dict_sys.mutex_unlock();
|
dict_sys.mutex_unlock();
|
||||||
dict_sys.unfreeze();
|
dict_sys.unfreeze();
|
||||||
mem_heap_free(heap);
|
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
@@ -5335,7 +5357,7 @@ i_s_sys_indexes_fill_table(
|
|||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
/* Start scan the SYS_INDEXES table */
|
/* Start scan the SYS_INDEXES table */
|
||||||
rec = dict_startscan_system(&pcur, &mtr, SYS_INDEXES);
|
rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_indexes);
|
||||||
|
|
||||||
/* Process each record in the table */
|
/* Process each record in the table */
|
||||||
while (rec) {
|
while (rec) {
|
||||||
@@ -5553,7 +5575,7 @@ i_s_sys_columns_fill_table(
|
|||||||
dict_sys.mutex_lock();
|
dict_sys.mutex_lock();
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
rec = dict_startscan_system(&pcur, &mtr, SYS_COLUMNS);
|
rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_columns);
|
||||||
|
|
||||||
while (rec) {
|
while (rec) {
|
||||||
const char* err_msg;
|
const char* err_msg;
|
||||||
@@ -5739,14 +5761,14 @@ i_s_sys_virtual_fill_table(
|
|||||||
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
|
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
|
||||||
|
|
||||||
/* deny access to user without PROCESS_ACL privilege */
|
/* deny access to user without PROCESS_ACL privilege */
|
||||||
if (check_global_access(thd, PROCESS_ACL)) {
|
if (check_global_access(thd, PROCESS_ACL) || !dict_sys.sys_virtual) {
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
dict_sys.mutex_lock();
|
dict_sys.mutex_lock();
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
rec = dict_startscan_system(&pcur, &mtr, SYS_VIRTUAL);
|
rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_virtual);
|
||||||
|
|
||||||
while (rec) {
|
while (rec) {
|
||||||
const char* err_msg;
|
const char* err_msg;
|
||||||
@@ -5936,7 +5958,7 @@ i_s_sys_fields_fill_table(
|
|||||||
the next index. This is used to calculate prefix length */
|
the next index. This is used to calculate prefix length */
|
||||||
last_id = 0;
|
last_id = 0;
|
||||||
|
|
||||||
rec = dict_startscan_system(&pcur, &mtr, SYS_FIELDS);
|
rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_fields);
|
||||||
|
|
||||||
while (rec) {
|
while (rec) {
|
||||||
ulint pos;
|
ulint pos;
|
||||||
@@ -6127,8 +6149,7 @@ i_s_sys_foreign_fill_table(
|
|||||||
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
|
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
|
||||||
|
|
||||||
/* deny access to user without PROCESS_ACL privilege */
|
/* deny access to user without PROCESS_ACL privilege */
|
||||||
if (check_global_access(thd, PROCESS_ACL)) {
|
if (check_global_access(thd, PROCESS_ACL) || !dict_sys.sys_foreign) {
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6136,7 +6157,7 @@ i_s_sys_foreign_fill_table(
|
|||||||
dict_sys.mutex_lock();
|
dict_sys.mutex_lock();
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN);
|
rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_foreign);
|
||||||
|
|
||||||
while (rec) {
|
while (rec) {
|
||||||
const char* err_msg;
|
const char* err_msg;
|
||||||
@@ -6320,7 +6341,8 @@ i_s_sys_foreign_cols_fill_table(
|
|||||||
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
|
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name.str);
|
||||||
|
|
||||||
/* deny access to user without PROCESS_ACL privilege */
|
/* deny access to user without PROCESS_ACL privilege */
|
||||||
if (check_global_access(thd, PROCESS_ACL)) {
|
if (check_global_access(thd, PROCESS_ACL)
|
||||||
|
|| !dict_sys.sys_foreign_cols) {
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6328,7 +6350,7 @@ i_s_sys_foreign_cols_fill_table(
|
|||||||
dict_sys.mutex_lock();
|
dict_sys.mutex_lock();
|
||||||
mtr_start(&mtr);
|
mtr_start(&mtr);
|
||||||
|
|
||||||
rec = dict_startscan_system(&pcur, &mtr, SYS_FOREIGN_COLS);
|
rec = dict_startscan_system(&pcur, &mtr, dict_sys.sys_foreign_cols);
|
||||||
|
|
||||||
while (rec) {
|
while (rec) {
|
||||||
const char* err_msg;
|
const char* err_msg;
|
||||||
|
@@ -455,8 +455,9 @@ ibuf_init_at_db_start(void)
|
|||||||
mtr.commit();
|
mtr.commit();
|
||||||
|
|
||||||
ibuf.index = dict_mem_index_create(
|
ibuf.index = dict_mem_index_create(
|
||||||
dict_mem_table_create("innodb_change_buffer",
|
dict_table_t::create(
|
||||||
fil_system.sys_space, 1, 0, 0, 0),
|
{C_STRING_WITH_LEN("innodb_change_buffer")},
|
||||||
|
fil_system.sys_space, 1, 0, 0, 0),
|
||||||
"CLUST_IND",
|
"CLUST_IND",
|
||||||
DICT_CLUSTERED | DICT_IBUF, 1);
|
DICT_CLUSTERED | DICT_IBUF, 1);
|
||||||
ibuf.index->id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID;
|
ibuf.index->id = DICT_IBUF_ID_MIN + IBUF_SPACE_ID;
|
||||||
@@ -1266,8 +1267,9 @@ ibuf_dummy_index_create(
|
|||||||
dict_table_t* table;
|
dict_table_t* table;
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
|
|
||||||
table = dict_mem_table_create("IBUF_DUMMY", NULL, n, 0,
|
table = dict_table_t::create({C_STRING_WITH_LEN("IBUF_DUMMY")},
|
||||||
comp ? DICT_TF_COMPACT : 0, 0);
|
nullptr, n, 0,
|
||||||
|
comp ? DICT_TF_COMPACT : 0, 0);
|
||||||
|
|
||||||
index = dict_mem_index_create(table, "IBUF_DUMMY", 0, n);
|
index = dict_mem_index_create(table, "IBUF_DUMMY", 0, n);
|
||||||
|
|
||||||
|
@@ -117,15 +117,6 @@ dict_create_index_tree_in_mem(
|
|||||||
dict_index_t* index, /*!< in/out: index */
|
dict_index_t* index, /*!< in/out: index */
|
||||||
const trx_t* trx); /*!< in: InnoDB transaction handle */
|
const trx_t* trx); /*!< in: InnoDB transaction handle */
|
||||||
|
|
||||||
/****************************************************************//**
|
|
||||||
Creates the foreign key constraints system tables inside InnoDB
|
|
||||||
at server bootstrap or server start if they are not found or are
|
|
||||||
not of the right form.
|
|
||||||
@return DB_SUCCESS or error code */
|
|
||||||
dberr_t
|
|
||||||
dict_create_or_check_foreign_constraint_tables(void);
|
|
||||||
/*================================================*/
|
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Generate a foreign key constraint name when it was not named by the user.
|
Generate a foreign key constraint name when it was not named by the user.
|
||||||
A generated constraint has a name of the format dbname/tablename_ibfk_NUMBER,
|
A generated constraint has a name of the format dbname/tablename_ibfk_NUMBER,
|
||||||
@@ -171,13 +162,6 @@ dict_foreigns_has_s_base_col(
|
|||||||
const dict_foreign_set& local_fk_set,
|
const dict_foreign_set& local_fk_set,
|
||||||
const dict_table_t* table);
|
const dict_table_t* table);
|
||||||
|
|
||||||
/** Creates the virtual column system tables inside InnoDB
|
|
||||||
at server bootstrap or server start if they are not found or are
|
|
||||||
not of the right form.
|
|
||||||
@return DB_SUCCESS or error code */
|
|
||||||
dberr_t
|
|
||||||
dict_create_or_check_sys_virtual();
|
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Add a foreign key definition to the data dictionary tables.
|
Add a foreign key definition to the data dictionary tables.
|
||||||
@return error code or DB_SUCCESS */
|
@return error code or DB_SUCCESS */
|
||||||
|
@@ -1373,23 +1373,48 @@ class dict_sys_t
|
|||||||
FIXME: merge the mutex and the latch, once MDEV-23484 has been fixed */
|
FIXME: merge the mutex and the latch, once MDEV-23484 has been fixed */
|
||||||
mysql_mutex_t mutex;
|
mysql_mutex_t mutex;
|
||||||
public:
|
public:
|
||||||
hash_table_t table_hash; /*!< hash table of the tables, based
|
/** Indexes of SYS_TABLE[] */
|
||||||
on name */
|
enum
|
||||||
/** hash table of persistent table IDs */
|
{
|
||||||
hash_table_t table_id_hash;
|
SYS_TABLES= 0,
|
||||||
dict_table_t* sys_tables; /*!< SYS_TABLES table */
|
SYS_INDEXES,
|
||||||
dict_table_t* sys_columns; /*!< SYS_COLUMNS table */
|
SYS_COLUMNS,
|
||||||
dict_table_t* sys_indexes; /*!< SYS_INDEXES table */
|
SYS_FIELDS,
|
||||||
dict_table_t* sys_fields; /*!< SYS_FIELDS table */
|
SYS_FOREIGN,
|
||||||
dict_table_t* sys_virtual; /*!< SYS_VIRTUAL table */
|
SYS_FOREIGN_COLS,
|
||||||
|
SYS_VIRTUAL
|
||||||
|
};
|
||||||
|
/** System table names */
|
||||||
|
static const span<const char> SYS_TABLE[];
|
||||||
|
|
||||||
/*=============================*/
|
/** all tables (persistent and temporary), hashed by name */
|
||||||
UT_LIST_BASE_NODE_T(dict_table_t)
|
hash_table_t table_hash;
|
||||||
table_LRU; /*!< List of tables that can be evicted
|
/** hash table of persistent table IDs */
|
||||||
from the cache */
|
hash_table_t table_id_hash;
|
||||||
UT_LIST_BASE_NODE_T(dict_table_t)
|
|
||||||
table_non_LRU; /*!< List of tables that can't be
|
/** the SYS_TABLES table */
|
||||||
evicted from the cache */
|
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:
|
private:
|
||||||
bool m_initialised= false;
|
bool m_initialised= false;
|
||||||
@@ -1418,46 +1443,47 @@ public:
|
|||||||
row_id= ut_uint64_align_up(id, ROW_ID_WRITE_MARGIN) + ROW_ID_WRITE_MARGIN;
|
row_id= ut_uint64_align_up(id, ROW_ID_WRITE_MARGIN) + ROW_ID_WRITE_MARGIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return a new temporary table ID */
|
/** @return a new temporary table ID */
|
||||||
table_id_t get_temporary_table_id() {
|
table_id_t acquire_temporary_table_id()
|
||||||
return temp_table_id.fetch_add(1, std::memory_order_relaxed);
|
{
|
||||||
}
|
return temp_table_id.fetch_add(1, std::memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
/** Look up a temporary table.
|
/** Look up a temporary table.
|
||||||
@param id temporary table ID
|
@param id temporary table ID
|
||||||
@return temporary table
|
@return temporary table
|
||||||
@retval NULL if the table does not exist
|
@retval nullptr if the table does not exist
|
||||||
(should only happen during the rollback of CREATE...SELECT) */
|
(should only happen during the rollback of CREATE...SELECT) */
|
||||||
dict_table_t* get_temporary_table(table_id_t id)
|
dict_table_t *acquire_temporary_table(table_id_t id)
|
||||||
{
|
{
|
||||||
mysql_mutex_assert_owner(&mutex);
|
mysql_mutex_assert_owner(&mutex);
|
||||||
dict_table_t* table;
|
dict_table_t *table;
|
||||||
ulint fold = ut_fold_ull(id);
|
ulint fold = ut_fold_ull(id);
|
||||||
HASH_SEARCH(id_hash, &temp_id_hash, fold, dict_table_t*, table,
|
HASH_SEARCH(id_hash, &temp_id_hash, fold, dict_table_t*, table,
|
||||||
ut_ad(table->cached), table->id == id);
|
ut_ad(table->cached), table->id == id);
|
||||||
if (UNIV_LIKELY(table != NULL)) {
|
if (UNIV_LIKELY(table != nullptr))
|
||||||
DBUG_ASSERT(table->is_temporary());
|
{
|
||||||
DBUG_ASSERT(table->id >= DICT_HDR_FIRST_ID);
|
DBUG_ASSERT(table->is_temporary());
|
||||||
table->acquire();
|
DBUG_ASSERT(table->id >= DICT_HDR_FIRST_ID);
|
||||||
}
|
table->acquire();
|
||||||
return table;
|
}
|
||||||
}
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
/** Look up a persistent table.
|
/** Look up a persistent table.
|
||||||
@param id table ID
|
@param id table ID
|
||||||
@return table
|
@return table
|
||||||
@retval NULL if not cached */
|
@retval nullptr if not cached */
|
||||||
dict_table_t* get_table(table_id_t id)
|
dict_table_t *find_table(table_id_t id)
|
||||||
{
|
{
|
||||||
mysql_mutex_assert_owner(&mutex);
|
mysql_mutex_assert_owner(&mutex);
|
||||||
dict_table_t* table;
|
dict_table_t *table;
|
||||||
ulint fold = ut_fold_ull(id);
|
ulint fold = ut_fold_ull(id);
|
||||||
HASH_SEARCH(id_hash, &table_id_hash, fold, dict_table_t*,
|
HASH_SEARCH(id_hash, &table_id_hash, fold, dict_table_t*, table,
|
||||||
table,
|
ut_ad(table->cached), table->id == id);
|
||||||
ut_ad(table->cached), table->id == id);
|
DBUG_ASSERT(!table || !table->is_temporary());
|
||||||
DBUG_ASSERT(!table || !table->is_temporary());
|
return table;
|
||||||
return table;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool is_initialised() const { return m_initialised; }
|
bool is_initialised() const { return m_initialised; }
|
||||||
|
|
||||||
@@ -1480,14 +1506,13 @@ public:
|
|||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
/** Find a table */
|
/** 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);
|
||||||
ut_ad(table->can_be_evicted == in_lru);
|
ut_ad(table->can_be_evicted == in_lru);
|
||||||
mysql_mutex_assert_owner(&mutex);
|
mysql_mutex_assert_owner(&mutex);
|
||||||
for (const dict_table_t* t = UT_LIST_GET_FIRST(in_lru
|
for (const dict_table_t* t= in_lru ? table_LRU.start : table_non_LRU.start;
|
||||||
? table_LRU : table_non_LRU);
|
t; t = UT_LIST_GET_NEXT(table_LRU, t))
|
||||||
t; t = UT_LIST_GET_NEXT(table_LRU, t))
|
|
||||||
{
|
{
|
||||||
if (t == table) return true;
|
if (t == table) return true;
|
||||||
ut_ad(t->can_be_evicted == in_lru);
|
ut_ad(t->can_be_evicted == in_lru);
|
||||||
@@ -1495,25 +1520,25 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/** Find a table */
|
/** 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);
|
return table->can_be_evicted ? find<true>(table) : find<false>(table);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Move a table to the non-LRU list from the LRU list. */
|
/** 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_ad(find(table));
|
ut_ad(find(table));
|
||||||
if (table->can_be_evicted)
|
if (table->can_be_evicted)
|
||||||
{
|
{
|
||||||
table->can_be_evicted = FALSE;
|
table->can_be_evicted= false;
|
||||||
UT_LIST_REMOVE(table_LRU, table);
|
UT_LIST_REMOVE(table_LRU, table);
|
||||||
UT_LIST_ADD_LAST(table_non_LRU, table);
|
UT_LIST_ADD_LAST(table_non_LRU, table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** Acquire a reference to a cached table. */
|
/** Acquire a reference to a cached table. */
|
||||||
inline void acquire(dict_table_t* table);
|
inline void acquire(dict_table_t *table);
|
||||||
|
|
||||||
/** Assert that the mutex is locked */
|
/** Assert that the mutex is locked */
|
||||||
void assert_locked() const { mysql_mutex_assert_owner(&mutex); }
|
void assert_locked() const { mysql_mutex_assert_owner(&mutex); }
|
||||||
@@ -1573,8 +1598,8 @@ public:
|
|||||||
+ (sizeof(dict_col_t) + sizeof(dict_field_t)) * 10
|
+ (sizeof(dict_col_t) + sizeof(dict_field_t)) * 10
|
||||||
+ sizeof(dict_field_t) * 5 /* total number of key fields */
|
+ sizeof(dict_field_t) * 5 /* total number of key fields */
|
||||||
+ 200; /* arbitrary, covering names and overhead */
|
+ 200; /* arbitrary, covering names and overhead */
|
||||||
size += (table_hash.n_cells + table_id_hash.n_cells
|
size += (table_hash.n_cells + table_id_hash.n_cells +
|
||||||
+ temp_id_hash.n_cells) * sizeof(hash_cell_t);
|
temp_id_hash.n_cells) * sizeof(hash_cell_t);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1582,12 +1607,43 @@ public:
|
|||||||
@param half whether to consider half the tables only (instead of all)
|
@param half whether to consider half the tables only (instead of all)
|
||||||
@return number of tables evicted */
|
@return number of tables evicted */
|
||||||
ulint evict_table_LRU(bool half);
|
ulint evict_table_LRU(bool half);
|
||||||
|
|
||||||
|
/** 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
|
||||||
|
{
|
||||||
|
assert_locked();
|
||||||
|
for (dict_table_t *table= static_cast<dict_table_t*>
|
||||||
|
(HASH_GET_FIRST(&table_hash, table_hash.calc_hash
|
||||||
|
(ut_fold_binary(reinterpret_cast<const byte*>
|
||||||
|
(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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();
|
||||||
};
|
};
|
||||||
|
|
||||||
/** the data dictionary cache */
|
/** the data dictionary cache */
|
||||||
extern dict_sys_t dict_sys;
|
extern dict_sys_t dict_sys;
|
||||||
|
|
||||||
#define dict_table_prevent_eviction(table) dict_sys.prevent_eviction(table)
|
|
||||||
#define dict_sys_lock() dict_sys.lock(SRW_LOCK_CALL)
|
#define dict_sys_lock() dict_sys.lock(SRW_LOCK_CALL)
|
||||||
#define dict_sys_unlock() dict_sys.unlock()
|
#define dict_sys_unlock() dict_sys.unlock()
|
||||||
|
|
||||||
|
@@ -39,20 +39,6 @@ Created 4/24/1996 Heikki Tuuri
|
|||||||
/** A stack of table names related through foreign key constraints */
|
/** A stack of table names related through foreign key constraints */
|
||||||
typedef std::deque<const char*, ut_allocator<const char*> > dict_names_t;
|
typedef std::deque<const char*, ut_allocator<const char*> > dict_names_t;
|
||||||
|
|
||||||
/** 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_VIRTUAL,
|
|
||||||
|
|
||||||
/* This must be last item. Defines the number of system tables. */
|
|
||||||
SYS_NUM_SYSTEM_TABLES
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Check each tablespace found in the data dictionary.
|
/** Check each tablespace found in the data dictionary.
|
||||||
Then look at each table defined in SYS_TABLES that has a space_id > 0
|
Then look at each table defined in SYS_TABLES that has a space_id > 0
|
||||||
to find all the file-per-table tablespaces.
|
to find all the file-per-table tablespaces.
|
||||||
@@ -74,18 +60,6 @@ dict_get_and_save_data_dir_path(
|
|||||||
dict_table_t* table,
|
dict_table_t* table,
|
||||||
bool dict_mutex_own);
|
bool dict_mutex_own);
|
||||||
|
|
||||||
/** Loads a table definition and also all its index definitions, and also
|
|
||||||
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.
|
|
||||||
@param[in] name Table name in the dbname/tablename format
|
|
||||||
@param[in] ignore_err Error to be ignored when loading
|
|
||||||
table and its index definition
|
|
||||||
@return table, NULL if does not exist; if the table is stored in an
|
|
||||||
.ibd file, but the file does not exist, then we set the file_unreadable
|
|
||||||
flag in the table object we return. */
|
|
||||||
dict_table_t* dict_load_table(const char* name, dict_err_ignore_t ignore_err);
|
|
||||||
|
|
||||||
/***********************************************************************//**
|
/***********************************************************************//**
|
||||||
Loads a table object based on the table id.
|
Loads a table object based on the table id.
|
||||||
@return table; NULL if table does not exist */
|
@return table; NULL if table does not exist */
|
||||||
@@ -140,7 +114,7 @@ dict_startscan_system(
|
|||||||
btr_pcur_t* pcur, /*!< out: persistent cursor to
|
btr_pcur_t* pcur, /*!< out: persistent cursor to
|
||||||
the record */
|
the record */
|
||||||
mtr_t* mtr, /*!< in: the mini-transaction */
|
mtr_t* mtr, /*!< in: the mini-transaction */
|
||||||
dict_system_id_t system_id); /*!< in: which system table to open */
|
dict_table_t* table); /*!< in: system table */
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
This function get the next system table record as we scan the table.
|
This function get the next system table record as we scan the table.
|
||||||
@return the record if found, NULL if end of scan. */
|
@return the record if found, NULL if end of scan. */
|
||||||
@@ -150,19 +124,18 @@ dict_getnext_system(
|
|||||||
btr_pcur_t* pcur, /*!< in/out: persistent cursor
|
btr_pcur_t* pcur, /*!< in/out: persistent cursor
|
||||||
to the record */
|
to the record */
|
||||||
mtr_t* mtr); /*!< in: the mini-transaction */
|
mtr_t* mtr); /*!< in: the mini-transaction */
|
||||||
/********************************************************************//**
|
|
||||||
This function processes one SYS_TABLES record and populate the dict_table_t
|
/** Load a table definition from a SYS_TABLES record to dict_table_t.
|
||||||
struct for the table.
|
Do not load any columns or indexes.
|
||||||
@return error message, or NULL on success */
|
@param[in] name Table name
|
||||||
const char*
|
@param[in] rec SYS_TABLES record
|
||||||
dict_process_sys_tables_rec_and_mtr_commit(
|
@param[out,own] table table, or nullptr
|
||||||
/*=======================================*/
|
@return error message
|
||||||
mem_heap_t* heap, /*!< in: temporary memory heap */
|
@retval nullptr on success */
|
||||||
const rec_t* rec, /*!< in: SYS_TABLES record */
|
const char *dict_load_table_low(const span<const char> &name,
|
||||||
dict_table_t** table, /*!< out: dict_table_t to fill */
|
const rec_t *rec, dict_table_t **table)
|
||||||
bool cached, /*!< in: whether to load from cache */
|
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||||
mtr_t* mtr); /*!< in/out: mini-transaction,
|
|
||||||
will be committed */
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
This function parses a SYS_INDEXES record and populate a dict_index_t
|
This function parses a SYS_INDEXES record and populate a dict_index_t
|
||||||
structure with the information from the record. For detail information
|
structure with the information from the record. For detail information
|
||||||
|
@@ -28,10 +28,10 @@ Created 1/8/1996 Heikki Tuuri
|
|||||||
#ifndef dict0mem_h
|
#ifndef dict0mem_h
|
||||||
#define dict0mem_h
|
#define dict0mem_h
|
||||||
|
|
||||||
|
#include "dict0types.h"
|
||||||
#include "data0type.h"
|
#include "data0type.h"
|
||||||
#include "mem0mem.h"
|
#include "mem0mem.h"
|
||||||
#include "row0types.h"
|
#include "row0types.h"
|
||||||
#include "rem0types.h"
|
|
||||||
#include "btr0types.h"
|
#include "btr0types.h"
|
||||||
#include "lock0types.h"
|
#include "lock0types.h"
|
||||||
#include "que0types.h"
|
#include "que0types.h"
|
||||||
@@ -298,17 +298,6 @@ parent table will fail, and user has to drop excessive foreign constraint
|
|||||||
before proceeds. */
|
before proceeds. */
|
||||||
#define FK_MAX_CASCADE_DEL 15
|
#define FK_MAX_CASCADE_DEL 15
|
||||||
|
|
||||||
/** Create a table memory object.
|
|
||||||
@param name table name
|
|
||||||
@param space tablespace
|
|
||||||
@param n_cols total number of columns (both virtual and non-virtual)
|
|
||||||
@param n_v_cols number of virtual columns
|
|
||||||
@param flags table flags
|
|
||||||
@param flags2 table flags2
|
|
||||||
@return own: table object */
|
|
||||||
dict_table_t *dict_mem_table_create(const char *name, fil_space_t *space,
|
|
||||||
ulint n_cols, ulint n_v_cols, ulint flags,
|
|
||||||
ulint flags2);
|
|
||||||
/****************************************************************/ /**
|
/****************************************************************/ /**
|
||||||
Free a table memory object. */
|
Free a table memory object. */
|
||||||
void
|
void
|
||||||
@@ -1816,7 +1805,7 @@ typedef enum {
|
|||||||
} dict_frm_t;
|
} dict_frm_t;
|
||||||
|
|
||||||
/** Data structure for a database table. Most fields will be
|
/** Data structure for a database table. Most fields will be
|
||||||
initialized to 0, NULL or FALSE in dict_mem_table_create(). */
|
zero-initialized in dict_table_t::create(). */
|
||||||
struct dict_table_t {
|
struct dict_table_t {
|
||||||
|
|
||||||
/** Get reference count.
|
/** Get reference count.
|
||||||
@@ -2435,10 +2424,24 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check whether the table name is same as mysql/innodb_stats_table
|
/** @return whether the name is
|
||||||
or mysql/innodb_index_stats.
|
mysql.innodb_index_stats or mysql.innodb_table_stats */
|
||||||
@return true if the table name is same as stats table */
|
inline bool is_stats_table() const;
|
||||||
bool is_stats_table() const;
|
|
||||||
|
/** Create metadata.
|
||||||
|
@param name table name
|
||||||
|
@param space tablespace
|
||||||
|
@param n_cols total number of columns (both virtual and non-virtual)
|
||||||
|
@param n_v_cols number of virtual columns
|
||||||
|
@param flags table flags
|
||||||
|
@param flags2 table flags2
|
||||||
|
@return newly allocated table object */
|
||||||
|
static dict_table_t *create(const span<const char> &name, fil_space_t *space,
|
||||||
|
ulint n_cols, ulint n_v_cols, ulint flags,
|
||||||
|
ulint flags2);
|
||||||
|
|
||||||
|
/** @return whether SYS_TABLES.NAME is for a '#sql-ib' table */
|
||||||
|
static bool is_garbage_name(const void *data, size_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void dict_index_t::set_modified(mtr_t& mtr) const
|
inline void dict_index_t::set_modified(mtr_t& mtr) const
|
||||||
|
@@ -1,50 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Copyright (c) 2010, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
|
||||||
|
|
||||||
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.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|
||||||
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/**************************************************//**
|
|
||||||
@file include/dict0priv.h
|
|
||||||
Data dictionary private functions
|
|
||||||
|
|
||||||
Created Fri 2 Jul 2010 13:30:38 EST - Sunny Bains
|
|
||||||
*******************************************************/
|
|
||||||
|
|
||||||
#ifndef dict0priv_h
|
|
||||||
#define dict0priv_h
|
|
||||||
|
|
||||||
/**********************************************************************//**
|
|
||||||
Gets a table; loads it to the dictionary cache if necessary. A low-level
|
|
||||||
function. Note: Not to be called from outside dict0*c functions.
|
|
||||||
@return table, NULL if not found */
|
|
||||||
UNIV_INLINE
|
|
||||||
dict_table_t*
|
|
||||||
dict_table_get_low(
|
|
||||||
/*===============*/
|
|
||||||
const char* table_name); /*!< in: table name */
|
|
||||||
|
|
||||||
/**********************************************************************//**
|
|
||||||
Checks if a table is in the dictionary cache.
|
|
||||||
@return table, NULL if not found */
|
|
||||||
UNIV_INLINE
|
|
||||||
dict_table_t*
|
|
||||||
dict_table_check_if_in_cache_low(
|
|
||||||
/*=============================*/
|
|
||||||
const char* table_name); /*!< in: table name */
|
|
||||||
|
|
||||||
#include "dict0priv.ic"
|
|
||||||
|
|
||||||
#endif /* dict0priv.h */
|
|
@@ -1,91 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
|
|
||||||
Copyright (c) 2010, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
|
||||||
|
|
||||||
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.,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|
||||||
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/******************************************************************//**
|
|
||||||
@file include/dict0priv.ic
|
|
||||||
Data dictionary system private include file
|
|
||||||
|
|
||||||
Created Wed 13 Oct 2010 16:10:14 EST Sunny Bains
|
|
||||||
***********************************************************************/
|
|
||||||
|
|
||||||
#include "dict0dict.h"
|
|
||||||
#include "dict0load.h"
|
|
||||||
|
|
||||||
/**********************************************************************//**
|
|
||||||
Gets a table; loads it to the dictionary cache if necessary. A low-level
|
|
||||||
function.
|
|
||||||
@return table, NULL if not found */
|
|
||||||
UNIV_INLINE
|
|
||||||
dict_table_t*
|
|
||||||
dict_table_get_low(
|
|
||||||
/*===============*/
|
|
||||||
const char* table_name) /*!< in: table name */
|
|
||||||
{
|
|
||||||
dict_table_t* table;
|
|
||||||
|
|
||||||
ut_ad(table_name);
|
|
||||||
dict_sys.assert_locked();
|
|
||||||
|
|
||||||
table = dict_table_check_if_in_cache_low(table_name);
|
|
||||||
|
|
||||||
if (table && table->corrupted) {
|
|
||||||
ib::error error;
|
|
||||||
error << "Table " << table->name << "is corrupted";
|
|
||||||
if (srv_load_corrupted) {
|
|
||||||
error << ", but innodb_force_load_corrupted is set";
|
|
||||||
} else {
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table == NULL) {
|
|
||||||
table = dict_load_table(table_name, DICT_ERR_IGNORE_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ut_ad(!table || table->cached);
|
|
||||||
|
|
||||||
return(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************//**
|
|
||||||
Checks if a table is in the dictionary cache.
|
|
||||||
@return table, NULL if not found */
|
|
||||||
UNIV_INLINE
|
|
||||||
dict_table_t*
|
|
||||||
dict_table_check_if_in_cache_low(
|
|
||||||
/*=============================*/
|
|
||||||
const char* table_name) /*!< in: table name */
|
|
||||||
{
|
|
||||||
dict_table_t* table;
|
|
||||||
ulint table_fold;
|
|
||||||
|
|
||||||
DBUG_ENTER("dict_table_check_if_in_cache_low");
|
|
||||||
DBUG_PRINT("dict_table_check_if_in_cache_low",
|
|
||||||
("table: '%s'", table_name));
|
|
||||||
|
|
||||||
ut_ad(table_name);
|
|
||||||
dict_sys.assert_locked();
|
|
||||||
|
|
||||||
/* Look for the table name in the hash table */
|
|
||||||
table_fold = ut_fold_string(table_name);
|
|
||||||
|
|
||||||
HASH_SEARCH(name_hash, &dict_sys.table_hash, table_fold,
|
|
||||||
dict_table_t*, table, ut_ad(table->cached),
|
|
||||||
!strcmp(table->name.m_name, table_name));
|
|
||||||
DBUG_RETURN(table);
|
|
||||||
}
|
|
@@ -28,8 +28,11 @@ Created 1/8/1996 Heikki Tuuri
|
|||||||
#define dict0types_h
|
#define dict0types_h
|
||||||
|
|
||||||
#include "univ.i"
|
#include "univ.i"
|
||||||
|
#include "span.h"
|
||||||
#include <rem0types.h>
|
#include <rem0types.h>
|
||||||
|
|
||||||
|
using st_::span;
|
||||||
|
|
||||||
struct dict_col_t;
|
struct dict_col_t;
|
||||||
struct dict_field_t;
|
struct dict_field_t;
|
||||||
struct dict_index_t;
|
struct dict_index_t;
|
||||||
|
@@ -39,7 +39,6 @@ Created 10/25/1995 Heikki Tuuri
|
|||||||
#include "log0recv.h"
|
#include "log0recv.h"
|
||||||
#include "dict0types.h"
|
#include "dict0types.h"
|
||||||
#include "ilist.h"
|
#include "ilist.h"
|
||||||
#include "span.h"
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
@@ -1621,7 +1620,7 @@ char* fil_make_filepath(const char *path, const fil_space_t::name_type &name,
|
|||||||
ib_extention ext, bool trim_name);
|
ib_extention ext, bool trim_name);
|
||||||
|
|
||||||
char *fil_make_filepath(const char* path, const table_name_t name,
|
char *fil_make_filepath(const char* path, const table_name_t name,
|
||||||
ib_extention ext, bool trim_name);
|
ib_extention suffix, bool strip_name);
|
||||||
|
|
||||||
/** Create a tablespace file.
|
/** Create a tablespace file.
|
||||||
@param[in] space_id Tablespace ID
|
@param[in] space_id Tablespace ID
|
||||||
@@ -1677,7 +1676,7 @@ statement to update the dictionary tables if they are incorrect.
|
|||||||
@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_TEMPORARY
|
@param[in] purpose FIL_TYPE_TABLESPACE or FIL_TYPE_TEMPORARY
|
||||||
@param[in] id tablespace ID
|
@param[in] id tablespace ID
|
||||||
@param[in] flags expected FSP_SPACE_FLAGS
|
@param[in] flags expected FSP_SPACE_FLAGS
|
||||||
@param[in] tablename table name
|
@param[in] name table name
|
||||||
If file-per-table, it is the table name in the databasename/tablename format
|
If file-per-table, it is the table name in the databasename/tablename format
|
||||||
@param[in] path_in expected filepath, usually read from dictionary
|
@param[in] path_in expected filepath, usually read from dictionary
|
||||||
@param[out] err DB_SUCCESS or error code
|
@param[out] err DB_SUCCESS or error code
|
||||||
@@ -1689,7 +1688,7 @@ fil_ibd_open(
|
|||||||
fil_type_t purpose,
|
fil_type_t purpose,
|
||||||
ulint id,
|
ulint id,
|
||||||
ulint flags,
|
ulint flags,
|
||||||
const table_name_t tablename,
|
fil_space_t::name_type name,
|
||||||
const char* path_in,
|
const char* path_in,
|
||||||
dberr_t* err = NULL)
|
dberr_t* err = NULL)
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
@@ -501,7 +501,7 @@ public:
|
|||||||
@param name table name
|
@param name table name
|
||||||
@return filepath()
|
@return filepath()
|
||||||
@retval nullptr if the .isl file does not exist or cannot be read */
|
@retval nullptr if the .isl file does not exist or cannot be read */
|
||||||
const char* open_link_file(const table_name_t& name);
|
const char* open_link_file(const fil_space_t::name_type name);
|
||||||
|
|
||||||
/** Delete an InnoDB Symbolic Link (ISL) file. */
|
/** Delete an InnoDB Symbolic Link (ISL) file. */
|
||||||
void delete_link_file(void);
|
void delete_link_file(void);
|
||||||
|
@@ -377,25 +377,17 @@ row_create_index_for_mysql(
|
|||||||
fil_encryption_t mode, /*!< in: encryption mode */
|
fil_encryption_t mode, /*!< in: encryption mode */
|
||||||
uint32_t key_id) /*!< in: encryption key_id */
|
uint32_t key_id) /*!< in: encryption key_id */
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
/*********************************************************************//**
|
|
||||||
The master thread in srv0srv.cc calls this regularly to drop tables which
|
/** The master task calls this regularly to drop tables which
|
||||||
we must drop in background after queries to them have ended. Such lazy
|
we must drop in background after queries to them have ended.
|
||||||
dropping of tables is needed in ALTER TABLE on Unix.
|
|
||||||
@return how many tables dropped + remaining tables in list */
|
@return how many tables dropped + remaining tables in list */
|
||||||
ulint
|
ulint row_drop_tables_for_mysql_in_background();
|
||||||
row_drop_tables_for_mysql_in_background(void);
|
|
||||||
/*=========================================*/
|
/** @return number of tables in the background drop list */
|
||||||
/*********************************************************************//**
|
ulint row_get_background_drop_list_len_low();
|
||||||
Get the background drop list length. NOTE: the caller must own the kernel
|
|
||||||
mutex!
|
|
||||||
@return how many tables in list */
|
|
||||||
ulint
|
|
||||||
row_get_background_drop_list_len_low(void);
|
|
||||||
/*======================================*/
|
|
||||||
|
|
||||||
/** Drop garbage tables during recovery. */
|
/** Drop garbage tables during recovery. */
|
||||||
void
|
void row_mysql_drop_garbage_tables();
|
||||||
row_mysql_drop_garbage_tables();
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Sets an exclusive lock on a table.
|
Sets an exclusive lock on a table.
|
||||||
|
@@ -964,7 +964,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @return whether the table has lock on
|
/** @return whether the table has lock on
|
||||||
mysql.innodb_table_stats and mysql.innodb_index_stats */
|
mysql.innodb_table_stats or mysql.innodb_index_stats */
|
||||||
bool has_stats_table_lock() const;
|
bool has_stats_table_lock() const;
|
||||||
|
|
||||||
/** Free the memory to trx_pools */
|
/** Free the memory to trx_pools */
|
||||||
|
@@ -3857,7 +3857,7 @@ released:
|
|||||||
LockMutexGuard g{SRW_LOCK_CALL};
|
LockMutexGuard g{SRW_LOCK_CALL};
|
||||||
for (const table_id_t id : to_evict)
|
for (const table_id_t id : to_evict)
|
||||||
{
|
{
|
||||||
if (dict_table_t *table= dict_sys.get_table(id))
|
if (dict_table_t *table= dict_sys.find_table(id))
|
||||||
if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks))
|
if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks))
|
||||||
dict_sys.remove(table, true);
|
dict_sys.remove(table, true);
|
||||||
}
|
}
|
||||||
|
@@ -1652,8 +1652,8 @@ page_zip_fields_decode(
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
table = dict_mem_table_create("ZIP_DUMMY", NULL, n, 0,
|
table = dict_table_t::create({C_STRING_WITH_LEN("ZIP_DUMMY")},
|
||||||
DICT_TF_COMPACT, 0);
|
nullptr, n, 0, DICT_TF_COMPACT, 0);
|
||||||
index = dict_mem_index_create(table, "ZIP_DUMMY", 0, n);
|
index = dict_mem_index_create(table, "ZIP_DUMMY", 0, n);
|
||||||
index->n_uniq = static_cast<unsigned>(n) & dict_index_t::MAX_N_FIELDS;
|
index->n_uniq = static_cast<unsigned>(n) & dict_index_t::MAX_N_FIELDS;
|
||||||
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
|
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
|
||||||
|
@@ -1783,8 +1783,9 @@ pars_create_table(
|
|||||||
|
|
||||||
n_cols = que_node_list_get_len(column_defs);
|
n_cols = que_node_list_get_len(column_defs);
|
||||||
|
|
||||||
table = dict_mem_table_create(
|
table = dict_table_t::create(
|
||||||
table_sym->name, NULL, n_cols, 0, flags, flags2);
|
{table_sym->name, strlen(table_sym->name)},
|
||||||
|
nullptr, n_cols, 0, flags, flags2);
|
||||||
|
|
||||||
mem_heap_t* heap = pars_sym_tab_global->heap;
|
mem_heap_t* heap = pars_sym_tab_global->heap;
|
||||||
column = column_defs;
|
column = column_defs;
|
||||||
|
@@ -4091,7 +4091,10 @@ row_import_for_mysql(
|
|||||||
ut_ad(!DICT_TF_HAS_DATA_DIR(table->flags) || table->data_dir_path);
|
ut_ad(!DICT_TF_HAS_DATA_DIR(table->flags) || table->data_dir_path);
|
||||||
const char *data_dir_path = DICT_TF_HAS_DATA_DIR(table->flags)
|
const char *data_dir_path = DICT_TF_HAS_DATA_DIR(table->flags)
|
||||||
? table->data_dir_path : nullptr;
|
? table->data_dir_path : nullptr;
|
||||||
filepath = fil_make_filepath(data_dir_path, table->name, IBD,
|
fil_space_t::name_type name{
|
||||||
|
table->name.m_name, strlen(table->name.m_name)};
|
||||||
|
|
||||||
|
filepath = fil_make_filepath(data_dir_path, name, IBD,
|
||||||
data_dir_path != nullptr);
|
data_dir_path != nullptr);
|
||||||
|
|
||||||
DBUG_EXECUTE_IF(
|
DBUG_EXECUTE_IF(
|
||||||
@@ -4116,7 +4119,7 @@ row_import_for_mysql(
|
|||||||
|
|
||||||
table->space = fil_ibd_open(
|
table->space = fil_ibd_open(
|
||||||
true, FIL_TYPE_IMPORT, table->space_id,
|
true, FIL_TYPE_IMPORT, table->space_id,
|
||||||
fsp_flags, table->name, filepath, &err);
|
fsp_flags, name, filepath, &err);
|
||||||
|
|
||||||
ut_ad((table->space == NULL) == (err != DB_SUCCESS));
|
ut_ad((table->space == NULL) == (err != DB_SUCCESS));
|
||||||
DBUG_EXECUTE_IF("ib_import_open_tablespace_failure",
|
DBUG_EXECUTE_IF("ib_import_open_tablespace_failure",
|
||||||
|
@@ -36,7 +36,6 @@ Created 9/17/2000 Heikki Tuuri
|
|||||||
#include "dict0crea.h"
|
#include "dict0crea.h"
|
||||||
#include "dict0dict.h"
|
#include "dict0dict.h"
|
||||||
#include "dict0load.h"
|
#include "dict0load.h"
|
||||||
#include "dict0priv.h"
|
|
||||||
#include "dict0stats.h"
|
#include "dict0stats.h"
|
||||||
#include "dict0stats_bg.h"
|
#include "dict0stats_bg.h"
|
||||||
#include "dict0defrag_bg.h"
|
#include "dict0defrag_bg.h"
|
||||||
@@ -2321,9 +2320,8 @@ row_create_table_for_mysql(
|
|||||||
ib::error() << "Trying to create a MySQL system table "
|
ib::error() << "Trying to create a MySQL system table "
|
||||||
<< table->name << " of type InnoDB. MySQL system"
|
<< table->name << " of type InnoDB. MySQL system"
|
||||||
" tables must be of the MyISAM type!";
|
" tables must be of the MyISAM type!";
|
||||||
#ifndef DBUG_OFF
|
|
||||||
err_exit:
|
err_exit:
|
||||||
#endif /* !DBUG_OFF */
|
|
||||||
dict_mem_table_free(table);
|
dict_mem_table_free(table);
|
||||||
|
|
||||||
trx->op_info = "";
|
trx->op_info = "";
|
||||||
@@ -2331,6 +2329,11 @@ err_exit:
|
|||||||
return(DB_ERROR);
|
return(DB_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!dict_sys.sys_tables_exist()) {
|
||||||
|
ib::error() << "Some InnoDB system tables are missing";
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
trx_start_if_not_started_xa(trx, true);
|
trx_start_if_not_started_xa(trx, true);
|
||||||
|
|
||||||
heap = mem_heap_create(512);
|
heap = mem_heap_create(512);
|
||||||
@@ -2622,10 +2625,8 @@ row_get_background_drop_list_len_low(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Drop garbage tables during recovery. */
|
/** Drop garbage tables during recovery. */
|
||||||
void
|
void row_mysql_drop_garbage_tables()
|
||||||
row_mysql_drop_garbage_tables()
|
|
||||||
{
|
{
|
||||||
mem_heap_t* heap = mem_heap_create(FN_REFLEN);
|
|
||||||
btr_pcur_t pcur;
|
btr_pcur_t pcur;
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
trx_t* trx = trx_create();
|
trx_t* trx = trx_create();
|
||||||
@@ -2641,7 +2642,6 @@ row_mysql_drop_garbage_tables()
|
|||||||
const rec_t* rec;
|
const rec_t* rec;
|
||||||
const byte* field;
|
const byte* field;
|
||||||
ulint len;
|
ulint len;
|
||||||
const char* table_name;
|
|
||||||
|
|
||||||
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
|
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
|
||||||
|
|
||||||
@@ -2655,38 +2655,37 @@ row_mysql_drop_garbage_tables()
|
|||||||
}
|
}
|
||||||
|
|
||||||
field = rec_get_nth_field_old(rec, 0/*NAME*/, &len);
|
field = rec_get_nth_field_old(rec, 0/*NAME*/, &len);
|
||||||
if (len == UNIV_SQL_NULL || len == 0) {
|
if (len == UNIV_SQL_NULL) {
|
||||||
/* Corrupted SYS_TABLES.NAME */
|
/* Corrupted SYS_TABLES.NAME */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
table_name = mem_heap_strdupl(
|
if (!dict_table_t::is_garbage_name(field, len)) {
|
||||||
heap,
|
continue;
|
||||||
reinterpret_cast<const char*>(field), len);
|
|
||||||
if (strstr(table_name, "/" TEMP_FILE_PREFIX_INNODB)) {
|
|
||||||
btr_pcur_store_position(&pcur, &mtr);
|
|
||||||
btr_pcur_commit_specify_mtr(&pcur, &mtr);
|
|
||||||
|
|
||||||
if (dict_load_table(table_name,
|
|
||||||
DICT_ERR_IGNORE_DROP)) {
|
|
||||||
row_drop_table_for_mysql(table_name, trx,
|
|
||||||
SQLCOM_DROP_TABLE);
|
|
||||||
trx_commit_for_mysql(trx);
|
|
||||||
}
|
|
||||||
|
|
||||||
mtr.start();
|
|
||||||
btr_pcur_restore_position(BTR_SEARCH_LEAF,
|
|
||||||
&pcur, &mtr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_heap_empty(heap);
|
btr_pcur_store_position(&pcur, &mtr);
|
||||||
|
btr_pcur_commit_specify_mtr(&pcur, &mtr);
|
||||||
|
|
||||||
|
const span<const char> name = {
|
||||||
|
reinterpret_cast<const char*>(pcur.old_rec), len
|
||||||
|
};
|
||||||
|
if (dict_sys.load_table(name, DICT_ERR_IGNORE_DROP)) {
|
||||||
|
char* table_name = mem_strdupl(name.data(), len);
|
||||||
|
row_drop_table_for_mysql(table_name, trx,
|
||||||
|
SQLCOM_DROP_TABLE);
|
||||||
|
ut_free(table_name);
|
||||||
|
trx_commit_for_mysql(trx);
|
||||||
|
}
|
||||||
|
|
||||||
|
mtr.start();
|
||||||
|
btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
btr_pcur_close(&pcur);
|
btr_pcur_close(&pcur);
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
trx->free();
|
trx->free();
|
||||||
mem_heap_free(heap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
@@ -3160,38 +3159,6 @@ row_drop_ancillary_fts_tables(
|
|||||||
return(DB_SUCCESS);
|
return(DB_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Drop a table from the memory cache as part of dropping a table.
|
|
||||||
@param[in] tablename A copy of table->name. Used when table == null
|
|
||||||
@param[in,out] table Table cache entry
|
|
||||||
@param[in,out] trx Transaction handle
|
|
||||||
@return error code or DB_SUCCESS */
|
|
||||||
UNIV_INLINE
|
|
||||||
dberr_t
|
|
||||||
row_drop_table_from_cache(
|
|
||||||
const char* tablename,
|
|
||||||
dict_table_t* table,
|
|
||||||
trx_t* trx)
|
|
||||||
{
|
|
||||||
dberr_t err = DB_SUCCESS;
|
|
||||||
ut_ad(!table->is_temporary());
|
|
||||||
|
|
||||||
/* Remove the pointer to this table object from the list
|
|
||||||
of modified tables by the transaction because the object
|
|
||||||
is going to be destroyed below. */
|
|
||||||
trx->mod_tables.erase(table);
|
|
||||||
|
|
||||||
dict_sys.remove(table);
|
|
||||||
|
|
||||||
if (dict_load_table(tablename, DICT_ERR_IGNORE_FK_NOKEY)) {
|
|
||||||
ib::error() << "Not able to remove table "
|
|
||||||
<< ut_get_name(trx, tablename)
|
|
||||||
<< " from the dictionary cache!";
|
|
||||||
err = DB_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Drop a table for MySQL.
|
/** Drop a table for MySQL.
|
||||||
If the data dictionary was not already locked by the transaction,
|
If the data dictionary was not already locked by the transaction,
|
||||||
the transaction will be committed. Otherwise, the data dictionary
|
the transaction will be committed. Otherwise, the data dictionary
|
||||||
@@ -3331,7 +3298,7 @@ row_drop_table_for_mysql(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dict_table_prevent_eviction(table);
|
dict_sys.prevent_eviction(table);
|
||||||
dict_table_close(table, TRUE, FALSE);
|
dict_table_close(table, TRUE, FALSE);
|
||||||
|
|
||||||
/* Check if the table is referenced by foreign key constraints from
|
/* Check if the table is referenced by foreign key constraints from
|
||||||
@@ -3475,10 +3442,8 @@ defer:
|
|||||||
|
|
||||||
pars_info_add_str_literal(info, "name", name);
|
pars_info_add_str_literal(info, "name", name);
|
||||||
|
|
||||||
if (sqlcom != SQLCOM_TRUNCATE
|
if (sqlcom != SQLCOM_TRUNCATE && strchr(name, '/')
|
||||||
&& strchr(name, '/')
|
&& dict_sys.sys_foreign && dict_sys.sys_foreign_cols) {
|
||||||
&& dict_table_get_low("SYS_FOREIGN")
|
|
||||||
&& dict_table_get_low("SYS_FOREIGN_COLS")) {
|
|
||||||
err = que_eval_sql(
|
err = que_eval_sql(
|
||||||
info,
|
info,
|
||||||
"PROCEDURE DROP_FOREIGN_PROC () IS\n"
|
"PROCEDURE DROP_FOREIGN_PROC () IS\n"
|
||||||
@@ -3507,7 +3472,7 @@ defer:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
do_drop:
|
do_drop:
|
||||||
if (dict_table_get_low("SYS_VIRTUAL")) {
|
if (dict_sys.sys_virtual) {
|
||||||
err = que_eval_sql(
|
err = que_eval_sql(
|
||||||
info,
|
info,
|
||||||
"PROCEDURE DROP_VIRTUAL_PROC () IS\n"
|
"PROCEDURE DROP_VIRTUAL_PROC () IS\n"
|
||||||
@@ -3588,12 +3553,8 @@ do_drop:
|
|||||||
IBD,
|
IBD,
|
||||||
table->data_dir_path != nullptr);
|
table->data_dir_path != nullptr);
|
||||||
|
|
||||||
/* Free the dict_table_t object. */
|
trx->mod_tables.erase(table);
|
||||||
err = row_drop_table_from_cache(tablename, table, trx);
|
dict_sys.remove(table);
|
||||||
if (err != DB_SUCCESS) {
|
|
||||||
ut_free(filepath);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do not attempt to drop known-to-be-missing tablespaces,
|
/* Do not attempt to drop known-to-be-missing tablespaces,
|
||||||
nor the system tablespace. */
|
nor the system tablespace. */
|
||||||
@@ -4136,8 +4097,8 @@ row_rename_table_for_mysql(
|
|||||||
dict_mem_table_fill_foreign_vcol_set(table);
|
dict_mem_table_fill_foreign_vcol_set(table);
|
||||||
|
|
||||||
while (!fk_tables.empty()) {
|
while (!fk_tables.empty()) {
|
||||||
dict_load_table(fk_tables.front(),
|
const char *f = fk_tables.front();
|
||||||
DICT_ERR_IGNORE_NONE);
|
dict_sys.load_table({f, strlen(f)});
|
||||||
fk_tables.pop_front();
|
fk_tables.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -428,10 +428,10 @@ static bool row_undo_ins_parse_undo_rec(undo_node_t* node, bool dict_locked)
|
|||||||
DICT_TABLE_OP_NORMAL);
|
DICT_TABLE_OP_NORMAL);
|
||||||
} else if (!dict_locked) {
|
} else if (!dict_locked) {
|
||||||
dict_sys.mutex_lock();
|
dict_sys.mutex_lock();
|
||||||
node->table = dict_sys.get_temporary_table(table_id);
|
node->table = dict_sys.acquire_temporary_table(table_id);
|
||||||
dict_sys.mutex_unlock();
|
dict_sys.mutex_unlock();
|
||||||
} else {
|
} else {
|
||||||
node->table = dict_sys.get_temporary_table(table_id);
|
node->table = dict_sys.acquire_temporary_table(table_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node->table) {
|
if (!node->table) {
|
||||||
|
@@ -1256,10 +1256,10 @@ static bool row_undo_mod_parse_undo_rec(undo_node_t* node, bool dict_locked)
|
|||||||
DICT_TABLE_OP_NORMAL);
|
DICT_TABLE_OP_NORMAL);
|
||||||
} else if (!dict_locked) {
|
} else if (!dict_locked) {
|
||||||
dict_sys.mutex_lock();
|
dict_sys.mutex_lock();
|
||||||
node->table = dict_sys.get_temporary_table(table_id);
|
node->table = dict_sys.acquire_temporary_table(table_id);
|
||||||
dict_sys.mutex_unlock();
|
dict_sys.mutex_unlock();
|
||||||
} else {
|
} else {
|
||||||
node->table = dict_sys.get_temporary_table(table_id);
|
node->table = dict_sys.acquire_temporary_table(table_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!node->table) {
|
if (!node->table) {
|
||||||
|
@@ -1454,6 +1454,7 @@ file_checked:
|
|||||||
if (srv_operation == SRV_OPERATION_RESTORE) {
|
if (srv_operation == SRV_OPERATION_RESTORE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
dict_sys.load_sys_tables();
|
||||||
trx_lists_init_at_db_start();
|
trx_lists_init_at_db_start();
|
||||||
break;
|
break;
|
||||||
case SRV_OPERATION_RESTORE_DELTA:
|
case SRV_OPERATION_RESTORE_DELTA:
|
||||||
@@ -1796,11 +1797,7 @@ skip_monitors:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the SYS_FOREIGN and SYS_FOREIGN_COLS system tables */
|
err = dict_sys.create_or_check_sys_tables();
|
||||||
err = dict_create_or_check_foreign_constraint_tables();
|
|
||||||
if (err == DB_SUCCESS) {
|
|
||||||
err = dict_create_or_check_sys_virtual();
|
|
||||||
}
|
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case DB_SUCCESS:
|
case DB_SUCCESS:
|
||||||
break;
|
break;
|
||||||
|
@@ -703,7 +703,6 @@ static my_bool trx_rollback_recovered_callback(rw_trx_hash_element_t *element,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Rollback any incomplete transactions which were encountered in crash recovery.
|
Rollback any incomplete transactions which were encountered in crash recovery.
|
||||||
|
|
||||||
|
@@ -2214,16 +2214,3 @@ trx_set_rw_mode(
|
|||||||
trx->read_view.set_creator_trx_id(trx->id);
|
trx->read_view.set_creator_trx_id(trx->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool trx_t::has_stats_table_lock() const
|
|
||||||
{
|
|
||||||
for (lock_list::const_iterator it= lock.table_locks.begin(),
|
|
||||||
end= lock.table_locks.end(); it != end; ++it)
|
|
||||||
{
|
|
||||||
const lock_t *lock= *it;
|
|
||||||
if (lock && lock->un_member.tab_lock.table->is_stats_table())
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user