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

Table-rebuilding DDL on a not-up-to-date temp table resets the binlog state

    XMLWordPrintable

Details

    Description

      If there is any changes to the temporary table that is not binlogged, the table is marked as not up to date.

      It does not survive DDL that rebuilds the table. ALTER … ADD COLUMN, ALTER … FORCE and OPTIMIZE go through the create path, which sets table_creation_was_logged = 1 again. The server then believes the replica's copy is current and replicates later statements verbatim against it — diverging a permanent base table with no error and a healthy applier.

      ALTER … FORCE is the decisive case: no schema change at all, purely a rebuild, and the state is still lost. ANALYZE and TRUNCATE don't rebuild, keep the state, and converge — the controls.

      master test.base: (1,510) (2,20) (3,30)
      replica test.base: (1,10) (2,20) (3,30)
      Slave_SQL_Running = Yes, Last_SQL_Errno = 0

      # THIS TEST FAILS ON UNFIXED SERVERS at the first diff_tables, and passes once
      # the state is preserved across a rebuild.
      --source include/have_innodb.inc
      --source include/master-slave.inc
       
      --connection master
      --disable_query_log
      CALL mtr.add_suppression("Unsafe statement written to the binary log");
      --enable_query_log
       
      SET SESSION binlog_format= STATEMENT;
      SELECT @@session.create_tmp_table_binlog_formats;
      CREATE TABLE base (id INT PRIMARY KEY, v INT) ENGINE=InnoDB;
      --sync_slave_with_master
       
      --echo #
      --echo # ======== ALTER ... FORCE -- a pure rebuild, no schema change
      --echo #
      --connection master
      CREATE TEMPORARY TABLE t (id INT PRIMARY KEY, v INT UNIQUE) ENGINE=InnoDB;
      CREATE TEMPORARY TABLE x (id INT PRIMARY KEY, v INT) ENGINE=InnoDB;
      INSERT INTO t VALUES (1,10),(2,20),(3,30);
      INSERT INTO x VALUES (1,1),(2,2),(3,3);
       
      --echo # A failing multi-table UPDATE marks t as not up to date.
      --error ER_DUP_ENTRY
      UPDATE t, x SET t.v = 10, x.v = x.v + 1 WHERE t.id = x.id;
       
      --echo # This change is correctly NOT binlogged, so the replica's copy of t is
      --echo # now stale. That is expected and safe on its own.
      UPDATE t SET v = v + 500 WHERE id = 1;
       
      --echo # The statement under test: a pure rebuild.
      ALTER TABLE t FORCE;
       
      --echo # Propagate t into the permanent base table.
      --echo # If t is still marked not up to date, this is row-logged and base
      --echo # converges. If the rebuild reset the state, it is statement-logged
      --echo # against the replica's stale copy and base diverges.
      INSERT INTO base SELECT id, v FROM t;
       
      --echo # master's view
      --sorted_result
      SELECT * FROM base;
       
      --sync_slave_with_master
      --source include/check_slave_no_error.inc
      --echo # replica's view of the same permanent table
      --connection slave
      --sorted_result
      SELECT * FROM base;
       
      --connection master
      --let $diff_tables= master:test.base, slave:test.base
      --source include/diff_tables.inc
      --echo # ==> base converged after ALTER ... FORCE
       
      --connection master
      DROP TEMPORARY TABLE t, x;
      DELETE FROM base;
      --sync_slave_with_master
       
      --echo #
      --echo # ======== control: ANALYZE does not rebuild, so the state survives
      --echo #
      --connection master
      CREATE TEMPORARY TABLE t (id INT PRIMARY KEY, v INT UNIQUE) ENGINE=InnoDB;
      CREATE TEMPORARY TABLE x (id INT PRIMARY KEY, v INT) ENGINE=InnoDB;
      INSERT INTO t VALUES (1,10),(2,20),(3,30);
      INSERT INTO x VALUES (1,1),(2,2),(3,3);
      --error ER_DUP_ENTRY
      UPDATE t, x SET t.v = 10, x.v = x.v + 1 WHERE t.id = x.id;
      UPDATE t SET v = v + 500 WHERE id = 1;
       
      ANALYZE TABLE t;
       
      INSERT INTO base SELECT id, v FROM t;
      --sorted_result
      SELECT * FROM base;
      --sync_slave_with_master
      --source include/check_slave_no_error.inc
      --connection master
      --let $diff_tables= master:test.base, slave:test.base
      --source include/diff_tables.inc
      --echo # ==> base converged after ANALYZE, as it must
       
      --connection master
      DROP TEMPORARY TABLE t, x;
      DROP TABLE base;
      --sync_slave_with_master
      --source include/rpl_end.inc
      

      Attachments

        Activity

          People

            Unassigned Unassigned
            Deepthi ES Deepthi Eranti Sreenivas
            Votes:
            0 Vote for this issue
            Watchers:
            2 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.