HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlMinor

Avoiding "Waiting for table metadata lock" when `ALTER TABLE DROP PARTITION`?

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
partitionwaitingdropalterforwhenavoidingmetadatatablelock

Problem

I have some tables that many users need to access to:

mysql> show create table v3_cam_date\G
*************************** 1. row ***************************
       Table: v3_cam_date
Create Table: CREATE TABLE `v3_cam_date` (
  `campaignid` mediumint(9) NOT NULL DEFAULT '0',
  `totalclick` mediumint(9) unsigned NOT NULL DEFAULT '0',
  `totalview` int(11) unsigned NOT NULL DEFAULT '0',
  `realclick` mediumint(9) unsigned NOT NULL DEFAULT '0',
  `clickcharge` mediumint(9) unsigned NOT NULL DEFAULT '0',
  `viewcharge` int(11) unsigned NOT NULL DEFAULT '0',
  `uv` mediumint(9) unsigned NOT NULL DEFAULT '0',
  `uc` mediumint(9) unsigned NOT NULL DEFAULT '0',
  `dt` date NOT NULL DEFAULT '0000-00-00',
  `ctr` decimal(5,3) NOT NULL DEFAULT '0.000' COMMENT '=-1: meaning not available(N/A)',
  `moneyc` int(11) unsigned NOT NULL DEFAULT '0',
  `moneyv` int(11) unsigned NOT NULL DEFAULT '0',
  KEY `ix_campaignid_dt` (`campaignid`,`dt`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (TO_DAYS(dt))
(PARTITION p0 VALUES LESS THAN (0) ENGINE = InnoDB,
 PARTITION p01 VALUES LESS THAN (734502) ENGINE = InnoDB,
 PARTITION p2 VALUES LESS THAN (734683) ENGINE = InnoDB,
 PARTITION p03 VALUES LESS THAN (734863) ENGINE = InnoDB,
 PARTITION p04 VALUES LESS THAN (734959) ENGINE = InnoDB,
 PARTITION p5 VALUES LESS THAN (735141) ENGINE = InnoDB,
 PARTITION p06 VALUES LESS THAN (735210) ENGINE = InnoDB,
 PARTITION MERGER_2013227 VALUES LESS THAN (735291) ENGINE = InnoDB,
 PARTITION pcurrent_2013227 VALUES LESS THAN (735292) ENGINE = InnoDB) */


When an user want to drop a partition ALTER TABLE v3_cam_date DROP PARTITION pcurrent_2013227, it may cause many transactions to be in the Waiting for table metadata lock state:

``
Id: 31560182
User: alice
Host: 192.168.3.40:36132
db: db
Command: Query
Time: 806
State: Waiting for table metadata lock
Info: SELECT COUNT(DISTINCT A.
campaignid) INTO _campaigncomplete
FROM
ox_campaigns` A

Solution

What you are asking for is impossible. Regardless of storage engine, DDL of any kind will lock a table. If you must remove a partition from a table that is active, you should:

  • Setup MySQL Replication (if you haven't done so already)



  • Perform all SELECTs involving v3_cam_date against the Slave



  • STOP SLAVE; on the Slave



  • Perform ALTER TABLE ... DROP PARTITION on the Master.



  • Perform all SELECTs involving v3_cam_date against the Master



  • START SLAVE; on the Slave (Replicates ALTER TABLE ... DROP PARTITION to the Slave)



This is probably your only recourse. The only other recourse is to simply wait out the ALTER TABLE ... DROP PARTITION.

This situation requires some intervention in the application. Within your application, you would have to create a Write DBVIP on the Master and use the Read DBVIP with one of the following three(3) options:
OPTION #1

  • Keep the Read DBVIP on the Slave



OPTION #2

  • Keep the Read DBVIP on the Master



  • When you must do an ALTER TABLE, move the Read DBVIP to the Slave



  • When ALTER TABLE has been completed, move the Read DBVIP to the Master



OPTION #3

  • Setup Read DBVIP on a LoadBalancer



  • Remove Master from LoadBalanced DBVIP on demand



Option #1 seems to be the simplest way in the long run.

Context

StackExchange Database Administrators Q#35553, answer score: 9

Revisions (0)

No revisions yet.