![MySQL 内存使用量导致服务器崩溃](https://linux22.com/image/774348/MySQL%20%E5%86%85%E5%AD%98%E4%BD%BF%E7%94%A8%E9%87%8F%E5%AF%BC%E8%87%B4%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%B4%A9%E6%BA%83.png)
首先我想说的是,我是服务器管理工作的新手,但我非常感兴趣并渴望学习。我在 Digital Ocean 上托管了一个小型 WordPress 网站,该网站相对较新,几乎没有流量。Droplet 运行的是典型的 LAMP 堆栈,有 1GB 内存,根据我的经验,这在过去已经足够了,因为我倾向于不使用很多插件并使用相当轻量的主题。我安装的唯一一个以前没有用过的插件是 WordFence。无论如何,在开发过程中,我偶尔会收到一条错误消息,显示“与数据库建立连接时出错”,有时网站根本无法加载,通过 SSH 连接非常缓慢。今天我遇到了这个问题,在它自行解决后,我通过 SSH 进入以查看我能找到什么。以下是我能够收集到的信息:
top
由于 mysql 使用率很高,因此不断将其列在最顶部
1724 mysql 20 0 1333488 405436 0 S 0.7 40.5 0:11.53 mysqld
grep -Ei 'oom|out of memory' /var/log/syslog
Jan 25 15:18:40 droplet kernel: [599977.961722] oom_kill_process.cold+0xb/0x10
Jan 25 15:18:40 droplet kernel: [599977.961936] [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name
Jan 25 15:18:40 droplet kernel: [599977.962031] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/system.slice/mysql.service,task=mysqld,pid=31337,uid=112
Jan 25 15:18:40 droplet kernel: [599977.962130] Out of memory: Killed process 31337 (mysqld) total-vm:1342776kB, anon-rss:439804kB, file-rss:0kB, shmem-rss:0kB, UID:112 pgtables:1264kB oom_score_adj:0
Jan 25 15:18:40 droplet kernel: [599978.039990] oom_reaper: reaped process 31337 (mysqld), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
Jan 25 15:26:50 droplet kernel: [600468.028506] systemd invoked oom-killer: gfp_mask=0x100cca(GFP_HIGHUSER_MOVABLE), order=0, oom_score_adj=0
Jan 25 15:26:50 droplet kernel: [600468.028534] oom_kill_process.cold+0xb/0x10
Jan 25 15:26:50 droplet kernel: [600468.028658] [ pid ] uid tgid total_vm rss pgtables_bytes swapents oom_score_adj name
Jan 25 15:26:50 droplet kernel: [600468.028754] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/system.slice/mysql.service,task=mysqld,pid=67924,uid=112
Jan 25 15:26:50 droplet kernel: [600468.028885] Out of memory: Killed process 67924 (mysqld) total-vm:1310584kB, anon-rss:385228kB, file-rss:0kB, shmem-rss:0kB, UID:112 pgtables:1132kB oom_score_adj:0
Jan 25 15:26:50 droplet kernel: [600468.092875] oom_reaper: reaped process 67924 (mysqld), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
作为一个新手,我不确定这是否值得关注(可能是某种攻击),或者这只是 Digital Ocean 的一键式 WordPress 安装的配置,或者 1GB 内存可能已经不够了。任何见解都将不胜感激!
答案1
我不是 MySQL 专家,但我花了一些时间在我运行的非关键个人服务器上减少 MySQL 8.0 内存使用量,而且运行良好。其他人可能会发布更好的答案 - 与他们一起讨论这个问题。
我运行 AWS EC2 t3a.nano 服务器,该服务器有五个 Wordpress 实例、MySQL 8.x.、PHP 7.x 和一些其他程序,内存为 512MB,交换空间为 1GB,因此对于低流量网站来说,1GB 已经足够了。您可以根据需要添加一些交换空间,您的操作系统会将不需要的数据分页,以便正在运行的进程有更多可用的内存。
您需要将 MySQL 配置为在有限的内存下运行,例如减少 RAM 大小、缓冲区和关闭性能模式。减少 PHP RAM 使用量也有助于减少内存不足杀手启动的可能性。MySQL 8.0 使用的 RAM 仍然比 MySQL 5.6 多得多,不过专家可能比我更能减少它。
以下是我的 MySQL 8 配置中的关键部分 - 请注意,我不是 MySQL 专家,在应用此配置之前,您应该做一些研究来了解此配置。其中一些可能是默认值,但我通常会将大多数参数设置为接近其最低允许值。
您的配置文件可能位于不同的位置。请确保在开始任何更改之前备份整个服务器,并在更改文件之前备份文件。
/etc/mysql/conf.d/mysql.cnf
# global settings
performance_schema = OFF
innodb_buffer_pool_size=50M
innodb_flush_method=O_DIRECT
innodb_log_buffer_size=1048576
innodb_log_file_size=4194304
innodb_max_undo_log_size=10485760
innodb_sort_buffer_size=64K
innodb_ft_cache_size=1600000
innodb_max_undo_log_size=10485760
max_connections=20
key_buffer_size=1M
# per-thread settings
thread_stack=140K
thread_cache_size = 2
read_buffer_size=8200
read_rnd_buffer_size=8200
max_heap_table_size=16K
tmp_table_size=128K
temptable_max_ram=2097152
bulk_insert_buffer_size=0
join_buffer_size=128
net_buffer_length=1K
/etc/mysql/mysql.conf.d/mysqld.cnf
key_buffer_size = 16M
thread_stack = 256K
以下是我对 PHP 配置进行的一些调整,以减少 RAM 使用量
/etc/php/7.4/fpm/pool.d/www.conf
pm.max_children = 3
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 1
pm.process_idle_timeout = 20s;
pm.max_requests = 50
php_admin_value[memory_limit] = 64M
服务器统计
以下是服务器“top”命令的一些统计数据
全面的
- 内存 448MB,可用 42MB,已使用 190MB,缓冲区/缓存 216MB
- 交换 1024,725MB 可用,300MB 已用
流程
- MySQL Virt 1459020 Res 44696 CPU 3% 内存 10%
- PHP FPM 7.x Virt 223124 Res 32464 CPU 0% 内存 7%
- Nginx Virt 63932 Res 7520 CPU 0% 内存 2%