銅仁住房和城鄉(xiāng)建設(shè)局網(wǎng)站網(wǎng)上國(guó)網(wǎng)推廣
以下課程來(lái)源于MOOC學(xué)習(xí)—原課程請(qǐng)見:數(shù)據(jù)庫(kù)原理與應(yīng)用
考研復(fù)習(xí)
DBMS保證系統(tǒng)中一切事務(wù)的原子性、一致性、隔離性和持續(xù)性
DBMS必須對(duì)事務(wù)故障、系統(tǒng)故障和介質(zhì)故障進(jìn)行恢復(fù)
恢復(fù)中最經(jīng)常使用的技術(shù):數(shù)據(jù)庫(kù)轉(zhuǎn)儲(chǔ)和登記日志文件
恢復(fù)的基本原理:利用存儲(chǔ)在后備副本、日志文件和數(shù)據(jù)庫(kù)鏡像中的冗余數(shù)據(jù)來(lái)重建數(shù)據(jù)庫(kù)
常用恢復(fù)技術(shù)
事務(wù)故障的恢復(fù)(UNDO)
系統(tǒng)故障的恢復(fù)(UNDO + REDO)
介質(zhì)故障的恢復(fù)(重裝備份并恢復(fù)到一致性狀態(tài) + REDO)
提高恢復(fù)效率的技術(shù) 檢查點(diǎn)技術(shù)(
?可以提高系統(tǒng)故障的恢復(fù)效率
?可以在一定程度上提高利用動(dòng)態(tài)轉(zhuǎn)儲(chǔ)備份進(jìn)行介質(zhì)故障恢復(fù)的效率)
鏡像技術(shù)(鏡像技術(shù)可以改善介質(zhì)故障的恢復(fù)效率)
事務(wù)
定義的一個(gè)數(shù)據(jù)庫(kù)操作序列,這些操作要么全做,要不都不做,不可分割
當(dāng)多條SQL語(yǔ)句必須當(dāng)作一個(gè)整體執(zhí)行才能實(shí)現(xiàn)它的功能時(shí),需要定義一個(gè)事務(wù)
目的:維護(hù)企業(yè)狀態(tài) 和 數(shù)據(jù)庫(kù)狀態(tài)一致的與數(shù)據(jù)庫(kù)交互的程序
事務(wù)是數(shù)據(jù)庫(kù)系統(tǒng)的邏輯工作單元
定義事務(wù)
begin transaction
? sql 語(yǔ)句序列
commit #提交事務(wù),事務(wù)中所有操作均成功執(zhí)行
rollback #回滾事務(wù),事務(wù)夭折,不能繼續(xù)執(zhí)行,已經(jīng)執(zhí)行的更新操作撤銷,恢復(fù)至原先狀態(tài)
begin transactionupdate accounts set bal=bal-100 where accno='A'update accounts set bal=bal+100 where accno='b'//轉(zhuǎn)賬業(yè)務(wù)
commit
//只有兩種結(jié)果:要么提交;要么回滾
事務(wù)特性ACID
原子性:Atomicity
- 事務(wù)所有數(shù)據(jù)庫(kù)操作 不可分割
- 所有操作要么都執(zhí)行完;要么沒(méi)有執(zhí)行
一致性:Consistency
- 數(shù)據(jù)庫(kù)的當(dāng)前實(shí)例狀態(tài)也是數(shù)據(jù)庫(kù)的狀態(tài)
- 用戶對(duì)數(shù)據(jù)庫(kù)操作 是從一個(gè)狀態(tài) 到另一個(gè)狀態(tài)
- 數(shù)據(jù)庫(kù)初始狀態(tài)是一致的
- 滿足數(shù)據(jù)庫(kù)的完整性約束;反映用戶對(duì)數(shù)據(jù)庫(kù)的操作
- 應(yīng)用程序員的基本職責(zé);維護(hù)企業(yè)狀態(tài) 和 數(shù)據(jù)庫(kù)狀態(tài)一致
隔離性:Isolation
- 多用戶的數(shù)據(jù)庫(kù)系統(tǒng) 允許 多個(gè)事務(wù)并發(fā)執(zhí)行
- 提高系統(tǒng)事務(wù)吞吐量,減少事務(wù)等待時(shí)間
- 并發(fā)執(zhí)行的 事務(wù)中 的數(shù)據(jù)庫(kù) 操作 可能會(huì)交錯(cuò)執(zhí)行,可能會(huì)對(duì)同一個(gè)數(shù)據(jù)對(duì)象操作
- 隔離性就是指:一個(gè)事務(wù)正常執(zhí)行而不被來(lái)自并發(fā)執(zhí)行的數(shù)據(jù)庫(kù)操作干擾,例如12306搶票
比如:若在并發(fā)執(zhí)行的一個(gè)事務(wù)中,同一個(gè)查詢的兩次查詢結(jié)果不一樣, 請(qǐng)問(wèn)是由于事務(wù)沒(méi)有保持什么特性造成的?
持久性:Durability
- 事務(wù)一旦提交,事務(wù)對(duì)數(shù)據(jù)庫(kù)的更新操作 永久保持在數(shù)據(jù)庫(kù)(銀行存錢的數(shù)據(jù)不能因?yàn)橥k姏](méi))

恢復(fù)機(jī)制
對(duì)發(fā)生故障后,對(duì)已經(jīng)成功的結(jié)果進(jìn)行恢復(fù),保持原子性和持久性
故障類型及原因
1.事務(wù)故障:執(zhí)行過(guò)程中發(fā)生錯(cuò)誤,導(dǎo)致事務(wù)夭折
- 內(nèi)部錯(cuò)誤:事物內(nèi)部操作受限【違反完整性約束,訪問(wèn)不到數(shù)據(jù),運(yùn)算溢出】
- 系統(tǒng)錯(cuò)誤:
- 破壞原子性
2.系統(tǒng)故障
- 造成系統(tǒng)停止運(yùn)轉(zhuǎn)的事件等,比如CPU故障,DBMS代碼錯(cuò)誤,操作系統(tǒng)故障
- 容易造成存儲(chǔ)器內(nèi)容丟失
- 破壞原子性,破壞持久性(已經(jīng)更新的結(jié)果可能還在緩沖區(qū)未寫入磁盤)
3.介質(zhì)故障:使數(shù)據(jù)存儲(chǔ)介質(zhì) 完全毀壞的硬故障
比如數(shù)據(jù)庫(kù)服務(wù)器毀壞,瞬時(shí)磁場(chǎng)干擾,磁頭碰撞損壞,等
破壞持久性(已經(jīng)更新的結(jié)果不能持久寫入磁盤中)
4.不一致錯(cuò)誤

竊取/不強(qiáng)制的緩沖區(qū)管理策略【緩沖器置換算法比如LRU】
1.為了從磁盤上輸入事務(wù)B 所需要的數(shù)據(jù)放到內(nèi)存,需要先將未提交的事務(wù)A所處理的數(shù)據(jù)輸出到磁盤上,以騰出空間給B,即B竊取A的空間
2.事務(wù)提交狗,更新結(jié)果沒(méi)有及時(shí)到磁盤上,即不強(qiáng)制的執(zhí)行output操作
? 竊取/不強(qiáng)制的緩沖區(qū)管理策略導(dǎo)致:
1.事務(wù)提交之前, 部分執(zhí)行結(jié)果可能已經(jīng)被更新到數(shù)據(jù)庫(kù)中
2.事務(wù)提交后,事務(wù)執(zhí)行結(jié)果并沒(méi)有立即更新到磁盤中
- 破壞事務(wù)的原子性和持久性、
問(wèn):如果緩沖區(qū)管理器不采用課件里的竊取/不強(qiáng)制的管理策略,而采用延遲更新策略,即直到事務(wù)提交,更新結(jié)果才會(huì)被寫到數(shù)據(jù)庫(kù)中,那么發(fā)生故障后,系統(tǒng)中不一致錯(cuò)誤狀態(tài)表現(xiàn)是什么?
答:已提交的事務(wù)對(duì)數(shù)據(jù)庫(kù)的更新結(jié)果有一部分甚至全部還在緩沖區(qū)中,尚未寫到磁盤上的數(shù)據(jù)庫(kù)中,破壞了事務(wù)的持久性?;蛘咭烟峤坏氖聞?wù)對(duì)數(shù)據(jù)庫(kù)的更新結(jié)果不能持久的保存在磁盤上,破壞了事務(wù)的持久性
問(wèn):更新日志記錄:如果緩沖區(qū)管理器不采用課件里的竊取/不強(qiáng)制的管理策略,而采用延遲更新策略,即直到事務(wù)提交,更新結(jié)果才會(huì)被寫到數(shù)據(jù)庫(kù)中,那么更新日志記錄里是否仍需要包括更新前的值?
答:不需要,如果磁盤上的數(shù)據(jù)庫(kù)中有更新后的值,說(shuō)明事物已成功提交,因此在恢復(fù)時(shí)不需要做UNDO操作,也不需要存儲(chǔ)更新前的值
恢復(fù)策略
日志
每個(gè)數(shù)據(jù)庫(kù)維護(hù)一個(gè)日志,記錄所有事務(wù)對(duì)該數(shù)據(jù)更新操作
格式:1. 以記錄為單位的日志文件(事務(wù)標(biāo)識(shí),操作類型,操作對(duì)象,更新前數(shù)據(jù)的舊值,更新后數(shù)據(jù)的新值);
? 2.以數(shù)據(jù)表為單位的日志文件(事務(wù)標(biāo)識(shí),被更新的數(shù)據(jù)塊)
內(nèi)容:1 各個(gè)事務(wù)的開始標(biāo)記;2 各個(gè)事務(wù)的結(jié)束標(biāo)記;3 各個(gè)事務(wù)所有的更新操作
作用:1 進(jìn)行事務(wù)故障恢復(fù);2 進(jìn)行系統(tǒng)故障恢復(fù);3 協(xié)助后備副本進(jìn)行介質(zhì)故障恢復(fù)
注:日志記錄的登記社會(huì)魂虛必須嚴(yán)格按照各個(gè)事務(wù)的操作執(zhí)行的先后
注:更新之前,需要將日志記錄先寫入
數(shù)據(jù)轉(zhuǎn)儲(chǔ)
轉(zhuǎn)儲(chǔ)是指DBA將整個(gè)數(shù)據(jù)庫(kù)復(fù)制到磁帶或另一個(gè)磁盤上保存起來(lái)的過(guò)程,
備用的數(shù)據(jù)成為后備副本或后援副本
數(shù)據(jù)轉(zhuǎn)儲(chǔ)的使用
數(shù)據(jù)庫(kù)遭到破壞后可以將后備副本重新裝入;重裝后備副本只能將數(shù)據(jù)庫(kù)恢復(fù)到轉(zhuǎn)儲(chǔ)時(shí)的狀態(tài)
轉(zhuǎn)儲(chǔ)方法
1.靜態(tài)轉(zhuǎn)儲(chǔ)
- 系統(tǒng)中無(wú)運(yùn)行事務(wù)時(shí)進(jìn)行的轉(zhuǎn)儲(chǔ)操作;轉(zhuǎn)儲(chǔ)期間不允許對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作
- 轉(zhuǎn)儲(chǔ)開始時(shí)數(shù)據(jù)庫(kù)處于一致性狀態(tài)
- 得到的一定是一個(gè)數(shù)據(jù)一致性的副本
優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單
缺點(diǎn):1.降低了數(shù)據(jù)庫(kù)的可用性 2.轉(zhuǎn)儲(chǔ)必須等待正運(yùn)行的用戶事務(wù)結(jié)束 3.新的事務(wù)必須等轉(zhuǎn)儲(chǔ)結(jié)束
2.動(dòng)態(tài)轉(zhuǎn)儲(chǔ)
- 轉(zhuǎn)儲(chǔ)操作與用戶并發(fā)進(jìn)行
- 轉(zhuǎn)儲(chǔ)期間允許對(duì)數(shù)據(jù)庫(kù)進(jìn)行存取或修改
優(yōu)點(diǎn):1.不用等待正在進(jìn)行的事務(wù)結(jié)束 2.轉(zhuǎn)儲(chǔ)期間允許對(duì)數(shù)據(jù)庫(kù)進(jìn)行存取或修改
缺點(diǎn):不能保證副本中的數(shù)據(jù)正確有效
**動(dòng)態(tài)轉(zhuǎn)儲(chǔ)進(jìn)行故障恢復(fù),**需要把動(dòng)態(tài)轉(zhuǎn)儲(chǔ)期間各事務(wù)對(duì)數(shù)據(jù)庫(kù)的修改活動(dòng)登記下來(lái),建立日志文件;后備副本加上日志文件才能把數(shù)據(jù)庫(kù)恢復(fù)到某一時(shí)刻的正確狀態(tài)
海量轉(zhuǎn)儲(chǔ):每次轉(zhuǎn)儲(chǔ)全部數(shù)據(jù)庫(kù),又稱完全轉(zhuǎn)儲(chǔ)
增量轉(zhuǎn)儲(chǔ):只轉(zhuǎn)儲(chǔ)上次轉(zhuǎn)儲(chǔ)之后,更新過(guò)的數(shù)據(jù)
海量轉(zhuǎn)儲(chǔ)與增量轉(zhuǎn)儲(chǔ)的比較
1.從恢復(fù)角度看,使用海量轉(zhuǎn)儲(chǔ)得到的后備副本進(jìn)行恢復(fù)往往更方便
2.如果數(shù)據(jù)庫(kù)很大,事務(wù)處理又十分頻繁,則增量轉(zhuǎn)儲(chǔ)更有效

利用靜態(tài)轉(zhuǎn)儲(chǔ)副本和日志文件進(jìn)行恢復(fù)

對(duì)上圖進(jìn)行說(shuō)明:
- 系統(tǒng)在Ta時(shí)刻停止運(yùn)行事務(wù),進(jìn)行數(shù)據(jù)庫(kù)轉(zhuǎn)儲(chǔ)
- 在Tb時(shí)刻轉(zhuǎn)儲(chǔ)完畢,得到Tb時(shí)刻的數(shù)據(jù)庫(kù)一致性副本
- 系統(tǒng)運(yùn)行到Tf時(shí)刻發(fā)生故障
- 為恢復(fù)數(shù)據(jù)庫(kù),首先由DBA重裝數(shù)據(jù)庫(kù)后備副本,將數(shù)據(jù)庫(kù)恢復(fù)到Tb時(shí)刻的狀態(tài)
- 重新運(yùn)行自Tb~Tf時(shí)刻的所有更新事務(wù),把數(shù)據(jù)庫(kù)恢復(fù)到故障發(fā)生前的一致狀態(tài)
數(shù)據(jù)的不一致錯(cuò)誤導(dǎo)致
- 夭折的事務(wù) 部分執(zhí)行結(jié)果 已經(jīng)更新數(shù)據(jù)庫(kù);需要撤銷
- 已經(jīng)提交的事務(wù),對(duì)數(shù)據(jù)庫(kù)的更新結(jié)果可能有一部分甚至全部還在緩沖區(qū)中,尚未寫入磁盤;需要執(zhí)行
撤銷事務(wù)UNDO
- 利用日志撤銷事務(wù)對(duì)數(shù)據(jù)庫(kù)的更新**,更新前舊值寫回**
- 保持事務(wù)原子性,事務(wù)以rollback方式結(jié)束
重做事務(wù)REDO
- 利用日志對(duì)數(shù)據(jù)庫(kù)的更新,更新后的新值寫入
- 保持事務(wù)持久性,事務(wù)以commit方式結(jié)束
事務(wù)故障后恢復(fù)UNDO
事務(wù)故障:事務(wù)運(yùn)行至正常終止點(diǎn)前被終止
恢復(fù)方法:由恢復(fù)子系統(tǒng)利用日志文件撤銷(UNDO)此事務(wù)已對(duì)數(shù)據(jù)庫(kù)進(jìn)行的修改
注:事務(wù)故障的恢復(fù)由系統(tǒng)自動(dòng)完成,對(duì)用戶是透明的,不需要用戶干預(yù)
恢復(fù)步驟
- **反向掃描文件日志(**從后往前掃描),查找該事務(wù)的更新操作
- 對(duì)該事務(wù)的更新操作執(zhí)行逆操作,即將日志記錄中“更新前的值”寫入數(shù)據(jù)庫(kù)
- 繼續(xù)反向掃描日志文件,查找該事務(wù)的其他更新操作,并做同樣處理。
- 如此處理下去,直至讀到此事務(wù)的開始標(biāo)記,事務(wù)故障恢復(fù)就完成了。
系統(tǒng)故障后恢復(fù)UNDO+REDO
系統(tǒng)故障:
- 未完成事務(wù)對(duì)數(shù)據(jù)庫(kù)的更新已寫入數(shù)據(jù)庫(kù)
- 已提交事務(wù)對(duì)數(shù)據(jù)庫(kù)的更新還留在緩存區(qū)沒(méi)來(lái)得及寫入數(shù)據(jù)庫(kù)
恢復(fù)方法:
- UNDO故障發(fā)生時(shí)未完成的事務(wù)
- Redo已完成的事務(wù)
注:系統(tǒng)故障的恢復(fù)由系統(tǒng)在重新啟動(dòng)時(shí)自動(dòng)完成,不需要用戶干預(yù)
恢復(fù)步驟:
- 正向掃描日志文件(1.將在故障發(fā)生前已經(jīng)提交的事務(wù)加入重做(REDO)隊(duì)列,這些事務(wù)既有begin transaction記錄,也有commit記錄;2.將在故障發(fā)生時(shí)未完成的事務(wù)加入撤銷(Undo)隊(duì)列,這些事務(wù)中只有begin transaction記錄,無(wú)相應(yīng)的commit記錄)
- 對(duì)撤銷(Undo)隊(duì)列事務(wù)進(jìn)行撤銷(Undo)處理(1.反向掃描日志文件,對(duì)每個(gè)undo事務(wù)的更新操作進(jìn)行逆操作;2.將日志記錄中“更新前的值”寫入數(shù)據(jù)庫(kù))
- 對(duì)重做(Redo)隊(duì)列事務(wù)進(jìn)行重做(Redo)處理(1.正向掃描日志文件,對(duì)每個(gè)REDO事務(wù)重新執(zhí)行登記的操作;2.將日志記錄中“更新后的值”寫入數(shù)據(jù)庫(kù))
介質(zhì)故障后恢復(fù)[需要DBA]
- 重裝數(shù)據(jù)庫(kù)
- 重做已完成的事務(wù)
具有檢查點(diǎn)的恢復(fù)技術(shù)
解決問(wèn)題:
- 搜索整個(gè)日志將耗費(fèi)大量的時(shí)間
- REDO處理:重新執(zhí)行,浪費(fèi)了大量時(shí)間
解決方法:
- 在日志文件中增加檢查點(diǎn)記錄
- 增加重新開始文件
- 恢復(fù)子系統(tǒng)在登錄日志文件期間動(dòng)態(tài)地維護(hù)日志

建立檢查點(diǎn):
恢復(fù)子系統(tǒng)可以定期或不定期地建立檢查點(diǎn),保存數(shù)據(jù)庫(kù)狀態(tài)
- 定期:按照預(yù)定的一個(gè)時(shí)間間隔,如每隔一小時(shí)建立一個(gè)檢查點(diǎn)
- 不定期:按照某種規(guī)則,如日志文件已寫滿一半建立一個(gè)檢查點(diǎn)
恢復(fù):

T1:在檢查點(diǎn)之前提交
T2:在檢查點(diǎn)之前開始執(zhí)行,在檢查點(diǎn)之后故障點(diǎn)之前提交
T3:在檢查點(diǎn)之前開始執(zhí)行,在故障點(diǎn)時(shí)還未完成
T4:在檢查點(diǎn)之后開始執(zhí)行,在故障點(diǎn)之前提交
T5:在檢查點(diǎn)之后開始執(zhí)行,在故障點(diǎn)時(shí)還未完成
利用檢查點(diǎn)的恢復(fù)步驟
- 從重新開始文件中找到最后一個(gè)檢查點(diǎn)記錄在日志文件中的地址,由該地址在日志文件中找到最后一個(gè)檢查點(diǎn)記錄
- 由該檢查點(diǎn)記錄得到檢查點(diǎn)建立時(shí)刻所有正在執(zhí)行的事務(wù)清單ACTIVE-LIST
- 建立兩個(gè)事務(wù)隊(duì)列
- UNDO-LIST
- REDO-LIST
- 把ACTIVE-LIST暫時(shí)放入U(xiǎn)NDO-LIST隊(duì)列,REDO隊(duì)列暫為空。
- 建立兩個(gè)事務(wù)隊(duì)列
- 從檢查點(diǎn)開始正向掃描日志文件,直到日志文件結(jié)束
- 如有新開始的事務(wù)Ti,把Ti暫時(shí)放入U(xiǎn)NDO-LIST隊(duì)列
- 如有提交的事務(wù)Tj,把Tj從UNDO-LIST隊(duì)列移到REDO-LIST隊(duì)列
- 對(duì)UNDO-LIST中的每個(gè)事務(wù)執(zhí)行UNDO操作
- 對(duì)REDO-LIST中的每個(gè)事務(wù)執(zhí)行REDO操作
數(shù)據(jù)鏡像[補(bǔ)充]
數(shù)據(jù)庫(kù)鏡像
-
DBMS自動(dòng)把整個(gè)數(shù)據(jù)庫(kù)或其中的關(guān)鍵數(shù)據(jù)復(fù)制到另一個(gè)磁盤上
-
DBMS自動(dòng)保證鏡像數(shù)據(jù)與主數(shù)據(jù)庫(kù)的一致性,每當(dāng)主數(shù)據(jù)庫(kù)更新時(shí),DBMS自動(dòng)把更新后的數(shù)據(jù)復(fù)制過(guò)去,如圖
出現(xiàn)介質(zhì)故障時(shí)
- 可由鏡像磁盤繼續(xù)提供使用
- 同時(shí)DBMS自動(dòng)利用鏡像磁盤數(shù)據(jù)進(jìn)行數(shù)據(jù)庫(kù)的恢復(fù)
- 不需要關(guān)閉系統(tǒng)和重裝數(shù)據(jù)庫(kù)副本
沒(méi)有出現(xiàn)故障時(shí)
- 可用于并發(fā)操作
- 一個(gè)用戶對(duì)數(shù)據(jù)加排他鎖修改數(shù)據(jù),其他用戶可以讀鏡像數(shù)據(jù)庫(kù)上的數(shù)據(jù),而不必等待該用戶釋放鎖
問(wèn):系統(tǒng)故障的恢復(fù)
如果緩沖區(qū)管理器不采用課件里的竊取/不強(qiáng)制的管理策略,而采用延遲更新策略,即直到事務(wù)提交,更新結(jié)果才會(huì)被寫到數(shù)據(jù)庫(kù)中,那么發(fā)生系統(tǒng)故障后,如何進(jìn)行恢復(fù)?
答:已提交的事務(wù)用REDO, 未提交的事務(wù)用UNDO
并發(fā)控制
多個(gè)事務(wù)如何一起執(zhí)行呢?
- 事務(wù)串行執(zhí)行:每個(gè)時(shí)刻只有一個(gè)事務(wù)運(yùn)行,其他事務(wù)必須等到這個(gè)事務(wù)結(jié)束后方能運(yùn)行。(事務(wù)一個(gè)接一個(gè)的運(yùn)行)
- 交叉并發(fā)方式:在單處理機(jī)系統(tǒng)中,并行事務(wù)并行操作輪流交叉運(yùn)行。 這種并行執(zhí)行方式稱為交叉并發(fā)方式。
- 同時(shí)并方式:在多處理機(jī)系統(tǒng)中,每個(gè)處理機(jī)可以運(yùn)行一個(gè)事務(wù),多個(gè)處理機(jī)可以同時(shí)運(yùn)行多個(gè)事務(wù),實(shí)現(xiàn)多個(gè)事務(wù)真正的并行運(yùn)行,這種并行執(zhí)行方式稱為同時(shí)并發(fā)方式。
事務(wù)是并發(fā)控制的基本單位,如果不考慮隔離性,會(huì)發(fā)生什么事呢?
丟失數(shù)據(jù):兩個(gè)事務(wù)T1、T2同時(shí)讀入同一數(shù)據(jù)并修改,T2提交的結(jié)果破壞了T1提交的結(jié)果,導(dǎo)致T1的修改被丟失
不可重復(fù)讀:對(duì)于數(shù)據(jù)庫(kù)中的某個(gè)數(shù)據(jù),一個(gè)事務(wù)范圍內(nèi)的多次查詢卻返回了不同的結(jié)果,這是由于在查詢過(guò)程中,數(shù)據(jù)被另外一個(gè)事務(wù)修改并提交了。
臟讀:一個(gè)事務(wù)在處理數(shù)據(jù)的過(guò)程中,讀取到另一個(gè)為提交事務(wù)的數(shù)據(jù)。
注意:不可重復(fù)讀和臟讀的區(qū)別是,臟讀讀取到的是一個(gè)未提交的數(shù)據(jù),而不可重復(fù)讀讀取到的是前一個(gè)事務(wù)提交的數(shù)據(jù)。
注意:而不可重復(fù)讀在一些情況也并不影響數(shù)據(jù)的正確性,比如需要多次查詢的數(shù)據(jù)也是要以最后一次查詢到的數(shù)據(jù)為主。
注意:丟失數(shù)據(jù)和不可重復(fù)讀都是讀取了另一條已經(jīng)提交的事務(wù)(這點(diǎn)就臟讀不同),所不同的是不可重復(fù)讀查詢的都是同一個(gè)數(shù)據(jù)項(xiàng),而丟失數(shù)據(jù)針對(duì)的是一批數(shù)據(jù)整體(比如數(shù)據(jù)的個(gè)數(shù))。
不可重復(fù)讀和幻讀是初學(xué)者不易分清的概念,我也是看了詳細(xì)的解讀才明白的,總的來(lái)說(shuō),解決不可重復(fù)讀的方法是 鎖行,解決丟失數(shù)據(jù)的方式是 鎖表。
1. 丟失數(shù)據(jù),幻讀(W-W)
兩個(gè)事務(wù)T1、T2同時(shí)讀入同一數(shù)據(jù)并修改,T2提交的結(jié)果破壞了T1提交的結(jié)果,導(dǎo)致T1的修改被丟失

2.不可重復(fù)讀(R-W)
事務(wù)T1讀取某一個(gè)數(shù)據(jù)后,事務(wù)T2執(zhí)行更新操作,使T1無(wú)法再現(xiàn)前一次讀取結(jié)果,包括三種情況:
⑴. T2執(zhí)行修改操作,T1再次讀數(shù)據(jù)時(shí),得到與前一次不同的值
⑵. T2執(zhí)行刪除操作,T1再次讀數(shù)據(jù)時(shí),發(fā)現(xiàn)某些記錄神秘的消失了
⑶. T2執(zhí)行插入操作,T1再次讀數(shù)據(jù)時(shí),發(fā)現(xiàn)多了一些記錄
(2)(3)發(fā)生的不可重復(fù)讀有時(shí)也稱為幻影現(xiàn)象。

3. 讀“臟”數(shù)據(jù)(W-R)
? 事務(wù)T1修改某一數(shù)據(jù)并將其寫回磁盤,事務(wù)T2讀取同一數(shù)據(jù)后,T1由于某種原因被撤銷,這時(shí)被T1修改過(guò)的數(shù)據(jù)恢復(fù)原值,T2讀到的數(shù)據(jù)就與數(shù)據(jù)庫(kù)中的數(shù)據(jù)不一致,則T2讀到的數(shù)據(jù)就為“臟”數(shù)據(jù),即不正確的數(shù)據(jù)。

如何避免發(fā)生這種數(shù)據(jù)不一致的現(xiàn)象?——DBMS必須提供并發(fā)控制機(jī)制
并發(fā)控制機(jī)制的任務(wù):對(duì)并發(fā)操作進(jìn)行正確調(diào)度、保證事務(wù)的隔離性、保證數(shù)據(jù)庫(kù)的一致性。
并發(fā)控制的主要技術(shù)有:封鎖、時(shí)間戳、樂(lè)觀控制法、多版本并發(fā)控制。
問(wèn):數(shù)據(jù)不一致問(wèn)題:對(duì)于“更新丟失”、“臟讀”和“不可重復(fù)讀”三種數(shù)據(jù)不一致問(wèn)題,認(rèn)為哪種是絕不允許發(fā)生的?給出理由。
答:應(yīng)該絕不允許“更新丟失”發(fā)生,因?yàn)椤芭K讀”和“不可重復(fù)讀”的后果雖然有時(shí)很嚴(yán)重,但有時(shí)也是無(wú)關(guān)緊要的,可以通過(guò)控制事務(wù)的隔離級(jí)別來(lái)避免,但是“更新丟失”一旦發(fā)生,后面所有需要對(duì)丟失的數(shù)據(jù)進(jìn)行操作的事務(wù)都會(huì)受影響,必須重做或者利用數(shù)據(jù)備份來(lái)恢復(fù)。
封鎖技術(shù)
封鎖是實(shí)現(xiàn)并發(fā)控制的一個(gè)有效措施,那么什么是封鎖呢?
封鎖是事務(wù)T在對(duì)某個(gè)數(shù)據(jù)對(duì)象(例如表、記錄等操作時(shí))。先向系統(tǒng)發(fā)出請(qǐng)求,對(duì)其加鎖。加鎖后事務(wù)T就對(duì)該數(shù)據(jù)對(duì)象有了一定的控制,在事務(wù)T釋放它的鎖之前,其他事務(wù)不能更新此數(shù)據(jù)對(duì)象。
封鎖有哪些類型呢?
排他鎖:簡(jiǎn)稱X鎖(又稱寫鎖),若事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加上X鎖,則只允許T讀取和修改A,其他任何事務(wù)都不能再對(duì)A加任何鎖。直到T釋放A上的鎖。
共享鎖:簡(jiǎn)稱S鎖(又稱讀鎖),若事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加上S鎖,則事務(wù)T可以讀A但不能修改A,其他事務(wù)只能再對(duì)A加S鎖,而不能加X(jué)鎖,直到T釋放A上的S鎖為止。
有了封鎖的類型,如何加鎖才能使并發(fā)操作不會(huì)出現(xiàn)數(shù)據(jù)不一致現(xiàn)象呢?
封鎖協(xié)議:約定了對(duì)數(shù)據(jù)對(duì)象何時(shí)申請(qǐng)X鎖或S鎖,持續(xù)時(shí)間、何時(shí)釋放等一系列規(guī)則。
三級(jí)封鎖見yaunwen
問(wèn):封鎖技術(shù)實(shí)現(xiàn)沖突可串行化:封鎖技術(shù)是如何實(shí)現(xiàn)并發(fā)事務(wù)的沖突可串行化的?
答:封鎖技術(shù)通過(guò)在數(shù)據(jù)對(duì)象上維護(hù)“鎖”以防止非可串行化的行為?;阪i的并發(fā)控制的基本思想是:當(dāng)一個(gè)事務(wù)在對(duì)其需要訪問(wèn)的數(shù)據(jù)對(duì)象(例如關(guān)系、元組)進(jìn)行操作之前,先向系統(tǒng)發(fā)出請(qǐng)求,獲得在它所訪問(wèn)的數(shù)據(jù)庫(kù)對(duì)象上的鎖,以防止其他事務(wù)幾乎在同一時(shí)間訪問(wèn)這些數(shù)據(jù)并因此引入非可行化的可能。封鎖技術(shù)可實(shí)現(xiàn)沖突可串行化。
死鎖
封鎖會(huì)帶來(lái)哪些問(wèn)題呢?
- 活鎖:如果事務(wù)T1封鎖了數(shù)據(jù)R,事務(wù)T2又請(qǐng)求封鎖數(shù)據(jù)R,于是T2等待;T3也請(qǐng)求封鎖數(shù)據(jù)R,當(dāng)T1釋放了R上的鎖之后,系統(tǒng)首先批準(zhǔn)了T3的請(qǐng)求,T2任然等待;然后T4又請(qǐng)求封鎖R,當(dāng)T3釋放R上的鎖之后,系統(tǒng)又批準(zhǔn)了T4的請(qǐng)求……T2有可能永遠(yuǎn)等待,這就是活鎖的情況。
避免活鎖的簡(jiǎn)單方法是:采用先來(lái)先服務(wù)策略
- 死鎖:如果事務(wù)T1封鎖了數(shù)據(jù)R1,T2封鎖了數(shù)據(jù)R2,然后T1又請(qǐng)求封鎖R2,因T2封鎖了R2,
于是T1等待T2釋放R2上的鎖;接著T2又請(qǐng)求封鎖R1,因T1封鎖了R1,于是T2等待T1釋放R1上的鎖。這樣就出現(xiàn)了T1在等待T2,而T2又在等待T1,的局面,T1、T2兩個(gè)事務(wù)永遠(yuǎn)不能結(jié)束,形成死鎖
解決死鎖的方法:有兩種思路
- 預(yù)防死鎖的發(fā)生
① 一次封鎖法:一次性將所有要使用的數(shù)據(jù)全部加鎖,否則就不能繼續(xù)執(zhí)行
? 存在的問(wèn)題:擴(kuò)大了封鎖范圍,降低了系統(tǒng)的并發(fā)度;
② 順序封鎖法:預(yù)先對(duì)數(shù)據(jù)對(duì)象規(guī)定一個(gè)封鎖順序,所有事務(wù)都按照這個(gè)順序?qū)嵤┓怄i。
存在的問(wèn)題:
1.數(shù)據(jù)庫(kù)在動(dòng)態(tài)地不斷變化,要維護(hù)這樣的資源的封鎖順序非常困難,成本很高。
2.事務(wù)的封鎖請(qǐng)求可以隨著事務(wù)的執(zhí)行而動(dòng)態(tài)地決定,很難實(shí)現(xiàn)確定每一個(gè)事務(wù)要封鎖哪些對(duì)象,因此很難按規(guī)定的順序去施加封鎖。
- 死鎖的診斷與解除(普遍采用的方法)
① 超時(shí)法:如果一個(gè)事務(wù)的等待時(shí)間超過(guò)了規(guī)定的時(shí)限,就認(rèn)為發(fā)生了死鎖
存在的問(wèn)題:
1.時(shí)間設(shè)置太短,有可能誤判死鎖
? 2.時(shí)間設(shè)置太長(zhǎng),死鎖發(fā)生后不能及時(shí)發(fā)現(xiàn)
② 等待圖法:事務(wù)等待圖是一個(gè)有向圖G=(T,U),T為結(jié)點(diǎn)的集合,每個(gè)結(jié)點(diǎn)表示正在運(yùn)行的事務(wù);U為邊的集合,表示事務(wù)等待情況,若事務(wù)T1等待T2,則在T1、T2之間畫一條有向邊,從T1指向T2。
? 事務(wù)等待圖動(dòng)態(tài)地反映了所有事務(wù)的等待情況。并發(fā)控制子系統(tǒng)周期性地(如每隔數(shù)秒)生成事務(wù)等待圖,并進(jìn)行檢測(cè)。如果發(fā)現(xiàn)圖中存在回路,則表示系統(tǒng)中出現(xiàn)了死鎖。并發(fā)控制子系統(tǒng)一旦檢測(cè)到系統(tǒng)中存在死鎖,就要設(shè)法解除。通常采用的方法是選擇一個(gè)處理死鎖代價(jià)最小的事務(wù),將其撤銷,釋放此事務(wù)持有的所有的鎖,使其他事務(wù)得以運(yùn)行下去
問(wèn):“若事務(wù)等待圖出現(xiàn)環(huán)路,則該并發(fā)調(diào)度不是沖突可串行化的?!蹦阏J(rèn)為這個(gè)判斷是否正確?理由
答:不正確,事務(wù)等待圖出現(xiàn)環(huán)路表明系統(tǒng)中存在死鎖,即事務(wù)在申請(qǐng)數(shù)據(jù)對(duì)象上的鎖時(shí)互相等待,但這并不能說(shuō)明該并發(fā)調(diào)度不是和另一個(gè)串行調(diào)度沖突等價(jià)的
多粒度封鎖
- 封鎖的粒度:封鎖對(duì)象的大小
在一個(gè)系統(tǒng)中同時(shí)支持多種封鎖粒度供不同的事務(wù)選擇是比較理想的,這種方法稱為多粒度封鎖。
- 封鎖的對(duì)象有哪些?
-
物理單元:頁(yè)(數(shù)據(jù)頁(yè)或索引頁(yè))、物理記錄等
-
邏輯單元:屬性值、屬性值的集合、元組、關(guān)系、索引項(xiàng)、整個(gè)索引、整個(gè)數(shù)據(jù)庫(kù)
-
如何進(jìn)行封鎖的?
多粒度樹:根節(jié)點(diǎn)是整個(gè)數(shù)據(jù)庫(kù),表示最大的數(shù)據(jù)粒度,葉節(jié)點(diǎn)表示最小的封鎖粒度。
多粒度封鎖協(xié)議
? 允許多粒度樹中的每個(gè)結(jié)點(diǎn)被獨(dú)立的加鎖,對(duì)每一個(gè)結(jié)點(diǎn)加鎖(顯式封鎖)意味著這個(gè)結(jié)點(diǎn)的所有后裔結(jié)點(diǎn)也被加以同樣類型的鎖(隱式封鎖)。
對(duì)某個(gè)數(shù)據(jù)加鎖時(shí),系統(tǒng)要檢查該數(shù)據(jù)對(duì)象上有無(wú)顯示封鎖與之沖突,同時(shí)還要上下檢查是否存在隱式封鎖,這樣的檢查效率太低,因此提出了——意向鎖
? 意向鎖:如果對(duì)一個(gè)結(jié)點(diǎn)加意向鎖,則說(shuō)明該結(jié)點(diǎn)的下層結(jié)點(diǎn)正在被加鎖;對(duì)任意一結(jié)點(diǎn)加鎖時(shí),必須先歲它的上層結(jié)點(diǎn)加意向鎖。
意向鎖有哪些種類?
IS鎖(意向共享鎖):如果對(duì)一個(gè)數(shù)據(jù)對(duì)象加IS鎖,表示它的后裔結(jié)點(diǎn)擬(意向)加S鎖。
IX鎖(意向排他鎖):如果對(duì)一個(gè)數(shù)據(jù)對(duì)象加IX鎖,表示它的后裔結(jié)點(diǎn)擬(意向)加X(jué)鎖。
SIX鎖(共享意向排他鎖):如果對(duì)一個(gè)數(shù)據(jù)對(duì)象加SIX鎖,表示對(duì)它加S鎖,再加IX鎖,即SIX=S+IX。
申請(qǐng)封鎖時(shí)應(yīng)該按自上而下的次序進(jìn)行,釋放封鎖時(shí)應(yīng)該按自下而上的次序進(jìn)行
問(wèn):基于DBMS提供的多粒度封鎖技術(shù),在實(shí)際應(yīng)用中,何時(shí)使用粗粒度鎖(如關(guān)系鎖),何時(shí)使用細(xì)粒度鎖(如元組鎖)?
答:需要處理少量元組的事務(wù)應(yīng)采用細(xì)粒度鎖,需要處理大量元組的事務(wù)應(yīng)采用粗粒度鎖 細(xì)粒度鎖比粗粒度鎖有更好的并發(fā)度,但是開銷較大,并發(fā)控制管理器需要更多的空間來(lái)保持關(guān)于細(xì)粒度鎖的信息,選擇時(shí)需同時(shí)考慮等所開銷和并發(fā)度兩個(gè)因素
隔離級(jí)別
什么是事務(wù)的隔離性(Isolation)呢?
隔離性是指,多個(gè)用戶的并發(fā)事務(wù)訪問(wèn)同一個(gè)數(shù)據(jù)庫(kù)時(shí),一個(gè)用戶的事務(wù)不應(yīng)該被其他用戶的事務(wù)干擾,多個(gè)并發(fā)事務(wù)之間要相互隔離。
四種事務(wù)隔離級(jí)別解決了上述問(wèn)題;大部分都適用中間兩種
讀未提交(Read uncommitted):【隔離級(jí)別最低】**
- 此時(shí)select語(yǔ)句不加鎖??赡茏x取到不一致的數(shù)據(jù),即“讀臟 ”。并發(fā)最高,一致性最差。
讀已提交(Read committed):【常用】
- 可避免 臟讀 的發(fā)生。在互聯(lián)網(wǎng)大數(shù)據(jù)量,高并發(fā)量的場(chǎng)景下,幾乎 不會(huì)使用 上述兩種隔離級(jí)別。
可重復(fù)讀(Repeatable read):【常用】
- MySql默認(rèn)隔離級(jí)別??杀苊?臟讀 、不可重復(fù)讀 的發(fā)生。
串行化(Serializable ):【隔離級(jí)別最高】
- 可避免 臟讀、不可重復(fù)讀、幻讀 的發(fā)生;一致性最好的,但并發(fā)性最差的隔離級(jí)別。
? 當(dāng)然級(jí)別越高,執(zhí)行效率就越低。像 Serializable 這樣的級(jí)別,就是以 鎖表 的方式(類似于Java多線程中的鎖)使得其他的線程只能在鎖外等待,所以平時(shí)選用何種隔離級(jí)別應(yīng)該根據(jù)實(shí)際情況。
問(wèn):默認(rèn)隔離級(jí)別的選擇:SQLSever 和Oracle都把默認(rèn)隔離級(jí)別設(shè)置為Read Committed(讀已提交),MySQL把默認(rèn)隔離級(jí)別設(shè)置Repeatable Read(可重復(fù)讀),而不是設(shè)置為更高的或者更低隔離級(jí)別, 你覺(jué)得這樣設(shè)置是基于什么考慮呢?
d):【隔離級(jí)別最低】**
- 此時(shí)select語(yǔ)句不加鎖。可能讀取到不一致的數(shù)據(jù),即“讀臟 ”。并發(fā)最高,一致性最差。
讀已提交(Read committed):【常用】
- 可避免 臟讀 的發(fā)生。在互聯(lián)網(wǎng)大數(shù)據(jù)量,高并發(fā)量的場(chǎng)景下,幾乎 不會(huì)使用 上述兩種隔離級(jí)別。
可重復(fù)讀(Repeatable read):【常用】
- MySql默認(rèn)隔離級(jí)別。可避免 臟讀 、不可重復(fù)讀 的發(fā)生。
串行化(Serializable ):【隔離級(jí)別最高】
- 可避免 臟讀、不可重復(fù)讀、幻讀 的發(fā)生;一致性最好的,但并發(fā)性最差的隔離級(jí)別。
? 當(dāng)然級(jí)別越高,執(zhí)行效率就越低。像 Serializable 這樣的級(jí)別,就是以 鎖表 的方式(類似于Java多線程中的鎖)使得其他的線程只能在鎖外等待,所以平時(shí)選用何種隔離級(jí)別應(yīng)該根據(jù)實(shí)際情況。
問(wèn):默認(rèn)隔離級(jí)別的選擇:SQLSever 和Oracle都把默認(rèn)隔離級(jí)別設(shè)置為Read Committed(讀已提交),MySQL把默認(rèn)隔離級(jí)別設(shè)置Repeatable Read(可重復(fù)讀),而不是設(shè)置為更高的或者更低隔離級(jí)別, 你覺(jué)得這樣設(shè)置是基于什么考慮呢?
答:通過(guò)設(shè)置數(shù)據(jù)庫(kù)的事務(wù)隔離級(jí)別可以解決多個(gè)事務(wù)并發(fā)情況下出現(xiàn)的臟讀、不可重復(fù)讀和幻讀問(wèn)題,數(shù)據(jù)庫(kù)事務(wù)隔離級(jí)別由低到高依次為Read uncommitted、Read committed、Repeatable read和Serializable等四種。數(shù)據(jù)庫(kù)不同,其支持的事務(wù)隔離級(jí)別亦不相同:MySQL數(shù)據(jù)庫(kù)支持上面四種事務(wù)隔離級(jí)別,默認(rèn)為Repeatable read;Oracle 數(shù)據(jù)庫(kù)支持Read committed和Serializable兩種事務(wù)隔離級(jí)別,默認(rèn)為Read committed