qua*_*nta 6 mysql innodb partitioning alter-table locking
我有一些许多用户需要访问的表:
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) */
Run Code Online (Sandbox Code Playgroud)
当用户想要删除一个分区时ALTER TABLE v3_cam_date DROP PARTITION pcurrent_2013227,可能会导致很多事务处于以下Waiting for table metadata lock状态:
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
INNER JOIN `selfserving_users` B ON B.`user_id` = A.`uid`
INNER JOIN `v3_cam_date` C ON C.`campaignid` = A.`campaignid`
WHERE A.`revenue_type` = 5 AND A.`deleted` = 0 AND A.`expire` = DATE_ADD( (SELECT `sys_date_cpc` FROM `000_sys_params_v4`) , INTERVAL 1 DAY)
AND A.`isExpired` = 0 AND IF( NAME_CONST('_permitid',3) = -1, 1=1, IF( NAME_CONST('_permitid',3) = 0, A.`uid` IN (SELECT C.`user_id` FROM `selfserving_users` C WHERE C.`groupid` = NAME_CONST('_groupid',17) ) ,A.`uid` = NAME_CONST('userid',5770)))
Run Code Online (Sandbox Code Playgroud)
在不锁定的情况下完成此操作的有效方法是什么?
你所要求的是不可能的。无论存储引擎如何,任何类型的 DDL 都会锁定表。如果您必须从活动表中删除分区,您应该:
v3_cam_date对 Slave执行所有涉及的SELECTsSTOP SLAVE; 在奴隶ALTER TABLE ... DROP PARTITION在主上执行。v3_cam_date到 Master 的SELECTsSTART SLAVE;在奴隶上(复制ALTER TABLE ... DROP PARTITION到奴隶)这可能是你唯一的办法。唯一的其他办法就是等待ALTER TABLE ... DROP PARTITION.
这种情况需要对应用程序进行一些干预。在您的应用程序中,您必须在 Master 上创建一个 Write DBVIP,并使用 Read DBVIP 和以下三 (3) 个选项之一:
ALTER TABLE,将读取 DBVIP 移至 SlaveALTER TABLE已经完成,移动阅读DBVIP法师从长远来看,选项#1 似乎是最简单的方法。
小智 -7
我通过重新启动 MySQL 服务,然后尝试删除分区来解决这个问题。此后放置分区将生效。发生这种情况是因为二进制日志显然有一些尚未在该表中完成的内容。
我希望这些信息对您有所帮助。