新聞中心
隨著互聯(lián)網(wǎng)和大數(shù)據(jù)的迅猛發(fā)展,數(shù)據(jù)在我們生活中扮演著越來越重要的角色。而在數(shù)據(jù)的存儲(chǔ)和管理中,數(shù)據(jù)庫系統(tǒng)是不可或缺的一部分。在數(shù)據(jù)庫系統(tǒng)中,事務(wù)是其中最重要的部分之一。事務(wù)的作用是確保操作系統(tǒng)中的數(shù)據(jù)一致性。然而,當(dāng)我們使用復(fù)雜的數(shù)據(jù)庫系統(tǒng)時(shí),如何確保事務(wù)的數(shù)據(jù)一致性呢?本文將介紹5種數(shù)據(jù)庫事務(wù)的技術(shù),以及如何使用它們來確保數(shù)據(jù)一致性。

達(dá)坂城網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián),達(dá)坂城網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為達(dá)坂城上千余家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)營銷網(wǎng)站建設(shè)要多少錢,請找那個(gè)售后服務(wù)好的達(dá)坂城做網(wǎng)站的公司定做!
1. ACID事務(wù)
ACID是最常用的數(shù)據(jù)庫事務(wù)技術(shù)。ACID是Atomicity、Consistency、Isolation、Durability的縮寫,分別代表原子性、一致性、隔離性和持久性。ACID作為一個(gè)完整的事務(wù),將被數(shù)據(jù)庫系統(tǒng)執(zhí)行或回滾。
*原子性:一個(gè)事務(wù)的所有操作在協(xié)商一個(gè)單獨(dú)的工作單位時(shí)執(zhí)行,要么全部成功,要么全部失敗。
*一致性:一個(gè)事務(wù)的所有操作都必須遵循一定的約束,以遵循業(yè)務(wù)邏輯規(guī)則。
*隔離性:并發(fā)執(zhí)行事務(wù)的能力。各個(gè)事務(wù)之間可以完全地相互獨(dú)立,同時(shí)也可以互相配合。
*持久性:在事務(wù)完成后,所有修改都將永久保存在數(shù)據(jù)庫中。
2. BASE技術(shù)
如果ACID技術(shù)存在一些缺點(diǎn),例如對系統(tǒng)進(jìn)行并發(fā)更新和持久性要求高的要求,那么BASE技術(shù)就提供了一個(gè)更可擴(kuò)展和更靈活的選擇。
*基本可用:盡可能地保證高故障容忍性、面向分布式架構(gòu),并實(shí)現(xiàn)最小化的故障造成的影響。
*軟狀態(tài):即讓系統(tǒng)在一個(gè)時(shí)間段內(nèi)保持中間狀態(tài),而不一定偏向某一方向。
*最終一致性:在一段時(shí)間后,所有的狀態(tài)都變?yōu)樽罱K一致狀態(tài)。
3. 分布式事務(wù)
分布式事務(wù)處理多個(gè)分布式系統(tǒng)之間的事務(wù)。不同分布式系統(tǒng)的數(shù)據(jù)分布在不同的物理位置上,可能由不同的管理員進(jìn)行管理。分布式事務(wù)提供了一種數(shù)據(jù)處理方式,可以確保在分布式環(huán)境下,事務(wù)的正確執(zhí)行。
* XA:XA是分布式事務(wù)的一種協(xié)議,其目的是確保一個(gè)多個(gè)數(shù)據(jù)庫之間的事務(wù)的一致性。
* Two-Phase Commit Protocol:這種協(xié)議需要在所有參與節(jié)點(diǎn)(數(shù)據(jù)庫服務(wù)器)之間進(jìn)行一個(gè)預(yù)提交過程,確認(rèn)所有事務(wù)都成功完成,并且所有其他節(jié)點(diǎn)都已經(jīng)做好提交的準(zhǔn)備。這樣,事務(wù)就可以成功提交,所有參與節(jié)點(diǎn)的數(shù)據(jù)都能更新到最新狀態(tài),實(shí)現(xiàn)數(shù)據(jù)一致性。
4. NoSQL的事務(wù)
NoSQL代表了不僅僅是SQL的數(shù)據(jù)庫系統(tǒng),但它們的共同點(diǎn)是它們都不使用傳統(tǒng)的關(guān)系型數(shù)據(jù)庫,因此可能不支持ACID事務(wù)。相反,這些數(shù)據(jù)庫系統(tǒng)主要支持基于日志的系統(tǒng),例如本地存儲(chǔ),支持最終一致性。
5. 原子操作
原子操作是在不用事務(wù)的情況下實(shí)現(xiàn)數(shù)據(jù)局部更新的一種技術(shù)。原子操作確保如果任何一部分失敗,整個(gè)操作將被取消并恢復(fù)到原始狀態(tài)。原子操作經(jīng)常應(yīng)用于高并發(fā)和資源受限的環(huán)境,如在開發(fā)云服務(wù)、移動(dòng)應(yīng)用程序和Web系統(tǒng)時(shí)會(huì)經(jīng)常用到。
數(shù)據(jù)庫系統(tǒng)必須確保數(shù)據(jù)的一致性,以便它們不會(huì)在事務(wù)處理過程中遭受損失。本文介紹了5種常用的事務(wù)技術(shù),以及如何使用它們來確保數(shù)據(jù)的一致性。無論使用哪種技術(shù),都要為系統(tǒng)提供適當(dāng)?shù)馁Y源和保障,以確保系統(tǒng)在處理事務(wù)時(shí)保持高效率和一致性。
相關(guān)問題拓展閱讀:
- 數(shù)據(jù)庫事務(wù)正確執(zhí)行的四個(gè)基本要素包括
- 數(shù)據(jù)庫管理系統(tǒng) (DBMS) 的五個(gè)重要軟件組成部分是什么?
- sql運(yùn)行問題?
數(shù)據(jù)庫事務(wù)正確執(zhí)行的四個(gè)基本要素包括
ACID,指數(shù)據(jù)庫事務(wù)正確執(zhí)行的四個(gè)基本要素的縮寫。包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。一個(gè)支持事務(wù)(Transaction)的數(shù)據(jù)庫,必需要具有這四種特性,否則在事務(wù)過程(Transaction processing)當(dāng)中無法保證數(shù)據(jù)的正確性,交易過程極可能達(dá)不到交易方的要求。
原子性
整個(gè)事務(wù)中的所有操作,要么全部完成,要么全部不完成,不可能停滯在中間某個(gè)環(huán)節(jié)。事務(wù)在執(zhí)行過程中發(fā)生錯(cuò)誤,會(huì)被回滾(Rollback)到事務(wù)開始前的狀態(tài),就像這銀伍個(gè)事務(wù)從來沒有執(zhí)行過一樣。
一致性
一個(gè)事務(wù)可以封裝狀態(tài)改變(除非它是一個(gè)只讀的)。事務(wù)必須始終保持系統(tǒng)處于一致的狀態(tài),不管在任何給定的時(shí)間并發(fā)事務(wù)有多少。
也就是說:如果事務(wù)是并發(fā)多個(gè),系統(tǒng)也必須如同串行事務(wù)一樣操作。其主要特征是保護(hù)性和不變性(Preserving an Invariant),以轉(zhuǎn)賬案例為例,假設(shè)有五個(gè)賬戶,每個(gè)賬戶余額是100元,那么五個(gè)賬戶總額是500元,如果在這個(gè)5個(gè)賬戶之間同時(shí)發(fā)生多個(gè)轉(zhuǎn)賬,無論并發(fā)多少個(gè),比如在A與B賬戶之間轉(zhuǎn)賬5元,在C與D賬戶之間轉(zhuǎn)賬10元,在B與E之間轉(zhuǎn)賬15元,五個(gè)賬戶總額也應(yīng)該還是500元,這就是保護(hù)性和不變性
隔離性
隔離狀態(tài)執(zhí)行事務(wù),使它們好像是系統(tǒng)在給定時(shí)間內(nèi)執(zhí)行的唯一操作。如果有兩個(gè)事務(wù),運(yùn)行在相同的時(shí)間內(nèi),執(zhí)行相同的功能,事務(wù)正稿的隔離性將確保每一事務(wù)在系統(tǒng)中認(rèn)為只有該事務(wù)在使用系統(tǒng)舉搏孝。這種屬性有時(shí)稱為串行化,為了防止事務(wù)操作間的混淆,必須串行化或序列化請求,使得在同一時(shí)間僅有一個(gè)請求用于同一數(shù)據(jù)。
持久性
在事務(wù)完成以后,該事務(wù)對數(shù)據(jù)庫所作的更改便持久的保存在數(shù)據(jù)庫之中,并不會(huì)被回滾。
由于一項(xiàng)操作通常會(huì)包含許多子操作,而這些子操作可能會(huì)因?yàn)橛布膿p壞或其他因素產(chǎn)生問題,要正確實(shí)現(xiàn)ACID并不容易。ACID建議數(shù)據(jù)庫將所有需要更新以及修改的資料一次操作完畢,但實(shí)際上并不可行。
目前主要有兩種方式實(shí)現(xiàn)ACID:之一種是Write ahead logging,也就是日志式的方式(現(xiàn)代數(shù)據(jù)庫均基于這種方式)。第二種是Shadow paging。
數(shù)據(jù)庫管理系統(tǒng) (DBMS) 的五個(gè)重要軟件組成部分是什么?
DBMS的五個(gè)重要的軟件組成部分鉛殲\x0d\x0a①DBMS引擎\x0d\x0a是DBMS中最重要的部分,它接受來自其他各個(gè)DBMS子系統(tǒng)的邏輯查詢請求,并將邏輯查詢請求轉(zhuǎn)換成其對應(yīng)的物理形式,實(shí)際上對數(shù)據(jù)庫和數(shù)據(jù)字典的存取感覺上就如同對它們在存儲(chǔ)設(shè)備上進(jìn)行的存取。\x0d\x0a②嘩李數(shù)據(jù)定義子系統(tǒng)\x0d\x0a幫助人們在數(shù)據(jù)庫中建立并維護(hù)數(shù)據(jù)字典,以及定義數(shù)據(jù)庫的文件結(jié)構(gòu)。\x0d\x0a③數(shù)據(jù)操作子系統(tǒng)\x0d\x0a幫助用戶增加、修改及刪除數(shù)據(jù)庫中的信息,并幫助用戶在亂激遲數(shù)據(jù)庫中挖掘有價(jià)值的信息。\x0d\x0a④應(yīng)用程序生成子系統(tǒng)\x0d\x0a包含了用以幫助用戶建立面向事務(wù)處理的應(yīng)用程序 。工具包括:建立數(shù)據(jù)輸入屏幕功能,為特定的DBMS選定程序設(shè)計(jì)語言,并利用程序設(shè)計(jì)語言為每個(gè)獨(dú)立的DBMS建立一個(gè)公共的操作交互界面。\x0d\x0a⑤數(shù)據(jù)管理子系統(tǒng)\x0d\x0a通過自身提供的備份與恢復(fù)工具、安全管理工具、更優(yōu)化查詢工具、并發(fā)控制和更新管理工具,幫助人們管理整個(gè)數(shù)據(jù)庫環(huán)境。
sql運(yùn)行問題?
sql運(yùn)行問題?
數(shù)據(jù)庫運(yùn)行過程中常見的故障有3類:事物故障、系統(tǒng)故障、介質(zhì)故障。
恢復(fù)策略:
1、事物故障:
發(fā)生事務(wù)故障時(shí),被迫中斷的事務(wù)可能已對數(shù)據(jù)庫進(jìn)行丁修改,為了消除該事務(wù)對數(shù)據(jù)庫的影響,要利用日志文件中所記載的信息,強(qiáng)行回滾該事務(wù),將數(shù)據(jù)庫恢復(fù)到修改前的初始狀態(tài)。
為此,要檢查日志文件中由這些事務(wù)所升謹(jǐn)引起的發(fā)生變化的記錄,取消這些沒有完成的事務(wù)所做的一切改變,這吵春基類恢復(fù)操作稱為事務(wù)撤銷。
2、系統(tǒng)故障:
系統(tǒng)故障的恢復(fù)要完成兩方面的工作,既要撤銷所有末完成的事務(wù),還要重做所有已提交的事務(wù),這樣才能將數(shù)據(jù)庫真正恢復(fù)到一致的狀態(tài)。
3、介質(zhì)故障:
介質(zhì)故障比事務(wù)故障和系統(tǒng)故障發(fā)生的可能性要小,但這是最嚴(yán)重的一種故障,破壞性很大,磁盤上的物理數(shù)據(jù)和日志文件可能被破壞,這需要裝入發(fā)生介質(zhì)故障前最新的后備數(shù)據(jù)庫副本,然后利用日志文件重做該副本后所運(yùn)行的所有事務(wù)。
“數(shù)據(jù)故障恢復(fù)”和“完整森肢性約束”、“并e799bee5baa6e4b893e5b19e發(fā)控制”一樣,都是數(shù)據(jù)庫數(shù)據(jù)保護(hù)機(jī)制中的一種完整性控制。所有的系統(tǒng)都免不了會(huì)發(fā)生故障,有可能是硬件失靈,有可能是軟件系統(tǒng)崩潰,也有可能是其他外界的原因,比如斷電等等。
數(shù)據(jù)庫運(yùn)行的突然中斷會(huì)使數(shù)據(jù)庫處在一個(gè)錯(cuò)誤的狀態(tài),而且故障排除后沒有辦法讓系統(tǒng)精確地從斷點(diǎn)繼續(xù)執(zhí)行下去。這就要求DBMS要有一套故障后的數(shù)據(jù)恢復(fù)機(jī)構(gòu),保證數(shù)據(jù)庫能夠回復(fù)到一致的、正確地狀態(tài)去。
1、用戶進(jìn)程提交一條sql語句給服務(wù)器進(jìn)程
SELECT * FROM EMP WHERE EMPNO = 7999
2、服務(wù)器進(jìn)程從用戶進(jìn)程把信息接收到后,在PGA中就要此進(jìn)程分配所需內(nèi)存,存儲(chǔ)相關(guān)的信息,如在會(huì)話內(nèi)存存儲(chǔ)相關(guān)的登錄信息等。
3、服務(wù)器進(jìn)程把這個(gè)sql語句的字符轉(zhuǎn)化為ASCII等效數(shù)字碼,接著這個(gè)ASCII碼被傳遞給一個(gè)HASH 函數(shù),并返回一個(gè)hash 值,然后服務(wù)器進(jìn)程將到shared pool中的library cache中去查找是否存在相同的hash值,如果存在,服務(wù)器進(jìn)程將使用這條語句已在高速緩存在 SHARED POOL 的library cache 中的已分析過的執(zhí)行計(jì)劃版本來執(zhí)行。
4、如果不存在,服務(wù)器進(jìn)程將在CGA中,配合UGA內(nèi)容對sql,進(jìn)行語法分析,首先檢查語法的正確性,接著對語句中涉及的表,索引,視圖等對象進(jìn)行解析,并對照數(shù)據(jù)字典檢查這些對象的名稱以及相關(guān)結(jié)構(gòu),并根據(jù)ORACLE 選用的優(yōu)化模式以及數(shù)據(jù)字典中是否存在相應(yīng)對象的統(tǒng)計(jì)數(shù)據(jù)和是否使用了存儲(chǔ)大綱來生成一個(gè)執(zhí)行計(jì)劃或從存儲(chǔ)大綱中選用一個(gè)執(zhí)行計(jì)劃,然后再用數(shù)據(jù)字典核對此用戶對相應(yīng)對象的執(zhí)行權(quán)限,最后生成一個(gè)編譯代碼。
5、ORACLE 將這條 sql 語句的本身實(shí)際文本、HASH 值、編譯代碼、與此語名相關(guān)聯(lián)的任何統(tǒng)計(jì)數(shù)據(jù)和該語句的執(zhí)行計(jì)劃緩存在 SHARED POOL 的 library cache中。服務(wù)器進(jìn)程通過 SHARED POOL 鎖存器(shared pool latch)來申請可以向哪些共享 PL/SQL 區(qū)中緩存這此內(nèi)容,也就是說被SHARED POOL 鎖存器鎖定的 PL/SQL 區(qū)中的塊不可被覆蓋,因?yàn)檫@些塊可能被其它進(jìn)程所使用。
6、在 SQL 分析階段將用到 LIBRARY CACHE,從數(shù)據(jù)字典中核對表、視圖等結(jié)構(gòu)的時(shí)候,需要將數(shù)據(jù)字典從磁盤讀入 LIBRARY CACHE,因此,在讀入之前也要使用LIBRARY CACHE 鎖存器(library cache pin,library cache lock)來申請用于緩存數(shù)據(jù)字典。到現(xiàn)在為止,這盯慧臘個(gè) sql 語句已經(jīng)被編譯成可執(zhí)碧桐行的代碼了,但還不知道要操作哪些數(shù)據(jù),所以服務(wù)器進(jìn)程還要為這個(gè) sql 準(zhǔn)備預(yù)處理數(shù)據(jù)。
7、首先服務(wù)器進(jìn)程要判斷所需數(shù)據(jù)是否在 db buffer 存在,如果存在且可用,則直接獲取該數(shù)據(jù),同時(shí)根據(jù)LRU 算法增加其訪問計(jì)數(shù);如果 buffer不存在所需數(shù)據(jù),則要從數(shù)據(jù)文件上讀取首先服務(wù)器進(jìn)程將在表頭部請求 TM 鎖(保證此事務(wù)執(zhí)行過程其他用戶不能修改表的結(jié)構(gòu)),如果成功加 TM 鎖,再請求一些行級(jí)鎖(TX 鎖),如果 TM、TX 鎖都成功加鎖,那么才開始從數(shù)據(jù)文件讀數(shù)據(jù),在讀數(shù)據(jù)之前,要先為讀取的文件準(zhǔn)備好buffer 空間。服務(wù)器進(jìn)程需要掃面 LRU list 尋找 free db buffer,掃描的過程中,服務(wù)器進(jìn)程會(huì)把發(fā)現(xiàn)的所有已經(jīng)被凱滑修改過的 db buffer 注冊到 dirty list 中, 這些 dirty buffer 會(huì)通過 dbwr 的觸發(fā)條件,隨后會(huì)被寫出到數(shù)據(jù)文件,找到了足夠的空閑 buffer,就可以把請求的數(shù)據(jù)行所在的數(shù)據(jù)塊放入到 db buffer 的空閑區(qū)域或者覆蓋已經(jīng)被擠出 LRU list 的非臟數(shù)據(jù)塊緩沖區(qū),并排列在 LRU list 的頭部,也就是在數(shù)據(jù)塊放入 DB BUFFER 之前也是要先申請 db buffer 中的鎖存器,成功加鎖后,才能讀數(shù)據(jù)到 db buffer。
8、記日志現(xiàn)在數(shù)據(jù)已經(jīng)被讀入到db buffer了,現(xiàn)在服務(wù)器進(jìn)程將該語句所影響的并被讀入db buffer 中的這些行數(shù)據(jù)的 rowid 及要更新的原值和新值及 scn 等信息從 PGA 逐條的寫入 redo log buffer 中。在寫入 redo log buffer 之前也要事先請求 redo log buffer 的鎖存器,成功加鎖后才開始寫入,當(dāng)寫入達(dá)到 redo log buffer 大小的三分之一或?qū)懭肓窟_(dá)到 1M 或超過三秒后或發(fā)生檢查點(diǎn)時(shí)或者 dbwr 之前發(fā)生,都會(huì)觸發(fā)lgwr進(jìn)程把redo log buffer 的數(shù)據(jù)寫入磁盤上的 redo file 文件中(這個(gè)時(shí)候會(huì)產(chǎn)生log file sync 等待事件)已經(jīng)被寫入 redofile 的 redo log buffer 所持有的鎖存器會(huì)被釋放,并可被后來的寫入信息覆蓋,redo log buffer是循環(huán)使用的。Redo file 也是循環(huán)使用的,當(dāng)一個(gè) redo file 寫滿后,lgwr 進(jìn)程會(huì)自動(dòng)切換到下一 redo file(這個(gè)時(shí)候可能出現(xiàn) log fileswitch(checkpoint complete)等待事件)。如果是歸檔模式,歸檔進(jìn)程還要將前一個(gè)寫滿的 redo file 文件的內(nèi)容寫到歸檔日志文件中(這個(gè)時(shí)候可能出現(xiàn) log file switch(archiving needed)。
9、為事務(wù)建立回滾段在完成本事務(wù)所有相關(guān)的 redo log buffer 之后,服務(wù)器進(jìn)程開始改寫這個(gè) db buffer的塊頭部事務(wù)列表并寫入 scn,然后 copy 包含這個(gè)塊的頭部事務(wù)列表及 scn 信息的數(shù)據(jù)副本放入回滾段中,將這時(shí)回滾段中的信息稱為數(shù)據(jù)塊的 前映 像 , 這個(gè)前映像用于以后的回滾、恢復(fù)和一致性讀。(回滾段可以存儲(chǔ)在專門的回滾表空間中,這個(gè)表空間由一個(gè)或多個(gè)物理文件組成,并專用于回滾表空間,回滾段也可在其它 表空間中的數(shù)據(jù)文件中開辟。
10、本事務(wù)修改數(shù)據(jù)塊 準(zhǔn)備工作都已經(jīng)做好了,現(xiàn)在可以改寫 db buffer 塊的數(shù)據(jù)內(nèi)容了,并在塊的頭部寫 入回滾段的地址。
11、放入 dirty list 如果一個(gè)行數(shù)據(jù)多次 update 而未 commit,則在回滾段中將會(huì)有多個(gè) 前映像除了之一個(gè)前映像含有scn信息外,其他每個(gè)前映像的頭部都有scn信息和前前映像回滾段地址。一個(gè)update 只對應(yīng)一個(gè)scn,然后服務(wù)器進(jìn)程將在 dirty list中建立一 條指向此db buffer 塊的指針(方便 dbwr 進(jìn)程可以找到 dirty list 的 db buffer 數(shù)據(jù)塊并寫入數(shù)據(jù)文件中)。 接著服務(wù)器進(jìn)程會(huì)從數(shù)據(jù)文件中繼續(xù)讀入第二個(gè)數(shù)據(jù)塊,重復(fù)前一數(shù)據(jù)塊的動(dòng)作,數(shù)據(jù)塊的讀入、記日志、建 立回滾段、修改數(shù)據(jù)塊、放入 dirty list。當(dāng) dirty queue 的長度達(dá)到閥值(一般是 25%),服務(wù)器進(jìn)程將通知dbwr 把臟數(shù)據(jù)寫出,就是釋放 db buffer 上的鎖存器,騰出更多的 free db buffer。前面一直都是在說明oracle 一次讀一個(gè)數(shù)據(jù)塊,其實(shí) oracle 可以一次讀入多個(gè)數(shù)據(jù)塊(db_file_multiblock_read_count 來設(shè)置一 次讀入塊的個(gè)數(shù))
12、在預(yù)處理的數(shù)據(jù)已經(jīng)緩存在 db buffer 或剛剛被從數(shù)據(jù)文件讀入到 db buffer 中,就要根據(jù) sql 語句的類型來決定接下來如何操作。
(1)如果是 select 語句,則要查看 db buffer 塊的頭部是否有事務(wù),如果有事務(wù),則從回滾段中讀取數(shù)據(jù);如果沒有事務(wù),則比較 select 的 scn 和 db buffer 塊頭部的 scn,如果前者小于后者,仍然要從回滾段中讀取數(shù)據(jù);如果前者大于后者,說明這是一非臟緩存,可以直接讀取這個(gè) db buffer 塊的中內(nèi)容。
(2)如果是 DML 操作,則即使在 db buffer 中找到一個(gè)沒有事務(wù),而且 SCN 比自己小的非臟緩存數(shù)據(jù)塊,服務(wù)器進(jìn)程仍然要到表的頭部對這條記錄申請加鎖,加鎖成功才能進(jìn)行后續(xù)動(dòng)作,如果不成功,則要等待前面的進(jìn)程解鎖后才能進(jìn)行動(dòng)作(這個(gè)時(shí)候阻塞是 tx 鎖阻塞)。用戶 commit 或 rollback 到現(xiàn)在為止,數(shù)據(jù)已經(jīng)在 db buffer 或數(shù)據(jù)文件中修改完成,但是否要永久寫到數(shù)文件中,要由用戶來決定 commit(保存更改到數(shù)據(jù)文件) rollback 撤銷數(shù)據(jù)的更改)。
如果用戶執(zhí)行 commit 命令:
只有當(dāng) sql 語句所影響的所有行所在的最后一個(gè)塊被讀入 db buffer 并且重做信息被寫入 redo log buffer(僅指日志緩沖區(qū),而不包括日志文件)之后,用戶才可以發(fā)去 commit 命令,commit 觸發(fā) lgwr 進(jìn)程,但不強(qiáng)制立即 dbwr來釋放所有相應(yīng) db buffer 塊的鎖(也就是no-force-at-commit,即提交不強(qiáng)制寫),也就是說有可能雖然已經(jīng) commit 了,但在隨后的一段時(shí)間內(nèi) dbwr 還在寫這條 sql 語句所涉及的數(shù)據(jù)塊。表頭部的行鎖并不在 commit 之后立即釋放,而是要等 dbwr 進(jìn)程完成之后才釋放,這就可能會(huì)出現(xiàn)一個(gè)用戶請求另一用戶已經(jīng) commit 的資源不成功的現(xiàn)象。
A、從 Commit 和 dbwr 進(jìn)程結(jié)束之間的時(shí)間很短,如果恰巧在 commit 之后,dbwr 未結(jié)束之前斷電,因?yàn)閏ommit 之后的數(shù)據(jù)已經(jīng)屬于數(shù)據(jù)文件的內(nèi)容,但這部分文件沒有完全寫入到數(shù)據(jù)文件中。所以需要前滾。由于 commit 已經(jīng)觸發(fā) lgwr,這些所有未來得及寫入數(shù)據(jù)文件的更改會(huì)在實(shí)例重啟后,由 on 進(jìn)程根據(jù)重做日 志文件來前滾,完成之前 commit 未完成的工作(即把更改寫入數(shù)據(jù)文件)。
B、如果未 commit 就斷電了,因?yàn)閿?shù)據(jù)已經(jīng)在 db buffer 更改了,沒有 commit,說明這部分?jǐn)?shù)據(jù)不屬于數(shù)據(jù)文件,由于 dbwr 之前觸發(fā) lgwr 也就是只要數(shù)據(jù)更改,(肯定要先有 log) 所有 DBWR,在數(shù)據(jù)文件上的修改都會(huì)被先一步記入重做日志文件,實(shí)例重啟后,ON 進(jìn)程再根據(jù)重做日志文件來回滾。其實(shí) on 的前滾回滾是根據(jù)檢查點(diǎn)來完成的,當(dāng)一個(gè)全部檢查點(diǎn)發(fā)生的時(shí)候,首先讓 LGWR 進(jìn)程將redo log buffer 中的所有緩沖(包含未提交的重做信息)寫入重做日志文件,然后讓 dbwr 進(jìn)程將 db buffer 已 提交的緩沖寫入數(shù)據(jù)文件(不強(qiáng)制寫未提交的)。然后更新控制文件和數(shù)據(jù)文件頭部的 SCN,表明當(dāng)前數(shù)據(jù)庫是一致的,在相鄰的兩個(gè)檢查點(diǎn)之間有很多事務(wù),有提交和未提交的。像前面的前滾回滾比較完整的說法是如下的說明:
AA、發(fā)生檢查點(diǎn)之前斷電,并且當(dāng)時(shí)有一個(gè)未提交的改變正在進(jìn)行,實(shí)例重啟之后,ON 進(jìn)程將從上一個(gè)檢查點(diǎn)開始核對這個(gè)檢查點(diǎn)之后記錄在重做日志文件中已提交的和未提交改變,因?yàn)閐bwr 之前會(huì)觸發(fā) lgwr,所以 dbwr 對數(shù)據(jù)文件的修改一定會(huì)被先記錄在重做日志文件中。因此,斷電前被DBWN 寫進(jìn)數(shù)據(jù)文件的改變將通過重做日志文件中的記錄進(jìn)行還原,叫做回滾。
BB. 如果斷電時(shí)有一個(gè)已提交,但 dbwr 動(dòng)作還沒有完全完成的改變存在,因?yàn)橐呀?jīng)提交,提交會(huì)觸發(fā) lgwr進(jìn)程,所以不管 dbwr 動(dòng)作是否已完成,該語句將要影響的行及其產(chǎn)生的結(jié)果一定已經(jīng)記錄在重做日志文件中了,則實(shí)例重啟后,ON 進(jìn)程根據(jù)重做日志文件進(jìn)行前滾.實(shí)例失敗后用于恢復(fù)的時(shí)間由兩個(gè)檢查點(diǎn)之間的間隔大小來決定,可以通個(gè)四個(gè)參數(shù)設(shè)置檢查點(diǎn)執(zhí)行的頻率:
Log_checkpoint_interval:
決定兩個(gè)檢查點(diǎn)之間寫入重做日志文件的系統(tǒng)物理塊(redo blocks)的大小,默認(rèn)值是 0,無限制。
log_checkpoint_timeout:
兩 個(gè) 檢 查 點(diǎn) 之 間 的 時(shí) 間 長 度(秒)默 認(rèn) 值 1800s。
fast_start_io_target:
決定了用于恢復(fù)時(shí)需要處理的塊的多少,默認(rèn)值是 0,無限制。
fast_start_mttr_target:
直接決定了用于恢復(fù)的時(shí)間的長短,默認(rèn)值是 0,無限制(ON 進(jìn)程執(zhí)行的前滾 和回滾與用戶的回滾是不同的,ON 是根據(jù)重做日志文件進(jìn)行前滾或回滾,而用戶的回滾一定是根據(jù)回滾段的內(nèi)容進(jìn)行回滾的。在這里要說一下回滾段存儲(chǔ)的數(shù)據(jù),假如是 delete 操作,則回滾段將會(huì)記錄整個(gè)行的數(shù)據(jù),假如是 update,則回滾段只記錄被修改了的字段的變化前的數(shù)據(jù)(前映像),也就是沒有被修改的字段是不會(huì)被記錄的,假如是insert,則回滾段只記錄插入記錄的 rowid。 這樣假如事務(wù)提交,那回滾段中簡單標(biāo)記該事務(wù)已經(jīng)提交;假如是 回退,則如果操作是 delete,回退的時(shí)候把回滾段中數(shù)據(jù)重新寫回?cái)?shù)據(jù)塊,操作如果是 update,則把變化前數(shù)據(jù)修改回去,操作如果是 insert,則根據(jù)記錄的 rowid 把該記錄刪除。
如果用戶 rollback:
則服務(wù)器進(jìn)程會(huì)根據(jù)數(shù)據(jù)文件塊和 DB BUFFER 中塊的頭部的事務(wù)列表和 SCN 以及回滾段地址找到回滾段中相應(yīng)的修改前的副本,并且用這些原值來還原當(dāng)前數(shù)據(jù)文件中已修改但未提交的改變。如果有多個(gè)前映像 服務(wù)器進(jìn)程會(huì)在一個(gè)前映像的頭部找到 前前映像 的回滾段地址,一直找到同一事務(wù)下的最早的一個(gè)前映像 為止。一旦發(fā)出了COMMIT,用戶就不能rollback,這使得 COMMIT 后 DBWR 進(jìn)程還沒有全部完成的后續(xù)動(dòng)作得到了保障。到現(xiàn)在為例一個(gè)事務(wù)已經(jīng)結(jié)束了。
本篇文章會(huì)分析下一個(gè) sql 語句在 MySQL 中的執(zhí)行流程,包括 sql 的查詢在 MySQL 內(nèi)部會(huì)怎么流轉(zhuǎn),sql 語句的更新是怎么完成的。
在分析之前我會(huì)先帶著你看看 MySQL 的基礎(chǔ)架構(gòu),知道了 MySQL 由那些組件組成以及這些組件的作用是什么,可以幫助我們理解和解決這些問題。
一 MySQL 基礎(chǔ)架構(gòu)分析
MySQL 基本架構(gòu)畢租概覽
下圖是 MySQL 的一個(gè)簡手豎兆要架構(gòu)圖,從下圖你可以很清晰的看到用戶的 SQL 語句在 MySQL 內(nèi)部是如何執(zhí)行的。
先簡單介紹一下下圖涉及的一些組件的基本作用幫助大家理解這幅圖,在 1.2 節(jié)中會(huì)詳細(xì)介紹到這些組件的作用。
連接器: 身份認(rèn)證和權(quán)限相關(guān)(登錄 MySQL 的時(shí)候)。
查詢緩存: 執(zhí)行查詢語句的時(shí)候,會(huì)先查詢緩存(MySQL 8.0 版本后移除,因?yàn)檫@個(gè)功能不太實(shí)用)。
分析器: 沒有命中緩存的話,SQL 語句就會(huì)經(jīng)過分析器,分析器說白了就是要先看你的 SQL 語句要干嘛,再檢查你的 SQL 語句語法是否正確。
優(yōu)化器: 按照 MySQL 認(rèn)為更優(yōu)的纖豎方案去執(zhí)行。
1、用戶進(jìn)程提交一條sql語句給服務(wù)器進(jìn)程
SELECT * FROM EMP WHERE EMPNO = 7999
2、服務(wù)器進(jìn)程從用戶進(jìn)程把信息接收到后,在PGA中就要此進(jìn)程分配所需內(nèi)存,存儲(chǔ)相關(guān)的信息,如在會(huì)話內(nèi)存存儲(chǔ)相關(guān)的登錄信息等。
3、服務(wù)器進(jìn)程把這個(gè)sql語句的字符轉(zhuǎn)化為ASCII等效數(shù)字碼,接著這個(gè)ASCII碼被傳遞給一個(gè)HASH 函數(shù),并返回一個(gè)hash 值,然后服務(wù)器進(jìn)程將到shared pool中的library cache中去查找是否存在相同的hash值,如果存在,服務(wù)器進(jìn)程將使用這條語句已在高速緩存在 SHARED POOL 的library cache 中的已分析過的執(zhí)行計(jì)劃版本來執(zhí)行。
4、如果不存在,服務(wù)器進(jìn)程將在CGA中,配合UGA內(nèi)容對sql,進(jìn)行語法分析,首先檢查語法的正確性,接著對語句中涉及的表,索引,視圖等對象進(jìn)行解析,并對照數(shù)據(jù)字典檢查這些對象的名稱以及相關(guān)結(jié)構(gòu),并根據(jù)ORACLE 選用的優(yōu)化模式以及數(shù)據(jù)字典中是否存在相應(yīng)對象的統(tǒng)計(jì)數(shù)據(jù)和是否使用了存儲(chǔ)大綱來生成一個(gè)執(zhí)行計(jì)劃或從存儲(chǔ)大綱中選用一個(gè)執(zhí)行計(jì)劃,然后再用數(shù)據(jù)字典核對此用戶對相應(yīng)對象的執(zhí)行權(quán)限,最后生成一個(gè)編譯代碼。
5、ORACLE 將這條 sql 語句的本身實(shí)際文本、HASH 值、編譯代碼、與此語名相關(guān)聯(lián)的任何統(tǒng)計(jì)數(shù)據(jù)和該語句的執(zhí)行計(jì)劃緩存在 SHARED POOL 的 library cache中。服務(wù)器進(jìn)程通過 SHARED POOL 鎖存器(shared pool latch)來申請可以向哪些共享 PL/SQL 區(qū)中緩存這此內(nèi)容,也就是說被SHARED POOL 鎖存器鎖定的 PL/SQL 區(qū)中的塊不可被覆蓋,因?yàn)檫@些塊可能被其它進(jìn)程所使用。
6、在 SQL 分析階段將用到 LIBRARY CACHE,從數(shù)據(jù)字典中核對表、視圖等結(jié)構(gòu)的時(shí)候,需要將數(shù)據(jù)字典從磁盤讀入 LIBRARY CACHE,因此,在讀入之前也要使用LIBRARY CACHE 鎖存器(library cache pin,library cache lock)來申請用于緩存數(shù)據(jù)字典。到現(xiàn)在為止,這盯慧臘個(gè) sql 語句已經(jīng)被編譯成可執(zhí)碧桐行的代碼了,但還不知道要操作哪些數(shù)據(jù),所以服務(wù)器進(jìn)程還要為這個(gè) sql 準(zhǔn)備預(yù)處理數(shù)據(jù)。
7、首先服務(wù)器進(jìn)程要判斷所需數(shù)據(jù)是否在 db buffer 存在,如果存在且可用,則直接獲取該數(shù)據(jù),同時(shí)根據(jù)LRU 算法增加其訪問計(jì)數(shù);如果 buffer不存在所需數(shù)據(jù),則要從數(shù)據(jù)文件上讀取首先服務(wù)器進(jìn)程將在表頭部請求 TM 鎖(保證此事務(wù)執(zhí)行過程其他用戶不能修改表的結(jié)構(gòu)),如果成功加 TM 鎖,再請求一些行級(jí)鎖(TX 鎖),如果 TM、TX 鎖都成功加鎖,那么才開始從數(shù)據(jù)文件讀數(shù)據(jù),在讀數(shù)據(jù)之前,要先為讀取的文件準(zhǔn)備好buffer 空間。服務(wù)器進(jìn)程需要掃面 LRU list 尋找 free db buffer,掃描的過程中,服務(wù)器進(jìn)程會(huì)把發(fā)現(xiàn)的所有已經(jīng)被凱滑修改過的 db buffer 注冊到 dirty list 中, 這些 dirty buffer 會(huì)通過 dbwr 的觸發(fā)條件,隨后會(huì)被寫出到數(shù)據(jù)文件,找到了足夠的空閑 buffer,就可以把請求的數(shù)據(jù)行所在的數(shù)據(jù)塊放入到 db buffer 的空閑區(qū)域或者覆蓋已經(jīng)被擠出 LRU list 的非臟數(shù)據(jù)塊緩沖區(qū),并排列在 LRU list 的頭部,也就是在數(shù)據(jù)塊放入 DB BUFFER 之前也是要先申請 db buffer 中的鎖存器,成功加鎖后,才能讀數(shù)據(jù)到 db buffer。
8、記日志現(xiàn)在數(shù)據(jù)已經(jīng)被讀入到db buffer了,現(xiàn)在服務(wù)器進(jìn)程將該語句所影響的并被讀入db buffer 中的這些行數(shù)據(jù)的 rowid 及要更新的原值和新值及 scn 等信息從 PGA 逐條的寫入 redo log buffer 中。在寫入 redo log buffer 之前也要事先請求 redo log buffer 的鎖存器,成功加鎖后才開始寫入,當(dāng)寫入達(dá)到 redo log buffer 大小的三分之一或?qū)懭肓窟_(dá)到 1M 或超過三秒后或發(fā)生檢查點(diǎn)時(shí)或者 dbwr 之前發(fā)生,都會(huì)觸發(fā)lgwr進(jìn)程把redo log buffer 的數(shù)據(jù)寫入磁盤上的 redo file 文件中(這個(gè)時(shí)候會(huì)產(chǎn)生log file sync 等待事件)已經(jīng)被寫入 redofile 的 redo log buffer 所持有的鎖存器會(huì)被釋放,并可被后來的寫入信息覆蓋,redo log buffer是循環(huán)使用的。Redo file 也是循環(huán)使用的,當(dāng)一個(gè) redo file 寫滿后,lgwr 進(jìn)程會(huì)自動(dòng)切換到下一 redo file(這個(gè)時(shí)候可能出現(xiàn) log fileswitch(checkpoint complete)等待事件)。如果是歸檔模式,歸檔進(jìn)程還要將前一個(gè)寫滿的 redo file 文件的內(nèi)容寫到歸檔日志文件中(這個(gè)時(shí)候可能出現(xiàn) log file switch(archiving needed)。
9、為事務(wù)建立回滾段在完成本事務(wù)所有相關(guān)的 redo log buffer 之后,服務(wù)器進(jìn)程開始改寫這個(gè) db buffer的塊頭部事務(wù)列表并寫入 scn,然后 copy 包含這個(gè)塊的頭部事務(wù)列表及 scn 信息的數(shù)據(jù)副本放入回滾段中,將這時(shí)回滾段中的信息稱為數(shù)據(jù)塊的 前映 像 , 這個(gè)前映像用于以后的回滾、恢復(fù)和一致性讀。(回滾段可以存儲(chǔ)在專門的回滾表空間中,這個(gè)表空間由一個(gè)或多個(gè)物理文件組成,并專用于回滾表空間,回滾段也可在其它 表空間中的數(shù)據(jù)文件中開辟。
10、本事務(wù)修改數(shù)據(jù)塊 準(zhǔn)備工作都已經(jīng)做好了,現(xiàn)在可以改寫 db buffer 塊的數(shù)據(jù)內(nèi)容了,并在塊的頭部寫 入回滾段的地址。
11、放入 dirty list 如果一個(gè)行數(shù)據(jù)多次 update 而未 commit,則在回滾段中將會(huì)有多個(gè) 前映像除了之一個(gè)前映像含有scn信息外,其他每個(gè)前映像的頭部都有scn信息和前前映像回滾段地址。一個(gè)update 只對應(yīng)一個(gè)scn,然后服務(wù)器進(jìn)程將在 dirty list中建立一 條指向此db buffer 塊的指針(方便 dbwr 進(jìn)程可以找到 dirty list 的 db buffer 數(shù)據(jù)塊并寫入數(shù)據(jù)文件中)。 接著服務(wù)器進(jìn)程會(huì)從數(shù)據(jù)文件中繼續(xù)讀入第二個(gè)數(shù)據(jù)塊,重復(fù)前一數(shù)據(jù)塊的動(dòng)作,數(shù)據(jù)塊的讀入、記日志、建 立回滾段、修改數(shù)據(jù)塊、放入 dirty list。當(dāng) dirty queue 的長度達(dá)到閥值(一般是 25%),服務(wù)器進(jìn)程將通知dbwr 把臟數(shù)據(jù)寫出,就是釋放 db buffer 上的鎖存器,騰出更多的 free db buffer。前面一直都是在說明oracle 一次讀一個(gè)數(shù)據(jù)塊,其實(shí) oracle 可以一次讀入多個(gè)數(shù)據(jù)塊(db_file_multiblock_read_count 來設(shè)置一 次讀入塊的個(gè)數(shù))
12、在預(yù)處理的數(shù)據(jù)已經(jīng)緩存在 db buffer 或剛剛被從數(shù)據(jù)文件讀入到 db buffer 中,就要根據(jù) sql 語句的類型來決定接下來如何操作。
(1)如果是 select 語句,則要查看 db buffer 塊的頭部是否有事務(wù),如果有事務(wù),則從回滾段中讀取數(shù)據(jù);如果沒有事務(wù),則比較 select 的 scn 和 db buffer 塊頭部的 scn,如果前者小于后者,仍然要從回滾段中讀取數(shù)據(jù);如果前者大于后者,說明這是一非臟緩存,可以直接讀取這個(gè) db buffer 塊的中內(nèi)容。
(2)如果是 DML 操作,則即使在 db buffer 中找到一個(gè)沒有事務(wù),而且 SCN 比自己小的非臟緩存數(shù)據(jù)塊,服務(wù)器進(jìn)程仍然要到表的頭部對這條記錄申請加鎖,加鎖成功才能進(jìn)行后續(xù)動(dòng)作,如果不成功,則要等待前面的進(jìn)程解鎖后才能進(jìn)行動(dòng)作(這個(gè)時(shí)候阻塞是 tx 鎖阻塞)。用戶 commit 或 rollback 到現(xiàn)在為止,數(shù)據(jù)已經(jīng)在 db buffer 或數(shù)據(jù)文件中修改完成,但是否要永久寫到數(shù)文件中,要由用戶來決定 commit(保存更改到數(shù)據(jù)文件) rollback 撤銷數(shù)據(jù)的更改)。
如果用戶執(zhí)行 commit 命令:
只有當(dāng) sql 語句所影響的所有行所在的最后一個(gè)塊被讀入 db buffer 并且重做信息被寫入 redo log buffer(僅指日志緩沖區(qū),而不包括日志文件)之后,用戶才可以發(fā)去 commit 命令,commit 觸發(fā) lgwr 進(jìn)程,但不強(qiáng)制立即 dbwr來釋放所有相應(yīng) db buffer 塊的鎖(也就是no-force-at-commit,即提交不強(qiáng)制寫),也就是說有可能雖然已經(jīng) commit 了,但在隨后的一段時(shí)間內(nèi) dbwr 還在寫這條 sql 語句所涉及的數(shù)據(jù)塊。表頭部的行鎖并不在 commit 之后立即釋放,而是要等 dbwr 進(jìn)程完成之后才釋放,這就可能會(huì)出現(xiàn)一個(gè)用戶請求另一用戶已經(jīng) commit 的資源不成功的現(xiàn)象。
A、從 Commit 和 dbwr 進(jìn)程結(jié)束之間的時(shí)間很短,如果恰巧在 commit 之后,dbwr 未結(jié)束之前斷電,因?yàn)閏ommit 之后的數(shù)據(jù)已經(jīng)屬于數(shù)據(jù)文件的內(nèi)容,但這部分文件沒有完全寫入到數(shù)據(jù)文件中。所以需要前滾。由于 commit 已經(jīng)觸發(fā) lgwr,這些所有未來得及寫入數(shù)據(jù)文件的更改會(huì)在實(shí)例重啟后,由 on 進(jìn)程根據(jù)重做日 志文件來前滾,完成之前 commit 未完成的工作(即把更改寫入數(shù)據(jù)文件)。
B、如果未 commit 就斷電了,因?yàn)閿?shù)據(jù)已經(jīng)在 db buffer 更改了,沒有 commit,說明這部分?jǐn)?shù)據(jù)不屬于數(shù)據(jù)文件,由于 dbwr 之前觸發(fā) lgwr 也就是只要數(shù)據(jù)更改,(肯定要先有 log) 所有 DBWR,在數(shù)據(jù)文件上的修改都會(huì)被先一步記入重做日志文件,實(shí)例重啟后,ON 進(jìn)程再根據(jù)重做日志文件來回滾。其實(shí) on 的前滾回滾是根據(jù)檢查點(diǎn)來完成的,當(dāng)一個(gè)全部檢查點(diǎn)發(fā)生的時(shí)候,首先讓 LGWR 進(jìn)程將redo log buffer 中的所有緩沖(包含未提交的重做信息)寫入重做日志文件,然后讓 dbwr 進(jìn)程將 db buffer 已 提交的緩沖寫入數(shù)據(jù)文件(不強(qiáng)制寫未提交的)。然后更新控制文件和數(shù)據(jù)文件頭部的 SCN,表明當(dāng)前數(shù)據(jù)庫是一致的,在相鄰的兩個(gè)檢查點(diǎn)之間有很多事務(wù),有提交和未提交的。像前面的前滾回滾比較完整的說法是如下的說明:
AA、發(fā)生檢查點(diǎn)之前斷電,并且當(dāng)時(shí)有一個(gè)未提交的改變正在進(jìn)行,實(shí)例重啟之后,ON 進(jìn)程將從上一個(gè)檢查點(diǎn)開始核對這個(gè)檢查點(diǎn)之后記錄在重做日志文件中已提交的和未提交改變,因?yàn)閐bwr 之前會(huì)觸發(fā) lgwr,所以 dbwr 對數(shù)據(jù)文件的修改一定會(huì)被先記錄在重做日志文件中。因此,斷電前被DBWN 寫進(jìn)數(shù)據(jù)文件的改變將通過重做日志文件中的記錄進(jìn)行還原,叫做回滾。
BB. 如果斷電時(shí)有一個(gè)已提交,但 dbwr 動(dòng)作還沒有完全完成的改變存在,因?yàn)橐呀?jīng)提交,提交會(huì)觸發(fā) lgwr進(jìn)程,所以不管 dbwr 動(dòng)作是否已完成,該語句將要影響的行及其產(chǎn)生的結(jié)果一定已經(jīng)記錄在重做日志文件中了,則實(shí)例重啟后,ON 進(jìn)程根據(jù)重做日志文件進(jìn)行前滾.實(shí)例失敗后用于恢復(fù)的時(shí)間由兩個(gè)檢查點(diǎn)之間的間隔大小來決定,可以通個(gè)四個(gè)參數(shù)設(shè)置檢查點(diǎn)執(zhí)行的頻率:
Log_checkpoint_interval:
決定兩個(gè)檢查點(diǎn)之間寫入重做日志文件的系統(tǒng)物理塊(redo blocks)的大小,默認(rèn)值是 0,無限制。
log_checkpoint_timeout:
兩 個(gè) 檢 查 點(diǎn) 之 間 的 時(shí) 間 長 度(秒)默 認(rèn) 值 1800s。
fast_start_io_target:
決定了用于恢復(fù)時(shí)需要處理的塊的多少,默認(rèn)值是 0,無限制。
fast_start_mttr_target:
直接決定了用于恢復(fù)的時(shí)間的長短,默認(rèn)值是 0,無限制(ON 進(jìn)程執(zhí)行的前滾 和回滾與用戶的回滾是不同的,ON 是根據(jù)重做日志文件進(jìn)行前滾或回滾,而用戶的回滾一定是根據(jù)回滾段的內(nèi)容進(jìn)行回滾的。在這里要說一下回滾段存儲(chǔ)的數(shù)據(jù),假如是 delete 操作,則回滾段將會(huì)記錄整個(gè)行的數(shù)據(jù),假如是 update,則回滾段只記錄被修改了的字段的變化前的數(shù)據(jù)(前映像),也就是沒有被修改的字段是不會(huì)被記錄的,假如是insert,則回滾段只記錄插入記錄的 rowid。 這樣假如事務(wù)提交,那回滾段中簡單標(biāo)記該事務(wù)已經(jīng)提交;假如是 回退,則如果操作是 delete,回退的時(shí)候把回滾段中數(shù)據(jù)重新寫回?cái)?shù)據(jù)塊,操作如果是 update,則把變化前數(shù)據(jù)修改回去,操作如果是 insert,則根據(jù)記錄的 rowid 把該記錄刪除。
如果用戶 rollback:
則服務(wù)器進(jìn)程會(huì)根據(jù)數(shù)據(jù)文件塊和 DB BUFFER 中塊的頭部的事務(wù)列表和 SCN 以及回滾段地址找到回滾段中相應(yīng)的修改前的副本,并且用這些原值來還原當(dāng)前數(shù)據(jù)文件中已修改但未提交的改變。如果有多個(gè)前映像 服務(wù)器進(jìn)程會(huì)在一個(gè)前映像的頭部找到 前前映像 的回滾段地址,一直找到同一事務(wù)下的最早的一個(gè)前映像 為止。一旦發(fā)出了COMMIT,用戶就不能rollback,這使得 COMMIT 后 DBWR 進(jìn)程還沒有全部完成的后續(xù)動(dòng)作得到了保障。到現(xiàn)在為例一個(gè)事務(wù)已經(jīng)結(jié)束了。
一個(gè)數(shù)據(jù)庫有5個(gè)事務(wù)的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于一個(gè)數(shù)據(jù)庫有5個(gè)事務(wù),5個(gè)事務(wù)的數(shù)據(jù)庫:如何確保數(shù)據(jù)一致性?,數(shù)據(jù)庫事務(wù)正確執(zhí)行的四個(gè)基本要素包括,數(shù)據(jù)庫管理系統(tǒng) (DBMS) 的五個(gè)重要軟件組成部分是什么?,sql運(yùn)行問題?的信息別忘了在本站進(jìn)行查找喔。
成都創(chuàng)新互聯(lián)科技有限公司,是一家專注于互聯(lián)網(wǎng)、IDC服務(wù)、應(yīng)用軟件開發(fā)、網(wǎng)站建設(shè)推廣的公司,為客戶提供互聯(lián)網(wǎng)基礎(chǔ)服務(wù)!
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡單好用,價(jià)格厚道的香港/美國云服務(wù)器和獨(dú)立服務(wù)器。創(chuàng)新互聯(lián)成都老牌IDC服務(wù)商,專注四川成都IDC機(jī)房服務(wù)器托管/機(jī)柜租用。為您精選優(yōu)質(zhì)idc數(shù)據(jù)中心機(jī)房租用、服務(wù)器托管、機(jī)柜租賃、大帶寬租用,可選線路電信、移動(dòng)、聯(lián)通等。
分享題目:5個(gè)事務(wù)的數(shù)據(jù)庫:如何確保數(shù)據(jù)一致性?(一個(gè)數(shù)據(jù)庫有5個(gè)事務(wù))
網(wǎng)頁鏈接:http://m.fisionsoft.com.cn/article/dhshjip.html


咨詢
建站咨詢
