为什么一个简单的MySQL更新查询有时需要几分钟?

为什么一个简单的MySQL更新查询有时需要几分钟?,mysql,mysql-management,Mysql,Mysql Management,我有一个庞大的数据库服务器,有许多非常相似的InnoDB数据库。我运行的查询通常只是更新小表中一行的时间戳。这在大多数情况下需要1-2毫秒。有时,在夜间,可能在备份和maatkit复制工具运行时,其中一个或多个查询可能会显示“更新”数分钟。在此期间,其他查询(包括maatkit查询)似乎正在正常进行,并且似乎没有其他查询正在执行。我无法解释或解决这个问题 我们在一对4路Xeon上使用mysql 4.1.22和gentoo 2.6.21,该4路Xeon具有16gig的RAM和RAID驱动器用于存储

我有一个庞大的数据库服务器,有许多非常相似的InnoDB数据库。我运行的查询通常只是更新小表中一行的时间戳。这在大多数情况下需要1-2毫秒。有时,在夜间,可能在备份和maatkit复制工具运行时,其中一个或多个查询可能会显示“更新”数分钟。在此期间,其他查询(包括maatkit查询)似乎正在正常进行,并且似乎没有其他查询正在执行。我无法解释或解决这个问题

我们在一对4路Xeon上使用mysql 4.1.22和gentoo 2.6.21,该4路Xeon具有16gig的RAM和RAID驱动器用于存储。复制已到位且运行良好,maatkit每晚确认复制。InnoDB使用了大部分RAM,cpu的空闲率通常为70-80%。这个表有大约100行,每行大约200字节。我试过在WHERE子句上使用和不使用索引,没有明显的变化。未发现异常日志消息(已检查系统消息和mysql错误)


还有谁听说过这个吗?解决了这样的问题?有没有关于如何调查的想法?

在执行
DML
操作时,
InnoDB
会锁定行和索引间隙

问题是它锁定了所有被检查的行,而不仅仅是那些受影响的行

例如,如果运行此查询:

UPDATE  mytable
SET     value = 10
WHERE   col1 = 1
        AND col2 = 2
,锁定将取决于用于查询的索引:

  • 如果使用了
    col1,col2
    上的索引,则仅锁定受影响的行

  • 如果使用了
    col
    上的索引,则
    col1=1
    的所有行都将被锁定

  • 如果使用了
    col2
    上的索引,则所有
    col2=2
    的行都将被锁定

  • 如果未使用索引,则所有行和索引间隔都将被锁定(包括
    主键上的行和索引间隔,这样即使
    插入到
    自动增量列中也会被锁定)

更糟糕的是,
MySQL
中的
EXPLAIN
不适用于
DML
操作,所以您必须猜测使用了哪个索引,因为优化器可以选择任何它认为最好的索引


因此,您的复制工具和更新可能会同时锁定记录(您可以看到,即使
中的
条件不重叠,也可能会发生这种情况)。

如果您可以在挂起此查询时访问服务器,请尝试执行“显示innodb状态”。从中获得的混乱数据的一部分是InnoDB表上所有活动连接/查询的状态。如果您的查询由于另一个事务而挂起,则会在其中显示。有锁数据的样本


此外,您还提到,这似乎发生在备份期间。你在用mysqldump吗?这将在转储处于活动状态时锁定表,以便转储的数据保持一致。

使用响应中提供的一些信息,我们继续调查并发现服务器上存在一些令人不安的行为。任何数据库中任何表上的简单“检查表”都会导致简单的更新查询锁定其他数据库和其他表。我不知道为什么会发生这种情况,尽管我们无法在MySQL v5.1上复制它,所以我们打算升级我们的数据库服务器

我不认为maatkit的mk表校验和有“校验表”的作用,但它也有类似的效果。关闭此脚本可以显著减少问题,但我们相信没有此脚本我们无法生存


我将把这个标记为我问题的答案。谢谢您的帮助。

那么进程列表不会显示“已锁定”吗?我有一个“ShowFullProcessList”,显示maatkit在一个db上工作,其中一个普通更新查询在第二个db上“更新”,另一个相同的普通更新查询在第三个db上“更新”,并且没有运行其他查询。我没有发布processlist,因为它包含了我必须编辑掉的客户端名称。@PaulC:
ShowProcessList
对于
InnoDB
表,不显示
Locked
,只显示
MyISAM
。即使针对
InnoDB
表的操作正在等待锁定,它仍将显示为
update
。知道InnoDB在真正“锁定”时将显示“update”是非常有用的。禁用maatkit的重新同步暂时停止了该问题,因此看起来maatkit所做的某些事情会在相当长的一段时间内锁定某些东西。仍在调查。。。