diff options
-rw-r--r-- | mysql-test/suite/innodb_zip/r/recover.result | 17 | ||||
-rw-r--r-- | mysql-test/suite/innodb_zip/t/recover.test | 16 | ||||
-rw-r--r-- | storage/innobase/btr/btr0cur.cc | 23 |
3 files changed, 47 insertions, 9 deletions
diff --git a/mysql-test/suite/innodb_zip/r/recover.result b/mysql-test/suite/innodb_zip/r/recover.result index b7452655268..fddb070538d 100644 --- a/mysql-test/suite/innodb_zip/r/recover.result +++ b/mysql-test/suite/innodb_zip/r/recover.result @@ -1,3 +1,14 @@ +FLUSH TABLES; +# +# MDEV-21892 Assertion 'index != clust_index || row_get_rec_trx_id()' +# +connect con1,localhost,root; +CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +INSERT INTO t1 VALUES (1),(2); +BEGIN; +UPDATE t1 SET pk=1; +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +connection default; # # MDEV-12720 recovery fails with "Generic error" # for ROW_FORMAT=compressed @@ -12,6 +23,12 @@ insert into a select null, uuid() from a a, a b, a c; SET GLOBAL innodb_flush_log_at_trx_commit=1; COMMIT; # restart +disconnect con1; +SELECT * FROM t1; +pk +1 +2 +DROP TABLE t1; SELECT COUNT(*) from a; COUNT(*) 1010 diff --git a/mysql-test/suite/innodb_zip/t/recover.test b/mysql-test/suite/innodb_zip/t/recover.test index f32ff3d3783..194ef10a8ef 100644 --- a/mysql-test/suite/innodb_zip/t/recover.test +++ b/mysql-test/suite/innodb_zip/t/recover.test @@ -1,12 +1,21 @@ --source include/innodb_page_size_small.inc --source include/not_embedded.inc ---disable_query_log # This test kills the server, which could corrupt some mysql.* tables # that are not created with ENGINE=InnoDB. # Flush any non-InnoDB tables to prevent that from happening. FLUSH TABLES; ---enable_query_log + +--echo # +--echo # MDEV-21892 Assertion 'index != clust_index || row_get_rec_trx_id()' +--echo # +connect (con1,localhost,root); +CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB ROW_FORMAT=COMPRESSED; +INSERT INTO t1 VALUES (1),(2); +BEGIN; +--error ER_DUP_ENTRY +UPDATE t1 SET pk=1; +connection default; --echo # --echo # MDEV-12720 recovery fails with "Generic error" @@ -25,6 +34,9 @@ COMMIT; --let $shutdown_timeout=0 --source include/restart_mysqld.inc +disconnect con1; +SELECT * FROM t1; +DROP TABLE t1; SELECT COUNT(*) from a; DROP TABLE a; diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index fbb2fbe9b5d..7e9be0c1a92 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -4110,16 +4110,25 @@ void btr_cur_upd_rec_in_place(rec_t *rec, const dict_index_t *index, } #endif /* UNIV_DEBUG */ - byte* info_bits = &rec[rec_offs_comp(offsets) - ? -REC_NEW_INFO_BITS - : -REC_OLD_INFO_BITS]; - compile_time_assert(REC_INFO_BITS_SHIFT == 0); - if ((*info_bits & REC_INFO_BITS_MASK) == update->info_bits) { - } else if (UNIV_LIKELY_NULL(block->page.zip.data)) { + static_assert(REC_INFO_BITS_SHIFT == 0, "compatibility"); + if (UNIV_LIKELY_NULL(block->page.zip.data)) { + ut_ad(rec_offs_comp(offsets)); + byte* info_bits = &rec[-REC_NEW_INFO_BITS]; + const bool flip_del_mark = (*info_bits ^ update->info_bits) + & REC_INFO_DELETED_FLAG; *info_bits &= ~REC_INFO_BITS_MASK; *info_bits |= update->info_bits; + + if (flip_del_mark) { + page_zip_rec_set_deleted(block, rec, update->info_bits + & REC_INFO_DELETED_FLAG, mtr); + } } else { - mtr->write<1>(*block, info_bits, + byte* info_bits = &rec[rec_offs_comp(offsets) + ? -REC_NEW_INFO_BITS + : -REC_OLD_INFO_BITS]; + + mtr->write<1,mtr_t::OPT>(*block, info_bits, (*info_bits & ~REC_INFO_BITS_MASK) | update->info_bits); } |