写点什么

【YashanDB 知识库】存储过程报错 snapshot too old

作者:YashanDB
  • 2024-07-16
    广东
  • 本文字数:1443 字

    阅读完需:约 5 分钟

问题描述

20231127 上午客户反馈绩效系统 20231125、20231126 出现 2 次 YAS-02020 snapshot too old 的问题,测试也有类似问题。


该过程是客户新增的存储过程,目的是通过 PRO_RUN_JOB 作为主控,调度其他存储过程,后续不用其他调度引擎。

原因分析

错误信息收集分析

分析存储过程报错日志,核查 UNDO_RETENTION、undo 表空间


看了相应的优化建议,可以增大参数 UNDO_RETENTION 的值,或者使用更大的 undo 表空间。


客户环境目前 UNDO_RETENTION 配置了 600,该参数单位是秒。临时修改客户测试环境的配置为 3000,试图规避问题。


正常理解,MVCC 用于高并发的情形,会出现该错误,而该存储过程执行是串行的,不符合预期!需要继续分析。

UNDO、MVCC 机制分析

了解背后机制,snapshot too old 是由于 db 需要做多版本控制(mvcc),在数据 commit 之后,仍然会保留 undo 一段时间,在超过这段时间之后 undo 的空间会被复用,如果需要还原的数据超过了这个时间,则还原不了,触发该错误。


崖山 db 快照隔离级别的核心就是 MVCC(Multi-Version Concurrency Control),多版本并发控制


快照本质上就是一个时间点。记录版本的时间点为事务提交的时间点。


可见性可分为 2 类情况:


1、事务内的语句可见性


2、事务间的可见性


由于老版本保留时间的限制,我们可能无法读取到某些很老的版本,这时就会有 snapshot too old 错误。


事务功能梳理 - YashanDB



可以确认:


  • 不同事务间,特别是长查询,容易出现该问题;

  • 另一个是专门的快照读,如 Oracle 的快照读 select count(*) from tableA as of timestamp to_timestamp('2013-10-16 08:46:57','yyyy-mm-dd hh24:mi:ss');

疑点一

分析测试环境出现过类似的问题,看到报错的时间点:


2023/11/23 13:21:52 执行的是 PRO_DAILY_DPSIT


2023/11/23 12:04:00 执行的是 PRO_SYS_USER_POST_REL


有个共同点:


PRO_SYS_USER_POST_REL 用的是 merge,同时读和写同个表


PRO_DAILY_DPSIT 用的是 insert into select,insert 和 select 的表有相同的


开始怀疑这里有并发机制,读写自同个表,但是作为同个事务内的,undo 不应该被释放掉,不符合预期!

确认问题

剩下的就是长查询的可能。只有在查询的时候才会报这个错误,update 的时候是不会报这个错误的。


继续分析游标 loop 的结果,如果在游标读取的时候报错,则 remark 也是:更新跑数任务明细表:单个任务成功结束的相关信息


fetch 在一开始就拿到 scn(SCN 即系统改变号(System Change Number)),每次 fetch 都用的 open 时的 scn,由于 loop 过程中还是 update RUN_JOB_DETA 表更新了 db 存储的某一个 block,commit 之后 undo 的数据会保留 undo_retention 的时间,当超过这个时间 undo 的空间会别其他任务复用。


而一个 block 不止一条数据,在后续 loop 的过程,如果继续读取到这个 block 的数据,需要对这个 block 还原到 scn 对应的状态再读取,由于 undo 已经被复用,就会报 snapshot too old 的错误。


undo 机制、MVCC 机制,在 Oracle、DB2 中都是有的,该问题也会存在。崖山的数据块不会存 2 个表的数据,可以使用下面方法规避:


PRO_RUN_JOB 这个存储过程使用游标读取 RUN_JOB_DETA 表做为配置表,loop 过程中需要更新的结果数据放到历史表(主要更新任务状态,开始、结束时间,耗时),配置表和历史结果分开存储,彻底解决问题。

经验教训

  • Undo 机制中,undo_retention 是一个不容易理解的参数项。设置之后,Oracle 会根据自动 undo 管理的原则进行调节,进行空间拓展,来适应实现用户的期间要求。而崖山 db 需要根据实际的业务频繁度和数量量、以及 undo 表空间设置情况进行综合评估。

  • 存储过程存在游标遍历,需要注意更新目标表不是 fetch 的表,否则存在类似问题。

用户头像

YashanDB

关注

全自研国产新型大数据管理系统 2022-02-15 加入

还未添加个人简介

评论

发布
暂无评论
【YashanDB知识库】存储过程报错snapshot too old_yashandb_YashanDB_InfoQ写作社区