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

BiE: PURGE BINARY LOGS refusal returns ER_ERROR_ON_READ (1024) naming an already-deleted file

    XMLWordPrintable

Details

    • Unexpected results

    Description

      With binlog-in-engine (BiE), PURGE BINARY LOGS fails when fewer replicas are connected than
      slave_connections_needed_for_purge (default 1; documented). Before any purge the error is
      ER_LOG_IN_USE (1378). After an earlier purge has removed the oldest file, the failure is
      ER_ERROR_ON_READ (1024) naming that already-deleted file. Both cases succeed when
      slave_connections_needed_for_purge=0 or when a replica/reader is connected.

      How to repeat (MTR test attached):
      1. Master and slave with --log-bin --binlog-storage-engine=innodb; slave caught up after 4 x (INSERT; FLUSH BINARY LOGS).
      2. PURGE BINARY LOGS TO 'binlog-000002.ibb'; – succeeds, files 0 and 1 removed
      3. STOP SLAVE (dump thread gone); 4 more x (INSERT; FLUSH BINARY LOGS).
      4. PURGE BINARY LOGS TO 'binlog-000004.ibb';

      Actual:
      ERROR 1024: Error reading file './binlog-000000.ibb' (errno: 2 "No such file or directory")

      Expected: the same ER_LOG_IN_USE (1378) as before the first purge, or at least an error that does not
      refer to a file the server has already deleted.

      BiE TEST :

      --source include/have_binlog_format_row.inc
      --source include/master-slave.inc
      --source include/have_innodb_binlog.inc
       
      CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
      --let $i= 0
      while ($i < 4)
      {
        --eval INSERT INTO t1 VALUES ($i)
        FLUSH BINARY LOGS;
        --inc $i
      }
      --sync_slave_with_master
       
      --echo #
      --echo # No replica connected and nothing purged yet: the purge is refused.
      --echo #
      --connection slave
      --source include/stop_slave.inc
      --connection master
      # The dump thread can linger after STOP SLAVE; kill it so no replica is connected.
      --let $dump_id= `SELECT id FROM information_schema.processlist WHERE command='Binlog Dump'`
      --disable_query_log
      --eval KILL $dump_id
      --enable_query_log
      --let $wait_condition= SELECT COUNT(*)=0 FROM information_schema.processlist WHERE command='Binlog Dump'
      --source include/wait_condition.inc
      --error ER_LOG_IN_USE
      PURGE BINARY LOGS TO 'binlog-000002.ibb';
      --let $first_log= query_get_value(SHOW BINARY LOGS, Log_name, 1)
      --echo # oldest binlog file: $first_log
       
      --echo #
      --echo # Setup: with a replica connected and caught up, purge files 0 and 1.
      --echo #
      --connection slave
      --source include/start_slave.inc
      --connection master
      --sync_slave_with_master
      --connection master
      --let $wait_condition= SELECT COUNT(*)=1 FROM information_schema.processlist WHERE command='Binlog Dump'
      --source include/wait_condition.inc
      PURGE BINARY LOGS TO 'binlog-000002.ibb';
       
      --echo #
      --echo # No replica connected, after the earlier purge removed file 0: the purge
      --echo # must be refused with the same ER_LOG_IN_USE. Before the fix it fails with
      --echo # ER_ERROR_ON_READ (1024), naming binlog-000000.ibb which was already deleted.
      --echo #
      --connection slave
      --source include/stop_slave.inc
      --connection master
      --let $dump_id= `SELECT id FROM information_schema.processlist WHERE command='Binlog Dump'`
      --disable_query_log
      --eval KILL $dump_id
      --enable_query_log
      --let $wait_condition= SELECT COUNT(*)=0 FROM information_schema.processlist WHERE command='Binlog Dump'
      --source include/wait_condition.inc
      --let $i= 10
      while ($i < 14)
      {
        --eval INSERT INTO t1 VALUES ($i)
        FLUSH BINARY LOGS;
        --inc $i
      }
      --error ER_LOG_IN_USE
      PURGE BINARY LOGS TO 'binlog-000004.ibb';
      --let $first_log= query_get_value(SHOW BINARY LOGS, Log_name, 1)
      --echo # oldest binlog file: $first_log
       
      --echo #
      --echo # Cleanup
      --echo #
      --connection slave
      --source include/start_slave.inc
      --connection master
      DROP TABLE t1;
      --source include/rpl_end.inc
      

      BiE test output :
      mysqltest: query 'PURGE BINARY LOGS TO 'binlog-000004.ibb'' failed with wrong errno
      ER_ERROR_ON_READ (1024): 'Error reading file './binlog-000000.ibb' (errno: 2 "No such file or directory")',
      instead of ER_LOG_IN_USE (1378)

      Legacy binlog behave correctly as attached in the below test :

      --source include/have_innodb.inc
      --source include/have_binlog_format_row.inc
      --source include/master-slave.inc
       
      # The rpl suite default is 0; use the binlog-in-engine default of 1.
      SET @old_min_slaves= @@GLOBAL.slave_connections_needed_for_purge;
      SET GLOBAL slave_connections_needed_for_purge= 1;
       
      CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
      --let $i= 0
      while ($i < 4)
      {
        --eval INSERT INTO t1 VALUES ($i)
        FLUSH BINARY LOGS;
        --inc $i
      }
      --sync_slave_with_master
       
      --echo #
      --echo # With a replica connected and caught up, purge files 1 and 2.
      --echo #
      --connection master
      --let $wait_condition= SELECT COUNT(*)=1 FROM information_schema.processlist WHERE command='Binlog Dump'
      --source include/wait_condition.inc
      PURGE BINARY LOGS TO 'master-bin.000003';
       
      --echo #
      --echo # No replica connected, after the earlier purge: with the legacy binlog the
      --echo # purge succeeds.
      --echo #
      --connection slave
      --source include/stop_slave.inc
      --connection master
      # The dump thread can linger after STOP SLAVE; kill it so no replica is connected.
      --let $dump_id= `SELECT id FROM information_schema.processlist WHERE command='Binlog Dump'`
      --disable_query_log
      --eval KILL $dump_id
      --enable_query_log
      --let $wait_condition= SELECT COUNT(*)=0 FROM information_schema.processlist WHERE command='Binlog Dump'
      --source include/wait_condition.inc
      --let $i= 10
      while ($i < 14)
      {
        --eval INSERT INTO t1 VALUES ($i)
        FLUSH BINARY LOGS;
        --inc $i
      }
      PURGE BINARY LOGS TO 'master-bin.000005';
      --let $first_log= query_get_value(SHOW BINARY LOGS, Log_name, 1)
      --echo # oldest binlog file: $first_log
       
      --echo #
      --echo # Cleanup
      --echo #
      --connection slave
      --source include/start_slave.inc
      --connection master
      SET GLOBAL slave_connections_needed_for_purge= @old_min_slaves;
      DROP TABLE t1;
      --source include/rpl_end.inc
       
      Result (mysql-test/suite/rpl/r/binlog_purge_replica_gate_legacy.result)
       
      include/master-slave.inc
      [connection master]
      SET @old_min_slaves= @@GLOBAL.slave_connections_needed_for_purge;
      SET GLOBAL slave_connections_needed_for_purge= 1;
      CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
      INSERT INTO t1 VALUES (0);
      FLUSH BINARY LOGS;
      INSERT INTO t1 VALUES (1);
      FLUSH BINARY LOGS;
      INSERT INTO t1 VALUES (2);
      FLUSH BINARY LOGS;
      INSERT INTO t1 VALUES (3);
      FLUSH BINARY LOGS;
      connection slave;
      #
      # With a replica connected and caught up, purge files 1 and 2.
      #
      connection master;
      PURGE BINARY LOGS TO 'master-bin.000003';
      #
      # No replica connected, after the earlier purge: with the legacy binlog the
      # purge succeeds.
      #
      connection slave;
      include/stop_slave.inc
      connection master;
      INSERT INTO t1 VALUES (10);
      FLUSH BINARY LOGS;
      INSERT INTO t1 VALUES (11);
      FLUSH BINARY LOGS;
      INSERT INTO t1 VALUES (12);
      FLUSH BINARY LOGS;
      INSERT INTO t1 VALUES (13);
      FLUSH BINARY LOGS;
      PURGE BINARY LOGS TO 'master-bin.000005';
      # oldest binlog file: master-bin.000005
      #
      # Cleanup
      #
      connection slave;
      include/start_slave.inc
      connection master;
      SET GLOBAL slave_connections_needed_for_purge= @old_min_slaves;
      DROP TABLE t1;
      include/rpl_end.inc
      

      Attachments

        Activity

          People

            knielsen Kristian Nielsen
            Deepthi ES Deepthi Eranti Sreenivas
            Votes:
            0 Vote for this issue
            Watchers:
            1 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.