mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-24653 Assertion block->page.id.page_no() == index->page failed in innobase_add_instant_try()
We may end up with an empty leaf page (containing only an ADD COLUMN metadata record) that is not the root page. innobase_add_instant_try(): Disable an optimization for a non-canonical empty table that contains a metadata record somewhere else than in the root page. btr_pcur_store_position(): Tolerate a non-canonical empty table.
This commit is contained in:
@ -263,7 +263,6 @@ a b vb
|
|||||||
4 NULL NULL
|
4 NULL NULL
|
||||||
5 NULL NULL
|
5 NULL NULL
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
|
|
||||||
#
|
#
|
||||||
# MDEV-21045 AddressSanitizer: use-after-poison in mem_heap_dup / row_log_table_get_pk_col
|
# MDEV-21045 AddressSanitizer: use-after-poison in mem_heap_dup / row_log_table_get_pk_col
|
||||||
#
|
#
|
||||||
@ -282,3 +281,21 @@ connection default;
|
|||||||
SET DEBUG_SYNC='RESET';
|
SET DEBUG_SYNC='RESET';
|
||||||
disconnect con2;
|
disconnect con2;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# MDEV-24653 Assertion block->page.id.page_no() == index->page failed
|
||||||
|
# in innobase_add_instant_try()
|
||||||
|
#
|
||||||
|
SET @saved_limit = @@GLOBAL.innodb_limit_optimistic_insert_debug;
|
||||||
|
SET GLOBAL innodb_limit_optimistic_insert_debug = 2;
|
||||||
|
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3),(4);
|
||||||
|
ALTER TABLE t1 ADD COLUMN b INT;
|
||||||
|
DELETE FROM t1;
|
||||||
|
InnoDB 0 transactions not purged
|
||||||
|
ALTER TABLE t1 ADD COLUMN c INT;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
a b c
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit;
|
||||||
|
# End of 10.3 tests
|
||||||
|
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
|
||||||
|
@ -292,8 +292,6 @@ CHECK TABLE t1;
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-21045 AddressSanitizer: use-after-poison in mem_heap_dup / row_log_table_get_pk_col
|
--echo # MDEV-21045 AddressSanitizer: use-after-poison in mem_heap_dup / row_log_table_get_pk_col
|
||||||
--echo #
|
--echo #
|
||||||
@ -319,3 +317,26 @@ SET DEBUG_SYNC='now SIGNAL update';
|
|||||||
SET DEBUG_SYNC='RESET';
|
SET DEBUG_SYNC='RESET';
|
||||||
--disconnect con2
|
--disconnect con2
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-24653 Assertion block->page.id.page_no() == index->page failed
|
||||||
|
--echo # in innobase_add_instant_try()
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET @saved_limit = @@GLOBAL.innodb_limit_optimistic_insert_debug;
|
||||||
|
SET GLOBAL innodb_limit_optimistic_insert_debug = 2;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3),(4);
|
||||||
|
ALTER TABLE t1 ADD COLUMN b INT;
|
||||||
|
DELETE FROM t1;
|
||||||
|
--source include/wait_all_purged.inc
|
||||||
|
ALTER TABLE t1 ADD COLUMN c INT;
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET GLOBAL innodb_limit_optimistic_insert_debug = @saved_limit;
|
||||||
|
|
||||||
|
--echo # End of 10.3 tests
|
||||||
|
|
||||||
|
SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2016, 2020, MariaDB Corporation.
|
Copyright (c) 2016, 2021, 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
|
||||||
@ -128,13 +128,14 @@ btr_pcur_store_position(
|
|||||||
cursor->old_stored = true;
|
cursor->old_stored = true;
|
||||||
|
|
||||||
if (page_is_empty(block->frame)) {
|
if (page_is_empty(block->frame)) {
|
||||||
|
ut_ad(block->page.id.page_no() == index->page);
|
||||||
|
empty_table:
|
||||||
/* It must be an empty index tree; NOTE that in this case
|
/* It must be an empty index tree; NOTE that in this case
|
||||||
we do not store the modify_clock, but always do a search
|
we do not store the modify_clock, but always do a search
|
||||||
if we restore the cursor position */
|
if we restore the cursor position */
|
||||||
|
|
||||||
ut_a(!page_has_siblings(block->frame));
|
ut_a(!page_has_siblings(block->frame));
|
||||||
ut_ad(page_is_leaf(block->frame));
|
ut_ad(page_is_leaf(block->frame));
|
||||||
ut_ad(block->page.id.page_no() == index->page);
|
|
||||||
|
|
||||||
if (page_rec_is_supremum_low(offs)) {
|
if (page_rec_is_supremum_low(offs)) {
|
||||||
cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE;
|
cursor->rel_pos = BTR_PCUR_AFTER_LAST_IN_TREE;
|
||||||
@ -150,7 +151,15 @@ before_first:
|
|||||||
rec = page_rec_get_prev(rec);
|
rec = page_rec_get_prev(rec);
|
||||||
|
|
||||||
ut_ad(!page_rec_is_infimum(rec));
|
ut_ad(!page_rec_is_infimum(rec));
|
||||||
ut_ad(!rec_is_metadata(rec, index));
|
|
||||||
|
if (UNIV_UNLIKELY(rec_is_metadata(rec, index))) {
|
||||||
|
/* The table may be empty such that it only
|
||||||
|
contains a metadata record, in a leaf page
|
||||||
|
that is not the root page. */
|
||||||
|
ut_ad(index->is_primary());
|
||||||
|
ut_ad(block->page.id.page_no() != index->page);
|
||||||
|
goto empty_table;
|
||||||
|
}
|
||||||
|
|
||||||
cursor->rel_pos = BTR_PCUR_AFTER;
|
cursor->rel_pos = BTR_PCUR_AFTER;
|
||||||
} else if (page_rec_is_infimum_low(offs)) {
|
} else if (page_rec_is_infimum_low(offs)) {
|
||||||
@ -160,7 +169,9 @@ before_first:
|
|||||||
ut_ad(!page_has_prev(block->frame));
|
ut_ad(!page_has_prev(block->frame));
|
||||||
rec = page_rec_get_next(rec);
|
rec = page_rec_get_next(rec);
|
||||||
if (page_rec_is_supremum(rec)) {
|
if (page_rec_is_supremum(rec)) {
|
||||||
ut_ad(page_has_next(block->frame));
|
ut_ad(page_has_next(block->frame)
|
||||||
|
|| block->page.id.page_no()
|
||||||
|
!= index->page);
|
||||||
goto before_first;
|
goto before_first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
|
||||||
Copyright (c) 2005, 2019, Oracle and/or its affiliates. All Rights Reserved.
|
Copyright (c) 2005, 2019, Oracle and/or its affiliates. All Rights Reserved.
|
||||||
Copyright (c) 2013, 2020, MariaDB Corporation.
|
Copyright (c) 2013, 2021, 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
|
||||||
@ -4482,11 +4482,13 @@ innobase_add_instant_try(
|
|||||||
const rec_t* rec = btr_pcur_get_rec(&pcur);
|
const rec_t* rec = btr_pcur_get_rec(&pcur);
|
||||||
que_thr_t* thr = pars_complete_graph_for_exec(
|
que_thr_t* thr = pars_complete_graph_for_exec(
|
||||||
NULL, trx, ctx->heap, NULL);
|
NULL, trx, ctx->heap, NULL);
|
||||||
|
const bool is_root = block->page.id.page_no() == index->page;
|
||||||
|
|
||||||
dberr_t err;
|
dberr_t err;
|
||||||
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 (is_root
|
||||||
|
&& !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;
|
||||||
}
|
}
|
||||||
@ -4528,7 +4530,7 @@ innobase_add_instant_try(
|
|||||||
}
|
}
|
||||||
btr_pcur_close(&pcur);
|
btr_pcur_close(&pcur);
|
||||||
goto func_exit;
|
goto func_exit;
|
||||||
} else if (page_rec_is_supremum(rec)) {
|
} else if (is_root && page_rec_is_supremum(rec)) {
|
||||||
empty_table:
|
empty_table:
|
||||||
/* The table is empty. */
|
/* The table is empty. */
|
||||||
ut_ad(fil_page_index_page_check(block->frame));
|
ut_ad(fil_page_index_page_check(block->frame));
|
||||||
|
Reference in New Issue
Block a user