Commit 655f78a2 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-18322 Assertion "wrong page type" on instant ALTER TABLE

row_ins_clust_index_entry_low(): Invoke btr_set_instant() in the same
mini-transaction that has successfully inserted the metadata record.
In this way, if inserting the metadata record fails before any
undo log record was written for it, the index root page will remain
consistent.

innobase_instant_try(): Remove the btr_set_instant() call.

This is a 10.6 version of c17aca2f.

Tested by: Matthias Leich
Reviewed by: Thirunarayanan Balathandayuthapani
parent f21a6cbf
......@@ -493,6 +493,30 @@ DROP TABLE t1;
CREATE TABLE t1 (i int AS (0) STORED, j INT) ENGINE=InnoDB;
ALTER TABLE t1 ADD COLUMN i INT GENERATED ALWAYS AS (1), DROP COLUMN i;
DROP TABLE t1;
#
# MDEV-18322 Assertion "wrong_page_type" on instant ALTER
#
BEGIN NOT ATOMIC
DECLARE c TEXT
DEFAULT(SELECT CONCAT('CREATE TABLE t1 (c',
GROUP_CONCAT(seq SEPARATOR ' CHAR(200), c'),
' CHAR(211)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT')
FROM seq_1_to_40);
EXECUTE IMMEDIATE c;
END;
$$
INSERT INTO t1 SET c1=NULL;
ALTER TABLE t1 ADD c41 INT FIRST;
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8123. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
ALTER TABLE t1 ADD c41 INT FIRST;
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8123. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
SELECT COUNT(*) FROM t1;
COUNT(*)
1
DROP TABLE t1;
# End of 10.4 tests
SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
# End of 10.6 tests
--source include/have_innodb.inc
--source include/have_sequence.inc
SET @save_stats_persistent = @@GLOBAL.innodb_stats_persistent;
SET GLOBAL innodb_stats_persistent = 0;
......@@ -529,6 +530,30 @@ CREATE TABLE t1 (i int AS (0) STORED, j INT) ENGINE=InnoDB;
ALTER TABLE t1 ADD COLUMN i INT GENERATED ALWAYS AS (1), DROP COLUMN i;
DROP TABLE t1;
--echo #
--echo # MDEV-18322 Assertion "wrong_page_type" on instant ALTER
--echo #
DELIMITER $$;
BEGIN NOT ATOMIC
DECLARE c TEXT
DEFAULT(SELECT CONCAT('CREATE TABLE t1 (c',
GROUP_CONCAT(seq SEPARATOR ' CHAR(200), c'),
' CHAR(211)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT')
FROM seq_1_to_40);
EXECUTE IMMEDIATE c;
END;
$$
DELIMITER ;$$
INSERT INTO t1 SET c1=NULL;
--error ER_TOO_BIG_ROWSIZE
ALTER TABLE t1 ADD c41 INT FIRST;
--error ER_TOO_BIG_ROWSIZE
ALTER TABLE t1 ADD c41 INT FIRST;
CHECK TABLE t1;
SELECT COUNT(*) FROM t1;
DROP TABLE t1;
--echo # End of 10.4 tests
SET GLOBAL innodb_stats_persistent = @save_stats_persistent;
......
......@@ -6201,24 +6201,20 @@ static bool innobase_instant_try(
/* Convert the table to the instant ALTER TABLE format. */
mtr.commit();
mtr.start();
index->set_modified(mtr);
if (buf_block_t* root = btr_root_block_get(index, RW_SX_LATCH, &mtr,
if (buf_block_t* root = btr_root_block_get(index, RW_S_LATCH, &mtr,
&err)) {
if (fil_page_get_type(root->page.frame) != FIL_PAGE_INDEX) {
DBUG_ASSERT("wrong page type" == 0);
err = DB_CORRUPTION;
goto func_exit;
}
btr_set_instant(root, *index, &mtr);
mtr.commit();
mtr.start();
index->set_modified(mtr);
err = row_ins_clust_index_entry_low(
BTR_NO_LOCKING_FLAG, BTR_MODIFY_TREE, index,
index->n_uniq, entry, 0, thr);
}
mtr.commit();
mtr.start();
err = row_ins_clust_index_entry_low(
BTR_NO_LOCKING_FLAG, BTR_MODIFY_TREE, index,
index->n_uniq, entry, 0, thr);
goto func_exit;
}
......
......@@ -2634,14 +2634,17 @@ row_ins_clust_index_entry_low(
ut_ad(!dict_index_is_online_ddl(index));
ut_ad(!index->table->persistent_autoinc);
ut_ad(!index->is_instant());
ut_ad(!entry->info_bits);
mtr.set_log_mode(MTR_LOG_NO_REDO);
} else {
index->set_modified(mtr);
if (UNIV_UNLIKELY(entry->is_metadata())) {
if (UNIV_UNLIKELY(entry->info_bits != 0)) {
ut_ad(entry->is_metadata());
ut_ad(index->is_instant());
ut_ad(!dict_index_is_online_ddl(index));
ut_ad(mode == BTR_MODIFY_TREE);
ut_ad(flags == BTR_NO_LOCKING_FLAG);
} else {
if (mode == BTR_MODIFY_LEAF
&& dict_index_is_online_ddl(index)) {
......@@ -2766,11 +2769,6 @@ row_ins_clust_index_entry_low(
skip_bulk_insert:
if (UNIV_UNLIKELY(entry->info_bits != 0)) {
ut_ad(entry->is_metadata());
ut_ad(flags == BTR_NO_LOCKING_FLAG);
ut_ad(index->is_instant());
ut_ad(!dict_index_is_online_ddl(index));
const rec_t* rec = btr_pcur_get_rec(&pcur);
if (rec_get_info_bits(rec, page_rec_is_comp(rec))
......@@ -2874,9 +2872,20 @@ row_ins_clust_index_entry_low(
}
}
if (err == DB_SUCCESS && entry->info_bits) {
if (buf_block_t* root
= btr_root_block_get(index, RW_X_LATCH, &mtr,
&err)) {
btr_set_instant(root, *index, &mtr);
} else {
ut_ad("cannot find root page" == 0);
}
}
mtr.commit();
if (big_rec) {
ut_ad(err == DB_SUCCESS);
/* Online table rebuild could read (and
ignore) the incomplete record at this point.
If online rebuild is in progress, the
......
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