MySQL/InnoDB有时会有一些更新运行非常慢,处于“更新”状态

MySQL/InnoDB有时会有一些更新运行非常慢,处于“更新”状态,mysql,innodb,percona,Mysql,Innodb,Percona,我们的数据库中的更新性能偶尔会大幅降低 例如,表FooTable中有大约40列带有varchar PK,另外还有10个索引。下面的查询耗时44秒,而在其他时间,它几乎是立即运行的。在减速期间,服务器上的平均负载非常低,5分钟的平均负载为1.5,根据vmstat的IO也相当合理 这里有一个例子: mysql> update FooTable set BarColumn=1349981286086 where varcharPK='e4348411-0fbb-460a-80f7-f1de304

我们的数据库中的更新性能偶尔会大幅降低

例如,表FooTable中有大约40列带有varchar PK,另外还有10个索引。下面的查询耗时44秒,而在其他时间,它几乎是立即运行的。在减速期间,服务器上的平均负载非常低,5分钟的平均负载为1.5,根据vmstat的IO也相当合理

这里有一个例子:

mysql> update FooTable set BarColumn=1349981286086 where varcharPK='e4348411-0fbb-460a-80f7-f1de304a9f7c'
Query OK, 1 row affected (44.94 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> show profile for QUERY 1;
+----------------------+-----------+
| Status               | Duration  |
+----------------------+-----------+
| starting             |  0.000030 |
| checking permissions |  0.000004 |
| Opening tables       |  0.000007 |
| System lock          |  0.000003 |
| Table lock           |  0.000003 |
| init                 |  0.000035 |
| Updating             | 44.949727 |
| end                  |  0.000006 |
| query end            |  0.000003 |
| freeing items        |  0.000115 |
| logging slow query   |  0.000002 |
| logging slow query   |  0.000052 |
| cleaning up          |  0.000003 |
+----------------------+-----------+
13 rows in set (0.02 sec)
值得一提的是,上面的示例查询是在“重建”的InnoDB表上运行的,ALTER table FooTable ENGINE=InnoDB;不到一周前。我最初怀疑这与InnoDB已知的varchar/non-sequential PKs性能问题有关,但是我们有其他使用sequential PKs的表,也看到了同样的问题

这在生产服务器上: Centos 5 2.6.18-238.19.1.el5 x86_64 MySQL/Percona 5.1.57-rel12.8-log 96GB内存,58.8G数据分布在87个表中

InnoDB的相关设置如下:

innodb_flush_log_at_trx_commit  = 2
innodb_buffer_pool_size         = 70G
innodb_log_file_size            = 512M
innodb_log_buffer_size          = 64M
innodb_file_per_table           = 1
innodb_thread_concurrency       = 0
innodb_flush_method             = O_DIRECT
innodb_read_io_threads          = 64
innodb_write_io_threads         = 64
optimizer_search_depth          = 0
innodb_file_format              = barracuda
我没有在这个表上使用FORMAT=COMPRESSED,但是我在其他表上使用FORMAT=COMPRESSED


有没有关于如何找出更新阶段中发生了什么的建议?这需要很长时间?

如何将varcharPK转换为文本并在varcharPK字段上使用哈希索引

alter table FooTable使用哈希添加键pk_索引varcharPK100


我曾经有过类似的问题,这很有帮助。我不确定这对你是否有帮助。听起来,如果可以拆分表也会很有帮助,因为它有太多的数据。

根本原因似乎是长期运行的应用程序事务。解决方案是将大型事务分解为较小的工作单元

解释与更新一起工作吗?从FooTable中选择BarColumn(其中varCharPK=…)是否可以获得相同的性能。。。?我想知道它是否在索引方面做了一些奇怪的事情。你不能对更新运行解释,但是如果我将其转换为SELECT,它看起来应该是使用键PRIMARY,rows 1。尝试在查询运行时显示PROCESSLIST。它可能会显示表上有锁的其他查询。如果您在一天中的不同时间多次执行相同的“更新”序列,性能会相同吗?IE控制插入的内容并测试其他内容factors@ethbunny不,否则它运行得很快。我目前倾向于太大/长时间运行的事务。您能解释一下这一更改背后的逻辑吗?使用哈希索引占用更少的索引空间,因此搜索和维护速度更快。检查此项:文本也不会像varchar那样与表数据一起存储,因此它也会使一切运行得更快。