问题描述

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. 使用Nginx在80端口上代理多个.NET CORE网站

    有两个.NET CORE3.1网站部署在CentOS7上(内网IP是192.168.2.32),现在想实现访问http://192.168.2.32时访问A网站,访问http://192.168.2. ...

  2. Spring Boot XML文件头

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-/ ...

  3. Java Executors类的9种创建线程池的方法及应用场景分析

    在Java中,Executors 类提供了多种静态工厂方法来创建不同类型的线程池.在学习线程池的过程中,一定避不开Executors类,掌握这个类的使用.原理.使用场景,对于实际项目开发时,运用自如, ...

  4. 【译】You probably should stop using a custom TaskScheduler

    来自Sergey Tepliakov的 https://sergeyteplyakov.github.io/Blog/csharp/2024/06/14/Custom_Task_Scheduler.h ...

  5. JuiceFS 直连 NFS 新功能介绍,赋能 NAS 进行 AI 训练

    NAS 通过提供多用户网络数据存取服务,极大地简化了数据共享和管理.而 NFS 作为实现这种共享的一种主流协议,尽管广泛应用,但在处理复杂的 AI 训练场景时常常受限于其性能和一致性问题. Juice ...

  6. [rCore学习笔记 02]Ubuntu 22虚拟机安装

    写在前面 本随笔是非常菜的菜鸡写的.如有问题请及时提出. 可以联系:1160712160@qq.com GitHhub:https://github.com/WindDevil (目前啥也没有 Ubu ...

  7. 文件系统(十):一文看懂 UBI 文件系统

    liwen01 2024.07.21 前言 UBI (Unsorted Block Images)文件系统是一种用于裸 flash 的文件系统管理层.它是专为管理原始闪存设备而设计,特别适用于嵌入式系 ...

  8. Nacos 高级详解:提升你的开发和部署效率

    Nacos 高级 一 .服务集群 需求 服务提供者搭建集群 服务调用者,依次显示集群中各服务的信息 搭建 修改服务提供方的controller,打印服务端端口号 package com.czxy.co ...

  9. win10远程桌面连接报错:出现身份验证错误,要求的函数不受支持(CredSSP)

    问题 解决办法 找到路径:计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System 在Syste ...

  10. 暑假java自学进度总结03

    一.今日所学: 1.标识符命名规则: 必须: 1>由数字,字母,下划线,美元符组成: 2>不能以数字开头: 3>不能是关键字: 4>区分大小写: 建议: 1>命名方法,变 ...