diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2021-02-04 14:23:01 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2021-02-04 16:52:43 +0530 |
commit | 69d49756cbaf4c807e58723055145deaf66dd060 (patch) | |
tree | 1169610df91559dea7c32d7f5445255541cf83bf | |
parent | 43ca6059cae8225e72fbd9495d20a6ce1c0f31b8 (diff) | |
download | mariadb-git-bb-10.6-MDEV-24781.tar.gz |
MDEV-24781 Assertion `mode == 16 || mode == 12 || fix_block->page.status != buf_page_t::FREED' failed in buf_page_get_lowbb-10.6-MDEV-24781
This is caused by commit 3cef4f8f0fc88ae5bfae4603d8d600ec84cc70a9
(MDEV-515). dict_table_t::clear() frees all the blob during
rollback of bulk insert.But online log tries to read the
freed blob while applying the log. It can be fixed if we
truncate the online log during rollback of bulk insert operation.
-rw-r--r-- | mysql-test/suite/innodb/r/innodb-table-online.result | 6 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb-table-online.test | 4 | ||||
-rw-r--r-- | storage/innobase/row/row0log.cc | 21 |
3 files changed, 26 insertions, 5 deletions
diff --git a/mysql-test/suite/innodb/r/innodb-table-online.result b/mysql-test/suite/innodb/r/innodb-table-online.result index 70c19eefd0d..42d75726615 100644 --- a/mysql-test/suite/innodb/r/innodb-table-online.result +++ b/mysql-test/suite/innodb/r/innodb-table-online.result @@ -446,21 +446,21 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT SET GLOBAL innodb_monitor_disable = module_ddl; DROP TABLE t1; -CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY, b blob) ENGINE=InnoDB; connection con1; SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL created WAIT_FOR ins'; ALTER TABLE t1 FORCE; connection default; SET DEBUG_SYNC = 'now WAIT_FOR created'; BEGIN; -INSERT INTO t1 VALUES(1); +INSERT INTO t1 VALUES(1, repeat('a', 10000)); ROLLBACK; SET DEBUG_SYNC = 'now SIGNAL ins'; connection con1; disconnect con1; connection default; SELECT * FROM t1; -a +a b DROP TABLE t1; SET DEBUG_SYNC = 'RESET'; SET GLOBAL innodb_file_per_table = @global_innodb_file_per_table_orig; diff --git a/mysql-test/suite/innodb/t/innodb-table-online.test b/mysql-test/suite/innodb/t/innodb-table-online.test index be346001953..86aa34f8c35 100644 --- a/mysql-test/suite/innodb/t/innodb-table-online.test +++ b/mysql-test/suite/innodb/t/innodb-table-online.test @@ -394,7 +394,7 @@ SHOW CREATE TABLE t1; SET GLOBAL innodb_monitor_disable = module_ddl; DROP TABLE t1; -CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +CREATE TABLE t1 (a INT PRIMARY KEY, b blob) ENGINE=InnoDB; connection con1; SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL created WAIT_FOR ins'; @@ -403,7 +403,7 @@ send ALTER TABLE t1 FORCE; connection default; SET DEBUG_SYNC = 'now WAIT_FOR created'; BEGIN; -INSERT INTO t1 VALUES(1); +INSERT INTO t1 VALUES(1, repeat('a', 10000)); ROLLBACK; SET DEBUG_SYNC = 'now SIGNAL ins'; diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 91762d13d20..aa8626e9042 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -326,6 +326,25 @@ row_log_block_free( DBUG_VOID_RETURN; } +/** Empty the online log. +@param index index log to be cleared */ +static void row_log_empty(dict_index_t *index) +{ + ut_ad(index->lock.have_s()); + row_log_t *log= index->online_log; + + mysql_mutex_lock(&log->mutex); + UT_DELETE(log->blobs); + log->blobs= NULL; + row_log_block_free(log->tail); + row_log_block_free(log->head); + row_merge_file_destroy_low(log->fd); + log->fd= OS_FILE_CLOSED; + log->tail.total= log->tail.blocks= log->tail.bytes= 0; + log->head.total= log->head.blocks= log->head.bytes= 0; + mysql_mutex_unlock(&log->mutex); +} + /******************************************************//** Logs an operation to a secondary index that is (or was) being created. */ void @@ -358,6 +377,7 @@ row_log_online_op( extra_size+1 (and reserve 0 as the end-of-chunk marker). */ if (!tuple) { + row_log_empty(index); mrec_size = 4; extra_size = 0; size = 2; @@ -4063,6 +4083,7 @@ row_log_apply( static void row_log_table_empty(dict_index_t *index) { ut_ad(index->lock.have_s()); + row_log_empty(index); row_log_t* log= index->online_log; ulint avail_size; if (byte *b= row_log_table_open(log, 1, &avail_size)) |