MDEV-24781 Assertion `mode == 16 || mode == 12 || fix_block->page.status !=...

MDEV-24781 Assertion `mode == 16 || mode == 12 || fix_block->page.status != buf_page_t::FREED' failed in buf_page_get_low

This is caused by commit 3cef4f8f
(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.
parent 5f463857
......@@ -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;
......
......@@ -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';
......
......@@ -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= nullptr;
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))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment