From 7223ec4ca79a436509a1734c8cfb082927159143 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 1 Feb 2017 16:03:57 +0530 Subject: [PATCH] Bug #25385590 DROP TABLE CRASHES IF INNODB_FORCE_RECOVERY > 4 Problem: ======== - Drop table assert if innodb_force_recovery is set to 5 or 6. For innodb_force_recovery 5 and 6, InnoDB doesn't scan the undo log and it makes the redo rollback segment as NULL. There is no way for transaction to write any undo log. - If innodb_force_recovery is set to 6 then InnoDB does not do the redo log roll-forward in connection with recovery. In this case, log_sys will be initalized only and it will not have latest checkpoint information. Checkpoint is done during shutdown even innodb_force_recovery is set to 6. So it leads to incorrect information update in checkpoint header. Solution: ======== 1) Allow drop table only if innodb_force_recovery < 5. 2) Make innodb as read-only if innodb_force_recovery is set to 6. 3) During shutdown, remove the checkpoint if innodb_force_recovery is set to 6. Reviewed-by: Jimmy Yang RB: 15075 --- storage/innobase/handler/ha_innodb.cc | 3 ++- storage/innobase/srv/srv0start.cc | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index af1793d1920..60528e2e3ec 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -13797,7 +13797,8 @@ ha_innobase::delete_table( extension, in contrast to ::create */ normalize_table_name(norm_name, name); - if (srv_read_only_mode) { + if (srv_read_only_mode + || srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) { DBUG_RETURN(HA_ERR_TABLE_READONLY); } diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 3ef937c303d..6d153ff1bc6 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1442,6 +1442,10 @@ innobase_start_or_create_for_mysql(void) size_t dirnamelen; unsigned i = 0; + if (srv_force_recovery == SRV_FORCE_NO_LOG_REDO) { + srv_read_only_mode = true; + } + high_level_read_only = srv_read_only_mode || srv_force_recovery > SRV_FORCE_NO_TRX_UNDO;