MySQL 内存优化

早上醒来,发现博客打不开了,提示无法连接数据库。通过终端登录,尝试连接 MySQL(Centos 7 一般用的是 MariaDB),果然无法连接,只得重启服务器来暂时解决。当时具体的报错信息已经忘了,只记得大概讲的是 MySQL 停止运行,又被锁定之类的。考虑到我的这台博客服务器内存较低,问题应该就出在 MySQL 的内存占用方面。果然,网上也有关于这方面的讨论。说是当服务器的内存过低,容易造成 MySQL 的运行经常性停止,其本质原因就在于不合理的缓存策略。那么,不妨就先从这方面入手去解决吧。

以往在服务器内存充足的时候,我们通常使用默认的 MySQL 配置。不过,这样的配置肯定需要耗费掉不少内存的。默认的配置如下:

performance_schema_max_table_instances 12500
table_definition_cache 1400
table_open_cache 2000

对于低内存的服务器(比如我的这台博客服务器只有 1G 内存),就应该适当地降低这些缓存的数值。在 Centos 7 的 /etc/my.cnf 配置文件中,加入如下修改:

[mysqld]
performance_schema_max_table_instances=400
table_definition_cache=400
table_open_cache=256

另外,我们也要考虑 MySQL 的最大连接数。过大的连接数会造成内存使用量过高,也会锁定 MySQL 服务器。那么也做一下修改吧。在上面那个配置中追加一条 max_connections 即可,如下:
通过如下方式,设置最大连接数:

[mysqld]
performance_schema_max_table_instances=400
table_definition_cache=400
table_open_cache=256
max_connections = 100;

这里遵循了一个小原则:对于小网站,最大连接数设定为 100 到 200 左右;而较为大型的网站可能需要 500 到 800,甚至更多。对于我这样的博客,100 也就够了。

此外,从性能的角度出发,还有一个参数可以配置。当我们连上 MySQL 后,可以通过如下命令查询

MariaDB [(none)]> show status like 'Threads%';

这时会返回如下结果:

+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_cached    | 0     |
| Threads_connected | 1     |
| Threads_created   | 123   |
| Threads_running   | 1     |
+-------------------+-------+
4 rows in set (0.00 sec)

其中,Threads_created 引起了我们的兴趣,因为随着请求数量的增加,其数值也变得越来越大。之所以线程会被不断创建出来,在于我们未对线程进行任何缓存处理。线程缓存自然加快了处理速度,不过也必然要占用更多内存。在 1G 物理内存的限制下,可以考虑把线程缓存数量 thread_cache_size 设置为 8,如下:

[mysqld]
performance_schema_max_table_instances=400
table_definition_cache=400
table_open_cache=256
max_connections = 100;
thread_cache_size = 8;

好吧,MySQL 的内存优化暂时就到这边。对这么一台低配的服务器,以后还是要继续观察内存的占用情况以及性能表现,针对各种问题适时适当地做出一些调整。

留下评论