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

Replica trigger mode YES logs local trigger rows to a downstream replica

    XMLWordPrintable

Details

    • Bug
    • Status: Open (View Workflow)
    • Major
    • Resolution: Unresolved
    • None
    • None
    • Replication, Triggers
    • None
    • Unexpected results
    • Hide
      In a MariaDB primary -> replica1 -> replica2 chain, an intermediate replica
      configured with {{slave_run_triggers_for_rbr=YES}} writes rows from its replica-local trigger into its binary log when {{log-slave-updates}} is enabled.
      Those local trigger rows are then replayed by replica2, even though replica1 is configured with {{YES}} rather than {{LOGGING}}. The same schedule with {{slave_run_triggers_for_rbr=NO}} produces no trigger rows, and the {{LOGGING}} configuration produces the expected downstream rows.
      Show
      In a MariaDB primary -> replica1 -> replica2 chain, an intermediate replica configured with {{slave_run_triggers_for_rbr=YES}} writes rows from its replica-local trigger into its binary log when {{log-slave-updates}} is enabled. Those local trigger rows are then replayed by replica2, even though replica1 is configured with {{YES}} rather than {{LOGGING}}. The same schedule with {{slave_run_triggers_for_rbr=NO}} produces no trigger rows, and the {{LOGGING}} configuration produces the expected downstream rows.

    Description

      Summary

      In a MariaDB primary -> replica1 -> replica2 chain, an intermediate replica
      configured with slave_run_triggers_for_rbr=YES writes rows from its
      replica-local trigger into its binary log when log-slave-updates is enabled.
      Those local trigger rows are then replayed by replica2, even though replica1 is
      configured with YES rather than LOGGING. The same schedule with
      slave_run_triggers_for_rbr=NO produces no trigger rows, and the
      LOGGING configuration produces the expected downstream rows.

      Environment

      • Product: MariaDB Server
      • Observed versions:
        • MariaDB 12.2.2, three-node chain
        • MariaDB 10.6, three-node chain
      • Topology: primary -> replica1 -> replica2
      • Replication: asynchronous file/position replication
      • Binary logging: binlog_format=ROW
      • Intermediate replica: log-slave-updates=ON
      • Storage engine: InnoDB

      Steps to reproduce

      Set up a three-node MariaDB chain:

      primary -> replica1 -> replica2
      

      Use row-based binary logging on all three servers. Enable
      log-slave-updates on replica1 and replica2.

      On the primary, create only the base table:

      CREATE TABLE base_t(
        id INT PRIMARY KEY,
        v INT NOT NULL,
        g INT GENERATED ALWAYS AS (v * 2) STORED,
        note VARCHAR(32) NOT NULL
      ) ENGINE=InnoDB;
      

      On replica1 and replica2, create the same base table plus a local audit table
      and a local AFTER INSERT trigger. This DDL is local to each replica; it is not
      created by primary replication.

      CREATE TABLE base_t(
        id INT PRIMARY KEY,
        v INT NOT NULL,
        g INT GENERATED ALWAYS AS (v * 2) STORED,
        note VARCHAR(32) NOT NULL
      ) ENGINE=InnoDB;
       
      CREATE TABLE side_audit(
        seq INT AUTO_INCREMENT PRIMARY KEY,
        origin VARCHAR(128) NOT NULL,
        row_id INT NOT NULL,
        seen_v INT NOT NULL,
        seen_g INT NOT NULL,
        note VARCHAR(32) NOT NULL,
        UNIQUE KEY uq_origin_row(origin,row_id)
      ) ENGINE=InnoDB;
       
      CREATE TRIGGER base_t_ai AFTER INSERT ON base_t
      FOR EACH ROW
      INSERT INTO side_audit(origin,row_id,seen_v,seen_g,note)
      VALUES(@@hostname,NEW.id,NEW.v,NEW.g,NEW.note);
      

      Configure replica1 to run local triggers for row events, but not to use
      LOGGING:

      SET GLOBAL slave_run_triggers_for_rbr='YES';
      

      Configure replica2 not to run local triggers for row events:

      SET GLOBAL slave_run_triggers_for_rbr='NO';
      

      Then run this INSERT on the primary and wait until both replication links have
      reached the corresponding binary log positions:

      INSERT INTO base_t(id,v,note)
      VALUES (1,10,'first'),(2,20,'second');
      

      Inspect the base and audit tables on all three servers:

      SELECT id,v,g,note FROM base_t ORDER BY id;
      SELECT origin,row_id,seen_v,seen_g,note FROM side_audit ORDER BY seq;
      SHOW SLAVE STATUS\G
      

      Expected result

      With slave_run_triggers_for_rbr=YES on replica1, replica1 should run its
      local trigger for the two row events and store two local audit rows. Since the
      mode is YES rather than LOGGING, those local trigger rows should not be
      written into replica1's binary log for downstream replay.

      Replica2 is configured with slave_run_triggers_for_rbr=NO, so replica2
      should not create its own local audit rows from the incoming base_t row
      events. The expected downstream audit table is therefore empty.

      Actual result

      The base table converges on all three servers:

      primary.base_t:
        (1, 10, 20, 'first')
        (2, 20, 40, 'second')
       
      replica1.base_t:
        (1, 10, 20, 'first')
        (2, 20, 40, 'second')
       
      replica2.base_t:
        (1, 10, 20, 'first')
        (2, 20, 40, 'second')
      

      Replica1 runs its local trigger and stores two audit rows, as expected:

      replica1.side_audit:
        (replica1_hostname, 1, 10, 20, 'first')
        (replica1_hostname, 2, 20, 40, 'second')
      

      Replica2 also receives those two audit rows:

      replica2.side_audit:
        (replica1_hostname, 1, 10, 20, 'first')
        (replica1_hostname, 2, 20, 40, 'second')
      

      The origin value is replica1's hostname, not replica2's hostname. This
      shows that the rows stored on replica2 came from replica1's binary log rather
      than from replica2's own local trigger. Both replica SQL threads remain running
      with no SQL error.

      Relevant controls

      The same chain was run with slave_run_triggers_for_rbr=NO on replica1 and
      NO on replica2. In that configuration, neither replica stored audit rows:

      replica1.side_audit row count: 0
      replica2.side_audit row count: 0
      

      The same chain was run with slave_run_triggers_for_rbr=LOGGING on replica1
      and NO on replica2. In that configuration, replica1 stored two local audit
      rows and replica2 received those two rows downstream:

      replica1.side_audit row count: 2
      replica2.side_audit row count: 2
      

      The YES result therefore matches the LOGGING result for the downstream
      audit rows, not the NO result.

      Repetition and scope

      The schedule reproduced on both tested MariaDB versions:

      MariaDB 12.2.2, replica1=YES, replica2=NO:     3/3 executions
      MariaDB 10.6,   replica1=YES, replica2=NO:     3/3 executions
       
      MariaDB 12.2.2, replica1=NO, replica2=NO:      3/3 controls, no audit rows
      MariaDB 10.6,   replica1=NO, replica2=NO:      3/3 controls, no audit rows
       
      MariaDB 12.2.2, replica1=LOGGING, replica2=NO: 3/3 controls, downstream audit rows
      MariaDB 10.6,   replica1=LOGGING, replica2=NO: 3/3 controls, downstream audit rows
      

      Every execution reached the expected primary log position on replica1 and the
      expected replica1 log position on replica2. Both replica SQL threads remained
      healthy, and the base_t rows matched on all three servers.

      Nearby issues checked

      This is not a case where replica2 creates its own local trigger rows. Replica2
      is configured with slave_run_triggers_for_rbr=NO, and the origin column
      records replica1's hostname in the rows observed on replica2.

      This is also different from the documented LOGGING mode: the intermediate
      replica is configured with YES, but the downstream result matches the
      LOGGING control.

      Attachments

        Activity

          People

            Deepthi ES Deepthi Eranti Sreenivas
            JaysonL Zhensheng Luo
            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.