本文主要梳理介绍云MYSQL客户端经常发生因redo覆盖导致备份失败原理逻辑。
一. 问题背景
在生产环境中,杭研部分实例备份失败问题,如下图所示:
排查备份日志,发现如下报错:
报错日志分析:
如下图xtrabackup备份原理图所示,xtrabackup备份期间会通过2个线程实现一边拷贝redolog,一边拷贝ibd文件,在此期间如果xtrabackup的redolog拷贝速度低于MySQL生成redolog的速率,两者差距会越拉越大,当redolog顺序写满后会从头开始覆盖写入,这时候就会导致xtrabackup再次拷贝redolog时发现对应的redolog已经丢失,于是抛出该错误。
xtrabackup备份原理图:
结合杭研业务和现网本身,罗列以下几点主要问题原因:
-
杭研本身数据量较大,备份时间较长。
-
杭研全天24H都会持续有数据写入,并没有所谓的业务低谷期。
-
现网MySQL的redolog默认大小为2G,日志容量比较小。
-
现网备份是直接备份到S3上,并不会在本地落盘,因此备份效率会折损。
二. redo写入监控
为了排查上述问题,首先需要监控MySQL的redo写入速率,这里通过监控MySQL中的Innodb_os_log_written状态值来实现。
Innodb_os_log_written:The number of bytes written to the InnoDB redo log files.
通过Innodb_os_log_written状态值,两次相减除以时间,从而获取该时间段内MySQL的平均redo写入速率。
三. 模拟S3备份失败
通过模拟不同redo写入速率情况下,S3备份失败的时间长短,从而总结出一定规律,为后续调整redolog大小给出一定的数据支撑。
测试场景说明
-
测试实例规格16c128G,数据量470G,100张表,单表4.7G。
-
通过设置不同的sysbench并发线程数,模拟出不同redo写入速率。
-
通过备份失败得到该redo写入压力下,xtrabackup拷贝redo的速率。(为什么不通过备份成功来计算redo拷贝速率:因为备份时长会随着数据量而改变,因此用备份时间内产生的redo大小除以备份时长不太精确,而用备份失败来计算则可以得到一个更加临界,也更具有参考意义的redo拷贝速率)
测试命令:
#通过sysbench模拟不同redo写入速率
nohup sysbench --db-driver=mysql --mysql-host=xxx --mysql-port=3306 --mysql-user=test \
--mysql-password='xxxx' --mysql-db=test --table-size=20000000 --tables=100 \
--report-interval=1 --db-ps-mode=disable --time=3600 --threads=4 oltp_write_only run &
#手动执行S3备份命令
xtrabackup --defaults-file=/etc/mysql/my.cnf --user=root --password=${MYSQL_ROOT_PASSWORD} --stream=xbstream \
--parallel=4 --compress --backup --target-dir=./ | s3cmd --no-ssl --access_key=xxxx --secret_key=xxxxx \
--host=xxx --host-bucket= put - s3://xxx/full.tar
测试结果
通过模拟不同redo写入速率的情况下,备份报错的时长,绘制了这张表格:
测试总结
根据上述表格,大概可以总结出以下结论:
-
redo写入速率越快,备份报错时间越短,我们通过获取备份时间内的redo写入大小除以备份报错时长得到redo写入速率,再根据redolog的总大小除以备份报错时长得到redo拷贝速率,两者相减得到偏差速率(即每秒未完成拷贝的redo大小)。
-
通过计算redo写入速率和偏差速率的比率,得到1个相对平均的比率值约等于0.56,即redo写入速率 * 0.56 ≈ 偏差速率。
-
另外同样测试了S3备份的平均备份速率,大约为100M/s,例如100G的数据量大约需要100*1024/100 ≈ 1024s ≈ 17min
-
最后我们得到了这样1个公式,redo总大小 ≥ 偏差速率 * 备份时长,这样才有可能不会出现备份时redo被覆盖的报错。
针对杭研的实例,下述列举了对应的数据情况:
四.调整redo大小后验证
对杭研重资源池32个实例统一调整redolog大小为16G,如下图所示:
经过一周的观察,原本备份会因为redolog偏小而一直引发redo被覆盖导致备份失败,后续增大redolog后,备份成功!!!
五. 现网redo默认大小建议
通过此次测试,认为现网redo默认2G的大小不太合适,建议增大redo 的默认大小,并且会随着实例的存储规格而进一步提高,下面给出建议方案:
附录:
实时监控Innodb_os_log_written写入速率脚本:
#!/bin/bash
mysqladmin -P3306 -uroot -p${MYSQL_ROOT_PASSWORD} -h127.0.0.1 -r -i 1 ext |
awk -F"|" \
"BEGIN{ count=0; }"'{ if($2 ~ /Variable_name/ && ((++count)%2000000000 == 1)){\
print "------Time-----|---log_written(KB)---|";\
}\
else if ($2 ~ /Innodb_os_log_written/){Innodb_os_log_written=$3/1024;}\
else if ($2 ~ /Uptime / && count >= 2){\
printf("%s |%22d \n",strftime("%m-%d %H:%M:%S"),Innodb_os_log_written)\
}}'
作者:
数据库产品部 - 运维安全组 - 许天云