Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-11985

Make innodb_read_only shutdown more robust

Details

    Description

      If InnoDB is started in innodb_read_only mode such that recovered incomplete transactions exist at startup (but the redo logs are clean), an assertion will fail at shutdown, because there would exist some non-prepared transactions.

      InnoDB: Failing assertion: UT_LIST_GET_LEN(trx_sys->rw_trx_list) == trx_sys->n_prepared_trx
      

      Repeating this bug requires two restarts after ensuring that some InnoDB redo log has been written, making some changes of an incomplete transaction durable:

      --let $restart_parameters= --innodb-force-recovery=3
      --source include/kill_and_restart_mysqld.inc
      --let $restart_parameters= --innodb-read-only
      --source include/restart_mysqld.inc
      --let $restart_parameters=
      --source include/restart_mysqld.inc
      

      Attachments

        Issue Links

          Activity

            marko Marko Mäkelä added a comment - https://github.com/MariaDB/server/commit/8b772150705d142a200805edc59365e979559020

            Code changes ok to push, please add test case for embedded server that uses UNINSTALL PLUGIN statement (actually not sure if you can do that, if not ok).

            jplindst Jan Lindström (Inactive) added a comment - Code changes ok to push, please add test case for embedded server that uses UNINSTALL PLUGIN statement (actually not sure if you can do that, if not ok).

            This issue affects 10.0 as well. The parameter innodb_read_only was introduced in 10.0.4, but there should be a shutdown hang already earlier when innodb_force_recovery=3 is used. That parameter existed already in MySQL 3.23.49, but back then, InnoDB shutdown did not wait transactions to be committed or rolled back.

            In 10.0 and 10.1, there would also be a hang on shutdown. There was a partial fix/workaround in MySQL 5.7, implemented in the function trx_sys_any_active_transactions():

            commit b7a0c7f5527647e8e3bdae9c7bbef922f8a1b5e4
            Author: Marko Mäkelä <marko.makela@oracle.com>
            Date:   Tue Apr 14 09:25:23 2015 +0300
             
                Bug#20874411 INNODB SHUTDOWN HANGS IF INNODB_FORCE_RECOVERY>=3
                SKIPPED ANY ROLLBACK
                
                trx_sys_any_active_transactions(): If any prepared ACTIVE transactions
                exist, and their rollback was prevented by innodb_force_recovery,
                convert these transactions to XA PREPARE state in the main-memory
                data structures, so that shutdown will proceed normally. These transactions
                will again recover as ACTIVE on the next restart, and they will be rolled
                back unless innodb_force_recovery>=3 again.
                
                trx_undo_fake_prepared(): An auxiliary function to set an undo log to
                PREPARED state.
            

            This work-around should be reverted from 10.2, because it is no longer necessary.

            marko Marko Mäkelä added a comment - This issue affects 10.0 as well. The parameter innodb_read_only was introduced in 10.0.4, but there should be a shutdown hang already earlier when innodb_force_recovery=3 is used. That parameter existed already in MySQL 3.23.49, but back then, InnoDB shutdown did not wait transactions to be committed or rolled back. In 10.0 and 10.1, there would also be a hang on shutdown. There was a partial fix/workaround in MySQL 5.7, implemented in the function trx_sys_any_active_transactions(): commit b7a0c7f5527647e8e3bdae9c7bbef922f8a1b5e4 Author: Marko Mäkelä <marko.makela@oracle.com> Date: Tue Apr 14 09:25:23 2015 +0300   Bug#20874411 INNODB SHUTDOWN HANGS IF INNODB_FORCE_RECOVERY>=3 SKIPPED ANY ROLLBACK trx_sys_any_active_transactions(): If any prepared ACTIVE transactions exist, and their rollback was prevented by innodb_force_recovery, convert these transactions to XA PREPARE state in the main-memory data structures, so that shutdown will proceed normally. These transactions will again recover as ACTIVE on the next restart, and they will be rolled back unless innodb_force_recovery>=3 again. trx_undo_fake_prepared(): An auxiliary function to set an undo log to PREPARED state. This work-around should be reverted from 10.2, because it is no longer necessary.
            marko Marko Mäkelä added a comment - 10.0 patch: https://github.com/MariaDB/server/commit/03ffe319b45a9dcc6efb2720f4692279ea10f4c8

            Note: The added test innodb.read_only_recovery reveals that starting with MySQL 5.7 or MariaDB Server 10.2, innodb_read_only is hard-wiring the transaction isolation level to READ UNCOMMITTED.
            Revised 10.2 patch for review:
            https://github.com/MariaDB/server/commit/eced3f1c62f6c41d0a302a07fdc70850b591319e
            The only changes since the previous commits are a comment and a SELECT added to the test, and reverting Bug#20874411.

            marko Marko Mäkelä added a comment - Note: The added test innodb.read_only_recovery reveals that starting with MySQL 5.7 or MariaDB Server 10.2, innodb_read_only is hard-wiring the transaction isolation level to READ UNCOMMITTED. Revised 10.2 patch for review: https://github.com/MariaDB/server/commit/eced3f1c62f6c41d0a302a07fdc70850b591319e The only changes since the previous commits are a comment and a SELECT added to the test, and reverting Bug#20874411.

            ok to push.

            jplindst Jan Lindström (Inactive) added a comment - ok to push.

            People

              marko Marko Mäkelä
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.