2

我有一个庞大的数据库服务器,里面有很多非常相似的 InnoDB 数据库。我经常运行的查询只是更新小表中一行的时间戳。大部分时间这需要 1-2 毫秒。有时,在晚上,可能在备份和 maatkit 复制工具正在运行时,这些查询中的一个或多个可能会在几分钟内显示“正在更新”。在此期间,其他查询,包括 maatkit 查询,似乎都在正常进行,似乎没有其他查询在执行。我一直无法解释或解决这个问题。

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

有没有其他人听说过这个?解决了这样的事情?关于如何调查的任何想法?

4

3 回答 3

1

进行DML操作时,InnoDB将锁放在行和索引间隙上。

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

说,如果你运行这个查询:

UPDATE  mytable
SET     value = 10
WHERE   col1 = 1
        AND col2 = 2

,锁定将取决于用于查询的索引:

  • 如果使用了索引col1, col2,则只有受影响的行将被锁定

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

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

  • 如果没有使用索引,所有行和索引间隙都将被锁定(包括在 , 上的PRIMARY KEY,所以即使INSERT是一AUTO_INCREMENT列也会锁定)

更糟糕的是,EXPLAINinMySQL对操作不起作用DML,因此您必须猜测使用了哪个索引,因为优化器可以选择任何认为最好的索引。

因此,您的复制工具和更新可能会同时锁定记录(如您所见,即使WHERE条件不重叠,这也可能发生)。

于 2010-02-12T15:27:11.630 回答
0

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

同样,您提到它似乎发生在 durint 备份中。你为此使用mysqldump吗?这将在转储处于活动状态时锁定表,以便转储的数据保持一致。

于 2010-02-12T19:22:32.720 回答
0

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

我认为 maatkit 的 mk-table-checksum 没有做“检查表”,但它具有类似的效果。关闭这个脚本可以显着减少问题,但我们相信没有这个脚本我们就活不下去。

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

于 2010-02-26T15:02:02.450 回答