日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

redo/undo

發(fā)布時(shí)間:2024/10/8 编程问答 75 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redo/undo 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、什么是redo?

redo:oracle在在線或者歸檔重做日志文件中的記錄的信息,外以出現(xiàn)失敗時(shí)可以利用這些數(shù)據(jù)來"重放"事務(wù)。
每個(gè)oracle數(shù)據(jù)都至少有二個(gè)在線重做日志組,每個(gè)組中的至少有一個(gè)成員,這些在線重做日志組以循環(huán)方式使用。
二、什么是undo?
undo:oracle在undo段中記錄的信息,用于取消或者回滾事務(wù)。
undo在數(shù)據(jù)庫內(nèi)部存儲(chǔ)在一組特殊的段中,稱作undo段。
利用undo段恢復(fù)數(shù)據(jù),不是將數(shù)據(jù)庫物理地恢復(fù)到執(zhí)行語句或者事務(wù)之前的樣子,只是從邏輯上恢復(fù)到原來的樣子,但是數(shù)據(jù)結(jié)構(gòu)以及數(shù)據(jù)庫塊本身在回滾后可能大不相同。oracle在回滾時(shí)候,它實(shí)際上會(huì)做與先前邏輯上相反的工作,對(duì)于每個(gè)insert,oracle會(huì)完成一個(gè)delete,對(duì)于每個(gè)delete,oracle會(huì)執(zhí)行一個(gè)insert,對(duì)于每個(gè)update,oracle則會(huì)執(zhí)行一個(gè)"反update",或者執(zhí)行另外一個(gè)update,將修改前的行放回去。

小實(shí)驗(yàn):

create table t as select * from all_objects where 1=0;
select * from t;
set autotrace traceonly statistics
select * from t;
insert into t select * from all_objects;
rollback;
select * from t;
set autotrace traceonly statistics
select * from t;

三、redo和undo如何協(xié)作?

undo信息存儲(chǔ)在undo表空間或者undo段中,但是也會(huì)受到redo的保護(hù)。

在dml語句中,redo和undo都會(huì)生成。update生成的undo要比insert大,因?yàn)閡pdate需要保存修改數(shù)據(jù)的"前"映像。

系統(tǒng)崩潰恢復(fù)有兩個(gè)過程,首先數(shù)據(jù)前滾,把系統(tǒng)放到失敗點(diǎn)上,然后回滾尚未提交的所有工作。這個(gè)動(dòng)作會(huì)再次同步數(shù)據(jù)文件。它會(huì)重放已經(jīng)進(jìn)行的工作,并撤銷尚未完成的所有工作。
oracle有一點(diǎn)很重要:rollback過程從不涉及到redo日志。只有恢復(fù)和歸檔時(shí)會(huì)讀取redo日志。oracle的目標(biāo)是可以順序?qū)憆edo日志,而且在寫日志時(shí)別人不會(huì)讀日志 。

四、commit會(huì)做什么?
commit通常是一個(gè)非常快的操作,而不論事務(wù)大小如何。
這是oracle提倡用戶的使用事務(wù)的提交根據(jù)業(yè)務(wù)來原因之一。commit的開銷存在二個(gè)因素:
1、增加與數(shù)據(jù)庫的往返通信。
2、每次提交時(shí),必須等待redo寫至磁盤,這會(huì)導(dǎo)致"等待"。在這種情況下,等待稱為"log file sync".
commit前做的工作:
1、已經(jīng)在SGA中生成了undo塊。
2、已經(jīng)在SGA中生成了已經(jīng)修改數(shù)據(jù)塊。
3、已經(jīng)在SGA中生成了對(duì)應(yīng)前二項(xiàng)的緩存redo。
4、取決于前三項(xiàng)的大小,以及這些工作花費(fèi)的時(shí)間,前面的某個(gè)數(shù)據(jù)或者某些數(shù)據(jù)可能已經(jīng)刷新輸出到磁盤。
5、已經(jīng)得到了所需的全部鎖。
commit時(shí)候做的工作:
1、為事務(wù)生成一個(gè)scn。每次有人commit時(shí),scn都會(huì)增1。
2、lgwr將所有余下的緩存重做日志條目寫至磁盤,并把scn記錄到redo日志文件中。這一步是真正的commit。如果出現(xiàn)了這一步,即已經(jīng)提交。事務(wù)條目會(huì)從v$transaction中刪除,這說明我們已經(jīng)提交。
3、v$lock中記錄著我們的會(huì)話持有的鎖,這些鎖都將被釋放,而排隊(duì)等待這些鎖的每一個(gè)人都會(huì)喚醒,可以繼續(xù)完成他們的工作。
4、如果事務(wù)修改的某些塊還在緩沖區(qū)緩存中,則會(huì)以一種快速的模式訪問并"清理"。塊清除是指清除存儲(chǔ)在數(shù)據(jù)塊首部的與鎖相關(guān)的信息。
五、rollback會(huì)做什么?
rollback必須邏輯地撤銷我們所做的工作,回滾時(shí)間絕對(duì)是所修改數(shù)據(jù)量的一個(gè)函數(shù)。
rollback時(shí)候做的工作:
1、撤銷已經(jīng)做的所有修改。其完成方式如下:從undo段讀回?cái)?shù)據(jù),然后實(shí)際上逆向執(zhí)行前面所做的操作,并將undo條目標(biāo)記為已用。
2、會(huì)話持有的所有鎖都將釋放,如果有人在排隊(duì)等待我們持有的鎖,就會(huì)被喚醒。
六、分析redo
redo管理是數(shù)據(jù)庫中的一個(gè)串行點(diǎn)。任何oracle實(shí)例都只有一個(gè)lgwr,最終所有事務(wù)都會(huì)歸于lgwr,要求這個(gè)進(jìn)程管理他們的redo,并commit其事務(wù)。lgwr要做的越多,系統(tǒng)就會(huì)越慢。
1、如何測(cè)量redo?
v$mystat:會(huì)話的統(tǒng)計(jì)信息。
v$statname:這個(gè)視圖告訴我們v$mystat中的每一行代表什么意思。
select b.NAME,a.VALUE from v$mystat a,v$statname b where a.STATISTIC#=b.STATISTIC# and b.name='redo size';

七、redo生成和before/after觸發(fā)器。
1、before或者after觸發(fā)器不影響delete生成的redo。
2、oracle9i release 2以及以前版本中,before或者after觸發(fā)器會(huì)使insert生成同樣數(shù)量的額外redo。在oracle 10g中,則不會(huì)生成任何額外的redo。
3、在oracle9i release 2 及以前的所有版本中,update生成的redo只受before觸發(fā)器影響,after觸發(fā)器不會(huì)增加任何額外的redo,不過oracle 10g中,
如果一個(gè)表沒有觸發(fā)器,對(duì)其更新期間生成的redo量總是比oracle9i及以前版本中要少。看來這是oracle著力解決的一個(gè)關(guān)鍵問題:對(duì)于無觸發(fā)器的表,要減少這種表更新所生成的redo量。
在oracle 10g中,如果表有一個(gè)before觸發(fā)器,則其更新期間生成的redo量比9i中更大。
如果表中after觸發(fā)器,則更新所生成的redo量與9i中一樣。

每個(gè)開發(fā)人員應(yīng)該具備的能力:
1、估計(jì)你的"事務(wù)"大小(需要修改數(shù)據(jù)量)。
2、在修改的數(shù)據(jù)量基礎(chǔ)上再增加10%-20%的開銷,具體增加多大的開銷取決于你的要修改的行數(shù),修改得行數(shù)越多,增加的開銷就越小。
3、對(duì)于update,要把這個(gè)估計(jì)值加倍。八、我能關(guān)掉redo日志生成嗎?
答案:不能。
1、在sql中設(shè)置nologging:有些sql和操作支持nologging字句,這個(gè)對(duì)象的所有操作在執(zhí)行時(shí)都不生成重做日志,而是說有些特定操作生成的redo會(huì)比平常少的多。
select * from v$database;
--改成archivelog mode
shutdown immediate
startup mount
alter database archivelog;
alter database open;
--改成noarchivelog mode
shutdown immediate
startup mount
alter database noarchivelog;
alter database open;
----------------------------------
drop table t;
@ 'C:\Oracle\mystat' "redo size"
create table t as select * from all_objects;
@ 'C:\Oracle\mystat' "redo size"
drop table t;
@ 'C:\Oracle\mystat' "redo size"
create table t nologging as select * from all_objects;
@ 'C:\Oracle\mystat' "redo size"
在noarchiving mode的數(shù)據(jù)庫中,除了數(shù)據(jù)字典的修改外,create table不會(huì)記錄日志,create index/drop index生成日志。
關(guān)于nologging操作,需要注意地方:
雖然是nologging mode,還會(huì)生成少量的redo,這些redo作用是保護(hù)數(shù)據(jù)字典。
nologging不能避免所有后續(xù)操作生成redo,在前面例子中,dml操作還會(huì)正常生成redo日志,sql*loader、insert /*append*/語法不生成日志。
在一個(gè)archivelog模式的數(shù)據(jù)執(zhí)行nologging操作后,必須盡快為受影響的數(shù)據(jù)文件建立一個(gè)新的基準(zhǔn)備份,從而避免由于介質(zhì)失敗而丟失對(duì)這些對(duì)象的后續(xù)修改。
2、nologing小結(jié):
索引的創(chuàng)建和alter(rebuild)。
表的批量insert(通過/*append*/)或者采用sql*loader,表數(shù)據(jù)不生成redo。
lob操作。
通過create table as select 創(chuàng)建表。
各種alter table 操作。
在一個(gè)archiveing mode數(shù)據(jù)庫中適當(dāng)使用nologging,可以加快許多操作的速度。

九、為什么不能分配一個(gè)新日志?
dbwr、lgwr、arch進(jìn)程操作時(shí)異步,如果dbwr還沒有完成redo日志所保護(hù)數(shù)據(jù)的檢查點(diǎn),或者arch還沒有把rdo日志文件復(fù)制到歸檔目標(biāo),就發(fā)生checkpoint not complete或者archival required。
解決辦法:
1、讓dbwr更快一些,可以使用async i/o、使用dbwr i/o從屬進(jìn)程,或者使用多個(gè)dbwr進(jìn)程。這個(gè)方法好處是:寧可ibuyong付出什么代價(jià)就能有所收獲,性能提高,而且不必修改如何邏輯/結(jié)構(gòu)/代碼。
2、增加更多重做日志文件。這種方法:可以消除系統(tǒng)中的"暫停",其缺點(diǎn)是會(huì)消耗更多的磁盤空間。
3、重新創(chuàng)建更大的日志文件。
4、讓檢查點(diǎn)發(fā)生得更頻繁,此方法很不可取。

十、塊清除。
block cleanout:即刪除所有修改數(shù)據(jù)塊上與"鎖定"有關(guān)的信息。
有二個(gè)場(chǎng)合會(huì)做block cleanout,在commit時(shí)候,在SGA中的數(shù)據(jù)塊中"鎖定"信息會(huì)被清除掉,不在SGA中的數(shù)據(jù)塊的將被忽略;這些被忽略的塊會(huì)在第一次訪問時(shí)候被清除。

十一、日志競(jìng)爭(zhēng)
出現(xiàn)日志競(jìng)爭(zhēng)時(shí),數(shù)據(jù)庫會(huì)提示“cannot allocate new log”。
原因可能是:redo放在一個(gè)慢速設(shè)備上。
redo與其他頻繁訪問的文件放在一個(gè)設(shè)備上。
以緩沖方式裝載日志設(shè)備。
redo采用一個(gè)慢速技術(shù),比如RAID-5.
解決方法:每組的redo日志文件放在不同的磁盤上;使用快速的設(shè)備;以raw磁盤裝載日志。
十二、臨時(shí)表和redo/undo
臨時(shí)表不會(huì)為它們的塊生成redo。因此,對(duì)臨時(shí)表的操作不是“可恢復(fù)的”,修改臨時(shí)表中的一個(gè)塊時(shí),不會(huì)將這個(gè)這個(gè)修改記錄到重做日志文件中,不過,臨時(shí)表確實(shí)會(huì)生成undo,而這個(gè)undo會(huì)記入日志,因此,臨時(shí)表也會(huì)生成一些redo。
臨時(shí)表的作用一般是insert和select為主。
十三、分析undo
1、dml操作生成undo情況
一般來說,insert生成的undo最少,因?yàn)閛racle為此所需要記錄的只是要“delete”的一個(gè)rowid;update一般排名第二,對(duì)于update,只需記錄修改的字節(jié);delete一般生成的redo最多,對(duì)于delete,oracle必須把整行的前映像記錄到undo段中。
如何測(cè)量?
在事務(wù)中,可以通過v$transaction.used_ublk字段察看。
drop table t;
create table t as select object_name unindexed,object_name indexed from all_objects ;
create index t_inx on t(indexed);
exec dbms_stats.gather_table_stats(user,'T');
SELECT used_ublk from v$transaction where addr =(select taddr from v$session where sid=(select sid from v$mystat where rownum=1));
update t set unindexed=lower(unindexed) ;
update t set indexed=lower(indexed);
2、ORA-01555:snapshot too old 錯(cuò)誤
錯(cuò)誤原因:undo段太小,不足以在系統(tǒng)上執(zhí)行工作;你的程序跨commit獲取;塊清除。
解決方案:適當(dāng)?shù)卦O(shè)置參數(shù)undo_retention(要大于執(zhí)行查詢嘴上的事務(wù)所需的時(shí)間),可以用v$undostat來確定長(zhǎng)時(shí)間運(yùn)行的查詢的持續(xù)時(shí)間,另外,要確保磁盤上已經(jīng)預(yù)留了足夠的空間,使undo段能根據(jù)所請(qǐng)求的undo_retention增大。
使用手動(dòng)的undo管理時(shí)加大或者增加更多的回滾段。這樣在長(zhǎng)時(shí)間運(yùn)行的查詢執(zhí)行期間,覆蓋undo數(shù)據(jù)的可能性降低。
減少查詢的運(yùn)行時(shí)間(調(diào)優(yōu))。
收集相關(guān)對(duì)象的停機(jī)信息,這個(gè)有助避免塊清除導(dǎo)致的錯(cuò)誤。
3、undo段大小確定
undo段管理方法:
自動(dòng)undo管理:通過undo_retention參數(shù)告訴oracle要把undo段保留多少時(shí)間。oralce根據(jù)并發(fā)工作負(fù)載來確定要?jiǎng)?chuàng)建多少個(gè)undo段,以及每個(gè)undo段應(yīng)該多大,這個(gè)undo管理的推薦方法。
手動(dòng)undo管理:dba根據(jù)估計(jì)和觀察到工作負(fù)載,確定手動(dòng)的創(chuàng)建多少個(gè)undo段,dba根據(jù)事務(wù)量和長(zhǎng)時(shí)間運(yùn)行查詢的長(zhǎng)度來確定這些undo段應(yīng)該多大。(問題:控制的參數(shù)有多少?)
在手動(dòng)undo管理中,undo段不會(huì)因?yàn)椴樵兌鴶U(kuò)大,只有insert、update和delete才會(huì)讓undo段增長(zhǎng)。所以dba需要定時(shí)調(diào)整undo段的大小。
在手動(dòng)undo管理中,回收機(jī)制是首先回收最小的undo段,如果所有的undo段的大小相同,會(huì)回收最老的undo段。因此遇到ora-01555錯(cuò)誤可能是系統(tǒng)中最小的回滾段指示的,就算你增加一個(gè)大的undo段也不能解決此問題,故建議設(shè)置一致的undo段大小。
4、延遲塊清除
在塊清除過程中,如果一個(gè)塊已經(jīng)修改,下一個(gè)會(huì)話訪問這個(gè)塊時(shí),可能必須查看最后一個(gè)修改這個(gè)塊的事務(wù)是否還是活動(dòng)。一旦確定該事務(wù)不再活動(dòng),就會(huì)完成塊清除,這樣另外一個(gè)會(huì)話訪問這個(gè)塊時(shí)就不必再經(jīng)歷同樣的過程。要完成塊清除,oracle會(huì)從塊首部確定前一個(gè)事務(wù)所用的undo段,然后確定從undo首部能不能看出這個(gè)事務(wù)很久以前就已經(jīng)提交,它在undo段事務(wù)表中的事務(wù)槽以及被覆蓋,另一種情況是commit scn孩子undo段的事務(wù)表中,這說明該事務(wù)只是剛剛提交。

轉(zhuǎn)載于:https://www.cnblogs.com/luoyx/archive/2011/12/22/2298669.html

總結(jié)

以上是生活随笔為你收集整理的redo/undo的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。