Commit 93d495f3 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-15418 innodb_force_recovery=5 displays bogus warnings

With MDEV-15132 in MariaDB 10.3.5, InnoDB no longer writes the
transaction identifier to the TRX_SYS page. The information is
only written to undo log headers and sometimes rollback segment
headers. Because the setting innodb_force_recovery=5 will skip
reading any of those pages, the maximum transaction identifier
will no longer be determined.

innobase_map_isolation_level(): Always report READ UNCOMMITTED
if innodb_force_recovery has been set to 5 or more, or
innodb_read_only is set. This will avoid errors reported by
lock_check_trx_id_sanity() and ReadView::check_trx_id_sanity().

lock_clust_rec_cons_read_sees(): Do not check for
innodb_read_only, now that innobase_map_isolation_level() will
guarantee that no read view will be created or used.

row_search_mvcc(): Do not check for innodb_force_recovery<5,
now that innobase_map_isolation_level() will guarantee that
no read view will be created or used.
parent 67f6d40b
......@@ -3,7 +3,7 @@ CREATE TABLE t(a INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t VALUES(1);
BEGIN;
INSERT INTO t VALUES(2);
DELETE FROM t WHERE a=2;
UPDATE t SET a=20 WHERE a=2;
connect con2, localhost, root;
# Normal MariaDB shutdown would roll back the above transaction.
# We want the transaction to remain open, so we will kill the server
......@@ -15,7 +15,7 @@ SET DEBUG_SYNC='after_trx_committed_in_memory SIGNAL committed WAIT_FOR ever';
COMMIT;
connection default;
SET DEBUG_SYNC='now WAIT_FOR committed';
# Ensure that the above incomplete transactions become durable.
# Ensure that the above transactions become durable.
SET GLOBAL innodb_flush_log_at_trx_commit=1;
BEGIN;
INSERT INTO t VALUES(-10000);
......@@ -29,17 +29,39 @@ SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM t;
a
1
20
UPDATE t SET a=3 WHERE a=1;
# Starting with MariaDB 10.2, innodb_read_only implies READ UNCOMMITTED.
# In earlier versions, this would return the last committed version
# (empty table)!
# (only a=3; no record for a=20)!
SELECT * FROM t;
a
3
20
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM t;
a
3
20
#
# MDEV-15418 innodb_force_recovery=5 displays bogus warnings
# about too new transaction identifier
#
# With the fix, innodb_force_recovery=5 implies READ UNCOMMITTED.
SELECT * FROM t;
a
3
20
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT * FROM t;
a
3
20
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT * FROM t;
a
3
20
SELECT * FROM t;
a
3
......
......@@ -4,6 +4,13 @@
# need to restart server
--source include/not_embedded.inc
--disable_query_log
# Ignore messages from the innodb_force_recovery=5 startup.
call mtr.add_suppression("\\[ERROR\\] InnoDB: Failed to find tablespace for table `test`\\.`t` in the cache");
call mtr.add_suppression("\\[Warning\\] InnoDB: Allocated tablespace ID.* for test/t, old maximum was 0");
FLUSH TABLES;
--enable_query_log
--connect(con1, localhost, root)
CREATE TABLE t(a INT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t VALUES(1);
......@@ -11,7 +18,7 @@ BEGIN;
# Generate insert_undo log.
INSERT INTO t VALUES(2);
# Generate update_undo log.
DELETE FROM t WHERE a=2;
UPDATE t SET a=20 WHERE a=2;
--connect(con2, localhost, root)
--echo # Normal MariaDB shutdown would roll back the above transaction.
--echo # We want the transaction to remain open, so we will kill the server
......@@ -34,7 +41,7 @@ send COMMIT;
connection default;
SET DEBUG_SYNC='now WAIT_FOR committed';
--echo # Ensure that the above incomplete transactions become durable.
--echo # Ensure that the above transactions become durable.
SET GLOBAL innodb_flush_log_at_trx_commit=1;
BEGIN;
INSERT INTO t VALUES(-10000);
......@@ -54,10 +61,22 @@ UPDATE t SET a=3 WHERE a=1;
--source include/restart_mysqld.inc
--echo # Starting with MariaDB 10.2, innodb_read_only implies READ UNCOMMITTED.
--echo # In earlier versions, this would return the last committed version
--echo # (empty table)!
--echo # (only a=3; no record for a=20)!
SELECT * FROM t;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM t;
--let $restart_parameters= --innodb-force-recovery=5
--source include/restart_mysqld.inc
--echo #
--echo # MDEV-15418 innodb_force_recovery=5 displays bogus warnings
--echo # about too new transaction identifier
--echo #
--echo # With the fix, innodb_force_recovery=5 implies READ UNCOMMITTED.
SELECT * FROM t;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT * FROM t;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SELECT * FROM t;
--let $restart_parameters=
--source include/restart_mysqld.inc
SELECT * FROM t;
......
......@@ -15785,6 +15785,10 @@ innobase_map_isolation_level(
/*=========================*/
enum_tx_isolation iso) /*!< in: MySQL isolation level code */
{
if (UNIV_UNLIKELY(srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN)
|| UNIV_UNLIKELY(srv_read_only_mode)) {
return TRX_ISO_READ_UNCOMMITTED;
}
switch (iso) {
case ISO_REPEATABLE_READ: return(TRX_ISO_REPEATABLE_READ);
case ISO_READ_COMMITTED: return(TRX_ISO_READ_COMMITTED);
......
......@@ -414,9 +414,7 @@ lock_clust_rec_cons_read_sees(
transactions from different connections cannot simultaneously
operate on same temp-table and so read of temp-table is
always consistent read. */
if (srv_read_only_mode || dict_table_is_temporary(index->table)) {
ut_ad(!view->is_open()
|| dict_table_is_temporary(index->table));
if (index->table->is_temporary()) {
return(true);
}
......
......@@ -5030,10 +5030,10 @@ row_search_mvcc(
high force recovery level set, we try to avoid crashes
by skipping this lookup */
if (srv_force_recovery < 5
&& !lock_clust_rec_cons_read_sees(
if (!lock_clust_rec_cons_read_sees(
rec, index, offsets, &trx->read_view)) {
ut_ad(srv_force_recovery
< SRV_FORCE_NO_UNDO_LOG_SCAN);
rec_t* old_vers;
/* The following call returns 'offsets'
associated with 'old_vers' */
......
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