[MDEV-13520] InnoDB attempts UPDATE with DB_TRX_ID=0 if innodb_force_recovery=3 Created: 2017-08-14  Updated: 2017-08-15  Resolved: 2017-08-15

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 10.2.7
Fix Version/s: 10.2.8

Type: Bug Priority: Major
Reporter: Marko Mäkelä Assignee: Marko Mäkelä
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Relates
relates to MDEV-13269 Upgrade tests for InnoDB undo log Closed

 Description   

InnoDB in MariaDB 10.2 fails to refuse UPDATE if the server is in read-only mode, and will hit a debug assertion failure because trx->id is 0 due to the read-only mode. This can be repeated with a slightly modified test:

diff --git a/mysql-test/suite/innodb/t/read_only_recovery.test b/mysql-test/suite/innodb/t/read_only_recovery.test
index a1a69be724b..aea676d3644 100644
--- a/mysql-test/suite/innodb/t/read_only_recovery.test
+++ b/mysql-test/suite/innodb/t/read_only_recovery.test
@@ -4,9 +4,10 @@
 
 --connect(con1, localhost, root)
 CREATE TABLE t(a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t VALUES(1);
 BEGIN;
 # Generate insert_undo log.
-INSERT INTO t VALUES(1),(2);
+INSERT INTO t VALUES(2);
 # Generate update_undo log.
 DELETE FROM t WHERE a=2;
 --connection default
@@ -27,6 +28,7 @@ ROLLBACK;
 SELECT * FROM t;
 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
 SELECT * FROM t;
+UPDATE t SET a=3 WHERE a=1;
 --let $restart_parameters= --innodb-read-only
 --source include/restart_mysqld.inc
 --echo # Starting with MariaDB 10.2, innodb_read_only implies READ UNCOMMITTED.

10.0 and 10.1 are behaving correctly:

CURRENT_TEST: innodb.read_only_recovery
mysqltest: At line 29: query 'UPDATE t SET a=3 WHERE a=1' failed: 1036: Table 't' is read only



 Comments   
Comment by Marko Mäkelä [ 2017-08-14 ]

bb-10.2-marko will continue to allow the UPDATE, and start to allow the read-write transaction creation even if innodb_force_recovery=3.

Comment by Marko Mäkelä [ 2017-08-14 ]

The behaviour change could actually have been introduced in MariaDB 10.2.7 by Do allow writes for innodb_force_recovery=2 or 3.

Comment by Jan Lindström (Inactive) [ 2017-08-15 ]

Ok to push. Can we document the force_recovery values and their actual meaning better somewhere in KB?

Comment by Marko Mäkelä [ 2017-08-15 ]

I think that we should deprecate innodb_force_recovery and replace it with something better. The option is bundling unrelated subsystems into one linear value.

Here is a short description:

innodb_force_recovery>=1 makes redo log based recovery ignore certain errors, such as missing data files or corrupted data pages. (Any redo log for affected files or pages will be skipped.)

innodb_force_recovery>=2 prevents purge from running. So, the undo logs would keep growing.

innodb_force_recovery>=3 disables the rollback of recovered transactions. It does not affect the rollback of currently active transactions.

Starting with MariaDB Server 10.2.7 write transactions are allowed with innodb_force_recovery<=3. But in that change, I forgot to change the trx_set_rw_mode(), introducing this very bug.

Starting with MariaDB Server 10.2.7, innodb_force_recovery>=3 will prevent some undo-generating background tasks from running. (These tasks could hit a lock wait due to the recovered incomplete transactions whose rollback is being prevented.)

Note: innodb_force_recovery>=4 is an invitation to corrupt the database, and should only be used as a last resort for dumping data when no backups exist.

Comment by Ian Gilfillan [ 2017-08-15 ]

I have expanded the docs at https://mariadb.com/kb/en/mariadb/xtradbinnodb-recovery-modes/ based on the above. Please take a look and let me know of any suggested changes, or go ahead and make them yourselves.

Generated at Thu Feb 08 08:06:14 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.