Merge 10.4 into 10.5

This commit is contained in:
Marko Mäkelä 2019-09-27 07:15:07 +03:00
commit 72f671ab7b
25 changed files with 161 additions and 326 deletions

View File

@ -1,7 +1,5 @@
DROP TABLE IF EXISTS t1, t2;
set @save_tmp_table_size=@@tmp_table_size; set @save_tmp_table_size=@@tmp_table_size;
set @save_max_heap_table_size=@@max_heap_table_size; set @save_max_heap_table_size=@@max_heap_table_size;
set @save_storage_engine=@@storage_engine;
set storage_engine=MYISAM; set storage_engine=MYISAM;
CREATE TABLE t1 (id INTEGER); CREATE TABLE t1 (id INTEGER);
CREATE TABLE t2 (id INTEGER); CREATE TABLE t2 (id INTEGER);
@ -126,35 +124,13 @@ DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
SET @@tmp_table_size=@save_tmp_table_size; SET @@tmp_table_size=@save_tmp_table_size;
SET @@max_heap_table_size=@save_max_heap_table_size; SET @@max_heap_table_size=@save_max_heap_table_size;
# #
# Bug mdev-4311: COUNT(DISTINCT...) requiring a file for Unique # MDEV-4311: COUNT(DISTINCT...) requiring a file for UNIQUE (bug #68749)
# (bug #68749) #
#
set @save_storage_engine=@@storage_engine;
set storage_engine=INNODB;
CREATE TABLE t1 (id INTEGER) ENGINE=InnoDB;
CREATE TABLE t2 (id INTEGER) ENGINE=InnoDB; CREATE TABLE t2 (id INTEGER) ENGINE=InnoDB;
INSERT INTO t1 (id) VALUES (1), (1), (1),(1); BEGIN;
INSERT INTO t1 (id) SELECT id FROM t1; INSERT INTO t2 SELECT b.seq FROM seq_1_to_128 a, seq_1_to_16384 b
INSERT INTO t1 (id) SELECT id FROM t1; ORDER BY b.seq*rand();
INSERT INTO t1 (id) SELECT id FROM t1;
INSERT INTO t1 (id) SELECT id FROM t1;
INSERT INTO t1 (id) SELECT id FROM t1;
INSERT INTO t1 SELECT id+1 FROM t1;
INSERT INTO t1 SELECT id+2 FROM t1;
INSERT INTO t1 SELECT id+4 FROM t1;
INSERT INTO t1 SELECT id+8 FROM t1;
INSERT INTO t1 SELECT id+16 FROM t1;
INSERT INTO t1 SELECT id+32 FROM t1;
INSERT INTO t1 SELECT id+64 FROM t1;
INSERT INTO t1 SELECT id+128 FROM t1;
INSERT INTO t1 SELECT id+256 FROM t1;
INSERT INTO t1 SELECT id+512 FROM t1;
INSERT INTO t1 SELECT id+1024 FROM t1;
INSERT INTO t1 SELECT id+2048 FROM t1;
INSERT INTO t1 SELECT id+4096 FROM t1;
INSERT INTO t1 SELECT id+8192 FROM t1;
INSERT INTO t2 SELECT id FROM t1 ORDER BY id*rand();
INSERT INTO t2 VALUE(NULL); INSERT INTO t2 VALUE(NULL);
# With default tmp_table_size / max_heap_table_size # With default tmp_table_size / max_heap_table_size
SELECT SQL_NO_CACHE count(DISTINCT id) sm FROM t2; SELECT SQL_NO_CACHE count(DISTINCT id) sm FROM t2;
@ -176,5 +152,5 @@ SET @@max_heap_table_size=@save_max_heap_table_size;
SELECT SQL_NO_CACHE count(DISTINCT id) sm FROM t2; SELECT SQL_NO_CACHE count(DISTINCT id) sm FROM t2;
sm sm
16384 16384
DROP TABLE t1,t2; COMMIT;
set storage_engine=@save_storage_engine; DROP TABLE t2;

View File

@ -4,15 +4,11 @@
--source include/big_test.inc --source include/big_test.inc
--source include/have_innodb.inc --source include/have_innodb.inc
--disable_warnings --source include/have_sequence.inc
DROP TABLE IF EXISTS t1, t2;
--enable_warnings
set @save_tmp_table_size=@@tmp_table_size; set @save_tmp_table_size=@@tmp_table_size;
set @save_max_heap_table_size=@@max_heap_table_size; set @save_max_heap_table_size=@@max_heap_table_size;
set @save_storage_engine=@@storage_engine;
# #
# Test the case when distinct values doesn't fit in memory and # Test the case when distinct values doesn't fit in memory and
# filesort is used (see uniques.cc:merge_walk) # filesort is used (see uniques.cc:merge_walk)
@ -94,39 +90,14 @@ DROP TABLE t2;
SET @@tmp_table_size=@save_tmp_table_size; SET @@tmp_table_size=@save_tmp_table_size;
SET @@max_heap_table_size=@save_max_heap_table_size; SET @@max_heap_table_size=@save_max_heap_table_size;
--echo # --echo #
--echo # Bug mdev-4311: COUNT(DISTINCT...) requiring a file for Unique --echo # MDEV-4311: COUNT(DISTINCT...) requiring a file for UNIQUE (bug #68749)
--echo # (bug #68749) --echo #
--echo #
set @save_storage_engine=@@storage_engine;
set storage_engine=INNODB;
CREATE TABLE t1 (id INTEGER) ENGINE=InnoDB;
CREATE TABLE t2 (id INTEGER) ENGINE=InnoDB; CREATE TABLE t2 (id INTEGER) ENGINE=InnoDB;
INSERT INTO t1 (id) VALUES (1), (1), (1),(1); BEGIN;
INSERT INTO t1 (id) SELECT id FROM t1; INSERT INTO t2 SELECT b.seq FROM seq_1_to_128 a, seq_1_to_16384 b
INSERT INTO t1 (id) SELECT id FROM t1; ORDER BY b.seq*rand();
INSERT INTO t1 (id) SELECT id FROM t1;
INSERT INTO t1 (id) SELECT id FROM t1;
INSERT INTO t1 (id) SELECT id FROM t1;
INSERT INTO t1 SELECT id+1 FROM t1;
INSERT INTO t1 SELECT id+2 FROM t1;
INSERT INTO t1 SELECT id+4 FROM t1;
INSERT INTO t1 SELECT id+8 FROM t1;
INSERT INTO t1 SELECT id+16 FROM t1;
INSERT INTO t1 SELECT id+32 FROM t1;
INSERT INTO t1 SELECT id+64 FROM t1;
INSERT INTO t1 SELECT id+128 FROM t1;
INSERT INTO t1 SELECT id+256 FROM t1;
INSERT INTO t1 SELECT id+512 FROM t1;
INSERT INTO t1 SELECT id+1024 FROM t1;
INSERT INTO t1 SELECT id+2048 FROM t1;
INSERT INTO t1 SELECT id+4096 FROM t1;
INSERT INTO t1 SELECT id+8192 FROM t1;
INSERT INTO t2 SELECT id FROM t1 ORDER BY id*rand();
INSERT INTO t2 VALUE(NULL); INSERT INTO t2 VALUE(NULL);
--echo # With default tmp_table_size / max_heap_table_size --echo # With default tmp_table_size / max_heap_table_size
@ -147,7 +118,6 @@ SET @@max_heap_table_size=@save_max_heap_table_size;
--echo # Back to default tmp_table_size / max_heap_table_size --echo # Back to default tmp_table_size / max_heap_table_size
SELECT SQL_NO_CACHE count(DISTINCT id) sm FROM t2; SELECT SQL_NO_CACHE count(DISTINCT id) sm FROM t2;
COMMIT;
DROP TABLE t1,t2; DROP TABLE t2;
set storage_engine=@save_storage_engine;

View File

@ -2,6 +2,10 @@
# Bug#69122 - INNODB DOESN'T REDO-LOG INSERT BUFFER MERGE # Bug#69122 - INNODB DOESN'T REDO-LOG INSERT BUFFER MERGE
# OPERATION IF IT IS DONE IN-PLACE # OPERATION IF IT IS DONE IN-PLACE
# #
call mtr.add_suppression("InnoDB: innodb_read_only prevents crash recovery");
call mtr.add_suppression("Plugin initialization aborted at srv0start\\.cc");
call mtr.add_suppression("Plugin 'InnoDB'");
FLUSH TABLES;
CREATE TABLE t1( CREATE TABLE t1(
a INT AUTO_INCREMENT PRIMARY KEY, a INT AUTO_INCREMENT PRIMARY KEY,
b CHAR(1), b CHAR(1),
@ -9,20 +13,7 @@ c INT,
INDEX(b)) INDEX(b))
ENGINE=InnoDB STATS_PERSISTENT=0; ENGINE=InnoDB STATS_PERSISTENT=0;
SET GLOBAL innodb_change_buffering_debug = 1; SET GLOBAL innodb_change_buffering_debug = 1;
INSERT INTO t1 VALUES(0,'x',1); INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_8192;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
BEGIN; BEGIN;
SELECT b FROM t1 LIMIT 3; SELECT b FROM t1 LIMIT 3;
b b
@ -38,9 +29,26 @@ SELECT b FROM t1 LIMIT 3;
ERROR HY000: Lost connection to MySQL server during query ERROR HY000: Lost connection to MySQL server during query
disconnect con1; disconnect con1;
connection default; connection default;
FOUND 1 /Wrote log record for ibuf update in place operation/ in my_restart.err FOUND 1 /Wrote log record for ibuf update in place operation/ in mysqld.1.err
# restart: --innodb-read-only
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check Error Unknown storage engine 'InnoDB'
test.t1 check error Corrupt
FOUND 1 /innodb_read_only prevents crash recovery/ in mysqld.1.err
# restart: --innodb-force-recovery=5
SELECT * FROM t1 LIMIT 1;
a b c
1 X 1
SHOW ENGINE INNODB STATUS;
Type Name Status
InnoDB insert 0, delete mark 0
SET GLOBAL innodb_fast_shutdown=0;
# restart # restart
CHECK TABLE t1; CHECK TABLE t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
SHOW ENGINE INNODB STATUS;
Type Name Status
InnoDB insert 79, delete mark 1
DROP TABLE t1; DROP TABLE t1;

View File

@ -283,3 +283,15 @@ ALTER TABLE t CHANGE COLUMN alpha a INT WITHOUT SYSTEM VERSIONING,
ALGORITHM=INSTANT; ALGORITHM=INSTANT;
DROP TABLE t; DROP TABLE t;
set @@system_versioning_alter_history = error; set @@system_versioning_alter_history = error;
#
# MDEV-20117 Assertion 0 failed in row_sel_get_clust_rec_for_mysql
#
CREATE TABLE t (b INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t SET b=1;
ALTER TABLE t ADD COLUMN a INT FIRST, ALGORITHM=INSTANT;
DELETE FROM t;
ALTER TABLE t ADD COLUMN c INT, ALGORITHM=INSTANT;
ALTER TABLE t DROP COLUMN c, ALGORITHM=INSTANT;
SELECT * FROM t;
a b
DROP TABLE t;

View File

@ -1,2 +1 @@
--log-error=$MYSQLTEST_VARDIR/tmp/my_restart.err
--innodb_buffer_pool_size=24M --innodb_buffer_pool_size=24M

View File

@ -11,6 +11,12 @@
--source include/not_valgrind.inc --source include/not_valgrind.inc
# This test is slow on buildbot. # This test is slow on buildbot.
--source include/big_test.inc --source include/big_test.inc
--source include/have_sequence.inc
call mtr.add_suppression("InnoDB: innodb_read_only prevents crash recovery");
call mtr.add_suppression("Plugin initialization aborted at srv0start\\.cc");
call mtr.add_suppression("Plugin 'InnoDB'");
FLUSH TABLES;
CREATE TABLE t1( CREATE TABLE t1(
a INT AUTO_INCREMENT PRIMARY KEY, a INT AUTO_INCREMENT PRIMARY KEY,
@ -27,25 +33,12 @@ ENGINE=InnoDB STATS_PERSISTENT=0;
# change buffering is possible, so that the change buffer will be used # change buffering is possible, so that the change buffer will be used
# whenever possible. # whenever possible.
SET GLOBAL innodb_change_buffering_debug = 1; SET GLOBAL innodb_change_buffering_debug = 1;
let SEARCH_FILE = $MYSQLTEST_VARDIR/tmp/my_restart.err; let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err;
# Create enough rows for the table, so that the change buffer will be # Create enough rows for the table, so that the change buffer will be
# used for modifying the secondary index page. There must be multiple # used for modifying the secondary index page. There must be multiple
# index pages, because changes to the root page are never buffered. # index pages, because changes to the root page are never buffered.
INSERT INTO t1 VALUES(0,'x',1); INSERT INTO t1 SELECT 0,'x',1 FROM seq_1_to_8192;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
INSERT INTO t1 SELECT 0,b,c FROM t1;
BEGIN; BEGIN;
SELECT b FROM t1 LIMIT 3; SELECT b FROM t1 LIMIT 3;
@ -63,10 +56,26 @@ SET DEBUG_DBUG='+d,crash_after_log_ibuf_upd_inplace';
SELECT b FROM t1 LIMIT 3; SELECT b FROM t1 LIMIT 3;
disconnect con1; disconnect con1;
connection default; connection default;
let SEARCH_PATTERN=Wrote log record for ibuf update in place operation; let SEARCH_PATTERN=Wrote log record for ibuf update in place operation;
--source include/search_pattern_in_file.inc --source include/search_pattern_in_file.inc
--source include/start_mysqld.inc
--let $restart_parameters= --innodb-read-only
--source include/start_mysqld.inc
CHECK TABLE t1; CHECK TABLE t1;
--source include/shutdown_mysqld.inc
let SEARCH_PATTERN=innodb_read_only prevents crash recovery;
--source include/search_pattern_in_file.inc
--let $restart_parameters= --innodb-force-recovery=5
--source include/start_mysqld.inc
SELECT * FROM t1 LIMIT 1;
replace_regex /.*operations:.* (insert.*), delete \d.*discarded .*/\1/;
SHOW ENGINE INNODB STATUS;
# Slow shutdown will not merge the changes due to innodb_force_recovery=5.
SET GLOBAL innodb_fast_shutdown=0;
--let $restart_parameters=
--source include/restart_mysqld.inc
CHECK TABLE t1;
replace_regex /.*operations:.* (insert.*), delete \d.*discarded .*/\1/;
SHOW ENGINE INNODB STATUS;
DROP TABLE t1; DROP TABLE t1;

View File

@ -20,6 +20,7 @@ SET GLOBAL innodb_fast_shutdown = 0;
--echo # Restart the server with innodb_force_recovery as 4. --echo # Restart the server with innodb_force_recovery as 4.
--let $restart_parameters= --innodb-force-recovery=4 --let $restart_parameters= --innodb-force-recovery=4
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
let $status=`SHOW ENGINE INNODB STATUS`;
select * from t1; select * from t1;
@ -59,6 +60,7 @@ show tables;
--echo # Restart the server with innodb_force_recovery as 5. --echo # Restart the server with innodb_force_recovery as 5.
--let $restart_parameters= --innodb-force-recovery=5 --let $restart_parameters= --innodb-force-recovery=5
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
let $status=`SHOW ENGINE INNODB STATUS`;
select * from t2; select * from t2;
@ -99,6 +101,7 @@ show tables;
--echo # Restart the server with innodb_force_recovery as 6. --echo # Restart the server with innodb_force_recovery as 6.
--let $restart_parameters= --innodb-force-recovery=6 --let $restart_parameters= --innodb-force-recovery=6
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
let $status=`SHOW ENGINE INNODB STATUS`;
select * from t2; select * from t2;
@ -136,6 +139,7 @@ show tables;
--echo # Restart the server with innodb_force_recovery=2 --echo # Restart the server with innodb_force_recovery=2
--let $restart_parameters= --innodb-force-recovery=2 --let $restart_parameters= --innodb-force-recovery=2
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
let $status=`SHOW ENGINE INNODB STATUS`;
select * from t2; select * from t2;
begin; begin;
@ -153,6 +157,7 @@ connection default;
--echo # Restart the server with innodb_force_recovery=3 --echo # Restart the server with innodb_force_recovery=3
--let $restart_parameters= --innodb-force-recovery=3 --let $restart_parameters= --innodb-force-recovery=3
--source include/start_mysqld.inc --source include/start_mysqld.inc
let $status=`SHOW ENGINE INNODB STATUS`;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
select * from t2; select * from t2;

View File

@ -293,3 +293,23 @@ ALTER TABLE t CHANGE COLUMN alpha a INT WITHOUT SYSTEM VERSIONING,
ALGORITHM=INSTANT; ALGORITHM=INSTANT;
DROP TABLE t; DROP TABLE t;
set @@system_versioning_alter_history = error; set @@system_versioning_alter_history = error;
--echo #
--echo # MDEV-20117 Assertion 0 failed in row_sel_get_clust_rec_for_mysql
--echo #
# This is not repeating the bug itself, but demonstrating that both
# parts of the fix are needed.
# To repeat the original bug, we should be somehow able to empty
# the table of user records while purgeable undo log records exist.
CREATE TABLE t (b INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t SET b=1;
ALTER TABLE t ADD COLUMN a INT FIRST, ALGORITHM=INSTANT;
DELETE FROM t;
ALTER TABLE t ADD COLUMN c INT, ALGORITHM=INSTANT;
# If page_cur_delete_rec() emptied the page (and wrongly reset the
# page type) during the previous ALTER TABLE, the following would hit
# an assertion failure because of root page type mismatch.
ALTER TABLE t DROP COLUMN c, ALGORITHM=INSTANT;
SELECT * FROM t;
DROP TABLE t;

View File

@ -7095,11 +7095,12 @@ void dbug_serve_apcs(THD *thd, int n_calls);
class ScopedStatementReplication class ScopedStatementReplication
{ {
public: public:
ScopedStatementReplication(THD *thd) : thd(thd) ScopedStatementReplication(THD *thd) :
{ saved_binlog_format(thd
if (thd) ? thd->set_current_stmt_binlog_format_stmt()
saved_binlog_format= thd->set_current_stmt_binlog_format_stmt(); : BINLOG_FORMAT_MIXED),
} thd(thd)
{}
~ScopedStatementReplication() ~ScopedStatementReplication()
{ {
if (thd) if (thd)
@ -7107,8 +7108,8 @@ public:
} }
private: private:
enum_binlog_format saved_binlog_format; const enum_binlog_format saved_binlog_format;
THD *thd; THD *const thd;
}; };

View File

@ -6209,8 +6209,6 @@ database_corrupted:
recv_recover_page(bpage); recv_recover_page(bpage);
} }
/* If space is being truncated then avoid ibuf operation.
During re-init we have already freed ibuf entries. */
if (uncompressed if (uncompressed
&& !recv_no_ibuf_operations && !recv_no_ibuf_operations
&& (bpage->id.space() == 0 && (bpage->id.space() == 0

View File

@ -957,87 +957,6 @@ dict_drop_index_tree(
return false; return false;
} }
/*******************************************************************//**
Recreate the index tree associated with a row in SYS_INDEXES table.
@return new root page number, or FIL_NULL on failure */
ulint
dict_recreate_index_tree(
/*=====================*/
const dict_table_t*
table, /*!< in/out: the table the index belongs to */
btr_pcur_t* pcur, /*!< in/out: persistent cursor pointing to
record in the clustered index of
SYS_INDEXES table. The cursor may be
repositioned in this call. */
mtr_t* mtr) /*!< in/out: mtr having the latch
on the record page. */
{
ut_ad(mutex_own(&dict_sys.mutex));
ut_a(!dict_table_is_comp(dict_sys.sys_indexes));
ut_ad(!table->space || table->space->id == table->space_id);
ulint len;
const rec_t* rec = btr_pcur_get_rec(pcur);
const byte* ptr = rec_get_nth_field_old(
rec, DICT_FLD__SYS_INDEXES__PAGE_NO, &len);
ut_ad(len == 4);
ut_ad(table->space_id == mach_read_from_4(
rec_get_nth_field_old(rec, DICT_FLD__SYS_INDEXES__SPACE,
&len)));
ut_ad(len == 4);
if (!table->space) {
/* It is a single table tablespae and the .ibd file is
missing: do nothing. */
ib::warn()
<< "Trying to TRUNCATE a missing .ibd file of table "
<< table->name << "!";
return(FIL_NULL);
}
ptr = rec_get_nth_field_old(rec, DICT_FLD__SYS_INDEXES__TYPE, &len);
ut_ad(len == 4);
ulint type = mach_read_from_4(ptr);
ptr = rec_get_nth_field_old(rec, DICT_FLD__SYS_INDEXES__ID, &len);
ut_ad(len == 8);
index_id_t index_id = mach_read_from_8(ptr);
/* We will need to commit the mini-transaction in order to avoid
deadlocks in the btr_create() call, because otherwise we would
be freeing and allocating pages in the same mini-transaction. */
btr_pcur_store_position(pcur, mtr);
mtr_commit(mtr);
mtr_start(mtr);
mtr->set_named_space(table->space);
btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr);
/* Find the index corresponding to this SYS_INDEXES record. */
for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes);
index != NULL;
index = UT_LIST_GET_NEXT(indexes, index)) {
if (index->id == index_id) {
ulint root_page_no = (index->type & DICT_FTS)
? FIL_NULL
: btr_create(type, table->space,
index_id, index, mtr);
index->page = unsigned(root_page_no);
return root_page_no;
}
}
ib::error() << "Failed to create index with index id " << index_id
<< " of table " << table->name;
return(FIL_NULL);
}
/*********************************************************************//** /*********************************************************************//**
Creates a table create graph. Creates a table create graph.
@return own: table create node */ @return own: table create node */

View File

@ -1873,10 +1873,8 @@ for concurrency control.
@param[in] id tablespace ID @param[in] id tablespace ID
@param[in] silent whether to silently ignore missing tablespaces @param[in] silent whether to silently ignore missing tablespaces
@return the tablespace @return the tablespace
@retval NULL if missing or being deleted or truncated */ @retval NULL if missing or being deleted */
UNIV_INTERN fil_space_t* fil_space_acquire_low(ulint id, bool silent)
fil_space_t*
fil_space_acquire_low(ulint id, bool silent)
{ {
fil_space_t* space; fil_space_t* space;
@ -2203,9 +2201,7 @@ enum fil_operation_t {
@param[in] space tablespace @param[in] space tablespace
@param[in] count number of attempts so far @param[in] count number of attempts so far
@return 0 if no operations else count + 1. */ @return 0 if no operations else count + 1. */
static static ulint fil_check_pending_ops(const fil_space_t* space, ulint count)
ulint
fil_check_pending_ops(const fil_space_t* space, ulint count)
{ {
ut_ad(mutex_own(&fil_system.mutex)); ut_ad(mutex_own(&fil_system.mutex));
@ -2216,7 +2212,7 @@ fil_check_pending_ops(const fil_space_t* space, ulint count)
if (ulint n_pending_ops = space->n_pending_ops) { if (ulint n_pending_ops = space->n_pending_ops) {
if (count > 5000) { if (count > 5000) {
ib::warn() << "Trying to close/delete/truncate" ib::warn() << "Trying to delete"
" tablespace '" << space->name " tablespace '" << space->name
<< "' but there are " << n_pending_ops << "' but there are " << n_pending_ops
<< " pending operations on it."; << " pending operations on it.";
@ -2263,7 +2259,7 @@ fil_check_pending_io(
ut_a(!(*node)->being_extended); ut_a(!(*node)->being_extended);
if (count > 1000) { if (count > 1000) {
ib::warn() << "Trying to delete/close/truncate" ib::warn() << "Trying to delete"
" tablespace '" << space->name " tablespace '" << space->name
<< "' but there are " << "' but there are "
<< space->n_pending_flushes << space->n_pending_flushes

View File

@ -931,8 +931,9 @@ RemoteDatafile::create_link_file(
prev_filepath = read_link_file(link_filepath); prev_filepath = read_link_file(link_filepath);
if (prev_filepath) { if (prev_filepath) {
/* Truncate will call this with an existing /* Truncate (starting with MySQL 5.6, probably no
link file which contains the same filepath. */ longer since MariaDB Server 10.2.19) used to call this
with an existing link file which contains the same filepath. */
bool same = !strcmp(prev_filepath, filepath); bool same = !strcmp(prev_filepath, filepath);
ut_free(prev_filepath); ut_free(prev_filepath);
if (same) { if (same) {

View File

@ -5820,7 +5820,8 @@ add_all_virtual:
dberr_t err = DB_SUCCESS; dberr_t err = DB_SUCCESS;
if (rec_is_metadata(rec, *index)) { if (rec_is_metadata(rec, *index)) {
ut_ad(page_rec_is_user_rec(rec)); ut_ad(page_rec_is_user_rec(rec));
if (!page_has_next(block->frame) if (!rec_is_alter_metadata(rec, *index)
&& !page_has_next(block->frame)
&& page_rec_is_last(rec, block->frame)) { && page_rec_is_last(rec, block->frame)) {
goto empty_table; goto empty_table;
} }

View File

@ -4609,15 +4609,10 @@ reset_bit:
ibuf_add_ops(ibuf.n_discarded_ops, dops); ibuf_add_ops(ibuf.n_discarded_ops, dops);
} }
/*********************************************************************//** /** Delete all change buffer entries for a tablespace,
Deletes all entries in the insert buffer for a given space id. This is used in DISCARD TABLESPACE, IMPORT TABLESPACE, or crash recovery.
in DISCARD TABLESPACE, IMPORT TABLESPACE, and 5.7 TRUNCATE TABLE recovery. @param[in] space missing or to-be-discarded tablespace */
NOTE: this does not update the page free bitmaps in the space. The space will void ibuf_delete_for_discarded_space(ulint space)
become CORRUPT when you call this function! */
void
ibuf_delete_for_discarded_space(
/*============================*/
ulint space) /*!< in: space id */
{ {
mem_heap_t* heap; mem_heap_t* heap;
btr_pcur_t pcur; btr_pcur_t pcur;

View File

@ -96,22 +96,6 @@ dict_create_index_tree(
dict_index_t* index, /*!< in/out: index */ dict_index_t* index, /*!< in/out: index */
const trx_t* trx); /*!< in: InnoDB transaction handle */ const trx_t* trx); /*!< in: InnoDB transaction handle */
/*******************************************************************//**
Recreate the index tree associated with a row in SYS_INDEXES table.
@return new root page number, or FIL_NULL on failure */
ulint
dict_recreate_index_tree(
/*======================*/
const dict_table_t* table, /*!< in: the table the index
belongs to */
btr_pcur_t* pcur, /*!< in/out: persistent cursor pointing
to record in the clustered index of
SYS_INDEXES table. The cursor may be
repositioned in this call. */
mtr_t* mtr); /*!< in: mtr having the latch
on the record page. The mtr may be
committed and restarted in this call. */
/** Drop the index tree associated with a row in SYS_INDEXES table. /** Drop the index tree associated with a row in SYS_INDEXES table.
@param[in,out] rec SYS_INDEXES record @param[in,out] rec SYS_INDEXES record
@param[in,out] pcur persistent cursor on rec @param[in,out] pcur persistent cursor on rec

View File

@ -910,24 +910,6 @@ inline ulint dict_table_extent_size(const dict_table_t* table)
return FSP_EXTENT_SIZE; return FSP_EXTENT_SIZE;
} }
/*********************************************************************//**
Obtain exclusive locks on all index trees of the table. This is to prevent
accessing index trees while InnoDB is updating internal metadata for
operations such as truncate tables. */
UNIV_INLINE
void
dict_table_x_lock_indexes(
/*======================*/
dict_table_t* table) /*!< in: table */
MY_ATTRIBUTE((nonnull));
/*********************************************************************//**
Release the exclusive locks on all index tree. */
UNIV_INLINE
void
dict_table_x_unlock_indexes(
/*========================*/
dict_table_t* table) /*!< in: table */
MY_ATTRIBUTE((nonnull));
/********************************************************************//** /********************************************************************//**
Checks if a column is in the ordering columns of the clustered index of a Checks if a column is in the ordering columns of the clustered index of a
table. Column prefixes are treated like whole columns. table. Column prefixes are treated like whole columns.

View File

@ -705,28 +705,6 @@ dict_tf_to_sys_tables_type(
return(type); return(type);
} }
/*********************************************************************//**
Obtain exclusive locks on all index trees of the table. This is to prevent
accessing index trees while InnoDB is updating internal metadata for
operations such as truncate tables. */
UNIV_INLINE
void
dict_table_x_lock_indexes(
/*======================*/
dict_table_t* table) /*!< in: table */
{
dict_index_t* index;
ut_ad(mutex_own(&dict_sys.mutex));
/* Loop through each index of the table and lock them */
for (index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
rw_lock_x_lock(dict_index_get_lock(index));
}
}
/*********************************************************************//** /*********************************************************************//**
Returns true if the particular FTS index in the table is still syncing Returns true if the particular FTS index in the table is still syncing
in the background, false otherwise. in the background, false otherwise.
@ -748,24 +726,6 @@ dict_fts_index_syncing(
} }
return(false); return(false);
} }
/*********************************************************************//**
Release the exclusive locks on all index tree. */
UNIV_INLINE
void
dict_table_x_unlock_indexes(
/*========================*/
dict_table_t* table) /*!< in: table */
{
dict_index_t* index;
ut_ad(mutex_own(&dict_sys.mutex));
for (index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
rw_lock_x_unlock(dict_index_get_lock(index));
}
}
/********************************************************************//** /********************************************************************//**
Gets the number of fields in the internal representation of an index, Gets the number of fields in the internal representation of an index,

View File

@ -95,18 +95,15 @@ struct fil_space_t {
/** Log sequence number of the latest MLOG_INDEX_LOAD record /** Log sequence number of the latest MLOG_INDEX_LOAD record
that was found while parsing the redo log */ that was found while parsing the redo log */
lsn_t enable_lsn; lsn_t enable_lsn;
/** set when an .ibd file is about to be deleted,
or an undo tablespace is about to be truncated.
When this is set following new ops are not allowed:
* read IO request
* ibuf merge
* file flush
Note that we can still possibly have new write operations
because we don't check this flag when doing flush batches. */
bool stop_new_ops; bool stop_new_ops;
/*!< we set this true when we start
deleting a single-table tablespace.
When this is set following new ops
are not allowed:
* read IO request
* ibuf merge
* file flush
Note that we can still possibly have
new write operations because we don't
check this flag when doing flush
batches. */
/** whether undo tablespace truncation is in progress */ /** whether undo tablespace truncation is in progress */
bool is_being_truncated; bool is_being_truncated;
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
@ -1115,10 +1112,8 @@ for concurrency control.
@param[in] id tablespace ID @param[in] id tablespace ID
@param[in] silent whether to silently ignore missing tablespaces @param[in] silent whether to silently ignore missing tablespaces
@return the tablespace @return the tablespace
@retval NULL if missing or being deleted or truncated */ @retval NULL if missing or being deleted */
UNIV_INTERN fil_space_t* fil_space_acquire_low(ulint id, bool silent)
fil_space_t*
fil_space_acquire_low(ulint id, bool silent)
MY_ATTRIBUTE((warn_unused_result)); MY_ATTRIBUTE((warn_unused_result));
/** Acquire a tablespace when it could be dropped concurrently. /** Acquire a tablespace when it could be dropped concurrently.

View File

@ -337,15 +337,11 @@ ibuf_merge_or_delete_for_page(
ulint zip_size, ulint zip_size,
bool update_ibuf_bitmap); bool update_ibuf_bitmap);
/*********************************************************************//** /** Delete all change buffer entries for a tablespace,
Deletes all entries in the insert buffer for a given space id. This is used in DISCARD TABLESPACE, IMPORT TABLESPACE, or crash recovery.
in DISCARD TABLESPACE and IMPORT TABLESPACE. @param[in] space missing or to-be-discarded tablespace */
NOTE: this does not update the page free bitmaps in the space. The space will void ibuf_delete_for_discarded_space(ulint space);
become CORRUPT when you call this function! */
void
ibuf_delete_for_discarded_space(
/*============================*/
ulint space); /*!< in: space id */
/** Contract the change buffer by reading pages to the buffer pool. /** Contract the change buffer by reading pages to the buffer pool.
@param[in] full If true, do a full contraction based @param[in] full If true, do a full contraction based
on PCT_IO(100). If false, the size of contract batch is determined on PCT_IO(100). If false, the size of contract batch is determined

View File

@ -995,9 +995,7 @@ page_create_zip(
buf_block_t* block, /*!< in/out: a buffer frame buf_block_t* block, /*!< in/out: a buffer frame
where the page is created */ where the page is created */
dict_index_t* index, /*!< in: the index of the dict_index_t* index, /*!< in: the index of the
page, or NULL when applying page */
TRUNCATE log
record during recovery */
ulint level, /*!< in: the B-tree level of ulint level, /*!< in: the B-tree level of
the page */ the page */
trx_id_t max_trx_id, /*!< in: PAGE_MAX_TRX_ID */ trx_id_t max_trx_id, /*!< in: PAGE_MAX_TRX_ID */

View File

@ -4678,12 +4678,15 @@ lock_trx_print_locks(
/** Functor to display all transactions */ /** Functor to display all transactions */
struct lock_print_info struct lock_print_info
{ {
lock_print_info(FILE* file, time_t now) : file(file), now(now) {} lock_print_info(FILE* file, time_t now) :
file(file), now(now),
purge_trx(purge_sys.query ? purge_sys.query->trx : NULL)
{}
void operator()(const trx_t* trx) const void operator()(const trx_t* trx) const
{ {
ut_ad(mutex_own(&trx_sys.mutex)); ut_ad(mutex_own(&trx_sys.mutex));
if (trx == purge_sys.query->trx) if (UNIV_UNLIKELY(trx == purge_trx))
return; return;
lock_trx_print_wait_and_mvcc_state(file, trx, now); lock_trx_print_wait_and_mvcc_state(file, trx, now);
@ -4693,6 +4696,7 @@ struct lock_print_info
FILE* const file; FILE* const file;
const time_t now; const time_t now;
const trx_t* const purge_trx;
}; };
/*********************************************************************//** /*********************************************************************//**

View File

@ -2490,7 +2490,8 @@ page_cur_delete_rec(
/* The record must not be the supremum or infimum record. */ /* The record must not be the supremum or infimum record. */
ut_ad(page_rec_is_user_rec(current_rec)); ut_ad(page_rec_is_user_rec(current_rec));
if (page_get_n_recs(page) == 1 && !recv_recovery_is_on()) { if (page_get_n_recs(page) == 1 && !recv_recovery_is_on()
&& !rec_is_alter_metadata(current_rec, *index)) {
/* Empty the page, unless we are applying the redo log /* Empty the page, unless we are applying the redo log
during crash recovery. During normal operation, the during crash recovery. During normal operation, the
page_create_empty() gets logged as one of MLOG_PAGE_CREATE, page_create_empty() gets logged as one of MLOG_PAGE_CREATE,

View File

@ -411,9 +411,7 @@ page_create_zip(
buf_block_t* block, /*!< in/out: a buffer frame buf_block_t* block, /*!< in/out: a buffer frame
where the page is created */ where the page is created */
dict_index_t* index, /*!< in: the index of the dict_index_t* index, /*!< in: the index of the
page, or NULL when applying page */
TRUNCATE log
record during recovery */
ulint level, /*!< in: the B-tree level ulint level, /*!< in: the B-tree level
of the page */ of the page */
trx_id_t max_trx_id, /*!< in: PAGE_MAX_TRX_ID */ trx_id_t max_trx_id, /*!< in: PAGE_MAX_TRX_ID */

View File

@ -1,7 +1,7 @@
/***************************************************************************** /*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation. Copyright (c) 2017, 2019, 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
@ -669,8 +669,11 @@ row_quiesce_set_state(
} }
row_mysql_lock_data_dictionary(trx); row_mysql_lock_data_dictionary(trx);
for (dict_index_t* index = dict_table_get_first_index(table);
dict_table_x_lock_indexes(table); index != NULL;
index = dict_table_get_next_index(index)) {
rw_lock_x_lock(&index->lock);
}
switch (state) { switch (state) {
case QUIESCE_START: case QUIESCE_START:
@ -687,7 +690,11 @@ row_quiesce_set_state(
table->quiesce = state; table->quiesce = state;
dict_table_x_unlock_indexes(table); for (dict_index_t* index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
rw_lock_x_unlock(&index->lock);
}
row_mysql_unlock_data_dictionary(trx); row_mysql_unlock_data_dictionary(trx);