Details

    Description

      InnoDB maintains an internal persistent sequence of transaction identifiers. This sequence is used for assigning both transaction start identifiers (DB_TRX_ID=trx->id) and end identifiers (trx->no) as well as end identifiers for the mysql.transaction_registry table that was introduced in MDEV-12894.

      Every 256th update of the sequence would cause a write to the TRX_SYS page. We can completely avoid accessing the TRX_SYS page if we modify the InnoDB startup so that resurrecting the sequence from other pages of the transaction system.

      It turns out that startup is not reading the undo log pages of of committed transactions. In order not to cause additional page accesses on startup, we must persist trx_sys.get_max_trx_id() in the rollback segment header pages. On startup, we will simply pick up the maximum value. This page format change will be identified by repurposing an existing field TRX_RSEG_MAX_SIZE and writing it as zero. This change has the convenient side effect that after a downgrade to an older version of MariaDB and MySQL, no transactions can be created.

      On transaction commit, we will still write some binlog and Galera WSREP XID information to the TRX_SYS page. If these features are disabled, the TRX_SYS page will not be accessed at all outside server startup or undo log tablespace truncation.

      Attachments

        Issue Links

          Activity

            An initial set of patches is available at bb-10.3-armed.

            marko Marko Mäkelä added a comment - An initial set of patches is available at bb-10.3-armed .

            Pushed to 10.3. Buildbot showed one related test failure, which I repeated locally:

            ./mtr --mem --no-reorder innodb.read_only_recovery innodb.recovery_shutdown
            

            Version: '10.3.5-MariaDB-debug-log'  socket: '/mariadb/10.3m/build/mysql-test/var/tmp/mysqld.1.sock'  port: 16000  Source distribution
            2018-01-31  9:01:32 0 [Note] InnoDB: Rollback of trx with id 0 completed
            2018-01-31 09:01:32 0x7facac545700  InnoDB: Assertion failure in file /mariadb/10.3m/storage/innobase/trx/trx0purge.cc line 155
            InnoDB: Failing assertion: purge_sys->iter.trx_no <= purge_sys->rseg->last_trx_no
            

            The fix was to restore some code that I did have at some point of the development but had inadvertently removed:

            diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
            index 4b8578b61e8..2e6078bd2f6 100644
            --- a/storage/innobase/trx/trx0undo.cc
            +++ b/storage/innobase/trx/trx0undo.cc
            @@ -1113,7 +1113,12 @@ trx_undo_mem_create_at_db_start(trx_rseg_t* rseg, ulint id, ulint page_no,
             		xid.null();
             	}
             
            -	trx_id_t trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_ID);
            +	trx_id_t trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_NO);
            +	if (trx_id > max_trx_id) {
            +		max_trx_id = trx_id;
            +	}
            +
            +	trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_ID);
             	if (trx_id > max_trx_id) {
             		max_trx_id = trx_id;
             	}
            

            In the above output, the message InnoDB: Rollback of trx with id 0 completed is unrelated to my changes (I tested with an earlier revision). It should be fixed to disclose the actual transaction ID.

            marko Marko Mäkelä added a comment - Pushed to 10.3. Buildbot showed one related test failure, which I repeated locally: ./mtr --mem --no-reorder innodb.read_only_recovery innodb.recovery_shutdown Version: '10.3.5-MariaDB-debug-log' socket: '/mariadb/10.3m/build/mysql-test/var/tmp/mysqld.1.sock' port: 16000 Source distribution 2018-01-31 9:01:32 0 [Note] InnoDB: Rollback of trx with id 0 completed 2018-01-31 09:01:32 0x7facac545700 InnoDB: Assertion failure in file /mariadb/10.3m/storage/innobase/trx/trx0purge.cc line 155 InnoDB: Failing assertion: purge_sys->iter.trx_no <= purge_sys->rseg->last_trx_no The fix was to restore some code that I did have at some point of the development but had inadvertently removed: diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc index 4b8578b61e8..2e6078bd2f6 100644 --- a/storage/innobase/trx/trx0undo.cc +++ b/storage/innobase/trx/trx0undo.cc @@ -1113,7 +1113,12 @@ trx_undo_mem_create_at_db_start(trx_rseg_t* rseg, ulint id, ulint page_no, xid.null(); } - trx_id_t trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_ID); + trx_id_t trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_NO); + if (trx_id > max_trx_id) { + max_trx_id = trx_id; + } + + trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_ID); if (trx_id > max_trx_id) { max_trx_id = trx_id; } In the above output, the message InnoDB: Rollback of trx with id 0 completed is unrelated to my changes (I tested with an earlier revision ). It should be fixed to disclose the actual transaction ID.

            Filed and fixed: MDEV-15143 InnoDB: Rollback of trx with id 0 completed

            marko Marko Mäkelä added a comment - Filed and fixed: MDEV-15143 InnoDB: Rollback of trx with id 0 completed

            People

              marko Marko Mäkelä
              marko Marko Mäkelä
              Votes:
              0 Vote for this issue
              Watchers:
              3 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.