读书笔记:数据库的"记忆碎片"问题:为什么你的查询突然失忆了?

我们的文章会在微信公众号IT民工的龙马人生博客网站( www.htz.pw )同步更新 ,欢迎关注收藏,也欢迎大家转载,但是请在文章开始地方标注文章出处,谢谢!
由于博客中有大量代码,通过页面浏览效果更佳。

本文为个人学习《Expert Oracle Database Architecture Techniques and Solutions for High Performance and Productivity(第四版本》一书过程中的笔记与理解分享,仅用于学习与交流,部分内容参考原书观点并结合>实际经验进行整理。若涉及版权问题,请联系删除或沟通处理。也请大家支持购买原版书籍。

数据库的"记忆碎片"问题:为什么你的查询突然失忆了?

大家好!今天我们来聊聊Oracle数据库中一个特别"矫情"的错误——ORA-01555快照过旧。这个错误就像是你让数据库回忆不久前的事情,它却突然失忆了!

这个错误有多"作"?

想象这样一个场景:

  1. 你刚整理完一个超大的文件柜(批量更新数据)
  2. 整理完就锁柜走人了(提交事务但没做后续操作)
  3. 一周后你想查某个文件(开始长查询)
  4. 期间同事们疯狂使用旁边的碎纸机(其他事务频繁提交)
  5. 当你终于找到那个文件时——糟糕!关键标签被同事的碎纸屑覆盖了!

这就是延迟块清除导致的ORA-01555错误!

为什么会出现这种"失忆"?

用生活场景来理解:

  1. 大扫除后遗症:你刚给整个图书馆的书籍都贴了新标签(批量更新),但没来得及登记到总目录(延迟块清除)

  2. 查询就像借书:你要借阅某本书时,需要检查标签是否合法(验证事务状态)

  3. 信息被覆盖:在你查阅期间,图书馆登记处换了新本子,旧记录没抄过来(撤销段被重用)

  4. 无法确认:现在既找不到原始标签记录,新本子又只记了新书(SCN超过查询时点)

如何预防这种"失忆症"?

方法一:给图书馆更好的登记系统(配置撤销表空间)

-- 创建能自动扩容的"登记本"
CREATE UNDO TABLESPACE undo_big
DATAFILE '/u01/undo_big.dbf' SIZE 4G
AUTOEXTEND ON NEXT 1G MAXSIZE 32G;

-- 规定"借阅记录至少保留2小时"
ALTER SYSTEM SET undo_retention = 7200;  -- 单位秒

方法二:大扫除后及时更新目录(收集统计信息)

-- 整理完书架后立即更新目录
EXEC DBMS_STATS.GATHER_TABLE_STATS('我的库','图书表');

方法三:优化查询方式

  1. 避免长时间查询:就像不要一次性借阅全馆书籍
  2. 分批处理:大查询拆分成小查询
  3. 避开高峰期:在事务少的时候跑大查询

实际工作中的小贴士

  1. 监控撤销空间使用:定期检查"登记本"还剩多少页
SELECT tablespace_name, status, sum(bytes)/1024/1024 "大小(MB)"
FROM dba_undo_extents
GROUP BY tablespace_name, status;
  1. 特别关注批量操作后:大更新后立即检查
-- 检查哪些块需要清理
SELECT COUNT(*) "待清理块数" 
FROM v$bh WHERE status = 'free' AND dirty = 'Y';
  1. 设置预警机制:当撤销空间使用超过80%时报警

记住这个口诀:

大操作后要整理,撤销空间留余地
长查询要优化,避开高峰最明智

现在,你的数据库再也不会关键时刻"掉链子"啦!

------------------作者介绍-----------------------
姓名:黄廷忠
现就职:Oracle中国高级服务团队
曾就职:OceanBase、云和恩墨、东方龙马等
电话、微信、QQ:18081072613
个人博客: (http://www.htz.pw)
CSDN地址: (https://blog.csdn.net/wwwhtzpw)
博客园地址: (https://www.cnblogs.com/www-htz-pw)

posted @ 2025-08-23 13:48  认真就输  阅读(7)  评论(0)    收藏  举报