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

READ UNCOMMITTED deadlock differs from READ COMMITTED for UPDATE IGNORE with innodb_snapshot_isolation=ON

    XMLWordPrintable

Details

    • Bug
    • Status: Confirmed (View Workflow)
    • Major
    • Resolution: Unresolved
    • 10.11, 12.3, 10.6.27, 12.2.2, 12.3.1
    • 10.11, 12.3
    • MariaDB Server 10.6, 12.2.2, and 12.3
      Storage engine: InnoDB
      innodb_snapshot_isolation = ON
      Isolation levels tested: READ UNCOMMITTED and READ COMMITTED

    Description

      Description:
      I found a possible inconsistency between READ UNCOMMITTED and READ COMMITTED when innodb_snapshot_isolation=ON.

      In this test case, `[1-2]` is blocked by Transaction 2. Under READ UNCOMMITTED, when `[2-4]` is executed, `[1-2]` fails with a deadlock error:

      MariaDB [test]> UPDATE IGNORE t0 SET c0=-1696424661 WHERE TRUE;
      ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
      

      However, under READ COMMITTED, `[2-4]` executes successfully. After Transaction 2 commits, `[1-2]` is unblocked and Transaction 1 completes successfully.

      I think this is suspicious because this test case does not involve any plain SELECT statement. It only uses INSERT, UPDATE IGNORE, DELETE, and SELECT ... LOCK IN SHARE MODE. Therefore, READ UNCOMMITTED and READ COMMITTED should behave consistently in this case.

      I also tested the same case on MySQL 8.4.9. Under both READ UNCOMMITTED and READ COMMITTED, MySQL does not report a deadlock, and its behavior is consistent with MariaDB READ COMMITTED.

      If this behavior is expected in MariaDB, could you please explain why READ UNCOMMITTED and READ COMMITTED differ here?

      Reproduction:

      CREATE TABLE IF NOT EXISTS t0(
      c0 REAL UNIQUE,
      c1 VARCHAR(100) UNIQUE,
      PRIMARY KEY(c0, c1)
      ) ENGINE=InnoDB;
       
      INSERT INTO t0 VALUES (0.24151, '0.2415081472877052');
      INSERT INTO t0 VALUES (0.45461, '0.45461267175108644');
      CREATE UNIQUE INDEX ic0 USING BTREE ON t0(c1 DESC);
      

      Transaction 1:

      [1-0] BEGIN;
      [1-1] INSERT INTO t0 VALUES (-1.525451085E9, '');
      [1-2] UPDATE IGNORE t0 SET c0=-1696424661 WHERE TRUE;
      [1-3] COMMIT;
      

      Transaction 2:

      [2-0] BEGIN;
      [2-1] SELECT t0.c1, t0.c0 FROM t0 WHERE TRUE LOCK IN SHARE MODE;
      [2-2] DELETE FROM t0 WHERE TRUE LIMIT 453060891;
      [2-3] INSERT INTO t0 VALUES (0.6002, 'S''');
      [2-4] INSERT INTO t0 VALUES (0.24151, '!\\');
      [2-5] COMMIT;
      COMMIT;
      

      Execute the statements in the following order:

      -- session 1
      SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
      [1-0] BEGIN;
       
      -- session 2
      SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
      [2-0] BEGIN;
      [2-1] SELECT t0.c1, t0.c0 FROM t0 WHERE TRUE LOCK IN SHARE MODE;
      [2-2] DELETE FROM t0 WHERE TRUE LIMIT 453060891;
       
      -- session 1
      [1-1] INSERT INTO t0 VALUES (-1.525451085E9, '');
      [1-2] UPDATE IGNORE t0 SET c0=-1696424661 WHERE TRUE;
      -- [1-2] is blocked by Transaction 2
       
      -- session 2
      [2-3] INSERT INTO t0 VALUES (0.6002, 'S''');
      [2-4] INSERT INTO t0 VALUES (0.24151, '!\');
      [2-5] COMMIT;
       
      -- session 1
      [1-3] COMMIT;
      

      Observed result under READ UNCOMMITTED:
      When `[2-4]` is executed, the blocked statement `[1-2]` fails with:

      MariaDB [test]> UPDATE IGNORE t0 SET c0=-1696424661 WHERE TRUE;
      ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
      

      The final table state is:

      MariaDB [test]> select * from t0;
      +---------+------+
      | c0      | c1   |
      +---------+------+
      | 0.24151 | !\   |
      | 0.6002  | S'   |
      +---------+------+
      

      Observed result under READ COMMITTED:
      Using the same schedule, `[2-4]` executes successfully. After `[2-5] COMMIT`, `[1-2]` is unblocked and Transaction 1 completes successfully.

      The final table state is:

      MariaDB [test]> select * from t0;
      +-------------+------+
      | c0          | c1   |
      +-------------+------+
      | -1696424661 |      |
      | 0.24151     | !\   |
      | 0.6002      | S'   |
      +-------------+------+
      

      Expected result:
      READ UNCOMMITTED and READ COMMITTED should behave consistently for this test case because it does not involve plain SELECT statements.

      In MySQL 8.4.9, the same test case does not report a deadlock under either READ UNCOMMITTED or READ COMMITTED. The behavior is consistent with MariaDB READ COMMITTED.

      Therefore, I expected MariaDB READ UNCOMMITTED to also avoid the deadlock and produce the same final state as READ COMMITTED.

      Attachments

        Issue Links

          Activity

            People

              thiru Thirunarayanan Balathandayuthapani
              yousaha yousaha
              Votes:
              0 Vote for this issue
              Watchers:
              4 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.