日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
5個事務的數(shù)據(jù)庫:如何確保數(shù)據(jù)一致性?(一個數(shù)據(jù)庫有5個事務)

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

達坂城網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián),達坂城網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為達坂城上千余家提供企業(yè)網(wǎng)站建設(shè)服務。企業(yè)網(wǎng)站搭建\外貿(mào)營銷網(wǎng)站建設(shè)要多少錢,請找那個售后服務好的達坂城做網(wǎng)站的公司定做!

1. ACID事務

ACID是最常用的數(shù)據(jù)庫事務技術(shù)。ACID是Atomicity、Consistency、Isolation、Durability的縮寫,分別代表原子性、一致性、隔離性和持久性。ACID作為一個完整的事務,將被數(shù)據(jù)庫系統(tǒng)執(zhí)行或回滾。

*原子性:一個事務的所有操作在協(xié)商一個單獨的工作單位時執(zhí)行,要么全部成功,要么全部失敗。

*一致性:一個事務的所有操作都必須遵循一定的約束,以遵循業(yè)務邏輯規(guī)則。

*隔離性:并發(fā)執(zhí)行事務的能力。各個事務之間可以完全地相互獨立,同時也可以互相配合。

*持久性:在事務完成后,所有修改都將永久保存在數(shù)據(jù)庫中。

2. BASE技術(shù)

如果ACID技術(shù)存在一些缺點,例如對系統(tǒng)進行并發(fā)更新和持久性要求高的要求,那么BASE技術(shù)就提供了一個更可擴展和更靈活的選擇。

*基本可用:盡可能地保證高故障容忍性、面向分布式架構(gòu),并實現(xiàn)最小化的故障造成的影響。

*軟狀態(tài):即讓系統(tǒng)在一個時間段內(nèi)保持中間狀態(tài),而不一定偏向某一方向。

*最終一致性:在一段時間后,所有的狀態(tài)都變?yōu)樽罱K一致狀態(tài)。

3. 分布式事務

分布式事務處理多個分布式系統(tǒng)之間的事務。不同分布式系統(tǒng)的數(shù)據(jù)分布在不同的物理位置上,可能由不同的管理員進行管理。分布式事務提供了一種數(shù)據(jù)處理方式,可以確保在分布式環(huán)境下,事務的正確執(zhí)行。

* XA:XA是分布式事務的一種協(xié)議,其目的是確保一個多個數(shù)據(jù)庫之間的事務的一致性。

* Two-Phase Commit Protocol:這種協(xié)議需要在所有參與節(jié)點(數(shù)據(jù)庫服務器)之間進行一個預提交過程,確認所有事務都成功完成,并且所有其他節(jié)點都已經(jīng)做好提交的準備。這樣,事務就可以成功提交,所有參與節(jié)點的數(shù)據(jù)都能更新到最新狀態(tài),實現(xiàn)數(shù)據(jù)一致性。

4. NoSQL的事務

NoSQL代表了不僅僅是SQL的數(shù)據(jù)庫系統(tǒng),但它們的共同點是它們都不使用傳統(tǒng)的關(guān)系型數(shù)據(jù)庫,因此可能不支持ACID事務。相反,這些數(shù)據(jù)庫系統(tǒng)主要支持基于日志的系統(tǒng),例如本地存儲,支持最終一致性。

5. 原子操作

原子操作是在不用事務的情況下實現(xiàn)數(shù)據(jù)局部更新的一種技術(shù)。原子操作確保如果任何一部分失敗,整個操作將被取消并恢復到原始狀態(tài)。原子操作經(jīng)常應用于高并發(fā)和資源受限的環(huán)境,如在開發(fā)云服務、移動應用程序和Web系統(tǒng)時會經(jīng)常用到。

數(shù)據(jù)庫系統(tǒng)必須確保數(shù)據(jù)的一致性,以便它們不會在事務處理過程中遭受損失。本文介紹了5種常用的事務技術(shù),以及如何使用它們來確保數(shù)據(jù)的一致性。無論使用哪種技術(shù),都要為系統(tǒng)提供適當?shù)馁Y源和保障,以確保系統(tǒng)在處理事務時保持高效率和一致性。

相關(guān)問題拓展閱讀:

  • 數(shù)據(jù)庫事務正確執(zhí)行的四個基本要素包括
  • 數(shù)據(jù)庫管理系統(tǒng) (DBMS) 的五個重要軟件組成部分是什么?
  • sql運行問題?

數(shù)據(jù)庫事務正確執(zhí)行的四個基本要素包括

ACID,指數(shù)據(jù)庫事務正確執(zhí)行的四個基本要素的縮寫。包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。一個支持事務(Transaction)的數(shù)據(jù)庫,必需要具有這四種特性,否則在事務過程(Transaction processing)當中無法保證數(shù)據(jù)的正確性,交易過程極可能達不到交易方的要求。

原子性

整個事務中的所有操作,要么全部完成,要么全部不完成,不可能停滯在中間某個環(huán)節(jié)。事務在執(zhí)行過程中發(fā)生錯誤,會被回滾(Rollback)到事務開始前的狀態(tài),就像這銀伍個事務從來沒有執(zhí)行過一樣。

一致性

一個事務可以封裝狀態(tài)改變(除非它是一個只讀的)。事務必須始終保持系統(tǒng)處于一致的狀態(tài),不管在任何給定的時間并發(fā)事務有多少。

也就是說:如果事務是并發(fā)多個,系統(tǒng)也必須如同串行事務一樣操作。其主要特征是保護性和不變性(Preserving an Invariant),以轉(zhuǎn)賬案例為例,假設(shè)有五個賬戶,每個賬戶余額是100元,那么五個賬戶總額是500元,如果在這個5個賬戶之間同時發(fā)生多個轉(zhuǎn)賬,無論并發(fā)多少個,比如在A與B賬戶之間轉(zhuǎn)賬5元,在C與D賬戶之間轉(zhuǎn)賬10元,在B與E之間轉(zhuǎn)賬15元,五個賬戶總額也應該還是500元,這就是保護性和不變性

隔離性

隔離狀態(tài)執(zhí)行事務,使它們好像是系統(tǒng)在給定時間內(nèi)執(zhí)行的唯一操作。如果有兩個事務,運行在相同的時間內(nèi),執(zhí)行相同的功能,事務正稿的隔離性將確保每一事務在系統(tǒng)中認為只有該事務在使用系統(tǒng)舉搏孝。這種屬性有時稱為串行化,為了防止事務操作間的混淆,必須串行化或序列化請求,使得在同一時間僅有一個請求用于同一數(shù)據(jù)。

持久性

在事務完成以后,該事務對數(shù)據(jù)庫所作的更改便持久的保存在數(shù)據(jù)庫之中,并不會被回滾。

由于一項操作通常會包含許多子操作,而這些子操作可能會因為硬件的損壞或其他因素產(chǎn)生問題,要正確實現(xiàn)ACID并不容易。ACID建議數(shù)據(jù)庫將所有需要更新以及修改的資料一次操作完畢,但實際上并不可行。

目前主要有兩種方式實現(xiàn)ACID:之一種是Write ahead logging,也就是日志式的方式(現(xiàn)代數(shù)據(jù)庫均基于這種方式)。第二種是Shadow paging。

數(shù)據(jù)庫管理系統(tǒng) (DBMS) 的五個重要軟件組成部分是什么?

DBMS的五個重要的軟件組成部分鉛殲\x0d\x0a①DBMS引擎\x0d\x0a是DBMS中最重要的部分,它接受來自其他各個DBMS子系統(tǒng)的邏輯查詢請求,并將邏輯查詢請求轉(zhuǎn)換成其對應的物理形式,實際上對數(shù)據(jù)庫和數(shù)據(jù)字典的存取感覺上就如同對它們在存儲設(shè)備上進行的存取。\x0d\x0a②嘩李數(shù)據(jù)定義子系統(tǒng)\x0d\x0a幫助人們在數(shù)據(jù)庫中建立并維護數(shù)據(jù)字典,以及定義數(shù)據(jù)庫的文件結(jié)構(gòu)。\x0d\x0a③數(shù)據(jù)操作子系統(tǒng)\x0d\x0a幫助用戶增加、修改及刪除數(shù)據(jù)庫中的信息,并幫助用戶在亂激遲數(shù)據(jù)庫中挖掘有價值的信息。\x0d\x0a④應用程序生成子系統(tǒng)\x0d\x0a包含了用以幫助用戶建立面向事務處理的應用程序 。工具包括:建立數(shù)據(jù)輸入屏幕功能,為特定的DBMS選定程序設(shè)計語言,并利用程序設(shè)計語言為每個獨立的DBMS建立一個公共的操作交互界面。\x0d\x0a⑤數(shù)據(jù)管理子系統(tǒng)\x0d\x0a通過自身提供的備份與恢復工具、安全管理工具、更優(yōu)化查詢工具、并發(fā)控制和更新管理工具,幫助人們管理整個數(shù)據(jù)庫環(huán)境。

sql運行問題?

sql運行問題?

數(shù)據(jù)庫運行過程中常見的故障有3類:事物故障、系統(tǒng)故障、介質(zhì)故障。

恢復策略:

1、事物故障:

發(fā)生事務故障時,被迫中斷的事務可能已對數(shù)據(jù)庫進行丁修改,為了消除該事務對數(shù)據(jù)庫的影響,要利用日志文件中所記載的信息,強行回滾該事務,將數(shù)據(jù)庫恢復到修改前的初始狀態(tài)。

為此,要檢查日志文件中由這些事務所升謹引起的發(fā)生變化的記錄,取消這些沒有完成的事務所做的一切改變,這吵春基類恢復操作稱為事務撤銷。

2、系統(tǒng)故障:

系統(tǒng)故障的恢復要完成兩方面的工作,既要撤銷所有末完成的事務,還要重做所有已提交的事務,這樣才能將數(shù)據(jù)庫真正恢復到一致的狀態(tài)。

3、介質(zhì)故障:

介質(zhì)故障比事務故障和系統(tǒng)故障發(fā)生的可能性要小,但這是最嚴重的一種故障,破壞性很大,磁盤上的物理數(shù)據(jù)和日志文件可能被破壞,這需要裝入發(fā)生介質(zhì)故障前最新的后備數(shù)據(jù)庫副本,然后利用日志文件重做該副本后所運行的所有事務。

“數(shù)據(jù)故障恢復”和“完整森肢性約束”、“并e799bee5baa6e4b893e5b19e發(fā)控制”一樣,都是數(shù)據(jù)庫數(shù)據(jù)保護機制中的一種完整性控制。所有的系統(tǒng)都免不了會發(fā)生故障,有可能是硬件失靈,有可能是軟件系統(tǒng)崩潰,也有可能是其他外界的原因,比如斷電等等。

數(shù)據(jù)庫運行的突然中斷會使數(shù)據(jù)庫處在一個錯誤的狀態(tài),而且故障排除后沒有辦法讓系統(tǒng)精確地從斷點繼續(xù)執(zhí)行下去。這就要求DBMS要有一套故障后的數(shù)據(jù)恢復機構(gòu),保證數(shù)據(jù)庫能夠回復到一致的、正確地狀態(tài)去。

1、用戶進程提交一條sql語句給服務器進程

SELECT * FROM EMP WHERE EMPNO = 7999

2、服務器進程從用戶進程把信息接收到后,在PGA中就要此進程分配所需內(nèi)存,存儲相關(guān)的信息,如在會話內(nèi)存存儲相關(guān)的登錄信息等。

3、服務器進程把這個sql語句的字符轉(zhuǎn)化為ASCII等效數(shù)字碼,接著這個ASCII碼被傳遞給一個HASH 函數(shù),并返回一個hash 值,然后服務器進程將到shared pool中的library cache中去查找是否存在相同的hash值,如果存在,服務器進程將使用這條語句已在高速緩存在 SHARED POOL 的library cache 中的已分析過的執(zhí)行計劃版本來執(zhí)行。

4、如果不存在,服務器進程將在CGA中,配合UGA內(nèi)容對sql,進行語法分析,首先檢查語法的正確性,接著對語句中涉及的表,索引,視圖等對象進行解析,并對照數(shù)據(jù)字典檢查這些對象的名稱以及相關(guān)結(jié)構(gòu),并根據(jù)ORACLE 選用的優(yōu)化模式以及數(shù)據(jù)字典中是否存在相應對象的統(tǒng)計數(shù)據(jù)和是否使用了存儲大綱來生成一個執(zhí)行計劃或從存儲大綱中選用一個執(zhí)行計劃,然后再用數(shù)據(jù)字典核對此用戶對相應對象的執(zhí)行權(quán)限,最后生成一個編譯代碼。

5、ORACLE 將這條 sql 語句的本身實際文本、HASH 值、編譯代碼、與此語名相關(guān)聯(lián)的任何統(tǒng)計數(shù)據(jù)和該語句的執(zhí)行計劃緩存在 SHARED POOL 的 library cache中。服務器進程通過 SHARED POOL 鎖存器(shared pool latch)來申請可以向哪些共享 PL/SQL 區(qū)中緩存這此內(nèi)容,也就是說被SHARED POOL 鎖存器鎖定的 PL/SQL 區(qū)中的塊不可被覆蓋,因為這些塊可能被其它進程所使用。

6、在 SQL 分析階段將用到 LIBRARY CACHE,從數(shù)據(jù)字典中核對表、視圖等結(jié)構(gòu)的時候,需要將數(shù)據(jù)字典從磁盤讀入 LIBRARY CACHE,因此,在讀入之前也要使用LIBRARY CACHE 鎖存器(library cache pin,library cache lock)來申請用于緩存數(shù)據(jù)字典。到現(xiàn)在為止,這盯慧臘個 sql 語句已經(jīng)被編譯成可執(zhí)碧桐行的代碼了,但還不知道要操作哪些數(shù)據(jù),所以服務器進程還要為這個 sql 準備預處理數(shù)據(jù)。

7、首先服務器進程要判斷所需數(shù)據(jù)是否在 db buffer 存在,如果存在且可用,則直接獲取該數(shù)據(jù),同時根據(jù)LRU 算法增加其訪問計數(shù);如果 buffer不存在所需數(shù)據(jù),則要從數(shù)據(jù)文件上讀取首先服務器進程將在表頭部請求 TM 鎖(保證此事務執(zhí)行過程其他用戶不能修改表的結(jié)構(gòu)),如果成功加 TM 鎖,再請求一些行級鎖(TX 鎖),如果 TM、TX 鎖都成功加鎖,那么才開始從數(shù)據(jù)文件讀數(shù)據(jù),在讀數(shù)據(jù)之前,要先為讀取的文件準備好buffer 空間。服務器進程需要掃面 LRU list 尋找 free db buffer,掃描的過程中,服務器進程會把發(fā)現(xiàn)的所有已經(jīng)被凱滑修改過的 db buffer 注冊到 dirty list 中, 這些 dirty buffer 會通過 dbwr 的觸發(fā)條件,隨后會被寫出到數(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)在服務器進程將該語句所影響的并被讀入db buffer 中的這些行數(shù)據(jù)的 rowid 及要更新的原值和新值及 scn 等信息從 PGA 逐條的寫入 redo log buffer 中。在寫入 redo log buffer 之前也要事先請求 redo log buffer 的鎖存器,成功加鎖后才開始寫入,當寫入達到 redo log buffer 大小的三分之一或?qū)懭肓窟_到 1M 或超過三秒后或發(fā)生檢查點時或者 dbwr 之前發(fā)生,都會觸發(fā)lgwr進程把redo log buffer 的數(shù)據(jù)寫入磁盤上的 redo file 文件中(這個時候會產(chǎn)生log file sync 等待事件)已經(jīng)被寫入 redofile 的 redo log buffer 所持有的鎖存器會被釋放,并可被后來的寫入信息覆蓋,redo log buffer是循環(huán)使用的。Redo file 也是循環(huán)使用的,當一個 redo file 寫滿后,lgwr 進程會自動切換到下一 redo file(這個時候可能出現(xiàn) log fileswitch(checkpoint complete)等待事件)。如果是歸檔模式,歸檔進程還要將前一個寫滿的 redo file 文件的內(nèi)容寫到歸檔日志文件中(這個時候可能出現(xiàn) log file switch(archiving needed)。

9、為事務建立回滾段在完成本事務所有相關(guān)的 redo log buffer 之后,服務器進程開始改寫這個 db buffer的塊頭部事務列表并寫入 scn,然后 copy 包含這個塊的頭部事務列表及 scn 信息的數(shù)據(jù)副本放入回滾段中,將這時回滾段中的信息稱為數(shù)據(jù)塊的 前映 像 , 這個前映像用于以后的回滾、恢復和一致性讀。(回滾段可以存儲在專門的回滾表空間中,這個表空間由一個或多個物理文件組成,并專用于回滾表空間,回滾段也可在其它 表空間中的數(shù)據(jù)文件中開辟。

10、本事務修改數(shù)據(jù)塊 準備工作都已經(jīng)做好了,現(xiàn)在可以改寫 db buffer 塊的數(shù)據(jù)內(nèi)容了,并在塊的頭部寫 入回滾段的地址。

11、放入 dirty list 如果一個行數(shù)據(jù)多次 update 而未 commit,則在回滾段中將會有多個 前映像除了之一個前映像含有scn信息外,其他每個前映像的頭部都有scn信息和前前映像回滾段地址。一個update 只對應一個scn,然后服務器進程將在 dirty list中建立一 條指向此db buffer 塊的指針(方便 dbwr 進程可以找到 dirty list 的 db buffer 數(shù)據(jù)塊并寫入數(shù)據(jù)文件中)。 接著服務器進程會從數(shù)據(jù)文件中繼續(xù)讀入第二個數(shù)據(jù)塊,重復前一數(shù)據(jù)塊的動作,數(shù)據(jù)塊的讀入、記日志、建 立回滾段、修改數(shù)據(jù)塊、放入 dirty list。當 dirty queue 的長度達到閥值(一般是 25%),服務器進程將通知dbwr 把臟數(shù)據(jù)寫出,就是釋放 db buffer 上的鎖存器,騰出更多的 free db buffer。前面一直都是在說明oracle 一次讀一個數(shù)據(jù)塊,其實 oracle 可以一次讀入多個數(shù)據(jù)塊(db_file_multiblock_read_count 來設(shè)置一 次讀入塊的個數(shù))

12、在預處理的數(shù)據(jù)已經(jīng)緩存在 db buffer 或剛剛被從數(shù)據(jù)文件讀入到 db buffer 中,就要根據(jù) sql 語句的類型來決定接下來如何操作。

(1)如果是 select 語句,則要查看 db buffer 塊的頭部是否有事務,如果有事務,則從回滾段中讀取數(shù)據(jù);如果沒有事務,則比較 select 的 scn 和 db buffer 塊頭部的 scn,如果前者小于后者,仍然要從回滾段中讀取數(shù)據(jù);如果前者大于后者,說明這是一非臟緩存,可以直接讀取這個 db buffer 塊的中內(nèi)容。

(2)如果是 DML 操作,則即使在 db buffer 中找到一個沒有事務,而且 SCN 比自己小的非臟緩存數(shù)據(jù)塊,服務器進程仍然要到表的頭部對這條記錄申請加鎖,加鎖成功才能進行后續(xù)動作,如果不成功,則要等待前面的進程解鎖后才能進行動作(這個時候阻塞是 tx 鎖阻塞)。用戶 commit 或 rollback 到現(xiàn)在為止,數(shù)據(jù)已經(jīng)在 db buffer 或數(shù)據(jù)文件中修改完成,但是否要永久寫到數(shù)文件中,要由用戶來決定 commit(保存更改到數(shù)據(jù)文件) rollback 撤銷數(shù)據(jù)的更改)。

如果用戶執(zhí)行 commit 命令:

只有當 sql 語句所影響的所有行所在的最后一個塊被讀入 db buffer 并且重做信息被寫入 redo log buffer(僅指日志緩沖區(qū),而不包括日志文件)之后,用戶才可以發(fā)去 commit 命令,commit 觸發(fā) lgwr 進程,但不強制立即 dbwr來釋放所有相應 db buffer 塊的鎖(也就是no-force-at-commit,即提交不強制寫),也就是說有可能雖然已經(jīng) commit 了,但在隨后的一段時間內(nèi) dbwr 還在寫這條 sql 語句所涉及的數(shù)據(jù)塊。表頭部的行鎖并不在 commit 之后立即釋放,而是要等 dbwr 進程完成之后才釋放,這就可能會出現(xiàn)一個用戶請求另一用戶已經(jīng) commit 的資源不成功的現(xiàn)象。

A、從 Commit 和 dbwr 進程結(jié)束之間的時間很短,如果恰巧在 commit 之后,dbwr 未結(jié)束之前斷電,因為commit 之后的數(shù)據(jù)已經(jīng)屬于數(shù)據(jù)文件的內(nèi)容,但這部分文件沒有完全寫入到數(shù)據(jù)文件中。所以需要前滾。由于 commit 已經(jīng)觸發(fā) lgwr,這些所有未來得及寫入數(shù)據(jù)文件的更改會在實例重啟后,由 on 進程根據(jù)重做日 志文件來前滾,完成之前 commit 未完成的工作(即把更改寫入數(shù)據(jù)文件)。

B、如果未 commit 就斷電了,因為數(shù)據(jù)已經(jīng)在 db buffer 更改了,沒有 commit,說明這部分數(shù)據(jù)不屬于數(shù)據(jù)文件,由于 dbwr 之前觸發(fā) lgwr 也就是只要數(shù)據(jù)更改,(肯定要先有 log) 所有 DBWR,在數(shù)據(jù)文件上的修改都會被先一步記入重做日志文件,實例重啟后,ON 進程再根據(jù)重做日志文件來回滾。其實 on 的前滾回滾是根據(jù)檢查點來完成的,當一個全部檢查點發(fā)生的時候,首先讓 LGWR 進程將redo log buffer 中的所有緩沖(包含未提交的重做信息)寫入重做日志文件,然后讓 dbwr 進程將 db buffer 已 提交的緩沖寫入數(shù)據(jù)文件(不強制寫未提交的)。然后更新控制文件和數(shù)據(jù)文件頭部的 SCN,表明當前數(shù)據(jù)庫是一致的,在相鄰的兩個檢查點之間有很多事務,有提交和未提交的。像前面的前滾回滾比較完整的說法是如下的說明:

AA、發(fā)生檢查點之前斷電,并且當時有一個未提交的改變正在進行,實例重啟之后,ON 進程將從上一個檢查點開始核對這個檢查點之后記錄在重做日志文件中已提交的和未提交改變,因為dbwr 之前會觸發(fā) lgwr,所以 dbwr 對數(shù)據(jù)文件的修改一定會被先記錄在重做日志文件中。因此,斷電前被DBWN 寫進數(shù)據(jù)文件的改變將通過重做日志文件中的記錄進行還原,叫做回滾。

BB. 如果斷電時有一個已提交,但 dbwr 動作還沒有完全完成的改變存在,因為已經(jīng)提交,提交會觸發(fā) lgwr進程,所以不管 dbwr 動作是否已完成,該語句將要影響的行及其產(chǎn)生的結(jié)果一定已經(jīng)記錄在重做日志文件中了,則實例重啟后,ON 進程根據(jù)重做日志文件進行前滾.實例失敗后用于恢復的時間由兩個檢查點之間的間隔大小來決定,可以通個四個參數(shù)設(shè)置檢查點執(zhí)行的頻率:

Log_checkpoint_interval:

決定兩個檢查點之間寫入重做日志文件的系統(tǒng)物理塊(redo blocks)的大小,默認值是 0,無限制。

log_checkpoint_timeout:

兩 個 檢 查 點 之 間 的 時 間 長 度(秒)默 認 值 1800s。

fast_start_io_target:

決定了用于恢復時需要處理的塊的多少,默認值是 0,無限制。

fast_start_mttr_target:

直接決定了用于恢復的時間的長短,默認值是 0,無限制(ON 進程執(zhí)行的前滾 和回滾與用戶的回滾是不同的,ON 是根據(jù)重做日志文件進行前滾或回滾,而用戶的回滾一定是根據(jù)回滾段的內(nèi)容進行回滾的。在這里要說一下回滾段存儲的數(shù)據(jù),假如是 delete 操作,則回滾段將會記錄整個行的數(shù)據(jù),假如是 update,則回滾段只記錄被修改了的字段的變化前的數(shù)據(jù)(前映像),也就是沒有被修改的字段是不會被記錄的,假如是insert,則回滾段只記錄插入記錄的 rowid。 這樣假如事務提交,那回滾段中簡單標記該事務已經(jīng)提交;假如是 回退,則如果操作是 delete,回退的時候把回滾段中數(shù)據(jù)重新寫回數(shù)據(jù)塊,操作如果是 update,則把變化前數(shù)據(jù)修改回去,操作如果是 insert,則根據(jù)記錄的 rowid 把該記錄刪除。

如果用戶 rollback:

則服務器進程會根據(jù)數(shù)據(jù)文件塊和 DB BUFFER 中塊的頭部的事務列表和 SCN 以及回滾段地址找到回滾段中相應的修改前的副本,并且用這些原值來還原當前數(shù)據(jù)文件中已修改但未提交的改變。如果有多個前映像 服務器進程會在一個前映像的頭部找到 前前映像 的回滾段地址,一直找到同一事務下的最早的一個前映像 為止。一旦發(fā)出了COMMIT,用戶就不能rollback,這使得 COMMIT 后 DBWR 進程還沒有全部完成的后續(xù)動作得到了保障。到現(xiàn)在為例一個事務已經(jīng)結(jié)束了。

本篇文章會分析下一個 sql 語句在 MySQL 中的執(zhí)行流程,包括 sql 的查詢在 MySQL 內(nèi)部會怎么流轉(zhuǎn),sql 語句的更新是怎么完成的。

在分析之前我會先帶著你看看 MySQL 的基礎(chǔ)架構(gòu),知道了 MySQL 由那些組件組成以及這些組件的作用是什么,可以幫助我們理解和解決這些問題。

一 MySQL 基礎(chǔ)架構(gòu)分析

MySQL 基本架構(gòu)畢租概覽

下圖是 MySQL 的一個簡手豎兆要架構(gòu)圖,從下圖你可以很清晰的看到用戶的 SQL 語句在 MySQL 內(nèi)部是如何執(zhí)行的。

先簡單介紹一下下圖涉及的一些組件的基本作用幫助大家理解這幅圖,在 1.2 節(jié)中會詳細介紹到這些組件的作用。

連接器: 身份認證和權(quán)限相關(guān)(登錄 MySQL 的時候)。

查詢緩存: 執(zhí)行查詢語句的時候,會先查詢緩存(MySQL 8.0 版本后移除,因為這個功能不太實用)。

分析器: 沒有命中緩存的話,SQL 語句就會經(jīng)過分析器,分析器說白了就是要先看你的 SQL 語句要干嘛,再檢查你的 SQL 語句語法是否正確。

優(yōu)化器: 按照 MySQL 認為更優(yōu)的纖豎方案去執(zhí)行。

1、用戶進程提交一條sql語句給服務器進程

SELECT * FROM EMP WHERE EMPNO = 7999

2、服務器進程從用戶進程把信息接收到后,在PGA中就要此進程分配所需內(nèi)存,存儲相關(guān)的信息,如在會話內(nèi)存存儲相關(guān)的登錄信息等。

3、服務器進程把這個sql語句的字符轉(zhuǎn)化為ASCII等效數(shù)字碼,接著這個ASCII碼被傳遞給一個HASH 函數(shù),并返回一個hash 值,然后服務器進程將到shared pool中的library cache中去查找是否存在相同的hash值,如果存在,服務器進程將使用這條語句已在高速緩存在 SHARED POOL 的library cache 中的已分析過的執(zhí)行計劃版本來執(zhí)行。

4、如果不存在,服務器進程將在CGA中,配合UGA內(nèi)容對sql,進行語法分析,首先檢查語法的正確性,接著對語句中涉及的表,索引,視圖等對象進行解析,并對照數(shù)據(jù)字典檢查這些對象的名稱以及相關(guān)結(jié)構(gòu),并根據(jù)ORACLE 選用的優(yōu)化模式以及數(shù)據(jù)字典中是否存在相應對象的統(tǒng)計數(shù)據(jù)和是否使用了存儲大綱來生成一個執(zhí)行計劃或從存儲大綱中選用一個執(zhí)行計劃,然后再用數(shù)據(jù)字典核對此用戶對相應對象的執(zhí)行權(quán)限,最后生成一個編譯代碼。

5、ORACLE 將這條 sql 語句的本身實際文本、HASH 值、編譯代碼、與此語名相關(guān)聯(lián)的任何統(tǒng)計數(shù)據(jù)和該語句的執(zhí)行計劃緩存在 SHARED POOL 的 library cache中。服務器進程通過 SHARED POOL 鎖存器(shared pool latch)來申請可以向哪些共享 PL/SQL 區(qū)中緩存這此內(nèi)容,也就是說被SHARED POOL 鎖存器鎖定的 PL/SQL 區(qū)中的塊不可被覆蓋,因為這些塊可能被其它進程所使用。

6、在 SQL 分析階段將用到 LIBRARY CACHE,從數(shù)據(jù)字典中核對表、視圖等結(jié)構(gòu)的時候,需要將數(shù)據(jù)字典從磁盤讀入 LIBRARY CACHE,因此,在讀入之前也要使用LIBRARY CACHE 鎖存器(library cache pin,library cache lock)來申請用于緩存數(shù)據(jù)字典。到現(xiàn)在為止,這盯慧臘個 sql 語句已經(jīng)被編譯成可執(zhí)碧桐行的代碼了,但還不知道要操作哪些數(shù)據(jù),所以服務器進程還要為這個 sql 準備預處理數(shù)據(jù)。

7、首先服務器進程要判斷所需數(shù)據(jù)是否在 db buffer 存在,如果存在且可用,則直接獲取該數(shù)據(jù),同時根據(jù)LRU 算法增加其訪問計數(shù);如果 buffer不存在所需數(shù)據(jù),則要從數(shù)據(jù)文件上讀取首先服務器進程將在表頭部請求 TM 鎖(保證此事務執(zhí)行過程其他用戶不能修改表的結(jié)構(gòu)),如果成功加 TM 鎖,再請求一些行級鎖(TX 鎖),如果 TM、TX 鎖都成功加鎖,那么才開始從數(shù)據(jù)文件讀數(shù)據(jù),在讀數(shù)據(jù)之前,要先為讀取的文件準備好buffer 空間。服務器進程需要掃面 LRU list 尋找 free db buffer,掃描的過程中,服務器進程會把發(fā)現(xiàn)的所有已經(jīng)被凱滑修改過的 db buffer 注冊到 dirty list 中, 這些 dirty buffer 會通過 dbwr 的觸發(fā)條件,隨后會被寫出到數(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)在服務器進程將該語句所影響的并被讀入db buffer 中的這些行數(shù)據(jù)的 rowid 及要更新的原值和新值及 scn 等信息從 PGA 逐條的寫入 redo log buffer 中。在寫入 redo log buffer 之前也要事先請求 redo log buffer 的鎖存器,成功加鎖后才開始寫入,當寫入達到 redo log buffer 大小的三分之一或?qū)懭肓窟_到 1M 或超過三秒后或發(fā)生檢查點時或者 dbwr 之前發(fā)生,都會觸發(fā)lgwr進程把redo log buffer 的數(shù)據(jù)寫入磁盤上的 redo file 文件中(這個時候會產(chǎn)生log file sync 等待事件)已經(jīng)被寫入 redofile 的 redo log buffer 所持有的鎖存器會被釋放,并可被后來的寫入信息覆蓋,redo log buffer是循環(huán)使用的。Redo file 也是循環(huán)使用的,當一個 redo file 寫滿后,lgwr 進程會自動切換到下一 redo file(這個時候可能出現(xiàn) log fileswitch(checkpoint complete)等待事件)。如果是歸檔模式,歸檔進程還要將前一個寫滿的 redo file 文件的內(nèi)容寫到歸檔日志文件中(這個時候可能出現(xiàn) log file switch(archiving needed)。

9、為事務建立回滾段在完成本事務所有相關(guān)的 redo log buffer 之后,服務器進程開始改寫這個 db buffer的塊頭部事務列表并寫入 scn,然后 copy 包含這個塊的頭部事務列表及 scn 信息的數(shù)據(jù)副本放入回滾段中,將這時回滾段中的信息稱為數(shù)據(jù)塊的 前映 像 , 這個前映像用于以后的回滾、恢復和一致性讀。(回滾段可以存儲在專門的回滾表空間中,這個表空間由一個或多個物理文件組成,并專用于回滾表空間,回滾段也可在其它 表空間中的數(shù)據(jù)文件中開辟。

10、本事務修改數(shù)據(jù)塊 準備工作都已經(jīng)做好了,現(xiàn)在可以改寫 db buffer 塊的數(shù)據(jù)內(nèi)容了,并在塊的頭部寫 入回滾段的地址。

11、放入 dirty list 如果一個行數(shù)據(jù)多次 update 而未 commit,則在回滾段中將會有多個 前映像除了之一個前映像含有scn信息外,其他每個前映像的頭部都有scn信息和前前映像回滾段地址。一個update 只對應一個scn,然后服務器進程將在 dirty list中建立一 條指向此db buffer 塊的指針(方便 dbwr 進程可以找到 dirty list 的 db buffer 數(shù)據(jù)塊并寫入數(shù)據(jù)文件中)。 接著服務器進程會從數(shù)據(jù)文件中繼續(xù)讀入第二個數(shù)據(jù)塊,重復前一數(shù)據(jù)塊的動作,數(shù)據(jù)塊的讀入、記日志、建 立回滾段、修改數(shù)據(jù)塊、放入 dirty list。當 dirty queue 的長度達到閥值(一般是 25%),服務器進程將通知dbwr 把臟數(shù)據(jù)寫出,就是釋放 db buffer 上的鎖存器,騰出更多的 free db buffer。前面一直都是在說明oracle 一次讀一個數(shù)據(jù)塊,其實 oracle 可以一次讀入多個數(shù)據(jù)塊(db_file_multiblock_read_count 來設(shè)置一 次讀入塊的個數(shù))

12、在預處理的數(shù)據(jù)已經(jīng)緩存在 db buffer 或剛剛被從數(shù)據(jù)文件讀入到 db buffer 中,就要根據(jù) sql 語句的類型來決定接下來如何操作。

(1)如果是 select 語句,則要查看 db buffer 塊的頭部是否有事務,如果有事務,則從回滾段中讀取數(shù)據(jù);如果沒有事務,則比較 select 的 scn 和 db buffer 塊頭部的 scn,如果前者小于后者,仍然要從回滾段中讀取數(shù)據(jù);如果前者大于后者,說明這是一非臟緩存,可以直接讀取這個 db buffer 塊的中內(nèi)容。

(2)如果是 DML 操作,則即使在 db buffer 中找到一個沒有事務,而且 SCN 比自己小的非臟緩存數(shù)據(jù)塊,服務器進程仍然要到表的頭部對這條記錄申請加鎖,加鎖成功才能進行后續(xù)動作,如果不成功,則要等待前面的進程解鎖后才能進行動作(這個時候阻塞是 tx 鎖阻塞)。用戶 commit 或 rollback 到現(xiàn)在為止,數(shù)據(jù)已經(jīng)在 db buffer 或數(shù)據(jù)文件中修改完成,但是否要永久寫到數(shù)文件中,要由用戶來決定 commit(保存更改到數(shù)據(jù)文件) rollback 撤銷數(shù)據(jù)的更改)。

如果用戶執(zhí)行 commit 命令:

只有當 sql 語句所影響的所有行所在的最后一個塊被讀入 db buffer 并且重做信息被寫入 redo log buffer(僅指日志緩沖區(qū),而不包括日志文件)之后,用戶才可以發(fā)去 commit 命令,commit 觸發(fā) lgwr 進程,但不強制立即 dbwr來釋放所有相應 db buffer 塊的鎖(也就是no-force-at-commit,即提交不強制寫),也就是說有可能雖然已經(jīng) commit 了,但在隨后的一段時間內(nèi) dbwr 還在寫這條 sql 語句所涉及的數(shù)據(jù)塊。表頭部的行鎖并不在 commit 之后立即釋放,而是要等 dbwr 進程完成之后才釋放,這就可能會出現(xiàn)一個用戶請求另一用戶已經(jīng) commit 的資源不成功的現(xiàn)象。

A、從 Commit 和 dbwr 進程結(jié)束之間的時間很短,如果恰巧在 commit 之后,dbwr 未結(jié)束之前斷電,因為commit 之后的數(shù)據(jù)已經(jīng)屬于數(shù)據(jù)文件的內(nèi)容,但這部分文件沒有完全寫入到數(shù)據(jù)文件中。所以需要前滾。由于 commit 已經(jīng)觸發(fā) lgwr,這些所有未來得及寫入數(shù)據(jù)文件的更改會在實例重啟后,由 on 進程根據(jù)重做日 志文件來前滾,完成之前 commit 未完成的工作(即把更改寫入數(shù)據(jù)文件)。

B、如果未 commit 就斷電了,因為數(shù)據(jù)已經(jīng)在 db buffer 更改了,沒有 commit,說明這部分數(shù)據(jù)不屬于數(shù)據(jù)文件,由于 dbwr 之前觸發(fā) lgwr 也就是只要數(shù)據(jù)更改,(肯定要先有 log) 所有 DBWR,在數(shù)據(jù)文件上的修改都會被先一步記入重做日志文件,實例重啟后,ON 進程再根據(jù)重做日志文件來回滾。其實 on 的前滾回滾是根據(jù)檢查點來完成的,當一個全部檢查點發(fā)生的時候,首先讓 LGWR 進程將redo log buffer 中的所有緩沖(包含未提交的重做信息)寫入重做日志文件,然后讓 dbwr 進程將 db buffer 已 提交的緩沖寫入數(shù)據(jù)文件(不強制寫未提交的)。然后更新控制文件和數(shù)據(jù)文件頭部的 SCN,表明當前數(shù)據(jù)庫是一致的,在相鄰的兩個檢查點之間有很多事務,有提交和未提交的。像前面的前滾回滾比較完整的說法是如下的說明:

AA、發(fā)生檢查點之前斷電,并且當時有一個未提交的改變正在進行,實例重啟之后,ON 進程將從上一個檢查點開始核對這個檢查點之后記錄在重做日志文件中已提交的和未提交改變,因為dbwr 之前會觸發(fā) lgwr,所以 dbwr 對數(shù)據(jù)文件的修改一定會被先記錄在重做日志文件中。因此,斷電前被DBWN 寫進數(shù)據(jù)文件的改變將通過重做日志文件中的記錄進行還原,叫做回滾。

BB. 如果斷電時有一個已提交,但 dbwr 動作還沒有完全完成的改變存在,因為已經(jīng)提交,提交會觸發(fā) lgwr進程,所以不管 dbwr 動作是否已完成,該語句將要影響的行及其產(chǎn)生的結(jié)果一定已經(jīng)記錄在重做日志文件中了,則實例重啟后,ON 進程根據(jù)重做日志文件進行前滾.實例失敗后用于恢復的時間由兩個檢查點之間的間隔大小來決定,可以通個四個參數(shù)設(shè)置檢查點執(zhí)行的頻率:

Log_checkpoint_interval:

決定兩個檢查點之間寫入重做日志文件的系統(tǒng)物理塊(redo blocks)的大小,默認值是 0,無限制。

log_checkpoint_timeout:

兩 個 檢 查 點 之 間 的 時 間 長 度(秒)默 認 值 1800s。

fast_start_io_target:

決定了用于恢復時需要處理的塊的多少,默認值是 0,無限制。

fast_start_mttr_target:

直接決定了用于恢復的時間的長短,默認值是 0,無限制(ON 進程執(zhí)行的前滾 和回滾與用戶的回滾是不同的,ON 是根據(jù)重做日志文件進行前滾或回滾,而用戶的回滾一定是根據(jù)回滾段的內(nèi)容進行回滾的。在這里要說一下回滾段存儲的數(shù)據(jù),假如是 delete 操作,則回滾段將會記錄整個行的數(shù)據(jù),假如是 update,則回滾段只記錄被修改了的字段的變化前的數(shù)據(jù)(前映像),也就是沒有被修改的字段是不會被記錄的,假如是insert,則回滾段只記錄插入記錄的 rowid。 這樣假如事務提交,那回滾段中簡單標記該事務已經(jīng)提交;假如是 回退,則如果操作是 delete,回退的時候把回滾段中數(shù)據(jù)重新寫回數(shù)據(jù)塊,操作如果是 update,則把變化前數(shù)據(jù)修改回去,操作如果是 insert,則根據(jù)記錄的 rowid 把該記錄刪除。

如果用戶 rollback:

則服務器進程會根據(jù)數(shù)據(jù)文件塊和 DB BUFFER 中塊的頭部的事務列表和 SCN 以及回滾段地址找到回滾段中相應的修改前的副本,并且用這些原值來還原當前數(shù)據(jù)文件中已修改但未提交的改變。如果有多個前映像 服務器進程會在一個前映像的頭部找到 前前映像 的回滾段地址,一直找到同一事務下的最早的一個前映像 為止。一旦發(fā)出了COMMIT,用戶就不能rollback,這使得 COMMIT 后 DBWR 進程還沒有全部完成的后續(xù)動作得到了保障。到現(xiàn)在為例一個事務已經(jīng)結(jié)束了。

一個數(shù)據(jù)庫有5個事務的介紹就聊到這里吧,感謝你花時間閱讀本站內(nèi)容,更多關(guān)于一個數(shù)據(jù)庫有5個事務,5個事務的數(shù)據(jù)庫:如何確保數(shù)據(jù)一致性?,數(shù)據(jù)庫事務正確執(zhí)行的四個基本要素包括,數(shù)據(jù)庫管理系統(tǒng) (DBMS) 的五個重要軟件組成部分是什么?,sql運行問題?的信息別忘了在本站進行查找喔。

成都創(chuàng)新互聯(lián)科技有限公司,是一家專注于互聯(lián)網(wǎng)、IDC服務、應用軟件開發(fā)、網(wǎng)站建設(shè)推廣的公司,為客戶提供互聯(lián)網(wǎng)基礎(chǔ)服務!
創(chuàng)新互聯(lián)(www.cdcxhl.com)提供簡單好用,價格厚道的香港/美國云服務器和獨立服務器。創(chuàng)新互聯(lián)成都老牌IDC服務商,專注四川成都IDC機房服務器托管/機柜租用。為您精選優(yōu)質(zhì)idc數(shù)據(jù)中心機房租用、服務器托管、機柜租賃、大帶寬租用,可選線路電信、移動、聯(lián)通等。


網(wǎng)站題目:5個事務的數(shù)據(jù)庫:如何確保數(shù)據(jù)一致性?(一個數(shù)據(jù)庫有5個事務)
本文網(wǎng)址:http://www.5511xx.com/article/dhshjip.html