後悔藥undo

640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1




01
web

作錯事情的時候,咱們常常對本身說的最多的一句話就是:要是當時不這麼作就行了,要是能復原就行了。現實中沒有後悔藥,oracle中有後悔藥,這個後悔藥就是undo。
sql



02數據庫

咱們對數據執行修改時,數據庫會生成undo信息,以便未來須要的時候能夠把數據變動回修改以前的狀態。此外,當你執行的事務或語句因爲某種緣由失敗的時候,或者你用一條rollback語句請求回滾時,oracle也須要利用這些undo信息將數據恢復到修改以前的樣子。undo用於取消一條語句或一組語句的做用,它是存儲在數據庫內部一組特殊的段中,稱爲undo段。數據結構



03oracle

undo會將數據庫「物理地」恢復到某個語句或事務以前的樣子嗎?咱們例子探究下:
app

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

而後查詢這個表,咱們在slqplus中啓用AUTOTRACE,它會報告I/O使用狀況。ide

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

因爲延遲段建立特性,能夠看到對錶的I/O數爲零。所謂的延遲段建立,就是咱們在執行create table命令時,數據庫不會分配任何存儲空間,一個extents也不會。分配空間的動做會延遲到第一個insert動做,此時數據庫纔會真正建立段。
spa

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1

insert語句會致使Oracle數據庫爲表t分配更多的數據庫,當執行rollback命令時,這些新分配的數據塊沒有由於回滾而消失,它們還在那裏,並且已經格式化(這和Linux中掛載盤有類似性),只不過如今爲空。當咱們進行第二次全表掃描時,Oracle必須讀取這些block,看看其中是否包含數據。orm



04事務

下面咱們指定延遲段建立表:

sql>drop table t purge;

Table dropped;


sql>CREATE TABLE t(x int) SEGMENT CREATION DEFERRED;

Table created;


SQL>select extent_id,bytes,blocks from user_extents where segment_name='T' order by extent_id;

no rows selected;


SQL>insert into t(x) values (1);

1 row created.


SQL>rollback;

Rollback complete.


SQL>select extent_id,bytes,blocks from user_extents where segment_name='T' order by extent_id;

 EXTENT_ID      BYTES     BLOCKS

---------- ---------- ----------

         0               65536          8

 在此能夠看到,表建立以後沒有分配任何存儲空間-----這個表沒有任何extents。當咱們執行insert並緊接着執行rollback以後,能夠看到insert確實分配了存儲空間,不過rollback並無將分配的存儲空間「釋放」。



由此能夠看出,segment確實由insert建立可是未被rollback" 撤銷";另外一方面,由insert新建立的塊會被第二次查詢掃描。所以"後悔藥"undo是邏輯地將數據恢復到原來的樣子,某些修改會被"邏輯地"取消,可是數據結構以及數據塊自己在回滾後可能(與事務或語句開始以前的數據塊狀態)大不相同

相關文章
相關標籤/搜索