2

我们都知道 InnoDB 的更新是行锁的,而 MyISAM 的更新是表锁的,但是你怎么解释呢?以下是问题正在发生时的 SHOW FULL PROCESSLIST 的结果:

╔═════════╦════════╦═════════╦════════════════════════════════╗
║ Command ║ Time   ║ State   ║ Info                           ║
╠═════════╬════════╬═════════╬════════════════════════════════╣
║ Query   ║ 0      ║ NULL    ║ SHOW FULL PROCESSLIST          ║
║ Query   ║ 121    ║ end     ║ UPDATE [InnoDB table]          ║
║ Query   ║ 121    ║ update  ║ INSERT INTO [MyISAM table]     ║
║ Query   ║ 121    ║ Locked  ║ INSERT INTO [MyISAM table]     ║
║ Query   ║ 120    ║ Locked  ║ INSERT INTO [MyISAM table]     ║
║ Query   ║ 120    ║ Locked  ║ INSERT INTO [MyISAM table]     ║
╚═════════╩════════╩═════════╩════════════════════════════════╝

我留下了一些列以节省空间。以上都发生在一个数据库中,指的是单个 InnoDB 表和单个 MyISAM 表。在此下方还有许多其他行,类似于底部的三行,但我再次将它们排除在外。

问题是由 InnoDB 表上的 UPDATE 开始的,然后似乎锁定了 MyISAM 表。整个数据库没有被锁定,因为每秒发生数百个 SELECT 查询并且它们没有卡住。请注意,第一个 INSERT 的状态是“更新”,这可能是导致后续插入被锁定的原因,但这引出了一个问题:什么是 INSERT 更新?自动增量?表索引?想必。但是为什么这样的更新会被另一个表的 UPDATE 阻止呢?有关状态含义的详细信息,请参见此处:

http://dev.mysql.com/doc/refman/5.1/en/general-thread-states.html

这是我到目前为止所知道的:

  • 查询没有任何问题 - UPDATE 已被适当索引,并且 INSERT 和 UPDATE 查询通常都需要 < 100 毫秒的时间来执行,但正如您所见,这需要 2 分钟以上。
  • 几乎所有在数据库上执行的查询都是 SELECT 和 INSERT - UPDATE 是例外。
  • 这绝对是导致问题的 UPDATE ,因为它是半可复制的 - 如果我执行类似的查询,有时它会重新创建问题,有时它会正常执行。
  • 只有这个特殊的 InnoDB 表似乎是一个问题,因为数据库中的其他 InnoDB 表更新没有问题,但它是最大的 - 它包含约 100 万行,大小为约 40 MB。
  • UPDATE 被复制到多台服务器上,但较长的执行时间似乎只发生在那些负载很大的服务器上。
  • 当问题发生时,我检查了服务器上的 CPU 负载和可用 RAM,它们都很好。

服务器规格:

  • Debian 挤压
  • MySQL 5.1
  • 8核
  • 32 GB 内存

在你问之前,这里有一些 [mysqld] 配置设置:

skip-external-locking
innodb_file_per_table
innodb_flush_method     = O_DIRECT
innodb_buffer_pool_size = 512M
key_buffer              = 1500M
read_rnd_buffer_size    = 512k
table_open_cache        = 4096
tmp_table_size          = 256M
max_heap_table_size     = 256M
concurrent_insert       = 2
max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8
max_connections         = 2000
open_files_limit        = 60000
query_cache_limit       = 1M
query_cache_size        = 512M

经过广泛的谷歌搜索后,我仍然不知所措,因此将不胜感激地收到任何帮助!

添加

为 InnoDB 表创建语法:

CREATE TABLE `tablename` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `column1` bigint(20) unsigned NOT NULL,
  `column2` int(10) unsigned NOT NULL,
  `column3` int(10) unsigned NOT NULL,
  `column4` int(10) unsigned NOT NULL,
  `column5` int(10) unsigned DEFAULT NULL,
  `column6` enum('yes','no') NOT NULL DEFAULT 'no',
  PRIMARY KEY (`id`),
  UNIQUE KEY (`column1`),
  KEY (`column2`),
  KEY (`column5`)
) ENGINE=InnoDB AUTO_INCREMENT=993266 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
4

1 回答 1

0

由于您的状态处于“结束”状态。这些事情都可能发生

对于最终状态,根据文档可能会发生以下操作:

◾ 更改表中的数据后删除查询缓存条目

◾ 将事件写入二进制日志

◾ 释放内存缓冲区,包括 blob

我建议禁用您的查询缓存或将其设置为较小的大小。现在它和整个缓冲池一样大。

于 2013-11-06T15:59:42.773 回答