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

DELETE fails to notice transaction abort, violating ACID

Details

    Description

      The test case appears to be deterministic, the concurrency here is on the transaction level. I suppose it can be further simplified, but it's not easy to guess blindly what can be replaced with what, so I'll leave it as it is for now, hopefully it will be clearer after the analysis.

      --source include/have_innodb.inc
       
      CREATE TABLE t1 (id INT PRIMARY KEY, col_varchar VARCHAR(8)) ENGINE=InnoDB;
      INSERT INTO t1 (id) VALUES (1),(2);
      CREATE TABLE t2 (id INT, f INT, s DATE, e DATE, PERIOD FOR p(s,e), PRIMARY KEY(id, p WITHOUT OVERLAPS)) ENGINE=InnoDB;
      INSERT INTO t2 VALUES (1,0,'2000-01-01','2000-01-02');
      CREATE TABLE t3 (id INT, f BLOB, UNIQUE(f)) ENGINE=InnoDB;
       
      --connection default
      SET innodb_lock_wait_timeout=1;
      START TRANSACTION;
      DELETE FROM t1;
       
      --connect (con1,localhost,root,,)
      START TRANSACTION;
      UPDATE t2 SET f = 20;
       
      --connection default
      --send
        DELETE FROM t2 FOR PORTION OF p FROM '2000-01-01' TO '2000-01-02';
       
      --connection con1
      INSERT INTO t3 (id) VALUES (1), (2);
      UPDATE t1 SET col_varchar = 'bar';
      COMMIT;
       
      --connection default
      --error ER_LOCK_DEADLOCK
      --reap
      COMMIT;
      UPDATE t3 SET f = 'foo' ORDER BY f LIMIT 1;
       
      # Cleanup
      DROP TABLE t1, t2, t3;
      

      10.6 d77b9a4925c971364707d435028add41e8015173

      mariadbd: /data/bld/10.6-asan/storage/innobase/handler/ha_innodb.cc:16341: virtual int ha_innobase::external_lock(THD*, int): Assertion `not_autocommit || trx->n_mysql_tables_in_use || (trx->lock.trx_locks).count == 0' failed.
      250126 21:12:56 [ERROR] /share8t/bld/10.6-asan/sql/mariadbd got signal 6 ;
       
      #9  0x00007fee4cc53eb2 in __GI___assert_fail (assertion=0x55ae9e0c92a0 "not_autocommit || trx->n_mysql_tables_in_use || (trx->lock.trx_locks).count == 0", file=0x55ae9e0b2be0 "/data/bld/10.6-asan/storage/innobase/handler/ha_innodb.cc", line=16341, function=0x55ae9e0c90e0 "virtual int ha_innobase::external_lock(THD*, int)") at ./assert/assert.c:101
      #10 0x000055ae9c78fe97 in ha_innobase::external_lock (this=0x62d0000a1760, thd=0x62b0000bd218, lock_type=0) at /data/bld/10.6-asan/storage/innobase/handler/ha_innodb.cc:16341
      #11 0x000055ae9bd01e12 in handler::ha_external_lock (this=0x62d0000a1760, thd=0x62b0000bd218, lock_type=0) at /data/bld/10.6-asan/sql/handler.cc:7226
      #12 0x000055ae9bcddd10 in handler::create_lookup_handler (this=0x6250002a3148) at /data/bld/10.6-asan/sql/handler.cc:3326
      #13 0x000055ae9bd06fb4 in handler::prepare_for_insert (this=0x6250002a3148, do_create=true) at /data/bld/10.6-asan/sql/handler.cc:7689
      #14 0x000055ae9b77872a in mysql_update (thd=0x62b0000bd218, table_list=0x62d0000a0578, fields=..., values=..., conds=0x0, order_num=1, order=0x62d0000a0ff0, limit=1, ignore=false, found_return=0x7fee3e0e3f00, updated_return=0x7fee3e0e3f20) at /data/bld/10.6-asan/sql/sql_update.cc:1024
      #15 0x000055ae9b43df7d in mysql_execute_command (thd=0x62b0000bd218, is_called_from_prepared_stmt=false) at /data/bld/10.6-asan/sql/sql_parse.cc:4477
      #16 0x000055ae9b457d60 in mysql_parse (thd=0x62b0000bd218, rawbuf=0x62d0000a0438 "UPDATE t3 SET f = 'foo' ORDER BY f LIMIT 1", length=42, parser_state=0x7fee3e0e4a90) at /data/bld/10.6-asan/sql/sql_parse.cc:8208
      #17 0x000055ae9b42d123 in dispatch_command (command=COM_QUERY, thd=0x62b0000bd218, packet=0x629000276219 "UPDATE t3 SET f = 'foo' ORDER BY f LIMIT 1", packet_length=42, blocking=true) at /data/bld/10.6-asan/sql/sql_parse.cc:1908
      #18 0x000055ae9b429e57 in do_command (thd=0x62b0000bd218, blocking=true) at /data/bld/10.6-asan/sql/sql_parse.cc:1421
      #19 0x000055ae9b8ac8c1 in do_handle_one_connection (connect=0x608000018ab8, put_in_cache=true) at /data/bld/10.6-asan/sql/sql_connect.cc:1386
      #20 0x000055ae9b8ac420 in handle_one_connection (arg=0x608000018a38) at /data/bld/10.6-asan/sql/sql_connect.cc:1298
      #21 0x000055ae9c525966 in pfs_spawn_thread (arg=0x617000007e98) at /data/bld/10.6-asan/storage/perfschema/pfs.cc:2201
      #22 0x00007fee4cca81c4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
      #23 0x00007fee4cd2885c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
      

      10.11 3a6af458e6149657c1e135af821a23a7c15c68f1

      mariadbd: /data/bld/11.4-asan/storage/innobase/trx/trx0trx.cc:376: void trx_t::free(): Assertion `!n_mysql_tables_in_use' failed.
      250126 21:13:52 [ERROR] /share8t/bld/11.4-asan/sql/mariadbd got signal 6 ;
       
      #9  0x00007f30dca53eb2 in __GI___assert_fail (assertion=0x55b9748a8880 "!n_mysql_tables_in_use", file=0x55b9748a8120 "/data/bld/11.4-asan/storage/innobase/trx/trx0trx.cc", line=376, function=0x55b9748a88c0 "void trx_t::free()") at ./assert/assert.c:101
      #10 0x000055b97318bc48 in trx_t::free (this=0x7f30cf970380) at /data/bld/11.4-asan/storage/innobase/trx/trx0trx.cc:376
      #11 0x000055b972b71000 in innobase_close_connection (thd=0x62c0001e0218) at /data/bld/11.4-asan/storage/innobase/handler/ha_innodb.cc:2954
      #12 0x000055b972177423 in ha_close_connection (thd=0x62c0001e0218) at /data/bld/11.4-asan/sql/handler.cc:955
      #13 0x000055b9716b7bef in THD::free_connection (this=0x62c0001e0218) at /data/bld/11.4-asan/sql/sql_class.cc:1737
      #14 0x000055b971432021 in unlink_thd (thd=0x62c0001e0218) at /data/bld/11.4-asan/sql/mysqld.cc:2871
      #15 0x000055b971cd9686 in do_handle_one_connection (connect=0x608000005138, put_in_cache=true) at /data/bld/11.4-asan/sql/sql_connect.cc:1419
      #16 0x000055b971cd9138 in handle_one_connection (arg=0x6080000050b8) at /data/bld/11.4-asan/sql/sql_connect.cc:1320
      #17 0x000055b9729557a8 in pfs_spawn_thread (arg=0x617000007e98) at /data/bld/11.4-asan/storage/perfschema/pfs.cc:2201
      #18 0x00007f30dcaa81c4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
      #19 0x00007f30dcb2885c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
      

      The failure started happening after this commit in 10.6:

      commit ddd7d5d8e34c3edd7ebf4790eec2c4e4d9141e94
      Commit:     Marko Mäkelä
      CommitDate: Thu Dec 12 18:02:00 2024 +0200
       
          MDEV-24035 Failing assertion: UT_LIST_GET_LEN(lock.trx_locks) == 0 causing disruption and replication failure
      

      No obvious immediate problem on a non-debug build.

      Attachments

        Issue Links

          Activity

            + if (error)
            + goto terminate_delete;

            This is wrong, as error is set to -1 oif the read loop is sucessfull.
            If there was an error, thd->is_error() is set.

            Better to do:

            + if (thd->is_error())
            + goto terminate_delete;

            However before doing that, the cleanups on the following lines needs to be done!

            monty Michael Widenius added a comment - + if (error) + goto terminate_delete; This is wrong, as error is set to -1 oif the read loop is sucessfull. If there was an error, thd->is_error() is set. Better to do: + if (thd->is_error()) + goto terminate_delete; However before doing that, the cleanups on the following lines needs to be done!

            More work is required. Working on it

            monty Michael Widenius added a comment - More work is required. Working on it

            I have now created a 'final' patch for the first part (checking error after read loop) and created a separate patch for this.
            Now working on another patch that changes prepare_for_insert() to generate errors for failures and also adding checking of the return value for prepare_for_insert() everywhere.

            monty Michael Widenius added a comment - I have now created a 'final' patch for the first part (checking error after read loop) and created a separate patch for this. Now working on another patch that changes prepare_for_insert() to generate errors for failures and also adding checking of the return value for prepare_for_insert() everywhere.

            Pushed solutions to bb-10.6-monty
            Sanja is taking over

            monty Michael Widenius added a comment - Pushed solutions to bb-10.6-monty Sanja is taking over

            I hope that the final version will include the assertion change that I suggested adding to ha_innobase::external_lock(), so that any further cases like this will fail in a more obvious way.

            marko Marko Mäkelä added a comment - I hope that the final version will include the assertion change that I suggested adding to ha_innobase::external_lock() , so that any further cases like this will fail in a more obvious way.

            People

              serg Sergei Golubchik
              elenst Elena Stepanova
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

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