我有一台开发服务器,最近从 14.04 升级到 16.04。
我有一个数据库“algebra”,它托管我的网站 algebra.com 的数据。这是一个问答网站,包含问题和答案,具有 1 对 N 的关系。
升级后,完全相同的数据库查询的性能急剧下降。
例如,通过问题 ID 连接问题和答案的查询,过去只需不到半秒的时间。升级后,需要一分钟。
由于这是一台开发服务器,我可以将它与生产服务器进行比较,生产服务器仍然运行 ubuntu 14.04,并且相同的查询仅需要 0.38 秒。
以下是查询计划
mysql> explain SELECT
-> questions.id, questions.email, questions.topic, questions.question,
-> questions.date,
-> questions.deleted,
-> questions.is_spam,
-> questions.solved,
->
-> questions.tb_id,
-> questions.tb_isbn,
-> questions.tb_title,
-> questions.tb_edition,
-> questions.tb_chapter,
-> questions.tb_problem,
->
-> solutions.id, solutions.author author, solutions.date, solutions.answer
-> FROM questions, solutions
-> WHERE
-> questions.solved = 1
-> AND questions.id = solutions.question
-> AND questions.deleted != 1
-> AND questions.is_spam != 1
-> ORDER BY solutions.date DESC
-> LIMIT 50;
关于“好服务器”:
+----+-------------+-----------+--------+-----------------------+---------+---------+----------------------------+--------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+--------+-----------------------+---------+---------+----------------------------+--------+----------------+
| 1 | SIMPLE | solutions | ALL | solutions_by_question | NULL | NULL | NULL | 650770 | Using filesort |
| 1 | SIMPLE | questions | eq_ref | PRIMARY | PRIMARY | 4 | algebra.solutions.question | 1 | Using where |
+----+-------------+-----------+--------+-----------------------+---------+---------+----------------------------+--------+----------------+
2 rows in set (0.00 sec)
关于“糟糕的服务器:
+----+-------------+-----------+------------+------+-----------------------+-----------------------+---------+----------------------+--------+----------+----------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+-----------------------+-----------------------+---------+----------------------+--------+----------+----------------------------------------------+
| 1 | SIMPLE | questions | NULL | ALL | PRIMARY | NULL | NULL | NULL | 482186 | 8.10 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | solutions | NULL | ref | solutions_by_question | solutions_by_question | 4 | algebra.questions.id | 1 | 100.00 | Using index condition |
+----+-------------+-----------+------------+------+-----------------------+-----------------------+---------+----------------------+--------+----------+----------------------------------------------+
数据库内容大致相同,开发数据库是昨晚服务器的备份。
有什么想法我可以从哪里开始这项徒劳无功的追求来理解性能下降?
谢谢!
答案1
如果您已更新至 16.04 Ubuntu 服务器,并且正在使用 5.7.12,那么您将遇到(至少部分)占用 RAM 的错误,并且一些动态优化/默认设置基于服务器的可用 RAM,并且设置得不够理想。这对很多人来说都是个问题,尤其是对于 RAM 较低的小型服务器/vps。
在 laracasts.com 上搜索 MySQL 5.7 内存泄漏
https://www.reddit.com/r/mysql/comments/4gnj93/mysql_5712_ubuntu_1604_ridiculous_memory/
还有其他问题,其中一些当然已在 5.7.13 中修复……
http://mysqlentomologist.blogspot.com/2016/06/fun-with-bugs-43-bugs-fixed-in-mysql.html
还进行了一些不同的优化/更改,这些优化/更改会产生影响,具体取决于您是否使用 InnoDB 或 MyISAM。举个例子,最近安装的 VPS 具有 2 GB RAM,如果您重新启动 MySQL,它将消耗大约 320 MB RAM,在维护模式下,空闲应用程序的 RAM 会缓慢上升,直到消耗 1 GB...流量或数据库查询为零(这是使用 MyISAM 的 OpenCart 安装...我不希望任何试图继续前进的人遇到这种情况...但这是一个“快点让我们这样做,使用这个...”的情况)。因此,由于应用程序中对 MyISAM 的依赖、内存泄漏以及 Oracle 团队抛出的一些糟糕的默认值,该特定实例需要更多的金钱和时间来回过头来处理 MySQL 的相同性能不佳问题。
当然,您可能希望针对新更新优化查询和连接。但与此同时,由于底层内存泄漏(如筛选问题),您可能会浪费大量精力而一事无成。如果您要进行优化,您不妨使用与给您带来问题的 MySQL 服务器不同的服务器进行优化。
考虑到 MySQL 修复错误的速度有多慢,你的选择有:
1)坚持下去,等待 repo 更新来修复它
2)卸载当前版本并返回到以前的版本(但为什么?)
3)用 MariaDB 或 Percona 替换它
如果您启动新的 Ubuntu 16.04 服务器,我会在连接任何远程管理用户代理或安装服务器管理面板之前更改存储库,以便您能够使用 MariaDB/Percona。或者跟踪官方 MySQL 存储库而不是 Ubuntu 存储库,这样您就可以更快地获得修复。
安全且直接的解决方案(肯定比延长使用有错误和发布流中存在重大兼容性断点的早期版本更明智)是切换到 MariaDB 或 Percona。或者,如果您使用的应用程序可以使用 PostgreSQL 和 MySQL,请切换到 Postgre——如果这不是不切实际的。
我不会浪费时间尝试优化数据库,除非我已更新到 5.7.13 并监控结果,或者切换到 MariaDB 或 Percona。优化/故障排除 5.7.12 只是一个黑洞,会浪费你的时间和资源。
答案2
具体来说,这是错误从 5.7.8 开始,memory/innodb/os0file 中使用的内存过多。
在 Ubuntu 中它被跟踪为Ubuntu 16.04 中 mysqld 守护进程的内存消耗过多,还有Reddit 上的讨论。