From 75a65d3201a4486af96cf3277b6c5a4ba460eef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 9 Jun 2021 14:23:20 +0300 Subject: [PATCH] MDEV-25886 CHECK TABLE crash with DB_MISSING_HISTORY if innodb_read_only Occasionally, the test innodb.alter_copy would fail in MariaDB 10.6.1, reporting DB_MISSING_HISTORY during CHECK TABLE. It started to occur during the development of MDEV-25180, which introduced purge_sys.stop_SYS(). If we delay purge more during DDL operations, then the test would almost always fail. The reason is that during startup we will restore a purge view, and CHECK TABLE would still use REPEATABLE READ even though innodb_read_only is set and other isolation levels than READ UNCOMMITTED are not guaranteed to work. ha_innobase::check(): Use READ UNCOMMITTED isolation level if innodb_read_only is set or innodb_force_recovery exceeds 3. dict_set_corrupted(): Do not update the persistent data dictionary if innodb_force_recovery exceeds 3. --- storage/innobase/dict/dict0dict.cc | 2 +- storage/innobase/handler/ha_innodb.cc | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 10b878c0e49..1d0e2af3cd6 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -5425,7 +5425,7 @@ dict_set_corrupted( /* If this is read only mode, do not update SYS_INDEXES, just mark it as corrupted in memory */ - if (srv_read_only_mode) { + if (high_level_read_only) { index->type |= DICT_CORRUPT; goto func_exit; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4e63edc65c2..65039919793 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -14796,10 +14796,9 @@ ha_innobase::check( /* We must run the index record counts at an isolation level >= READ COMMITTED, because a dirty read can see a wrong number - of records in some index; to play safe, we use always - REPEATABLE READ here (except when undo logs are unavailable) */ - m_prebuilt->trx->isolation_level = srv_force_recovery - >= SRV_FORCE_NO_UNDO_LOG_SCAN + of records in some index; to play safe, we normally use + REPEATABLE READ here */ + m_prebuilt->trx->isolation_level = high_level_read_only ? TRX_ISO_READ_UNCOMMITTED : TRX_ISO_REPEATABLE_READ;