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

TRUNCATE on a partitioned InnoDB table fails with ERROR 1205 when LOCK TABLES also holds the table through an alias, a view or a trigger

    XMLWordPrintable

Details

    Description

      --source include/have_partition.inc
      --source include/have_innodb.inc
       
      CREATE TABLE t1 (a INT) ENGINE=InnoDB PARTITION BY RANGE (a) (PARTITION p0 VALUES LESS THAN (10), PARTITION p1 VALUES LESS THAN MAXVALUE);
      INSERT INTO t1 VALUES (1),(20);
      LOCK TABLES t1 WRITE, t1 AS a1 READ;
      --error 0,ER_LOCK_WAIT_TIMEOUT
      TRUNCATE TABLE t1;
      if ($mysql_errno)
      {
        --die The partitioned InnoDB table cannot be truncated while LOCK TABLES also holds an alias of it: TRUNCATE TABLE fails with a lock wait timeout
      }
      --error 0,ER_LOCK_WAIT_TIMEOUT
      ALTER TABLE t1 TRUNCATE PARTITION p0;
      if ($mysql_errno)
      {
        --die The partition cannot be truncated while LOCK TABLES also holds an alias of the table: TRUNCATE PARTITION fails with a lock wait timeout
      }
      UNLOCK TABLES;
      DROP TABLE t1;

      Leads to:

      CS 13.1.2 87e62ca17270e163a6d41b3fc8d6f4d440f1bb88 (Debug, Clang 22.1.8-20260622) Build 06/10/2026

      mysqltest: At line 11: The partitioned InnoDB table cannot be truncated while LOCK TABLES also holds an alias of it: TRUNCATE TABLE fails with a lock wait timeout

      The TRUNCATE TABLE fails after about 0.7 seconds with ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction, and the rows stay. ALTER TABLE t1 TRUNCATE PARTITION p0 fails the same way, and so does a WRITE alias. A view v1 over t1, locked with LOCK TABLES t1 WRITE, v1 READ, gives the same error, and so does a trigger on another locked table that uses t1:

      CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB PARTITION BY HASH (a) PARTITIONS 2;
      CREATE TABLE t2 (a INT) ENGINE=InnoDB;
      CREATE TRIGGER tr AFTER INSERT ON t2 FOR EACH ROW INSERT INTO t1 VALUES (NEW.a, 0);
      INSERT INTO t1 VALUES (1, 1), (2, 2);
      LOCK TABLES t1 WRITE, t2 WRITE;
      TRUNCATE TABLE t1;
      UNLOCK TABLES;
      DROP TABLE t1, t2;

      The same TRUNCATE TABLE works on an InnoDB table that is not partitioned, on a partitioned MyISAM table, and on the partitioned InnoDB table locked without an alias. Optimized builds give the same result.

      From the code it seems that Sql_cmd_truncate_table::handler_truncate() in sql/sql_truncate.cc closes the other instances of the table only when the engine has HTON_TRUNCATE_REQUIRES_EXCLUSIVE_USE. InnoDB has the flag, partition_hton in sql/ha_partition.cc does not. Sql_cmd_alter_table_truncate_partition::execute() in sql/sql_partition_admin.cc does not close them at all. The other instance then keeps the InnoDB partition open, and ha_innobase::truncate() waits 14 times 50 ms for the reference count to drop to 1 and returns DB_LOCK_WAIT_TIMEOUT.

      Attachments

        Issue Links

          Activity

            People

              holyfoot Alexey Botchkov
              Roel Roel Van de Paar
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0d
                  0d
                  Logged:
                  Time Spent - 1.25h
                  1.25h

                  Git Integration

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