问题描述

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知识库】存储过程报错snapshot too old的更多相关文章

  1. TFDStoredProc执行sql server的部分存储过程报错,有的是好的。

    TFDStoredProc执行sql server的部分存储过程报错,有的是好的. Invalid character value for cast specification 暂时无解.用fdque ...

  2. Mybatis调用存储过程报错

    Mybatis调用存储过程 贴码 123456 Error querying database. Cause: java.sql.SQLException: User does not have ac ...

  3. mysql 创建存储过程报错

    在创建存储过程前把结束符定义为 delimiter // 然后再创建就不会报错

  4. C# 调用存储过程 Sql Server存储过程 存储过程报错,程序中的try

    C#程序调用Sql Server存储过程,存储过程中报错情况,返回值... 0.SQL存储过程 USE [Opos] GO /****** Object: StoredProcedure [dbo]. ...

  5. java 执行mysql 8.0.11存储过程报错The user specified as a definer ('root'@'10.%.%.%') does not exist解决办法

    执行存储过程,报错 java.sql.SQLException: The user specified as a definer ('root'@'10.%.%.%') does not exist ...

  6. 执行存储过程报错——ora-01031:权限不足

    1. 执行DDL报错 在oracle存储过程中,默认是可以直接执行DML和DQL的,但是执行CREATE这种的DDL则需要借助EXECUTE IMMEDIATE ···了,如下备份表语句 --抄表表备 ...

  7. 在mybatis中使用存储过程报错java.sql.SQLException: ORA-06550: 第 1 行, 第 7 列: PLS-00905: 对象 USER1.HELLO_TEST 无效 ORA-06550: 第 1 行, 第 7 列:

    hello_test是我的存储过程的名字,在mapper.xml文件中是这么写的 <select id="getPageByProcedure" statementType= ...

  8. navicat创建存储过程报错

    搞了半天这个恶心的报错,最后发现竟然是存储过程的一个varchar类型的参数没给长度,如varchar(64)长度必须指定不然就会报错: mark一记

  9. Oracle执行存储过程报错——ora-01031:权限不足

    执行DDL报错 在oracle存储过程中,默认是可以直接执行DML和DQL的,但是执行CREATE这种的DDL则需要借助EXECUTE IMMEDIATE 如: create or replace p ...

  10. PHP多次调用Mysql存储过程报错解决办法

    PHP多次调用Mysql数据库的存储过程会出现问题,主要问题为存储过程中执行多次SQL语句不能一一释放导致的,网上找了一些解决办法,比如使用 multi_query 然后一个一个释放,但是发现根本不适 ...

随机推荐

  1. Kubernetes(K8S)基本概念

    前言 有公司用 java 或 go , vue 或 react , linux 或 win ,但所有的大厂都在用k8s,没有或,而且是全世界.一个熟悉k8s的开发,薪资可以轻松上25的 base . ...

  2. Java中字符串去除空格

    1. str.trim(); 去掉首尾空格 2. str.replace(" ", ""); 去掉所有空格,包括首尾.中间 String str = " ...

  3. acwing 875

    acwing875 题目大意:快速幂模板题 Train of thought 此题如果采用暴力的做法时间复杂度为0(n*b); n为样例的数目,b是幂 我们想要优化暴力的做法,首先样例的数量是没有办法 ...

  4. 小程序-浅谈云函数获取数据和云数据库api获取数据的区别

    区别:在于条数的限制,云数据库api获取数据限制20条以内,云函数限制100条以内 index.wxml <button bindtap="shujukuget">数据 ...

  5. 薅 AWS 羊毛的船新方式,以 ChatBot 为例

    还在担心一年免费服务器到期后该怎么办?(Solo社区 投稿) 网上绝大多数薅 AWS 羊毛的教程都是在教大家如何申请创建一年免费的 VPS,太 OUT 了!就问一个问题,一年到期了那咋办? 其实,除了 ...

  6. Django 多数据库配置与使用总结

    Django 多数据库配置与使用总结 By:授客 QQ:103355122 #实践环境 Win 10 Python 3.5.4 Django-2.0.13.tar.gz 官方下载地址: https:/ ...

  7. vue codemirror sql编辑器功能 可自定义提醒(关键字,库名,表名),高亮,主题

    工作中再一次需要开发sql编辑器,优化上篇文章内容 https://www.cnblogs.com/Lu-Lu/p/14388888.html 本次功能是tab页打开多个sql编辑器,效果图: 安装: ...

  8. C# 通过反射(Reflection)调用不同名泛型方法

    概述 由于工作需要,需要通过数据类型和方法名控制方法走向 用到的数据类型有8种(string,Int16,Int32,Int64,Boolean,Byte,Single,Double) 读取的方法(参 ...

  9. 嘿,我使用了mp的自连接+分页查询之后,再使用条件查询居然失效了。

    原因:我想通过自连接查询将一个表的两条数据放在一起,为此我重写了mp的分页查询 IPage<Indi> selectIndiShow(IPage<Indi> page, @Pa ...

  10. android实现多线程基础

    //创建线程类 class Mythread extends Thread{ @Override public void run(){ //定义行为 } } //实例化线程类 MyThread mt= ...