1,检查是否有老事务未提交
PolarDB中的undo log承担MVCC的历史版本作用,因此当有未提交事务持有老的Read View会阻塞undo log的清理,造成空间积累。可用如下命令查看是否存在大事务
select * from information_schema.innodb_trx;
需要注意,PolarDB的只读节点由于跟读写节点共享存储,只读节点上的未提交大事务同样会影响undo log的清理
出现这种问题,再kill掉事务对应的线程后,undo会停止继续扩大, 如果需要undo文件回收,可以通过如下步骤2中确定undo hisotry推进解释后,在通过步骤3进行undo文件的空间清理(truncate)
2,确定是否undo清理滞后
当写入压力大时,PolarDB的策略会优先保证当前的写入性能,可能会导致undo log的清理滞后,可以通过如下命令查看当前undo history的长度:
select COUNT from information_schema.innodb_metrics where name = 'trx_rseg_history_len';
如果这值大于100万,或者几分钟的时间内,还在不断地上升,并且当前压力确实比较大,可以通过如下步骤调整:
1),调大参数innodb_purge_batch_size,这个不需要重启实例,可以观察一段时间
2),调大参数innodb_purge_threads,建议跟实例规格核数一致,这个需要重启实例,建议业务低峰操作
等待undo history长度降低以后,undo空间会停止增长,如果需要回收undo空间,见步骤3进行清理
3,打开undo truncate进行清理
可以调整参数innodb_undo_log_truncate=ON,来打开undo truncate,由于这个功能会在实例切换或重启是带来额外的开销, 建议在空间回收后就关闭,尤其是需要发起如小版本升级等任务之前先关闭。需要的时候再打开。
PolarDB维护8个undo文件,当单个文件超过innodb_max_undo_log_size后,就会触发undo truncate,这个默认一共8G,因此如果长时间超过8G,写入压力较小,并且实例版本比较老,可以尝试做小版本升级来解决
注:如果发现参数修改界面找不到innodb_undo_log_truncate参数
一些历史版本存在undo trucate相关缺陷,关闭了innodb_undo_log_truncate的修改,导致在参数修改界面看不到这个参数。遇到这种情况可以考虑升级到最新的小版本解决