mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-25506 (3 of 3): Do not delete .ibd files before commit
This is a complete rewrite of DROP TABLE, also as part of other DDL, such as ALTER TABLE, CREATE TABLE...SELECT, TRUNCATE TABLE. The background DROP TABLE queue hack is removed. If a transaction needs to drop and create a table by the same name (like TRUNCATE TABLE does), it must first rename the table to an internal #sql-ib name. No committed version of the data dictionary will include any #sql-ib tables, because whenever a transaction renames a table to a #sql-ib name, it will also drop that table. Either the rename will be rolled back, or the drop will be committed. Data files will be unlinked after the transaction has been committed and a FILE_RENAME record has been durably written. The file will actually be deleted when the detached file handle returned by fil_delete_tablespace() will be closed, after the latches have been released. It is possible that a purge of the delete of the SYS_INDEXES record for the clustered index will execute fil_delete_tablespace() concurrently with the DDL transaction. In that case, the thread that arrives later will wait for the other thread to finish. HTON_TRUNCATE_REQUIRES_EXCLUSIVE_USE: A new handler flag. ha_innobase::truncate() now requires that all other references to the table be released in advance. This was implemented by Monty. ha_innobase::delete_table(): If CREATE TABLE..SELECT is detected, we will "hijack" the current transaction, drop the table in the current transaction and commit the current transaction. This essentially fixes MDEV-21602. There is a FIXME comment about making the check less failure-prone. ha_innobase::truncate(), ha_innobase::delete_table(): Implement a fast path for temporary tables. We will no longer allow temporary tables to use the adaptive hash index. dict_table_t::mdl_name: The original table name for the purpose of acquiring MDL in purge, to prevent a race condition between a DDL transaction that is dropping a table, and purge processing undo log records of DML that had executed before the DDL operation. For #sql-backup- tables during ALTER TABLE...ALGORITHM=COPY, the dict_table_t::mdl_name will differ from dict_table_t::name. dict_table_t::parse_name(): Use mdl_name instead of name. dict_table_rename_in_cache(): Update mdl_name. For the internal FTS_ tables of FULLTEXT INDEX, purge would acquire MDL on the FTS_ table name, but not on the main table, and therefore it would be able to run concurrently with a DDL transaction that is dropping the table. Previously, the DROP TABLE queue hack prevented a race between purge and DDL. For now, we introduce purge_sys.stop_FTS() to prevent purge from opening any table, while a DDL transaction that may drop FTS_ tables is in progress. The function fts_lock_table(), which will be invoked before the dictionary is locked, will wait for purge to release any table handles. trx_t::drop_table_statistics(): Drop statistics for the table. This replaces dict_stats_drop_index(). We will drop or rename persistent statistics atomically as part of DDL transactions. On lock conflict for dropping statistics, we will fail instantly with DB_LOCK_WAIT_TIMEOUT, because we will be holding the exclusive data dictionary latch. trx_t::commit_cleanup(): Separated from trx_t::commit_in_memory(). Relax an assertion around fts_commit() and allow DB_LOCK_WAIT_TIMEOUT in addition to DB_DUPLICATE_KEY. The call to fts_commit() is entirely misplaced here and may obviously break the consistency of transactions that affect FULLTEXT INDEX. It needs to be fixed separately. dict_table_t::n_foreign_key_checks_running: Remove (MDEV-21175). The counter was a work-around for missing meta-data locking (MDL) on the SQL layer, and not really needed in MariaDB. ER_TABLE_IN_FK_CHECK: Replaced with ER_UNUSED_28. HA_ERR_TABLE_IN_FK_CHECK: Remove. row_ins_check_foreign_constraints(): Do not acquire dict_sys.latch either. The SQL-layer MDL will protect us. This was reviewed by Thirunarayanan Balathandayuthapani and tested by Matthias Leich.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (c) 2013 SkySQL Ab
|
/* Copyright (c) 2013, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -74,7 +74,6 @@
|
|||||||
{ "HA_ERR_INDEX_COL_TOO_LONG", HA_ERR_INDEX_COL_TOO_LONG, "" },
|
{ "HA_ERR_INDEX_COL_TOO_LONG", HA_ERR_INDEX_COL_TOO_LONG, "" },
|
||||||
{ "HA_ERR_INDEX_CORRUPT", HA_ERR_INDEX_CORRUPT, "" },
|
{ "HA_ERR_INDEX_CORRUPT", HA_ERR_INDEX_CORRUPT, "" },
|
||||||
{ "HA_ERR_UNDO_REC_TOO_BIG", HA_ERR_UNDO_REC_TOO_BIG, "" },
|
{ "HA_ERR_UNDO_REC_TOO_BIG", HA_ERR_UNDO_REC_TOO_BIG, "" },
|
||||||
{ "HA_ERR_TABLE_IN_FK_CHECK", HA_ERR_TABLE_IN_FK_CHECK, "" },
|
|
||||||
{ "HA_ERR_ROW_NOT_VISIBLE", HA_ERR_ROW_NOT_VISIBLE, "" },
|
{ "HA_ERR_ROW_NOT_VISIBLE", HA_ERR_ROW_NOT_VISIBLE, "" },
|
||||||
{ "HA_ERR_ABORTED_BY_USER", HA_ERR_ABORTED_BY_USER, "" },
|
{ "HA_ERR_ABORTED_BY_USER", HA_ERR_ABORTED_BY_USER, "" },
|
||||||
{ "HA_ERR_DISK_FULL", HA_ERR_DISK_FULL, "" },
|
{ "HA_ERR_DISK_FULL", HA_ERR_DISK_FULL, "" },
|
||||||
|
@@ -513,7 +513,7 @@ enum ha_base_keytype {
|
|||||||
#define HA_ERR_INDEX_CORRUPT 180 /* Index corrupted */
|
#define HA_ERR_INDEX_CORRUPT 180 /* Index corrupted */
|
||||||
#define HA_ERR_UNDO_REC_TOO_BIG 181 /* Undo log record too big */
|
#define HA_ERR_UNDO_REC_TOO_BIG 181 /* Undo log record too big */
|
||||||
#define HA_FTS_INVALID_DOCID 182 /* Invalid InnoDB Doc ID */
|
#define HA_FTS_INVALID_DOCID 182 /* Invalid InnoDB Doc ID */
|
||||||
#define HA_ERR_TABLE_IN_FK_CHECK 183 /* Table being used in foreign key check */
|
/* #define HA_ERR_TABLE_IN_FK_CHECK 183 */ /* Table being used in foreign key check */
|
||||||
#define HA_ERR_TABLESPACE_EXISTS 184 /* The tablespace existed in storage engine */
|
#define HA_ERR_TABLESPACE_EXISTS 184 /* The tablespace existed in storage engine */
|
||||||
#define HA_ERR_TOO_MANY_FIELDS 185 /* Table has too many columns */
|
#define HA_ERR_TOO_MANY_FIELDS 185 /* Table has too many columns */
|
||||||
#define HA_ERR_ROW_IN_WRONG_PARTITION 186 /* Row in wrong partition */
|
#define HA_ERR_ROW_IN_WRONG_PARTITION 186 /* Row in wrong partition */
|
||||||
|
@@ -97,10 +97,7 @@ call mtr.check_testcase();
|
|||||||
|
|
||||||
let $datadir=`select @@datadir`;
|
let $datadir=`select @@datadir`;
|
||||||
list_files $datadir mysql_upgrade_info;
|
list_files $datadir mysql_upgrade_info;
|
||||||
list_files_write_file $datadir.tempfiles.txt $datadir/test #sql*;
|
list_files $datadir/test #sql*;
|
||||||
--replace_regex /#sql-ib[1-9][0-9]*\.ibd\n//
|
|
||||||
cat_file $datadir.tempfiles.txt;
|
|
||||||
remove_file $datadir.tempfiles.txt;
|
|
||||||
list_files $datadir/mysql #sql*;
|
list_files $datadir/mysql #sql*;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@@ -86,11 +86,7 @@ show create table t1;
|
|||||||
--error ER_CONSTRAINT_FAILED
|
--error ER_CONSTRAINT_FAILED
|
||||||
insert t1 values (2, '2020-01-03', 20);
|
insert t1 values (2, '2020-01-03', 20);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
--let $regexp=/#sql-ib[0-9a-f]+\.ibd\n//
|
--list_files $datadir/test
|
||||||
--list_files_write_file $datadir.files.txt $datadir/test
|
|
||||||
--replace_regex $regexp
|
|
||||||
--cat_file $datadir.files.txt
|
|
||||||
--remove_file $datadir.files.txt
|
|
||||||
|
|
||||||
# MyISAM, different execution path
|
# MyISAM, different execution path
|
||||||
create table t1(id int, d date not null, b bool not null default 0, primary key(id,d))
|
create table t1(id int, d date not null, b bool not null default 0, primary key(id,d))
|
||||||
@@ -106,10 +102,7 @@ show create table t1;
|
|||||||
--error ER_CONSTRAINT_FAILED
|
--error ER_CONSTRAINT_FAILED
|
||||||
insert t1 values (2, '2020-01-03', 20);
|
insert t1 values (2, '2020-01-03', 20);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
--list_files_write_file $datadir.files.txt $datadir/test
|
--list_files $datadir/test
|
||||||
--replace_regex $regexp
|
|
||||||
--cat_file $datadir.files.txt
|
|
||||||
--remove_file $datadir.files.txt
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# MDEV-13097 Online alter of a partitioned MyISAM table with auto_increment
|
# MDEV-13097 Online alter of a partitioned MyISAM table with auto_increment
|
||||||
|
@@ -38,10 +38,6 @@ idxa n_diff_pfx01 a
|
|||||||
idxa n_diff_pfx02 a,DB_ROW_ID
|
idxa n_diff_pfx02 a,DB_ROW_ID
|
||||||
idxa n_leaf_pages Number of leaf pages in the index
|
idxa n_leaf_pages Number of leaf pages in the index
|
||||||
idxa size Number of pages in the index
|
idxa size Number of pages in the index
|
||||||
idxb n_diff_pfx01 b
|
|
||||||
idxb n_diff_pfx02 b,DB_ROW_ID
|
|
||||||
idxb n_leaf_pages Number of leaf pages in the index
|
|
||||||
idxb size Number of pages in the index
|
|
||||||
vidxcd n_diff_pfx01 c
|
vidxcd n_diff_pfx01 c
|
||||||
vidxcd n_diff_pfx02 c,d
|
vidxcd n_diff_pfx02 c,d
|
||||||
vidxcd n_diff_pfx03 c,d,DB_ROW_ID
|
vidxcd n_diff_pfx03 c,d,DB_ROW_ID
|
||||||
@@ -58,14 +54,6 @@ index_name stat_name stat_description
|
|||||||
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
|
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
|
||||||
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
|
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
|
||||||
GEN_CLUST_INDEX size Number of pages in the index
|
GEN_CLUST_INDEX size Number of pages in the index
|
||||||
idxb n_diff_pfx01 b
|
|
||||||
idxb n_diff_pfx02 b,DB_ROW_ID
|
|
||||||
idxb n_leaf_pages Number of leaf pages in the index
|
|
||||||
idxb size Number of pages in the index
|
|
||||||
vidxcd n_diff_pfx01 d
|
|
||||||
vidxcd n_diff_pfx02 d,DB_ROW_ID
|
|
||||||
vidxcd n_leaf_pages Number of leaf pages in the index
|
|
||||||
vidxcd size Number of pages in the index
|
|
||||||
ALTER TABLE t ADD INDEX vidxe (e), ALGORITHM=INPLACE;
|
ALTER TABLE t ADD INDEX vidxe (e), ALGORITHM=INPLACE;
|
||||||
select count(*) from t;
|
select count(*) from t;
|
||||||
count(*)
|
count(*)
|
||||||
@@ -77,18 +65,6 @@ index_name stat_name stat_description
|
|||||||
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
|
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
|
||||||
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
|
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
|
||||||
GEN_CLUST_INDEX size Number of pages in the index
|
GEN_CLUST_INDEX size Number of pages in the index
|
||||||
idxb n_diff_pfx01 b
|
|
||||||
idxb n_diff_pfx02 b,DB_ROW_ID
|
|
||||||
idxb n_leaf_pages Number of leaf pages in the index
|
|
||||||
idxb size Number of pages in the index
|
|
||||||
vidxcd n_diff_pfx01 d
|
|
||||||
vidxcd n_diff_pfx02 d,DB_ROW_ID
|
|
||||||
vidxcd n_leaf_pages Number of leaf pages in the index
|
|
||||||
vidxcd size Number of pages in the index
|
|
||||||
vidxe n_diff_pfx01 e
|
|
||||||
vidxe n_diff_pfx02 e,DB_ROW_ID
|
|
||||||
vidxe n_leaf_pages Number of leaf pages in the index
|
|
||||||
vidxe size Number of pages in the index
|
|
||||||
ALTER TABLE t ADD COLUMN f INT GENERATED ALWAYS AS(a + a), ADD INDEX vidxf (f), ALGORITHM=INPLACE;
|
ALTER TABLE t ADD COLUMN f INT GENERATED ALWAYS AS(a + a), ADD INDEX vidxf (f), ALGORITHM=INPLACE;
|
||||||
select count(*) from t;
|
select count(*) from t;
|
||||||
count(*)
|
count(*)
|
||||||
@@ -100,22 +76,6 @@ index_name stat_name stat_description
|
|||||||
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
|
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
|
||||||
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
|
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
|
||||||
GEN_CLUST_INDEX size Number of pages in the index
|
GEN_CLUST_INDEX size Number of pages in the index
|
||||||
idxb n_diff_pfx01 b
|
|
||||||
idxb n_diff_pfx02 b,DB_ROW_ID
|
|
||||||
idxb n_leaf_pages Number of leaf pages in the index
|
|
||||||
idxb size Number of pages in the index
|
|
||||||
vidxcd n_diff_pfx01 d
|
|
||||||
vidxcd n_diff_pfx02 d,DB_ROW_ID
|
|
||||||
vidxcd n_leaf_pages Number of leaf pages in the index
|
|
||||||
vidxcd size Number of pages in the index
|
|
||||||
vidxe n_diff_pfx01 e
|
|
||||||
vidxe n_diff_pfx02 e,DB_ROW_ID
|
|
||||||
vidxe n_leaf_pages Number of leaf pages in the index
|
|
||||||
vidxe size Number of pages in the index
|
|
||||||
vidxf n_diff_pfx01 f
|
|
||||||
vidxf n_diff_pfx02 f,DB_ROW_ID
|
|
||||||
vidxf n_leaf_pages Number of leaf pages in the index
|
|
||||||
vidxf size Number of pages in the index
|
|
||||||
ALTER TABLE t DROP INDEX vidxcd;
|
ALTER TABLE t DROP INDEX vidxcd;
|
||||||
SELECT index_name, stat_name, stat_description
|
SELECT index_name, stat_name, stat_description
|
||||||
FROM mysql.innodb_index_stats
|
FROM mysql.innodb_index_stats
|
||||||
@@ -124,16 +84,4 @@ index_name stat_name stat_description
|
|||||||
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
|
GEN_CLUST_INDEX n_diff_pfx01 DB_ROW_ID
|
||||||
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
|
GEN_CLUST_INDEX n_leaf_pages Number of leaf pages in the index
|
||||||
GEN_CLUST_INDEX size Number of pages in the index
|
GEN_CLUST_INDEX size Number of pages in the index
|
||||||
idxb n_diff_pfx01 b
|
|
||||||
idxb n_diff_pfx02 b,DB_ROW_ID
|
|
||||||
idxb n_leaf_pages Number of leaf pages in the index
|
|
||||||
idxb size Number of pages in the index
|
|
||||||
vidxe n_diff_pfx01 e
|
|
||||||
vidxe n_diff_pfx02 e,DB_ROW_ID
|
|
||||||
vidxe n_leaf_pages Number of leaf pages in the index
|
|
||||||
vidxe size Number of pages in the index
|
|
||||||
vidxf n_diff_pfx01 f
|
|
||||||
vidxf n_diff_pfx02 f,DB_ROW_ID
|
|
||||||
vidxf n_leaf_pages Number of leaf pages in the index
|
|
||||||
vidxf size Number of pages in the index
|
|
||||||
DROP TABLE t;
|
DROP TABLE t;
|
||||||
|
@@ -15,6 +15,5 @@ SELECT t.name 'Table Name',
|
|||||||
WHERE t.name not like 'SYS_%'
|
WHERE t.name not like 'SYS_%'
|
||||||
AND t.name NOT LIKE 'mysql/%'
|
AND t.name NOT LIKE 'mysql/%'
|
||||||
AND t.name NOT LIKE 'sys/%'
|
AND t.name NOT LIKE 'sys/%'
|
||||||
AND t.name NOT LIKE '%/#sql-ib%'
|
|
||||||
ORDER BY t.name;
|
ORDER BY t.name;
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
|
@@ -11,6 +11,6 @@ SELECT name 'Space_Name',
|
|||||||
filename 'Path'
|
filename 'Path'
|
||||||
FROM information_schema.innodb_sys_tablespaces
|
FROM information_schema.innodb_sys_tablespaces
|
||||||
WHERE name != 'innodb_system'
|
WHERE name != 'innodb_system'
|
||||||
AND name NOT LIKE 'mysql/%' AND name NOT LIKE '%/#sql-ib%'
|
AND name NOT LIKE 'mysql/%'
|
||||||
ORDER BY space;
|
ORDER BY space;
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
|
@@ -1,25 +0,0 @@
|
|||||||
CREATE TABLE t(c0 SERIAL, c1 INT, c2 INT, c3 INT, c4 INT,
|
|
||||||
KEY(c1), KEY(c2), KEY(c2,c1),
|
|
||||||
KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1),
|
|
||||||
KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1),
|
|
||||||
KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB;
|
|
||||||
CREATE TABLE `#mysql50##sql-ib-foo`(a SERIAL) ENGINE=InnoDB;
|
|
||||||
INSERT INTO t (c1) VALUES (1),(2),(1);
|
|
||||||
SET DEBUG_DBUG='+d,row_drop_table_add_to_background';
|
|
||||||
CREATE TABLE target (PRIMARY KEY(c1)) ENGINE=InnoDB SELECT * FROM t;
|
|
||||||
ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
|
||||||
SELECT * from target;
|
|
||||||
ERROR 42S02: Table 'test.target' doesn't exist
|
|
||||||
DROP TABLE t;
|
|
||||||
# restart
|
|
||||||
CREATE TABLE t (a INT) ENGINE=InnoDB;
|
|
||||||
DROP TABLE t;
|
|
||||||
DROP TABLE target;
|
|
||||||
ERROR 42S02: Unknown table 'test.target'
|
|
||||||
CREATE TABLE target (a INT) ENGINE=InnoDB;
|
|
||||||
DROP TABLE target;
|
|
||||||
SELECT * FROM `#mysql50##sql-ib-foo`;
|
|
||||||
ERROR 42S02: Table 'test.#mysql50##sql-ib-foo' doesn't exist in engine
|
|
||||||
DROP TABLE `#mysql50##sql-ib-foo`;
|
|
||||||
Warnings:
|
|
||||||
Warning 1932 Table 'test.#mysql50##sql-ib-foo' doesn't exist in engine
|
|
@@ -8,7 +8,6 @@ SET GLOBAL innodb_monitor_enable = module_ddl;
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -27,7 +26,6 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -81,7 +79,6 @@ SET DEBUG_SYNC = 'now WAIT_FOR scanned';
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -99,7 +96,6 @@ SET DEBUG_SYNC = 'now WAIT_FOR created';
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -113,7 +109,6 @@ ALTER TABLE t1 ADD UNIQUE INDEX(c2);
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -163,7 +158,6 @@ SET DEBUG_SYNC = 'now WAIT_FOR c2d_created';
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -175,7 +169,6 @@ ERROR 70100: Query execution was interrupted
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -243,7 +236,6 @@ SET DEBUG_SYNC = 'now WAIT_FOR c2e_created';
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -283,7 +275,6 @@ ROLLBACK;
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -316,7 +307,6 @@ ERROR HY000: Creating index 'c2e' required more than 'innodb_online_alter_log_ma
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 1
|
ddl_background_drop_indexes 1
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -328,7 +318,6 @@ name pos
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 1
|
ddl_background_drop_indexes 1
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -338,7 +327,6 @@ ALTER TABLE t1 COMMENT 'testing if c2e will be dropped';
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -363,7 +351,6 @@ SET DEBUG_SYNC = 'now WAIT_FOR c2f_created';
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -387,7 +374,6 @@ ROLLBACK;
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -400,7 +386,6 @@ ALTER TABLE t1 CHANGE c2 c22f INT;
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -464,7 +449,6 @@ name pos
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 1
|
ddl_background_drop_indexes 1
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -473,7 +457,6 @@ connection default;
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 1
|
ddl_background_drop_indexes 1
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -493,7 +476,6 @@ ALTER TABLE t1 DROP INDEX c2d, DROP INDEX c2f;
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
|
@@ -10,7 +10,6 @@ SET GLOBAL innodb_monitor_enable = module_ddl;
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -29,7 +28,6 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -95,7 +93,6 @@ SET DEBUG_SYNC = 'now WAIT_FOR scanned';
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -123,7 +120,6 @@ ALTER TABLE t1 DROP INDEX c2, ADD PRIMARY KEY(c1), ALGORITHM = INPLACE;
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -148,7 +144,6 @@ SET DEBUG_SYNC = 'now WAIT_FOR rebuilt';
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -164,7 +159,6 @@ ERROR 70100: Query execution was interrupted
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -215,7 +209,6 @@ SET DEBUG_SYNC = 'now WAIT_FOR rebuilt2';
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -247,7 +240,6 @@ ROLLBACK;
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -274,7 +266,6 @@ ERROR HY000: Creating index 'PRIMARY' required more than 'innodb_online_alter_lo
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 0
|
ddl_sort_file_alter_table 0
|
||||||
@@ -304,7 +295,6 @@ SET DEBUG_SYNC = 'now WAIT_FOR rebuilt3';
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 2
|
ddl_sort_file_alter_table 2
|
||||||
@@ -320,7 +310,6 @@ ROLLBACK;
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 1
|
ddl_online_create_index 1
|
||||||
ddl_pending_alter_table 1
|
ddl_pending_alter_table 1
|
||||||
ddl_sort_file_alter_table 2
|
ddl_sort_file_alter_table 2
|
||||||
@@ -330,7 +319,6 @@ connection con1;
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 2
|
ddl_sort_file_alter_table 2
|
||||||
@@ -410,7 +398,6 @@ SET DEBUG_SYNC = 'now SIGNAL ddl_timed_out';
|
|||||||
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl';
|
||||||
name count
|
name count
|
||||||
ddl_background_drop_indexes 0
|
ddl_background_drop_indexes 0
|
||||||
ddl_background_drop_tables 0
|
|
||||||
ddl_online_create_index 0
|
ddl_online_create_index 0
|
||||||
ddl_pending_alter_table 0
|
ddl_pending_alter_table 0
|
||||||
ddl_sort_file_alter_table 6
|
ddl_sort_file_alter_table 6
|
||||||
|
@@ -476,6 +476,7 @@ ALTER TABLE t1 IMPORT TABLESPACE;
|
|||||||
ERROR HY000: Index for table 't1' is corrupt; try to repair it
|
ERROR HY000: Index for table 't1' is corrupt; try to repair it
|
||||||
SET SESSION debug_dbug=@saved_debug_dbug;
|
SET SESSION debug_dbug=@saved_debug_dbug;
|
||||||
restore: t1 .ibd and .cfg files
|
restore: t1 .ibd and .cfg files
|
||||||
|
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
@@ -1,41 +1,22 @@
|
|||||||
DROP TABLE if exists t1;
|
|
||||||
select @@global.innodb_stats_persistent;
|
select @@global.innodb_stats_persistent;
|
||||||
@@global.innodb_stats_persistent
|
@@global.innodb_stats_persistent
|
||||||
0
|
0
|
||||||
set global innodb_defragment_stats_accuracy = 20;
|
set global innodb_defragment_stats_accuracy = 20;
|
||||||
# Create table.
|
CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(256), KEY SECOND(a, b))
|
||||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256), KEY SECOND(a, b)) ENGINE=INNODB;
|
ENGINE=INNODB;
|
||||||
# Populate data
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1_to_1024;
|
||||||
INSERT INTO t1 VALUES(1, REPEAT('A', 256));
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
# Not enough page splits to trigger persistent stats write yet.
|
# Not enough page splits to trigger persistent stats write yet.
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select * from mysql.innodb_index_stats where table_name='t1'
|
||||||
count(stat_value) = 0
|
and stat_name in ('n_page_split','n_pages_freed,n_leaf_pages_defrag');
|
||||||
1
|
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1025_to_2048;
|
||||||
count(stat_value) = 0
|
|
||||||
1
|
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
count(stat_value) = 0
|
|
||||||
1
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
# Persistent stats recorded.
|
# Persistent stats recorded.
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
select * from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
||||||
count(stat_value) = 0
|
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
||||||
1
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
# Delete some rows.
|
# Delete some rows.
|
||||||
@@ -62,13 +43,12 @@ delete from t1 where a between 100 * 1 and 100 * 1 + 30;
|
|||||||
# restart
|
# restart
|
||||||
# Server Restarted
|
# Server Restarted
|
||||||
# Confirm persistent stats still there after restart.
|
# Confirm persistent stats still there after restart.
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
select * from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
||||||
count(stat_value) = 0
|
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
||||||
1
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
optimize table t1;
|
optimize table t1;
|
||||||
@@ -77,101 +57,65 @@ test.t1 optimize status OK
|
|||||||
select sleep(2);
|
select sleep(2);
|
||||||
sleep(2)
|
sleep(2)
|
||||||
0
|
0
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
set global innodb_defragment_stats_accuracy = 40;
|
set global innodb_defragment_stats_accuracy = 40;
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_2049_to_4096;
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_4097_to_8192;
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
# Table rename should cause stats rename.
|
# Table rename should cause stats rename.
|
||||||
rename table t1 to t2;
|
rename table t1 to t2;
|
||||||
select sleep(1);
|
select * from mysql.innodb_index_stats where table_name = 't1';
|
||||||
sleep(1)
|
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
||||||
0
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_page_split');
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
|
||||||
count(stat_value) = 0
|
|
||||||
1
|
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
|
||||||
count(stat_value) = 0
|
|
||||||
1
|
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
count(stat_value) = 0
|
|
||||||
1
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
|
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_pages_freed');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_leaf_pages_defrag');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
# Drop index should cause stats drop.
|
# Drop index should cause stats drop.
|
||||||
drop index SECOND on t2;
|
drop index SECOND on t2;
|
||||||
select sleep(3);
|
select * from mysql.innodb_index_stats where table_name = 't2' and index_name = 'SECOND';
|
||||||
sleep(3)
|
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
||||||
0
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_page_split');
|
|
||||||
count(stat_value) > 0
|
|
||||||
1
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_pages_freed');
|
|
||||||
count(stat_value) > 0
|
|
||||||
1
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
count(stat_value) > 0
|
|
||||||
1
|
|
||||||
# restart
|
# restart
|
||||||
Server Restarted
|
Server Restarted
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_page_split');
|
||||||
count(stat_value) = 0
|
|
||||||
1
|
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
|
||||||
count(stat_value) = 0
|
|
||||||
1
|
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
count(stat_value) = 0
|
|
||||||
1
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
|
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_pages_freed');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_leaf_pages_defrag');
|
||||||
count(stat_value) > 0
|
count(stat_value) > 0
|
||||||
1
|
1
|
||||||
# Clean up
|
# Clean up
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
|
select * from mysql.innodb_index_stats where table_name = 't2';
|
||||||
count(stat_value) = 0
|
database_name table_name index_name last_update stat_name stat_value sample_size stat_description
|
||||||
1
|
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
|
|
||||||
count(stat_value) = 0
|
|
||||||
1
|
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
count(stat_value) = 0
|
|
||||||
1
|
|
||||||
|
@@ -228,7 +228,6 @@ innodb_master_thread_sleeps server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL N
|
|||||||
innodb_activity_count server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Current server activity count
|
innodb_activity_count server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Current server activity count
|
||||||
innodb_master_active_loops server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times master thread performs its tasks when server is active
|
innodb_master_active_loops server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times master thread performs its tasks when server is active
|
||||||
innodb_master_idle_loops server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times master thread performs its tasks when server is idle
|
innodb_master_idle_loops server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times master thread performs its tasks when server is idle
|
||||||
innodb_background_drop_table_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to process drop table list
|
|
||||||
innodb_log_flush_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to flush log records
|
innodb_log_flush_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to flush log records
|
||||||
innodb_dict_lru_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to process DICT LRU list
|
innodb_dict_lru_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to process DICT LRU list
|
||||||
innodb_dict_lru_count_active server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of tables evicted from DICT LRU list in the active loop
|
innodb_dict_lru_count_active server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of tables evicted from DICT LRU list in the active loop
|
||||||
@@ -245,7 +244,6 @@ dml_system_inserts dml 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 s
|
|||||||
dml_system_deletes dml 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of system rows deleted
|
dml_system_deletes dml 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of system rows deleted
|
||||||
dml_system_updates dml 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of system rows updated
|
dml_system_updates dml 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of system rows updated
|
||||||
ddl_background_drop_indexes ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of indexes waiting to be dropped after failed index creation
|
ddl_background_drop_indexes ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of indexes waiting to be dropped after failed index creation
|
||||||
ddl_background_drop_tables ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of tables in background drop table list
|
|
||||||
ddl_online_create_index ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of indexes being created online
|
ddl_online_create_index ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of indexes being created online
|
||||||
ddl_pending_alter_table ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of ALTER TABLE, CREATE INDEX, DROP INDEX in progress
|
ddl_pending_alter_table ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of ALTER TABLE, CREATE INDEX, DROP INDEX in progress
|
||||||
ddl_sort_file_alter_table ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of sort files created during alter table
|
ddl_sort_file_alter_table ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of sort files created during alter table
|
||||||
|
@@ -1,7 +1,14 @@
|
|||||||
|
CREATE DATABASE unlocked;
|
||||||
|
CREATE TABLE unlocked.t1(a INT PRIMARY KEY) ENGINE=INNODB STATS_PERSISTENT=0;
|
||||||
|
CREATE DATABASE locked;
|
||||||
|
CREATE TABLE locked.t1(a INT PRIMARY KEY) ENGINE=INNODB STATS_PERSISTENT=1;
|
||||||
|
CREATE TABLE innodb_stats_drop_locked (c INT, KEY c_key (c))
|
||||||
|
ENGINE=INNODB STATS_PERSISTENT=1;
|
||||||
|
ANALYZE TABLE innodb_stats_drop_locked;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.innodb_stats_drop_locked analyze status Engine-independent statistics collected
|
test.innodb_stats_drop_locked analyze status Engine-independent statistics collected
|
||||||
test.innodb_stats_drop_locked analyze status OK
|
test.innodb_stats_drop_locked analyze status OK
|
||||||
SET autocommit=0;
|
BEGIN;
|
||||||
SELECT table_name FROM mysql.innodb_table_stats
|
SELECT table_name FROM mysql.innodb_table_stats
|
||||||
WHERE table_name='innodb_stats_drop_locked'
|
WHERE table_name='innodb_stats_drop_locked'
|
||||||
FOR UPDATE;
|
FOR UPDATE;
|
||||||
@@ -19,21 +26,23 @@ innodb_stats_drop_locked
|
|||||||
innodb_stats_drop_locked
|
innodb_stats_drop_locked
|
||||||
innodb_stats_drop_locked
|
innodb_stats_drop_locked
|
||||||
connect con1,localhost,root,,;
|
connect con1,localhost,root,,;
|
||||||
connection con1;
|
|
||||||
ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
|
ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
|
||||||
Warnings:
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
Warning 1205 Unable to delete statistics for index c_key from mysql.innodb_index_stats because the rows are locked: Lock wait timeout. They can be deleted later using DELETE FROM mysql.innodb_index_stats WHERE database_name = 'test' AND table_name = 'innodb_stats_drop_locked' AND index_name = 'c_key';
|
|
||||||
SHOW CREATE TABLE innodb_stats_drop_locked;
|
SHOW CREATE TABLE innodb_stats_drop_locked;
|
||||||
Table Create Table
|
Table Create Table
|
||||||
innodb_stats_drop_locked CREATE TABLE `innodb_stats_drop_locked` (
|
innodb_stats_drop_locked CREATE TABLE `innodb_stats_drop_locked` (
|
||||||
`c` int(11) DEFAULT NULL
|
`c` int(11) DEFAULT NULL,
|
||||||
|
KEY `c_key` (`c`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=1
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1 STATS_PERSISTENT=1
|
||||||
DROP TABLE innodb_stats_drop_locked;
|
DROP TABLE innodb_stats_drop_locked;
|
||||||
SHOW TABLES;
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
Tables_in_test
|
DROP DATABASE unlocked;
|
||||||
connection default;
|
DROP DATABASE locked;
|
||||||
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
|
connection default;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
DROP DATABASE locked;
|
||||||
SELECT table_name FROM mysql.innodb_table_stats
|
SELECT table_name FROM mysql.innodb_table_stats
|
||||||
WHERE table_name='innodb_stats_drop_locked';
|
WHERE table_name='innodb_stats_drop_locked';
|
||||||
table_name
|
table_name
|
||||||
@@ -48,5 +57,17 @@ innodb_stats_drop_locked
|
|||||||
innodb_stats_drop_locked
|
innodb_stats_drop_locked
|
||||||
innodb_stats_drop_locked
|
innodb_stats_drop_locked
|
||||||
innodb_stats_drop_locked
|
innodb_stats_drop_locked
|
||||||
DELETE FROM mysql.innodb_index_stats WHERE database_name='test' AND table_name='innodb_stats_drop_locked';
|
ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
|
||||||
DELETE FROM mysql.innodb_table_stats WHERE database_name='test' AND table_name='innodb_stats_drop_locked';
|
SELECT table_name FROM mysql.innodb_index_stats
|
||||||
|
WHERE table_name='innodb_stats_drop_locked';
|
||||||
|
table_name
|
||||||
|
innodb_stats_drop_locked
|
||||||
|
innodb_stats_drop_locked
|
||||||
|
innodb_stats_drop_locked
|
||||||
|
DROP TABLE innodb_stats_drop_locked;
|
||||||
|
SELECT table_name FROM mysql.innodb_table_stats
|
||||||
|
WHERE table_name='innodb_stats_drop_locked';
|
||||||
|
table_name
|
||||||
|
SELECT table_name FROM mysql.innodb_index_stats
|
||||||
|
WHERE table_name='innodb_stats_drop_locked';
|
||||||
|
table_name
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
CREATE TABLE stats_rename1 (a INT, PRIMARY KEY (a))
|
CREATE TABLE stats_rename1 (a INT PRIMARY KEY, b INT UNIQUE)
|
||||||
ENGINE=INNODB STATS_PERSISTENT=1;
|
ENGINE=INNODB STATS_PERSISTENT=1;
|
||||||
|
BEGIN;
|
||||||
INSERT INTO mysql.innodb_table_stats
|
INSERT INTO mysql.innodb_table_stats
|
||||||
SELECT
|
SELECT
|
||||||
database_name,
|
database_name,
|
||||||
@@ -22,6 +23,7 @@ sample_size,
|
|||||||
stat_description
|
stat_description
|
||||||
FROM mysql.innodb_index_stats
|
FROM mysql.innodb_index_stats
|
||||||
WHERE table_name = 'stats_rename1';
|
WHERE table_name = 'stats_rename1';
|
||||||
|
COMMIT;
|
||||||
SELECT table_name, n_rows
|
SELECT table_name, n_rows
|
||||||
FROM mysql.innodb_table_stats
|
FROM mysql.innodb_table_stats
|
||||||
WHERE table_name IN ('stats_rename1', 'stats_rename2');
|
WHERE table_name IN ('stats_rename1', 'stats_rename2');
|
||||||
@@ -44,6 +46,18 @@ table_name stats_rename1
|
|||||||
index_name PRIMARY
|
index_name PRIMARY
|
||||||
stat_name size
|
stat_name size
|
||||||
stat_value 1
|
stat_value 1
|
||||||
|
table_name stats_rename1
|
||||||
|
index_name b
|
||||||
|
stat_name n_diff_pfx01
|
||||||
|
stat_value 0
|
||||||
|
table_name stats_rename1
|
||||||
|
index_name b
|
||||||
|
stat_name n_leaf_pages
|
||||||
|
stat_value 1
|
||||||
|
table_name stats_rename1
|
||||||
|
index_name b
|
||||||
|
stat_name size
|
||||||
|
stat_value 1
|
||||||
table_name stats_rename2
|
table_name stats_rename2
|
||||||
index_name PRIMARY
|
index_name PRIMARY
|
||||||
stat_name n_diff_pfx01
|
stat_name n_diff_pfx01
|
||||||
@@ -56,7 +70,32 @@ table_name stats_rename2
|
|||||||
index_name PRIMARY
|
index_name PRIMARY
|
||||||
stat_name size
|
stat_name size
|
||||||
stat_value 567
|
stat_value 567
|
||||||
|
table_name stats_rename2
|
||||||
|
index_name b
|
||||||
|
stat_name n_diff_pfx01
|
||||||
|
stat_value 567
|
||||||
|
table_name stats_rename2
|
||||||
|
index_name b
|
||||||
|
stat_name n_leaf_pages
|
||||||
|
stat_value 567
|
||||||
|
table_name stats_rename2
|
||||||
|
index_name b
|
||||||
|
stat_name size
|
||||||
|
stat_value 567
|
||||||
RENAME TABLE stats_rename1 TO stats_rename2;
|
RENAME TABLE stats_rename1 TO stats_rename2;
|
||||||
|
ERROR 23000: Can't write; duplicate key in table 'mysql.innodb_table_stats'
|
||||||
|
BEGIN;
|
||||||
|
DELETE FROM mysql.innodb_table_stats WHERE table_name='stats_rename2';
|
||||||
|
DELETE FROM mysql.innodb_index_stats WHERE table_name='stats_rename2';
|
||||||
|
COMMIT;
|
||||||
|
RENAME TABLE stats_rename1 TO stats_rename2;
|
||||||
|
UPDATE mysql.innodb_index_stats SET index_name='c'
|
||||||
|
WHERE table_name='stats_rename2' AND index_name='PRIMARY';
|
||||||
|
ALTER TABLE stats_rename2 CHANGE b d INT, RENAME INDEX b TO c;
|
||||||
|
ERROR 23000: Can't write; duplicate key in table 'mysql.innodb_index_stats'
|
||||||
|
UPDATE mysql.innodb_index_stats SET index_name='PRIMARY'
|
||||||
|
WHERE table_name='stats_rename2' AND index_name='c';
|
||||||
|
ALTER TABLE stats_rename2 CHANGE b d INT, RENAME INDEX b TO c;
|
||||||
SELECT table_name, n_rows
|
SELECT table_name, n_rows
|
||||||
FROM mysql.innodb_table_stats
|
FROM mysql.innodb_table_stats
|
||||||
WHERE table_name IN ('stats_rename1', 'stats_rename2');
|
WHERE table_name IN ('stats_rename1', 'stats_rename2');
|
||||||
@@ -77,4 +116,16 @@ table_name stats_rename2
|
|||||||
index_name PRIMARY
|
index_name PRIMARY
|
||||||
stat_name size
|
stat_name size
|
||||||
stat_value 1
|
stat_value 1
|
||||||
|
table_name stats_rename2
|
||||||
|
index_name c
|
||||||
|
stat_name n_diff_pfx01
|
||||||
|
stat_value 0
|
||||||
|
table_name stats_rename2
|
||||||
|
index_name c
|
||||||
|
stat_name n_leaf_pages
|
||||||
|
stat_value 1
|
||||||
|
table_name stats_rename2
|
||||||
|
index_name c
|
||||||
|
stat_name size
|
||||||
|
stat_value 1
|
||||||
DROP TABLE stats_rename2;
|
DROP TABLE stats_rename2;
|
||||||
|
@@ -74,6 +74,8 @@ DROP TABLE t2,t3;
|
|||||||
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
|
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
ERROR HY000: Can't create table `test`.`t0` (errno: 184 "Tablespace already exists")
|
ERROR HY000: Can't create table `test`.`t0` (errno: 184 "Tablespace already exists")
|
||||||
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
|
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
ERROR HY000: Can't create table `test`.`t0` (errno: 184 "Tablespace already exists")
|
||||||
|
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
DROP TABLE t0;
|
DROP TABLE t0;
|
||||||
CREATE TABLE u1(a INT PRIMARY KEY) ENGINE=InnoDB;
|
CREATE TABLE u1(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
CREATE TABLE u2(a INT PRIMARY KEY) ENGINE=InnoDB;
|
CREATE TABLE u2(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
@@ -194,7 +194,6 @@ innodb_master_thread_sleeps disabled
|
|||||||
innodb_activity_count disabled
|
innodb_activity_count disabled
|
||||||
innodb_master_active_loops disabled
|
innodb_master_active_loops disabled
|
||||||
innodb_master_idle_loops disabled
|
innodb_master_idle_loops disabled
|
||||||
innodb_background_drop_table_usec disabled
|
|
||||||
innodb_log_flush_usec disabled
|
innodb_log_flush_usec disabled
|
||||||
innodb_dict_lru_usec disabled
|
innodb_dict_lru_usec disabled
|
||||||
innodb_dict_lru_count_active disabled
|
innodb_dict_lru_count_active disabled
|
||||||
@@ -211,7 +210,6 @@ dml_system_inserts disabled
|
|||||||
dml_system_deletes disabled
|
dml_system_deletes disabled
|
||||||
dml_system_updates disabled
|
dml_system_updates disabled
|
||||||
ddl_background_drop_indexes disabled
|
ddl_background_drop_indexes disabled
|
||||||
ddl_background_drop_tables disabled
|
|
||||||
ddl_online_create_index disabled
|
ddl_online_create_index disabled
|
||||||
ddl_pending_alter_table disabled
|
ddl_pending_alter_table disabled
|
||||||
ddl_sort_file_alter_table disabled
|
ddl_sort_file_alter_table disabled
|
||||||
|
@@ -1,31 +0,0 @@
|
|||||||
FLUSH TABLES;
|
|
||||||
CREATE TABLE t1 (a SERIAL, b INT, c INT, d INT) ENGINE=InnoDB;
|
|
||||||
INSERT INTO t1 () VALUES ();
|
|
||||||
connect con1,localhost,root,,test;
|
|
||||||
SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever';
|
|
||||||
RENAME TABLE t1 TO t2;
|
|
||||||
connection default;
|
|
||||||
SET DEBUG_SYNC='now WAIT_FOR renamed';
|
|
||||||
# restart
|
|
||||||
disconnect con1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
a b c d
|
|
||||||
1 NULL NULL NULL
|
|
||||||
CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
|
||||||
BEGIN;
|
|
||||||
INSERT INTO t2 VALUES(1);
|
|
||||||
connect con1,localhost,root,,test;
|
|
||||||
SET DEBUG_SYNC='innodb_rename_in_cache SIGNAL committed WAIT_FOR ever';
|
|
||||||
RENAME TABLE t1 TO t3;
|
|
||||||
connection default;
|
|
||||||
SET DEBUG_SYNC='now WAIT_FOR committed';
|
|
||||||
COMMIT;
|
|
||||||
# restart
|
|
||||||
disconnect con1;
|
|
||||||
SELECT * FROM t1;
|
|
||||||
a b c d
|
|
||||||
1 NULL NULL NULL
|
|
||||||
SELECT * FROM t2;
|
|
||||||
a
|
|
||||||
1
|
|
||||||
DROP TABLE t1,t2;
|
|
@@ -50,3 +50,13 @@ Warnings:
|
|||||||
Warning 1814 Tablespace has been discarded for table `u`
|
Warning 1814 Tablespace has been discarded for table `u`
|
||||||
TRUNCATE u;
|
TRUNCATE u;
|
||||||
DROP TABLE u;
|
DROP TABLE u;
|
||||||
|
#
|
||||||
|
# Test for a regression found during MDEV-25506 rewrite of DROP
|
||||||
|
#
|
||||||
|
CREATE TEMPORARY TABLE t1 (a INT) ENGINE=InnoDB;
|
||||||
|
LOCK TABLE t1 READ;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TEMPORARY TABLE t1;
|
||||||
|
# End of 10.6 tests
|
||||||
|
@@ -18,8 +18,9 @@ disconnect con2;
|
|||||||
connect con1,localhost,root;
|
connect con1,localhost,root;
|
||||||
SELECT * FROM t1 LOCK IN SHARE MODE;
|
SELECT * FROM t1 LOCK IN SHARE MODE;
|
||||||
connection default;
|
connection default;
|
||||||
|
SET innodb_lock_wait_timeout=1;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
# restart
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
@@ -30,6 +31,9 @@ SELECT * FROM t1;
|
|||||||
a
|
a
|
||||||
1
|
1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||||
|
XA ROLLBACK 'y';
|
||||||
|
DROP TABLE t2;
|
||||||
SET GLOBAL innodb_fast_shutdown=0;
|
SET GLOBAL innodb_fast_shutdown=0;
|
||||||
# restart
|
# restart
|
||||||
XA ROLLBACK 'y';
|
|
||||||
|
@@ -46,16 +46,15 @@ CREATE TABLE tab(a INT) ENGINE=InnoDB;
|
|||||||
# Remove the *.ibd file
|
# Remove the *.ibd file
|
||||||
ALTER TABLE tab DISCARD TABLESPACE;
|
ALTER TABLE tab DISCARD TABLESPACE;
|
||||||
|
|
||||||
# Move the *.ibd,*.cfg file into orginal location
|
# Move the *.ibd,*.cfg file into original location
|
||||||
--move_file $MYSQLD_DATADIR/tab.cfg $MYSQLD_DATADIR/test/tab.cfg
|
--move_file $MYSQLD_DATADIR/tab.cfg $MYSQLD_DATADIR/test/tab.cfg
|
||||||
--move_file $MYSQLD_DATADIR/tab.ibd $MYSQLD_DATADIR/test/tab.ibd
|
--move_file $MYSQLD_DATADIR/tab.ibd $MYSQLD_DATADIR/test/tab.ibd
|
||||||
|
|
||||||
--error ER_TABLE_SCHEMA_MISMATCH
|
--error ER_TABLE_SCHEMA_MISMATCH
|
||||||
ALTER TABLE tab IMPORT TABLESPACE;
|
ALTER TABLE tab IMPORT TABLESPACE;
|
||||||
|
|
||||||
# Take the backup of the ibd and cfg files
|
--move_file $MYSQLD_DATADIR/test/tab.cfg $MYSQLD_DATADIR/tab.cfg
|
||||||
--copy_file $MYSQLD_DATADIR/test/tab.cfg $MYSQLD_DATADIR/tab.cfg
|
--move_file $MYSQLD_DATADIR/test/tab.ibd $MYSQLD_DATADIR/tab.ibd
|
||||||
--copy_file $MYSQLD_DATADIR/test/tab.ibd $MYSQLD_DATADIR/tab.ibd
|
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
DROP TABLE tab;
|
DROP TABLE tab;
|
||||||
|
@@ -1,48 +0,0 @@
|
|||||||
--source include/have_innodb.inc
|
|
||||||
--source include/have_debug.inc
|
|
||||||
# Embedded server does not support restarting
|
|
||||||
--source include/not_embedded.inc
|
|
||||||
|
|
||||||
let $MYSQLD_DATADIR=`select @@datadir`;
|
|
||||||
|
|
||||||
CREATE TABLE t(c0 SERIAL, c1 INT, c2 INT, c3 INT, c4 INT,
|
|
||||||
KEY(c1), KEY(c2), KEY(c2,c1),
|
|
||||||
KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1),
|
|
||||||
KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1),
|
|
||||||
KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB;
|
|
||||||
|
|
||||||
CREATE TABLE `#mysql50##sql-ib-foo`(a SERIAL) ENGINE=InnoDB;
|
|
||||||
INSERT INTO t (c1) VALUES (1),(2),(1);
|
|
||||||
|
|
||||||
let $n= 10;
|
|
||||||
|
|
||||||
SET DEBUG_DBUG='+d,row_drop_table_add_to_background';
|
|
||||||
--disable_query_log
|
|
||||||
let $i= $n;
|
|
||||||
while ($i) {
|
|
||||||
eval CREATE TABLE t$i LIKE t;
|
|
||||||
dec $i;
|
|
||||||
}
|
|
||||||
let $i= $n;
|
|
||||||
while ($i) {
|
|
||||||
eval DROP TABLE t$i;
|
|
||||||
dec $i;
|
|
||||||
}
|
|
||||||
--enable_query_log
|
|
||||||
--error ER_DUP_ENTRY
|
|
||||||
CREATE TABLE target (PRIMARY KEY(c1)) ENGINE=InnoDB SELECT * FROM t;
|
|
||||||
--error ER_NO_SUCH_TABLE
|
|
||||||
SELECT * from target;
|
|
||||||
DROP TABLE t;
|
|
||||||
--source include/shutdown_mysqld.inc
|
|
||||||
--remove_files_wildcard $MYSQLD_DATADIR/test #sql-*.ibd
|
|
||||||
--source include/start_mysqld.inc
|
|
||||||
CREATE TABLE t (a INT) ENGINE=InnoDB;
|
|
||||||
DROP TABLE t;
|
|
||||||
--error ER_BAD_TABLE_ERROR
|
|
||||||
DROP TABLE target;
|
|
||||||
CREATE TABLE target (a INT) ENGINE=InnoDB;
|
|
||||||
DROP TABLE target;
|
|
||||||
--error ER_NO_SUCH_TABLE_IN_ENGINE
|
|
||||||
SELECT * FROM `#mysql50##sql-ib-foo`;
|
|
||||||
DROP TABLE `#mysql50##sql-ib-foo`;
|
|
@@ -1014,6 +1014,7 @@ do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
|
|||||||
ib_restore_tablespaces("test", "t1");
|
ib_restore_tablespaces("test", "t1");
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@@ -96,6 +96,10 @@ if ($checksum_algorithm == "strict_full_crc32") {
|
|||||||
ALTER TABLE t2 IMPORT TABLESPACE;
|
ALTER TABLE t2 IMPORT TABLESPACE;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
|
|
||||||
|
if ($error_code) {
|
||||||
|
--remove_file $MYSQLD_DATADIR/test/t2.ibd
|
||||||
|
}
|
||||||
|
|
||||||
SET GLOBAL innodb_file_per_table = 1;
|
SET GLOBAL innodb_file_per_table = 1;
|
||||||
SELECT @@innodb_file_per_table;
|
SELECT @@innodb_file_per_table;
|
||||||
|
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
SET @innodb_file_per_table_orig=@@GLOBAL.innodb_file_per_table;
|
SET @innodb_file_per_table_orig=@@GLOBAL.innodb_file_per_table;
|
||||||
LET $regexp=/FTS_[0-9a-f_]+([A-Z0-9_]+)\.([islbd]{3})/FTS_AUX_\1.\2/ /#sql-ib[1-9][0-9]*\.ibd\n//;
|
LET $regexp=/FTS_[0-9a-f_]+([A-Z0-9_]+)\.([islbd]{3})/FTS_AUX_\1.\2/;
|
||||||
|
|
||||||
# Set up some variables
|
# Set up some variables
|
||||||
LET $MYSQL_DATA_DIR = `select @@datadir`;
|
LET $MYSQL_DATA_DIR = `select @@datadir`;
|
||||||
|
@@ -1,46 +1,26 @@
|
|||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_sequence.inc
|
||||||
--source include/big_test.inc
|
--source include/big_test.inc
|
||||||
--source include/not_valgrind.inc
|
--source include/not_valgrind.inc
|
||||||
--source include/not_embedded.inc
|
--source include/not_embedded.inc
|
||||||
|
|
||||||
--disable_warnings
|
|
||||||
DROP TABLE if exists t1;
|
|
||||||
--enable_warnings
|
|
||||||
|
|
||||||
--disable_query_log
|
|
||||||
let $innodb_defragment_stats_accuracy_orig=`select @@innodb_defragment_stats_accuracy`;
|
|
||||||
--enable_query_log
|
|
||||||
|
|
||||||
select @@global.innodb_stats_persistent;
|
select @@global.innodb_stats_persistent;
|
||||||
set global innodb_defragment_stats_accuracy = 20;
|
set global innodb_defragment_stats_accuracy = 20;
|
||||||
|
|
||||||
--echo # Create table.
|
CREATE TABLE t1(a INT PRIMARY KEY, b VARCHAR(256), KEY SECOND(a, b))
|
||||||
CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256), KEY SECOND(a, b)) ENGINE=INNODB;
|
ENGINE=INNODB;
|
||||||
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1_to_1024;
|
||||||
--echo # Populate data
|
|
||||||
INSERT INTO t1 VALUES(1, REPEAT('A', 256));
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
|
||||||
|
|
||||||
--echo # Not enough page splits to trigger persistent stats write yet.
|
--echo # Not enough page splits to trigger persistent stats write yet.
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select * from mysql.innodb_index_stats where table_name='t1'
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
and stat_name in ('n_page_split','n_pages_freed,n_leaf_pages_defrag');
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_1025_to_2048;
|
||||||
|
|
||||||
--echo # Persistent stats recorded.
|
--echo # Persistent stats recorded.
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
select * from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
--echo # Delete some rows.
|
--echo # Delete some rows.
|
||||||
let $num_delete = 20;
|
let $num_delete = 20;
|
||||||
@@ -55,71 +35,53 @@ while ($num_delete)
|
|||||||
--echo # Server Restarted
|
--echo # Server Restarted
|
||||||
|
|
||||||
--echo # Confirm persistent stats still there after restart.
|
--echo # Confirm persistent stats still there after restart.
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
select * from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
optimize table t1;
|
optimize table t1;
|
||||||
select sleep(2);
|
select sleep(2);
|
||||||
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
set global innodb_defragment_stats_accuracy = 40;
|
set global innodb_defragment_stats_accuracy = 40;
|
||||||
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_2049_to_4096;
|
||||||
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
|
INSERT INTO t1 SELECT seq, REPEAT('A', 256) FROM seq_4097_to_8192;
|
||||||
|
|
||||||
INSERT INTO t1 (b) SELECT b from t1;
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_page_split');
|
||||||
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_pages_freed');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't1' and stat_name in ('n_leaf_pages_defrag');
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
|
|
||||||
|
|
||||||
--echo # Table rename should cause stats rename.
|
--echo # Table rename should cause stats rename.
|
||||||
rename table t1 to t2;
|
rename table t1 to t2;
|
||||||
select sleep(1);
|
select * from mysql.innodb_index_stats where table_name = 't1';
|
||||||
|
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_page_split');
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_pages_freed');
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
|
|
||||||
--echo # Drop index should cause stats drop.
|
--echo # Drop index should cause stats drop.
|
||||||
drop index SECOND on t2;
|
drop index SECOND on t2;
|
||||||
select sleep(3);
|
|
||||||
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_page_split');
|
select * from mysql.innodb_index_stats where table_name = 't2' and index_name = 'SECOND';
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_pages_freed');
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and index_name = 'SECOND' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
|
|
||||||
--source include/restart_mysqld.inc
|
--source include/restart_mysqld.inc
|
||||||
--echo Server Restarted
|
--echo Server Restarted
|
||||||
|
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_page_split');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_page_split');
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_pages_freed');
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_leaf_pages_defrag');
|
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name = 't2' and stat_name in ('n_leaf_pages_defrag');
|
||||||
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
|
|
||||||
select count(stat_value) > 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
|
|
||||||
--echo # Clean up
|
--echo # Clean up
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
|
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_page_split');
|
select * from mysql.innodb_index_stats where table_name = 't2';
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_pages_freed');
|
|
||||||
select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like '%t2%' and stat_name in ('n_leaf_pages_defrag');
|
|
||||||
|
|
||||||
--disable_query_log
|
|
||||||
EVAL SET GLOBAL innodb_defragment_stats_accuracy = $innodb_defragment_stats_accuracy_orig;
|
|
||||||
--enable_query_log
|
|
||||||
|
@@ -5,49 +5,42 @@
|
|||||||
|
|
||||||
-- source include/have_innodb.inc
|
-- source include/have_innodb.inc
|
||||||
|
|
||||||
-- disable_warnings
|
CREATE DATABASE unlocked;
|
||||||
-- disable_query_log
|
CREATE TABLE unlocked.t1(a INT PRIMARY KEY) ENGINE=INNODB STATS_PERSISTENT=0;
|
||||||
|
CREATE DATABASE locked;
|
||||||
DROP TABLE IF EXISTS innodb_stats_drop_locked;
|
CREATE TABLE locked.t1(a INT PRIMARY KEY) ENGINE=INNODB STATS_PERSISTENT=1;
|
||||||
|
|
||||||
CREATE TABLE innodb_stats_drop_locked (c INT, KEY c_key (c))
|
CREATE TABLE innodb_stats_drop_locked (c INT, KEY c_key (c))
|
||||||
ENGINE=INNODB STATS_PERSISTENT=1;
|
ENGINE=INNODB STATS_PERSISTENT=1;
|
||||||
|
|
||||||
ANALYZE TABLE innodb_stats_drop_locked;
|
ANALYZE TABLE innodb_stats_drop_locked;
|
||||||
|
|
||||||
-- enable_warnings
|
BEGIN;
|
||||||
-- enable_query_log
|
|
||||||
|
|
||||||
SET autocommit=0;
|
|
||||||
|
|
||||||
SELECT table_name FROM mysql.innodb_table_stats
|
SELECT table_name FROM mysql.innodb_table_stats
|
||||||
WHERE table_name='innodb_stats_drop_locked'
|
WHERE table_name='innodb_stats_drop_locked'
|
||||||
FOR UPDATE;
|
FOR UPDATE;
|
||||||
|
|
||||||
SELECT table_name FROM mysql.innodb_index_stats
|
SELECT table_name FROM mysql.innodb_index_stats
|
||||||
WHERE table_name='innodb_stats_drop_locked'
|
WHERE table_name='innodb_stats_drop_locked'
|
||||||
FOR UPDATE;
|
FOR UPDATE;
|
||||||
|
|
||||||
-- connect (con1,localhost,root,,)
|
-- connect (con1,localhost,root,,)
|
||||||
|
--error ER_LOCK_WAIT_TIMEOUT
|
||||||
-- connection con1
|
|
||||||
|
|
||||||
ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
|
ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
|
||||||
|
|
||||||
# the index should be gone
|
# the index should be gone
|
||||||
SHOW CREATE TABLE innodb_stats_drop_locked;
|
SHOW CREATE TABLE innodb_stats_drop_locked;
|
||||||
|
|
||||||
|
--error ER_LOCK_WAIT_TIMEOUT
|
||||||
DROP TABLE innodb_stats_drop_locked;
|
DROP TABLE innodb_stats_drop_locked;
|
||||||
|
|
||||||
# the table should be gone
|
DROP DATABASE unlocked;
|
||||||
SHOW TABLES;
|
--error ER_LOCK_WAIT_TIMEOUT
|
||||||
|
DROP DATABASE locked;
|
||||||
-- connection default
|
|
||||||
|
|
||||||
-- disconnect con1
|
-- disconnect con1
|
||||||
|
-- connection default
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
DROP DATABASE locked;
|
||||||
|
|
||||||
# the stats should be there
|
# the stats should be there
|
||||||
|
|
||||||
SELECT table_name FROM mysql.innodb_table_stats
|
SELECT table_name FROM mysql.innodb_table_stats
|
||||||
@@ -56,8 +49,15 @@ WHERE table_name='innodb_stats_drop_locked';
|
|||||||
SELECT table_name FROM mysql.innodb_index_stats
|
SELECT table_name FROM mysql.innodb_index_stats
|
||||||
WHERE table_name='innodb_stats_drop_locked';
|
WHERE table_name='innodb_stats_drop_locked';
|
||||||
|
|
||||||
DELETE FROM mysql.innodb_index_stats WHERE database_name='test' AND table_name='innodb_stats_drop_locked';
|
ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
|
||||||
DELETE FROM mysql.innodb_table_stats WHERE database_name='test' AND table_name='innodb_stats_drop_locked';
|
|
||||||
--disable_query_log
|
SELECT table_name FROM mysql.innodb_index_stats
|
||||||
call mtr.add_suppression("Unable to delete statistics for table test.innodb_stats_drop_locked: Lock wait timeout. They can be deleted later using DELETE FROM mysql.innodb_index_stats WHERE database_name");
|
WHERE table_name='innodb_stats_drop_locked';
|
||||||
--enable_query_log
|
|
||||||
|
DROP TABLE innodb_stats_drop_locked;
|
||||||
|
|
||||||
|
SELECT table_name FROM mysql.innodb_table_stats
|
||||||
|
WHERE table_name='innodb_stats_drop_locked';
|
||||||
|
|
||||||
|
SELECT table_name FROM mysql.innodb_index_stats
|
||||||
|
WHERE table_name='innodb_stats_drop_locked';
|
||||||
|
@@ -10,9 +10,10 @@
|
|||||||
|
|
||||||
-- vertical_results
|
-- vertical_results
|
||||||
|
|
||||||
CREATE TABLE stats_rename1 (a INT, PRIMARY KEY (a))
|
CREATE TABLE stats_rename1 (a INT PRIMARY KEY, b INT UNIQUE)
|
||||||
ENGINE=INNODB STATS_PERSISTENT=1;
|
ENGINE=INNODB STATS_PERSISTENT=1;
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
INSERT INTO mysql.innodb_table_stats
|
INSERT INTO mysql.innodb_table_stats
|
||||||
SELECT
|
SELECT
|
||||||
database_name,
|
database_name,
|
||||||
@@ -36,6 +37,7 @@ sample_size,
|
|||||||
stat_description
|
stat_description
|
||||||
FROM mysql.innodb_index_stats
|
FROM mysql.innodb_index_stats
|
||||||
WHERE table_name = 'stats_rename1';
|
WHERE table_name = 'stats_rename1';
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
SELECT table_name, n_rows
|
SELECT table_name, n_rows
|
||||||
FROM mysql.innodb_table_stats
|
FROM mysql.innodb_table_stats
|
||||||
@@ -45,7 +47,22 @@ SELECT table_name, index_name, stat_name, stat_value
|
|||||||
FROM mysql.innodb_index_stats
|
FROM mysql.innodb_index_stats
|
||||||
WHERE table_name IN ('stats_rename1', 'stats_rename2');
|
WHERE table_name IN ('stats_rename1', 'stats_rename2');
|
||||||
|
|
||||||
|
--error ER_DUP_KEY
|
||||||
RENAME TABLE stats_rename1 TO stats_rename2;
|
RENAME TABLE stats_rename1 TO stats_rename2;
|
||||||
|
BEGIN;
|
||||||
|
DELETE FROM mysql.innodb_table_stats WHERE table_name='stats_rename2';
|
||||||
|
DELETE FROM mysql.innodb_index_stats WHERE table_name='stats_rename2';
|
||||||
|
COMMIT;
|
||||||
|
RENAME TABLE stats_rename1 TO stats_rename2;
|
||||||
|
|
||||||
|
UPDATE mysql.innodb_index_stats SET index_name='c'
|
||||||
|
WHERE table_name='stats_rename2' AND index_name='PRIMARY';
|
||||||
|
--error ER_DUP_KEY
|
||||||
|
ALTER TABLE stats_rename2 CHANGE b d INT, RENAME INDEX b TO c;
|
||||||
|
UPDATE mysql.innodb_index_stats SET index_name='PRIMARY'
|
||||||
|
WHERE table_name='stats_rename2' AND index_name='c';
|
||||||
|
|
||||||
|
ALTER TABLE stats_rename2 CHANGE b d INT, RENAME INDEX b TO c;
|
||||||
|
|
||||||
SELECT table_name, n_rows
|
SELECT table_name, n_rows
|
||||||
FROM mysql.innodb_table_stats
|
FROM mysql.innodb_table_stats
|
||||||
|
@@ -79,6 +79,7 @@ select * from t1;
|
|||||||
alter table t1 import tablespace;
|
alter table t1 import tablespace;
|
||||||
--error ER_TABLESPACE_DISCARDED
|
--error ER_TABLESPACE_DISCARDED
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
--remove_file $MYSQLD_DATADIR/test/t1.ibd
|
||||||
|
|
||||||
drop table t2;
|
drop table t2;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
@@ -137,7 +137,9 @@ DROP TABLE t2,t3;
|
|||||||
|
|
||||||
--error ER_CANT_CREATE_TABLE
|
--error ER_CANT_CREATE_TABLE
|
||||||
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
|
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
--error ER_CANT_CREATE_TABLE
|
||||||
|
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
--remove_file $MYSQLD_DATADIR/test/t0.ibd
|
||||||
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
|
CREATE TABLE t0(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
DROP TABLE t0;
|
DROP TABLE t0;
|
||||||
|
|
||||||
|
@@ -1,41 +0,0 @@
|
|||||||
--source include/have_innodb.inc
|
|
||||||
--source include/have_debug.inc
|
|
||||||
--source include/have_debug_sync.inc
|
|
||||||
--source include/not_embedded.inc
|
|
||||||
|
|
||||||
FLUSH TABLES;
|
|
||||||
LET $datadir= `SELECT @@datadir`;
|
|
||||||
|
|
||||||
CREATE TABLE t1 (a SERIAL, b INT, c INT, d INT) ENGINE=InnoDB;
|
|
||||||
INSERT INTO t1 () VALUES ();
|
|
||||||
|
|
||||||
--connect (con1,localhost,root,,test)
|
|
||||||
SET DEBUG_SYNC='before_rename_table_commit SIGNAL renamed WAIT_FOR ever';
|
|
||||||
--send
|
|
||||||
RENAME TABLE t1 TO t2;
|
|
||||||
--connection default
|
|
||||||
SET DEBUG_SYNC='now WAIT_FOR renamed';
|
|
||||||
--let $shutdown_timeout=0
|
|
||||||
--source include/restart_mysqld.inc
|
|
||||||
--disconnect con1
|
|
||||||
SELECT * FROM t1;
|
|
||||||
|
|
||||||
CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
|
||||||
BEGIN;
|
|
||||||
INSERT INTO t2 VALUES(1);
|
|
||||||
|
|
||||||
--connect (con1,localhost,root,,test)
|
|
||||||
SET DEBUG_SYNC='innodb_rename_in_cache SIGNAL committed WAIT_FOR ever';
|
|
||||||
--send
|
|
||||||
RENAME TABLE t1 TO t3;
|
|
||||||
--connection default
|
|
||||||
SET DEBUG_SYNC='now WAIT_FOR committed';
|
|
||||||
COMMIT;
|
|
||||||
|
|
||||||
--let $shutdown_timeout=0
|
|
||||||
--source include/restart_mysqld.inc
|
|
||||||
--disconnect con1
|
|
||||||
SELECT * FROM t1;
|
|
||||||
SELECT * FROM t2;
|
|
||||||
|
|
||||||
DROP TABLE t1,t2;
|
|
@@ -1,7 +1,6 @@
|
|||||||
--source include/innodb_page_size.inc
|
--source include/innodb_page_size.inc
|
||||||
# Embedded server tests do not support restarting
|
# Embedded server tests do not support restarting
|
||||||
--source include/not_embedded.inc
|
--source include/not_embedded.inc
|
||||||
--source include/maybe_debug.inc
|
|
||||||
|
|
||||||
--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");
|
||||||
@@ -31,9 +30,6 @@ let bugdir= $MYSQLTEST_VARDIR/tmp/table_flags;
|
|||||||
--let $d=$d --innodb-undo-tablespaces=0
|
--let $d=$d --innodb-undo-tablespaces=0
|
||||||
--let $d=$d --innodb-purge-rseg-truncate-frequency=1
|
--let $d=$d --innodb-purge-rseg-truncate-frequency=1
|
||||||
--let $d=$d --skip-innodb-fast-shutdown
|
--let $d=$d --skip-innodb-fast-shutdown
|
||||||
if ($have_debug) {
|
|
||||||
--let $d=$d --debug=d,create_and_drop_garbage
|
|
||||||
}
|
|
||||||
--let $restart_noprint=1
|
--let $restart_noprint=1
|
||||||
--let $restart_parameters=$d --innodb-stats-persistent=0
|
--let $restart_parameters=$d --innodb-stats-persistent=0
|
||||||
--source include/restart_mysqld.inc
|
--source include/restart_mysqld.inc
|
||||||
|
@@ -67,3 +67,15 @@ RENAME TABLE t TO u;
|
|||||||
TRUNCATE u;
|
TRUNCATE u;
|
||||||
TRUNCATE u;
|
TRUNCATE u;
|
||||||
DROP TABLE u;
|
DROP TABLE u;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Test for a regression found during MDEV-25506 rewrite of DROP
|
||||||
|
--echo #
|
||||||
|
CREATE TEMPORARY TABLE t1 (a INT) ENGINE=InnoDB;
|
||||||
|
LOCK TABLE t1 READ;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
TRUNCATE TABLE t1;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TEMPORARY TABLE t1;
|
||||||
|
|
||||||
|
--echo # End of 10.6 tests
|
||||||
|
@@ -39,10 +39,10 @@ let $wait_condition=
|
|||||||
info = 'SELECT * FROM t1 LOCK IN SHARE MODE';
|
info = 'SELECT * FROM t1 LOCK IN SHARE MODE';
|
||||||
--source include/wait_condition.inc
|
--source include/wait_condition.inc
|
||||||
|
|
||||||
|
SET innodb_lock_wait_timeout=1;
|
||||||
|
--error ER_LOCK_WAIT_TIMEOUT
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
|
|
||||||
--source include/restart_mysqld.inc
|
|
||||||
|
|
||||||
disconnect con1;
|
disconnect con1;
|
||||||
|
|
||||||
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
|
||||||
@@ -51,8 +51,10 @@ XA ROLLBACK 'x';
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
--error ER_LOCK_WAIT_TIMEOUT
|
||||||
|
DROP TABLE t2;
|
||||||
|
XA ROLLBACK 'y';
|
||||||
|
DROP TABLE t2;
|
||||||
|
|
||||||
SET GLOBAL innodb_fast_shutdown=0;
|
SET GLOBAL innodb_fast_shutdown=0;
|
||||||
--source include/restart_mysqld.inc
|
--source include/restart_mysqld.inc
|
||||||
|
|
||||||
XA ROLLBACK 'y';
|
|
||||||
|
@@ -33,6 +33,10 @@ connection default;
|
|||||||
disconnect ddl1;
|
disconnect ddl1;
|
||||||
disconnect ddl2;
|
disconnect ddl2;
|
||||||
disconnect ddl3;
|
disconnect ddl3;
|
||||||
|
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
||||||
|
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
||||||
|
InnoDB 0 transactions not purged
|
||||||
|
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
|
||||||
CHECK TABLE t1,t2,t3;
|
CHECK TABLE t1,t2,t3;
|
||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
@@ -151,6 +155,5 @@ id title body
|
|||||||
1 MySQL Tutorial DBMS stands for Database...
|
1 MySQL Tutorial DBMS stands for Database...
|
||||||
2 MariaDB Tutorial DB means Database ...
|
2 MariaDB Tutorial DB means Database ...
|
||||||
DROP TABLE mdev19073, mdev19073_2;
|
DROP TABLE mdev19073, mdev19073_2;
|
||||||
SELECT * FROM information_schema.innodb_sys_tables
|
SELECT * FROM information_schema.innodb_sys_tables WHERE name LIKE 'test/%';
|
||||||
WHERE name LIKE 'test/%' AND name NOT LIKE 'test/#sql-ib%';
|
|
||||||
TABLE_ID NAME FLAG N_COLS SPACE ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
|
TABLE_ID NAME FLAG N_COLS SPACE ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE
|
||||||
|
@@ -20,12 +20,13 @@ DROP TABLE t;
|
|||||||
CREATE TABLE t1 (pk INT, a VARCHAR(8), PRIMARY KEY(pk),
|
CREATE TABLE t1 (pk INT, a VARCHAR(8), PRIMARY KEY(pk),
|
||||||
FULLTEXT KEY(a)) ENGINE=InnoDB;
|
FULLTEXT KEY(a)) ENGINE=InnoDB;
|
||||||
CREATE TABLE t2 (b INT, FOREIGN KEY(b) REFERENCES t1(pk)) ENGINE=InnoDB;
|
CREATE TABLE t2 (b INT, FOREIGN KEY(b) REFERENCES t1(pk)) ENGINE=InnoDB;
|
||||||
DROP TABLE t1;
|
DROP TABLE/*foo*/ t1;
|
||||||
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
|
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
|
||||||
SET DEBUG_DBUG="+d,fts_instrument_sync";
|
SET DEBUG_DBUG="+d,fts_instrument_sync";
|
||||||
INSERT INTO t1 VALUES(1, "mariadb");
|
INSERT INTO t1 VALUES(1, "mariadb");
|
||||||
ALTER TABLE t1 FORCE;
|
ALTER TABLE t1 FORCE;
|
||||||
DROP TABLE t2, t1;
|
DROP TABLE t2, t1;
|
||||||
|
SET SESSION debug_dbug=@saved_debug_dbug;
|
||||||
#
|
#
|
||||||
# MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX
|
# MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX
|
||||||
#
|
#
|
||||||
@@ -56,12 +57,10 @@ DROP TABLE t1;
|
|||||||
# MDEV-25663 Double free of transaction during TRUNCATE
|
# MDEV-25663 Double free of transaction during TRUNCATE
|
||||||
#
|
#
|
||||||
call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)");
|
call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)");
|
||||||
SET DEBUG_DBUG='-d,ib_create_table_fail_too_many_trx';
|
|
||||||
CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
|
CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
|
||||||
SET @save_dbug= @@debug_dbug;
|
|
||||||
SET debug_dbug='+d,ib_create_table_fail_too_many_trx';
|
SET debug_dbug='+d,ib_create_table_fail_too_many_trx';
|
||||||
TRUNCATE t1;
|
TRUNCATE t1;
|
||||||
ERROR HY000: Got error -1 "Internal error < 0 (Not system error)" from storage engine InnoDB
|
ERROR HY000: Got error -1 "Internal error < 0 (Not system error)" from storage engine InnoDB
|
||||||
SET debug_dbug=@save_dbug;
|
SET debug_dbug=@saved_debug_dbug;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
# End of 10.3 tests
|
# End of 10.3 tests
|
||||||
|
@@ -100,6 +100,14 @@ disconnect ddl1;
|
|||||||
disconnect ddl2;
|
disconnect ddl2;
|
||||||
disconnect ddl3;
|
disconnect ddl3;
|
||||||
|
|
||||||
|
# Ensure that the history list length will actually be decremented by purge.
|
||||||
|
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
||||||
|
SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
|
||||||
|
# Wait for purge, so that any #sql-ib.ibd files from the previous kill
|
||||||
|
# will be deleted.
|
||||||
|
source ../../innodb/include/wait_all_purged.inc;
|
||||||
|
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
|
||||||
|
|
||||||
CHECK TABLE t1,t2,t3;
|
CHECK TABLE t1,t2,t3;
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
|
|
||||||
@@ -245,17 +253,4 @@ SELECT * FROM mdev19073_2 WHERE MATCH (title, body)
|
|||||||
AGAINST ('Database' IN NATURAL LANGUAGE MODE);
|
AGAINST ('Database' IN NATURAL LANGUAGE MODE);
|
||||||
DROP TABLE mdev19073, mdev19073_2;
|
DROP TABLE mdev19073, mdev19073_2;
|
||||||
|
|
||||||
if (!$have_debug)
|
SELECT * FROM information_schema.innodb_sys_tables WHERE name LIKE 'test/%';
|
||||||
{
|
|
||||||
--disable_query_log
|
|
||||||
# Some errors are reported despite the MDEV-24626 fix.
|
|
||||||
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: (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: Expected tablespace id [1-9][0-9]* but found 0 in the file .*/test/(FTS_|#sql-(alter|backup)-).*\\.ibd");
|
|
||||||
--enable_query_log
|
|
||||||
}
|
|
||||||
|
|
||||||
SELECT * FROM information_schema.innodb_sys_tables
|
|
||||||
WHERE name LIKE 'test/%' AND name NOT LIKE 'test/#sql-ib%';
|
|
||||||
|
@@ -48,12 +48,13 @@ CREATE TABLE t1 (pk INT, a VARCHAR(8), PRIMARY KEY(pk),
|
|||||||
FULLTEXT KEY(a)) ENGINE=InnoDB;
|
FULLTEXT KEY(a)) ENGINE=InnoDB;
|
||||||
CREATE TABLE t2 (b INT, FOREIGN KEY(b) REFERENCES t1(pk)) ENGINE=InnoDB;
|
CREATE TABLE t2 (b INT, FOREIGN KEY(b) REFERENCES t1(pk)) ENGINE=InnoDB;
|
||||||
--error ER_ROW_IS_REFERENCED_2
|
--error ER_ROW_IS_REFERENCED_2
|
||||||
DROP TABLE t1;
|
DROP TABLE/*foo*/ t1;
|
||||||
SET DEBUG_DBUG="+d,fts_instrument_sync";
|
SET DEBUG_DBUG="+d,fts_instrument_sync";
|
||||||
INSERT INTO t1 VALUES(1, "mariadb");
|
INSERT INTO t1 VALUES(1, "mariadb");
|
||||||
ALTER TABLE t1 FORCE;
|
ALTER TABLE t1 FORCE;
|
||||||
# Cleanup
|
# Cleanup
|
||||||
DROP TABLE t2, t1;
|
DROP TABLE t2, t1;
|
||||||
|
SET SESSION debug_dbug=@saved_debug_dbug;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX
|
--echo # MDEV-25200 Index count mismatch due to aborted FULLTEXT INDEX
|
||||||
@@ -88,13 +89,11 @@ DROP TABLE t1;
|
|||||||
--echo # MDEV-25663 Double free of transaction during TRUNCATE
|
--echo # MDEV-25663 Double free of transaction during TRUNCATE
|
||||||
--echo #
|
--echo #
|
||||||
call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)");
|
call mtr.add_suppression("InnoDB: \\(Too many concurrent transactions\\)");
|
||||||
SET DEBUG_DBUG='-d,ib_create_table_fail_too_many_trx';
|
|
||||||
|
|
||||||
CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
|
CREATE TABLE t1 (b CHAR(12), FULLTEXT KEY(b)) engine=InnoDB;
|
||||||
SET @save_dbug= @@debug_dbug;
|
|
||||||
SET debug_dbug='+d,ib_create_table_fail_too_many_trx';
|
SET debug_dbug='+d,ib_create_table_fail_too_many_trx';
|
||||||
--error ER_GET_ERRNO
|
--error ER_GET_ERRNO
|
||||||
TRUNCATE t1;
|
TRUNCATE t1;
|
||||||
SET debug_dbug=@save_dbug;
|
SET debug_dbug=@saved_debug_dbug;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
--echo # End of 10.3 tests
|
--echo # End of 10.3 tests
|
||||||
|
@@ -111,6 +111,7 @@ ALTER TABLE t1 IMPORT TABLESPACE;
|
|||||||
ERROR HY000: Index for table 't1' is corrupt; try to repair it
|
ERROR HY000: Index for table 't1' is corrupt; try to repair it
|
||||||
SET SESSION debug_dbug=@saved_debug_dbug;
|
SET SESSION debug_dbug=@saved_debug_dbug;
|
||||||
restore: t1 .ibd and .cfg files
|
restore: t1 .ibd and .cfg files
|
||||||
|
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
@@ -162,11 +162,8 @@ SELECT count(*) FROM t7_restart;
|
|||||||
--echo #
|
--echo #
|
||||||
--source include/shutdown_mysqld.inc
|
--source include/shutdown_mysqld.inc
|
||||||
|
|
||||||
--let $regexp=/#sql-ib[0-9a-f]+\.ibd\n//
|
|
||||||
|
|
||||||
--echo ---- MYSQL_DATA_DIR/test
|
--echo ---- MYSQL_DATA_DIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
@@ -174,7 +171,6 @@ SELECT count(*) FROM t7_restart;
|
|||||||
--list_files $MYSQL_TMP_DIR/alt_dir
|
--list_files $MYSQL_TMP_DIR/alt_dir
|
||||||
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
@@ -263,13 +259,11 @@ SHOW CREATE TABLE t7_restart;
|
|||||||
|
|
||||||
--echo ---- MYSQL_DATA_DIR/test
|
--echo ---- MYSQL_DATA_DIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
@@ -320,13 +314,11 @@ RENAME TABLE t5_restart TO t55_restart;
|
|||||||
|
|
||||||
--echo ---- MYSQL_DATA_DIR/test
|
--echo ---- MYSQL_DATA_DIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
@@ -358,13 +350,11 @@ SHOW CREATE TABLE t77_restart;
|
|||||||
|
|
||||||
--echo ---- MYSQL_DATA_DIR/test
|
--echo ---- MYSQL_DATA_DIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
@@ -404,19 +394,16 @@ SHOW CREATE TABLE t77_restart;
|
|||||||
--mkdir $MYSQL_TMP_DIR/new_dir/test
|
--mkdir $MYSQL_TMP_DIR/new_dir/test
|
||||||
--echo ---- MYSQL_DATA_DIR/test
|
--echo ---- MYSQL_DATA_DIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
--echo ---- MYSQL_TMP_DIR/new_dir/test
|
--echo ---- MYSQL_TMP_DIR/new_dir/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/new_dir/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/new_dir/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
@@ -466,19 +453,16 @@ SHOW CREATE TABLE t77_restart;
|
|||||||
|
|
||||||
--echo ---- MYSQL_DATA_DIR/test
|
--echo ---- MYSQL_DATA_DIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
--echo ---- MYSQL_TMP_DIR/alt_dir/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/alt_dir/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
--echo ---- MYSQL_TMP_DIR/new_dir/test
|
--echo ---- MYSQL_TMP_DIR/new_dir/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/new_dir/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/new_dir/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
@@ -522,13 +506,11 @@ SHOW CREATE TABLE t77_restart;
|
|||||||
|
|
||||||
--echo ---- MYSQL_DATA_DIR/test
|
--echo ---- MYSQL_DATA_DIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
--echo ---- MYSQL_TMP_DIR/new_dir/test
|
--echo ---- MYSQL_TMP_DIR/new_dir/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/new_dir/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/new_dir/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
@@ -570,13 +552,11 @@ SHOW CREATE TABLE t77_restart;
|
|||||||
|
|
||||||
--echo ---- MYSQL_DATA_DIR/test
|
--echo ---- MYSQL_DATA_DIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_DATA_DIR/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
--echo ---- MYSQL_TMP_DIR/new_dir/test
|
--echo ---- MYSQL_TMP_DIR/new_dir/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/new_dir/test
|
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQL_TMP_DIR/new_dir/test
|
||||||
--replace_regex $regexp
|
|
||||||
--replace_result #P# #p# #SP# #sp#
|
--replace_result #P# #p# #SP# #sp#
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
--cat_file $MYSQLD_DATADIR.files.txt
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
--remove_file $MYSQLD_DATADIR.files.txt
|
||||||
|
@@ -280,6 +280,7 @@ do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl";
|
|||||||
ib_restore_tablespaces("test", "t1");
|
ib_restore_tablespaces("test", "t1");
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
ALTER TABLE t1 IMPORT TABLESPACE;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
--list_files_write_file $DATADIR.files.txt $DATADIR/test
|
--list_files_write_file $DATADIR.files.txt $DATADIR/test
|
||||||
--replace_result #p# #P# #sp# #SP#
|
--replace_result #p# #P# #sp# #SP#
|
||||||
--replace_regex /#sql-ib[1-9][0-9]*\.ibd\n//
|
|
||||||
--cat_file $DATADIR.files.txt
|
--cat_file $DATADIR.files.txt
|
||||||
--remove_file $DATADIR.files.txt
|
--remove_file $DATADIR.files.txt
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
@@ -20,7 +19,7 @@ SELECT * FROM t1;
|
|||||||
--echo # State after crash (before recovery)
|
--echo # State after crash (before recovery)
|
||||||
--list_files_write_file $DATADIR.files.txt $DATADIR/test
|
--list_files_write_file $DATADIR.files.txt $DATADIR/test
|
||||||
--replace_result #p# #P# #sp# #SP# #tmp# #TMP#
|
--replace_result #p# #P# #sp# #SP# #tmp# #TMP#
|
||||||
--replace_regex /sql-exchange.*\./sql-exchange./ /sql-shadow-[0-9a-f]*-/sql-shadow-/ /#sql-ib[1-9][0-9]*\.ibd\n//
|
--replace_regex /sql-exchange.*\./sql-exchange./ /sql-shadow-[0-9a-f]*-/sql-shadow-/
|
||||||
--cat_file $DATADIR.files.txt
|
--cat_file $DATADIR.files.txt
|
||||||
--remove_file $DATADIR.files.txt
|
--remove_file $DATADIR.files.txt
|
||||||
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
|
||||||
@@ -29,7 +28,6 @@ SELECT * FROM t1;
|
|||||||
--echo # State after crash recovery
|
--echo # State after crash recovery
|
||||||
--list_files_write_file $DATADIR.files.txt $DATADIR/test
|
--list_files_write_file $DATADIR.files.txt $DATADIR/test
|
||||||
--replace_result #p# #P# #sp# #SP#
|
--replace_result #p# #P# #sp# #SP#
|
||||||
--replace_regex /#sql-ib[1-9][0-9]*\.ibd\n//
|
|
||||||
--cat_file $DATADIR.files.txt
|
--cat_file $DATADIR.files.txt
|
||||||
--remove_file $DATADIR.files.txt
|
--remove_file $DATADIR.files.txt
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
|
@@ -93,17 +93,9 @@ SHOW WARNINGS;
|
|||||||
|
|
||||||
--echo # Verifying .frm, .par, .isl & .ibd files
|
--echo # Verifying .frm, .par, .isl & .ibd files
|
||||||
--echo ---- MYSQLD_DATADIR/test
|
--echo ---- MYSQLD_DATADIR/test
|
||||||
--let $regexp=/#sql-ib[0-9a-f]+\.ibd\n//
|
--list_files $MYSQLD_DATADIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQLD_DATADIR/test
|
|
||||||
--replace_regex $regexp
|
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
|
||||||
--echo ---- MYSQLTEST_VARDIR/mysql-test-data-dir/test
|
--echo ---- MYSQLTEST_VARDIR/mysql-test-data-dir/test
|
||||||
--let $regexp=/#sql-ib[0-9a-f]+\.ibd\n//
|
--list_files $MYSQLTEST_VARDIR/mysql-test-data-dir/test
|
||||||
--list_files_write_file $MYSQLTEST_VARDIR/files.txt $MYSQLTEST_VARDIR/mysql-test-data-dir/test
|
|
||||||
--replace_regex $regexp
|
|
||||||
--cat_file $MYSQLTEST_VARDIR/files.txt
|
|
||||||
--remove_file $MYSQLTEST_VARDIR/files.txt
|
|
||||||
--echo # The ibd tablespaces should not be directly under the DATA DIRECTORY
|
--echo # The ibd tablespaces should not be directly under the DATA DIRECTORY
|
||||||
--echo ---- MYSQLTEST_VARDIR/mysql-test-data-dir
|
--echo ---- MYSQLTEST_VARDIR/mysql-test-data-dir
|
||||||
--list_files $MYSQLTEST_VARDIR/mysql-test-data-dir
|
--list_files $MYSQLTEST_VARDIR/mysql-test-data-dir
|
||||||
@@ -122,11 +114,7 @@ ALTER TABLE t1 engine=MyISAM;
|
|||||||
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
--echo # Verifying .frm, .par and MyISAM files (.MYD, MYI)
|
--echo # Verifying .frm, .par and MyISAM files (.MYD, MYI)
|
||||||
--let $regexp=/#sql-ib[0-9a-f]+\.ibd\n//
|
--list_files $MYSQLD_DATADIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQLD_DATADIR/test
|
|
||||||
--replace_regex $regexp
|
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
|
||||||
--echo ---- MYSQLTEST_VARDIR/mysql-test-data-dir
|
--echo ---- MYSQLTEST_VARDIR/mysql-test-data-dir
|
||||||
--list_files $MYSQLTEST_VARDIR/mysql-test-data-dir
|
--list_files $MYSQLTEST_VARDIR/mysql-test-data-dir
|
||||||
--echo ---- MYSQLTEST_VARDIR/mysql-test-idx-dir
|
--echo ---- MYSQLTEST_VARDIR/mysql-test-idx-dir
|
||||||
@@ -142,21 +130,13 @@ ALTER TABLE t1 engine=InnoDB;
|
|||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
--echo # Verifying .frm, .par, .isl and InnoDB .ibd files
|
--echo # Verifying .frm, .par, .isl and InnoDB .ibd files
|
||||||
--echo ---- MYSQLD_DATADIR/test
|
--echo ---- MYSQLD_DATADIR/test
|
||||||
--let $regexp=/#sql-ib[0-9a-f]+\.ibd\n//
|
--list_files $MYSQLD_DATADIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQLD_DATADIR/test
|
|
||||||
--replace_regex $regexp
|
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
|
||||||
--echo ---- MYSQLTEST_VARDIR/mysql-test-data-dir
|
--echo ---- MYSQLTEST_VARDIR/mysql-test-data-dir
|
||||||
--list_files $MYSQLTEST_VARDIR/mysql-test-data-dir
|
--list_files $MYSQLTEST_VARDIR/mysql-test-data-dir
|
||||||
--echo ---- MYSQLTEST_VARDIR/mysql-test-idx-dir
|
--echo ---- MYSQLTEST_VARDIR/mysql-test-idx-dir
|
||||||
--list_files $MYSQLTEST_VARDIR/mysql-test-idx-dir
|
--list_files $MYSQLTEST_VARDIR/mysql-test-idx-dir
|
||||||
--echo ---- MYSQLTEST_VARDIR/mysql-test-data-dir/test
|
--echo ---- MYSQLTEST_VARDIR/mysql-test-data-dir/test
|
||||||
--let $regexp=/#sql-ib[0-9a-f]+\.ibd\n//
|
--list_files $MYSQLTEST_VARDIR/mysql-test-data-dir/test
|
||||||
--list_files_write_file $MYSQLTEST_VARDIR/files.txt $MYSQLTEST_VARDIR/mysql-test-data-dir/test
|
|
||||||
--replace_regex $regexp
|
|
||||||
--cat_file $MYSQLTEST_VARDIR/files.txt
|
|
||||||
--remove_file $MYSQLTEST_VARDIR/files.txt
|
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
@@ -52,11 +52,7 @@ insert into t1 values (1), (11), (21), (33);
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
SHOW CREATE TABLE t1;
|
SHOW CREATE TABLE t1;
|
||||||
--replace_result #p# #P# #sp# #SP#
|
--replace_result #p# #P# #sp# #SP#
|
||||||
--let $regexp=/#sql-ib[0-9a-f]+\.ibd\n//
|
--list_files $MYSQLD_DATADIR/test
|
||||||
--list_files_write_file $MYSQLD_DATADIR.files.txt $MYSQLD_DATADIR/test
|
|
||||||
--replace_regex $regexp
|
|
||||||
--cat_file $MYSQLD_DATADIR.files.txt
|
|
||||||
--remove_file $MYSQLD_DATADIR.files.txt
|
|
||||||
|
|
||||||
SET DEBUG_SYNC='before_open_in_get_all_tables SIGNAL parked WAIT_FOR open';
|
SET DEBUG_SYNC='before_open_in_get_all_tables SIGNAL parked WAIT_FOR open';
|
||||||
SET DEBUG_SYNC='partition_open_error SIGNAL alter WAIT_FOR finish';
|
SET DEBUG_SYNC='partition_open_error SIGNAL alter WAIT_FOR finish';
|
||||||
|
@@ -81,18 +81,6 @@ NUMERIC_BLOCK_SIZE 0
|
|||||||
ENUM_VALUE_LIST NULL
|
ENUM_VALUE_LIST NULL
|
||||||
READ_ONLY YES
|
READ_ONLY YES
|
||||||
COMMAND_LINE_ARGUMENT REQUIRED
|
COMMAND_LINE_ARGUMENT REQUIRED
|
||||||
VARIABLE_NAME INNODB_BACKGROUND_DROP_LIST_EMPTY
|
|
||||||
SESSION_VALUE NULL
|
|
||||||
DEFAULT_VALUE OFF
|
|
||||||
VARIABLE_SCOPE GLOBAL
|
|
||||||
VARIABLE_TYPE BOOLEAN
|
|
||||||
VARIABLE_COMMENT Wait for the background drop list to become empty
|
|
||||||
NUMERIC_MIN_VALUE NULL
|
|
||||||
NUMERIC_MAX_VALUE NULL
|
|
||||||
NUMERIC_BLOCK_SIZE NULL
|
|
||||||
ENUM_VALUE_LIST OFF,ON
|
|
||||||
READ_ONLY NO
|
|
||||||
COMMAND_LINE_ARGUMENT OPTIONAL
|
|
||||||
VARIABLE_NAME INNODB_BUFFER_POOL_CHUNK_SIZE
|
VARIABLE_NAME INNODB_BUFFER_POOL_CHUNK_SIZE
|
||||||
SESSION_VALUE NULL
|
SESSION_VALUE NULL
|
||||||
DEFAULT_VALUE 134217728
|
DEFAULT_VALUE 134217728
|
||||||
|
@@ -493,7 +493,6 @@ int ha_init_errors(void)
|
|||||||
SETMSG(HA_ERR_INDEX_COL_TOO_LONG, ER_DEFAULT(ER_INDEX_COLUMN_TOO_LONG));
|
SETMSG(HA_ERR_INDEX_COL_TOO_LONG, ER_DEFAULT(ER_INDEX_COLUMN_TOO_LONG));
|
||||||
SETMSG(HA_ERR_INDEX_CORRUPT, ER_DEFAULT(ER_INDEX_CORRUPT));
|
SETMSG(HA_ERR_INDEX_CORRUPT, ER_DEFAULT(ER_INDEX_CORRUPT));
|
||||||
SETMSG(HA_FTS_INVALID_DOCID, "Invalid InnoDB FTS Doc ID");
|
SETMSG(HA_FTS_INVALID_DOCID, "Invalid InnoDB FTS Doc ID");
|
||||||
SETMSG(HA_ERR_TABLE_IN_FK_CHECK, ER_DEFAULT(ER_TABLE_IN_FK_CHECK));
|
|
||||||
SETMSG(HA_ERR_DISK_FULL, ER_DEFAULT(ER_DISK_FULL));
|
SETMSG(HA_ERR_DISK_FULL, ER_DEFAULT(ER_DISK_FULL));
|
||||||
SETMSG(HA_ERR_FTS_TOO_MANY_WORDS_IN_PHRASE, "Too many words in a FTS phrase or proximity search");
|
SETMSG(HA_ERR_FTS_TOO_MANY_WORDS_IN_PHRASE, "Too many words in a FTS phrase or proximity search");
|
||||||
SETMSG(HA_ERR_FK_DEPTH_EXCEEDED, "Foreign key cascade delete/update exceeds");
|
SETMSG(HA_ERR_FK_DEPTH_EXCEEDED, "Foreign key cascade delete/update exceeds");
|
||||||
@@ -4259,9 +4258,6 @@ void handler::print_error(int error, myf errflag)
|
|||||||
case HA_ERR_UNDO_REC_TOO_BIG:
|
case HA_ERR_UNDO_REC_TOO_BIG:
|
||||||
textno= ER_UNDO_RECORD_TOO_BIG;
|
textno= ER_UNDO_RECORD_TOO_BIG;
|
||||||
break;
|
break;
|
||||||
case HA_ERR_TABLE_IN_FK_CHECK:
|
|
||||||
textno= ER_TABLE_IN_FK_CHECK;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
/* The error was "unknown" to this function.
|
/* The error was "unknown" to this function.
|
||||||
|
@@ -1853,11 +1853,13 @@ handlerton *ha_default_tmp_handlerton(THD *thd);
|
|||||||
*/
|
*/
|
||||||
#define HTON_REQUIRES_CLOSE_AFTER_TRUNCATE (1 << 18)
|
#define HTON_REQUIRES_CLOSE_AFTER_TRUNCATE (1 << 18)
|
||||||
|
|
||||||
|
/* Truncate requires that all other handlers are closed */
|
||||||
|
#define HTON_TRUNCATE_REQUIRES_EXCLUSIVE_USE (1 << 19)
|
||||||
/*
|
/*
|
||||||
Used by mysql_inplace_alter_table() to decide if we should call
|
Used by mysql_inplace_alter_table() to decide if we should call
|
||||||
hton->notify_tabledef_changed() before commit (MyRocks) or after (InnoDB).
|
hton->notify_tabledef_changed() before commit (MyRocks) or after (InnoDB).
|
||||||
*/
|
*/
|
||||||
#define HTON_REQUIRES_NOTIFY_TABLEDEF_CHANGED_AFTER_COMMIT (1 << 19)
|
#define HTON_REQUIRES_NOTIFY_TABLEDEF_CHANGED_AFTER_COMMIT (1 << 20)
|
||||||
|
|
||||||
class Ha_trx_info;
|
class Ha_trx_info;
|
||||||
|
|
||||||
|
@@ -6636,8 +6636,8 @@ ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC
|
|||||||
ER_BINLOG_UNSAFE_INSERT_TWO_KEYS
|
ER_BINLOG_UNSAFE_INSERT_TWO_KEYS
|
||||||
eng "INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe"
|
eng "INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe"
|
||||||
|
|
||||||
ER_TABLE_IN_FK_CHECK
|
ER_UNUSED_28
|
||||||
eng "Table is being used in foreign key check"
|
eng "You should never see it"
|
||||||
|
|
||||||
ER_UNUSED_1
|
ER_UNUSED_1
|
||||||
eng "You should never see it"
|
eng "You should never see it"
|
||||||
|
@@ -2583,7 +2583,12 @@ void Locked_tables_list::mark_table_for_reopen(THD *thd, TABLE *table)
|
|||||||
for (TABLE_LIST *table_list= m_locked_tables;
|
for (TABLE_LIST *table_list= m_locked_tables;
|
||||||
table_list; table_list= table_list->next_global)
|
table_list; table_list= table_list->next_global)
|
||||||
{
|
{
|
||||||
if (table_list->table->s == share)
|
/*
|
||||||
|
table_list->table can be NULL in the case of TRUNCATE TABLE where
|
||||||
|
the table was locked twice and one instance closed in
|
||||||
|
close_all_tables_for_name().
|
||||||
|
*/
|
||||||
|
if (table_list->table && table_list->table->s == share)
|
||||||
table_list->table->internal_set_needs_reopen(true);
|
table_list->table->internal_set_needs_reopen(true);
|
||||||
}
|
}
|
||||||
/* This is needed in the case where lock tables where not used */
|
/* This is needed in the case where lock tables where not used */
|
||||||
|
@@ -237,6 +237,21 @@ Sql_cmd_truncate_table::handler_truncate(THD *thd, TABLE_LIST *table_ref,
|
|||||||
DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG);
|
DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG);
|
||||||
|
|
||||||
table= table_ref->table;
|
table= table_ref->table;
|
||||||
|
|
||||||
|
if ((table->file->ht->flags & HTON_TRUNCATE_REQUIRES_EXCLUSIVE_USE) &&
|
||||||
|
!is_tmp_table)
|
||||||
|
{
|
||||||
|
if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
|
||||||
|
DBUG_RETURN(TRUNCATE_FAILED_SKIP_BINLOG);
|
||||||
|
/*
|
||||||
|
Get rid of all TABLE instances belonging to this thread
|
||||||
|
except one to be used for TRUNCATE
|
||||||
|
*/
|
||||||
|
close_all_tables_for_name(thd, table->s,
|
||||||
|
HA_EXTRA_NOT_USED,
|
||||||
|
table);
|
||||||
|
}
|
||||||
|
|
||||||
error= table->file->ha_truncate();
|
error= table->file->ha_truncate();
|
||||||
|
|
||||||
if (!is_tmp_table && !error)
|
if (!is_tmp_table && !error)
|
||||||
@@ -366,8 +381,8 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*hton_can_recreate= !sequence
|
*hton_can_recreate= (!sequence &&
|
||||||
&& ha_check_storage_engine_flag(hton, HTON_CAN_RECREATE);
|
ha_check_storage_engine_flag(hton, HTON_CAN_RECREATE));
|
||||||
|
|
||||||
if (versioned)
|
if (versioned)
|
||||||
{
|
{
|
||||||
@@ -496,10 +511,11 @@ bool Sql_cmd_truncate_table::truncate_table(THD *thd, TABLE_LIST *table_ref)
|
|||||||
|
|
||||||
if (error == TRUNCATE_OK && thd->locked_tables_mode &&
|
if (error == TRUNCATE_OK && thd->locked_tables_mode &&
|
||||||
(table_ref->table->file->ht->flags &
|
(table_ref->table->file->ht->flags &
|
||||||
HTON_REQUIRES_CLOSE_AFTER_TRUNCATE))
|
(HTON_REQUIRES_CLOSE_AFTER_TRUNCATE |
|
||||||
|
HTON_TRUNCATE_REQUIRES_EXCLUSIVE_USE)))
|
||||||
{
|
{
|
||||||
thd->locked_tables_list.mark_table_for_reopen(thd, table_ref->table);
|
thd->locked_tables_list.mark_table_for_reopen(thd, table_ref->table);
|
||||||
if (unlikely(thd->locked_tables_list.reopen_tables(thd, true)))
|
if (unlikely(thd->locked_tables_list.reopen_tables(thd, false)))
|
||||||
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
|
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -48,6 +48,7 @@ SET(INNOBASE_SOURCES
|
|||||||
dict/dict0stats.cc
|
dict/dict0stats.cc
|
||||||
dict/dict0stats_bg.cc
|
dict/dict0stats_bg.cc
|
||||||
dict/dict0defrag_bg.cc
|
dict/dict0defrag_bg.cc
|
||||||
|
dict/drop.cc
|
||||||
eval/eval0eval.cc
|
eval/eval0eval.cc
|
||||||
eval/eval0proc.cc
|
eval/eval0proc.cc
|
||||||
fil/fil0fil.cc
|
fil/fil0fil.cc
|
||||||
|
@@ -1196,19 +1196,27 @@ void btr_free_if_exists(fil_space_t *space, uint32_t page,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Free an index tree in a temporary tablespace.
|
/** Drop a temporary table
|
||||||
@param[in] page_id root page id */
|
@param table temporary table */
|
||||||
void btr_free(const page_id_t page_id)
|
void btr_drop_temporary_table(const dict_table_t &table)
|
||||||
{
|
{
|
||||||
|
ut_ad(table.is_temporary());
|
||||||
|
ut_ad(table.space == fil_system.temp_space);
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
mtr.start();
|
mtr.start();
|
||||||
mtr.set_log_mode(MTR_LOG_NO_REDO);
|
for (const dict_index_t *index= table.indexes.start; index;
|
||||||
|
index= dict_table_get_next_index(index))
|
||||||
buf_block_t* block = buf_page_get(page_id, 0, RW_X_LATCH, &mtr);
|
{
|
||||||
|
if (buf_block_t *block= buf_page_get_low({SRV_TMP_SPACE_ID, index->page}, 0,
|
||||||
if (block) {
|
RW_X_LATCH, nullptr, BUF_GET, &mtr,
|
||||||
|
nullptr, false))
|
||||||
|
{
|
||||||
btr_free_but_not_root(block, MTR_LOG_NO_REDO);
|
btr_free_but_not_root(block, MTR_LOG_NO_REDO);
|
||||||
|
mtr.set_log_mode(MTR_LOG_NO_REDO);
|
||||||
btr_free_root(block, &mtr);
|
btr_free_root(block, &mtr);
|
||||||
|
mtr.commit();
|
||||||
|
mtr.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
}
|
}
|
||||||
|
@@ -1404,22 +1404,19 @@ btr_cur_search_to_nth_level_func(
|
|||||||
info->n_searches++;
|
info->n_searches++;
|
||||||
# endif
|
# endif
|
||||||
if (autoinc == 0
|
if (autoinc == 0
|
||||||
&& latch_mode <= BTR_MODIFY_LEAF
|
|
||||||
&& info->last_hash_succ
|
|
||||||
# ifdef MYSQL_INDEX_DISABLE_AHI
|
|
||||||
&& !index->disable_ahi
|
|
||||||
# endif
|
|
||||||
&& !estimate
|
&& !estimate
|
||||||
# ifdef PAGE_CUR_LE_OR_EXTENDS
|
&& latch_mode <= BTR_MODIFY_LEAF
|
||||||
&& mode != PAGE_CUR_LE_OR_EXTENDS
|
&& !modify_external
|
||||||
# endif /* PAGE_CUR_LE_OR_EXTENDS */
|
|
||||||
&& !dict_index_is_spatial(index)
|
|
||||||
/* If !ahi_latch, we do a dirty read of
|
/* If !ahi_latch, we do a dirty read of
|
||||||
btr_search_enabled below, and btr_search_guess_on_hash()
|
btr_search_enabled below, and btr_search_guess_on_hash()
|
||||||
will have to check it again. */
|
will have to check it again. */
|
||||||
&& btr_search_enabled
|
&& btr_search_enabled
|
||||||
&& !modify_external
|
# ifdef PAGE_CUR_LE_OR_EXTENDS
|
||||||
|
&& mode != PAGE_CUR_LE_OR_EXTENDS
|
||||||
|
# endif /* PAGE_CUR_LE_OR_EXTENDS */
|
||||||
|
&& info->last_hash_succ
|
||||||
&& !(tuple->info_bits & REC_INFO_MIN_REC_FLAG)
|
&& !(tuple->info_bits & REC_INFO_MIN_REC_FLAG)
|
||||||
|
&& !index->is_spatial() && !index->table->is_temporary()
|
||||||
&& btr_search_guess_on_hash(index, info, tuple, mode,
|
&& btr_search_guess_on_hash(index, info, tuple, mode,
|
||||||
latch_mode, cursor,
|
latch_mode, cursor,
|
||||||
ahi_latch, mtr)) {
|
ahi_latch, mtr)) {
|
||||||
@@ -2443,9 +2440,6 @@ need_opposite_intention:
|
|||||||
btr_search_build_page_hash_index() before building a
|
btr_search_build_page_hash_index() before building a
|
||||||
page hash index, while holding search latch. */
|
page hash index, while holding search latch. */
|
||||||
if (!btr_search_enabled) {
|
if (!btr_search_enabled) {
|
||||||
# ifdef MYSQL_INDEX_DISABLE_AHI
|
|
||||||
} else if (index->disable_ahi) {
|
|
||||||
# endif
|
|
||||||
} else if (tuple->info_bits & REC_INFO_MIN_REC_FLAG) {
|
} else if (tuple->info_bits & REC_INFO_MIN_REC_FLAG) {
|
||||||
ut_ad(index->is_instant());
|
ut_ad(index->is_instant());
|
||||||
/* This may be a search tuple for
|
/* This may be a search tuple for
|
||||||
@@ -2453,6 +2447,8 @@ need_opposite_intention:
|
|||||||
ut_ad(tuple->is_metadata()
|
ut_ad(tuple->is_metadata()
|
||||||
|| (tuple->is_metadata(tuple->info_bits
|
|| (tuple->is_metadata(tuple->info_bits
|
||||||
^ REC_STATUS_INSTANT)));
|
^ REC_STATUS_INSTANT)));
|
||||||
|
} else if (index->is_spatial()) {
|
||||||
|
} else if (index->table->is_temporary()) {
|
||||||
} else if (rec_is_metadata(btr_cur_get_rec(cursor), *index)) {
|
} else if (rec_is_metadata(btr_cur_get_rec(cursor), *index)) {
|
||||||
/* Only user records belong in the adaptive
|
/* Only user records belong in the adaptive
|
||||||
hash index. */
|
hash index. */
|
||||||
@@ -3602,13 +3598,11 @@ fail_err:
|
|||||||
|
|
||||||
#ifdef BTR_CUR_HASH_ADAPT
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
if (!leaf) {
|
if (!leaf) {
|
||||||
# ifdef MYSQL_INDEX_DISABLE_AHI
|
|
||||||
} else if (index->disable_ahi) {
|
|
||||||
# endif
|
|
||||||
} else if (entry->info_bits & REC_INFO_MIN_REC_FLAG) {
|
} else if (entry->info_bits & REC_INFO_MIN_REC_FLAG) {
|
||||||
ut_ad(entry->is_metadata());
|
ut_ad(entry->is_metadata());
|
||||||
ut_ad(index->is_instant());
|
ut_ad(index->is_instant());
|
||||||
ut_ad(flags == BTR_NO_LOCKING_FLAG);
|
ut_ad(flags == BTR_NO_LOCKING_FLAG);
|
||||||
|
} else if (index->table->is_temporary()) {
|
||||||
} else {
|
} else {
|
||||||
srw_lock* ahi_latch = btr_search_sys.get_latch(*index);
|
srw_lock* ahi_latch = btr_search_sys.get_latch(*index);
|
||||||
if (!reorg && cursor->flag == BTR_CUR_HASH) {
|
if (!reorg && cursor->flag == BTR_CUR_HASH) {
|
||||||
@@ -3811,14 +3805,12 @@ btr_cur_pessimistic_insert(
|
|||||||
ut_ad(!big_rec_vec);
|
ut_ad(!big_rec_vec);
|
||||||
} else {
|
} else {
|
||||||
#ifdef BTR_CUR_HASH_ADAPT
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
# ifdef MYSQL_INDEX_DISABLE_AHI
|
|
||||||
if (index->disable_ahi); else
|
|
||||||
# endif
|
|
||||||
if (entry->info_bits & REC_INFO_MIN_REC_FLAG) {
|
if (entry->info_bits & REC_INFO_MIN_REC_FLAG) {
|
||||||
ut_ad(entry->is_metadata());
|
ut_ad(entry->is_metadata());
|
||||||
ut_ad(index->is_instant());
|
ut_ad(index->is_instant());
|
||||||
ut_ad(flags & BTR_NO_LOCKING_FLAG);
|
ut_ad(flags & BTR_NO_LOCKING_FLAG);
|
||||||
ut_ad(!(flags & BTR_CREATE_FLAG));
|
ut_ad(!(flags & BTR_CREATE_FLAG));
|
||||||
|
} else if (index->table->is_temporary()) {
|
||||||
} else {
|
} else {
|
||||||
btr_search_update_hash_on_insert(
|
btr_search_update_hash_on_insert(
|
||||||
cursor, btr_search_sys.get_latch(*index));
|
cursor, btr_search_sys.get_latch(*index));
|
||||||
|
@@ -293,11 +293,7 @@ is NOT protected by any semaphore, to save CPU time! Do not assume its fields
|
|||||||
are consistent.
|
are consistent.
|
||||||
@param[in,out] info search info
|
@param[in,out] info search info
|
||||||
@param[in] cursor cursor which was just positioned */
|
@param[in] cursor cursor which was just positioned */
|
||||||
static
|
static void btr_search_info_update_hash(btr_search_t *info, btr_cur_t *cursor)
|
||||||
void
|
|
||||||
btr_search_info_update_hash(
|
|
||||||
btr_search_t* info,
|
|
||||||
btr_cur_t* cursor)
|
|
||||||
{
|
{
|
||||||
dict_index_t* index = cursor->index;
|
dict_index_t* index = cursor->index;
|
||||||
int cmp;
|
int cmp;
|
||||||
@@ -1280,7 +1276,6 @@ retry:
|
|||||||
|
|
||||||
assert_block_ahi_valid(block);
|
assert_block_ahi_valid(block);
|
||||||
|
|
||||||
|
|
||||||
if (!index || !btr_search_enabled) {
|
if (!index || !btr_search_enabled) {
|
||||||
if (is_freed) {
|
if (is_freed) {
|
||||||
part->latch.wr_unlock();
|
part->latch.wr_unlock();
|
||||||
@@ -1290,9 +1285,7 @@ retry:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
ut_ad(!index->table->is_temporary());
|
||||||
ut_ad(!index->disable_ahi);
|
|
||||||
#endif
|
|
||||||
ut_ad(btr_search_enabled);
|
ut_ad(btr_search_enabled);
|
||||||
|
|
||||||
ut_ad(block->page.id().space() == index->table->space_id);
|
ut_ad(block->page.id().space() == index->table->space_id);
|
||||||
@@ -1479,9 +1472,8 @@ btr_search_build_page_hash_index(
|
|||||||
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
|
rec_offs offsets_[REC_OFFS_NORMAL_SIZE];
|
||||||
rec_offs* offsets = offsets_;
|
rec_offs* offsets = offsets_;
|
||||||
|
|
||||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
ut_ad(!index->table->is_temporary());
|
||||||
if (index->disable_ahi) return;
|
|
||||||
#endif
|
|
||||||
if (!btr_search_enabled) {
|
if (!btr_search_enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1661,8 +1653,7 @@ exit_func:
|
|||||||
/** Updates the search info.
|
/** Updates the search info.
|
||||||
@param[in,out] info search info
|
@param[in,out] info search info
|
||||||
@param[in,out] cursor cursor which was just positioned */
|
@param[in,out] cursor cursor which was just positioned */
|
||||||
void
|
void btr_search_info_update_slow(btr_search_t *info, btr_cur_t *cursor)
|
||||||
btr_search_info_update_slow(btr_search_t* info, btr_cur_t* cursor)
|
|
||||||
{
|
{
|
||||||
srw_lock* ahi_latch = &btr_search_sys.get_part(*cursor->index)
|
srw_lock* ahi_latch = &btr_search_sys.get_part(*cursor->index)
|
||||||
->latch;
|
->latch;
|
||||||
@@ -1779,7 +1770,7 @@ drop_exit:
|
|||||||
/** Updates the page hash index when a single record is deleted from a page.
|
/** Updates the page hash index when a single record is deleted from a page.
|
||||||
@param[in] cursor cursor which was positioned on the record to delete
|
@param[in] cursor cursor which was positioned on the record to delete
|
||||||
using btr_cur_search_, the record is not yet deleted.*/
|
using btr_cur_search_, the record is not yet deleted.*/
|
||||||
void btr_search_update_hash_on_delete(btr_cur_t* cursor)
|
void btr_search_update_hash_on_delete(btr_cur_t *cursor)
|
||||||
{
|
{
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
const rec_t* rec;
|
const rec_t* rec;
|
||||||
@@ -1790,9 +1781,6 @@ void btr_search_update_hash_on_delete(btr_cur_t* cursor)
|
|||||||
rec_offs_init(offsets_);
|
rec_offs_init(offsets_);
|
||||||
|
|
||||||
ut_ad(page_is_leaf(btr_cur_get_page(cursor)));
|
ut_ad(page_is_leaf(btr_cur_get_page(cursor)));
|
||||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
|
||||||
if (cursor->index->disable_ahi) return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!btr_search_enabled) {
|
if (!btr_search_enabled) {
|
||||||
return;
|
return;
|
||||||
@@ -1810,6 +1798,8 @@ void btr_search_update_hash_on_delete(btr_cur_t* cursor)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ut_ad(!cursor->index->table->is_temporary());
|
||||||
|
|
||||||
if (index != cursor->index) {
|
if (index != cursor->index) {
|
||||||
btr_search_drop_page_hash_index(block);
|
btr_search_drop_page_hash_index(block);
|
||||||
return;
|
return;
|
||||||
@@ -1864,9 +1854,7 @@ void btr_search_update_hash_node_on_insert(btr_cur_t *cursor,
|
|||||||
rec_t* rec;
|
rec_t* rec;
|
||||||
|
|
||||||
ut_ad(ahi_latch == &btr_search_sys.get_part(*cursor->index)->latch);
|
ut_ad(ahi_latch == &btr_search_sys.get_part(*cursor->index)->latch);
|
||||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
|
||||||
if (cursor->index->disable_ahi) return;
|
|
||||||
#endif
|
|
||||||
if (!btr_search_enabled) {
|
if (!btr_search_enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1884,6 +1872,8 @@ void btr_search_update_hash_node_on_insert(btr_cur_t *cursor,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ut_ad(!cursor->index->table->is_temporary());
|
||||||
|
|
||||||
if (index != cursor->index) {
|
if (index != cursor->index) {
|
||||||
ut_ad(index->id == cursor->index->id);
|
ut_ad(index->id == cursor->index->id);
|
||||||
btr_search_drop_page_hash_index(block);
|
btr_search_drop_page_hash_index(block);
|
||||||
@@ -1949,9 +1939,7 @@ void btr_search_update_hash_on_insert(btr_cur_t *cursor,
|
|||||||
|
|
||||||
ut_ad(ahi_latch == &btr_search_sys.get_part(*cursor->index)->latch);
|
ut_ad(ahi_latch == &btr_search_sys.get_part(*cursor->index)->latch);
|
||||||
ut_ad(page_is_leaf(btr_cur_get_page(cursor)));
|
ut_ad(page_is_leaf(btr_cur_get_page(cursor)));
|
||||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
|
||||||
if (cursor->index->disable_ahi) return;
|
|
||||||
#endif
|
|
||||||
if (!btr_search_enabled) {
|
if (!btr_search_enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1973,9 +1961,8 @@ void btr_search_update_hash_on_insert(btr_cur_t *cursor,
|
|||||||
|
|
||||||
rec = btr_cur_get_rec(cursor);
|
rec = btr_cur_get_rec(cursor);
|
||||||
|
|
||||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
ut_ad(!cursor->index->table->is_temporary());
|
||||||
ut_a(!index->disable_ahi);
|
|
||||||
#endif
|
|
||||||
if (index != cursor->index) {
|
if (index != cursor->index) {
|
||||||
ut_ad(index->id == cursor->index->id);
|
ut_ad(index->id == cursor->index->id);
|
||||||
btr_search_drop_page_hash_index(block);
|
btr_search_drop_page_hash_index(block);
|
||||||
|
@@ -897,17 +897,6 @@ 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 */
|
||||||
@@ -1388,34 +1377,15 @@ dberr_t dict_sys_t::create_or_check_sys_tables()
|
|||||||
return DB_SUCCESS;
|
return DB_SUCCESS;
|
||||||
|
|
||||||
trx_t *trx= trx_create();
|
trx_t *trx= trx_create();
|
||||||
trx->dict_operation = true;
|
trx->dict_operation= true;
|
||||||
row_mysql_lock_data_dictionary(trx);
|
row_mysql_lock_data_dictionary(trx);
|
||||||
|
|
||||||
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););
|
|
||||||
|
|
||||||
/* NOTE: when designing InnoDB's foreign key support in 2001, Heikki Tuuri
|
/* 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
|
made a mistake and defined table names and the foreign key id to be of type
|
||||||
'CHAR' (internally, really a VARCHAR).
|
CHAR (internally, really VARCHAR). The type should have been VARBINARY. */
|
||||||
The type should have been VARBINARY. */
|
|
||||||
|
|
||||||
|
/* System tables are always created inside the system tablespace. */
|
||||||
const auto srv_file_per_table_backup= srv_file_per_table;
|
const auto 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;
|
srv_file_per_table= 0;
|
||||||
dberr_t error;
|
dberr_t error;
|
||||||
const char *tablename;
|
const char *tablename;
|
||||||
|
@@ -716,18 +716,18 @@ bool dict_table_t::parse_name(char (&db_name)[NAME_LEN + 1],
|
|||||||
const size_t db_len= name.dblen();
|
const size_t db_len= name.dblen();
|
||||||
ut_ad(db_len <= MAX_DATABASE_NAME_LEN);
|
ut_ad(db_len <= MAX_DATABASE_NAME_LEN);
|
||||||
|
|
||||||
memcpy(db_buf, name.m_name, db_len);
|
memcpy(db_buf, mdl_name.m_name, db_len);
|
||||||
db_buf[db_len]= 0;
|
db_buf[db_len]= 0;
|
||||||
|
|
||||||
size_t tbl_len= strlen(name.m_name + db_len + 1);
|
size_t tbl_len= strlen(mdl_name.m_name + db_len + 1);
|
||||||
const bool is_temp= name.is_temporary();
|
const bool is_temp= mdl_name.is_temporary();
|
||||||
|
|
||||||
if (is_temp);
|
if (is_temp);
|
||||||
else if (const char *is_part= static_cast<const char*>
|
else if (const char *is_part= static_cast<const char*>
|
||||||
(memchr(name.m_name + db_len + 1, '#', tbl_len)))
|
(memchr(mdl_name.m_name + db_len + 1, '#', tbl_len)))
|
||||||
tbl_len= static_cast<size_t>(is_part - &name.m_name[db_len + 1]);
|
tbl_len= static_cast<size_t>(is_part - &mdl_name.m_name[db_len + 1]);
|
||||||
|
|
||||||
memcpy(tbl_buf, name.m_name + db_len + 1, tbl_len);
|
memcpy(tbl_buf, mdl_name.m_name + db_len + 1, tbl_len);
|
||||||
tbl_buf[tbl_len]= 0;
|
tbl_buf[tbl_len]= 0;
|
||||||
|
|
||||||
if (!dict_locked)
|
if (!dict_locked)
|
||||||
@@ -1019,13 +1019,13 @@ void dict_sys_t::create()
|
|||||||
|
|
||||||
|
|
||||||
/** Acquire a reference to a cached table. */
|
/** Acquire a reference to a cached table. */
|
||||||
inline void dict_sys_t::acquire(dict_table_t* table)
|
inline void dict_sys_t::acquire(dict_table_t *table)
|
||||||
{
|
{
|
||||||
ut_ad(dict_sys.find(table));
|
ut_ad(dict_sys.find(table));
|
||||||
if (table->can_be_evicted)
|
if (table->can_be_evicted)
|
||||||
{
|
{
|
||||||
UT_LIST_REMOVE(dict_sys.table_LRU, table);
|
UT_LIST_REMOVE(table_LRU, table);
|
||||||
UT_LIST_ADD_FIRST(dict_sys.table_LRU, table);
|
UT_LIST_ADD_FIRST(table_LRU, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
table->acquire();
|
table->acquire();
|
||||||
@@ -1490,25 +1490,7 @@ dict_table_t::rename_tablespace(const char *new_name, bool replace) const
|
|||||||
ut_ad(!is_temporary());
|
ut_ad(!is_temporary());
|
||||||
|
|
||||||
if (!space)
|
if (!space)
|
||||||
{
|
|
||||||
const char *data_dir= DICT_TF_HAS_DATA_DIR(flags)
|
|
||||||
? data_dir_path : nullptr;
|
|
||||||
ut_ad(data_dir || !DICT_TF_HAS_DATA_DIR(flags));
|
|
||||||
|
|
||||||
if (char *filepath= fil_make_filepath(data_dir, name, IBD,
|
|
||||||
data_dir != nullptr))
|
|
||||||
{
|
|
||||||
fil_delete_tablespace(space_id, true);
|
|
||||||
os_file_type_t ftype;
|
|
||||||
bool exists;
|
|
||||||
/* Delete any temp file hanging around. */
|
|
||||||
if (os_file_status(filepath, &exists, &ftype) && exists &&
|
|
||||||
!os_file_delete_if_exists(innodb_temp_file_key, filepath, nullptr))
|
|
||||||
ib::info() << "Delete of " << filepath << " failed.";
|
|
||||||
ut_free(filepath);
|
|
||||||
}
|
|
||||||
return DB_SUCCESS;
|
return DB_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
const char *old_path= UT_LIST_GET_FIRST(space->chain)->name;
|
const char *old_path= UT_LIST_GET_FIRST(space->chain)->name;
|
||||||
fil_space_t::name_type space_name{new_name, strlen(new_name)};
|
fil_space_t::name_type space_name{new_name, strlen(new_name)};
|
||||||
@@ -1594,17 +1576,33 @@ dict_table_rename_in_cache(
|
|||||||
HASH_DELETE(dict_table_t, name_hash, &dict_sys.table_hash,
|
HASH_DELETE(dict_table_t, name_hash, &dict_sys.table_hash,
|
||||||
ut_fold_string(old_name), table);
|
ut_fold_string(old_name), table);
|
||||||
|
|
||||||
if (strlen(new_name) > strlen(table->name.m_name)) {
|
const bool keep_mdl_name = dict_table_t::is_temporary_name(new_name)
|
||||||
|
&& !table->name.is_temporary();
|
||||||
|
|
||||||
|
if (keep_mdl_name) {
|
||||||
|
/* Preserve the original table name for
|
||||||
|
dict_table_t::parse_name() and dict_acquire_mdl_shared(). */
|
||||||
|
table->mdl_name.m_name = mem_heap_strdup(table->heap,
|
||||||
|
table->name.m_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t new_len = strlen(new_name);
|
||||||
|
|
||||||
|
if (new_len > strlen(table->name.m_name)) {
|
||||||
/* We allocate MAX_FULL_NAME_LEN + 1 bytes here to avoid
|
/* We allocate MAX_FULL_NAME_LEN + 1 bytes here to avoid
|
||||||
memory fragmentation, we assume a repeated calls of
|
memory fragmentation, we assume a repeated calls of
|
||||||
ut_realloc() with the same size do not cause fragmentation */
|
ut_realloc() with the same size do not cause fragmentation */
|
||||||
ut_a(strlen(new_name) <= MAX_FULL_NAME_LEN);
|
ut_a(new_len <= MAX_FULL_NAME_LEN);
|
||||||
|
|
||||||
table->name.m_name = static_cast<char*>(
|
table->name.m_name = static_cast<char*>(
|
||||||
ut_realloc(table->name.m_name, MAX_FULL_NAME_LEN + 1));
|
ut_realloc(table->name.m_name, MAX_FULL_NAME_LEN + 1));
|
||||||
}
|
}
|
||||||
strcpy(table->name.m_name, new_name);
|
strcpy(table->name.m_name, new_name);
|
||||||
|
|
||||||
|
if (!keep_mdl_name) {
|
||||||
|
table->mdl_name.m_name = table->name.m_name;
|
||||||
|
}
|
||||||
|
|
||||||
/* Add table to hash table of tables */
|
/* Add table to hash table of tables */
|
||||||
HASH_INSERT(dict_table_t, name_hash, &dict_sys.table_hash, fold,
|
HASH_INSERT(dict_table_t, name_hash, &dict_sys.table_hash, fold,
|
||||||
table);
|
table);
|
||||||
@@ -2065,9 +2063,6 @@ dict_index_add_to_cache(
|
|||||||
new_index->trx_id = index->trx_id;
|
new_index->trx_id = index->trx_id;
|
||||||
new_index->set_committed(index->is_committed());
|
new_index->set_committed(index->is_committed());
|
||||||
new_index->nulls_equal = index->nulls_equal;
|
new_index->nulls_equal = index->nulls_equal;
|
||||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
|
||||||
new_index->disable_ahi = index->disable_ahi;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
n_ord = new_index->n_uniq;
|
n_ord = new_index->n_uniq;
|
||||||
/* Flag the ordering columns and also set column max_prefix */
|
/* Flag the ordering columns and also set column max_prefix */
|
||||||
|
@@ -853,14 +853,6 @@ static ulint dict_check_sys_tables()
|
|||||||
rec_get_nth_field_old(rec, DICT_FLD__SYS_TABLES__NAME,
|
rec_get_nth_field_old(rec, DICT_FLD__SYS_TABLES__NAME,
|
||||||
&len));
|
&len));
|
||||||
|
|
||||||
if (len == UNIV_SQL_NULL
|
|
||||||
|| dict_table_t::is_garbage_name(field, len)) {
|
|
||||||
/* This table will be dropped by
|
|
||||||
dict_table_t::drop_garbage().
|
|
||||||
We do not care if the file exists. */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_PRINT("dict_check_sys_tables",
|
DBUG_PRINT("dict_check_sys_tables",
|
||||||
("name: %*.s", static_cast<int>(len), field));
|
("name: %*.s", static_cast<int>(len), field));
|
||||||
|
|
||||||
@@ -2451,7 +2443,7 @@ corrupted:
|
|||||||
<< " failed, the table has missing"
|
<< " failed, the table has missing"
|
||||||
" foreign key indexes. Turn off"
|
" foreign key indexes. Turn off"
|
||||||
" 'foreign_key_checks' and try again.";
|
" 'foreign_key_checks' and try again.";
|
||||||
|
evict:
|
||||||
dict_sys.remove(table);
|
dict_sys.remove(table);
|
||||||
table = NULL;
|
table = NULL;
|
||||||
} else {
|
} else {
|
||||||
@@ -2468,8 +2460,9 @@ corrupted:
|
|||||||
if (!srv_force_recovery
|
if (!srv_force_recovery
|
||||||
|| !index
|
|| !index
|
||||||
|| !index->is_primary()) {
|
|| !index->is_primary()) {
|
||||||
dict_sys.remove(table);
|
ib::warn() << "Failed to load table " << table->name
|
||||||
table = NULL;
|
<< ":" << err;
|
||||||
|
goto evict;
|
||||||
} else if (index->is_corrupted()
|
} else if (index->is_corrupted()
|
||||||
&& table->is_readable()) {
|
&& table->is_readable()) {
|
||||||
/* It is possible we force to load a corrupted
|
/* It is possible we force to load a corrupted
|
||||||
|
@@ -159,6 +159,7 @@ dict_table_t *dict_table_t::create(const span<const char> &name,
|
|||||||
table->flags= static_cast<unsigned>(flags) & ((1U << DICT_TF_BITS) - 1);
|
table->flags= static_cast<unsigned>(flags) & ((1U << DICT_TF_BITS) - 1);
|
||||||
table->flags2= static_cast<unsigned>(flags2) & ((1U << DICT_TF2_BITS) - 1);
|
table->flags2= static_cast<unsigned>(flags2) & ((1U << DICT_TF2_BITS) - 1);
|
||||||
table->name.m_name= mem_strdupl(name.data(), name.size());
|
table->name.m_name= mem_strdupl(name.data(), name.size());
|
||||||
|
table->mdl_name.m_name= table->name.m_name;
|
||||||
table->is_system_db= dict_mem_table_is_system(table->name.m_name);
|
table->is_system_db= dict_mem_table_is_system(table->name.m_name);
|
||||||
table->space= space;
|
table->space= space;
|
||||||
table->space_id= space ? space->id : ULINT_UNDEFINED;
|
table->space_id= space ? space->id : ULINT_UNDEFINED;
|
||||||
@@ -221,7 +222,6 @@ dict_mem_table_free(
|
|||||||
table->referenced_set.~dict_foreign_set();
|
table->referenced_set.~dict_foreign_set();
|
||||||
|
|
||||||
ut_free(table->name.m_name);
|
ut_free(table->name.m_name);
|
||||||
table->name.m_name = NULL;
|
|
||||||
|
|
||||||
/* Clean up virtual index info structures that are registered
|
/* Clean up virtual index info structures that are registered
|
||||||
with virtual columns */
|
with virtual columns */
|
||||||
|
@@ -529,61 +529,35 @@ free the trx object. If it is not NULL then it will be rolled back
|
|||||||
only in the case of error, but not freed.
|
only in the case of error, but not freed.
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
static
|
static
|
||||||
dberr_t
|
dberr_t dict_stats_exec_sql(pars_info_t *pinfo, const char* sql, trx_t *trx)
|
||||||
dict_stats_exec_sql(
|
|
||||||
pars_info_t* pinfo,
|
|
||||||
const char* sql,
|
|
||||||
trx_t* trx)
|
|
||||||
{
|
{
|
||||||
dberr_t err;
|
|
||||||
bool trx_started = false;
|
|
||||||
|
|
||||||
ut_d(dict_sys.assert_locked());
|
ut_d(dict_sys.assert_locked());
|
||||||
|
|
||||||
if (!dict_stats_persistent_storage_check(true)) {
|
if (!dict_stats_persistent_storage_check(true))
|
||||||
|
{
|
||||||
pars_info_free(pinfo);
|
pars_info_free(pinfo);
|
||||||
return(DB_STATS_DO_NOT_EXIST);
|
return DB_STATS_DO_NOT_EXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trx == NULL) {
|
if (trx)
|
||||||
trx = trx_create();
|
return que_eval_sql(pinfo, sql, FALSE, trx);
|
||||||
trx_started = true;
|
|
||||||
|
|
||||||
if (srv_read_only_mode) {
|
trx= trx_create();
|
||||||
|
if (srv_read_only_mode)
|
||||||
trx_start_internal_read_only(trx);
|
trx_start_internal_read_only(trx);
|
||||||
} else {
|
else
|
||||||
trx_start_internal(trx);
|
trx_start_internal(trx);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = que_eval_sql(pinfo, sql, FALSE, trx); /* pinfo is freed here */
|
trx->dict_operation_lock_mode= RW_X_LATCH;
|
||||||
|
dberr_t err= que_eval_sql(pinfo, sql, FALSE, trx);
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("stats_index_error",
|
if (err == DB_SUCCESS)
|
||||||
if (!trx_started) {
|
trx->commit();
|
||||||
err = DB_STATS_DO_NOT_EXIST;
|
else
|
||||||
trx->error_state = DB_STATS_DO_NOT_EXIST;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!trx_started && err == DB_SUCCESS) {
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err == DB_SUCCESS) {
|
|
||||||
trx_commit_for_mysql(trx);
|
|
||||||
} else {
|
|
||||||
trx->op_info = "rollback of internal trx on stats tables";
|
|
||||||
trx->dict_operation_lock_mode = RW_X_LATCH;
|
|
||||||
trx->rollback();
|
trx->rollback();
|
||||||
trx->dict_operation_lock_mode = 0;
|
trx->dict_operation_lock_mode= 0;
|
||||||
trx->op_info = "";
|
|
||||||
ut_a(trx->error_state == DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trx_started) {
|
|
||||||
trx->free();
|
trx->free();
|
||||||
}
|
return err;
|
||||||
|
|
||||||
return(err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
@@ -671,6 +645,7 @@ dict_stats_table_clone_create(
|
|||||||
t->heap = heap;
|
t->heap = heap;
|
||||||
|
|
||||||
t->name.m_name = mem_heap_strdup(heap, table->name.m_name);
|
t->name.m_name = mem_heap_strdup(heap, table->name.m_name);
|
||||||
|
t->mdl_name.m_name = t->name.m_name;
|
||||||
|
|
||||||
t->corrupted = table->corrupted;
|
t->corrupted = table->corrupted;
|
||||||
|
|
||||||
@@ -2749,6 +2724,9 @@ dict_stats_save(
|
|||||||
table_utf8, sizeof(table_utf8));
|
table_utf8, sizeof(table_utf8));
|
||||||
|
|
||||||
const time_t now = time(NULL);
|
const time_t now = time(NULL);
|
||||||
|
trx_t* trx = trx_create();
|
||||||
|
trx_start_internal(trx);
|
||||||
|
trx->dict_operation_lock_mode = RW_X_LATCH;
|
||||||
dict_sys_lock();
|
dict_sys_lock();
|
||||||
|
|
||||||
pinfo = pars_info_create();
|
pinfo = pars_info_create();
|
||||||
@@ -2782,20 +2760,21 @@ dict_stats_save(
|
|||||||
":clustered_index_size,\n"
|
":clustered_index_size,\n"
|
||||||
":sum_of_other_index_sizes\n"
|
":sum_of_other_index_sizes\n"
|
||||||
");\n"
|
");\n"
|
||||||
"END;", NULL);
|
"END;", trx);
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(ret != DB_SUCCESS)) {
|
if (UNIV_UNLIKELY(ret != DB_SUCCESS)) {
|
||||||
ib::error() << "Cannot save table statistics for table "
|
ib::error() << "Cannot save table statistics for table "
|
||||||
<< table->name << ": " << ret;
|
<< table->name << ": " << ret;
|
||||||
func_exit:
|
rollback_and_exit:
|
||||||
|
trx->rollback();
|
||||||
|
free_and_exit:
|
||||||
|
trx->dict_operation_lock_mode = 0;
|
||||||
dict_sys_unlock();
|
dict_sys_unlock();
|
||||||
|
trx->free();
|
||||||
dict_stats_snapshot_free(table);
|
dict_stats_snapshot_free(table);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
trx_t* trx = trx_create();
|
|
||||||
trx_start_internal(trx);
|
|
||||||
|
|
||||||
dict_index_t* index;
|
dict_index_t* index;
|
||||||
index_map_t indexes(
|
index_map_t indexes(
|
||||||
(ut_strcmp_functor()),
|
(ut_strcmp_functor()),
|
||||||
@@ -2864,7 +2843,7 @@ func_exit:
|
|||||||
stat_description, trx);
|
stat_description, trx);
|
||||||
|
|
||||||
if (ret != DB_SUCCESS) {
|
if (ret != DB_SUCCESS) {
|
||||||
goto end;
|
goto rollback_and_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2874,7 +2853,7 @@ func_exit:
|
|||||||
"Number of leaf pages "
|
"Number of leaf pages "
|
||||||
"in the index", trx);
|
"in the index", trx);
|
||||||
if (ret != DB_SUCCESS) {
|
if (ret != DB_SUCCESS) {
|
||||||
goto end;
|
goto rollback_and_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = dict_stats_save_index_stat(index, now, "size",
|
ret = dict_stats_save_index_stat(index, now, "size",
|
||||||
@@ -2883,15 +2862,12 @@ func_exit:
|
|||||||
"Number of pages "
|
"Number of pages "
|
||||||
"in the index", trx);
|
"in the index", trx);
|
||||||
if (ret != DB_SUCCESS) {
|
if (ret != DB_SUCCESS) {
|
||||||
goto end;
|
goto rollback_and_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trx_commit_for_mysql(trx);
|
trx->commit();
|
||||||
|
goto free_and_exit;
|
||||||
end:
|
|
||||||
trx->free();
|
|
||||||
goto func_exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
@@ -3657,112 +3633,15 @@ transient:
|
|||||||
return(DB_SUCCESS);
|
return(DB_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove the information for a particular index's stats from the persistent
|
/** Execute DELETE FROM mysql.innodb_table_stats
|
||||||
storage if it exists and if there is data stored for this index.
|
@param database_name database name
|
||||||
This function creates its own trx and commits it.
|
@param table_name table name
|
||||||
|
@param trx transaction (nullptr=start and commit a new one)
|
||||||
We must modify system tables in a separate transaction in order to
|
|
||||||
adhere to the InnoDB design constraint that dict_sys.latch prevents
|
|
||||||
lock waits on system tables. If we modified system and user tables in
|
|
||||||
the same transaction, we should exclusively hold dict_sys.latch until
|
|
||||||
the transaction is committed, and effectively block other transactions
|
|
||||||
that will attempt to open any InnoDB tables. Because we have no
|
|
||||||
guarantee that user transactions will be committed fast, we cannot
|
|
||||||
afford to keep the system tables locked in a user transaction.
|
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
dberr_t
|
dberr_t dict_stats_delete_from_table_stats(const char *database_name,
|
||||||
dict_stats_drop_index(
|
const char *table_name, trx_t *trx)
|
||||||
/*==================*/
|
|
||||||
const char* db_and_table,/*!< in: db and table, e.g. 'db/table' */
|
|
||||||
const char* iname, /*!< in: index name */
|
|
||||||
char* errstr, /*!< out: error message if != DB_SUCCESS
|
|
||||||
is returned */
|
|
||||||
ulint errstr_sz)/*!< in: size of the errstr buffer */
|
|
||||||
{
|
|
||||||
char db_utf8[MAX_DB_UTF8_LEN];
|
|
||||||
char table_utf8[MAX_TABLE_UTF8_LEN];
|
|
||||||
pars_info_t* pinfo;
|
|
||||||
dberr_t ret;
|
|
||||||
|
|
||||||
dict_sys.assert_not_locked();
|
|
||||||
|
|
||||||
/* skip indexes whose table names do not contain a database name
|
|
||||||
e.g. if we are dropping an index from SYS_TABLES */
|
|
||||||
if (strchr(db_and_table, '/') == NULL) {
|
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
dict_fs2utf8(db_and_table, db_utf8, sizeof(db_utf8),
|
|
||||||
table_utf8, sizeof(table_utf8));
|
|
||||||
|
|
||||||
pinfo = pars_info_create();
|
|
||||||
|
|
||||||
pars_info_add_str_literal(pinfo, "database_name", db_utf8);
|
|
||||||
|
|
||||||
pars_info_add_str_literal(pinfo, "table_name", table_utf8);
|
|
||||||
|
|
||||||
pars_info_add_str_literal(pinfo, "index_name", iname);
|
|
||||||
|
|
||||||
dict_sys_lock();
|
|
||||||
|
|
||||||
ret = dict_stats_exec_sql(
|
|
||||||
pinfo,
|
|
||||||
"PROCEDURE DROP_INDEX_STATS () IS\n"
|
|
||||||
"BEGIN\n"
|
|
||||||
"DELETE FROM \"" INDEX_STATS_NAME "\" WHERE\n"
|
|
||||||
"database_name = :database_name AND\n"
|
|
||||||
"table_name = :table_name AND\n"
|
|
||||||
"index_name = :index_name;\n"
|
|
||||||
"END;\n", NULL);
|
|
||||||
|
|
||||||
dict_sys_unlock();
|
|
||||||
|
|
||||||
if (ret == DB_STATS_DO_NOT_EXIST) {
|
|
||||||
ret = DB_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret != DB_SUCCESS) {
|
|
||||||
snprintf(errstr, errstr_sz,
|
|
||||||
"Unable to delete statistics for index %s"
|
|
||||||
" from %s%s: %s. They can be deleted later using"
|
|
||||||
" DELETE FROM %s WHERE"
|
|
||||||
" database_name = '%s' AND"
|
|
||||||
" table_name = '%s' AND"
|
|
||||||
" index_name = '%s';",
|
|
||||||
iname,
|
|
||||||
INDEX_STATS_NAME_PRINT,
|
|
||||||
(ret == DB_LOCK_WAIT_TIMEOUT
|
|
||||||
? " because the rows are locked"
|
|
||||||
: ""),
|
|
||||||
ut_strerr(ret),
|
|
||||||
INDEX_STATS_NAME_PRINT,
|
|
||||||
db_utf8,
|
|
||||||
table_utf8,
|
|
||||||
iname);
|
|
||||||
|
|
||||||
ut_print_timestamp(stderr);
|
|
||||||
fprintf(stderr, " InnoDB: %s\n", errstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
|
||||||
Executes
|
|
||||||
DELETE FROM mysql.innodb_table_stats
|
|
||||||
WHERE database_name = '...' AND table_name = '...';
|
|
||||||
Creates its own transaction and commits it.
|
|
||||||
@return DB_SUCCESS or error code */
|
|
||||||
UNIV_INLINE
|
|
||||||
dberr_t
|
|
||||||
dict_stats_delete_from_table_stats(
|
|
||||||
/*===============================*/
|
|
||||||
const char* database_name, /*!< in: database name, e.g. 'db' */
|
|
||||||
const char* table_name) /*!< in: table name, e.g. 'table' */
|
|
||||||
{
|
{
|
||||||
pars_info_t* pinfo;
|
pars_info_t* pinfo;
|
||||||
dberr_t ret;
|
|
||||||
|
|
||||||
ut_d(dict_sys.assert_locked());
|
ut_d(dict_sys.assert_locked());
|
||||||
|
|
||||||
@@ -3771,33 +3650,25 @@ dict_stats_delete_from_table_stats(
|
|||||||
pars_info_add_str_literal(pinfo, "database_name", database_name);
|
pars_info_add_str_literal(pinfo, "database_name", database_name);
|
||||||
pars_info_add_str_literal(pinfo, "table_name", table_name);
|
pars_info_add_str_literal(pinfo, "table_name", table_name);
|
||||||
|
|
||||||
ret = dict_stats_exec_sql(
|
return dict_stats_exec_sql(
|
||||||
pinfo,
|
pinfo,
|
||||||
"PROCEDURE DELETE_FROM_TABLE_STATS () IS\n"
|
"PROCEDURE DELETE_FROM_TABLE_STATS () IS\n"
|
||||||
"BEGIN\n"
|
"BEGIN\n"
|
||||||
"DELETE FROM \"" TABLE_STATS_NAME "\" WHERE\n"
|
"DELETE FROM \"" TABLE_STATS_NAME "\" WHERE\n"
|
||||||
"database_name = :database_name AND\n"
|
"database_name = :database_name AND\n"
|
||||||
"table_name = :table_name;\n"
|
"table_name = :table_name;\n"
|
||||||
"END;\n", NULL);
|
"END;\n", trx);
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/** Execute DELETE FROM mysql.innodb_index_stats
|
||||||
Executes
|
@param database_name database name
|
||||||
DELETE FROM mysql.innodb_index_stats
|
@param table_name table name
|
||||||
WHERE database_name = '...' AND table_name = '...';
|
@param trx transaction (nullptr=start and commit a new one)
|
||||||
Creates its own transaction and commits it.
|
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
UNIV_INLINE
|
dberr_t dict_stats_delete_from_index_stats(const char *database_name,
|
||||||
dberr_t
|
const char *table_name, trx_t *trx)
|
||||||
dict_stats_delete_from_index_stats(
|
|
||||||
/*===============================*/
|
|
||||||
const char* database_name, /*!< in: database name, e.g. 'db' */
|
|
||||||
const char* table_name) /*!< in: table name, e.g. 'table' */
|
|
||||||
{
|
{
|
||||||
pars_info_t* pinfo;
|
pars_info_t* pinfo;
|
||||||
dberr_t ret;
|
|
||||||
|
|
||||||
ut_d(dict_sys.assert_locked());
|
ut_d(dict_sys.assert_locked());
|
||||||
|
|
||||||
@@ -3806,375 +3677,144 @@ dict_stats_delete_from_index_stats(
|
|||||||
pars_info_add_str_literal(pinfo, "database_name", database_name);
|
pars_info_add_str_literal(pinfo, "database_name", database_name);
|
||||||
pars_info_add_str_literal(pinfo, "table_name", table_name);
|
pars_info_add_str_literal(pinfo, "table_name", table_name);
|
||||||
|
|
||||||
ret = dict_stats_exec_sql(
|
return dict_stats_exec_sql(
|
||||||
pinfo,
|
pinfo,
|
||||||
"PROCEDURE DELETE_FROM_INDEX_STATS () IS\n"
|
"PROCEDURE DELETE_FROM_INDEX_STATS () IS\n"
|
||||||
"BEGIN\n"
|
"BEGIN\n"
|
||||||
"DELETE FROM \"" INDEX_STATS_NAME "\" WHERE\n"
|
"DELETE FROM \"" INDEX_STATS_NAME "\" WHERE\n"
|
||||||
"database_name = :database_name AND\n"
|
"database_name = :database_name AND\n"
|
||||||
"table_name = :table_name;\n"
|
"table_name = :table_name;\n"
|
||||||
"END;\n", NULL);
|
"END;\n", trx);
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/** Execute DELETE FROM mysql.innodb_index_stats
|
||||||
Removes the statistics for a table and all of its indexes from the
|
@param database_name database name
|
||||||
persistent statistics storage if it exists and if there is data stored for
|
@param table_name table name
|
||||||
the table. This function creates its own transaction and commits it.
|
@param index_name name of the index
|
||||||
|
@param trx transaction (nullptr=start and commit a new one)
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
dberr_t
|
dberr_t dict_stats_delete_from_index_stats(const char *database_name,
|
||||||
dict_stats_drop_table(
|
const char *table_name,
|
||||||
/*==================*/
|
const char *index_name, trx_t *trx)
|
||||||
const char* db_and_table, /*!< in: db and table, e.g. 'db/table' */
|
|
||||||
char* errstr, /*!< out: error message
|
|
||||||
if != DB_SUCCESS is returned */
|
|
||||||
ulint errstr_sz) /*!< in: size of errstr buffer */
|
|
||||||
{
|
|
||||||
char db_utf8[MAX_DB_UTF8_LEN];
|
|
||||||
char table_utf8[MAX_TABLE_UTF8_LEN];
|
|
||||||
dberr_t ret;
|
|
||||||
|
|
||||||
ut_d(dict_sys.assert_locked());
|
|
||||||
|
|
||||||
/* skip tables that do not contain a database name
|
|
||||||
e.g. if we are dropping SYS_TABLES */
|
|
||||||
if (strchr(db_and_table, '/') == NULL) {
|
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* skip innodb_table_stats and innodb_index_stats themselves */
|
|
||||||
if (strcmp(db_and_table, TABLE_STATS_NAME) == 0
|
|
||||||
|| strcmp(db_and_table, INDEX_STATS_NAME) == 0) {
|
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
dict_fs2utf8(db_and_table, db_utf8, sizeof(db_utf8),
|
|
||||||
table_utf8, sizeof(table_utf8));
|
|
||||||
|
|
||||||
ret = dict_stats_delete_from_table_stats(db_utf8, table_utf8);
|
|
||||||
|
|
||||||
if (ret == DB_SUCCESS) {
|
|
||||||
ret = dict_stats_delete_from_index_stats(db_utf8, table_utf8);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == DB_STATS_DO_NOT_EXIST) {
|
|
||||||
ret = DB_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret != DB_SUCCESS) {
|
|
||||||
|
|
||||||
snprintf(errstr, errstr_sz,
|
|
||||||
"Unable to delete statistics for table %s.%s: %s."
|
|
||||||
" They can be deleted later using"
|
|
||||||
|
|
||||||
" DELETE FROM %s WHERE"
|
|
||||||
" database_name = '%s' AND"
|
|
||||||
" table_name = '%s';"
|
|
||||||
|
|
||||||
" DELETE FROM %s WHERE"
|
|
||||||
" database_name = '%s' AND"
|
|
||||||
" table_name = '%s';",
|
|
||||||
|
|
||||||
db_utf8, table_utf8,
|
|
||||||
ut_strerr(ret),
|
|
||||||
|
|
||||||
INDEX_STATS_NAME_PRINT,
|
|
||||||
db_utf8, table_utf8,
|
|
||||||
|
|
||||||
TABLE_STATS_NAME_PRINT,
|
|
||||||
db_utf8, table_utf8);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
|
||||||
Executes
|
|
||||||
UPDATE mysql.innodb_table_stats SET
|
|
||||||
database_name = '...', table_name = '...'
|
|
||||||
WHERE database_name = '...' AND table_name = '...';
|
|
||||||
Creates its own transaction and commits it.
|
|
||||||
@return DB_SUCCESS or error code */
|
|
||||||
UNIV_INLINE
|
|
||||||
dberr_t
|
|
||||||
dict_stats_rename_table_in_table_stats(
|
|
||||||
/*===================================*/
|
|
||||||
const char* old_dbname_utf8,/*!< in: database name, e.g. 'olddb' */
|
|
||||||
const char* old_tablename_utf8,/*!< in: table name, e.g. 'oldtable' */
|
|
||||||
const char* new_dbname_utf8,/*!< in: database name, e.g. 'newdb' */
|
|
||||||
const char* new_tablename_utf8)/*!< in: table name, e.g. 'newtable' */
|
|
||||||
{
|
{
|
||||||
pars_info_t* pinfo;
|
pars_info_t* pinfo;
|
||||||
dberr_t ret;
|
|
||||||
|
|
||||||
ut_d(dict_sys.assert_locked());
|
ut_d(dict_sys.assert_locked());
|
||||||
|
|
||||||
pinfo = pars_info_create();
|
pinfo = pars_info_create();
|
||||||
|
|
||||||
pars_info_add_str_literal(pinfo, "old_dbname_utf8", old_dbname_utf8);
|
pars_info_add_str_literal(pinfo, "database_name", database_name);
|
||||||
pars_info_add_str_literal(pinfo, "old_tablename_utf8", old_tablename_utf8);
|
pars_info_add_str_literal(pinfo, "table_name", table_name);
|
||||||
pars_info_add_str_literal(pinfo, "new_dbname_utf8", new_dbname_utf8);
|
pars_info_add_str_literal(pinfo, "index_name", index_name);
|
||||||
pars_info_add_str_literal(pinfo, "new_tablename_utf8", new_tablename_utf8);
|
|
||||||
|
|
||||||
ret = dict_stats_exec_sql(
|
return dict_stats_exec_sql(
|
||||||
pinfo,
|
pinfo,
|
||||||
"PROCEDURE RENAME_TABLE_IN_TABLE_STATS () IS\n"
|
"PROCEDURE DELETE_FROM_INDEX_STATS () IS\n"
|
||||||
|
"BEGIN\n"
|
||||||
|
"DELETE FROM \"" INDEX_STATS_NAME "\" WHERE\n"
|
||||||
|
"database_name = :database_name AND\n"
|
||||||
|
"table_name = :table_name AND\n"
|
||||||
|
"index_name = :index_name;\n"
|
||||||
|
"END;\n", trx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Rename a table in InnoDB persistent stats storage.
|
||||||
|
@param old_name old table name
|
||||||
|
@param new_name new table name
|
||||||
|
@param trx transaction
|
||||||
|
@return DB_SUCCESS or error code */
|
||||||
|
dberr_t dict_stats_rename_table(const char *old_name, const char *new_name,
|
||||||
|
trx_t *trx)
|
||||||
|
{
|
||||||
|
/* skip the statistics tables themselves */
|
||||||
|
if (!strcmp(old_name, TABLE_STATS_NAME) ||
|
||||||
|
!strcmp(old_name, INDEX_STATS_NAME) ||
|
||||||
|
!strcmp(new_name, TABLE_STATS_NAME) ||
|
||||||
|
!strcmp(new_name, INDEX_STATS_NAME))
|
||||||
|
return DB_SUCCESS;
|
||||||
|
|
||||||
|
char old_db[MAX_DB_UTF8_LEN];
|
||||||
|
char new_db[MAX_DB_UTF8_LEN];
|
||||||
|
char old_table[MAX_TABLE_UTF8_LEN];
|
||||||
|
char new_table[MAX_TABLE_UTF8_LEN];
|
||||||
|
|
||||||
|
dict_fs2utf8(old_name, old_db, sizeof old_db, old_table, sizeof old_table);
|
||||||
|
dict_fs2utf8(new_name, new_db, sizeof new_db, new_table, sizeof new_table);
|
||||||
|
|
||||||
|
if (dict_table_t::is_temporary_name(old_name) ||
|
||||||
|
dict_table_t::is_temporary_name(new_name))
|
||||||
|
{
|
||||||
|
if (dberr_t e= dict_stats_delete_from_table_stats(old_db, old_table, trx))
|
||||||
|
return e;
|
||||||
|
return dict_stats_delete_from_index_stats(old_db, old_table, trx);
|
||||||
|
}
|
||||||
|
|
||||||
|
pars_info_t *pinfo= pars_info_create();
|
||||||
|
pars_info_add_str_literal(pinfo, "old_db", old_db);
|
||||||
|
pars_info_add_str_literal(pinfo, "old_table", old_table);
|
||||||
|
pars_info_add_str_literal(pinfo, "new_db", new_db);
|
||||||
|
pars_info_add_str_literal(pinfo, "new_table", new_table);
|
||||||
|
|
||||||
|
static const char sql[]=
|
||||||
|
"PROCEDURE RENAME_TABLE_IN_STATS() IS\n"
|
||||||
"BEGIN\n"
|
"BEGIN\n"
|
||||||
"UPDATE \"" TABLE_STATS_NAME "\" SET\n"
|
"UPDATE \"" TABLE_STATS_NAME "\" SET\n"
|
||||||
"database_name = :new_dbname_utf8,\n"
|
"database_name=:new_db, table_name=:new_table\n"
|
||||||
"table_name = :new_tablename_utf8\n"
|
"WHERE database_name=:old_db AND table_name=:old_table;\n"
|
||||||
"WHERE\n"
|
|
||||||
"database_name = :old_dbname_utf8 AND\n"
|
|
||||||
"table_name = :old_tablename_utf8;\n"
|
|
||||||
"END;\n", NULL);
|
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
|
||||||
Executes
|
|
||||||
UPDATE mysql.innodb_index_stats SET
|
|
||||||
database_name = '...', table_name = '...'
|
|
||||||
WHERE database_name = '...' AND table_name = '...';
|
|
||||||
Creates its own transaction and commits it.
|
|
||||||
@return DB_SUCCESS or error code */
|
|
||||||
UNIV_INLINE
|
|
||||||
dberr_t
|
|
||||||
dict_stats_rename_table_in_index_stats(
|
|
||||||
/*===================================*/
|
|
||||||
const char* old_dbname_utf8,/*!< in: database name, e.g. 'olddb' */
|
|
||||||
const char* old_tablename_utf8,/*!< in: table name, e.g. 'oldtable' */
|
|
||||||
const char* new_dbname_utf8,/*!< in: database name, e.g. 'newdb' */
|
|
||||||
const char* new_tablename_utf8)/*!< in: table name, e.g. 'newtable' */
|
|
||||||
{
|
|
||||||
pars_info_t* pinfo;
|
|
||||||
dberr_t ret;
|
|
||||||
|
|
||||||
ut_d(dict_sys.assert_locked());
|
|
||||||
|
|
||||||
pinfo = pars_info_create();
|
|
||||||
|
|
||||||
pars_info_add_str_literal(pinfo, "old_dbname_utf8", old_dbname_utf8);
|
|
||||||
pars_info_add_str_literal(pinfo, "old_tablename_utf8", old_tablename_utf8);
|
|
||||||
pars_info_add_str_literal(pinfo, "new_dbname_utf8", new_dbname_utf8);
|
|
||||||
pars_info_add_str_literal(pinfo, "new_tablename_utf8", new_tablename_utf8);
|
|
||||||
|
|
||||||
ret = dict_stats_exec_sql(
|
|
||||||
pinfo,
|
|
||||||
"PROCEDURE RENAME_TABLE_IN_INDEX_STATS () IS\n"
|
|
||||||
"BEGIN\n"
|
|
||||||
"UPDATE \"" INDEX_STATS_NAME "\" SET\n"
|
"UPDATE \"" INDEX_STATS_NAME "\" SET\n"
|
||||||
"database_name = :new_dbname_utf8,\n"
|
"database_name=:new_db, table_name=:new_table\n"
|
||||||
"table_name = :new_tablename_utf8\n"
|
"WHERE database_name=:old_db AND table_name=:old_table;\n"
|
||||||
"WHERE\n"
|
"END;\n";
|
||||||
"database_name = :old_dbname_utf8 AND\n"
|
|
||||||
"table_name = :old_tablename_utf8;\n"
|
|
||||||
"END;\n", NULL);
|
|
||||||
|
|
||||||
return(ret);
|
return dict_stats_exec_sql(pinfo, sql, trx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/** Rename an index in InnoDB persistent statistics.
|
||||||
Renames a table in InnoDB persistent stats storage.
|
@param db database name
|
||||||
This function creates its own transaction and commits it.
|
@param table table name
|
||||||
|
@param old_name old table name
|
||||||
|
@param new_name new table name
|
||||||
|
@param trx transaction
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
dberr_t
|
dberr_t dict_stats_rename_index(const char *db, const char *table,
|
||||||
dict_stats_rename_table(
|
const char *old_name, const char *new_name,
|
||||||
/*====================*/
|
trx_t *trx)
|
||||||
const char* old_name, /*!< in: old name, e.g. 'db/table' */
|
|
||||||
const char* new_name, /*!< in: new name, e.g. 'db/table' */
|
|
||||||
char* errstr, /*!< out: error string if != DB_SUCCESS
|
|
||||||
is returned */
|
|
||||||
size_t errstr_sz) /*!< in: errstr size */
|
|
||||||
{
|
{
|
||||||
char old_db_utf8[MAX_DB_UTF8_LEN];
|
if (!dict_stats_persistent_storage_check(true))
|
||||||
char new_db_utf8[MAX_DB_UTF8_LEN];
|
return DB_STATS_DO_NOT_EXIST;
|
||||||
char old_table_utf8[MAX_TABLE_UTF8_LEN];
|
pars_info_t *pinfo= pars_info_create();
|
||||||
char new_table_utf8[MAX_TABLE_UTF8_LEN];
|
|
||||||
dberr_t ret;
|
|
||||||
|
|
||||||
/* skip innodb_table_stats and innodb_index_stats themselves */
|
pars_info_add_str_literal(pinfo, "db", db);
|
||||||
if (strcmp(old_name, TABLE_STATS_NAME) == 0
|
pars_info_add_str_literal(pinfo, "table", table);
|
||||||
|| strcmp(old_name, INDEX_STATS_NAME) == 0
|
pars_info_add_str_literal(pinfo, "old", old_name);
|
||||||
|| strcmp(new_name, TABLE_STATS_NAME) == 0
|
pars_info_add_str_literal(pinfo, "new", new_name);
|
||||||
|| strcmp(new_name, INDEX_STATS_NAME) == 0) {
|
|
||||||
|
|
||||||
return(DB_SUCCESS);
|
static const char sql[]=
|
||||||
}
|
"PROCEDURE RENAME_INDEX_IN_STATS() IS\n"
|
||||||
|
"BEGIN\n"
|
||||||
|
"UPDATE \"" INDEX_STATS_NAME "\" SET index_name=:new\n"
|
||||||
|
"WHERE database_name=:db AND table_name=:table AND index_name=:old;\n"
|
||||||
|
"END;\n";
|
||||||
|
|
||||||
dict_fs2utf8(old_name, old_db_utf8, sizeof(old_db_utf8),
|
return dict_stats_exec_sql(pinfo, sql, trx);
|
||||||
old_table_utf8, sizeof(old_table_utf8));
|
|
||||||
|
|
||||||
dict_fs2utf8(new_name, new_db_utf8, sizeof(new_db_utf8),
|
|
||||||
new_table_utf8, sizeof(new_table_utf8));
|
|
||||||
|
|
||||||
dict_sys_lock();
|
|
||||||
|
|
||||||
ulint n_attempts = 0;
|
|
||||||
do {
|
|
||||||
n_attempts++;
|
|
||||||
|
|
||||||
ret = dict_stats_rename_table_in_table_stats(
|
|
||||||
old_db_utf8, old_table_utf8,
|
|
||||||
new_db_utf8, new_table_utf8);
|
|
||||||
|
|
||||||
if (ret == DB_DUPLICATE_KEY) {
|
|
||||||
dict_stats_delete_from_table_stats(
|
|
||||||
new_db_utf8, new_table_utf8);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == DB_STATS_DO_NOT_EXIST) {
|
|
||||||
ret = DB_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret != DB_SUCCESS) {
|
|
||||||
dict_sys_unlock();
|
|
||||||
std::this_thread::sleep_for(
|
|
||||||
std::chrono::milliseconds(200));
|
|
||||||
dict_sys_lock();
|
|
||||||
}
|
|
||||||
} while ((ret == DB_DEADLOCK
|
|
||||||
|| ret == DB_DUPLICATE_KEY
|
|
||||||
|| ret == DB_LOCK_WAIT_TIMEOUT)
|
|
||||||
&& n_attempts < 5);
|
|
||||||
|
|
||||||
if (ret != DB_SUCCESS) {
|
|
||||||
snprintf(errstr, errstr_sz,
|
|
||||||
"Unable to rename statistics from"
|
|
||||||
" %s.%s to %s.%s in %s: %s."
|
|
||||||
" They can be renamed later using"
|
|
||||||
|
|
||||||
" UPDATE %s SET"
|
|
||||||
" database_name = '%s',"
|
|
||||||
" table_name = '%s'"
|
|
||||||
" WHERE"
|
|
||||||
" database_name = '%s' AND"
|
|
||||||
" table_name = '%s';",
|
|
||||||
|
|
||||||
old_db_utf8, old_table_utf8,
|
|
||||||
new_db_utf8, new_table_utf8,
|
|
||||||
TABLE_STATS_NAME_PRINT,
|
|
||||||
ut_strerr(ret),
|
|
||||||
|
|
||||||
TABLE_STATS_NAME_PRINT,
|
|
||||||
new_db_utf8, new_table_utf8,
|
|
||||||
old_db_utf8, old_table_utf8);
|
|
||||||
dict_sys_unlock();
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
/* else */
|
|
||||||
|
|
||||||
n_attempts = 0;
|
|
||||||
do {
|
|
||||||
n_attempts++;
|
|
||||||
|
|
||||||
ret = dict_stats_rename_table_in_index_stats(
|
|
||||||
old_db_utf8, old_table_utf8,
|
|
||||||
new_db_utf8, new_table_utf8);
|
|
||||||
|
|
||||||
if (ret == DB_DUPLICATE_KEY) {
|
|
||||||
dict_stats_delete_from_index_stats(
|
|
||||||
new_db_utf8, new_table_utf8);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == DB_STATS_DO_NOT_EXIST) {
|
|
||||||
ret = DB_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret != DB_SUCCESS) {
|
|
||||||
dict_sys_unlock();
|
|
||||||
std::this_thread::sleep_for(
|
|
||||||
std::chrono::milliseconds(200));
|
|
||||||
dict_sys_lock();
|
|
||||||
}
|
|
||||||
} while ((ret == DB_DEADLOCK
|
|
||||||
|| ret == DB_DUPLICATE_KEY
|
|
||||||
|| ret == DB_LOCK_WAIT_TIMEOUT)
|
|
||||||
&& n_attempts < 5);
|
|
||||||
|
|
||||||
dict_sys_unlock();
|
|
||||||
|
|
||||||
if (ret != DB_SUCCESS) {
|
|
||||||
snprintf(errstr, errstr_sz,
|
|
||||||
"Unable to rename statistics from"
|
|
||||||
" %s.%s to %s.%s in %s: %s."
|
|
||||||
" They can be renamed later using"
|
|
||||||
|
|
||||||
" UPDATE %s SET"
|
|
||||||
" database_name = '%s',"
|
|
||||||
" table_name = '%s'"
|
|
||||||
" WHERE"
|
|
||||||
" database_name = '%s' AND"
|
|
||||||
" table_name = '%s';",
|
|
||||||
|
|
||||||
old_db_utf8, old_table_utf8,
|
|
||||||
new_db_utf8, new_table_utf8,
|
|
||||||
INDEX_STATS_NAME_PRINT,
|
|
||||||
ut_strerr(ret),
|
|
||||||
|
|
||||||
INDEX_STATS_NAME_PRINT,
|
|
||||||
new_db_utf8, new_table_utf8,
|
|
||||||
old_db_utf8, old_table_utf8);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/** Delete all persistent statistics for a database.
|
||||||
Renames an index in InnoDB persistent stats storage.
|
@param db database name
|
||||||
This function creates its own transaction and commits it.
|
@param trx transaction
|
||||||
@return DB_SUCCESS or error code. DB_STATS_DO_NOT_EXIST will be returned
|
@return DB_SUCCESS or error code */
|
||||||
if the persistent stats do not exist. */
|
dberr_t dict_stats_delete(const char *db, trx_t *trx)
|
||||||
dberr_t
|
|
||||||
dict_stats_rename_index(
|
|
||||||
/*====================*/
|
|
||||||
const dict_table_t* table, /*!< in: table whose index
|
|
||||||
is renamed */
|
|
||||||
const char* old_index_name, /*!< in: old index name */
|
|
||||||
const char* new_index_name) /*!< in: new index name */
|
|
||||||
{
|
{
|
||||||
dict_sys_lock();
|
static const char sql[] =
|
||||||
|
"PROCEDURE DROP_DATABASE_STATS () IS\n"
|
||||||
if (!dict_stats_persistent_storage_check(true)) {
|
|
||||||
dict_sys_unlock();
|
|
||||||
return(DB_STATS_DO_NOT_EXIST);
|
|
||||||
}
|
|
||||||
|
|
||||||
char dbname_utf8[MAX_DB_UTF8_LEN];
|
|
||||||
char tablename_utf8[MAX_TABLE_UTF8_LEN];
|
|
||||||
|
|
||||||
dict_fs2utf8(table->name.m_name, dbname_utf8, sizeof(dbname_utf8),
|
|
||||||
tablename_utf8, sizeof(tablename_utf8));
|
|
||||||
|
|
||||||
pars_info_t* pinfo;
|
|
||||||
|
|
||||||
pinfo = pars_info_create();
|
|
||||||
|
|
||||||
pars_info_add_str_literal(pinfo, "dbname_utf8", dbname_utf8);
|
|
||||||
pars_info_add_str_literal(pinfo, "tablename_utf8", tablename_utf8);
|
|
||||||
pars_info_add_str_literal(pinfo, "new_index_name", new_index_name);
|
|
||||||
pars_info_add_str_literal(pinfo, "old_index_name", old_index_name);
|
|
||||||
|
|
||||||
dberr_t ret;
|
|
||||||
|
|
||||||
ret = dict_stats_exec_sql(
|
|
||||||
pinfo,
|
|
||||||
"PROCEDURE RENAME_INDEX_IN_INDEX_STATS () IS\n"
|
|
||||||
"BEGIN\n"
|
"BEGIN\n"
|
||||||
"UPDATE \"" INDEX_STATS_NAME "\" SET\n"
|
"DELETE FROM \"" TABLE_STATS_NAME "\" WHERE database_name=:db;\n"
|
||||||
"index_name = :new_index_name\n"
|
"DELETE FROM \"" INDEX_STATS_NAME "\" WHERE database_name=:db;\n"
|
||||||
"WHERE\n"
|
"END;\n";
|
||||||
"database_name = :dbname_utf8 AND\n"
|
|
||||||
"table_name = :tablename_utf8 AND\n"
|
|
||||||
"index_name = :old_index_name;\n"
|
|
||||||
"END;\n", NULL);
|
|
||||||
|
|
||||||
dict_sys_unlock();
|
pars_info_t *pinfo= pars_info_create();
|
||||||
|
pars_info_add_str_literal(pinfo, "db", db);
|
||||||
return(ret);
|
return dict_stats_exec_sql(pinfo, sql, trx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tests @{ */
|
/* tests @{ */
|
||||||
|
256
storage/innobase/dict/drop.cc
Normal file
256
storage/innobase/dict/drop.cc
Normal file
@@ -0,0 +1,256 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
|
||||||
|
Copyright (c) 2021, MariaDB Corporation.
|
||||||
|
|
||||||
|
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 dict/drop.cc
|
||||||
|
Data Dictionary Language operations that delete .ibd files */
|
||||||
|
|
||||||
|
/* We implement atomic data dictionary operations as follows.
|
||||||
|
|
||||||
|
1. A data dictionary transaction is started.
|
||||||
|
2. We acquire exclusive lock on all the tables that are to be dropped
|
||||||
|
during the execution of the transaction.
|
||||||
|
3. We lock the data dictionary cache.
|
||||||
|
4. All metadata tables will be updated within the single DDL transaction,
|
||||||
|
including deleting or renaming InnoDB persistent statistics.
|
||||||
|
4b. If any lock wait would occur while we are holding the dict_sys latches,
|
||||||
|
we will instantly report a timeout error and roll back the transaction.
|
||||||
|
5. The transaction metadata is marked as committed.
|
||||||
|
6. If any files were deleted, we will durably write FILE_DELETE
|
||||||
|
to the redo log and start deleting the files.
|
||||||
|
6b. Also purge after a commit may perform file deletion. This is also the
|
||||||
|
recovery mechanism if the server was killed between step 5 and 6.
|
||||||
|
7. We unlock the data dictionary cache.
|
||||||
|
8. The file handles of the unlinked files will be closed. This will actually
|
||||||
|
reclaim the space in the file system (delete-on-close semantics).
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
(a) Purge will be locked out by MDL. For internal tables related to
|
||||||
|
FULLTEXT INDEX, purge will not acquire MDL on the user table name,
|
||||||
|
and therefore, when we are dropping any FTS_ tables, we must suspend
|
||||||
|
and resume purge to prevent a race condition.
|
||||||
|
|
||||||
|
(b) If a transaction needs to both drop and create a table by some
|
||||||
|
name, it must rename the table in between. This is used by
|
||||||
|
ha_innobase::truncate() and fts_drop_common_tables().
|
||||||
|
|
||||||
|
(c) No data is ever destroyed before the transaction is committed,
|
||||||
|
so we can trivially roll back the transaction at any time.
|
||||||
|
Lock waits during a DDL operation are no longer a fatal error
|
||||||
|
that would cause the InnoDB to hang or to intentionally crash.
|
||||||
|
(Only ALTER TABLE...DISCARD TABLESPACE may discard data before commit.)
|
||||||
|
|
||||||
|
(d) The only changes to the data dictionary cache that are performed
|
||||||
|
before transaction commit and must be rolled back explicitly are as follows:
|
||||||
|
(d1) fts_optimize_add_table() to undo fts_optimize_remove_table()
|
||||||
|
(d2) stats_bg_flag= BG_STAT_NONE to undo dict_stats_stop_bg()
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "trx0purge.h"
|
||||||
|
#include "dict0dict.h"
|
||||||
|
#include "dict0stats.h"
|
||||||
|
#include "dict0stats_bg.h"
|
||||||
|
|
||||||
|
#include "dict0defrag_bg.h"
|
||||||
|
#include "btr0defragment.h"
|
||||||
|
|
||||||
|
#include "que0que.h"
|
||||||
|
#include "pars0pars.h"
|
||||||
|
|
||||||
|
/** Try to drop the foreign key constraints for a persistent table.
|
||||||
|
@param name name of persistent table
|
||||||
|
@return error code */
|
||||||
|
dberr_t trx_t::drop_table_foreign(const table_name_t &name)
|
||||||
|
{
|
||||||
|
ut_d(dict_sys.assert_locked());
|
||||||
|
ut_ad(state == TRX_STATE_ACTIVE);
|
||||||
|
ut_ad(dict_operation);
|
||||||
|
ut_ad(dict_operation_lock_mode == RW_X_LATCH);
|
||||||
|
|
||||||
|
if (!dict_sys.sys_foreign || !dict_sys.sys_foreign_cols)
|
||||||
|
return DB_SUCCESS;
|
||||||
|
|
||||||
|
pars_info_t *info= pars_info_create();
|
||||||
|
pars_info_add_str_literal(info, "name", name.m_name);
|
||||||
|
return que_eval_sql(info,
|
||||||
|
"PROCEDURE DROP_FOREIGN() IS\n"
|
||||||
|
"fid CHAR;\n"
|
||||||
|
|
||||||
|
"DECLARE CURSOR fk IS\n"
|
||||||
|
"SELECT ID FROM SYS_FOREIGN\n"
|
||||||
|
"WHERE FOR_NAME=:name\n"
|
||||||
|
"AND TO_BINARY(FOR_NAME)=TO_BINARY(:name)\n"
|
||||||
|
"FOR UPDATE;\n"
|
||||||
|
|
||||||
|
"BEGIN\n"
|
||||||
|
"OPEN fk;\n"
|
||||||
|
"WHILE 1=1 LOOP\n"
|
||||||
|
" FETCH fk INTO fid;\n"
|
||||||
|
" IF (SQL % NOTFOUND)THEN RETURN;END IF;\n"
|
||||||
|
" DELETE FROM SYS_FOREIGN_COLS"
|
||||||
|
" WHERE ID=fid;\n"
|
||||||
|
" DELETE FROM SYS_FOREIGN WHERE ID=fid;\n"
|
||||||
|
"END LOOP;\n"
|
||||||
|
"CLOSE fk;\n"
|
||||||
|
"END;\n", FALSE, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Try to drop the statistics for a persistent table.
|
||||||
|
@param name name of persistent table
|
||||||
|
@return error code */
|
||||||
|
dberr_t trx_t::drop_table_statistics(const table_name_t &name)
|
||||||
|
{
|
||||||
|
ut_d(dict_sys.assert_locked());
|
||||||
|
ut_ad(dict_operation_lock_mode == RW_X_LATCH);
|
||||||
|
|
||||||
|
if (strstr(name.m_name, "/" TEMP_FILE_PREFIX_INNODB) ||
|
||||||
|
!strcmp(name.m_name, TABLE_STATS_NAME) ||
|
||||||
|
!strcmp(name.m_name, INDEX_STATS_NAME))
|
||||||
|
return DB_SUCCESS;
|
||||||
|
|
||||||
|
char db[MAX_DB_UTF8_LEN], table[MAX_TABLE_UTF8_LEN];
|
||||||
|
dict_fs2utf8(name.m_name, db, sizeof db, table, sizeof table);
|
||||||
|
|
||||||
|
dberr_t err= dict_stats_delete_from_table_stats(db, table, this);
|
||||||
|
if (err == DB_SUCCESS || err == DB_STATS_DO_NOT_EXIST)
|
||||||
|
{
|
||||||
|
err= dict_stats_delete_from_index_stats(db, table, this);
|
||||||
|
if (err == DB_STATS_DO_NOT_EXIST)
|
||||||
|
err= DB_SUCCESS;
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Try to drop a persistent table.
|
||||||
|
@param table persistent table
|
||||||
|
@param fk whether to drop FOREIGN KEY metadata
|
||||||
|
@return error code */
|
||||||
|
dberr_t trx_t::drop_table(const dict_table_t &table)
|
||||||
|
{
|
||||||
|
ut_d(dict_sys.assert_locked());
|
||||||
|
ut_ad(state == TRX_STATE_ACTIVE);
|
||||||
|
ut_ad(dict_operation);
|
||||||
|
ut_ad(dict_operation_lock_mode == RW_X_LATCH);
|
||||||
|
ut_ad(!table.is_temporary());
|
||||||
|
ut_ad(!(table.stats_bg_flag & BG_STAT_IN_PROGRESS));
|
||||||
|
/* The table must be exclusively locked by this transaction. */
|
||||||
|
ut_ad(table.get_ref_count() <= 1);
|
||||||
|
ut_ad(!table.n_waiting_or_granted_auto_inc_locks);
|
||||||
|
ut_ad(table.n_lock_x_or_s == 1);
|
||||||
|
ut_ad(UT_LIST_GET_LEN(table.locks) >= 1);
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
|
bool found_x;
|
||||||
|
for (lock_t *lock= UT_LIST_GET_FIRST(table.locks); lock;
|
||||||
|
lock= UT_LIST_GET_NEXT(un_member.tab_lock.locks, lock))
|
||||||
|
{
|
||||||
|
ut_ad(lock->trx == this);
|
||||||
|
if (lock->type_mode == (LOCK_X | LOCK_TABLE))
|
||||||
|
found_x= true;
|
||||||
|
else
|
||||||
|
ut_ad(lock->type_mode == (LOCK_IX | LOCK_TABLE));
|
||||||
|
}
|
||||||
|
ut_ad(found_x);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (dict_sys.sys_virtual)
|
||||||
|
{
|
||||||
|
pars_info_t *info= pars_info_create();
|
||||||
|
pars_info_add_ull_literal(info, "id", table.id);
|
||||||
|
if (dberr_t err= que_eval_sql(info,
|
||||||
|
"PROCEDURE DROP_VIRTUAL() IS\n"
|
||||||
|
"BEGIN\n"
|
||||||
|
"DELETE FROM SYS_VIRTUAL"
|
||||||
|
" WHERE TABLE_ID=:id;\n"
|
||||||
|
"END;\n", FALSE, this))
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Once DELETE FROM SYS_INDEXES is committed, purge may invoke
|
||||||
|
dict_drop_index_tree(). */
|
||||||
|
|
||||||
|
if (!(table.flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS)));
|
||||||
|
else if (dberr_t err= fts_drop_tables(this, table))
|
||||||
|
{
|
||||||
|
ib::error() << "Unable to remove FTS tables for "
|
||||||
|
<< table.name << ": " << err;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod_tables.emplace(const_cast<dict_table_t*>(&table), undo_no).
|
||||||
|
first->second.set_dropped();
|
||||||
|
|
||||||
|
pars_info_t *info= pars_info_create();
|
||||||
|
pars_info_add_ull_literal(info, "id", table.id);
|
||||||
|
return que_eval_sql(info,
|
||||||
|
"PROCEDURE DROP_TABLE() IS\n"
|
||||||
|
"iid CHAR;\n"
|
||||||
|
|
||||||
|
"DECLARE CURSOR idx IS\n"
|
||||||
|
"SELECT ID FROM SYS_INDEXES\n"
|
||||||
|
"WHERE TABLE_ID=:id FOR UPDATE;\n"
|
||||||
|
|
||||||
|
"BEGIN\n"
|
||||||
|
"OPEN idx;\n"
|
||||||
|
"WHILE 1 = 1 LOOP\n"
|
||||||
|
" FETCH idx INTO iid;\n"
|
||||||
|
" IF (SQL % NOTFOUND) THEN EXIT; END IF;\n"
|
||||||
|
" DELETE FROM SYS_FIELDS WHERE INDEX_ID=iid;\n"
|
||||||
|
" DELETE FROM SYS_INDEXES WHERE CURRENT OF idx;\n"
|
||||||
|
"END LOOP;\n"
|
||||||
|
"CLOSE idx;\n"
|
||||||
|
|
||||||
|
"DELETE FROM SYS_COLUMNS WHERE TABLE_ID=:id;\n"
|
||||||
|
"DELETE FROM SYS_TABLES WHERE ID=:id;\n"
|
||||||
|
|
||||||
|
"END;\n", FALSE, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Commit the transaction, possibly after drop_table().
|
||||||
|
@param deleted handles of data files that were deleted */
|
||||||
|
void trx_t::commit(std::vector<pfs_os_file_t> &deleted)
|
||||||
|
{
|
||||||
|
ut_ad(dict_operation);
|
||||||
|
commit_persist();
|
||||||
|
if (dict_operation)
|
||||||
|
{
|
||||||
|
dict_sys.assert_locked();
|
||||||
|
for (const auto &p : mod_tables)
|
||||||
|
{
|
||||||
|
if (p.second.is_dropped())
|
||||||
|
{
|
||||||
|
dict_table_t *table= p.first;
|
||||||
|
dict_stats_recalc_pool_del(table);
|
||||||
|
dict_stats_defrag_pool_del(table, nullptr);
|
||||||
|
if (btr_defragment_active)
|
||||||
|
btr_defragment_remove_table(table);
|
||||||
|
const fil_space_t *space= table->space;
|
||||||
|
ut_ad(!strstr(table->name.m_name, "/FTS_") ||
|
||||||
|
purge_sys.must_wait_FTS());
|
||||||
|
dict_sys.remove(table);
|
||||||
|
if (const auto id= space ? space->id : 0)
|
||||||
|
{
|
||||||
|
pfs_os_file_t d= fil_delete_tablespace(id);
|
||||||
|
if (d != OS_FILE_CLOSED)
|
||||||
|
deleted.emplace_back(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
commit_cleanup();
|
||||||
|
}
|
@@ -2312,9 +2312,6 @@ void fil_space_crypt_close_tablespace(const fil_space_t *space)
|
|||||||
while (crypt_data->rotate_state.active_threads
|
while (crypt_data->rotate_state.active_threads
|
||||||
|| crypt_data->rotate_state.flushing) {
|
|| crypt_data->rotate_state.flushing) {
|
||||||
mysql_mutex_unlock(&crypt_data->mutex);
|
mysql_mutex_unlock(&crypt_data->mutex);
|
||||||
/* release dict mutex so that scrub threads can release their
|
|
||||||
* table references */
|
|
||||||
dict_sys.mutex_unlock();
|
|
||||||
|
|
||||||
/* wakeup throttle (all) sleepers */
|
/* wakeup throttle (all) sleepers */
|
||||||
mysql_mutex_lock(&fil_crypt_threads_mutex);
|
mysql_mutex_lock(&fil_crypt_threads_mutex);
|
||||||
@@ -2323,8 +2320,6 @@ void fil_space_crypt_close_tablespace(const fil_space_t *space)
|
|||||||
mysql_mutex_unlock(&fil_crypt_threads_mutex);
|
mysql_mutex_unlock(&fil_crypt_threads_mutex);
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||||
dict_sys.mutex_lock();
|
|
||||||
mysql_mutex_lock(&crypt_data->mutex);
|
|
||||||
|
|
||||||
time_t now = time(0);
|
time_t now = time(0);
|
||||||
|
|
||||||
@@ -2339,6 +2334,8 @@ void fil_space_crypt_close_tablespace(const fil_space_t *space)
|
|||||||
<< crypt_data->rotate_state.flushing << ".";
|
<< crypt_data->rotate_state.flushing << ".";
|
||||||
last = now;
|
last = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mysql_mutex_lock(&crypt_data->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_mutex_unlock(&crypt_data->mutex);
|
mysql_mutex_unlock(&crypt_data->mutex);
|
||||||
|
@@ -1566,39 +1566,61 @@ fil_name_write(
|
|||||||
fil_space_t *fil_space_t::check_pending_operations(ulint id)
|
fil_space_t *fil_space_t::check_pending_operations(ulint id)
|
||||||
{
|
{
|
||||||
ut_a(!is_system_tablespace(id));
|
ut_a(!is_system_tablespace(id));
|
||||||
|
bool being_deleted= false;
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
fil_space_t *space= fil_space_get_by_id(id);
|
fil_space_t *space= fil_space_get_by_id(id);
|
||||||
|
|
||||||
if (!space);
|
if (!space);
|
||||||
else if (space->pending() & STOPPING)
|
else if (space->pending() & STOPPING)
|
||||||
space= nullptr;
|
being_deleted= true;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
space->reacquire();
|
|
||||||
if (space->crypt_data)
|
if (space->crypt_data)
|
||||||
{
|
{
|
||||||
|
space->reacquire();
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
fil_space_crypt_close_tablespace(space);
|
fil_space_crypt_close_tablespace(space);
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
}
|
|
||||||
space->set_stopping(true);
|
|
||||||
space->release();
|
space->release();
|
||||||
}
|
}
|
||||||
|
being_deleted= space->set_stopping();
|
||||||
|
}
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
|
|
||||||
if (!space)
|
if (!space)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
if (being_deleted)
|
||||||
|
{
|
||||||
|
/* A thread executing DDL and another thread executing purge may
|
||||||
|
be executing fil_delete_tablespace() concurrently for the same
|
||||||
|
tablespace. Wait for the other thread to complete the operation. */
|
||||||
for (ulint count= 0;; count++)
|
for (ulint count= 0;; count++)
|
||||||
{
|
{
|
||||||
auto pending= space->referenced();
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
|
space= fil_space_get_by_id(id);
|
||||||
|
ut_ad(!space || space->is_stopping());
|
||||||
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
|
if (!space)
|
||||||
|
return nullptr;
|
||||||
|
/* Issue a warning every 10.24 seconds, starting after 2.56 seconds */
|
||||||
|
if ((count & 511) == 128)
|
||||||
|
sql_print_warning("InnoDB: Waiting for tablespace " ULINTPF
|
||||||
|
" to be deleted", id);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ulint count= 0;; count++)
|
||||||
|
{
|
||||||
|
const unsigned pending= space->referenced();
|
||||||
if (!pending)
|
if (!pending)
|
||||||
return space;
|
return space;
|
||||||
/* Give a warning every 10 second, starting after 1 second */
|
/* Issue a warning every 10.24 seconds, starting after 2.56 seconds */
|
||||||
if ((count % 500) == 50)
|
if ((count & 511) == 128)
|
||||||
ib::warn() << "Trying to delete tablespace '"
|
sql_print_warning("InnoDB: Trying to delete tablespace '%s' "
|
||||||
<< space->chain.start->name << "' but there are "
|
"but there are %u pending operations",
|
||||||
<< pending << " pending operations on it.";
|
space->chain.start->name, id);
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1645,117 +1667,60 @@ void fil_close_tablespace(ulint id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Delete a tablespace and associated .ibd file.
|
/** Delete a tablespace and associated .ibd file.
|
||||||
@param[in] id tablespace identifier
|
@param id tablespace identifier
|
||||||
@param[in] if_exists whether to ignore missing tablespace
|
@return detached file handle (to be closed by the caller)
|
||||||
@param[out] detached deatched file handle (if closing is not wanted)
|
@return OS_FILE_CLOSED if no file existed */
|
||||||
@return DB_SUCCESS or error */
|
pfs_os_file_t fil_delete_tablespace(ulint id)
|
||||||
dberr_t fil_delete_tablespace(ulint id, bool if_exists,
|
|
||||||
pfs_os_file_t *detached)
|
|
||||||
{
|
{
|
||||||
ut_ad(!is_system_tablespace(id));
|
ut_ad(!is_system_tablespace(id));
|
||||||
ut_ad(!detached || *detached == OS_FILE_CLOSED);
|
pfs_os_file_t handle= OS_FILE_CLOSED;
|
||||||
|
if (fil_space_t *space= fil_space_t::check_pending_operations(id))
|
||||||
dberr_t err;
|
|
||||||
fil_space_t *space = fil_space_t::check_pending_operations(id);
|
|
||||||
|
|
||||||
if (!space) {
|
|
||||||
err = DB_TABLESPACE_NOT_FOUND;
|
|
||||||
if (!if_exists) {
|
|
||||||
ib::error() << "Cannot delete tablespace " << id
|
|
||||||
<< " because it is not found"
|
|
||||||
" in the tablespace memory cache.";
|
|
||||||
}
|
|
||||||
func_exit:
|
|
||||||
ibuf_delete_for_discarded_space(id);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IMPORTANT: Because we have set space::stop_new_ops there
|
|
||||||
can't be any new reads or flushes. We are here
|
|
||||||
because node::n_pending was zero above. However, it is still
|
|
||||||
possible to have pending read and write requests:
|
|
||||||
|
|
||||||
A read request can happen because the reader thread has
|
|
||||||
gone through the ::stop_new_ops check in buf_page_init_for_read()
|
|
||||||
before the flag was set and has not yet incremented ::n_pending
|
|
||||||
when we checked it above.
|
|
||||||
|
|
||||||
A write request can be issued any time because we don't check
|
|
||||||
fil_space_t::is_stopping() when queueing a block for write.
|
|
||||||
|
|
||||||
We deal with pending write requests in the following function
|
|
||||||
where we'd minimally evict all dirty pages belonging to this
|
|
||||||
space from the flush_list. Note that if a block is IO-fixed
|
|
||||||
we'll wait for IO to complete.
|
|
||||||
|
|
||||||
To deal with potential read requests, we will check the
|
|
||||||
is_stopping() in fil_space_t::io(). */
|
|
||||||
|
|
||||||
err = DB_SUCCESS;
|
|
||||||
buf_flush_remove_pages(id);
|
|
||||||
|
|
||||||
/* If it is a delete then also delete any generated files, otherwise
|
|
||||||
when we drop the database the remove directory will fail. */
|
|
||||||
{
|
{
|
||||||
/* Before deleting the file, write a log record about
|
/* Before deleting the file(s), persistently write a log record. */
|
||||||
it, so that InnoDB crash recovery will expect the file
|
|
||||||
to be gone. */
|
|
||||||
mtr_t mtr;
|
mtr_t mtr;
|
||||||
|
|
||||||
mtr.start();
|
mtr.start();
|
||||||
mtr.log_file_op(FILE_DELETE, id, space->chain.start->name);
|
mtr.log_file_op(FILE_DELETE, id, space->chain.start->name);
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
/* Even if we got killed shortly after deleting the
|
|
||||||
tablespace file, the record must have already been
|
|
||||||
written to the redo log. */
|
|
||||||
log_write_up_to(mtr.commit_lsn(), true);
|
log_write_up_to(mtr.commit_lsn(), true);
|
||||||
|
|
||||||
if (char* cfg_name = fil_make_filepath(
|
/* Remove any additional files. */
|
||||||
space->chain.start->name,
|
if (char *cfg_name= fil_make_filepath(space->chain.start->name,
|
||||||
fil_space_t::name_type{}, CFG, false)) {
|
fil_space_t::name_type{}, CFG,
|
||||||
os_file_delete_if_exists(innodb_data_file_key,
|
false))
|
||||||
cfg_name, nullptr);
|
{
|
||||||
|
os_file_delete_if_exists(innodb_data_file_key, cfg_name, nullptr);
|
||||||
ut_free(cfg_name);
|
ut_free(cfg_name);
|
||||||
}
|
}
|
||||||
}
|
if (FSP_FLAGS_HAS_DATA_DIR(space->flags))
|
||||||
|
|
||||||
/* Delete the link file pointing to the ibd file we are deleting. */
|
|
||||||
if (FSP_FLAGS_HAS_DATA_DIR(space->flags)) {
|
|
||||||
RemoteDatafile::delete_link_file(space->name());
|
RemoteDatafile::delete_link_file(space->name());
|
||||||
}
|
|
||||||
|
/* Remove the directory entry. The file will actually be deleted
|
||||||
|
when our caller closes the handle. */
|
||||||
|
os_file_delete(innodb_data_file_key, space->chain.start->name);
|
||||||
|
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
|
/* Sanity checks after reacquiring fil_system.mutex */
|
||||||
/* Double check the sanity of pending ops after reacquiring
|
ut_ad(space == fil_space_get_by_id(id));
|
||||||
the fil_system::mutex. */
|
ut_ad(!space->referenced());
|
||||||
ut_a(space == fil_space_get_by_id(id));
|
ut_ad(space->is_stopping());
|
||||||
ut_a(!space->referenced());
|
ut_ad(UT_LIST_GET_LEN(space->chain) == 1);
|
||||||
ut_a(UT_LIST_GET_LEN(space->chain) == 1);
|
/* Detach the file handle. */
|
||||||
pfs_os_file_t handle = fil_system.detach(space, detached != nullptr);
|
handle= fil_system.detach(space, true);
|
||||||
if (detached) {
|
|
||||||
*detached = handle;
|
|
||||||
}
|
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
|
|
||||||
mysql_mutex_lock(&log_sys.mutex);
|
mysql_mutex_lock(&log_sys.mutex);
|
||||||
|
if (space->max_lsn)
|
||||||
if (space->max_lsn != 0) {
|
{
|
||||||
ut_d(space->max_lsn = 0);
|
ut_d(space->max_lsn = 0);
|
||||||
fil_system.named_spaces.remove(*space);
|
fil_system.named_spaces.remove(*space);
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_mutex_unlock(&log_sys.mutex);
|
mysql_mutex_unlock(&log_sys.mutex);
|
||||||
|
|
||||||
if (!os_file_delete(innodb_data_file_key, space->chain.start->name)
|
fil_space_free_low(space);
|
||||||
&& !os_file_delete_if_exists(innodb_data_file_key,
|
|
||||||
space->chain.start->name, NULL)) {
|
|
||||||
/* Note: This is because we have removed the
|
|
||||||
tablespace instance from the cache. */
|
|
||||||
err = DB_IO_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_space_free_low(space);
|
ibuf_delete_for_discarded_space(id);
|
||||||
goto func_exit;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************//**
|
/*******************************************************************//**
|
||||||
|
@@ -267,20 +267,20 @@ Datafile::read_first_page(bool read_only_mode)
|
|||||||
IORequestReadPartial, m_handle, m_first_page, 0,
|
IORequestReadPartial, m_handle, m_first_page, 0,
|
||||||
page_size, &n_read);
|
page_size, &n_read);
|
||||||
|
|
||||||
if (err == DB_IO_ERROR && n_read >= UNIV_PAGE_SIZE_MIN) {
|
if (err == DB_SUCCESS) {
|
||||||
|
|
||||||
page_size >>= 1;
|
|
||||||
|
|
||||||
} else if (err == DB_SUCCESS) {
|
|
||||||
|
|
||||||
ut_a(n_read == page_size);
|
ut_a(n_read == page_size);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == DB_IO_ERROR && n_read == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (err == DB_IO_ERROR && n_read >= UNIV_PAGE_SIZE_MIN) {
|
||||||
|
page_size >>= 1;
|
||||||
} else if (srv_operation == SRV_OPERATION_BACKUP) {
|
} else if (srv_operation == SRV_OPERATION_BACKUP) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
ib::error() << "Cannot read first page of '"
|
ib::info() << "Cannot read first page of '"
|
||||||
<< m_filepath << "': " << err;
|
<< m_filepath << "': " << err;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,9 @@ Full Text Search interface
|
|||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
#include "trx0roll.h"
|
#include "trx0roll.h"
|
||||||
|
#ifdef UNIV_DEBUG
|
||||||
|
# include "trx0purge.h"
|
||||||
|
#endif
|
||||||
#include "row0mysql.h"
|
#include "row0mysql.h"
|
||||||
#include "row0upd.h"
|
#include "row0upd.h"
|
||||||
#include "dict0types.h"
|
#include "dict0types.h"
|
||||||
@@ -871,7 +874,7 @@ fts_drop_index(
|
|||||||
mysql_mutex_unlock(&cache->init_lock);
|
mysql_mutex_unlock(&cache->init_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = fts_drop_index_tables(trx, index);
|
err = fts_drop_index_tables(trx, *index);
|
||||||
|
|
||||||
ib_vector_remove(indexes, (const void*) index);
|
ib_vector_remove(indexes, (const void*) index);
|
||||||
|
|
||||||
@@ -1400,46 +1403,43 @@ fts_cache_add_doc(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
/** Drop a table.
|
||||||
Drops a table. If the table can't be found we return a SUCCESS code.
|
@param trx transaction
|
||||||
@return DB_SUCCESS or error code */
|
@param table_name FTS_ table name
|
||||||
static MY_ATTRIBUTE((nonnull, warn_unused_result))
|
@param rename whether to rename before dropping
|
||||||
dberr_t
|
@return error code
|
||||||
fts_drop_table(
|
@retval DB_SUCCESS if the table was dropped
|
||||||
/*===========*/
|
@retval DB_FAIL if the table did not exist */
|
||||||
trx_t* trx, /*!< in: transaction */
|
static dberr_t fts_drop_table(trx_t *trx, const char *table_name, bool rename)
|
||||||
const char* table_name) /*!< in: table to drop */
|
|
||||||
{
|
{
|
||||||
dict_table_t* table;
|
if (dict_table_t *table= dict_table_open_on_name(table_name, TRUE, FALSE,
|
||||||
dberr_t error = DB_SUCCESS;
|
DICT_ERR_IGNORE_DROP))
|
||||||
|
{
|
||||||
/* Check that the table exists in our data dictionary.
|
table->release();
|
||||||
Similar to regular drop table case, we will open table with
|
if (rename)
|
||||||
DICT_ERR_IGNORE_INDEX_ROOT and DICT_ERR_IGNORE_CORRUPT option */
|
{
|
||||||
table = dict_table_open_on_name(
|
mem_heap_t *heap= mem_heap_create(FN_REFLEN);
|
||||||
table_name, TRUE, FALSE,
|
char *tmp= dict_mem_create_temporary_tablename(heap, table->name.m_name,
|
||||||
static_cast<dict_err_ignore_t>(
|
table->id);
|
||||||
DICT_ERR_IGNORE_INDEX_ROOT | DICT_ERR_IGNORE_CORRUPT));
|
dberr_t err= row_rename_table_for_mysql(table->name.m_name, tmp, trx,
|
||||||
|
false);
|
||||||
if (table != 0) {
|
mem_heap_free(heap);
|
||||||
|
if (err != DB_SUCCESS)
|
||||||
dict_table_close(table, TRUE, FALSE);
|
{
|
||||||
|
ib::error() << "Unable to rename table " << table_name << ": " << err;
|
||||||
/* Pass nonatomic=false (don't allow data dict unlock),
|
return err;
|
||||||
because the transaction may hold locks on SYS_* tables from
|
|
||||||
previous calls to fts_drop_table(). */
|
|
||||||
error = row_drop_table_for_mysql(table_name, trx,
|
|
||||||
SQLCOM_DROP_DB, false, false);
|
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
|
|
||||||
ib::error() << "Unable to drop FTS index aux table "
|
|
||||||
<< table_name << ": " << error;
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
error = DB_FAIL;
|
if (dberr_t err= trx->drop_table(*table))
|
||||||
|
{
|
||||||
|
ib::error() << "Unable to drop table " << table->name << ": " << err;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(error);
|
return DB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DB_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
@@ -1473,7 +1473,7 @@ fts_rename_one_aux_table(
|
|||||||
fts_table_new_name[table_new_name_len] = 0;
|
fts_table_new_name[table_new_name_len] = 0;
|
||||||
|
|
||||||
return row_rename_table_for_mysql(
|
return row_rename_table_for_mysql(
|
||||||
fts_table_old_name, fts_table_new_name, trx, false, false);
|
fts_table_old_name, fts_table_new_name, trx, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
@@ -1539,25 +1539,115 @@ fts_rename_aux_tables(
|
|||||||
return(DB_SUCCESS);
|
return(DB_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Lock an internal FTS_ table, before fts_drop_table() */
|
||||||
|
static dberr_t fts_lock_table(trx_t *trx, const char *table_name)
|
||||||
|
{
|
||||||
|
ut_ad(purge_sys.must_wait_FTS());
|
||||||
|
|
||||||
|
if (dict_table_t *table= dict_table_open_on_name(table_name, false, false,
|
||||||
|
DICT_ERR_IGNORE_DROP))
|
||||||
|
{
|
||||||
|
dberr_t err= lock_table_for_trx(table, trx, LOCK_X);
|
||||||
|
/* Wait for purge threads to stop using the table. */
|
||||||
|
for (uint n= 15; table->get_ref_count() > 1; )
|
||||||
|
{
|
||||||
|
if (!--n)
|
||||||
|
{
|
||||||
|
err= DB_LOCK_WAIT_TIMEOUT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
}
|
||||||
|
table->release();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return DB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Lock the internal FTS_ tables for an index, before fts_drop_index_tables().
|
||||||
|
@param trx transaction
|
||||||
|
@param index fulltext index */
|
||||||
|
dberr_t fts_lock_index_tables(trx_t *trx, const dict_index_t &index)
|
||||||
|
{
|
||||||
|
ut_ad(index.type & DICT_FTS);
|
||||||
|
fts_table_t fts_table;
|
||||||
|
char table_name[MAX_FULL_NAME_LEN];
|
||||||
|
FTS_INIT_INDEX_TABLE(&fts_table, nullptr, FTS_INDEX_TABLE, (&index));
|
||||||
|
for (const fts_index_selector_t *s= fts_index_selector; s->suffix; s++)
|
||||||
|
{
|
||||||
|
fts_table.suffix= s->suffix;
|
||||||
|
fts_get_table_name(&fts_table, table_name, false);
|
||||||
|
if (dberr_t err= fts_lock_table(trx, table_name))
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return DB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Lock the internal common FTS_ tables, before fts_drop_common_tables().
|
||||||
|
@param trx transaction
|
||||||
|
@param table table containing FULLTEXT INDEX
|
||||||
|
@return DB_SUCCESS or error code */
|
||||||
|
dberr_t fts_lock_common_tables(trx_t *trx, const dict_table_t &table)
|
||||||
|
{
|
||||||
|
fts_table_t fts_table;
|
||||||
|
char table_name[MAX_FULL_NAME_LEN];
|
||||||
|
|
||||||
|
FTS_INIT_FTS_TABLE(&fts_table, nullptr, FTS_COMMON_TABLE, (&table));
|
||||||
|
|
||||||
|
for (const char **suffix= fts_common_tables; *suffix; suffix++)
|
||||||
|
{
|
||||||
|
fts_table.suffix= *suffix;
|
||||||
|
fts_get_table_name(&fts_table, table_name, false);
|
||||||
|
if (dberr_t err= fts_lock_table(trx, table_name))
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return DB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Lock the internal FTS_ tables for table, before fts_drop_tables().
|
||||||
|
@param trx transaction
|
||||||
|
@param table table containing FULLTEXT INDEX
|
||||||
|
@return DB_SUCCESS or error code */
|
||||||
|
dberr_t fts_lock_tables(trx_t *trx, const dict_table_t &table)
|
||||||
|
{
|
||||||
|
if (dberr_t err= fts_lock_common_tables(trx, table))
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (!table.fts)
|
||||||
|
return DB_SUCCESS;
|
||||||
|
|
||||||
|
auto indexes= table.fts->indexes;
|
||||||
|
if (!indexes)
|
||||||
|
return DB_SUCCESS;
|
||||||
|
|
||||||
|
for (ulint i= 0; i < ib_vector_size(indexes); ++i)
|
||||||
|
if (dberr_t err=
|
||||||
|
fts_lock_index_tables(trx, *static_cast<const dict_index_t*>
|
||||||
|
(ib_vector_getp(indexes, i))))
|
||||||
|
return err;
|
||||||
|
return DB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/** Drops the common ancillary tables needed for supporting an FTS index
|
/** Drops the common ancillary tables needed for supporting an FTS index
|
||||||
on the given table. row_mysql_lock_data_dictionary must have been called
|
on the given table. row_mysql_lock_data_dictionary must have been called
|
||||||
before this.
|
before this.
|
||||||
@param[in] trx transaction to drop fts common table
|
@param trx transaction to drop fts common table
|
||||||
@param[in] fts_table table with an FTS index
|
@param fts_table table with an FTS index
|
||||||
|
@param rename whether to rename before dropping
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
static dberr_t fts_drop_common_tables(trx_t *trx, fts_table_t *fts_table)
|
static dberr_t fts_drop_common_tables(trx_t *trx, fts_table_t *fts_table,
|
||||||
|
bool rename)
|
||||||
{
|
{
|
||||||
ulint i;
|
|
||||||
dberr_t error = DB_SUCCESS;
|
dberr_t error = DB_SUCCESS;
|
||||||
|
|
||||||
for (i = 0; fts_common_tables[i] != NULL; ++i) {
|
for (ulint i = 0; fts_common_tables[i] != NULL; ++i) {
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
char table_name[MAX_FULL_NAME_LEN];
|
char table_name[MAX_FULL_NAME_LEN];
|
||||||
|
|
||||||
fts_table->suffix = fts_common_tables[i];
|
fts_table->suffix = fts_common_tables[i];
|
||||||
fts_get_table_name(fts_table, table_name, true);
|
fts_get_table_name(fts_table, table_name, true);
|
||||||
|
|
||||||
err = fts_drop_table(trx, table_name);
|
err = fts_drop_table(trx, table_name, rename);
|
||||||
|
|
||||||
/* We only return the status of the last error. */
|
/* We only return the status of the last error. */
|
||||||
if (err != DB_SUCCESS && err != DB_FAIL) {
|
if (err != DB_SUCCESS && err != DB_FAIL) {
|
||||||
@@ -1571,17 +1661,13 @@ static dberr_t fts_drop_common_tables(trx_t *trx, fts_table_t *fts_table)
|
|||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
Drops FTS auxiliary tables for an FTS index
|
Drops FTS auxiliary tables for an FTS index
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
dberr_t
|
dberr_t fts_drop_index_tables(trx_t *trx, const dict_index_t &index)
|
||||||
fts_drop_index_tables(
|
|
||||||
trx_t* trx, /*!< in: transaction */
|
|
||||||
dict_index_t* index) /*!< in: fts instance */
|
|
||||||
|
|
||||||
{
|
{
|
||||||
ulint i;
|
ulint i;
|
||||||
fts_table_t fts_table;
|
fts_table_t fts_table;
|
||||||
dberr_t error = DB_SUCCESS;
|
dberr_t error = DB_SUCCESS;
|
||||||
|
|
||||||
FTS_INIT_INDEX_TABLE(&fts_table, NULL, FTS_INDEX_TABLE, index);
|
FTS_INIT_INDEX_TABLE(&fts_table, nullptr, FTS_INDEX_TABLE, (&index));
|
||||||
|
|
||||||
for (i = 0; i < FTS_NUM_AUX_INDEX; ++i) {
|
for (i = 0; i < FTS_NUM_AUX_INDEX; ++i) {
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
@@ -1590,7 +1676,7 @@ fts_drop_index_tables(
|
|||||||
fts_table.suffix = fts_get_suffix(i);
|
fts_table.suffix = fts_get_suffix(i);
|
||||||
fts_get_table_name(&fts_table, table_name, true);
|
fts_get_table_name(&fts_table, table_name, true);
|
||||||
|
|
||||||
err = fts_drop_table(trx, table_name);
|
err = fts_drop_table(trx, table_name, false);
|
||||||
|
|
||||||
/* We only return the status of the last error. */
|
/* We only return the status of the last error. */
|
||||||
if (err != DB_SUCCESS && err != DB_FAIL) {
|
if (err != DB_SUCCESS && err != DB_FAIL) {
|
||||||
@@ -1611,52 +1697,36 @@ dberr_t
|
|||||||
fts_drop_all_index_tables(
|
fts_drop_all_index_tables(
|
||||||
/*======================*/
|
/*======================*/
|
||||||
trx_t* trx, /*!< in: transaction */
|
trx_t* trx, /*!< in: transaction */
|
||||||
fts_t* fts) /*!< in: fts instance */
|
const fts_t* fts) /*!< in: fts instance */
|
||||||
{
|
{
|
||||||
dberr_t error = DB_SUCCESS;
|
dberr_t error= DB_SUCCESS;
|
||||||
|
auto indexes= fts->indexes;
|
||||||
|
if (!indexes)
|
||||||
|
return DB_SUCCESS;
|
||||||
|
|
||||||
for (ulint i = 0;
|
for (ulint i= 0; i < ib_vector_size(indexes); ++i)
|
||||||
fts->indexes != 0 && i < ib_vector_size(fts->indexes);
|
if (dberr_t err= fts_drop_index_tables(trx,
|
||||||
++i) {
|
*static_cast<const dict_index_t*>
|
||||||
|
(ib_vector_getp(indexes, i))))
|
||||||
dberr_t err;
|
error= err;
|
||||||
dict_index_t* index;
|
return error;
|
||||||
|
|
||||||
index = static_cast<dict_index_t*>(
|
|
||||||
ib_vector_getp(fts->indexes, i));
|
|
||||||
|
|
||||||
err = fts_drop_index_tables(trx, index);
|
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
|
||||||
error = err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************//**
|
/** Drop the internal FTS_ tables for table.
|
||||||
Drops the ancillary tables needed for supporting an FTS index on a
|
@param trx transaction
|
||||||
given table. row_mysql_lock_data_dictionary must have been called before
|
@param table table containing FULLTEXT INDEX
|
||||||
this.
|
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
dberr_t
|
dberr_t fts_drop_tables(trx_t *trx, const dict_table_t &table)
|
||||||
fts_drop_tables(
|
|
||||||
/*============*/
|
|
||||||
trx_t* trx, /*!< in: transaction */
|
|
||||||
dict_table_t* table) /*!< in: table has the FTS index */
|
|
||||||
{
|
{
|
||||||
dberr_t error;
|
dberr_t error;
|
||||||
fts_table_t fts_table;
|
fts_table_t fts_table;
|
||||||
|
|
||||||
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
|
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, (&table));
|
||||||
|
|
||||||
/* TODO: This is not atomic and can cause problems during recovery. */
|
error = fts_drop_common_tables(trx, &fts_table, false);
|
||||||
|
|
||||||
error = fts_drop_common_tables(trx, &fts_table);
|
if (error == DB_SUCCESS && table.fts) {
|
||||||
|
error = fts_drop_all_index_tables(trx, table.fts);
|
||||||
if (error == DB_SUCCESS && table->fts) {
|
|
||||||
error = fts_drop_all_index_tables(trx, table->fts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(error);
|
return(error);
|
||||||
@@ -1797,7 +1867,7 @@ fts_create_common_tables(
|
|||||||
|
|
||||||
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
|
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
|
||||||
|
|
||||||
error = fts_drop_common_tables(trx, &fts_table);
|
error = fts_drop_common_tables(trx, &fts_table, true);
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
if (error != DB_SUCCESS) {
|
||||||
|
|
||||||
@@ -4172,8 +4242,7 @@ begin_sync:
|
|||||||
index_cache = static_cast<fts_index_cache_t*>(
|
index_cache = static_cast<fts_index_cache_t*>(
|
||||||
ib_vector_get(cache->indexes, i));
|
ib_vector_get(cache->indexes, i));
|
||||||
|
|
||||||
if (index_cache->index->to_be_dropped
|
if (index_cache->index->to_be_dropped) {
|
||||||
|| index_cache->index->table->to_be_dropped) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4201,7 +4270,6 @@ begin_sync:
|
|||||||
ib_vector_get(cache->indexes, i));
|
ib_vector_get(cache->indexes, i));
|
||||||
|
|
||||||
if (index_cache->index->to_be_dropped
|
if (index_cache->index->to_be_dropped
|
||||||
|| index_cache->index->table->to_be_dropped
|
|
||||||
|| fts_sync_index_check(index_cache)) {
|
|| fts_sync_index_check(index_cache)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@@ -94,7 +94,6 @@ this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "mtr0mtr.h"
|
#include "mtr0mtr.h"
|
||||||
#include "os0file.h"
|
#include "os0file.h"
|
||||||
#include "page0zip.h"
|
#include "page0zip.h"
|
||||||
#include "pars0pars.h"
|
|
||||||
#include "rem0types.h"
|
#include "rem0types.h"
|
||||||
#include "row0import.h"
|
#include "row0import.h"
|
||||||
#include "row0ins.h"
|
#include "row0ins.h"
|
||||||
@@ -186,7 +185,7 @@ static char* innobase_reset_all_monitor_counter;
|
|||||||
stopword table to be used */
|
stopword table to be used */
|
||||||
static char* innobase_server_stopword_table;
|
static char* innobase_server_stopword_table;
|
||||||
|
|
||||||
static my_bool innobase_rollback_on_timeout;
|
my_bool innobase_rollback_on_timeout;
|
||||||
static my_bool innobase_create_status_file;
|
static my_bool innobase_create_status_file;
|
||||||
my_bool innobase_stats_on_metadata;
|
my_bool innobase_stats_on_metadata;
|
||||||
static my_bool innodb_optimize_fulltext_only;
|
static my_bool innodb_optimize_fulltext_only;
|
||||||
@@ -1312,7 +1311,8 @@ static ibool innodb_drop_database_fk(void *node, void *report)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove all tables in the named database inside InnoDB.
|
/** After DROP DATABASE executed ha_innobase::delete_table() on all
|
||||||
|
tables that it was aware of, drop any leftover tables inside InnoDB.
|
||||||
@param path database path */
|
@param path database path */
|
||||||
static void innodb_drop_database(handlerton*, char *path)
|
static void innodb_drop_database(handlerton*, char *path)
|
||||||
{
|
{
|
||||||
@@ -1375,15 +1375,12 @@ retry:
|
|||||||
continue;
|
continue;
|
||||||
const auto n_handles= table->get_ref_count();
|
const auto n_handles= table->get_ref_count();
|
||||||
const bool locks= !n_handles && lock_table_has_locks(table);
|
const bool locks= !n_handles && lock_table_has_locks(table);
|
||||||
const auto n_fk_checks= table->n_foreign_key_checks_running;
|
if (n_handles || locks)
|
||||||
if (n_fk_checks || n_handles || locks)
|
|
||||||
{
|
{
|
||||||
err= DB_ERROR;
|
err= DB_ERROR;
|
||||||
ib::error errmsg;
|
ib::error errmsg;
|
||||||
errmsg << "DROP DATABASE: cannot DROP TABLE " << table->name;
|
errmsg << "DROP DATABASE: cannot DROP TABLE " << table->name;
|
||||||
if (n_fk_checks)
|
if (n_handles)
|
||||||
errmsg << " due to " << n_fk_checks << " FOREIGN KEY checks";
|
|
||||||
else if (n_handles)
|
|
||||||
errmsg << " due to " << n_handles << " open handles";
|
errmsg << " due to " << n_handles << " open handles";
|
||||||
else
|
else
|
||||||
errmsg << " due to locks";
|
errmsg << " due to locks";
|
||||||
@@ -1393,6 +1390,20 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trx_start_for_ddl(trx);
|
||||||
|
uint errors= 0;
|
||||||
|
char db[NAME_LEN + 1];
|
||||||
|
strconvert(&my_charset_filename, namebuf, len, system_charset_info, db,
|
||||||
|
sizeof db, &errors);
|
||||||
|
if (errors);
|
||||||
|
else if (dict_stats_delete(db, trx))
|
||||||
|
{
|
||||||
|
/* Ignore this error. Leaving garbage statistics behind is a
|
||||||
|
lesser evil. Carry on to try to remove any garbage tables. */
|
||||||
|
trx->rollback();
|
||||||
|
trx_start_for_ddl(trx);
|
||||||
|
}
|
||||||
|
|
||||||
static const char drop_database[] =
|
static const char drop_database[] =
|
||||||
"PROCEDURE DROP_DATABASE_PROC () IS\n"
|
"PROCEDURE DROP_DATABASE_PROC () IS\n"
|
||||||
"fk CHAR;\n"
|
"fk CHAR;\n"
|
||||||
@@ -1453,7 +1464,6 @@ retry:
|
|||||||
"END;\n";
|
"END;\n";
|
||||||
|
|
||||||
innodb_drop_database_fk_report report{{namebuf, len + 1}, false};
|
innodb_drop_database_fk_report report{{namebuf, len + 1}, false};
|
||||||
trx_start_for_ddl(trx);
|
|
||||||
|
|
||||||
if (err == DB_SUCCESS)
|
if (err == DB_SUCCESS)
|
||||||
{
|
{
|
||||||
@@ -1539,8 +1549,7 @@ retry:
|
|||||||
ut_ad("corrupted SYS_TABLES.SPACE" == 0);
|
ut_ad("corrupted SYS_TABLES.SPACE" == 0);
|
||||||
else if (uint32_t space_id= mach_read_from_4(s))
|
else if (uint32_t space_id= mach_read_from_4(s))
|
||||||
{
|
{
|
||||||
pfs_os_file_t detached= OS_FILE_CLOSED;
|
pfs_os_file_t detached= fil_delete_tablespace(space_id);
|
||||||
fil_delete_tablespace(space_id, true, &detached);
|
|
||||||
if (detached != OS_FILE_CLOSED)
|
if (detached != OS_FILE_CLOSED)
|
||||||
to_close.emplace_back(detached);
|
to_close.emplace_back(detached);
|
||||||
}
|
}
|
||||||
@@ -1900,6 +1909,9 @@ static int innobase_wsrep_set_checkpoint(handlerton* hton, const XID* xid);
|
|||||||
static int innobase_wsrep_get_checkpoint(handlerton* hton, XID* xid);
|
static int innobase_wsrep_get_checkpoint(handlerton* hton, XID* xid);
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
|
|
||||||
|
#define normalize_table_name(a,b) \
|
||||||
|
normalize_table_name_c_low(a,b,IF_WIN(true,false))
|
||||||
|
|
||||||
ulonglong ha_innobase::table_version() const
|
ulonglong ha_innobase::table_version() const
|
||||||
{
|
{
|
||||||
/* This is either "garbage" or something that was assigned
|
/* This is either "garbage" or something that was assigned
|
||||||
@@ -2030,7 +2042,7 @@ convert_error_code_to_mysql(
|
|||||||
|
|
||||||
if (thd) {
|
if (thd) {
|
||||||
thd_mark_transaction_to_rollback(
|
thd_mark_transaction_to_rollback(
|
||||||
thd, (bool) row_rollback_on_timeout);
|
thd, innobase_rollback_on_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(HA_ERR_LOCK_WAIT_TIMEOUT);
|
return(HA_ERR_LOCK_WAIT_TIMEOUT);
|
||||||
@@ -2066,9 +2078,6 @@ convert_error_code_to_mysql(
|
|||||||
"InnoDB");
|
"InnoDB");
|
||||||
return(HA_ERR_INTERNAL_ERROR);
|
return(HA_ERR_INTERNAL_ERROR);
|
||||||
|
|
||||||
case DB_TABLE_IN_FK_CHECK:
|
|
||||||
return(HA_ERR_TABLE_IN_FK_CHECK);
|
|
||||||
|
|
||||||
case DB_TABLE_NOT_FOUND:
|
case DB_TABLE_NOT_FOUND:
|
||||||
return(HA_ERR_NO_SUCH_TABLE);
|
return(HA_ERR_NO_SUCH_TABLE);
|
||||||
|
|
||||||
@@ -3809,8 +3818,6 @@ static int innodb_init_params()
|
|||||||
|
|
||||||
srv_buf_pool_size = ulint(innobase_buffer_pool_size);
|
srv_buf_pool_size = ulint(innobase_buffer_pool_size);
|
||||||
|
|
||||||
row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
|
|
||||||
|
|
||||||
if (innobase_open_files < 10) {
|
if (innobase_open_files < 10) {
|
||||||
innobase_open_files = 300;
|
innobase_open_files = 300;
|
||||||
if (srv_file_per_table && tc_size > 300 && tc_size < open_files_limit) {
|
if (srv_file_per_table && tc_size > 300 && tc_size < open_files_limit) {
|
||||||
@@ -3943,6 +3950,7 @@ static int innodb_init(void* p)
|
|||||||
HTON_NATIVE_SYS_VERSIONING |
|
HTON_NATIVE_SYS_VERSIONING |
|
||||||
HTON_WSREP_REPLICATION |
|
HTON_WSREP_REPLICATION |
|
||||||
HTON_REQUIRES_CLOSE_AFTER_TRUNCATE |
|
HTON_REQUIRES_CLOSE_AFTER_TRUNCATE |
|
||||||
|
HTON_TRUNCATE_REQUIRES_EXCLUSIVE_USE |
|
||||||
HTON_REQUIRES_NOTIFY_TABLEDEF_CHANGED_AFTER_COMMIT;
|
HTON_REQUIRES_NOTIFY_TABLEDEF_CHANGED_AFTER_COMMIT;
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
@@ -4129,9 +4137,8 @@ innobase_commit_low(
|
|||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
const char* tmp = 0;
|
const char* tmp = 0;
|
||||||
const bool is_wsrep = trx->is_wsrep();
|
const bool is_wsrep = trx->is_wsrep();
|
||||||
THD* thd = trx->mysql_thd;
|
|
||||||
if (is_wsrep) {
|
if (is_wsrep) {
|
||||||
tmp = thd_proc_info(thd, "innobase_commit_low()");
|
tmp = thd_proc_info(trx->mysql_thd, "innobase_commit_low()");
|
||||||
}
|
}
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
if (trx_is_started(trx)) {
|
if (trx_is_started(trx)) {
|
||||||
@@ -4145,7 +4152,7 @@ innobase_commit_low(
|
|||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
if (is_wsrep) {
|
if (is_wsrep) {
|
||||||
thd_proc_info(thd, tmp);
|
thd_proc_info(trx->mysql_thd, tmp);
|
||||||
}
|
}
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
}
|
}
|
||||||
@@ -5009,10 +5016,6 @@ ha_innobase::table_cache_type()
|
|||||||
return(HA_CACHE_TBL_ASKTRANSACT);
|
return(HA_CACHE_TBL_ASKTRANSACT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
|
||||||
Determines if the primary key is clustered index.
|
|
||||||
@return true */
|
|
||||||
|
|
||||||
/** Normalizes a table name string.
|
/** Normalizes a table name string.
|
||||||
A normalized name consists of the database name catenated to '/'
|
A normalized name consists of the database name catenated to '/'
|
||||||
and table name. For example: test/mytable.
|
and table name. For example: test/mytable.
|
||||||
@@ -5027,7 +5030,7 @@ normalize_table_name_c_low(
|
|||||||
char* norm_name, /* out: normalized name as a
|
char* norm_name, /* out: normalized name as a
|
||||||
null-terminated string */
|
null-terminated string */
|
||||||
const char* name, /* in: table name string */
|
const char* name, /* in: table name string */
|
||||||
ibool set_lower_case) /* in: TRUE if we want to set
|
bool set_lower_case) /* in: TRUE if we want to set
|
||||||
name to lower case */
|
name to lower case */
|
||||||
{
|
{
|
||||||
char* name_ptr;
|
char* name_ptr;
|
||||||
@@ -5095,29 +5098,11 @@ create_table_info_t::create_table_info_t(
|
|||||||
m_default_row_format(innodb_default_row_format),
|
m_default_row_format(innodb_default_row_format),
|
||||||
m_create_info(create_info),
|
m_create_info(create_info),
|
||||||
m_table_name(table_name), m_table(NULL),
|
m_table_name(table_name), m_table(NULL),
|
||||||
m_drop_before_rollback(false),
|
|
||||||
m_remote_path(remote_path),
|
m_remote_path(remote_path),
|
||||||
m_innodb_file_per_table(file_per_table)
|
m_innodb_file_per_table(file_per_table)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Normalizes a table name string.
|
|
||||||
A normalized name consists of the database name catenated to '/'
|
|
||||||
and table name. For example: test/mytable.
|
|
||||||
On Windows, normalization puts both the database name and the
|
|
||||||
table name always to lower case if "set_lower_case" is set to TRUE.
|
|
||||||
@param[out] norm_name Normalized name, null-terminated.
|
|
||||||
@param[in] name Name to normalize.
|
|
||||||
@param[in] set_lower_case True if we also should fold to lower case. */
|
|
||||||
void
|
|
||||||
create_table_info_t::normalize_table_name_low(
|
|
||||||
char* norm_name,
|
|
||||||
const char* name,
|
|
||||||
ibool set_lower_case)
|
|
||||||
{
|
|
||||||
normalize_table_name_c_low(norm_name, name, set_lower_case);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(DBUG_OFF)
|
#if !defined(DBUG_OFF)
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
Test normalize_table_name_low(). */
|
Test normalize_table_name_low(). */
|
||||||
@@ -5172,7 +5157,7 @@ test_normalize_table_name_low()
|
|||||||
" testing \"%s\", expected \"%s\"... ",
|
" testing \"%s\", expected \"%s\"... ",
|
||||||
test_data[i][0], test_data[i][1]);
|
test_data[i][0], test_data[i][1]);
|
||||||
|
|
||||||
create_table_info_t::normalize_table_name_low(
|
normalize_table_name_c_low(
|
||||||
norm_name, test_data[i][0], FALSE);
|
norm_name, test_data[i][0], FALSE);
|
||||||
|
|
||||||
if (strcmp(norm_name, test_data[i][1]) == 0) {
|
if (strcmp(norm_name, test_data[i][1]) == 0) {
|
||||||
@@ -6040,10 +6025,8 @@ ha_innobase::open_dict_table(
|
|||||||
whether there exists table name in
|
whether there exists table name in
|
||||||
system table whose name is
|
system table whose name is
|
||||||
not being normalized to lower case */
|
not being normalized to lower case */
|
||||||
create_table_info_t::
|
normalize_table_name_c_low(
|
||||||
normalize_table_name_low(
|
par_case_name, table_name, false);
|
||||||
par_case_name,
|
|
||||||
table_name, FALSE);
|
|
||||||
#endif
|
#endif
|
||||||
ib_table = dict_table_open_on_name(
|
ib_table = dict_table_open_on_name(
|
||||||
par_case_name, FALSE, TRUE,
|
par_case_name, FALSE, TRUE,
|
||||||
@@ -10395,7 +10378,6 @@ create_table_info_t::create_table_def()
|
|||||||
DBUG_PRINT("enter", ("table_name: %s", m_table_name));
|
DBUG_PRINT("enter", ("table_name: %s", m_table_name));
|
||||||
|
|
||||||
DBUG_ASSERT(m_trx->mysql_thd == m_thd);
|
DBUG_ASSERT(m_trx->mysql_thd == m_thd);
|
||||||
DBUG_ASSERT(!m_drop_before_rollback);
|
|
||||||
|
|
||||||
/* MySQL does the name length check. But we do additional check
|
/* MySQL does the name length check. But we do additional check
|
||||||
on the name length here */
|
on the name length here */
|
||||||
@@ -10672,7 +10654,6 @@ err_col:
|
|||||||
} else {
|
} else {
|
||||||
if (err == DB_SUCCESS) {
|
if (err == DB_SUCCESS) {
|
||||||
err = row_create_table_for_mysql(table, m_trx);
|
err = row_create_table_for_mysql(table, m_trx);
|
||||||
m_drop_before_rollback = (err == DB_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("ib_crash_during_create_for_encryption",
|
DBUG_EXECUTE_IF("ib_crash_during_create_for_encryption",
|
||||||
@@ -12493,9 +12474,6 @@ int create_table_info_t::create_table(bool create_fk)
|
|||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_ASSERT(m_drop_before_rollback
|
|
||||||
== !(m_flags2 & DICT_TF2_TEMPORARY));
|
|
||||||
|
|
||||||
/* Create the keys */
|
/* Create the keys */
|
||||||
|
|
||||||
if (m_form->s->keys == 0 || primary_key_no == -1) {
|
if (m_form->s->keys == 0 || primary_key_no == -1) {
|
||||||
@@ -13044,18 +13022,15 @@ ha_innobase::create(
|
|||||||
/* Drop the being-created table before rollback,
|
/* Drop the being-created table before rollback,
|
||||||
so that rollback can possibly rename back a table
|
so that rollback can possibly rename back a table
|
||||||
that could have been renamed before the failed creation. */
|
that could have been renamed before the failed creation. */
|
||||||
if (info.drop_before_rollback()) {
|
|
||||||
trx->error_state = DB_SUCCESS;
|
|
||||||
row_drop_table_for_mysql(info.table_name(),
|
|
||||||
trx, SQLCOM_TRUNCATE, true,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
trx_rollback_for_mysql(trx);
|
trx_rollback_for_mysql(trx);
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
} else {
|
} else {
|
||||||
innobase_commit_low(trx);
|
/* When this is invoked as part of ha_innobase::truncate(),
|
||||||
|
the old copy of the table will be deleted here. */
|
||||||
|
std::vector<pfs_os_file_t> deleted;
|
||||||
|
trx->commit(deleted);
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
ut_ad(!srv_read_only_mode);
|
for (pfs_os_file_t d : deleted) os_file_close(d);
|
||||||
error = info.create_table_update_dict();
|
error = info.create_table_update_dict();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13142,7 +13117,7 @@ ha_innobase::discard_or_import_tablespace(
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = row_discard_tablespace_for_mysql(
|
err = row_discard_tablespace_for_mysql(
|
||||||
m_prebuilt->table->name.m_name, m_prebuilt->trx);
|
m_prebuilt->table, m_prebuilt->trx);
|
||||||
|
|
||||||
} else if (m_prebuilt->table->is_readable()) {
|
} else if (m_prebuilt->table->is_readable()) {
|
||||||
/* Commit the transaction in order to
|
/* Commit the transaction in order to
|
||||||
@@ -13222,141 +13197,210 @@ ha_innobase::discard_or_import_tablespace(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/** DROP TABLE (possibly as part of DROP DATABASE, CREATE/ALTER TABLE)
|
||||||
Drops a table from an InnoDB database. Before calling this function,
|
@param name table name
|
||||||
MySQL calls innobase_commit to commit the transaction of the current user.
|
|
||||||
Then the current user cannot have locks set on the table. Drop table
|
|
||||||
operation inside InnoDB will remove all locks any user has on the table
|
|
||||||
inside InnoDB.
|
|
||||||
@param[in] name table name
|
|
||||||
@param[in] sqlcom SQLCOM_DROP_DB, SQLCOM_TRUNCATE, ...
|
|
||||||
@return error number */
|
@return error number */
|
||||||
inline int ha_innobase::delete_table(const char* name, enum_sql_command sqlcom)
|
int ha_innobase::delete_table(const char *name)
|
||||||
{
|
{
|
||||||
dberr_t err;
|
|
||||||
THD* thd = ha_thd();
|
|
||||||
char norm_name[FN_REFLEN];
|
|
||||||
|
|
||||||
DBUG_ENTER("ha_innobase::delete_table");
|
DBUG_ENTER("ha_innobase::delete_table");
|
||||||
|
if (high_level_read_only)
|
||||||
DBUG_EXECUTE_IF(
|
|
||||||
"test_normalize_table_name_low",
|
|
||||||
test_normalize_table_name_low();
|
|
||||||
);
|
|
||||||
DBUG_EXECUTE_IF(
|
|
||||||
"test_ut_format_name",
|
|
||||||
test_ut_format_name();
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Strangely, MySQL passes the table name without the '.frm'
|
|
||||||
extension, in contrast to ::create */
|
|
||||||
normalize_table_name(norm_name, name);
|
|
||||||
|
|
||||||
if (high_level_read_only) {
|
|
||||||
DBUG_RETURN(HA_ERR_TABLE_READONLY);
|
DBUG_RETURN(HA_ERR_TABLE_READONLY);
|
||||||
|
|
||||||
|
THD *thd= ha_thd();
|
||||||
|
|
||||||
|
DBUG_EXECUTE_IF("test_normalize_table_name_low",
|
||||||
|
test_normalize_table_name_low(););
|
||||||
|
DBUG_EXECUTE_IF("test_ut_format_name", test_ut_format_name(););
|
||||||
|
|
||||||
|
trx_t *parent_trx= check_trx_exists(thd);
|
||||||
|
dict_table_t *table;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
char norm_name[FN_REFLEN];
|
||||||
|
normalize_table_name(norm_name, name);
|
||||||
|
span<const char> n{norm_name, strlen(norm_name)};
|
||||||
|
|
||||||
|
dict_sys.lock(SRW_LOCK_CALL);
|
||||||
|
table= dict_sys.load_table(n, DICT_ERR_IGNORE_DROP);
|
||||||
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
|
if (!table && lower_case_table_names == 1 && is_partition(norm_name))
|
||||||
|
{
|
||||||
|
IF_WIN(normalize_table_name_c_low(norm_name, name, false),
|
||||||
|
innobase_casedn_str(norm_name));
|
||||||
|
table= dict_sys.load_table(n, DICT_ERR_IGNORE_DROP);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!table)
|
||||||
|
{
|
||||||
|
dict_sys.unlock();
|
||||||
|
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
trx_t* parent_trx = check_trx_exists(thd);
|
if (dict_stats_stop_bg(table))
|
||||||
|
break;
|
||||||
|
dict_sys.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove the to-be-dropped table from the list of modified tables
|
if (table->is_temporary())
|
||||||
by parent_trx. Otherwise we may end up with an orphaned pointer to
|
{
|
||||||
the table object from parent_trx::mod_tables. This could happen in:
|
dict_sys.remove(table, false, true);
|
||||||
SET AUTOCOMMIT=0;
|
dict_sys.unlock();
|
||||||
CREATE TABLE t (PRIMARY KEY (a)) ENGINE=INNODB SELECT 1 AS a UNION
|
parent_trx->mod_tables.erase(table); /* CREATE...SELECT error handling */
|
||||||
ALL SELECT 1 AS a; */
|
btr_drop_temporary_table(*table);
|
||||||
for (auto iter = parent_trx->mod_tables.begin();
|
dict_mem_table_free(table);
|
||||||
iter != parent_trx->mod_tables.end();
|
DBUG_RETURN(0);
|
||||||
++iter) {
|
}
|
||||||
|
|
||||||
dict_table_t* table_to_drop = iter->first;
|
table->acquire();
|
||||||
|
dict_sys.unlock();
|
||||||
|
|
||||||
if (strcmp(norm_name, table_to_drop->name.m_name) == 0) {
|
trx_t *trx= parent_trx;
|
||||||
parent_trx->mod_tables.erase(iter);
|
if (!trx->lock.table_locks.empty() &&
|
||||||
|
thd_sql_command(trx->mysql_thd) == SQLCOM_CREATE_TABLE)
|
||||||
|
{
|
||||||
|
#if 0 // MDEV-21602 FIXME: this fails for innodb.innodb and some others
|
||||||
|
for (const lock_t *l : trx->lock.table_locks)
|
||||||
|
if (l && l->type_mode == (LOCK_IX | LOCK_TABLE) &&
|
||||||
|
l->un_member.tab_lock.table == table)
|
||||||
|
goto create_select;
|
||||||
|
sql_print_warning("InnoDB: CREATE...SELECT did not hold expected locks");
|
||||||
|
create_select:
|
||||||
|
#endif
|
||||||
|
/* CREATE TABLE...PRIMARY KEY...SELECT ought to be dropping the
|
||||||
|
table because a duplicate key was detected. We shall hijack the
|
||||||
|
existing transaction to drop the table and commit the transaction.
|
||||||
|
If this is a partitioned table, one partition will use this hijacked
|
||||||
|
transaction; others will use a separate transaction, one per partition. */
|
||||||
|
ut_ad(!trx->dict_operation_lock_mode);
|
||||||
|
ut_ad(trx->will_lock);
|
||||||
|
ut_ad(trx->state == TRX_STATE_ACTIVE);
|
||||||
|
trx->dict_operation= true;
|
||||||
|
trx->internal= true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
trx= innobase_trx_allocate(thd);
|
||||||
|
trx_start_for_ddl(trx);
|
||||||
|
}
|
||||||
|
|
||||||
|
dberr_t err= lock_table_for_trx(table, trx, LOCK_X);
|
||||||
|
const bool fts= err == DB_SUCCESS &&
|
||||||
|
(table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS));
|
||||||
|
|
||||||
|
if (fts)
|
||||||
|
{
|
||||||
|
fts_optimize_remove_table(table);
|
||||||
|
purge_sys.stop_FTS();
|
||||||
|
err= fts_lock_tables(trx, *table);
|
||||||
|
}
|
||||||
|
|
||||||
|
dict_sys.lock(SRW_LOCK_CALL);
|
||||||
|
trx->dict_operation_lock_mode= RW_X_LATCH;
|
||||||
|
if (!table->release() && err == DB_SUCCESS)
|
||||||
|
{
|
||||||
|
/* Wait for purge threads to stop using the table. */
|
||||||
|
for (uint n= 15;;)
|
||||||
|
{
|
||||||
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
row_mysql_lock_data_dictionary(trx);
|
||||||
|
|
||||||
|
if (!--n)
|
||||||
|
{
|
||||||
|
err= DB_LOCK_WAIT_TIMEOUT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!table->get_ref_count())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trx_t* trx = innobase_trx_allocate(thd);
|
if (err != DB_SUCCESS)
|
||||||
|
{
|
||||||
ulint name_len = strlen(name);
|
err_exit:
|
||||||
|
trx->rollback();
|
||||||
ut_a(name_len < 1000);
|
trx->dict_operation_lock_mode= 0;
|
||||||
|
switch (err) {
|
||||||
trx->will_lock = true;
|
case DB_CANNOT_DROP_CONSTRAINT:
|
||||||
|
case DB_LOCK_WAIT_TIMEOUT:
|
||||||
/* Drop the table in InnoDB */
|
break;
|
||||||
|
default:
|
||||||
err = row_drop_table_for_mysql(norm_name, trx, sqlcom);
|
ib::error() << "DROP TABLE " << table->name << ": " << err;
|
||||||
|
|
||||||
if (err == DB_TABLE_NOT_FOUND && lower_case_table_names == 1) {
|
|
||||||
char* is_part = is_partition(norm_name);
|
|
||||||
|
|
||||||
if (is_part) {
|
|
||||||
char par_case_name[FN_REFLEN];
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
/* Check for the table using lower
|
|
||||||
case name, including the partition
|
|
||||||
separator "P" */
|
|
||||||
strcpy(par_case_name, norm_name);
|
|
||||||
innobase_casedn_str(par_case_name);
|
|
||||||
#else
|
|
||||||
/* On Windows platfrom, check
|
|
||||||
whether there exists table name in
|
|
||||||
system table whose name is
|
|
||||||
not being normalized to lower case */
|
|
||||||
normalize_table_name_c_low(
|
|
||||||
par_case_name, name, FALSE);
|
|
||||||
#endif
|
|
||||||
err = row_drop_table_for_mysql(
|
|
||||||
par_case_name, trx, sqlcom);
|
|
||||||
}
|
}
|
||||||
|
table->stats_bg_flag= BG_STAT_NONE;
|
||||||
|
if (fts)
|
||||||
|
{
|
||||||
|
fts_optimize_add_table(table);
|
||||||
|
purge_sys.resume_FTS();
|
||||||
}
|
}
|
||||||
|
dict_sys.unlock();
|
||||||
ut_ad(!srv_read_only_mode);
|
if (trx != parent_trx)
|
||||||
|
|
||||||
innobase_commit_low(trx);
|
|
||||||
|
|
||||||
trx->free();
|
trx->free();
|
||||||
|
|
||||||
DBUG_RETURN(convert_error_code_to_mysql(err, 0, NULL));
|
DBUG_RETURN(convert_error_code_to_mysql(err, 0, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Drop an InnoDB table.
|
if (!table->no_rollback() && trx->check_foreigns)
|
||||||
@param[in] name table name
|
{
|
||||||
@return error number */
|
const bool drop_db= thd_sql_command(thd) == SQLCOM_DROP_DB;
|
||||||
int ha_innobase::delete_table(const char* name)
|
for (auto foreign : table->referenced_set)
|
||||||
{
|
{
|
||||||
enum_sql_command sqlcom = enum_sql_command(thd_sql_command(ha_thd()));
|
/* We should allow dropping a referenced table if creating
|
||||||
/* SQLCOM_TRUNCATE should be passed via ha_innobase::truncate() only.
|
that referenced table has failed for some reason. For example
|
||||||
|
if referenced table is created but it column types that are
|
||||||
|
referenced do not match. */
|
||||||
|
if (foreign->foreign_table == table ||
|
||||||
|
(drop_db &&
|
||||||
|
dict_tables_have_same_db(table->name.m_name,
|
||||||
|
foreign->foreign_table_name_lookup)))
|
||||||
|
continue;
|
||||||
|
mysql_mutex_lock(&dict_foreign_err_mutex);
|
||||||
|
rewind(dict_foreign_err_file);
|
||||||
|
ut_print_timestamp(dict_foreign_err_file);
|
||||||
|
fputs(" Cannot drop table ", dict_foreign_err_file);
|
||||||
|
ut_print_name(dict_foreign_err_file, trx, table->name.m_name);
|
||||||
|
fputs("\nbecause it is referenced by ", dict_foreign_err_file);
|
||||||
|
ut_print_name(dict_foreign_err_file, trx, foreign->foreign_table_name);
|
||||||
|
putc('\n', dict_foreign_err_file);
|
||||||
|
mysql_mutex_unlock(&dict_foreign_err_mutex);
|
||||||
|
err= DB_CANNOT_DROP_CONSTRAINT;
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
On client disconnect, when dropping temporary tables, the
|
if (!table->no_rollback())
|
||||||
previous sqlcom would not be overwritten. In such a case, we
|
{
|
||||||
will have thd_kill_level() != NOT_KILLED, !m_prebuilt can
|
err= trx->drop_table_foreign(table->name);
|
||||||
hold, and sqlcom could be anything, including TRUNCATE.
|
if (err == DB_SUCCESS)
|
||||||
|
err= trx->drop_table_statistics(table->name);
|
||||||
|
if (err != DB_SUCCESS)
|
||||||
|
goto err_exit;
|
||||||
|
}
|
||||||
|
|
||||||
The sqlcom only matters for persistent tables; no persistent
|
err= trx->drop_table(*table);
|
||||||
metadata or FOREIGN KEY metadata is kept for temporary
|
if (err != DB_SUCCESS)
|
||||||
tables. Therefore, we relax the assertion. If there is a bug
|
goto err_exit;
|
||||||
that slips through this assertion due to !m_prebuilt, the
|
|
||||||
worst impact should be that on DROP TABLE of a persistent
|
std::vector<pfs_os_file_t> deleted;
|
||||||
table, FOREIGN KEY constraints will be ignored and their
|
trx->commit(deleted);
|
||||||
metadata will not be removed. */
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
DBUG_ASSERT(sqlcom != SQLCOM_TRUNCATE
|
if (trx != parent_trx)
|
||||||
|| (thd_kill_level(ha_thd()) != THD_IS_NOT_KILLED
|
trx->free();
|
||||||
&& (!m_prebuilt
|
for (pfs_os_file_t d : deleted)
|
||||||
|| m_prebuilt->table->is_temporary())));
|
os_file_close(d);
|
||||||
return delete_table(name, sqlcom);
|
if (fts)
|
||||||
|
purge_sys.resume_FTS();
|
||||||
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Rename an InnoDB table.
|
/** Rename an InnoDB table.
|
||||||
@param[in,out] trx InnoDB data dictionary transaction
|
@param[in,out] trx InnoDB data dictionary transaction
|
||||||
@param[in] from old table name
|
@param[in] from old table name
|
||||||
@param[in] to new table name
|
@param[in] to new table name
|
||||||
@param[in] commit whether to commit trx (and to enforce FOREIGN KEY)
|
@param[in] use_fk whether to enforce FOREIGN KEY
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
inline dberr_t innobase_rename_table(trx_t *trx, const char *from,
|
inline dberr_t innobase_rename_table(trx_t *trx, const char *from,
|
||||||
const char *to, bool commit)
|
const char *to, bool use_fk)
|
||||||
{
|
{
|
||||||
dberr_t error;
|
dberr_t error;
|
||||||
char norm_to[FN_REFLEN];
|
char norm_to[FN_REFLEN];
|
||||||
@@ -13375,14 +13419,7 @@ inline dberr_t innobase_rename_table(trx_t *trx, const char *from,
|
|||||||
trx_start_if_not_started(trx, true);
|
trx_start_if_not_started(trx, true);
|
||||||
ut_ad(trx->will_lock);
|
ut_ad(trx->will_lock);
|
||||||
|
|
||||||
if (commit) {
|
error = row_rename_table_for_mysql(norm_from, norm_to, trx, use_fk);
|
||||||
/* Serialize data dictionary operations with dictionary mutex:
|
|
||||||
no deadlocks can occur then in these operations. */
|
|
||||||
row_mysql_lock_data_dictionary(trx);
|
|
||||||
}
|
|
||||||
|
|
||||||
error = row_rename_table_for_mysql(norm_from, norm_to, trx, commit,
|
|
||||||
commit);
|
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
if (error != DB_SUCCESS) {
|
||||||
if (error == DB_TABLE_NOT_FOUND
|
if (error == DB_TABLE_NOT_FOUND
|
||||||
@@ -13402,13 +13439,12 @@ inline dberr_t innobase_rename_table(trx_t *trx, const char *from,
|
|||||||
whether there exists table name in
|
whether there exists table name in
|
||||||
system table whose name is
|
system table whose name is
|
||||||
not being normalized to lower case */
|
not being normalized to lower case */
|
||||||
create_table_info_t::normalize_table_name_low(
|
normalize_table_name_c_low(
|
||||||
par_case_name, from, FALSE);
|
par_case_name, from, false);
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
trx_start_if_not_started(trx, true);
|
trx_start_if_not_started(trx, true);
|
||||||
error = row_rename_table_for_mysql(
|
error = row_rename_table_for_mysql(
|
||||||
par_case_name, norm_to, trx,
|
par_case_name, norm_to, trx, false);
|
||||||
true, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13432,10 +13468,6 @@ inline dberr_t innobase_rename_table(trx_t *trx, const char *from,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commit) {
|
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13453,44 +13485,9 @@ int ha_innobase::truncate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
HA_CREATE_INFO info;
|
HA_CREATE_INFO info;
|
||||||
mem_heap_t* heap = mem_heap_create(1000);
|
|
||||||
dict_table_t* ib_table = m_prebuilt->table;
|
dict_table_t* ib_table = m_prebuilt->table;
|
||||||
const auto update_time = ib_table->update_time;
|
|
||||||
const auto stored_lock = m_prebuilt->stored_select_lock_type;
|
|
||||||
info.init();
|
info.init();
|
||||||
update_create_info_from_table(&info, table);
|
update_create_info_from_table(&info, table);
|
||||||
|
|
||||||
if (ib_table->is_temporary()) {
|
|
||||||
info.options|= HA_LEX_CREATE_TMP_TABLE;
|
|
||||||
} else {
|
|
||||||
dict_get_and_save_data_dir_path(ib_table, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* data_file_name = ib_table->data_dir_path;
|
|
||||||
|
|
||||||
if (data_file_name) {
|
|
||||||
info.data_file_name = data_file_name
|
|
||||||
= mem_heap_strdup(heap, data_file_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* temp_name = dict_mem_create_temporary_tablename(
|
|
||||||
heap, ib_table->name.m_name, ib_table->id);
|
|
||||||
const char* name = mem_heap_strdup(heap, ib_table->name.m_name);
|
|
||||||
trx_t* trx = innobase_trx_allocate(m_user_thd);
|
|
||||||
|
|
||||||
trx->will_lock = true;
|
|
||||||
trx->dict_operation = true;
|
|
||||||
row_mysql_lock_data_dictionary(trx);
|
|
||||||
dict_stats_wait_bg_to_stop_using_table(ib_table, trx);
|
|
||||||
|
|
||||||
int err = convert_error_code_to_mysql(
|
|
||||||
innobase_rename_table(trx, ib_table->name.m_name, temp_name,
|
|
||||||
false),
|
|
||||||
ib_table->flags, m_user_thd);
|
|
||||||
if (err) {
|
|
||||||
trx_rollback_for_mysql(trx);
|
|
||||||
row_mysql_unlock_data_dictionary(trx);
|
|
||||||
} else {
|
|
||||||
switch (dict_tf_get_rec_format(ib_table->flags)) {
|
switch (dict_tf_get_rec_format(ib_table->flags)) {
|
||||||
case REC_FORMAT_REDUNDANT:
|
case REC_FORMAT_REDUNDANT:
|
||||||
info.row_type = ROW_TYPE_REDUNDANT;
|
info.row_type = ROW_TYPE_REDUNDANT;
|
||||||
@@ -13506,38 +13503,139 @@ int ha_innobase::truncate()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = create(name, table, &info,
|
const auto stored_lock = m_prebuilt->stored_select_lock_type;
|
||||||
ib_table->is_temporary()
|
trx_t* trx = innobase_trx_allocate(m_user_thd);
|
||||||
|| dict_table_is_file_per_table(ib_table), trx);
|
trx_start_for_ddl(trx);
|
||||||
|
|
||||||
|
if (ib_table->is_temporary()) {
|
||||||
|
info.options|= HA_LEX_CREATE_TMP_TABLE;
|
||||||
|
btr_drop_temporary_table(*ib_table);
|
||||||
|
m_prebuilt->table = nullptr;
|
||||||
|
row_prebuilt_free(m_prebuilt, false);
|
||||||
|
m_prebuilt = nullptr;
|
||||||
|
my_free(m_upd_buf);
|
||||||
|
m_upd_buf = nullptr;
|
||||||
|
m_upd_buf_size = 0;
|
||||||
|
|
||||||
|
row_mysql_lock_data_dictionary(trx);
|
||||||
|
ib_table->release();
|
||||||
|
dict_sys.remove(ib_table, false, true);
|
||||||
|
|
||||||
|
int err = create(ib_table->name.m_name, table, &info, true,
|
||||||
|
trx);
|
||||||
|
if (!err) {
|
||||||
|
err = open(ib_table->name.m_name, 0, 0);
|
||||||
|
m_prebuilt->stored_select_lock_type = stored_lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
trx->free();
|
trx->free();
|
||||||
|
|
||||||
if (!err) {
|
#ifdef BTR_CUR_HASH_ADAPT
|
||||||
/* Reopen the newly created table, and drop the
|
if (UT_LIST_GET_LEN(ib_table->freed_indexes)) {
|
||||||
original table that was renamed to temp_name. */
|
ib_table->vc_templ = nullptr;
|
||||||
|
ib_table->id = 0;
|
||||||
|
DBUG_RETURN(err);
|
||||||
|
}
|
||||||
|
#endif /* BTR_CUR_HASH_ADAPT */
|
||||||
|
|
||||||
|
dict_mem_table_free(ib_table);
|
||||||
|
DBUG_RETURN(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_heap_t* heap = mem_heap_create(1000);
|
||||||
|
|
||||||
|
dict_get_and_save_data_dir_path(ib_table, false);
|
||||||
|
info.data_file_name = ib_table->data_dir_path;
|
||||||
|
const char* temp_name = dict_mem_create_temporary_tablename(
|
||||||
|
heap, ib_table->name.m_name, ib_table->id);
|
||||||
|
const char* name = mem_heap_strdup(heap, ib_table->name.m_name);
|
||||||
|
|
||||||
|
dberr_t error = lock_table_for_trx(ib_table, trx, LOCK_X);
|
||||||
|
const bool fts = error == DB_SUCCESS
|
||||||
|
&& ib_table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS);
|
||||||
|
|
||||||
|
if (fts) {
|
||||||
|
fts_optimize_remove_table(ib_table);
|
||||||
|
purge_sys.stop_FTS();
|
||||||
|
error = fts_lock_tables(trx, *ib_table);
|
||||||
|
}
|
||||||
|
|
||||||
|
row_mysql_lock_data_dictionary(trx);
|
||||||
|
dict_stats_wait_bg_to_stop_using_table(ib_table, trx);
|
||||||
|
/* Wait for purge threads to stop using the table. */
|
||||||
|
for (uint n = 15; ib_table->get_ref_count() > 1; ) {
|
||||||
|
if (!--n) {
|
||||||
|
error = DB_LOCK_WAIT_TIMEOUT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
row_mysql_lock_data_dictionary(trx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error == DB_SUCCESS) {
|
||||||
|
error = innobase_rename_table(trx, ib_table->name.m_name,
|
||||||
|
temp_name, false);
|
||||||
|
|
||||||
|
if (error == DB_SUCCESS) {
|
||||||
|
error = trx->drop_table(*ib_table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = convert_error_code_to_mysql(error, ib_table->flags,
|
||||||
|
m_user_thd);
|
||||||
|
if (err) {
|
||||||
|
trx_rollback_for_mysql(trx);
|
||||||
|
if (fts) {
|
||||||
|
fts_optimize_add_table(ib_table);
|
||||||
|
purge_sys.resume_FTS();
|
||||||
|
}
|
||||||
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
|
} else {
|
||||||
|
const auto update_time = ib_table->update_time;
|
||||||
|
const auto stored_lock = m_prebuilt->stored_select_lock_type;
|
||||||
|
ib_table->release();
|
||||||
|
m_prebuilt->table = nullptr;
|
||||||
|
|
||||||
|
err = create(name, table, &info,
|
||||||
|
dict_table_is_file_per_table(ib_table), trx);
|
||||||
|
if (fts) {
|
||||||
|
purge_sys.resume_FTS();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
reload:
|
||||||
|
m_prebuilt->table = dict_table_open_on_name(
|
||||||
|
name, false, false, DICT_ERR_IGNORE_NONE);
|
||||||
|
} else {
|
||||||
row_prebuilt_t* prebuilt = m_prebuilt;
|
row_prebuilt_t* prebuilt = m_prebuilt;
|
||||||
uchar* upd_buf = m_upd_buf;
|
uchar* upd_buf = m_upd_buf;
|
||||||
ulint upd_buf_size = m_upd_buf_size;
|
ulint upd_buf_size = m_upd_buf_size;
|
||||||
/* Mimic ha_innobase::close(). */
|
/* Mimic ha_innobase::close(). */
|
||||||
m_prebuilt = NULL;
|
m_prebuilt = nullptr;
|
||||||
m_upd_buf = NULL;
|
m_upd_buf = nullptr;
|
||||||
m_upd_buf_size = 0;
|
m_upd_buf_size = 0;
|
||||||
|
|
||||||
err = open(name, 0, 0);
|
err = open(name, 0, 0);
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
m_prebuilt->stored_select_lock_type = stored_lock;
|
m_prebuilt->stored_select_lock_type
|
||||||
|
= stored_lock;
|
||||||
m_prebuilt->table->update_time = update_time;
|
m_prebuilt->table->update_time = update_time;
|
||||||
row_prebuilt_free(prebuilt, FALSE);
|
row_prebuilt_free(prebuilt, false);
|
||||||
delete_table(temp_name, SQLCOM_TRUNCATE);
|
|
||||||
my_free(upd_buf);
|
my_free(upd_buf);
|
||||||
} else {
|
} else {
|
||||||
/* Revert to the old table before truncation. */
|
/* Revert to the old table. */
|
||||||
m_prebuilt = prebuilt;
|
m_prebuilt = prebuilt;
|
||||||
m_upd_buf = upd_buf;
|
m_upd_buf = upd_buf;
|
||||||
m_upd_buf_size = upd_buf_size;
|
m_upd_buf_size = upd_buf_size;
|
||||||
|
goto reload;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trx->free();
|
||||||
|
|
||||||
mem_heap_free(heap);
|
mem_heap_free(heap);
|
||||||
DBUG_RETURN(err);
|
DBUG_RETURN(err);
|
||||||
@@ -13567,54 +13665,46 @@ ha_innobase::rename_table(
|
|||||||
/* We are doing a DDL operation. */
|
/* We are doing a DDL operation. */
|
||||||
trx->will_lock = true;
|
trx->will_lock = true;
|
||||||
trx->dict_operation = true;
|
trx->dict_operation = true;
|
||||||
|
row_mysql_lock_data_dictionary(trx);
|
||||||
|
|
||||||
dberr_t error = innobase_rename_table(trx, from, to, true);
|
dberr_t error = innobase_rename_table(trx, from, to, true);
|
||||||
|
|
||||||
DEBUG_SYNC(thd, "after_innobase_rename_table");
|
DEBUG_SYNC(thd, "after_innobase_rename_table");
|
||||||
|
|
||||||
innobase_commit_low(trx);
|
|
||||||
|
|
||||||
trx->free();
|
|
||||||
|
|
||||||
if (error == DB_SUCCESS) {
|
if (error == DB_SUCCESS) {
|
||||||
char norm_from[MAX_FULL_NAME_LEN];
|
char norm_from[MAX_FULL_NAME_LEN];
|
||||||
char norm_to[MAX_FULL_NAME_LEN];
|
char norm_to[MAX_FULL_NAME_LEN];
|
||||||
char errstr[512];
|
|
||||||
dberr_t ret;
|
|
||||||
|
|
||||||
normalize_table_name(norm_from, from);
|
normalize_table_name(norm_from, from);
|
||||||
normalize_table_name(norm_to, to);
|
normalize_table_name(norm_to, to);
|
||||||
|
|
||||||
ret = dict_stats_rename_table(norm_from, norm_to,
|
error = dict_stats_rename_table(norm_from, norm_to, trx);
|
||||||
errstr, sizeof(errstr));
|
|
||||||
|
|
||||||
if (ret != DB_SUCCESS) {
|
|
||||||
ib::error() << errstr;
|
|
||||||
|
|
||||||
push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
|
|
||||||
ER_LOCK_WAIT_TIMEOUT, errstr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add a special case to handle the Duplicated Key error
|
|
||||||
and return DB_ERROR instead.
|
|
||||||
This is to avoid a possible SIGSEGV error from mysql error
|
|
||||||
handling code. Currently, mysql handles the Duplicated Key
|
|
||||||
error by re-entering the storage layer and getting dup key
|
|
||||||
info by calling get_dup_key(). This operation requires a valid
|
|
||||||
table handle ('row_prebuilt_t' structure) which could no
|
|
||||||
longer be available in the error handling stage. The suggested
|
|
||||||
solution is to report a 'table exists' error message (since
|
|
||||||
the dup key error here is due to an existing table whose name
|
|
||||||
is the one we are trying to rename to) and return the generic
|
|
||||||
error code. */
|
|
||||||
if (error == DB_DUPLICATE_KEY) {
|
if (error == DB_DUPLICATE_KEY) {
|
||||||
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to);
|
/* The duplicate may also occur in
|
||||||
|
mysql.innodb_index_stats. */
|
||||||
|
my_error(ER_DUP_KEY, MYF(0),
|
||||||
|
"mysql.innodb_table_stats");
|
||||||
|
error = DB_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error == DB_SUCCESS) {
|
||||||
|
innobase_commit_low(trx);
|
||||||
|
} else {
|
||||||
|
trx->rollback();
|
||||||
|
}
|
||||||
|
|
||||||
|
row_mysql_unlock_data_dictionary(trx);
|
||||||
|
trx->free();
|
||||||
|
|
||||||
|
if (error == DB_DUPLICATE_KEY) {
|
||||||
|
/* We are not able to deal with handler::get_dup_key()
|
||||||
|
during DDL operations, because the duplicate key would
|
||||||
|
exist in metadata tables, not in the user table. */
|
||||||
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), to);
|
||||||
error = DB_ERROR;
|
error = DB_ERROR;
|
||||||
} else if (error == DB_LOCK_WAIT_TIMEOUT) {
|
} else if (error == DB_LOCK_WAIT_TIMEOUT) {
|
||||||
my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0), to);
|
my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0), to);
|
||||||
|
|
||||||
error = DB_LOCK_WAIT;
|
error = DB_LOCK_WAIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17784,20 +17874,11 @@ innobase_fts_find_ranking(FT_INFO* fts_hdl, uchar*, uint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
static my_bool innodb_background_drop_list_empty = TRUE;
|
|
||||||
static my_bool innodb_log_checkpoint_now = TRUE;
|
static my_bool innodb_log_checkpoint_now = TRUE;
|
||||||
static my_bool innodb_buf_flush_list_now = TRUE;
|
static my_bool innodb_buf_flush_list_now = TRUE;
|
||||||
static uint innodb_merge_threshold_set_all_debug
|
static uint innodb_merge_threshold_set_all_debug
|
||||||
= DICT_INDEX_MERGE_THRESHOLD_DEFAULT;
|
= DICT_INDEX_MERGE_THRESHOLD_DEFAULT;
|
||||||
|
|
||||||
/** Wait for the background drop list to become empty. */
|
|
||||||
static
|
|
||||||
void
|
|
||||||
wait_background_drop_list_empty(THD*, st_mysql_sys_var*, void*, const void*)
|
|
||||||
{
|
|
||||||
row_wait_for_background_drop_list_empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
Force innodb to checkpoint. */
|
Force innodb to checkpoint. */
|
||||||
static
|
static
|
||||||
@@ -18341,12 +18422,6 @@ static MYSQL_SYSVAR_ULONG(io_capacity_max, srv_max_io_capacity,
|
|||||||
SRV_MAX_IO_CAPACITY_LIMIT, 0);
|
SRV_MAX_IO_CAPACITY_LIMIT, 0);
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
static MYSQL_SYSVAR_BOOL(background_drop_list_empty,
|
|
||||||
innodb_background_drop_list_empty,
|
|
||||||
PLUGIN_VAR_OPCMDARG,
|
|
||||||
"Wait for the background drop list to become empty",
|
|
||||||
NULL, wait_background_drop_list_empty, FALSE);
|
|
||||||
|
|
||||||
static MYSQL_SYSVAR_BOOL(log_checkpoint_now, innodb_log_checkpoint_now,
|
static MYSQL_SYSVAR_BOOL(log_checkpoint_now, innodb_log_checkpoint_now,
|
||||||
PLUGIN_VAR_OPCMDARG,
|
PLUGIN_VAR_OPCMDARG,
|
||||||
"Force checkpoint now",
|
"Force checkpoint now",
|
||||||
@@ -19382,7 +19457,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
|||||||
MYSQL_SYSVAR(purge_threads),
|
MYSQL_SYSVAR(purge_threads),
|
||||||
MYSQL_SYSVAR(purge_batch_size),
|
MYSQL_SYSVAR(purge_batch_size),
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
MYSQL_SYSVAR(background_drop_list_empty),
|
|
||||||
MYSQL_SYSVAR(log_checkpoint_now),
|
MYSQL_SYSVAR(log_checkpoint_now),
|
||||||
MYSQL_SYSVAR(buf_flush_list_now),
|
MYSQL_SYSVAR(buf_flush_list_now),
|
||||||
MYSQL_SYSVAR(merge_threshold_set_all_debug),
|
MYSQL_SYSVAR(merge_threshold_set_all_debug),
|
||||||
|
@@ -204,8 +204,6 @@ public:
|
|||||||
TABLE* form,
|
TABLE* form,
|
||||||
HA_CREATE_INFO* create_info) override;
|
HA_CREATE_INFO* create_info) override;
|
||||||
|
|
||||||
inline int delete_table(const char* name, enum_sql_command sqlcom);
|
|
||||||
|
|
||||||
int truncate() override;
|
int truncate() override;
|
||||||
|
|
||||||
int delete_table(const char *name) override;
|
int delete_table(const char *name) override;
|
||||||
@@ -708,26 +706,9 @@ public:
|
|||||||
const char* table_name() const
|
const char* table_name() const
|
||||||
{ return(m_table_name); }
|
{ return(m_table_name); }
|
||||||
|
|
||||||
/** @return whether the table needs to be dropped on rollback */
|
|
||||||
bool drop_before_rollback() const { return m_drop_before_rollback; }
|
|
||||||
|
|
||||||
THD* thd() const
|
THD* thd() const
|
||||||
{ return(m_thd); }
|
{ return(m_thd); }
|
||||||
|
|
||||||
/** Normalizes a table name string.
|
|
||||||
A normalized name consists of the database name catenated to '/' and
|
|
||||||
table name. An example: test/mytable. On Windows normalization puts
|
|
||||||
both the database name and the table name always to lower case if
|
|
||||||
"set_lower_case" is set to true.
|
|
||||||
@param[in,out] norm_name Buffer to return the normalized name in.
|
|
||||||
@param[in] name Table name string.
|
|
||||||
@param[in] set_lower_case True if we want to set name to lower
|
|
||||||
case. */
|
|
||||||
static void normalize_table_name_low(
|
|
||||||
char* norm_name,
|
|
||||||
const char* name,
|
|
||||||
ibool set_lower_case);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Parses the table name into normal name and either temp path or
|
/** Parses the table name into normal name and either temp path or
|
||||||
remote path if needed.*/
|
remote path if needed.*/
|
||||||
@@ -757,8 +738,6 @@ private:
|
|||||||
char* m_table_name;
|
char* m_table_name;
|
||||||
/** Table */
|
/** Table */
|
||||||
dict_table_t* m_table;
|
dict_table_t* m_table;
|
||||||
/** Whether the table needs to be dropped before rollback */
|
|
||||||
bool m_drop_before_rollback;
|
|
||||||
|
|
||||||
/** Remote path (DATA DIRECTORY) or zero length-string */
|
/** Remote path (DATA DIRECTORY) or zero length-string */
|
||||||
char* m_remote_path;
|
char* m_remote_path;
|
||||||
@@ -861,15 +840,6 @@ innodb_base_col_setup_for_stored(
|
|||||||
/** whether this is a stored generated column */
|
/** whether this is a stored generated column */
|
||||||
#define innobase_is_s_fld(field) ((field)->vcol_info && (field)->stored_in_db())
|
#define innobase_is_s_fld(field) ((field)->vcol_info && (field)->stored_in_db())
|
||||||
|
|
||||||
/** Always normalize table name to lower case on Windows */
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define normalize_table_name(norm_name, name) \
|
|
||||||
create_table_info_t::normalize_table_name_low(norm_name, name, TRUE)
|
|
||||||
#else
|
|
||||||
#define normalize_table_name(norm_name, name) \
|
|
||||||
create_table_info_t::normalize_table_name_low(norm_name, name, FALSE)
|
|
||||||
#endif /* _WIN32 */
|
|
||||||
|
|
||||||
/** Converts a search mode flag understood by MySQL to a flag understood
|
/** Converts a search mode flag understood by MySQL to a flag understood
|
||||||
by InnoDB.
|
by InnoDB.
|
||||||
@param[in] find_flag MySQL search mode flag.
|
@param[in] find_flag MySQL search mode flag.
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -337,9 +337,9 @@ btr_create(
|
|||||||
void btr_free_if_exists(fil_space_t *space, uint32_t page,
|
void btr_free_if_exists(fil_space_t *space, uint32_t page,
|
||||||
index_id_t index_id, mtr_t *mtr);
|
index_id_t index_id, mtr_t *mtr);
|
||||||
|
|
||||||
/** Free an index tree in a temporary tablespace.
|
/** Drop a temporary table
|
||||||
@param[in] page_id root page id */
|
@param table temporary table */
|
||||||
void btr_free(const page_id_t page_id);
|
void btr_drop_temporary_table(const dict_table_t &table);
|
||||||
|
|
||||||
/** Read the last used AUTO_INCREMENT value from PAGE_ROOT_AUTO_INC.
|
/** Read the last used AUTO_INCREMENT value from PAGE_ROOT_AUTO_INC.
|
||||||
@param[in,out] index clustered index
|
@param[in,out] index clustered index
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@@ -128,7 +128,7 @@ void btr_search_update_hash_on_insert(btr_cur_t *cursor,
|
|||||||
/** Updates the page hash index when a single record is deleted from a page.
|
/** Updates the page hash index when a single record is deleted from a page.
|
||||||
@param[in] cursor cursor which was positioned on the record to delete
|
@param[in] cursor cursor which was positioned on the record to delete
|
||||||
using btr_cur_search_, the record is not yet deleted.*/
|
using btr_cur_search_, the record is not yet deleted.*/
|
||||||
void btr_search_update_hash_on_delete(btr_cur_t* cursor);
|
void btr_search_update_hash_on_delete(btr_cur_t *cursor);
|
||||||
|
|
||||||
/** Validates the search system.
|
/** Validates the search system.
|
||||||
@return true if ok */
|
@return true if ok */
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2018, 2020, MariaDB Corporation.
|
Copyright (c) 2018, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@@ -47,8 +47,7 @@ static inline btr_search_t* btr_search_info_create(mem_heap_t* heap)
|
|||||||
/** Updates the search info.
|
/** Updates the search info.
|
||||||
@param[in,out] info search info
|
@param[in,out] info search info
|
||||||
@param[in,out] cursor cursor which was just positioned */
|
@param[in,out] cursor cursor which was just positioned */
|
||||||
void
|
void btr_search_info_update_slow(btr_search_t *info, btr_cur_t *cursor);
|
||||||
btr_search_info_update_slow(btr_search_t* info, btr_cur_t* cursor);
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Updates the search info. */
|
Updates the search info. */
|
||||||
@@ -59,7 +58,10 @@ btr_search_info_update(
|
|||||||
dict_index_t* index, /*!< in: index of the cursor */
|
dict_index_t* index, /*!< in: index of the cursor */
|
||||||
btr_cur_t* cursor) /*!< in: cursor which was just positioned */
|
btr_cur_t* cursor) /*!< in: cursor which was just positioned */
|
||||||
{
|
{
|
||||||
if (dict_index_is_spatial(index) || !btr_search_enabled) {
|
ut_ad(!index->is_spatial());
|
||||||
|
ut_ad(!index->table->is_temporary());
|
||||||
|
|
||||||
|
if (!btr_search_enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -118,8 +118,6 @@ enum dberr_t {
|
|||||||
DB_READ_ONLY, /*!< Update operation attempted in
|
DB_READ_ONLY, /*!< Update operation attempted in
|
||||||
a read-only transaction */
|
a read-only transaction */
|
||||||
DB_FTS_INVALID_DOCID, /* FTS Doc ID cannot be zero */
|
DB_FTS_INVALID_DOCID, /* FTS Doc ID cannot be zero */
|
||||||
DB_TABLE_IN_FK_CHECK, /* table is being used in foreign
|
|
||||||
key check */
|
|
||||||
DB_ONLINE_LOG_TOO_BIG, /*!< Modification log grew too big
|
DB_ONLINE_LOG_TOO_BIG, /*!< Modification log grew too big
|
||||||
during online index creation */
|
during online index creation */
|
||||||
|
|
||||||
|
@@ -1000,15 +1000,6 @@ struct dict_index_t {
|
|||||||
representation we add more columns */
|
representation we add more columns */
|
||||||
unsigned nulls_equal:1;
|
unsigned nulls_equal:1;
|
||||||
/*!< if true, SQL NULL == SQL NULL */
|
/*!< if true, SQL NULL == SQL NULL */
|
||||||
#ifdef BTR_CUR_HASH_ADAPT
|
|
||||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
|
||||||
unsigned disable_ahi:1;
|
|
||||||
/*!< whether to disable the
|
|
||||||
adaptive hash index.
|
|
||||||
Maybe this could be disabled for
|
|
||||||
temporary tables? */
|
|
||||||
#endif
|
|
||||||
#endif /* BTR_CUR_HASH_ADAPT */
|
|
||||||
unsigned n_uniq:10;/*!< number of fields from the beginning
|
unsigned n_uniq:10;/*!< number of fields from the beginning
|
||||||
which are enough to determine an index
|
which are enough to determine an index
|
||||||
entry uniquely */
|
entry uniquely */
|
||||||
@@ -1958,23 +1949,6 @@ struct dict_table_t {
|
|||||||
return versioned() && cols[vers_start].mtype == DATA_INT;
|
return versioned() && cols[vers_start].mtype == DATA_INT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void inc_fk_checks()
|
|
||||||
{
|
|
||||||
#ifdef UNIV_DEBUG
|
|
||||||
int32_t fk_checks=
|
|
||||||
#endif
|
|
||||||
n_foreign_key_checks_running++;
|
|
||||||
ut_ad(fk_checks >= 0);
|
|
||||||
}
|
|
||||||
void dec_fk_checks()
|
|
||||||
{
|
|
||||||
#ifdef UNIV_DEBUG
|
|
||||||
int32_t fk_checks=
|
|
||||||
#endif
|
|
||||||
n_foreign_key_checks_running--;
|
|
||||||
ut_ad(fk_checks > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** For overflow fields returns potential max length stored inline */
|
/** For overflow fields returns potential max length stored inline */
|
||||||
inline size_t get_overflow_field_local_len() const;
|
inline size_t get_overflow_field_local_len() const;
|
||||||
|
|
||||||
@@ -2049,7 +2023,7 @@ public:
|
|||||||
table_id_t id;
|
table_id_t id;
|
||||||
/** dict_sys.id_hash chain node */
|
/** dict_sys.id_hash chain node */
|
||||||
dict_table_t* id_hash;
|
dict_table_t* id_hash;
|
||||||
/** Table name. */
|
/** Table name in name_hash */
|
||||||
table_name_t name;
|
table_name_t name;
|
||||||
/** dict_sys.name_hash chain node */
|
/** dict_sys.name_hash chain node */
|
||||||
dict_table_t* name_hash;
|
dict_table_t* name_hash;
|
||||||
@@ -2100,12 +2074,6 @@ public:
|
|||||||
/** TRUE if the table object has been added to the dictionary cache. */
|
/** TRUE if the table object has been added to the dictionary cache. */
|
||||||
unsigned cached:1;
|
unsigned cached:1;
|
||||||
|
|
||||||
/** TRUE if the table is to be dropped, but not yet actually dropped
|
|
||||||
(could in the background drop list). It is turned on at the beginning
|
|
||||||
of row_drop_table_for_mysql() and turned off just before we start to
|
|
||||||
update system tables for the drop. It is protected by dict_sys.latch. */
|
|
||||||
unsigned to_be_dropped:1;
|
|
||||||
|
|
||||||
/** Number of non-virtual columns defined so far. */
|
/** Number of non-virtual columns defined so far. */
|
||||||
unsigned n_def:10;
|
unsigned n_def:10;
|
||||||
|
|
||||||
@@ -2202,11 +2170,6 @@ public:
|
|||||||
loading child table into memory along with its parent table. */
|
loading child table into memory along with its parent table. */
|
||||||
byte fk_max_recusive_level;
|
byte fk_max_recusive_level;
|
||||||
|
|
||||||
/** Count of how many foreign key check operations are currently being
|
|
||||||
performed on the table. We cannot drop the table while there are
|
|
||||||
foreign key checks running on it. */
|
|
||||||
Atomic_counter<int32_t> n_foreign_key_checks_running;
|
|
||||||
|
|
||||||
/** DDL transaction that last touched the table definition, or 0 if
|
/** DDL transaction that last touched the table definition, or 0 if
|
||||||
no history is available. This includes possible changes in
|
no history is available. This includes possible changes in
|
||||||
ha_innobase::prepare_inplace_alter_table() and
|
ha_innobase::prepare_inplace_alter_table() and
|
||||||
@@ -2219,6 +2182,11 @@ public:
|
|||||||
an empty leaf page), and an ahi_latch (if btr_search_enabled). */
|
an empty leaf page), and an ahi_latch (if btr_search_enabled). */
|
||||||
Atomic_relaxed<trx_id_t> bulk_trx_id;
|
Atomic_relaxed<trx_id_t> bulk_trx_id;
|
||||||
|
|
||||||
|
/** Original table name, for MDL acquisition in purge. Normally,
|
||||||
|
this points to the same as name. When is_temporary_name(name.m_name) holds,
|
||||||
|
this should be a copy of the original table name, allocated from heap. */
|
||||||
|
table_name_t mdl_name;
|
||||||
|
|
||||||
/*!< set of foreign key constraints in the table; these refer to
|
/*!< set of foreign key constraints in the table; these refer to
|
||||||
columns in other tables */
|
columns in other tables */
|
||||||
dict_foreign_set foreign_set;
|
dict_foreign_set foreign_set;
|
||||||
@@ -2439,9 +2407,6 @@ public:
|
|||||||
static dict_table_t *create(const span<const char> &name, fil_space_t *space,
|
static dict_table_t *create(const span<const char> &name, fil_space_t *space,
|
||||||
ulint n_cols, ulint n_v_cols, ulint flags,
|
ulint n_cols, ulint n_v_cols, ulint flags,
|
||||||
ulint flags2);
|
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,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, MariaDB Corporation.
|
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@@ -64,10 +64,5 @@ dict_mem_fill_index_struct(
|
|||||||
/* The '1 +' above prevents allocation
|
/* The '1 +' above prevents allocation
|
||||||
of an empty mem block */
|
of an empty mem block */
|
||||||
index->nulls_equal = false;
|
index->nulls_equal = false;
|
||||||
#ifdef BTR_CUR_HASH_ADAPT
|
|
||||||
#ifdef MYSQL_INDEX_DISABLE_AHI
|
|
||||||
index->disable_ahi = false;
|
|
||||||
#endif
|
|
||||||
#endif /* BTR_CUR_HASH_ADAPT */
|
|
||||||
ut_d(index->magic_n = DICT_INDEX_MAGIC_N);
|
ut_d(index->magic_n = DICT_INDEX_MAGIC_N);
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2009, 2018, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2009, 2018, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2017, 2020, MariaDB Corporation.
|
Copyright (c) 2017, 2021, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify it under
|
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
|
the terms of the GNU General Public License as published by the Free Software
|
||||||
@@ -30,9 +30,6 @@ Created Jan 06, 2010 Vasil Dimov
|
|||||||
#include "dict0types.h"
|
#include "dict0types.h"
|
||||||
#include "trx0types.h"
|
#include "trx0types.h"
|
||||||
|
|
||||||
#define TABLE_STATS_NAME "mysql/innodb_table_stats"
|
|
||||||
#define INDEX_STATS_NAME "mysql/innodb_index_stats"
|
|
||||||
|
|
||||||
enum dict_stats_upd_option_t {
|
enum dict_stats_upd_option_t {
|
||||||
DICT_STATS_RECALC_PERSISTENT,/* (re) calculate the
|
DICT_STATS_RECALC_PERSISTENT,/* (re) calculate the
|
||||||
statistics using a precise and slow
|
statistics using a precise and slow
|
||||||
@@ -140,40 +137,31 @@ dict_stats_update(
|
|||||||
the stats or to fetch them from
|
the stats or to fetch them from
|
||||||
the persistent storage */
|
the persistent storage */
|
||||||
|
|
||||||
/** Remove the information for a particular index's stats from the persistent
|
/** Execute DELETE FROM mysql.innodb_table_stats
|
||||||
storage if it exists and if there is data stored for this index.
|
@param database_name database name
|
||||||
This function creates its own trx and commits it.
|
@param table_name table name
|
||||||
|
@param trx transaction (nullptr=start and commit a new one)
|
||||||
We must modify system tables in a separate transaction in order to
|
|
||||||
adhere to the InnoDB design constraint that dict_sys.latch prevents
|
|
||||||
lock waits on system tables. If we modified system and user tables in
|
|
||||||
the same transaction, we should exclusively hold dict_sys.latch until
|
|
||||||
the transaction is committed, and effectively block other transactions
|
|
||||||
that will attempt to open any InnoDB tables. Because we have no
|
|
||||||
guarantee that user transactions will be committed fast, we cannot
|
|
||||||
afford to keep the system tables locked in a user transaction.
|
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
dberr_t
|
dberr_t dict_stats_delete_from_table_stats(const char *database_name,
|
||||||
dict_stats_drop_index(
|
const char *table_name,
|
||||||
/*==================*/
|
trx_t *trx= nullptr);
|
||||||
const char* tname, /*!< in: table name */
|
/** Execute DELETE FROM mysql.innodb_index_stats
|
||||||
const char* iname, /*!< in: index name */
|
@param database_name database name
|
||||||
char* errstr, /*!< out: error message if != DB_SUCCESS
|
@param table_name table name
|
||||||
is returned */
|
@param trx transaction (nullptr=start and commit a new one)
|
||||||
ulint errstr_sz);/*!< in: size of the errstr buffer */
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
|
||||||
Removes the statistics for a table and all of its indexes from the
|
|
||||||
persistent storage if it exists and if there is data stored for the table.
|
|
||||||
This function creates its own transaction and commits it.
|
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
dberr_t
|
dberr_t dict_stats_delete_from_index_stats(const char *database_name,
|
||||||
dict_stats_drop_table(
|
const char *table_name,
|
||||||
/*==================*/
|
trx_t *trx= nullptr);
|
||||||
const char* table_name, /*!< in: table name */
|
/** Execute DELETE FROM mysql.innodb_index_stats
|
||||||
char* errstr, /*!< out: error message
|
@param database_name database name
|
||||||
if != DB_SUCCESS is returned */
|
@param table_name table name
|
||||||
ulint errstr_sz); /*!< in: size of errstr buffer */
|
@param index_name name of the index
|
||||||
|
@param trx transaction (nullptr=start and commit a new one)
|
||||||
|
@return DB_SUCCESS or error code */
|
||||||
|
dberr_t dict_stats_delete_from_index_stats(const char *database_name,
|
||||||
|
const char *table_name,
|
||||||
|
const char *index_name, trx_t *trx);
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Fetches or calculates new estimates for index statistics. */
|
Fetches or calculates new estimates for index statistics. */
|
||||||
@@ -183,31 +171,29 @@ dict_stats_update_for_index(
|
|||||||
dict_index_t* index) /*!< in/out: index */
|
dict_index_t* index) /*!< in/out: index */
|
||||||
MY_ATTRIBUTE((nonnull));
|
MY_ATTRIBUTE((nonnull));
|
||||||
|
|
||||||
/*********************************************************************//**
|
/** Rename a table in InnoDB persistent stats storage.
|
||||||
Renames a table in InnoDB persistent stats storage.
|
@param old_name old table name
|
||||||
This function creates its own transaction and commits it.
|
@param new_name new table name
|
||||||
|
@param trx transaction
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
dberr_t
|
dberr_t dict_stats_rename_table(const char *old_name, const char *new_name,
|
||||||
dict_stats_rename_table(
|
trx_t *trx);
|
||||||
/*====================*/
|
/** Rename an index in InnoDB persistent statistics.
|
||||||
const char* old_name, /*!< in: old table name */
|
@param db database name
|
||||||
const char* new_name, /*!< in: new table name */
|
@param table table name
|
||||||
char* errstr, /*!< out: error string if != DB_SUCCESS
|
@param old_name old table name
|
||||||
is returned */
|
@param new_name new table name
|
||||||
size_t errstr_sz); /*!< in: errstr size */
|
@param trx transaction
|
||||||
/*********************************************************************//**
|
@return DB_SUCCESS or error code */
|
||||||
Renames an index in InnoDB persistent stats storage.
|
dberr_t dict_stats_rename_index(const char *db, const char *table,
|
||||||
This function creates its own transaction and commits it.
|
const char *old_name, const char *new_name,
|
||||||
@return DB_SUCCESS or error code. DB_STATS_DO_NOT_EXIST will be returned
|
trx_t *trx);
|
||||||
if the persistent stats do not exist. */
|
|
||||||
dberr_t
|
/** Delete all persistent statistics for a database.
|
||||||
dict_stats_rename_index(
|
@param db database name
|
||||||
/*====================*/
|
@param trx transaction
|
||||||
const dict_table_t* table, /*!< in: table whose index
|
@return DB_SUCCESS or error code */
|
||||||
is renamed */
|
dberr_t dict_stats_delete(const char *db, trx_t *trx);
|
||||||
const char* old_index_name, /*!< in: old index name */
|
|
||||||
const char* new_index_name) /*!< in: new index name */
|
|
||||||
__attribute__((warn_unused_result));
|
|
||||||
|
|
||||||
/** Save an individual index's statistic into the persistent statistics
|
/** Save an individual index's statistic into the persistent statistics
|
||||||
storage.
|
storage.
|
||||||
|
@@ -168,4 +168,7 @@ enum spatial_status_t {
|
|||||||
SPATIAL_ONLY = 3
|
SPATIAL_ONLY = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TABLE_STATS_NAME "mysql/innodb_table_stats"
|
||||||
|
#define INDEX_STATS_NAME "mysql/innodb_index_stats"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -518,8 +518,12 @@ public:
|
|||||||
/** Close each file. Only invoked on fil_system.temp_space. */
|
/** Close each file. Only invoked on fil_system.temp_space. */
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
/** Note that operations on the tablespace must stop or can resume */
|
/** Note that operations on the tablespace must stop.
|
||||||
inline void set_stopping(bool stopping);
|
@return whether the operations were already stopped */
|
||||||
|
inline bool set_stopping();
|
||||||
|
|
||||||
|
/** Note that operations on the tablespace can resume after truncation */
|
||||||
|
inline void clear_stopping();
|
||||||
|
|
||||||
/** Look up the tablespace and wait for pending operations to cease
|
/** Look up the tablespace and wait for pending operations to cease
|
||||||
@param id tablespace identifier
|
@param id tablespace identifier
|
||||||
@@ -1508,12 +1512,19 @@ inline void fil_space_t::reacquire()
|
|||||||
#endif /* SAFE_MUTEX */
|
#endif /* SAFE_MUTEX */
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Note that operations on the tablespace must stop or can resume */
|
/** Note that operations on the tablespace must stop.
|
||||||
inline void fil_space_t::set_stopping(bool stopping)
|
@return whether the operations were already stopped */
|
||||||
|
inline bool fil_space_t::set_stopping()
|
||||||
{
|
{
|
||||||
mysql_mutex_assert_owner(&fil_system.mutex);
|
mysql_mutex_assert_owner(&fil_system.mutex);
|
||||||
ut_d(auto n=) n_pending.fetch_xor(STOPPING, std::memory_order_relaxed);
|
return n_pending.fetch_or(STOPPING, std::memory_order_relaxed) & STOPPING;
|
||||||
ut_ad(!(n & STOPPING) == stopping);
|
}
|
||||||
|
|
||||||
|
inline void fil_space_t::clear_stopping()
|
||||||
|
{
|
||||||
|
mysql_mutex_assert_owner(&fil_system.mutex);
|
||||||
|
ut_d(auto n=) n_pending.fetch_and(~STOPPING, std::memory_order_relaxed);
|
||||||
|
ut_ad(n & STOPPING);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Flush pending writes from the file system cache to the file. */
|
/** Flush pending writes from the file system cache to the file. */
|
||||||
@@ -1595,13 +1606,12 @@ fil_write_flushed_lsn(
|
|||||||
lsn_t lsn)
|
lsn_t lsn)
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
|
||||||
|
MY_ATTRIBUTE((warn_unused_result))
|
||||||
/** Delete a tablespace and associated .ibd file.
|
/** Delete a tablespace and associated .ibd file.
|
||||||
@param[in] id tablespace identifier
|
@param id tablespace identifier
|
||||||
@param[in] if_exists whether to ignore missing tablespace
|
@return detached file handle (to be closed by the caller)
|
||||||
@param[out] detached deatched file handle (if closing is not wanted)
|
@return OS_FILE_CLOSED if no file existed */
|
||||||
@return DB_SUCCESS or error */
|
pfs_os_file_t fil_delete_tablespace(ulint id);
|
||||||
dberr_t fil_delete_tablespace(ulint id, bool if_exists= false,
|
|
||||||
pfs_os_file_t *detached= nullptr);
|
|
||||||
|
|
||||||
/** Close a single-table tablespace on failed IMPORT TABLESPACE.
|
/** Close a single-table tablespace on failed IMPORT TABLESPACE.
|
||||||
The tablespace must be cached in the memory cache.
|
The tablespace must be cached in the memory cache.
|
||||||
|
@@ -500,17 +500,29 @@ fts_add_doc_id_column(
|
|||||||
dict_table_t* table, /*!< in/out: Table with FTS index */
|
dict_table_t* table, /*!< in/out: Table with FTS index */
|
||||||
mem_heap_t* heap); /*!< in: temporary memory heap, or NULL */
|
mem_heap_t* heap); /*!< in: temporary memory heap, or NULL */
|
||||||
|
|
||||||
/*********************************************************************//**
|
/** Lock the internal FTS_ tables for an index, before fts_drop_index_tables().
|
||||||
Drops the ancillary tables needed for supporting an FTS index on the
|
@param trx transaction
|
||||||
given table. row_mysql_lock_data_dictionary must have been called before
|
@param index fulltext index */
|
||||||
this.
|
dberr_t fts_lock_index_tables(trx_t *trx, const dict_index_t &index);
|
||||||
|
|
||||||
|
/** Lock the internal common FTS_ tables, before fts_drop_common_tables().
|
||||||
|
@param trx transaction
|
||||||
|
@param table table containing FULLTEXT INDEX
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
dberr_t
|
dberr_t fts_lock_common_tables(trx_t *trx, const dict_table_t &table);
|
||||||
fts_drop_tables(
|
|
||||||
/*============*/
|
/** Lock the internal FTS_ tables for table, before fts_drop_tables().
|
||||||
trx_t* trx, /*!< in: transaction */
|
@param trx transaction
|
||||||
dict_table_t* table); /*!< in: table has the FTS
|
@param table table containing FULLTEXT INDEX
|
||||||
index */
|
@return DB_SUCCESS or error code */
|
||||||
|
dberr_t fts_lock_tables(trx_t *trx, const dict_table_t &table);
|
||||||
|
|
||||||
|
/** Drop the internal FTS_ tables for table.
|
||||||
|
@param trx transaction
|
||||||
|
@param table table containing FULLTEXT INDEX
|
||||||
|
@return DB_SUCCESS or error code */
|
||||||
|
dberr_t fts_drop_tables(trx_t *trx, const dict_table_t &table);
|
||||||
|
|
||||||
/******************************************************************//**
|
/******************************************************************//**
|
||||||
The given transaction is about to be committed; do whatever is necessary
|
The given transaction is about to be committed; do whatever is necessary
|
||||||
from the FTS system's POV.
|
from the FTS system's POV.
|
||||||
@@ -643,11 +655,7 @@ fts_optimize_init(void);
|
|||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
Drops index ancillary tables for a FTS index
|
Drops index ancillary tables for a FTS index
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
dberr_t
|
dberr_t fts_drop_index_tables(trx_t *trx, const dict_index_t &index)
|
||||||
fts_drop_index_tables(
|
|
||||||
/*==================*/
|
|
||||||
trx_t* trx, /*!< in: transaction */
|
|
||||||
dict_index_t* index) /*!< in: Index to drop */
|
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
|
|
||||||
/** Add the table to add to the OPTIMIZER's list.
|
/** Add the table to add to the OPTIMIZER's list.
|
||||||
|
@@ -453,7 +453,7 @@ normalize_table_name_c_low(
|
|||||||
char* norm_name, /*!< out: normalized name as a
|
char* norm_name, /*!< out: normalized name as a
|
||||||
null-terminated string */
|
null-terminated string */
|
||||||
const char* name, /*!< in: table name string */
|
const char* name, /*!< in: table name string */
|
||||||
ibool set_lower_case); /*!< in: TRUE if we want to set
|
bool set_lower_case); /*!< in: true if we want to set
|
||||||
name to lower case */
|
name to lower case */
|
||||||
|
|
||||||
/** Create a MYSQL_THD for a background thread and mark it as such.
|
/** Create a MYSQL_THD for a background thread and mark it as such.
|
||||||
|
@@ -37,11 +37,6 @@ Created 9/17/2000 Heikki Tuuri
|
|||||||
#include "fts0fts.h"
|
#include "fts0fts.h"
|
||||||
#include "gis0type.h"
|
#include "gis0type.h"
|
||||||
|
|
||||||
#include "sql_list.h"
|
|
||||||
#include "sql_cmd.h"
|
|
||||||
|
|
||||||
extern ibool row_rollback_on_timeout;
|
|
||||||
|
|
||||||
struct row_prebuilt_t;
|
struct row_prebuilt_t;
|
||||||
class ha_innobase;
|
class ha_innobase;
|
||||||
|
|
||||||
@@ -378,17 +373,6 @@ row_create_index_for_mysql(
|
|||||||
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 task calls this regularly to drop tables which
|
|
||||||
we must drop in background after queries to them have ended.
|
|
||||||
@return how many tables dropped + remaining tables in list */
|
|
||||||
ulint row_drop_tables_for_mysql_in_background();
|
|
||||||
|
|
||||||
/** @return number of tables in the background drop list */
|
|
||||||
ulint row_get_background_drop_list_len_low();
|
|
||||||
|
|
||||||
/** Drop garbage tables during recovery. */
|
|
||||||
void row_mysql_drop_garbage_tables();
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Sets an exclusive lock on a table.
|
Sets an exclusive lock on a table.
|
||||||
@return error code or DB_SUCCESS */
|
@return error code or DB_SUCCESS */
|
||||||
@@ -401,36 +385,12 @@ row_mysql_lock_table(
|
|||||||
const char* op_info) /*!< in: string for trx->op_info */
|
const char* op_info) /*!< in: string for trx->op_info */
|
||||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||||
|
|
||||||
/** Drop a table.
|
|
||||||
If the data dictionary was not already locked by the transaction,
|
|
||||||
the transaction will be committed. Otherwise, the data dictionary
|
|
||||||
will remain locked.
|
|
||||||
@param[in] name Table name
|
|
||||||
@param[in,out] trx Transaction handle
|
|
||||||
@param[in] sqlcom type of SQL operation
|
|
||||||
@param[in] create_failed true=create table failed
|
|
||||||
because e.g. foreign key column
|
|
||||||
@param[in] nonatomic Whether it is permitted to release
|
|
||||||
and reacquire dict_sys.latch
|
|
||||||
@return error code */
|
|
||||||
dberr_t
|
|
||||||
row_drop_table_for_mysql(
|
|
||||||
const char* name,
|
|
||||||
trx_t* trx,
|
|
||||||
enum_sql_command sqlcom,
|
|
||||||
bool create_failed = false,
|
|
||||||
bool nonatomic = true);
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Discards the tablespace of a table which stored in an .ibd file. Discarding
|
Discards the tablespace of a table which stored in an .ibd file. Discarding
|
||||||
means that this function deletes the .ibd file and assigns a new table id for
|
means that this function deletes the .ibd file and assigns a new table id for
|
||||||
the table. Also the file_unreadable flag is set.
|
the table. Also the file_unreadable flag is set.
|
||||||
@return error code or DB_SUCCESS */
|
@return error code or DB_SUCCESS */
|
||||||
dberr_t
|
dberr_t row_discard_tablespace_for_mysql(dict_table_t *table, trx_t *trx)
|
||||||
row_discard_tablespace_for_mysql(
|
|
||||||
/*=============================*/
|
|
||||||
const char* name, /*!< in: table name */
|
|
||||||
trx_t* trx) /*!< in: transaction handle */
|
|
||||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||||
/*****************************************************************//**
|
/*****************************************************************//**
|
||||||
Imports a tablespace. The space id in the .ibd file must match the space id
|
Imports a tablespace. The space id in the .ibd file must match the space id
|
||||||
@@ -452,7 +412,6 @@ row_rename_table_for_mysql(
|
|||||||
const char* old_name, /*!< in: old table name */
|
const char* old_name, /*!< in: old table name */
|
||||||
const char* new_name, /*!< in: new table name */
|
const char* new_name, /*!< in: new table name */
|
||||||
trx_t* trx, /*!< in/out: transaction */
|
trx_t* trx, /*!< in/out: transaction */
|
||||||
bool commit, /*!< in: whether to commit trx */
|
|
||||||
bool use_fk) /*!< in: whether to parse and enforce
|
bool use_fk) /*!< in: whether to parse and enforce
|
||||||
FOREIGN KEY constraints */
|
FOREIGN KEY constraints */
|
||||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||||
@@ -472,17 +431,6 @@ row_scan_index_for_mysql(
|
|||||||
ulint* n_rows) /*!< out: number of entries
|
ulint* n_rows) /*!< out: number of entries
|
||||||
seen in the consistent read */
|
seen in the consistent read */
|
||||||
MY_ATTRIBUTE((warn_unused_result));
|
MY_ATTRIBUTE((warn_unused_result));
|
||||||
/*********************************************************************//**
|
|
||||||
Initialize this module */
|
|
||||||
void
|
|
||||||
row_mysql_init(void);
|
|
||||||
/*================*/
|
|
||||||
|
|
||||||
/*********************************************************************//**
|
|
||||||
Close this module */
|
|
||||||
void
|
|
||||||
row_mysql_close(void);
|
|
||||||
/*=================*/
|
|
||||||
|
|
||||||
/* A struct describing a place for an individual column in the MySQL
|
/* A struct describing a place for an individual column in the MySQL
|
||||||
row format which is presented to the table handler in ha_innobase.
|
row format which is presented to the table handler in ha_innobase.
|
||||||
@@ -946,10 +894,4 @@ innobase_rename_vc_templ(
|
|||||||
#define ROW_READ_TRY_SEMI_CONSISTENT 1
|
#define ROW_READ_TRY_SEMI_CONSISTENT 1
|
||||||
#define ROW_READ_DID_SEMI_CONSISTENT 2
|
#define ROW_READ_DID_SEMI_CONSISTENT 2
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
|
||||||
/** Wait for the background drop list to become empty. */
|
|
||||||
void
|
|
||||||
row_wait_for_background_drop_list_empty();
|
|
||||||
#endif /* UNIV_DEBUG */
|
|
||||||
|
|
||||||
#endif /* row0mysql.h */
|
#endif /* row0mysql.h */
|
||||||
|
@@ -377,7 +377,6 @@ enum monitor_id_t {
|
|||||||
MONITOR_OVLD_SERVER_ACTIVITY,
|
MONITOR_OVLD_SERVER_ACTIVITY,
|
||||||
MONITOR_MASTER_ACTIVE_LOOPS,
|
MONITOR_MASTER_ACTIVE_LOOPS,
|
||||||
MONITOR_MASTER_IDLE_LOOPS,
|
MONITOR_MASTER_IDLE_LOOPS,
|
||||||
MONITOR_SRV_BACKGROUND_DROP_TABLE_MICROSECOND,
|
|
||||||
MONITOR_SRV_LOG_FLUSH_MICROSECOND,
|
MONITOR_SRV_LOG_FLUSH_MICROSECOND,
|
||||||
MONITOR_SRV_DICT_LRU_MICROSECOND,
|
MONITOR_SRV_DICT_LRU_MICROSECOND,
|
||||||
MONITOR_SRV_DICT_LRU_EVICT_COUNT_ACTIVE,
|
MONITOR_SRV_DICT_LRU_EVICT_COUNT_ACTIVE,
|
||||||
@@ -400,7 +399,6 @@ enum monitor_id_t {
|
|||||||
/* Data DDL related counters */
|
/* Data DDL related counters */
|
||||||
MONITOR_MODULE_DDL_STATS,
|
MONITOR_MODULE_DDL_STATS,
|
||||||
MONITOR_BACKGROUND_DROP_INDEX,
|
MONITOR_BACKGROUND_DROP_INDEX,
|
||||||
MONITOR_BACKGROUND_DROP_TABLE,
|
|
||||||
MONITOR_ONLINE_CREATE_INDEX,
|
MONITOR_ONLINE_CREATE_INDEX,
|
||||||
MONITOR_PENDING_ALTER_TABLE,
|
MONITOR_PENDING_ALTER_TABLE,
|
||||||
MONITOR_ALTER_TABLE_SORT_FILES,
|
MONITOR_ALTER_TABLE_SORT_FILES,
|
||||||
|
@@ -138,6 +138,8 @@ private:
|
|||||||
Atomic_counter<uint32_t> m_paused;
|
Atomic_counter<uint32_t> m_paused;
|
||||||
/** number of stop_SYS() calls without resume_SYS() */
|
/** number of stop_SYS() calls without resume_SYS() */
|
||||||
Atomic_counter<uint32_t> m_SYS_paused;
|
Atomic_counter<uint32_t> m_SYS_paused;
|
||||||
|
/** number of stop_FTS() calls without resume_FTS() */
|
||||||
|
Atomic_counter<uint32_t> m_FTS_paused;
|
||||||
public:
|
public:
|
||||||
que_t* query; /*!< The query graph which will do the
|
que_t* query; /*!< The query graph which will do the
|
||||||
parallelized purge operation */
|
parallelized purge operation */
|
||||||
@@ -243,13 +245,14 @@ public:
|
|||||||
|
|
||||||
/** @return whether the purge tasks are active */
|
/** @return whether the purge tasks are active */
|
||||||
bool running() const;
|
bool running() const;
|
||||||
/** Stop purge during FLUSH TABLES FOR EXPORT */
|
/** Stop purge during FLUSH TABLES FOR EXPORT. */
|
||||||
void stop();
|
void stop();
|
||||||
/** Resume purge at UNLOCK TABLES after FLUSH TABLES FOR EXPORT */
|
/** Resume purge at UNLOCK TABLES after FLUSH TABLES FOR EXPORT */
|
||||||
void resume();
|
void resume();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void wait_SYS();
|
void wait_SYS();
|
||||||
|
void wait_FTS();
|
||||||
public:
|
public:
|
||||||
/** Suspend purge in data dictionary tables */
|
/** Suspend purge in data dictionary tables */
|
||||||
void stop_SYS();
|
void stop_SYS();
|
||||||
@@ -260,6 +263,15 @@ public:
|
|||||||
/** check stop_SYS() */
|
/** check stop_SYS() */
|
||||||
void check_stop_SYS() { if (must_wait_SYS()) wait_SYS(); }
|
void check_stop_SYS() { if (must_wait_SYS()) wait_SYS(); }
|
||||||
|
|
||||||
|
/** Pause purge during a DDL operation that could drop FTS_ tables. */
|
||||||
|
void stop_FTS() { m_FTS_paused++; }
|
||||||
|
/** Resume purge after stop_FTS(). */
|
||||||
|
void resume_FTS() { ut_d(const auto p=) m_FTS_paused--; ut_ad(p); }
|
||||||
|
/** @return whether stop_SYS() is in effect */
|
||||||
|
bool must_wait_FTS() const { return m_FTS_paused; }
|
||||||
|
/** check stop_SYS() */
|
||||||
|
void check_stop_FTS() { if (must_wait_FTS()) wait_FTS(); }
|
||||||
|
|
||||||
/** A wrapper around ReadView::changes_visible(). */
|
/** A wrapper around ReadView::changes_visible(). */
|
||||||
bool changes_visible(trx_id_t id, const table_name_t &name) const
|
bool changes_visible(trx_id_t id, const table_name_t &name) const
|
||||||
{
|
{
|
||||||
|
@@ -38,7 +38,6 @@ Created 3/26/1996 Heikki Tuuri
|
|||||||
#include "ilist.h"
|
#include "ilist.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
|
||||||
|
|
||||||
// Forward declaration
|
// Forward declaration
|
||||||
struct mtr_t;
|
struct mtr_t;
|
||||||
@@ -412,7 +411,8 @@ class trx_mod_table_time_t
|
|||||||
|
|
||||||
/** First modification of the table, possibly ORed with BULK */
|
/** First modification of the table, possibly ORed with BULK */
|
||||||
undo_no_t first;
|
undo_no_t first;
|
||||||
/** First modification of a system versioned column (or NONE) */
|
/** First modification of a system versioned column
|
||||||
|
(NONE= no versioning, BULK= the table was dropped) */
|
||||||
undo_no_t first_versioned= NONE;
|
undo_no_t first_versioned= NONE;
|
||||||
public:
|
public:
|
||||||
/** Constructor
|
/** Constructor
|
||||||
@@ -427,17 +427,26 @@ public:
|
|||||||
{ auto f= first & LIMIT; return f <= first_versioned && f <= rows; }
|
{ auto f= first & LIMIT; return f <= first_versioned && f <= rows; }
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
/** @return if versioned columns were modified */
|
/** @return if versioned columns were modified */
|
||||||
bool is_versioned() const { return first_versioned != NONE; }
|
bool is_versioned() const { return (~first_versioned & LIMIT) != 0; }
|
||||||
|
/** @return if the table was dropped */
|
||||||
|
bool is_dropped() const { return first_versioned == BULK; }
|
||||||
|
|
||||||
/** After writing an undo log record, set is_versioned() if needed
|
/** After writing an undo log record, set is_versioned() if needed
|
||||||
@param rows number of modified rows so far */
|
@param rows number of modified rows so far */
|
||||||
void set_versioned(undo_no_t rows)
|
void set_versioned(undo_no_t rows)
|
||||||
{
|
{
|
||||||
ut_ad(!is_versioned());
|
ut_ad(first_versioned == NONE);
|
||||||
first_versioned= rows;
|
first_versioned= rows;
|
||||||
ut_ad(valid(rows));
|
ut_ad(valid(rows));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** After writing an undo log record, note that the table will be dropped */
|
||||||
|
void set_dropped()
|
||||||
|
{
|
||||||
|
ut_ad(first_versioned == NONE);
|
||||||
|
first_versioned= BULK;
|
||||||
|
}
|
||||||
|
|
||||||
/** Notify the start of a bulk insert operation */
|
/** Notify the start of a bulk insert operation */
|
||||||
void start_bulk_insert() { first|= BULK; }
|
void start_bulk_insert() { first|= BULK; }
|
||||||
|
|
||||||
@@ -923,6 +932,10 @@ private:
|
|||||||
inline void commit_tables();
|
inline void commit_tables();
|
||||||
/** Mark a transaction committed in the main memory data structures. */
|
/** Mark a transaction committed in the main memory data structures. */
|
||||||
inline void commit_in_memory(const mtr_t *mtr);
|
inline void commit_in_memory(const mtr_t *mtr);
|
||||||
|
/** Write log for committing the transaction. */
|
||||||
|
void commit_persist();
|
||||||
|
/** Clean up the transaction after commit_in_memory() */
|
||||||
|
void commit_cleanup();
|
||||||
/** Commit the transaction in a mini-transaction.
|
/** Commit the transaction in a mini-transaction.
|
||||||
@param mtr mini-transaction (if there are any persistent modifications) */
|
@param mtr mini-transaction (if there are any persistent modifications) */
|
||||||
void commit_low(mtr_t *mtr= nullptr);
|
void commit_low(mtr_t *mtr= nullptr);
|
||||||
@@ -931,6 +944,24 @@ public:
|
|||||||
void commit();
|
void commit();
|
||||||
|
|
||||||
|
|
||||||
|
/** Try to drop a persistent table.
|
||||||
|
@param table persistent table
|
||||||
|
@param fk whether to drop FOREIGN KEY metadata
|
||||||
|
@return error code */
|
||||||
|
dberr_t drop_table(const dict_table_t &table);
|
||||||
|
/** Try to drop the foreign key constraints for a persistent table.
|
||||||
|
@param name name of persistent table
|
||||||
|
@return error code */
|
||||||
|
dberr_t drop_table_foreign(const table_name_t &name);
|
||||||
|
/** Try to drop the statistics for a persistent table.
|
||||||
|
@param name name of persistent table
|
||||||
|
@return error code */
|
||||||
|
dberr_t drop_table_statistics(const table_name_t &name);
|
||||||
|
/** Commit the transaction, possibly after drop_table().
|
||||||
|
@param deleted handles of data files that were deleted */
|
||||||
|
void commit(std::vector<pfs_os_file_t> &deleted);
|
||||||
|
|
||||||
|
|
||||||
/** Discard all savepoints */
|
/** Discard all savepoints */
|
||||||
void savepoints_discard()
|
void savepoints_discard()
|
||||||
{ savepoints_discard(UT_LIST_GET_FIRST(trx_savepoints)); }
|
{ savepoints_discard(UT_LIST_GET_FIRST(trx_savepoints)); }
|
||||||
|
@@ -1265,19 +1265,16 @@ lock_rec_enqueue_waiting(
|
|||||||
trx_t* trx = thr_get_trx(thr);
|
trx_t* trx = thr_get_trx(thr);
|
||||||
ut_ad(trx->mutex_is_owner());
|
ut_ad(trx->mutex_is_owner());
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(trx->dict_operation)) {
|
if (UNIV_UNLIKELY(trx->dict_operation_lock_mode == RW_X_LATCH)) {
|
||||||
ib::error() << "A record lock wait happens in a dictionary"
|
ut_ad(!strcmp(index->table->name.m_name, TABLE_STATS_NAME)
|
||||||
" operation. index "
|
|| !strcmp(index->table->name.m_name, INDEX_STATS_NAME));
|
||||||
<< index->name
|
instant_timeout:
|
||||||
<< " of table "
|
trx->error_state = DB_LOCK_WAIT_TIMEOUT;
|
||||||
<< index->table->name
|
return DB_LOCK_WAIT_TIMEOUT;
|
||||||
<< ". " << BUG_REPORT_MSG;
|
|
||||||
ut_ad(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trx->mysql_thd && thd_lock_wait_timeout(trx->mysql_thd) == 0) {
|
if (trx->mysql_thd && thd_lock_wait_timeout(trx->mysql_thd) == 0) {
|
||||||
trx->error_state = DB_LOCK_WAIT_TIMEOUT;
|
goto instant_timeout;
|
||||||
return DB_LOCK_WAIT_TIMEOUT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enqueue the lock request that will wait to be granted, note that
|
/* Enqueue the lock request that will wait to be granted, note that
|
||||||
@@ -3314,11 +3311,11 @@ lock_table_enqueue_waiting(
|
|||||||
trx_t* trx = thr_get_trx(thr);
|
trx_t* trx = thr_get_trx(thr);
|
||||||
ut_ad(trx->mutex_is_owner());
|
ut_ad(trx->mutex_is_owner());
|
||||||
|
|
||||||
if (UNIV_UNLIKELY(trx->dict_operation)) {
|
if (UNIV_UNLIKELY(trx->dict_operation_lock_mode == RW_X_LATCH)) {
|
||||||
ib::error() << "A table lock wait happens in a dictionary"
|
ut_ad(!strcmp(table->name.m_name, TABLE_STATS_NAME)
|
||||||
" operation. Table " << table->name
|
|| !strcmp(table->name.m_name, INDEX_STATS_NAME));
|
||||||
<< ". " << BUG_REPORT_MSG;
|
trx->error_state = DB_LOCK_WAIT_TIMEOUT;
|
||||||
ut_ad(0);
|
return DB_LOCK_WAIT_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
|
@@ -1482,8 +1482,7 @@ os_file_rename_func(
|
|||||||
|
|
||||||
/* New path must not exist. */
|
/* New path must not exist. */
|
||||||
ut_ad(os_file_status(newpath, &exists, &type));
|
ut_ad(os_file_status(newpath, &exists, &type));
|
||||||
/* MDEV-25506 FIXME: Remove the strstr() */
|
ut_ad(!exists);
|
||||||
ut_ad(!exists || strstr(oldpath, "/" TEMP_FILE_PREFIX_INNODB));
|
|
||||||
|
|
||||||
/* Old path must exist. */
|
/* Old path must exist. */
|
||||||
ut_ad(os_file_status(oldpath, &exists, &type));
|
ut_ad(os_file_status(oldpath, &exists, &type));
|
||||||
@@ -2535,8 +2534,7 @@ os_file_rename_func(
|
|||||||
|
|
||||||
/* New path must not exist. */
|
/* New path must not exist. */
|
||||||
ut_ad(os_file_status(newpath, &exists, &type));
|
ut_ad(os_file_status(newpath, &exists, &type));
|
||||||
/* MDEV-25506 FIXME: Remove the strstr() */
|
ut_ad(!exists);
|
||||||
ut_ad(!exists || strstr(oldpath, "/" TEMP_FILE_PREFIX_INNODB));
|
|
||||||
|
|
||||||
/* Old path must exist. */
|
/* Old path must exist. */
|
||||||
ut_ad(os_file_status(oldpath, &exists, &type));
|
ut_ad(os_file_status(oldpath, &exists, &type));
|
||||||
|
@@ -1830,16 +1830,12 @@ do_possible_lock_wait:
|
|||||||
|
|
||||||
thr->lock_state = QUE_THR_LOCK_ROW;
|
thr->lock_state = QUE_THR_LOCK_ROW;
|
||||||
|
|
||||||
check_table->inc_fk_checks();
|
|
||||||
|
|
||||||
err = lock_wait(thr);
|
err = lock_wait(thr);
|
||||||
|
|
||||||
thr->lock_state = QUE_THR_LOCK_NOLOCK;
|
thr->lock_state = QUE_THR_LOCK_NOLOCK;
|
||||||
|
|
||||||
check_table->dec_fk_checks();
|
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
} else if (check_table->to_be_dropped) {
|
} else if (check_table->name.is_temporary()) {
|
||||||
err = DB_LOCK_WAIT_TIMEOUT;
|
err = DB_LOCK_WAIT_TIMEOUT;
|
||||||
} else {
|
} else {
|
||||||
err = DB_LOCK_WAIT;
|
err = DB_LOCK_WAIT;
|
||||||
@@ -1912,14 +1908,10 @@ row_ins_check_foreign_constraints(
|
|||||||
{
|
{
|
||||||
dict_foreign_t* foreign;
|
dict_foreign_t* foreign;
|
||||||
dberr_t err = DB_SUCCESS;
|
dberr_t err = DB_SUCCESS;
|
||||||
trx_t* trx;
|
|
||||||
ibool got_s_lock = FALSE;
|
|
||||||
mem_heap_t* heap = NULL;
|
mem_heap_t* heap = NULL;
|
||||||
|
|
||||||
DBUG_ASSERT(index->is_primary() == pk);
|
DBUG_ASSERT(index->is_primary() == pk);
|
||||||
|
|
||||||
trx = thr_get_trx(thr);
|
|
||||||
|
|
||||||
DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd,
|
DEBUG_SYNC_C_IF_THD(thr_get_trx(thr)->mysql_thd,
|
||||||
"foreign_constraint_check_for_ins");
|
"foreign_constraint_check_for_ins");
|
||||||
|
|
||||||
@@ -1965,32 +1957,9 @@ row_ins_check_foreign_constraints(
|
|||||||
FALSE, FALSE, DICT_ERR_IGNORE_NONE);
|
FALSE, FALSE, DICT_ERR_IGNORE_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == trx->dict_operation_lock_mode) {
|
|
||||||
got_s_lock = TRUE;
|
|
||||||
|
|
||||||
row_mysql_freeze_data_dictionary(trx);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (referenced_table) {
|
|
||||||
foreign->foreign_table->inc_fk_checks();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOTE that if the thread ends up waiting for a lock
|
|
||||||
we will release dict_sys.latch temporarily!
|
|
||||||
But the counter on the table protects the referenced
|
|
||||||
table from being dropped while the check is running. */
|
|
||||||
|
|
||||||
err = row_ins_check_foreign_constraint(
|
err = row_ins_check_foreign_constraint(
|
||||||
TRUE, foreign, table, ref_tuple, thr);
|
TRUE, foreign, table, ref_tuple, thr);
|
||||||
|
|
||||||
if (referenced_table) {
|
|
||||||
foreign->foreign_table->dec_fk_checks();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (got_s_lock) {
|
|
||||||
row_mysql_unfreeze_data_dictionary(trx);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ref_table != NULL) {
|
if (ref_table != NULL) {
|
||||||
dict_table_close(ref_table, FALSE, FALSE);
|
dict_table_close(ref_table, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
|
@@ -3787,7 +3787,7 @@ static void row_merge_drop_fulltext_indexes(trx_t *trx, dict_table_t *table)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
fts_optimize_remove_table(table);
|
fts_optimize_remove_table(table);
|
||||||
fts_drop_tables(trx, table);
|
fts_drop_tables(trx, *table);
|
||||||
fts_free(table);
|
fts_free(table);
|
||||||
DICT_TF2_FLAG_UNSET(table, DICT_TF2_FTS);
|
DICT_TF2_FLAG_UNSET(table, DICT_TF2_FTS);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -111,8 +111,10 @@ row_purge_remove_clust_if_poss_low(
|
|||||||
MDL_ticket* mdl_ticket = nullptr;
|
MDL_ticket* mdl_ticket = nullptr;
|
||||||
dict_table_t *table = nullptr;
|
dict_table_t *table = nullptr;
|
||||||
pfs_os_file_t f = OS_FILE_CLOSED;
|
pfs_os_file_t f = OS_FILE_CLOSED;
|
||||||
retry:
|
|
||||||
if (table_id) {
|
if (table_id) {
|
||||||
|
retry:
|
||||||
|
purge_sys.check_stop_FTS();
|
||||||
dict_sys.mutex_lock();
|
dict_sys.mutex_lock();
|
||||||
table = dict_table_open_on_id(
|
table = dict_table_open_on_id(
|
||||||
table_id, true, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED,
|
table_id, true, DICT_TABLE_OP_OPEN_ONLY_IF_CACHED,
|
||||||
@@ -184,7 +186,7 @@ close_and_exit:
|
|||||||
mdl_ticket = nullptr;
|
mdl_ticket = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fil_delete_tablespace(space_id, true, &f);
|
f = fil_delete_tablespace(space_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
@@ -739,6 +741,12 @@ void purge_sys_t::wait_SYS()
|
|||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void purge_sys_t::wait_FTS()
|
||||||
|
{
|
||||||
|
while (must_wait_FTS())
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
}
|
||||||
|
|
||||||
/** Reset DB_TRX_ID, DB_ROLL_PTR of a clustered index record
|
/** Reset DB_TRX_ID, DB_ROLL_PTR of a clustered index record
|
||||||
whose old history can no longer be observed.
|
whose old history can no longer be observed.
|
||||||
@param[in,out] node purge node
|
@param[in,out] node purge node
|
||||||
@@ -1034,11 +1042,13 @@ row_purge_parse_undo_rec(
|
|||||||
}
|
}
|
||||||
|
|
||||||
try_again:
|
try_again:
|
||||||
|
purge_sys.check_stop_FTS();
|
||||||
|
|
||||||
node->table = dict_table_open_on_id(
|
node->table = dict_table_open_on_id(
|
||||||
table_id, false, DICT_TABLE_OP_NORMAL, node->purge_thd,
|
table_id, false, DICT_TABLE_OP_NORMAL, node->purge_thd,
|
||||||
&node->mdl_ticket);
|
&node->mdl_ticket);
|
||||||
|
|
||||||
if (node->table == NULL || node->table->name.is_temporary()) {
|
if (!node->table) {
|
||||||
/* The table has been dropped: no need to do purge and
|
/* The table has been dropped: no need to do purge and
|
||||||
release mdl happened as a part of open process itself */
|
release mdl happened as a part of open process itself */
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
|
@@ -140,6 +140,27 @@ restart:
|
|||||||
mem_heap_free(heap);
|
mem_heap_free(heap);
|
||||||
} else {
|
} else {
|
||||||
switch (node->table->id) {
|
switch (node->table->id) {
|
||||||
|
case DICT_COLUMNS_ID:
|
||||||
|
/* This is rolling back an INSERT into SYS_COLUMNS.
|
||||||
|
If it was part of an instant ALTER TABLE operation, we
|
||||||
|
must evict the table definition, so that it can be
|
||||||
|
reloaded after the dictionary operation has been
|
||||||
|
completed. At this point, any corresponding operation
|
||||||
|
to the metadata record will have been rolled back. */
|
||||||
|
ut_ad(!online);
|
||||||
|
ut_ad(node->trx->dict_operation_lock_mode
|
||||||
|
== RW_X_LATCH);
|
||||||
|
ut_ad(node->rec_type == TRX_UNDO_INSERT_REC);
|
||||||
|
if (rec_get_n_fields_old(rec)
|
||||||
|
!= DICT_NUM_FIELDS__SYS_COLUMNS
|
||||||
|
|| (rec_get_1byte_offs_flag(rec)
|
||||||
|
? rec_1_get_field_end_info(rec, 0) != 8
|
||||||
|
: rec_2_get_field_end_info(rec, 0) != 8)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
static_assert(!DICT_FLD__SYS_COLUMNS__TABLE_ID, "");
|
||||||
|
node->trx->evict_table(mach_read_from_8(rec));
|
||||||
|
break;
|
||||||
case DICT_INDEXES_ID:
|
case DICT_INDEXES_ID:
|
||||||
ut_ad(!online);
|
ut_ad(!online);
|
||||||
ut_ad(node->trx->dict_operation_lock_mode
|
ut_ad(node->trx->dict_operation_lock_mode
|
||||||
@@ -154,6 +175,8 @@ restart:
|
|||||||
ut_ad("corrupted SYS_INDEXES record" == 0);
|
ut_ad("corrupted SYS_INDEXES record" == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pfs_os_file_t d = OS_FILE_CLOSED;
|
||||||
|
|
||||||
if (const uint32_t space_id = dict_drop_index_tree(
|
if (const uint32_t space_id = dict_drop_index_tree(
|
||||||
&node->pcur, node->trx, &mtr)) {
|
&node->pcur, node->trx, &mtr)) {
|
||||||
if (table) {
|
if (table) {
|
||||||
@@ -185,36 +208,19 @@ restart:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fil_delete_tablespace(space_id, true);
|
d = fil_delete_tablespace(space_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
mtr.commit();
|
mtr.commit();
|
||||||
|
|
||||||
|
if (d != OS_FILE_CLOSED) {
|
||||||
|
os_file_close(d);
|
||||||
|
}
|
||||||
|
|
||||||
mtr.start();
|
mtr.start();
|
||||||
success = btr_pcur_restore_position(
|
success = btr_pcur_restore_position(
|
||||||
BTR_MODIFY_LEAF, &node->pcur, &mtr);
|
BTR_MODIFY_LEAF, &node->pcur, &mtr);
|
||||||
ut_a(success);
|
ut_a(success);
|
||||||
break;
|
|
||||||
case DICT_COLUMNS_ID:
|
|
||||||
/* This is rolling back an INSERT into SYS_COLUMNS.
|
|
||||||
If it was part of an instant ALTER TABLE operation, we
|
|
||||||
must evict the table definition, so that it can be
|
|
||||||
reloaded after the dictionary operation has been
|
|
||||||
completed. At this point, any corresponding operation
|
|
||||||
to the metadata record will have been rolled back. */
|
|
||||||
ut_ad(!online);
|
|
||||||
ut_ad(node->trx->dict_operation_lock_mode
|
|
||||||
== RW_X_LATCH);
|
|
||||||
ut_ad(node->rec_type == TRX_UNDO_INSERT_REC);
|
|
||||||
if (rec_get_n_fields_old(rec)
|
|
||||||
!= DICT_NUM_FIELDS__SYS_COLUMNS
|
|
||||||
|| (rec_get_1byte_offs_flag(rec)
|
|
||||||
? rec_1_get_field_end_info(rec, 0) != 8
|
|
||||||
: rec_2_get_field_end_info(rec, 0) != 8)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
static_assert(!DICT_FLD__SYS_COLUMNS__TABLE_ID, "");
|
|
||||||
node->trx->evict_table(mach_read_from_8(rec));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -281,21 +281,9 @@ row_upd_check_references_constraints(
|
|||||||
FALSE, FALSE, DICT_ERR_IGNORE_NONE);
|
FALSE, FALSE, DICT_ERR_IGNORE_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foreign_table) {
|
|
||||||
foreign_table->inc_fk_checks();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* NOTE that if the thread ends up waiting for a lock
|
|
||||||
we will release dict_sys.latch temporarily!
|
|
||||||
But the inc_fk_checks() protects foreign_table from
|
|
||||||
being dropped while the check is running. */
|
|
||||||
|
|
||||||
err = row_ins_check_foreign_constraint(
|
err = row_ins_check_foreign_constraint(
|
||||||
FALSE, foreign, table, entry, thr);
|
FALSE, foreign, table, entry, thr);
|
||||||
|
|
||||||
if (foreign_table) {
|
|
||||||
foreign_table->dec_fk_checks();
|
|
||||||
}
|
|
||||||
if (ref_table != NULL) {
|
if (ref_table != NULL) {
|
||||||
dict_table_close(ref_table, FALSE, FALSE);
|
dict_table_close(ref_table, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
|
@@ -1090,11 +1090,6 @@ static monitor_info_t innodb_counter_info[] =
|
|||||||
MONITOR_NONE,
|
MONITOR_NONE,
|
||||||
MONITOR_DEFAULT_START, MONITOR_MASTER_IDLE_LOOPS},
|
MONITOR_DEFAULT_START, MONITOR_MASTER_IDLE_LOOPS},
|
||||||
|
|
||||||
{"innodb_background_drop_table_usec", "server",
|
|
||||||
"Time (in microseconds) spent to process drop table list",
|
|
||||||
MONITOR_NONE,
|
|
||||||
MONITOR_DEFAULT_START, MONITOR_SRV_BACKGROUND_DROP_TABLE_MICROSECOND},
|
|
||||||
|
|
||||||
{"innodb_log_flush_usec", "server",
|
{"innodb_log_flush_usec", "server",
|
||||||
"Time (in microseconds) spent to flush log records",
|
"Time (in microseconds) spent to flush log records",
|
||||||
MONITOR_NONE,
|
MONITOR_NONE,
|
||||||
@@ -1189,11 +1184,6 @@ static monitor_info_t innodb_counter_info[] =
|
|||||||
MONITOR_NONE,
|
MONITOR_NONE,
|
||||||
MONITOR_DEFAULT_START, MONITOR_BACKGROUND_DROP_INDEX},
|
MONITOR_DEFAULT_START, MONITOR_BACKGROUND_DROP_INDEX},
|
||||||
|
|
||||||
{"ddl_background_drop_tables", "ddl",
|
|
||||||
"Number of tables in background drop table list",
|
|
||||||
MONITOR_NONE,
|
|
||||||
MONITOR_DEFAULT_START, MONITOR_BACKGROUND_DROP_TABLE},
|
|
||||||
|
|
||||||
{"ddl_online_create_index", "ddl",
|
{"ddl_online_create_index", "ddl",
|
||||||
"Number of indexes being created online",
|
"Number of indexes being created online",
|
||||||
MONITOR_NONE,
|
MONITOR_NONE,
|
||||||
|
@@ -677,7 +677,6 @@ srv_boot(void)
|
|||||||
{
|
{
|
||||||
srv_thread_pool_init();
|
srv_thread_pool_init();
|
||||||
trx_pool_init();
|
trx_pool_init();
|
||||||
row_mysql_init();
|
|
||||||
srv_init();
|
srv_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1374,6 +1373,8 @@ void purge_sys_t::stop_SYS()
|
|||||||
/** Stop purge during FLUSH TABLES FOR EXPORT */
|
/** Stop purge during FLUSH TABLES FOR EXPORT */
|
||||||
void purge_sys_t::stop()
|
void purge_sys_t::stop()
|
||||||
{
|
{
|
||||||
|
dict_sys.assert_not_locked();
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
latch.wr_lock(SRW_LOCK_CALL);
|
latch.wr_lock(SRW_LOCK_CALL);
|
||||||
@@ -1471,10 +1472,7 @@ The master thread is tasked to ensure that flush of log file happens
|
|||||||
once every second in the background. This is to ensure that not more
|
once every second in the background. This is to ensure that not more
|
||||||
than one second of trxs are lost in case of crash when
|
than one second of trxs are lost in case of crash when
|
||||||
innodb_flush_logs_at_trx_commit != 1 */
|
innodb_flush_logs_at_trx_commit != 1 */
|
||||||
static
|
static void srv_sync_log_buffer_in_background()
|
||||||
void
|
|
||||||
srv_sync_log_buffer_in_background(void)
|
|
||||||
/*===================================*/
|
|
||||||
{
|
{
|
||||||
time_t current_time = time(NULL);
|
time_t current_time = time(NULL);
|
||||||
|
|
||||||
@@ -1496,8 +1494,6 @@ srv_shutdown_print_master_pending(
|
|||||||
/*==============================*/
|
/*==============================*/
|
||||||
time_t* last_print_time, /*!< last time the function
|
time_t* last_print_time, /*!< last time the function
|
||||||
print the message */
|
print the message */
|
||||||
ulint n_tables_to_drop, /*!< number of tables to
|
|
||||||
be dropped */
|
|
||||||
ulint n_bytes_merged) /*!< number of change buffer
|
ulint n_bytes_merged) /*!< number of change buffer
|
||||||
just merged */
|
just merged */
|
||||||
{
|
{
|
||||||
@@ -1506,11 +1502,6 @@ srv_shutdown_print_master_pending(
|
|||||||
if (difftime(current_time, *last_print_time) > 60) {
|
if (difftime(current_time, *last_print_time) > 60) {
|
||||||
*last_print_time = current_time;
|
*last_print_time = current_time;
|
||||||
|
|
||||||
if (n_tables_to_drop) {
|
|
||||||
ib::info() << "Waiting for " << n_tables_to_drop
|
|
||||||
<< " table(s) to be dropped";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check change buffer merge, we only wait for change buffer
|
/* Check change buffer merge, we only wait for change buffer
|
||||||
merge if it is a slow shutdown */
|
merge if it is a slow shutdown */
|
||||||
if (!srv_fast_shutdown && n_bytes_merged) {
|
if (!srv_fast_shutdown && n_bytes_merged) {
|
||||||
@@ -1585,14 +1576,6 @@ srv_master_do_active_tasks(void)
|
|||||||
|
|
||||||
MONITOR_INC(MONITOR_MASTER_ACTIVE_LOOPS);
|
MONITOR_INC(MONITOR_MASTER_ACTIVE_LOOPS);
|
||||||
|
|
||||||
/* ALTER TABLE in MySQL requires on Unix that the table handler
|
|
||||||
can drop tables lazily after there no longer are SELECT
|
|
||||||
queries to them. */
|
|
||||||
srv_main_thread_op_info = "doing background drop tables";
|
|
||||||
row_drop_tables_for_mysql_in_background();
|
|
||||||
MONITOR_INC_TIME_IN_MICRO_SECS(
|
|
||||||
MONITOR_SRV_BACKGROUND_DROP_TABLE_MICROSECOND, counter_time);
|
|
||||||
|
|
||||||
ut_d(srv_master_do_disabled_loop());
|
ut_d(srv_master_do_disabled_loop());
|
||||||
|
|
||||||
if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
|
if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
|
||||||
@@ -1646,17 +1629,6 @@ srv_master_do_idle_tasks(void)
|
|||||||
|
|
||||||
MONITOR_INC(MONITOR_MASTER_IDLE_LOOPS);
|
MONITOR_INC(MONITOR_MASTER_IDLE_LOOPS);
|
||||||
|
|
||||||
|
|
||||||
/* ALTER TABLE in MySQL requires on Unix that the table handler
|
|
||||||
can drop tables lazily after there no longer are SELECT
|
|
||||||
queries to them. */
|
|
||||||
ulonglong counter_time = microsecond_interval_timer();
|
|
||||||
srv_main_thread_op_info = "doing background drop tables";
|
|
||||||
row_drop_tables_for_mysql_in_background();
|
|
||||||
MONITOR_INC_TIME_IN_MICRO_SECS(
|
|
||||||
MONITOR_SRV_BACKGROUND_DROP_TABLE_MICROSECOND,
|
|
||||||
counter_time);
|
|
||||||
|
|
||||||
ut_d(srv_master_do_disabled_loop());
|
ut_d(srv_master_do_disabled_loop());
|
||||||
|
|
||||||
if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
|
if (srv_shutdown_state > SRV_SHUTDOWN_INITIATED) {
|
||||||
@@ -1672,6 +1644,7 @@ srv_master_do_idle_tasks(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ulonglong counter_time = microsecond_interval_timer();
|
||||||
srv_main_thread_op_info = "enforcing dict cache limit";
|
srv_main_thread_op_info = "enforcing dict cache limit";
|
||||||
if (ulint n_evicted = dict_sys.evict_table_LRU(false)) {
|
if (ulint n_evicted = dict_sys.evict_table_LRU(false)) {
|
||||||
MONITOR_INC_VALUE(
|
MONITOR_INC_VALUE(
|
||||||
@@ -1692,7 +1665,6 @@ and optionally change buffer merge (on innodb_fast_shutdown=0). */
|
|||||||
void srv_shutdown(bool ibuf_merge)
|
void srv_shutdown(bool ibuf_merge)
|
||||||
{
|
{
|
||||||
ulint n_bytes_merged = 0;
|
ulint n_bytes_merged = 0;
|
||||||
ulint n_tables_to_drop;
|
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -1700,11 +1672,6 @@ void srv_shutdown(bool ibuf_merge)
|
|||||||
ut_ad(srv_shutdown_state == SRV_SHUTDOWN_CLEANUP);
|
ut_ad(srv_shutdown_state == SRV_SHUTDOWN_CLEANUP);
|
||||||
++srv_main_shutdown_loops;
|
++srv_main_shutdown_loops;
|
||||||
|
|
||||||
/* FIXME: Remove the background DROP TABLE queue; it is not
|
|
||||||
crash-safe and breaks ACID. */
|
|
||||||
srv_main_thread_op_info = "doing background drop tables";
|
|
||||||
n_tables_to_drop = row_drop_tables_for_mysql_in_background();
|
|
||||||
|
|
||||||
if (ibuf_merge) {
|
if (ibuf_merge) {
|
||||||
srv_main_thread_op_info = "checking free log space";
|
srv_main_thread_op_info = "checking free log space";
|
||||||
log_free_check();
|
log_free_check();
|
||||||
@@ -1717,10 +1684,10 @@ void srv_shutdown(bool ibuf_merge)
|
|||||||
|
|
||||||
/* Print progress message every 60 seconds during shutdown */
|
/* Print progress message every 60 seconds during shutdown */
|
||||||
if (srv_print_verbose_log) {
|
if (srv_print_verbose_log) {
|
||||||
srv_shutdown_print_master_pending(
|
srv_shutdown_print_master_pending(&now,
|
||||||
&now, n_tables_to_drop, n_bytes_merged);
|
n_bytes_merged);
|
||||||
}
|
}
|
||||||
} while (n_bytes_merged || n_tables_to_drop);
|
} while (n_bytes_merged);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The periodic master task controlling the server. */
|
/** The periodic master task controlling the server. */
|
||||||
|
@@ -1764,9 +1764,6 @@ file_checked:
|
|||||||
&& !srv_read_only_mode) {
|
&& !srv_read_only_mode) {
|
||||||
/* Drop partially created indexes. */
|
/* Drop partially created indexes. */
|
||||||
row_merge_drop_temp_indexes();
|
row_merge_drop_temp_indexes();
|
||||||
/* Drop garbage tables. */
|
|
||||||
row_mysql_drop_garbage_tables();
|
|
||||||
|
|
||||||
/* Rollback incomplete non-DDL transactions */
|
/* Rollback incomplete non-DDL transactions */
|
||||||
trx_rollback_is_active = true;
|
trx_rollback_is_active = true;
|
||||||
srv_thread_pool->submit_task(&rollback_all_recovered_task);
|
srv_thread_pool->submit_task(&rollback_all_recovered_task);
|
||||||
@@ -1898,10 +1895,6 @@ void srv_shutdown_bg_undo_sources()
|
|||||||
ut_ad(!srv_read_only_mode);
|
ut_ad(!srv_read_only_mode);
|
||||||
fts_optimize_shutdown();
|
fts_optimize_shutdown();
|
||||||
dict_stats_shutdown();
|
dict_stats_shutdown();
|
||||||
while (row_get_background_drop_list_len_low()) {
|
|
||||||
srv_inc_activity_count();
|
|
||||||
std::this_thread::yield();
|
|
||||||
}
|
|
||||||
srv_undo_sources = false;
|
srv_undo_sources = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2028,7 +2021,6 @@ void innodb_shutdown()
|
|||||||
|
|
||||||
dict_sys.close();
|
dict_sys.close();
|
||||||
btr_search_sys_free();
|
btr_search_sys_free();
|
||||||
row_mysql_close();
|
|
||||||
srv_free();
|
srv_free();
|
||||||
fil_system.close();
|
fil_system.close();
|
||||||
pars_lexer_close();
|
pars_lexer_close();
|
||||||
|
@@ -694,7 +694,8 @@ not_free:
|
|||||||
|
|
||||||
/* Adjust the tablespace metadata. */
|
/* Adjust the tablespace metadata. */
|
||||||
mysql_mutex_lock(&fil_system.mutex);
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
space.set_stopping(true);
|
ut_d(bool stopped=) space.set_stopping();
|
||||||
|
ut_ad(!stopped);
|
||||||
space.is_being_truncated = true;
|
space.is_being_truncated = true;
|
||||||
if (space.crypt_data) {
|
if (space.crypt_data) {
|
||||||
space.reacquire();
|
space.reacquire();
|
||||||
@@ -806,7 +807,7 @@ not_free:
|
|||||||
mysql_mutex_lock(&fil_system.mutex);
|
mysql_mutex_lock(&fil_system.mutex);
|
||||||
ut_ad(&space == purge_sys.truncate.current);
|
ut_ad(&space == purge_sys.truncate.current);
|
||||||
ut_ad(space.is_being_truncated);
|
ut_ad(space.is_being_truncated);
|
||||||
purge_sys.truncate.current->set_stopping(false);
|
purge_sys.truncate.current->clear_stopping();
|
||||||
purge_sys.truncate.current->is_being_truncated = false;
|
purge_sys.truncate.current->is_being_truncated = false;
|
||||||
mysql_mutex_unlock(&fil_system.mutex);
|
mysql_mutex_unlock(&fil_system.mutex);
|
||||||
|
|
||||||
|
@@ -59,6 +59,8 @@ const trx_t* trx_roll_crash_recv_trx;
|
|||||||
@retval false if the rollback was aborted by shutdown */
|
@retval false if the rollback was aborted by shutdown */
|
||||||
inline bool trx_t::rollback_finish()
|
inline bool trx_t::rollback_finish()
|
||||||
{
|
{
|
||||||
|
mod_tables.clear();
|
||||||
|
|
||||||
if (UNIV_LIKELY(error_state == DB_SUCCESS))
|
if (UNIV_LIKELY(error_state == DB_SUCCESS))
|
||||||
{
|
{
|
||||||
commit();
|
commit();
|
||||||
@@ -89,6 +91,7 @@ inline bool trx_t::rollback_finish()
|
|||||||
undo= nullptr;
|
undo= nullptr;
|
||||||
}
|
}
|
||||||
commit_low();
|
commit_low();
|
||||||
|
commit_cleanup();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1427,6 +1427,10 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr)
|
|||||||
ut_ad(!(lock.was_chosen_as_deadlock_victim & byte(~2U)));
|
ut_ad(!(lock.was_chosen_as_deadlock_victim & byte(~2U)));
|
||||||
lock.was_chosen_as_deadlock_victim= false;
|
lock.was_chosen_as_deadlock_victim= false;
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
|
}
|
||||||
|
|
||||||
|
void trx_t::commit_cleanup()
|
||||||
|
{
|
||||||
mutex.wr_lock();
|
mutex.wr_lock();
|
||||||
dict_operation= false;
|
dict_operation= false;
|
||||||
|
|
||||||
@@ -1452,16 +1456,19 @@ void trx_t::commit_low(mtr_t *mtr)
|
|||||||
ut_ad(!mtr == (aborted || !has_logged_or_recovered()));
|
ut_ad(!mtr == (aborted || !has_logged_or_recovered()));
|
||||||
ut_ad(!mtr || !aborted);
|
ut_ad(!mtr || !aborted);
|
||||||
|
|
||||||
/* undo_no is non-zero if we're doing the final commit. */
|
|
||||||
if (fts_trx && undo_no)
|
if (fts_trx && undo_no)
|
||||||
{
|
{
|
||||||
ut_a(!is_autocommit_non_locking());
|
ut_a(!is_autocommit_non_locking());
|
||||||
/* FTS-FIXME: Temporarily tolerate DB_DUPLICATE_KEY instead of
|
/* MDEV-24088 FIXME: Invoke fts_commit() earlier (before possible
|
||||||
dying. This is a possible scenario if there is a crash between
|
XA PREPARE), so that we will be able to return an error and rollback
|
||||||
|
the transaction, instead of violating consistency!
|
||||||
|
|
||||||
|
The original claim about DB_DUPLICATE KEY was:
|
||||||
|
This is a possible scenario if there is a crash between
|
||||||
insert to DELETED table committing and transaction committing. The
|
insert to DELETED table committing and transaction committing. The
|
||||||
fix would be able to return error from this function */
|
fix would be able to return error from this function */
|
||||||
if (dberr_t error= fts_commit(this))
|
if (ut_d(dberr_t error=) fts_commit(this))
|
||||||
ut_a(error == DB_DUPLICATE_KEY);
|
ut_ad(error == DB_DUPLICATE_KEY || error == DB_LOCK_WAIT_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
@@ -1498,7 +1505,7 @@ void trx_t::commit_low(mtr_t *mtr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void trx_t::commit()
|
void trx_t::commit_persist()
|
||||||
{
|
{
|
||||||
mtr_t *mtr= nullptr;
|
mtr_t *mtr= nullptr;
|
||||||
mtr_t local_mtr;
|
mtr_t local_mtr;
|
||||||
@@ -1511,6 +1518,15 @@ void trx_t::commit()
|
|||||||
commit_low(mtr);
|
commit_low(mtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void trx_t::commit()
|
||||||
|
{
|
||||||
|
commit_persist();
|
||||||
|
ut_d(for (const auto &p : mod_tables) ut_ad(!p.second.is_dropped()));
|
||||||
|
commit_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
Prepares a transaction for commit/rollback. */
|
Prepares a transaction for commit/rollback. */
|
||||||
void
|
void
|
||||||
|
@@ -428,8 +428,6 @@ ut_strerr(
|
|||||||
return("End of index");
|
return("End of index");
|
||||||
case DB_IO_ERROR:
|
case DB_IO_ERROR:
|
||||||
return("I/O error");
|
return("I/O error");
|
||||||
case DB_TABLE_IN_FK_CHECK:
|
|
||||||
return("Table is being used in foreign key check");
|
|
||||||
case DB_NOT_FOUND:
|
case DB_NOT_FOUND:
|
||||||
return("not found");
|
return("not found");
|
||||||
case DB_ONLINE_LOG_TOO_BIG:
|
case DB_ONLINE_LOG_TOO_BIG:
|
||||||
|
@@ -210,7 +210,6 @@ innodb_master_thread_sleeps server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL N
|
|||||||
innodb_activity_count server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Current server activity count
|
innodb_activity_count server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Current server activity count
|
||||||
innodb_master_active_loops server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times master thread performs its tasks when server is active
|
innodb_master_active_loops server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times master thread performs its tasks when server is active
|
||||||
innodb_master_idle_loops server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times master thread performs its tasks when server is idle
|
innodb_master_idle_loops server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of times master thread performs its tasks when server is idle
|
||||||
innodb_background_drop_table_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to process drop table list
|
|
||||||
innodb_log_flush_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to flush log records
|
innodb_log_flush_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to flush log records
|
||||||
innodb_dict_lru_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to process DICT LRU list
|
innodb_dict_lru_usec server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Time (in microseconds) spent to process DICT LRU list
|
||||||
innodb_dict_lru_count_active server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of tables evicted from DICT LRU list in the active loop
|
innodb_dict_lru_count_active server 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of tables evicted from DICT LRU list in the active loop
|
||||||
@@ -227,7 +226,6 @@ dml_system_inserts dml 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 s
|
|||||||
dml_system_deletes dml 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of system rows deleted
|
dml_system_deletes dml 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of system rows deleted
|
||||||
dml_system_updates dml 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of system rows updated
|
dml_system_updates dml 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 status_counter Number of system rows updated
|
||||||
ddl_background_drop_indexes ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of indexes waiting to be dropped after failed index creation
|
ddl_background_drop_indexes ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of indexes waiting to be dropped after failed index creation
|
||||||
ddl_background_drop_tables ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of tables in background drop table list
|
|
||||||
ddl_online_create_index ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of indexes being created online
|
ddl_online_create_index ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of indexes being created online
|
||||||
ddl_pending_alter_table ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of ALTER TABLE, CREATE INDEX, DROP INDEX in progress
|
ddl_pending_alter_table ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of ALTER TABLE, CREATE INDEX, DROP INDEX in progress
|
||||||
ddl_sort_file_alter_table ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of sort files created during alter table
|
ddl_sort_file_alter_table ddl 0 NULL NULL NULL 0 NULL NULL NULL NULL NULL NULL NULL 0 counter Number of sort files created during alter table
|
||||||
|
Reference in New Issue
Block a user