summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2021-02-04 14:23:01 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2021-02-04 16:52:43 +0530
commit69d49756cbaf4c807e58723055145deaf66dd060 (patch)
tree1169610df91559dea7c32d7f5445255541cf83bf
parent43ca6059cae8225e72fbd9495d20a6ce1c0f31b8 (diff)
downloadmariadb-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.result6
-rw-r--r--mysql-test/suite/innodb/t/innodb-table-online.test4
-rw-r--r--storage/innobase/row/row0log.cc21
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))