达梦数据库报错“回滚记录版本太旧,无法获取用户记录”问题根源原理和解决方法
根本原因
导致这个问题的根本原因就是当报错的sql开始执行后,其他会话对该sql所用到的基表进行了表操作并提交,并且报错的这个sql的执行时间(从其他会话修改完成基表并提交后到报错的sql执行完成的时间)超过了数据库参数UNDO_RETENTION的限制。
解决办法
1、推荐方法:优化这个sql,让它的执行速度加快,这样执行时间就不会超过UNDO_RETENTION参数的限制,就不会报错。
2、当该sql没有较好的优化手段时:可以想办法保证在该sql执行时,没有其他会话去操作该表的数据。没有会话操作,就不会记录到undo日志中,也不会导致报错。即使这个sql执行1小时也不会报错。
3、调整数据库的UNDO_RETENTION参数
调整方法:这个参数默认是90,调整这个参数会直接影响ROLL表空间的大小,调整参数要慎重。
SP_SET_PARA_DOUBLE_VALUE (1,'UNDO_RETENTION',450);
undo_retention 建议按需配置,在ROLL表空间能保持较小的情况下(系统内的事务数比较少),可以适当放大一点。
反过来,如果系统内修改非常多,ROLL很大,那么undo_retention调大的话,一定要非常慎重;默认是90秒。
具体场景:如果需要调大undo_retention参数且当前数据库的ROLL表空间也已经非常大了;那么势必要考虑磁盘是否可以使用SSD,这种情况万万不可使用普通机械盘(同步写的IO速率比较一般的磁盘)。
宏观上,undo_retention的配置,是redo roll 的写入,和ckpt速率需要达到一个均衡的机制;或者可以短时间内失衡,但是在一个业务周期内,如果在有限的roll大小,可以再追回来,那么undo_retention可以适当调整;否则,一定要谨慎调整!