1. 问题现象
某客户MySQL数据库出现频繁carsh 掉,导致苍穹业务中断。数据库错误日志报错信息如下图所示。
统计最近几天carsh 的次数,10月11号当天carsh recovery 了10次。
根据报错信息分析mysqld got signal 11,信号量为11为内存段错误。根据以往经验出现这种错误要么是数据文件损坏或者触发了数据库的bug。首先我们根据抛出错误中的SQL语句拿到数据库中执行发现是可以正常执行出结果的,哪说明这个表对应的文件是没有损坏的,并且每次carsh 抛出的SQL语句对应的表都不相同,也都可以正常执行,这说明数据文件是没有损坏的。
此时我们就怀疑哪里触发了数据库的bug导致的carsh,计划升级到目前客户稳定运行的8.0.26版本。根据堆栈信息应该是在随机读取数据的时候出错了。
附堆栈对应的源码信息。ha_rnd_next该方法是从存储引擎层随机读取数据。
/**
Read next row via random scan.
@param buf Buffer to read the row into
@return Operation status
@retval 0 Success
@retval != 0 Error (error code returned)
*/
int handler::ha_rnd_next(uchar *buf) {
int result;
DBUG_EXECUTE_IF("ha_rnd_next_deadlock", return HA_ERR_LOCK_DEADLOCK;);
DBUG_TRACE;
assert(table_share->tmp_table != NO_TMP_TABLE || m_lock_type != F_UNLCK);
assert(inited == RND);
// Set status for the need to update generated fields
m_update_generated_read_fields = table->has_gcol();
MYSQL_TABLE_IO_WAIT(PSI_TABLE_FETCH_ROW, MAX_KEY, result,
{ result = rnd_next(buf); })
if (!result && m_update_generated_read_fields) {
result = update_generated_read_fields(buf, table);
m_update_generated_read_fields = false;
}
table->set_row_status_from_handler(result);
return result;
}
2. 数据库升级
升级数据库到8.0.26checklist
###########################
1.关闭数据库
systemctl stop mysqld
2.备份数据
cp -r mysqldata mysqldata.bak1011 ##大概40min,根据数据量测试评估
3.上传安装包
tar -xvJf mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz -C /home/KDCC/mysql/mysql
ln -s mysql-8.0.26-linux-glibc2.12-x86_64 mysql8.0.26
4.配置启动程序
cp /usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/mysqld.service.bak1011
vim /usr/lib/systemd/system/mysqld.service
ExecStart=/home/KDCC/mysql/mysql/mysql-8.0.23-linux-glibc2.12-x86_64/bin/mysqld_safe --defaults-file=/home/KDCC/mysql/mysql3306/etc/my.cnf --basedir=/home/KDCC/mysql/mysql/mysql
改成
ExecStart=/home/KDCC/mysql/mysql/mysql-8.0.26-linux-glibc2.12-x86_64/bin/mysqld_safe --defaults-file=/home/KDCC/mysql/mysql3306/etc/my.cnf --basedir=/home/KDCC/mysql/mysql/mysql8.0.26
systemctl daemon-reload
systemctl enable mysqld.service
5.启动数据库
systemctl start mysqld
查看错误日志是否有报错信息
6.回退
mv mysqldata mysqldata_1011
mv mysqldata.bak1011 mysqldata
mv /usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/mysqld.service_1011
mv /usr/lib/systemd/system/mysqld.service.bak1011 /usr/lib/systemd/system/mysqld.service
启动数据库
systemctl start mysqld
升级已经完成
3. 参数调整
苍穹在MySQL8.0.26 下也发生触发bug的情况,需要通过参数调整来规避bug
internal_tmp_mem_storage_engine=Memory ##规避/tmp/#sql1a324_1f4a_8b' is full报错
innodb_adaptive_hash_index = 0 ##规避频繁drop和Insert/load data bug
eq_range_index_dive_limit = 10001 ##优化sql中的in
range_optimizer_max_mem_size= 64M ##优化sql中的in
4. 建议
如果MySQL是8.0.19,8.0.21,8.0.23版本有出现宕机的情况可以升级到8.0.26版本。如果使用更高版本建议使用8.0.32