mysql 有负载

mysql 有负载

我的网站和服务器都很庞大和沉重,我的服务器有 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 的输出可能不相关。

相关内容