当你的程序依赖于 MySQL 查询缓存…

前两天升级和迁移了一个 MySQL 环境,因为:

  1. 某天我发现原来的环境居然是个 RAID 0,尽管已经有个 Slave 环境了,但是把数据放在毫无冗余的磁盘上面实在是有太大风险。
  2. 系统需要扩展了,接手这个项目时候,程序和数据库都在一个机器,从性能、安全各个方面来说都不是很好的方案。
  3. MySQL 5.6 相比 5.5 在查询优化上面有很大的提升。
  4. 事实上刚好还有个 mongodb 需要升级版本,可以一起下线后升级。

OK,于是就找了个凌晨,下线、升级了,初看起来一切正常。

但是到了第二天,问题出现了。开发说从 MySQL 同步数据到 mongodb 非常慢,只有原来的 1/36!

于是都开始怀疑是 mongodb 的问题,难道是程序逻辑有问题?写新版本的 mongodb 没有对参数什么的?但是得到否定的答复。

。。。。。。

折腾了好一会儿,看了 mongodb 的各种文档之后,看了一下一直在跑着的 mongostat 输出,发现是有出现过高并发的写入(但不是出现问题的同步造成的),至少,这说明了——mongodb 升级后的写入功能本身是没有问题,事实上,观察到的结果是有提升。排除了 mongodb 的问题,心想是否可能 MySQL 的数据库问题,看了一眼慢日志,结果确实发现有大量的同一个超过 1s 的查询,时间点和同步一致。

问了一下开发,他们说这个查询应该会被缓存住,第一下很慢,但是后面就很快了!好吧,我看了一眼 MySQL 的查询缓存:

mysql> show status like 'Qcache%';

哈!全部是0,查询缓存被关闭了!

再查了一下 MySQL 的参考文档

query_cache_type
...
This variable defaults to OFF as of MySQL 5.6.8, ON before that.

MySQL 在 5.6 之前的版本是默认开启查询缓存的,而 5.6 开始却默认关闭了它!

于是,设置 query_cache_type=1 之后,重启 MySQL,同步一切正常了。

总结:MySQL 做了这个改动,但是却没有在它们的升级文档中给出说明;开发把程序一个重要的功能依赖于这个数据库缓存,也没有说明。谢谢你们一起给我出了难题!当然,更重要的一个事情是——升级之前没有彻底的测试过!!!所有人都想当然了,这是流程规范的问题。

CentOS 7 修改 MariaDB 的最大打开文件数

记一下这个坑

最近将一个 php 环境迁移到了 CentOS 7,一开始一切都好,但是网站正式上线后一段时间却老是出现 php-fpm 进程繁忙的情况了。

刚开始以为是 php-fpm 哪里配错了,后来才发现是 MariaDB 的问题,日志里面一直在报达到了最大打开文件数。看了下,发现最大可以打开文件数是 1024,确实小了。

limits.conf 里面是早就把限制调高了的,所以在 /etc/my.cnf 里面加了一行

open-file-limits = 10240

结果重启后却还是 1024。

最终是在 /usr/lib/systemd/system/mariadb.service 里面找到了线索

# It's not recommended to modify this file in-place, because it will be
# overwritten during package upgrades.  If you want to customize, the
# best way is to create a file "/etc/systemd/system/mariadb.service",
# containing
#       .include /lib/systemd/system/mariadb.service
#       ...make your changes here...
# or create a file "/etc/systemd/system/mariadb.service.d/foo.conf",
# which doesn't need to include ".include" call and which will be parsed
# after the file mariadb.service itself is parsed.
#
# For more info about custom unit files, see systemd.unit(5) or
# http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F
# For example, if you want to increase mariadb's open-files-limit to 10000,
# you need to increase systemd's LimitNOFILE setting, so create a file named
# "/etc/systemd/system/mariadb.service.d/limits.conf" containing:
#       [Service]
#       LimitNOFILE=10000

需要由 systemd 来提高最大可以打开文件数。

于是按照提示创建了 /etc/systemd/system/mariadb.d/limits.conf 加入了

[Service]
LimitNOFILE=65535

结果发现还是老样子

最终,再把 /etc/my.cnf 里面的 open-file-limits = 10240 删除掉才行。。。