Linux Redhat 9 oom不触发
测试环境
Amazon AMI ID: ami-0e54fe8afeb8fa59a
Operating System: Red Hat Enterprise Linux 9.2 (Plow)
Kernel: Linux 5.14.0-284.11.1.el9_2.x86_64
MySQL Version: Ver 8.0.33 for Linux on x86_64 (MySQL Community Server - GPL)
测试步骤:
使用上面的AMI启动一个新的实例, 在实例启动之后ssh连接进去。
按照MySQL官方的 repo 安装一个社区的版本。
# https://dev.mysql.com/downloads/repo/yum/ # (mysql80-community-release-el9-1.noarch.rpm) wget https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm dnf install -y ./mysql80-community-release-el9-1.noarch.rpm dnf makecache -y dnf update -y # Refer this doc to install mysql-community packages. # https://dev.mysql.com/doc/refman/8.0/en/linux-installation-yum-repo.html dnf install -y mysql-community-server # Check the installation success. systemctl status mysqld
编辑MySQL配置文件, 添加如下的参数:
vim /etc/my.cnf #设置buffer pool 的参数大于物理内存。 例如 os 本身由可用的内存是 16G, 那么设置一个更大的值即可。 innodb_buffer_pool_size = 40G sudo systemctl enable --now mysqld sudo systemctl status mysqld # 获取root用户的临时初始化密码: sudo grep 'temporary password' /var/log/mysqld.log # 使用root用户登录, 并查看配置已经生效。 mysql -u root -p MySQL [(none)]> show variables like "%buffer_pool_size%"; +-------------------------+-------------+ | Variable_name | Value | +-------------------------+-------------+ | innodb_buffer_pool_size | 42949672960 | +-------------------------+-------------+ 1 row in set (0.005 sec)
创建database 以及 table:
create database test; CREATE TABLE tt1( id int NOT NULL AUTO_INCREMENT PRIMARY KEY, person_id tinyint not null , person_name1 VARCHAR(3000) , person_name2 VARCHAR(3000) , person_name3 VARCHAR(3000) , person_name4 VARCHAR(3000) , person_name5 VARCHAR(3000) , gmt_create datetime , gmt_modified datetime ) ; insert into tt1 (person_id, person_name1, person_name2, person_name3, person_name4, person_name5, gmt_create, gmt_modified) values (1, lpad('',3000,'*'), lpad('',3000,'*'), lpad('',3000,'*'), lpad('',3000,'*'), lpad('',3000,'*'), now(), now()); # 反复执行这个命令, 复制全表的数据, 大概执行 10 次左右。 insert into tt1 (person_id, person_name1, person_name2, person_name3, person_name4, person_name5, gmt_create, gmt_modified) select person_id, person_name1, person_name2, person_name3, person_name4, person_name5, now(), now() from tt1; # 查看当前table的信息 ,确认一下数据量。 show table status like 'tt1'\G
在另一个机器上面 select 这个表格。
select count(*) from tt1;
如果数据量足够大的话, 那么就会占用超过物理内存的空间,导致OOM。
问题
其他版本的os上面都会触发oom, 然后MySQL会被干掉重启, 只有Redhat 9 这个版本的os是不会触发的。
测试了Ubuntu 22, amazonlinux2, amazonlinux2023 都没由这个问题, 他们的内核都是 5.10+ 。
Redhat 9 这个版本的表现是, 在接近物理内存容量极限的时候, os 开始非常频繁的扫描并尝试回收内存的空间, 导致命令的响应变慢,我开了sar的监控命令,返回数据的速度也会便的比较慢, 大部分的进程会慢慢变成 Uninterreptable状态, 并且数量越来越多, 最终会导致实例的网络子系统不工作, 完全不响应任何的网络报文,实例的健康检查失败。CPU使用率依旧还在, EBS的监控显示这个卷满速度读取输出, 并且非常平稳, 响应时间以及队列的长度也没有异常。
如果这个时候尝试取手动触发oom, 是可以成功的, 在杀掉Mysqld之后, os就恢复了正常。
分析思路
可以确定的是 磁盘的工作是正常的, CPU使用率慢慢增长但是也是正常的。 这部分的工作没有问题。
在发生问题的时候因为网络无法正常的工作,ssh已经断开, 无法确定当时的情况。
初步判断是内存的问题, 但是具体的差异是哪里。
第一
sar命令中的记录
第二
尝试对比与行为正常的os的差异, 获取sysctl -a 并记录到文件中。
对比完关于内存部分的参数, 完全没有任何的差别, 不是设置或者配置文件导致的这个问题。
min 水位的设置是默认的, 与其他的发行版本一直, 测试的时候用的相同的规格, 所以不存在这类的差异。
第三
触发一个kdump 看看网络不相应的时候 os 当时的状态, 这个不太会。
第四
查看内核的编译选项, 看看有什么不同。
第五
学习os 内存的部分, 看看具体这个版本的内核如何进行内存的回收的, 或者触发oom的条件有哪些。