Skip to content

Commit 597510a

Browse files
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 3cef4f8 (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.
1 parent 5f46385 commit 597510a

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

mysql-test/suite/innodb/r/innodb-table-online.result

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,21 +446,21 @@ t1 CREATE TABLE `t1` (
446446
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=REDUNDANT
447447
SET GLOBAL innodb_monitor_disable = module_ddl;
448448
DROP TABLE t1;
449-
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
449+
CREATE TABLE t1 (a INT PRIMARY KEY, b blob) ENGINE=InnoDB;
450450
connection con1;
451451
SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL created WAIT_FOR ins';
452452
ALTER TABLE t1 FORCE;
453453
connection default;
454454
SET DEBUG_SYNC = 'now WAIT_FOR created';
455455
BEGIN;
456-
INSERT INTO t1 VALUES(1);
456+
INSERT INTO t1 VALUES(1, repeat('a', 10000));
457457
ROLLBACK;
458458
SET DEBUG_SYNC = 'now SIGNAL ins';
459459
connection con1;
460460
disconnect con1;
461461
connection default;
462462
SELECT * FROM t1;
463-
a
463+
a b
464464
DROP TABLE t1;
465465
SET DEBUG_SYNC = 'RESET';
466466
SET GLOBAL innodb_file_per_table = @global_innodb_file_per_table_orig;

mysql-test/suite/innodb/t/innodb-table-online.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ SHOW CREATE TABLE t1;
394394
SET GLOBAL innodb_monitor_disable = module_ddl;
395395
DROP TABLE t1;
396396

397-
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
397+
CREATE TABLE t1 (a INT PRIMARY KEY, b blob) ENGINE=InnoDB;
398398

399399
connection con1;
400400
SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL created WAIT_FOR ins';
@@ -403,7 +403,7 @@ send ALTER TABLE t1 FORCE;
403403
connection default;
404404
SET DEBUG_SYNC = 'now WAIT_FOR created';
405405
BEGIN;
406-
INSERT INTO t1 VALUES(1);
406+
INSERT INTO t1 VALUES(1, repeat('a', 10000));
407407
ROLLBACK;
408408
SET DEBUG_SYNC = 'now SIGNAL ins';
409409

storage/innobase/row/row0log.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,25 @@ row_log_block_free(
326326
DBUG_VOID_RETURN;
327327
}
328328

329+
/** Empty the online log.
330+
@param index index log to be cleared */
331+
static void row_log_empty(dict_index_t *index)
332+
{
333+
ut_ad(index->lock.have_s());
334+
row_log_t *log= index->online_log;
335+
336+
mysql_mutex_lock(&log->mutex);
337+
UT_DELETE(log->blobs);
338+
log->blobs= nullptr;
339+
row_log_block_free(log->tail);
340+
row_log_block_free(log->head);
341+
row_merge_file_destroy_low(log->fd);
342+
log->fd= OS_FILE_CLOSED;
343+
log->tail.total= log->tail.blocks= log->tail.bytes= 0;
344+
log->head.total= log->head.blocks= log->head.bytes= 0;
345+
mysql_mutex_unlock(&log->mutex);
346+
}
347+
329348
/******************************************************//**
330349
Logs an operation to a secondary index that is (or was) being created. */
331350
void
@@ -358,6 +377,7 @@ row_log_online_op(
358377
extra_size+1 (and reserve 0 as the end-of-chunk marker). */
359378

360379
if (!tuple) {
380+
row_log_empty(index);
361381
mrec_size = 4;
362382
extra_size = 0;
363383
size = 2;
@@ -4063,6 +4083,7 @@ row_log_apply(
40634083
static void row_log_table_empty(dict_index_t *index)
40644084
{
40654085
ut_ad(index->lock.have_s());
4086+
row_log_empty(index);
40664087
row_log_t* log= index->online_log;
40674088
ulint avail_size;
40684089
if (byte *b= row_log_table_open(log, 1, &avail_size))

0 commit comments

Comments
 (0)