本文介绍了由于日志文件过多导致存储空间被占满的问题描述、解决方案以及后续维护等内容。
问题描述
PolarDB MySQL版集群由于Binlog文件、Redo日志或者Undo日志过多,占用了太多存储空间,且在空间分析中确认日志空间使用量较高。如下图所示:
引发该问题的原因可能是由于大事务在快速生成Binlog文件、Redo文件或Undo文件时,占用了太多的集群存储空间。
解决方案
清理Binlog文件、Undo文件或Redo文件时,界面更新有延迟,请耐心等待。
由于DML等操作(比如涉及大字段的DML操作)会快速生成Binlog文件、Undo文件或Redo文件,在这种情况下,建议您考虑升级扩展存储空间,并且排查快速生成Binlog文件、Undo文件或Redo文件的原因。
若根据以下方案仍不能通过清理日志文件释放足够的存储空间,您可以清理其他类型的数据文件来降低存储空间使用率。详情请参见由于数据文件过多导致集群存储空间被占满的解决办法。
Binlog日志
保存策略
Binlog文件有如下两种保存策略:
开启Binlog后,文件默认保存3天,超过3天的Binlog文件会被自动删除。
说明在2023年11月23日前购买的PolarDB MySQL版集群,其Binlog文件默认保存两周(14天)。
在2024年1月17日前购买的PolarDB MySQL版集群,其Binlog文件默认保存一周(7天)。
关闭Binlog后,已有的Binlog文件会一直保留,不会自动删除。
修改保存时长
修改Binlog保存时长不会造成连接闪断,也不需要重启集群。
但如果修改保存时长导致大量Binlog文件需要被清除(如10 TB),则在清除时可能会造成短时间的数据库写入异常。因此,在Binlog文件较大的情况下,建议在业务低峰期进行操作,并分多次缩短Binlog的保存时长,每次清除一部分Binlog数据。
若您的集群已开启Binlog,您可以通过如下两种方式修改Binlog文件保存时长:
若集群版本为PolarDB MySQL版5.6,您可以通过修改loose_expire_logs_hours(取值范围为0~2376,单位为小时,默认值为72)的参数值来设置Binlog的保存时长。0表示不自动删除Binlog文件。
若集群版本为PolarDB MySQL版5.7或8.0,您可以通过修改binlog_expire_logs_seconds(取值范围为0~4294967295,单位为秒,默认值为259200)的参数值来设置Binlog的保存时长。0表示不自动删除Binlog文件。
说明通过修改这两个参数的参数值来设置Binlog的保存时长后,集群中历史Binlog文件不会被立即自动清除。此时若您需要清除历史Binlog文件,可以通过如下三种方法之一:
当集群中最后一个Binlog文件达到
max_binlog_size
,切换到新的Binlog文件后,这些历史Binlog文件将会被自动清除。使用高权限账号执行flush binary logs命令可以立即触发Binlog文件切换并清除过期的Binlog文件。
您也可重启集群。集群重启后将自动清除历史Binlog文件。
若您的集群未开启Binlog,此时如需删除Binlog文件,您可以重新打开Binlog,将上述Binlog的保存时长参数(loose_expire_logs_hours或binlog_expire_logs_seconds)设置为一个较小的值,等文件超过保存时长自动删除后再关闭Binlog。
Redo日志
Redo日志正常情况下会在备份完成后自动清理,无需手动干预。但由于存在Redo文件缓存池,通常Redo会占用2~11 GB左右的空间,最多时会占用11 GB,其中包括缓冲池中的8个Redo日志(8 GB)、正在写的Redo日志(1 GB)、提前创建的Redo日志(1 GB)以及最后一个Redo日志(1 GB)。您可以通过参数loose_innodb_polar_log_file_max_reuse
来调整保留的Redo文件缓存个数,从而减少日志空间占用量,但在压力大的情况下,性能可能会出现周期性的小幅波动。
Undo日志
检查是否有未提交的旧事务,PolarDB中的Undo log承担MVCC的历史版本作用,因此当有未提交事务持有旧的Read View时会阻塞Undo log的清理,造成空间积累。您可以使用以下命令查看是否存在大事务:
SELECT * FROM INFORMATION_SCHEMA.innodb_trx;
PolarDB的只读节点与读写节点共享存储,只读节点上的未提交的大事务同样会影响Undo log的清理,在kill掉事务对应的线程后,Undo会停止继续扩大。如果需要回收Undo文件,您可以通过如下步骤确定Undo history推进情况后,再进行Undo文件的空间清理。
当写入压力大时,确定是否将Undo清理滞后,PolarDB的策略会优先保证当前的写入性能,可能会导致Undo log的清理滞后。您可以通过如下命令查看当前Undo history的长度:
SELECT COUNT FROM INFORMATION_SCHEMA.innodb_metrics WHERE name = 'trx_rseg_history_len';
如果该值大于100万,或者几分钟的时间内,该值还在不断地上升,并且当前压力确实比较大,可以通过如下步骤调整:
将参数
innodb_purge_batch_size
的值调大,该操作不会重启集群。将参数
innodb_purge_threads
的值调大,建议跟集群规格中的核数一致,该操作会重启集群,建议在业务低峰期操作,等待Undo history长度降低以后,Undo空间会停止增长,如果需要回收Undo空间,可以打开Undo truncate开关进行清理。
将
innodb_undo_log_truncate
参数的值设置为ON,来打开Undo truncate开关。由于Undo truncate功能会在集群切换或重启时带来额外的开销,建议在空间回收后立即关闭该功能,尤其是发起小版本升级等任务之前先关闭。需要的时候再打开。PolarDB维护8个Undo文件,当单个文件超过innodb_max_undo_log_size
后,就会触发Undo truncate。innodb_max_undo_log_size
默认为8 GB,因此如果长时间超过8 GB,写入压力较小,并且集群版本比较老,可以尝试做小版本升级来升级到最新版本。说明一些历史版本存在Undo truncate相关缺陷,关闭了修改
innodb_undo_log_truncate
的权限,导致在参数修改界面找不到该参数。此时需要通过小版本升级操作将当前版本升级到最新的版本。
后续维护
扩展存储空间,PolarDB MySQL版采用存储与计算分离的架构,您可以选择手动扩容/缩容存储空间或设置自动扩展标准版存储空间两种方式中的任意一种来扩展当前的存储空间容量。