【问题标题】:MySQL / InnoDB occasionally some updates run very slow, in 'Updating' statusMySQL / InnoDB 有时某些更新运行非常缓慢,处于“正在更新”状态
【发布时间】:2012-10-12 14:45:09
【问题描述】:

我们的数据库中的 UPDATE 性能偶尔会大幅下降。

例如,表 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)

上面的示例查询是在不到一周前“重建”(ALTER TABLE FooTable ENGINE=InnoDB;)的 InnoDB 表上运行的。我最初怀疑这与 InnoDB 已知的 varchar/非顺序 PK 的性能问题有关,但是我们有其他使用顺序 PK 的表并且遇到了相同的问题。

这是在生产服务器上: 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,但我在其他表上使用。

关于如何弄清楚需要这么长时间的更新阶段发生了什么的任何建议?

【问题讨论】:

  • EXPLAIN 是否与UPDATE 一起使用? SELECT BarColumn FROM FooTable WHERE varCharPK=... 的性能是否相同?我想知道它是否对索引做了一些奇怪的事情。
  • 您不能在 UPDATE 上运行解释,但是如果我将它转换为 SELECT,它看起来应该是这样,它使用键 PRIMARY,第 1 行。
  • 在查询运行时尝试执行“SHOW PROCESSLIST”。它可能会显示其他对表有锁定的查询。
  • 如果您在一天的不同时间点多次执行相同的“更新”序列 - 性能是否相同? (IE 控制插入的内容并测试其他因素)
  • @ethbunny 不,否则它运行得非常快。我目前倾向于过大/长时间运行的交易。

标签: mysql innodb percona


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    如何(将 varcharPK 转换为文本和)在 varcharPK 字段上使用哈希索引?

    alter table FooTable add KEY pk_index (varcharPK(100)) USING HASH

    我曾经遇到过类似的问题,这很有帮助。我不确定它会帮助你。听起来如果您可以拆分表格也会很有帮助 - 它的数据“太多”。

    【讨论】:

    • 你能解释一下这个变化背后的逻辑吗?
    • 使用散列索引占用更少的索引空间,因此搜索和维护速度更快。检查这个:stackoverflow.com/questions/12689460/…
    • 此外,文本不与表格数据(如 varchar)一起存储,因此它也会让一切变得更快。
    猜你喜欢
    • 1970-01-01
    • 2012-02-20
    • 2012-09-23
    • 1970-01-01
    • 2018-12-14
    • 2018-01-22
    • 2013-06-27
    • 1970-01-01
    • 2016-01-26
    相关资源
    最近更新 更多