写点什么

YashanDB|大事务回滚卡死全库,YAS-02016 报错怎么破?

作者:数据库砖家
  • 2025-04-24
    广东
  • 本文字数:1025 字

    阅读完需:约 3 分钟

在使用 YashanDB 过程中,一位用户因执行大数据量插入操作而导致全库卡死,后续操作全部报错:

YAS-02016 no free undo blocks

该问题背后,其实是 UNDO 空间管理不当+大事务操作未做拆分 所引发的连锁反应。

一、问题现场回顾

客户执行如下操作:

insert into target_tableselect * from big_table;  -- 源表数据量达 100G+
复制代码

执行持续时间长达 20 小时未完成;

客户为进行后续操作,强行 kill +重启数据库;

之后数据库一直处于回滚状态,任何 SQL 操作均失败,并报错:

YAS-02016 no free undo blocks
复制代码

二、环境信息

三、问题根因分析

  1. 事务太大,超出 UNDO 最大容量


    源表数据 100G,而 UNDO 表空间最大仅 64G;


    插入期间未做任何分批或索引优化;


导致 rollback 阶段也需要大量 UNDO 空间,但空间已满,写入失败。

  1. 强制 kill 导致 rollback 更慢


    kill 后数据库自动执行 rollback;


    rollback 过程中不能 truncate、不能重用 UNDO,只能原样重放;


    且 rollback 阶段不能新增 undo file(会报 YAS-02042),空间释放完全依赖 rollback 完成;


    索引过多,导致 IO 写入慢,进一步拖慢进度。

  2. 回滚期间 UNDO 空间未释放,影响全局操作

rollback 期间,所有新事务都需申请 UNDO;

但 UNDO 被大事务“霸占”,没有空闲块,导致所有操作都失败。

四、处理过程与关键操作

操作 1:尝试扩展 UNDO 空间(失败)

alter tablespace undo_ts add datafile 'undo02.dbf' size 10g;
复制代码

报错:YAS-02042 cannot execute tablespace DDL when the database is rolling back

操作 2:尝试缩短 UNDO 保留时间(效果有限)

alter system set UNDO_RETENTION = 3;alter system checkpoint;
复制代码

提交事务的 UNDO 可被释放;

但回滚事务仍占用空间,无法提前释放。

操作 3:删除目标表索引,提升 rollback IO 速度(效果显著)

rollback 前写入速度仅 400K/s;

删除索引后提升至 4MB/s;

rollback 完成耗时从数小时缩短至 20 分钟。

操作 4:rollback 后重建 undo 策略

增加两个 UNDO 数据文件;

修改插入逻辑,改为分批插入 + 拆分事务提交。

五、经验建议与总结

线上环境避免大事务


1、UNDO 空间提前规划

默认最大 64G,虽然支持自动扩展,但到上限后需手动扩容; 建议在大数据导入前手动添加数据文件,提升上限。

2、大事务建议先删除索引再导入

插入前删除或设置为 UNUSABLE; 插入完成后再 create index 或 rebuild; 可显著提升写入和 rollback 性能。

3、回滚期间尽量不操作系统

rollback 期间不建议频繁尝试新操作;

可通过 v$rollback、iostat 等观察进度;

避免再次触发新一轮 “YAS-02016” 错误。

用户头像

还未添加个人签名 2025-04-09 加入

还未添加个人简介

评论

发布
暂无评论
YashanDB|大事务回滚卡死全库,YAS-02016 报错怎么破?_数据库·_数据库砖家_InfoQ写作社区