【发布时间】: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 地址并再次测试..