我的网站和服务器都很庞大和沉重,我的服务器有 8GB RAM 和 6 核处理器。
我收到了托管团队的一封邮件,关于 mysql 数据库的负载,
现在我的网站运行速度真的很慢,我收到的邮件包含一个日志文件
root@server [~]# mysqladmin pr
+-------+------------------+-----------+--------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-------+------------------+-----------+--------------+---------+------+--------------+------------------------------------------------------------------------------------------------------+
| 17969 | leechprotect | localhost | leechprotect | Sleep | 103 | | |
| 18706 | database_user | localhost | database_name | Sleep | 25 | | |
| 18717 | database_user | localhost | database_name | Query | 19 | Sending data | SELECT DISTINCT SQL_CALC_FOUND_ROWS
se_users.user_id,
se_users.user_username,
se_users.us |
| 18737 | database_user | localhost | database_name | Query | 19 | Sending data | SELECT DISTINCT SQL_CALC_FOUND_ROWS
se_users.user_id,
se_users.user_username,
se_users.us |
| 18745 | database_user | localhost | database_name | Query | 20 | Sending data | SELECT DISTINCT SQL_CALC_FOUND_ROWS
se_users.user_id,
se_users.user_username,
se_users.us |
| 18752 | database_user | localhost | database_name | Query | 19 | executing | SELECT DISTINCT SQL_CALC_FOUND_ROWS
se_users.user_id,
se_users.user_username,
se_users.us |
| 18777 | database_user | localhost | database_name | Query | 17 | executing | SELECT DISTINCT SQL_CALC_FOUND_ROWS
se_users.user_id,
se_users.user_username,
se_users.us |
| 18815 | database_user | localhost | database_name | Query | 15 | Sending data | SELECT DISTINCT SQL_CALC_FOUND_ROWS
se_users.user_id,
se_users.user_username,
se_users.us |
| 18926 | database_user | localhost | database_name | Query | 2 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18951 | database_user | localhost | database_name | Sleep | 1 | | |
| 18952 | database_user | localhost | database_name | Query | 1 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18953 | database_user | localhost | database_name | Sleep | 1 | | |
| 18954 | database_user | localhost | database_name | Sleep | 1 | | |
| 18955 | database_user | localhost | database_name | Query | 3 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18958 | database_user | localhost | database_name | Sleep | 1 | | |
| 18960 | database_user | localhost | database_name | Query | 2 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18961 | database_user | localhost | database_name | Query | 2 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18962 | database_user | localhost | database_name | Query | 3 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18963 | database_user | localhost | database_name | Query | 3 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18964 | database_user | localhost | database_name | Query | 2 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18965 | database_user | localhost | database_name | Query | 1 | executing | SELECT DISTINCT SQL_CALC_FOUND_ROWS
se_users.user_id,
se_users.user_username,
se_users.us |
| 18967 | database_user | localhost | database_name | Sleep | 0 | | |
| 18968 | database_user | localhost | database_name | Query | 2 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18974 | database_user | localhost | database_name | Query | 2 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18978 | database_user | localhost | database_name | Query | 1 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18979 | database_user | localhost | database_name | Query | 1 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18980 | database_user | localhost | database_name | Query | 1 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18982 | database_user | localhost | database_name | Query | 1 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18983 | database_user | localhost | database_name | Sleep | 0 | | |
| 18984 | database_user | localhost | database_name | Query | 1 | executing | SELECT DISTINCT SQL_CALC_FOUND_ROWS
se_users.user_id,
se_users.user_username,
se_users.us |
| 18985 | database_user | localhost | database_name | Query | 1 | Sending data | SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1' |
| 18986 | database_user | localhost | database_name | Sleep | 0 | | |
| 18987 | database_user | localhost | database_name | Sleep | 0 | | |
| 18988 | database_user | localhost | database_name | Sleep | 0 | | |
| 18989 | database_user | localhost | database_name | Sleep | 0 | | |
| 18990 | root | localhost | | Query | 0 | | show processlist
我无法理解这个日志,有人能帮我吗
我的最高指挥
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
11050 mysql 15 0 1510m 272m 4080 S 629.0 7.0 675:31.90 mysqld
26990 database_user 16 0 130m 24m 6812 R 25.4 0.6 0:00.84 php
26989 database_user 16 0 155m 39m 7652 R 21.8 1.0 0:00.76 php
26988 database_user 16 0 154m 38m 7648 R 21.5 1.0 0:00.74 php
27011 database_user 16 0 0 0 0 R 18.8 0.0 0:00.57 php
26835 database_user 16 0 156m 40m 7632 R 17.5 1.0 0:00.69 php
26909 database_user 16 0 0 0 0 Z 16.5 0.0 0:00.68 php <defunct>
26977 database_user 16 0 0 0 0 Z 14.2 0.0 0:00.51 php <defunct>
26947 database_user 15 0 154m 37m 7632 R 12.9 1.0 0:00.58 php
26844 database_user 16 0 0 0 0 Z 11.2 0.0 0:00.59 php <defunct>
26956 database_user 15 0 154m 38m 7632 R 10.9 1.0 0:00.42 php
27005 database_user 16 0 146m 30m 7596 R 8.3 0.8 0:00.25 php
27058 database_user 16 0 139m 22m 7328 S 7.9 0.6 0:00.24 php
26878 database_user 16 0 0 0 0 Z 7.6 0.0 0:00.44 php <defunct>
27052 database_user 17 0 140m 23m 7292 R 7.6 0.6 0:00.23 php
27037 database_user 15 0 143m 26m 7320 S 7.3 0.7 0:00.22 php
26964 database_user 16 0 0 0 0 Z 6.9 0.0 0:00.29 php <defunct>
:)
答案1
你们托管团队提供的不是日志,而是从mysqladmin pr(ocesslist)获取的当前正在运行的Mysql进程。
并且您的 Mysql proc 列表显示您主要有 2 个查询的多个实例:
从 se_friends 中选择 count(friend_id) 作为 total_friends,其中 friend_status='1'
选择不同的 SQL_CALC_FOUND_ROWS se_users.user_id,se_users.user_username,se_users.us
我不确定它们是否完整,但你应该优化你的查询。例如: - 你应该使用 count(*) 而不是 count(friend_id)
您没有启用查询缓存吗?如果没有,您应该启用它,因为这将极大地提高性能。如果启用了,您应该检查查询缓存状态以进一步调整它,以便您最常用的查询保留在缓存中。
根据系统 top 输出,Mysql 占用了超过 600% 的 CPU,看来您的 Mysql 服务器急需调整。顺便说一句,您对 top 的解释是错误的,那不是数据库用户(mysql 用户),而是系统用户。
由于许多 PHP 进程也会消耗服务器负载,因此您的服务器总体上需要进行一些调整。尽早完成这项工作。
为了优化 Mysql,您应该尝试调整以下变量:
以下变量将设置全局缓冲区
最大连接数
最大用户连接数
表缓存
密钥缓冲区大小
查询缓存大小
下面的变量将设置每个线程缓冲区:
tmp_table_size 最大堆表大小
读取缓冲区大小 排序缓冲区大小
连接缓冲区大小
如果您使用 InnoDB,则必须调整以下变量:
innodb_log_buffer_size
innodb_additional_mem_pool_size
innodb_buffer_pool_size
还有许多其他变量需要考虑。但是,如果您调整上述变量以满足您的要求,那么在性能方面将产生巨大的差异。
但是,除非您真正了解这些变量的正确值,否则不要这样做。因此,在开始在生产服务器上调整 Mysql 之前,请先学习它,因为如果您做得不正确,可能会适得其反。
如果您没有足够的时间学习,请找一个了解这项工作的人来完成它。
答案2
“发送数据”处有大量进程意味着要么逻辑层中的响应处理存在严重问题,要么许多查询返回的结果集非常大。您没有提到逻辑层是在什么地方实现的。
查看 SQL,相同的 SQL 一次又一次出现:
SELECT count(friend_id) AS total_friends FROM se_friends WHERE friend_status='1'
我真诚地希望这是截断的 - 并且缺少更有意义和更具体的命令部分 - 否则这根本就没有意义。您应该能够从慢速查询日志中看到更多信息。
此查询仅返回一行。但 SQL 执行和逻辑检索数据大约需要 2 秒钟(由于没有执行任何这些操作,这表明查询运行非常快,不到 0.1 秒 - 大部分时间都被逻辑层占用)。虽然这可能是由于数据库和逻辑层之间的网络非常慢而引起的,但这里的情况并非如此(连接来自本地主机)。当上下文切换出现问题时也可能会发生这种情况 - 数据库服务器和客户端不断被其他进程抢占。但是对于 6 个核心,这将需要是一个非常激进的过程。
如果您可以让逻辑层更快地检索数据,这将对负载产生巨大的影响。
请提供有关正在运行的 SQL 和逻辑层以及“top”输出的更多详细信息
答案3
查看上面的时间列,似乎以下语句是最慢的:
SELECT DISTINCT SQL_CALC_FOUND_ROWS se_users.user_id, se_users.user_username, se_users.us
它花费了最多的时间,而且看起来它只是选择整个表,但我不能确定,因为看起来语句的其余部分被截断了......
为了改变这种情况,你可以包含一个引用索引的 WHERE 语句,使用限制命令,或者使用解释命令来调试你的语句。
您可能还想了解mysqltuner如果您有能力/权限调整数据库。如果您尝试调试 MySQL 数据库的负载,top 的输出可能不相关。