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

xtrabackup_binlog_info (10.6) or mariadb_backup_binlog_info (11.4) gets the sequence number incorrect when active table is ENGINE=ARIA

Details

    Description

      Tested on: 10.6.19-15 Enterprise (consistent), 10.6.19 Community (consistent), 11.4.5 Community (consistent)

      • You will need 3 instances to make this occur: Master (db1) / Slave (db2) / Slave (db3)
      • The backup is taken on the SLAVE that is running, but after restore on the other slave, replication is connected to master.
      • If inserts on the master are slowed down to one per second, this failure does not occur and checksum table shows that tables are perfect copies.
      • If the table is ENGINE=INNODB the failure will not occur.

      On master, create a table:

      Drop schema if exists Rpa; Create schema Rpa; Use Rpa;
      DROP TABLE IF EXISTS `aria_table`;
      CREATE TABLE `aria_table` (
        `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
        `message` longtext NOT NULL, `createdOn` datetime NOT NULL DEFAULT current_timestamp(),
        `processId` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_svax` (`processId`)
      ) ENGINE=ARIA AUTO_INCREMENT=7295 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci PAGE_CHECKSUM=1;
      

      On master, run a bash script that quickly inserts into the aria_table:

      #!/bin/bash
      touch t.txt
      mariadb -Ae "truncate table Rpa.aria_table;"
      ii=0
      while [ -f t.txt ]; do
       ii=$(( $ii + 1 ))
        mariadb -Ae "use Rpa; INSERT INTO aria_table ( message, createdOn, processId) VALUES ( 'Lorem ipsum dolor sit amet, et pharetra nulla tincidunt.', now(), round(rand()*10000000));"
      echo $ii
      done
      echo "finished"
      

      Verify that db2 is a slave of db1 and that the slave is running.

      On db3, stop server, destroy the data:

      systemctl stop mariadb
      datadir=/var/lib/mysql
      logdir=/var/log/mysql 
      rm -fr $datadir/*  $logdir/*  
      

      On db2, use mariabackup to stream a backup into the datadir of db3:

      datadir=/var/lib/mysql  
      replica=192.168.8.113
      mariabackup --user=root --backup --stream=xbstream | ssh -o StrictHostKeyChecking=NO root@"$replica" -t "cd $datadir; mbstream  -x"
      

      On db3, set the replication to db1

      mhost=db1.edw.ee 
      datadir=/var/lib/mysql
      logdir=/var/log/mysql
      mport=3306
      mpw=password
      muser=repl
       
      # Test the connectivity from this replica node to the primary:
      mariadb -h$mhost -u$muser -p$mpw -ABNe "select now(); select @@hostname;"
       
      cd $datadir
       
      gtid=$(cat $datadir/*_binlog_info | tail -1 | awk '{print $3}')
      echo $gtid $mhost $mport $muser $mpw
       
      mariabackup --prepare --target-dir=$datadir
       
      chown -R mysql:mysql $datadir
      chown -R mysql:mysql $logdir
       
      systemctl start mariadb;
       
      mariadb -ABNe "stop slave; reset slave; set global gtid_slave_pos='$gtid'; change master to master_host='$mhost', master_port=$mport, master_user='$muser', master_password='$mpw', master_use_gtid=slave_pos; start slave;"
       
      mariadb -Ae "show replica status\G"
      

      ERROR OCCURS!

      Last_SQL_Error: Error 'Duplicate entry '9699' for key 'PRIMARY'' on query. Default database: 'Rpa'. Query: 'INSERT INTO aria_table ( message, createdOn, processId) VALUES ( 'Lorem ipsum dolor sit amet, et pharetra nulla tincidunt.', now(), round(rand()*10000000))'
      

      Attachments

        Activity

          susil.behera Susil Behera added a comment -

          So, the problem is with mariabackup --stream=xbstream only. Normal backup works fine.

          susil.behera Susil Behera added a comment - So, the problem is with mariabackup --stream=xbstream only. Normal backup works fine.
          susil.behera Susil Behera added a comment -

          julien.fritschAfter I confirmed the issue locally I thought you (I mean product manager) would be the one who would take it further. I think I'm wrong here, so I'm assigning this to my dev lead bnestere.

          susil.behera Susil Behera added a comment - julien.fritsch After I confirmed the issue locally I thought you (I mean product manager) would be the one who would take it further. I think I'm wrong here, so I'm assigning this to my dev lead bnestere .

          I've found out the issue here. It pertains to the online backup feature, which Aria supports when the table both 1) is transactional and 2) uses page_checksum=1).

          To explain, first, there is a backup lock which mariabackup takes when saving the state of the server. This will prevent transactions from updating tables which aren't configured for online backup.

          Then, when the slave is replicating events, in-addition to re-executing the regular transactions as they occurred on the master, it also updates another table pertaining to the slave state, mysql.gtid_slave_pos.

          If the mysql.gtid_slave_pos table is not configured for online backup, then the state of the replica will be inconsistent during the backup. That is, the update to the regular tables targeted by the replicated transaction will proceed; however, the slave will get stuck at commit-time, as it won't be able to lock mysql.gtid_slave_pos, as the backup lock is already taken by mariabackup, and mysql.gtid_slave_pos isn't configured for online backup.

          To figure out: should Aria engine support online backup on a replica? I think even if mysql.gtid_slave_pos would be configured to be transactional and use page_checksum=1, I think there would still be a race condition in-between these updates, where mariabackup could still backup new transaction data, while reading an out-dated GTID to restore replication at.

          bnestere Brandon Nesterenko added a comment - I've found out the issue here. It pertains to the online backup feature, which Aria supports when the table both 1) is transactional and 2) uses page_checksum=1 ). To explain, first, there is a backup lock which mariabackup takes when saving the state of the server. This will prevent transactions from updating tables which aren't configured for online backup. Then, when the slave is replicating events, in-addition to re-executing the regular transactions as they occurred on the master, it also updates another table pertaining to the slave state, mysql.gtid_slave_pos . If the mysql.gtid_slave_pos table is not configured for online backup, then the state of the replica will be inconsistent during the backup. That is, the update to the regular tables targeted by the replicated transaction will proceed; however, the slave will get stuck at commit-time, as it won't be able to lock mysql.gtid_slave_pos , as the backup lock is already taken by mariabackup, and mysql.gtid_slave_pos isn't configured for online backup. To figure out: should Aria engine support online backup on a replica? I think even if mysql.gtid_slave_pos would be configured to be transactional and use page_checksum=1 , I think there would still be a race condition in-between these updates, where mariabackup could still backup new transaction data, while reading an out-dated GTID to restore replication at.
          bnestere Brandon Nesterenko added a comment - - edited

          Re-assigning to monty, as he wants to fix the issue.

          A couple notes from our discussion for inspiration to a fix:

          Fix should be either
          1) everything done in Aria in 1 commit, or
          2) or a transaction that continues so the gtid_slave_pos can be updated.

          Note too, look at how InnoDB does this for inspiration.

          And an MTR test which simplifies the issue:

          #
          #   This test shows that mariabackup can take an inconsistent backup of a slave
          # while replicating transactions from Aria tables configured to use online
          # backup (page_checksum=1 and transactional=1). This is because the slave adds
          # an extra implicit part of the transaction to also update the
          # mysql.gtid_slave_pos table separately. When the BACKUP_COMMIT lock is taken,
          # the updates to the replicated Aria table with online backup are allowed to
          # proceed, but then the slave hangs when trying to update mysql.gtid_slave_pos.
          #
          #   Note the test doesn't actually use mariabackup, but rather, emulates its
          # locking behavior using the backup staging commands manually.
          #
          # References:
          #   MDEV-36143: xbstream gets the sequence number incorrect when active table
          #               is ENGINE=ARIA
          #
           
          --source include/have_innodb.inc
          --source include/have_binlog_format_row.inc
          --source include/master-slave.inc
           
          --echo #
          --echo # Initialize test schema
          --connection master
          CREATE TABLE t1 (a int) ENGINE=ARIA TRANSACTIONAL=1 PAGE_CHECKSUM=1;
          --source include/save_master_gtid.inc
           
          --echo #
          --echo # Slave: Take BLOCK_COMMIT backup lock on slave
          --connect(extra_slave,127.0.0.1,root,,test,$SLAVE_MYPORT)
          --connection extra_slave
          backup stage start;
          backup stage flush;
          backup stage block_ddl;
          backup stage block_commit;
           
          --echo #
          --echo # Master: Insert into aria table
          --connection master
          INSERT INTO t1 VALUES (1);
          --let $master_gtid= `SELECT @@global.gtid_binlog_pos`
           
          --echo #
          --echo # Wait for slave to start replicating transaction
          --connection slave
           
          --let $wait_condition= select count(*)=1 from test.t1;
          --source include/wait_condition.inc
           
          --echo # Validating slave state..
          --let $slave_gtid= `SELECT @@global.gtid_slave_pos`
          if (`SELECT strcmp("$master_gtid","$slave_gtid")`)
          {
           
            --echo # The following transaction was replicated on the slave after BLOCK_COMMIT backup lock was taken
            select * from t1;
           
            --echo # Yet the GTID state could not update
            --echo # GTID for the transaction: $master_gtid
            --echo # Slave state GTID: $slave_gtid
           
            --echo # Slave state inconsistent on backup: BLOCK_COMMIT backup lock was taken on running slave before running a transaction, yet a partial transaction was allowed through
            --echo # Mariabackup would create an invalid slave when restoring the backup taken at this point
            --die Slave state inconsistent on backup: BLOCK_COMMIT backup lock was taken on running slave before running a transaction, yet a partial transaction was allowed through
          }
           
          --connection extra_slave
          backup stage end;
           
          --echo #
          --echo # Cleanup
          --connection master
          drop table t1;
          --source include/save_master_gtid.inc
          --connection slave
          --source include/sync_with_master_gtid.inc
           
          --source include/rpl_end.inc
          --echo # End of test
          
          

          Also, updating the remaining time to 4h per Monty's request.

          bnestere Brandon Nesterenko added a comment - - edited Re-assigning to monty , as he wants to fix the issue. A couple notes from our discussion for inspiration to a fix: Fix should be either 1) everything done in Aria in 1 commit, or 2) or a transaction that continues so the gtid_slave_pos can be updated. Note too, look at how InnoDB does this for inspiration. And an MTR test which simplifies the issue: # # This test shows that mariabackup can take an inconsistent backup of a slave # while replicating transactions from Aria tables configured to use online # backup (page_checksum=1 and transactional=1). This is because the slave adds # an extra implicit part of the transaction to also update the # mysql.gtid_slave_pos table separately. When the BACKUP_COMMIT lock is taken, # the updates to the replicated Aria table with online backup are allowed to # proceed, but then the slave hangs when trying to update mysql.gtid_slave_pos. # # Note the test doesn't actually use mariabackup, but rather, emulates its # locking behavior using the backup staging commands manually. # # References: # MDEV-36143: xbstream gets the sequence number incorrect when active table # is ENGINE=ARIA #   --source include/have_innodb.inc --source include/have_binlog_format_row.inc --source include/master-slave.inc   --echo # --echo # Initialize test schema --connection master CREATE TABLE t1 (a int) ENGINE=ARIA TRANSACTIONAL=1 PAGE_CHECKSUM=1; --source include/save_master_gtid.inc   --echo # --echo # Slave: Take BLOCK_COMMIT backup lock on slave --connect(extra_slave,127.0.0.1,root,,test,$SLAVE_MYPORT) --connection extra_slave backup stage start; backup stage flush; backup stage block_ddl; backup stage block_commit;   --echo # --echo # Master: Insert into aria table --connection master INSERT INTO t1 VALUES (1); --let $master_gtid= `SELECT @@global.gtid_binlog_pos`   --echo # --echo # Wait for slave to start replicating transaction --connection slave   --let $wait_condition= select count(*)=1 from test.t1; --source include/wait_condition.inc   --echo # Validating slave state.. --let $slave_gtid= `SELECT @@global.gtid_slave_pos` if (`SELECT strcmp("$master_gtid","$slave_gtid")`) {   --echo # The following transaction was replicated on the slave after BLOCK_COMMIT backup lock was taken select * from t1;   --echo # Yet the GTID state could not update --echo # GTID for the transaction: $master_gtid --echo # Slave state GTID: $slave_gtid   --echo # Slave state inconsistent on backup: BLOCK_COMMIT backup lock was taken on running slave before running a transaction, yet a partial transaction was allowed through --echo # Mariabackup would create an invalid slave when restoring the backup taken at this point --die Slave state inconsistent on backup: BLOCK_COMMIT backup lock was taken on running slave before running a transaction, yet a partial transaction was allowed through }   --connection extra_slave backup stage end;   --echo # --echo # Cleanup --connection master drop table t1; --source include/save_master_gtid.inc --connection slave --source include/sync_with_master_gtid.inc   --source include/rpl_end.inc --echo # End of test Also, updating the remaining time to 4h per Monty's request.
          monty Michael Widenius added a comment -

          I have been busy with finishing my tasks for next release of MariaDB.
          I will start looking at this as my main task next weeks Monday.

          monty Michael Widenius added a comment - I have been busy with finishing my tasks for next release of MariaDB. I will start looking at this as my main task next weeks Monday.

          People

            monty Michael Widenius
            edward Edward Stoever
            Votes:
            1 Vote for this issue
            Watchers:
            9 Start watching this issue

            Dates

              Created:
              Updated:

              Git Integration

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