理解UNDO-1

2017-02-23 曾凡坤-小凡仙 曾凡坤一小凡仙
UNDO在ORACLE 里面是非常重要的组件,也是ORACLE能竞争过MSSQL,IBM等数据库的重要优势.后来MYSQL数据库的 innodb引撑也加入了UNDO特色.

UNDO是什么? 业界的叫法很多,中文名词也很多,然后对于理解它反而造成了混乱. 什么前滚,撤销,回滚.

实际上UNDO 就是UNDO .它只是暂时保存下过去的东西而已, 一个表空间.
好比我们要做某些事情需要临时空间来操作,也许叫工作空间. 当然我们的ORACLE也有个临时表空间. 不过我们的数据库里的数据很重要,干活之前得把原来的数据放在另外个地方保存起来.等活干好了,干完了,得到领导肯定的好评.那就可以把新数据存进数据库里面,原来的数据就可以废弃了!

所以UNDO实际修改数据临时把原来的数据存放的表空间, 太长了,简短说是,旧数据表空间!
那好了 我们有了旧数据表空间,保留旧数据可以干什么呢? 其实我们想到干什么就能干什么.
目前能干下面的事
1 我们活干失败了,领导不满意, 就要把数据恢复过来,或者叫还原回来
2 我们干活当中,是有个时间长度的,最小也要毫秒的时间.这个时候,别人来查数据,如果没有旧数据,那他该查什么呢? 等你活干完了,看新的数据吗? 可新数据不是他想要的.

好了 我们把上面1和2 拿数据库术语来说是
1 事务回滚 ROLLBACK,实列恢复. 实列恢复不仅需要REDO日志,也需要UNDO来参与
2 这叫读一致性,不能读脏,不能读已提交, CR块.ACID

一个事务的开始需要从UNDO里面要到东西才能干活. 得先获得UNDO表空间里的块.
事务叫做一系列的操作,可以通俗理解工作内容,工作步骤,工作流程. 翻译成IT术语就是一些列的SQL.
如果你写过存储过程的话,可以理解一个存储过程就一个事务单位.

所以UNDO和事务是挂勾的, 事务需要在UNDO里存放旧数据. 涉及到事务的地方有两个,一个是UNDO里面,另外一个是数据块里面的ITL槽. 叫做事务槽.

我们给事务分配个ID, 这个ID不是自增量,也不是时间量,而是跟UNDO有关的.
我们执行个事务如下:
update zfk set object_name=’zfk’ where object_id=9;
不提交它,然后查询事务表V TRANSATCION;.selectADDR,XIDUSN,XIDSLOT,XIDSQN,UBAFIL,UBABLK,UBASQN,UBAREC,STATUS,XID,FLAG,STARTSCNfromv transaction

XID 05001B00DEAF000 是十六进制的事务ID
它是由 XIDUSN.XIDSLOT.XIDSQN组成的. 把值转换成16进制 5=>05; 27=>1B;45022=>AFDE . 然这个值是反的.
这三个是什么呢? XIDUSN是UNDO段编号, XIDSLOT是段里面的事务槽编号,XIDSQN是该事务槽中第几次被重用. 也就是重用次数.

从上面XID的编码可以推算出,同时活跃的XID多少? 取决于UNDO表空间里的段多少,以及每个段里面的事务槽是多少.
在10G以后,UNDO采用自动管理模式,下图是系统自动生成的10个段.另外一个是SYSTME的

来我们看看UNDO段,段头块里面的信息

这个图只是让大家在大脑里有个映像而已,重点看事务控制区,事务表和空闲块.

这篇不详细讲事务的事情! 我们主题是UNDO嘛!!

UNDO段很多人把它做成圆圈形式,我觉得容易误解人,还有这个前值映像.

UNDO 里面的段,段中的块会反复地重用! 不仅是重用而且 要覆盖旧数据.
这就容易导致 ORA-01555 快照太旧. 结合上面的图好像是时钟样,转一圈,不管三七二十一就把前面的块给覆盖掉了.不是这样的感觉的.
从UNDO段头的块里面看到有个空闲块池! 那么这就涉及两个问题, 问题一就是事务槽的事务被重用,另外个是UNDO块的重用.是两个不同对象的重用.
ORACLE 对UNDO 块的重用是有条件的, 优先使用空闲块,否则就扩展,再者重用!

应像这图样在大脑里形成映像, 灰色的代表已经使用的UNDO块,绿色代表是未使用的块,叫空闲块.
因此UNDO表空间中的数据在不同时段就会有不同的状态显示,在dba_undo_extents 数据字典里记录了UNDO中每个区段的状态.
SQL> SELECT tablespace_name, status, SUM (bytes) / 1024 / 1024 as “Bytes(M)”
FROM dba_undo_extents
GROUP BY tablespace_name, status;
TABLESPACE_NAME STATUS Bytes(M)


UNDOTBS2 EXPIRED 1.4375
UNDOTBS2 UNEXPIRED .375
UNDOTBS2 ACTIVE .125
UNDOTBS1 EXPIRED 22
其中:
ACTIVE :未提交的事务所占用的UNDO块,该块所关联的事务并未提交,用于实现读一致性,所以该数据不能被其它事务的数据所覆盖 。
UNEXPIRED:已经提交但未过期的UNDO块,该UNDO块关联的事务已经提交,但是仍受到undo retention参数保持时间的影响,当undo表空间中没有可用的数据块时,这些数据块会直接被覆盖而进行重用。
EXPIRED: 事务已经提交,而且UNDO块保存时间已经超过undo retention参数指定的时间,属于已经过期的数据.可以被随时重用。
需要说明的是,当设置表空间启动Guarantee特性时,UNEXPIRED类型的块就必须要等到undo_retention 指定时间过期后才能被重用。

这个UNDO段没有空闲块了,那只好重用某些块了! 那到底重用哪些UNDO块呢?
仔细阅读上面的文字可以理清下.
实际上我们通过红绿灯来表示

1 优先重用绿色的 EXPIRED
2 接着重用 黄色的 RETENTION 保护期900秒中的块. 当然你可以制定规则,不可以重用黄色的.你可以使用ALTER TABLESPACE undotbs1 RETENTION GUARANTEE 修改UNDO表空间的属性,强制黄色的不能重用
3 从其他的UNDO段里偷空闲的UNDO块用

另外说下 11G有个讨厌的参数如下
–设置UNDO自动调优,它会使的UNDO长期得不到释放
alter system set “_undo_autotune” = flase scope=spfile;

一般来说UNDO表空间给一个数据文件,在LINUX下能扩展到32GB,基本上能满足所有的业务.
然并卵的事情,32GB UNDO也要使用掉,ORACLE很贪吃的, 按照上面的原则基本上先扩展后重用,也就是说32GB过不鸟几个月就到达了.UNDO空间使用率100% 其实这个没啥关系,除非你的磁盘空间真心的少,不够用的话,只要新建个UNDO表空间,再进行空间切换,释放旧的UNDO空间的磁盘大小.

再说下 一个事务申请一个UNDO块来使用, 这个时候是以独占模式霸占整个块. 也就是说该UNDO块只要它一个事务可以写,其他事务不可以写. 只有等它写完了,还有空闲的空间,别的事务就可以写.
另外一个事务,只能在一个UNDO段里面工作,原则上不可以跨段,使用别的段里的UNDO块.
这就是说事务最多使用的UNDO块数量,取决于UNDO段. 超过了就容易报
ORA-1628 回滚段达到32765最大值

也就是说我们要控制事务的大小,不能让它产生太多旧数据了,方法是分批修改数据.
这里再谈下前值映像. 很早以前,我一致认为是整个数据块,保存在UNDO里面,否则UNDO使用那么多呢? 这个前值映像真的不好理解,它实际上就是 该列的原值. 不是块,也不是一整行.

ORA-01555 快照太旧 这个错误是怎么回事呢? 其实这个错误在很早以前大约10年前吧,还挺流行的. 意思是说我要的旧数据找不到了,被重用了!
大家一看到是被重用了,就是手UNDO段要么太小了,只有不够用,不能扩展才开始重用.要么是事务太频繁了. 这个是什么意思呢? 也就是说事务非常多,在不能扩展的情况下,事务需要重用块.很不幸你需要的块被中招重用了.
这要从多方面优化, 1 是增加UNDO表空间大小.2优化你自己的查询语句或者其他DML语句.让其查询时间变短; 3 是优化大事务,让其使用更少的块.

图片请看微信公众号
http://mp.weixin.qq.com/s/-dRF1tagGQppfSHlRuPOSg

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值