Bug #56422 CHECK TABLE run when the table is locked reports corruption along with timeout
Submitted: 31 Aug 2010 19:28 Modified: 20 Nov 2010 18:09
Reporter: Elena Stepanova Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.5.6-m3, 5.6.0-m4, 5.6.99 OS:Any
Assigned to: Jon Olav Hauglid CPU Architecture:Any
Triage: Triaged: D3 (Medium)

[31 Aug 2010 19:28] Elena Stepanova
Description:
If CHECK TABLE (or REPAIR TABLE) is executed when the table is locked by another connection, after timeout it returns two records: one is Msg_type=Error with Msg_text='Lock wait timeout exceeded; try restarting transaction', which could be expected, but the other one is error/Corrupt:

Table   Op      Msg_type        Msg_text
test.t  check   Error   Lock wait timeout exceeded; try restarting transaction
test.t  check   error   Corrupt

The 2nd one is misleading, as there is no actual corruption.

How to repeat:
--disable_warnings
DROP TABLE IF EXISTS t;
--enable_warnings

CREATE TABLE t ( i INT );
--echo # One connection locks the table
LOCK TABLE t WRITE;

--connect (con1,localhost,root,,)
SET lock_wait_timeout=1;
--echo # Another connection is trying to run CHECK
CHECK TABLE t;

--connection default

UNLOCK TABLES;
DROP TABLE t;

--exit
[17 Sep 2010 8:49] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/118442

3141 Jon Olav Hauglid	2010-09-17
      Bug #56494 Segfault in upgrade_shared_lock_to_exclusive() for
                 REPAIR of merge table
      Bug #56422 CHECK TABLE run when the table is locked reports
                 corruption along with timeout
      
      The crash happened if a table maintenance statement (ANALYZE TABLE,
      REPAIR TABLE, etc.) was executed on a MERGE table and opening and 
      locking a child table failed. This could for example happen if a child
      table did not exist or if a lock timeout happened while waiting for
      a conflicting metadata lock to disappear.
      
      Since opening and locking the MERGE table and its children failed,
      the tables would be closed and the metadata locks released.
      However, TABLE_LIST::table for the MERGE table would still be set,
      with its value invalid since the tables had been closed.
      This caused the table maintenance statement to try to continue
      and upgrade the metadata lock on the MERGE table. But since the lock
      already had been released, this caused a segfault.
      
      This patch fixes the problem by setting TABLE_LIST::table to NULL 
      if open_and_lock_tables() fails. This prevents the maintenance
      statement from continuing and trying to upgrade the metadata lock.
      
      The patch also fixes a problem where REPAIR TABLE ... USE_FRM
      would cause an assert for MERGE tables, even if child tables
      were opened successfully.
      
      Finally, the patch changes the error message from "Corrupt" to
      "Operation failed" for a number of issues not related to table
      corruption. For example "Lock wait timeout exceeded" and 
      "Deadlock found trying to get lock".
      
      Test cases added to mdl_sync.test and check.test.
[21 Sep 2010 9:47] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/118686

3141 Jon Olav Hauglid	2010-09-21
      Bug #56494 Segfault in upgrade_shared_lock_to_exclusive() for
                 REPAIR of merge table
      Bug #56422 CHECK TABLE run when the table is locked reports
                 corruption along with timeout
      
      The crash happened if a table maintenance statement (ANALYZE TABLE,
      REPAIR TABLE, etc.) was executed on a MERGE table and opening and 
      locking a child table failed. This could for example happen if a child
      table did not exist or if a lock timeout happened while waiting for
      a conflicting metadata lock to disappear.
      
      Since opening and locking the MERGE table and its children failed,
      the tables would be closed and the metadata locks released.
      However, TABLE_LIST::table for the MERGE table would still be set,
      with its value invalid since the tables had been closed.
      This caused the table maintenance statement to try to continue
      and upgrade the metadata lock on the MERGE table. But since the lock
      already had been released, this caused a segfault.
      
      This patch fixes the problem by setting TABLE_LIST::table to NULL 
      if open_and_lock_tables() fails. This prevents maintenance
      statements from continuing and trying to upgrade the metadata lock.
      
      The patch also includes a 5.5 version of the fix for
      Bug #46339 crash on REPAIR TABLE merge table USE_FRM.
      This bug caused REPAIR TABLE ... USE_FRM to give an assert 
      when used on merge tables.
      
      Finally, the patch changes the error message from "Corrupt" to
      "Operation failed" for a number of issues not related to table
      corruption. For example "Lock wait timeout exceeded" and 
      "Deadlock found trying to get lock".
      
      Test cases added to merge.test and check.test.
[22 Sep 2010 8:16] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/118779

3141 Jon Olav Hauglid	2010-09-22
      Bug #56494 Segfault in upgrade_shared_lock_to_exclusive() for
                 REPAIR of merge table
      Bug #56422 CHECK TABLE run when the table is locked reports
                 corruption along with timeout
      
      The crash happened if a table maintenance statement (ANALYZE TABLE,
      REPAIR TABLE, etc.) was executed on a MERGE table and opening and 
      locking a child table failed. This could for example happen if a child
      table did not exist or if a lock timeout happened while waiting for
      a conflicting metadata lock to disappear.
      
      Since opening and locking the MERGE table and its children failed,
      the tables would be closed and the metadata locks released.
      However, TABLE_LIST::table for the MERGE table would still be set,
      with its value invalid since the tables had been closed.
      This caused the table maintenance statement to try to continue
      and upgrade the metadata lock on the MERGE table. But since the lock
      already had been released, this caused a segfault.
      
      This patch fixes the problem by setting TABLE_LIST::table to NULL 
      if open_and_lock_tables() fails. This prevents maintenance
      statements from continuing and trying to upgrade the metadata lock.
      
      The patch includes a 5.5 version of the fix for
      Bug #46339 crash on REPAIR TABLE merge table USE_FRM.
      This bug caused REPAIR TABLE ... USE_FRM to give an assert 
      when used on merge tables.
      
      The patch also enables the CHECK TABLE statement for log tables.
      Before, CHECK TABLE for log tables gave ER_CANT_LOCK_LOG_TABLE,
      yet still counted the statement as successfully executed.
      With the changes to table maintenance statement error handling
      in this patch, CHECK TABLE would no longer be considered as
      successful in this case. This would have caused upgrade scripts
      to mistakenly think that the general and slow logs are corrupted
      and have to be repaired. Enabling CHECK TABLES for log tables
      prevents this from happening.
      
      Finally, the patch changes the error message from "Corrupt" to
      "Operation failed" for a number of issues not related to table
      corruption. For example "Lock wait timeout exceeded" and 
      "Deadlock found trying to get lock".
      
      Test cases added to merge.test and check.test.
[22 Sep 2010 8:19] Jon Olav Hauglid
Fixed in the scope of Bug#56494.
Pushed to mysql-5.5-runtime (5.5.7-m3).
[23 Sep 2010 9:14] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/118914

3142 Jon Olav Hauglid	2010-09-23
      Followup to Bug #56422 CHECK TABLE run when the table is locked
                             reports corruption along with timeout
      
      This patch updates the result file for the
      parts.partition_special_innodb test case which was, by mistake,
      not updated in the original patch.
[4 Nov 2010 1:59] Paul Dubois
The server crashed if a table maintenance statement such as ANALYZE
TABLE or REPAIR TABLE was executed on a MERGE table and opening and
locking a child table failed. For example, this could happen if a
child table did not exist or if a lock timeout happened while waiting
for a conflicting metadata lock to disappear.

As a consequence of this bug fix, it is now possible to use CHECK
TABLE for log tables without producing an error.
[9 Nov 2010 19:44] Bugs System
Pushed into mysql-5.5 5.5.7-rc (revid:sunanda.menon@sun.com-20101109182959-otkxq8vo2dcd13la) (version source revid:marko.makela@oracle.com-20100824081003-v4ecy0tga99cpxw2) (merge vers: 5.1.50) (pib:21)
[13 Nov 2010 16:18] Bugs System
Pushed into mysql-trunk 5.6.99-m5 (revid:alexander.nozdrin@oracle.com-20101113155825-czmva9kg4n31anmu) (version source revid:marko.makela@oracle.com-20100824081003-v4ecy0tga99cpxw2) (merge vers: 5.1.50) (pib:21)
[13 Nov 2010 16:31] Bugs System
Pushed into mysql-next-mr (revid:alexander.nozdrin@oracle.com-20101113160336-atmtmfb3mzm4pz4i) (version source revid:marko.makela@oracle.com-20100824081003-v4ecy0tga99cpxw2) (pib:21)
[20 Nov 2010 18:09] Paul Dubois
Noted in 5.5.7 changelog.