【问题标题】:Connecting to MySQL database slow, takes n seconds连接 MySQL 数据库慢,需要 n 秒
【发布时间】:2017-07-05 18:23:15
【问题描述】:

为什么连接到我的 InnoDB 数据库经常延迟整数秒?

一些背景

我有一个非常小的 MySQL 数据库,由一个表“用户”(150 条记录)和一个表“连接”(增长到 150*150 条记录)组成。表和索引加起来不到 5 MB。

当用户处于活动状态时,“连接”中的 5-50 条记录会更改(权重已更改)或添加(如果它们尚不存在)。整个应用运行流畅,加载时间低于约 100 毫秒。

除非他们不是。

详情

即使在非常小的负载下,页面加载时间也会从 60 毫秒飙升到 1000 毫秒到 10000 毫秒之间。

使用 Symfony 中的分析器,我可以在 'getRepository' 语句上确定 95+% 的延迟,而每个查询只花费约 1 毫秒。这让我相信连接到数据库是一个缓慢的动作。我写了一个帮助脚本定期连接到数据库来测试这个理论。

<?php // call this script commandline using watch
$a = microtime(true);
$pdo = new PDO('mysql:host=127.0.0.1;dbname=mydb','myuser','mypass');
file_put_contents( 'performance.txt', (microtime(true)-$a).PHP_EOL, FILE_APPEND );

谜底

连接到数据库始终花费 1-3 毫秒、1,001-1,003 毫秒、2,001-2,003 毫秒、3,001-3,003 毫秒等。整数秒数加上正常时间。介于两者之间,例如 400 毫秒或 800 毫秒。由于没有写入,几乎立即建立了联系。一旦通过应用程序执行了一些写入,就会达到更高的数字。

是什么导致了这种行为? InnoDB page_cleaner 似乎每 1000 毫秒工作一次,也许这就是解释的一部分?

更重要的是,我该如何解决这个问题?我正在考虑切换到 MEMORY 表,但我想说应该有更优雅的选项。

编辑

应要求,the variables and global status

附加信息:我直接连接到 127.0.0.1(参见上面的代码 sn-p)并且我测试了 skip-name-resolve 标志没有效果。顺便说一下,这是一个 Debian 服务器。

编辑 2

我发现延迟是 1、3、7 或 15 秒。注意模式:1 秒,+2s,+4s,+8s。这看起来确实是一些超时问题...

【问题讨论】:

  • 如果我正确理解您的问题,如果问题是连接,则更改到内存表可能无济于事。我怀疑的事情:没有足够的线程/(db)连接可用,连接池设置(只是因为我们曾经遇到过问题:))或类似的东西。连接很慢,不是查询。也许在运行缓慢时看看innotop 屏幕?如果您没有看到任何长时间运行的查询和更高的负载,则说明创建连接存在问题
  • 不知道innotop,感谢您的提示。负载:0.00,QPS:10-20,慢速:0,QCacheHit:50%,KCacheHit:100.00%。看起来,查询真的不是问题。
  • 我切换到 MEMORY 作为测试。奇怪的连接延迟问题仍然存在......
  • 请提供SHOW VARIABLES;SHOW GLOBAL STATUS;。我怀疑其中埋藏着一些线索。 (使用 post.it 之类的,因为这个论坛无法处理那么多文本。)
  • 在 Windows 服务器上,我以前使用“localhost”作为主机时遇到过这个问题...输入 IP 地址并再次测试..

标签: php mysql innodb


【解决方案1】:

反向 dns 查找需要很长时间是很常见的。随着host_cache 的大小,它会产生不稳定的行为。

通过将其添加到 my.cnf 来关闭它

[mysqld]
skip-name-resolve

请注意,如果您更改此设置,所有授权都必须通过 ip,而不是通过名称。

manual 中还有更多内容可供阅读

【讨论】:

  • 我已经将此添加到 my.cnf 中,如配置转储 ("skip_name_resolve ON") 中所示。问题依然存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 2017-07-08
  • 2016-03-24
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
  • 2020-06-10
相关资源
最近更新 更多