【发布时间】:2014-09-30 10:56:51
【问题描述】:
我遇到了以下问题,希望有人帮助我解决它... mysql版本5.6.19-0ubuntu0.14.04.1-log。
CREATE TABLE `dr` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`start_date` bigint(20) unsigned NOT NULL,
`end_date` bigint(20) unsigned NOT NULL,
UNIQUE KEY `id` (`id`,`start_date`),
KEY `start_date` (`start_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;
CREATE TABLE `map_dr2pdu` (
`drtable_id` int(10) unsigned NOT NULL,
`dr_id` bigint(20) unsigned NOT NULL,
`packet_location` bigint(20) unsigned NOT NULL,
`sctp_chunk` smallint(5) unsigned DEFAULT NULL,
KEY `dr_id` (`dr_id`),
KEY `drtable_id` (`drtable_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;
CREATE TABLE `dr_hot` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`start_date` bigint(20) unsigned NOT NULL,
`end_date` bigint(20) unsigned NOT NULL,
UNIQUE KEY `id` (`id`,`start_date`)
) ENGINE=MEMORY;
CREATE TABLE `map_dr2pdu_hot` (
`drtable_id` int(10) unsigned NOT NULL,
`dr_id` bigint(20) unsigned NOT NULL,
`packet_location` bigint(20) unsigned NOT NULL,
`sctp_chunk` smallint(5) unsigned DEFAULT NULL,
KEY `dr_id` (`dr_id`),
KEY `drtable_id` (`drtable_id`)
) ENGINE=MEMORY;
dr 和 map_dr2pdu 有分区(如果重要的话)。
dr_hot.id <===> map_dr2pdu_hot.dr_id
有一个客户端C1(自动提交关闭)
写入
dr_hot获取 LAST_INSERTED_ID 并将 1-n 条记录插入
map_dr2pdu_hot。
C1 提交政治:500 次插入或 1 秒(先到)
引入内存表只是为了支持高插入率。实际数据必须存储在dr 和map_dr2pdu (INNODB) 表中。让这个“旋转”
还有第二个客户端C2(自动提交关闭)
- 锁定
_hot表, - 存储其自动增量 ID
- 将其数据转储到内存中的文件中,
- 截断
_hot表(比删除更快) - 更新其自动增量 ID
- 提交
- 解锁表
- [从文件加载数据到 INNODB 表]
C2 开始工作时出现问题:
mysql> show processlist;
+--------+-----------------+-----------------+-----------+---------+-------+----------------+---------------+----+
| Id | User | Host | db | Command | Time | State | Info |
+--------+-----------------+-----------------+-----------+---------+-------+---------------------------------+----+
| 1 | event_scheduler | localhost | NULL | Daemon | 1 | Waiting for next activation | NULL |
| 57 | riva | localhost | riva | Sleep | 283 | | NULL |
| 115748 | root | localhost | riva | Query | 0 | init | show processlist |
| 117538 | riva | localhost | riva | Sleep | 10889 | | NULL |
| 120150 | riva | localhost | riva | Sleep | 30 | | NULL |
| 120155 | riva | localhost | riva | Sleep | 7 | | NULL |
| 120158 | riva | localhost | riva | Sleep | 5 | | NULL |
| 120161 | riva | localhost | riva | Sleep | 5 | | NULL |
| 120164 | riva | localhost | riva | Sleep | 5 | | NULL |
| 120167 | riva | localhost | riva | Sleep | 7 | | NULL |
| 120170 | riva | localhost | riva | Query | 22 | Waiting for table metadata lock | ALTER TABLE dr_hot AUTO_INCREMENT=1152885790 |
| 120178 | riva | localhost | riva | Sleep | 5 | | NULL |
| 120179 | riva | localhost | riva | Query | 23 | Waiting for table metadata lock | LOCK TABLES map_dr2pdu_hot LOW_PRIORITY WRITE |
| 120243 | riva | localhost | riva | Sleep | 24 | | NULL |
| 120244 | riva | localhost:40934 | riva | Sleep | 24 | | NULL |
| 120245 | riva | localhost:40935 | riva | Sleep | 24 | | NULL |
| 120246 | riva | localhost:40936 | riva | Sleep | 22 | | NULL |
| 120247 | riva | localhost:40937 | riva | Sleep | 24 | | NULL |
| 120248 | riva | localhost:40938 | riva | Sleep | 24 | | NULL |
| 120249 | riva | localhost:40939 | riva | Sleep | 24 | | NULL |
| 120250 | riva | localhost:40940 | riva | Sleep | 24 | | NULL |
| 120251 | riva | localhost:40941 | riva | Sleep | 22 | | NULL |
| 120252 | riva | localhost:40942 | riva | Sleep | 22 | | NULL |
| 120253 | riva | localhost:40943 | riva | Execute | 22 | Waiting for table metadata lock | INSERT INTO map_dr2pdu_hot (xdrtable_id, xdr_id, packet_location) VALUES (25, 6078, |
+--------+-----------------+-----------------+-----------+---------+-------+---------------------------------+------+
24 rows in set (0.00 sec)
mysql general_log + 进程列表:
119177 Execute INSERT INTO map_dr2pdu_hot (drtable_id, dr_id, packet_location) VALUES (26, 131287232, 606
4773029186237937)
119177 Query COMMIT
119453 Query LOCK TABLES map_dr2pdu_hot WRITE
processlist:
| 119453 | rivasense | localhost | rivasense | Query | 164 | Waiting for table metadata lock | LOCK TABLES map_dr2pdu_hot WRITE
119177 Query START TRANSACTION
119177 Execute INSERT INTO dr_hot ()
显示引擎innodb状态,不显示任何死锁,就像
mysql> select * from INNODB_LOCKS;
Empty set (0.04 sec)
mysql> select * from INNODB_LOCK_WAITS;
Empty set (0.00 sec)
据我了解:C1 获取插入锁定并且似乎没有提交,但它根据日志执行。因此,C2 无法锁定表。
请帮助找出根本原因。
2014 年 6 月 10 日更新:
当 C1 尝试将某些内容写入map_dr2pdu_hot 并且 C2 同时尝试锁定同一个表时,基本上问题可重现。这被视为“几乎”死锁(未在死锁中列出)并随着 lock_wait_timeout 过期而释放。
您能建议如何解决这样的问题吗?
【问题讨论】:
-
我们必须在 mem 表中使用,因为当它们用作 app 和 innodb(磁盘)表之间的缓冲区时,可以将插入率提高 3+x 倍...