自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

由淺到深讓你明白 MySQL 的事務(wù)

數(shù)據(jù)庫 MySQL
事務(wù)(Transaction)是并發(fā)控制的基本單位。所謂的事務(wù)呢,它是一個(gè)操作序列,這些操作要么都執(zhí)行,要么都不執(zhí)行,它是一個(gè)不可分割的工作單位。

什么是事務(wù)

事務(wù)(Transaction)是并發(fā)控制的基本單位。所謂的事務(wù)呢,它是一個(gè)操作序列,這些操作要么都執(zhí)行,要么都不執(zhí)行,它是一個(gè)不可分割的工作單位。為什么?因?yàn)槭聞?wù)是數(shù)據(jù)庫維護(hù)數(shù)據(jù)一致性的單位,在每一個(gè)事務(wù)結(jié)束的時(shí)候都能保持?jǐn)?shù)據(jù)的一致性,如像積分表和積分詳情表一起更新要么就成功,要么就失敗。

事務(wù)的四大特性ACID

「原子性(Atomicity):」 原子性是指整個(gè)數(shù)據(jù)庫的事務(wù)是一個(gè)不可分割的工作單位,在每一個(gè)都應(yīng)該是原子操作。當(dāng)我們執(zhí)行一個(gè)事務(wù)的時(shí)候,如果在一系列的操作中,有一個(gè)操作失敗了,那么需要將這一個(gè)事務(wù)中的所有操作恢復(fù)到執(zhí)行事務(wù)之前的狀態(tài),這就是事務(wù)的原子性。

「一致性(Consistency):」 一致性呢是指事務(wù)將數(shù)據(jù)庫從一種狀態(tài)轉(zhuǎn)變成為下一種一致性的狀態(tài),也就是說是在事務(wù)的執(zhí)行前后,這兩種狀態(tài)應(yīng)該是一樣的,也就是在數(shù)據(jù)庫的完整性約束不會(huì)被破壞。另外的話,還需要注意的是一致性不關(guān)注中間的過程是發(fā)生了什么。

「隔離性(lsolation):」 Mysql數(shù)據(jù)庫可以同時(shí)的話啟動(dòng)很多的事務(wù),但是呢,事務(wù)跟事務(wù)之間他們是相互分離的,也就是互不影響的,這就是事務(wù)的隔離性。

「持久性(Durability):」 事務(wù)的持久性是指事務(wù)一旦提交,就是永久的了。說白了就是發(fā)生了問題,數(shù)據(jù)庫也是可以恢復(fù)的。因此持久性保證事務(wù)的高可靠性。

Mysql事務(wù)隔離級(jí)別

「Read uncommitted(讀取未提交的數(shù)據(jù)):」 即便是事務(wù)沒有commit,但是其他連接任然能讀到未提交的數(shù)據(jù),這個(gè)事務(wù)隔離級(jí)別是等級(jí)最低的。

「Read committed(可以讀取其他事務(wù)提交的數(shù)據(jù)):」 當(dāng)前會(huì)話只能讀取到其他事務(wù)提交的數(shù)據(jù),沒有提交的數(shù)據(jù)是讀取不到的。

「Repeatable read(可重讀):」 這個(gè)是Mysql的默認(rèn)隔離級(jí)別:當(dāng)前會(huì)話可以重復(fù)讀,就是每次讀取到的結(jié)果集都是相同的,不管其他的事務(wù)有沒有提交。

「Serializable(串行化):」 其他會(huì)話對(duì)該表的寫操作將會(huì)被掛起,可以看到,這個(gè)是隔離級(jí)別里最為嚴(yán)格的,但是這樣做勢必會(huì)對(duì)性能造成影響

設(shè)置事務(wù)隔離級(jí)別的代碼是

  1. set session transaction isolation level serializable

一個(gè)數(shù)據(jù)庫事務(wù)通常的話包含了一個(gè)序列對(duì)數(shù)據(jù)庫的讀/寫操作,它的存在主要是包含有以下兩個(gè)目的:

第一,為數(shù)據(jù)庫操作序列提供了一個(gè)從失敗中恢復(fù)到正常狀態(tài)的方法,同時(shí)呢也提供了數(shù)據(jù)庫即使在異常狀態(tài)下仍然能夠保持一致性的方法。

第二,當(dāng)多個(gè)應(yīng)用程序在并發(fā)訪問數(shù)據(jù)庫的時(shí)候,可以在這些應(yīng)用程序之間提供一個(gè)隔離的方法,以防止彼此的操作相互干擾對(duì)方。

并發(fā)事務(wù)導(dǎo)致的問題

在許多的事務(wù)同時(shí)處理一個(gè)數(shù)據(jù)的時(shí)候,如果沒有采取有效的隔離機(jī)制的話,那么并發(fā)處理數(shù)據(jù)的時(shí)候,會(huì)帶來一些問題。

「臟讀:」 臟讀是指在一個(gè)事務(wù)的處理過程中讀取了另外一個(gè)沒有提交事務(wù)里的數(shù)據(jù)。

「幻讀:」 也叫虛讀是指在一個(gè)事務(wù)執(zhí)行了兩次查詢,第二次的結(jié)果集包含了第一次中沒有或者是某些行已被刪除的數(shù)據(jù),造成了兩次的結(jié)果不一致,只是呢另一個(gè)事務(wù)在這兩次查詢中間插入或者是刪除造成的?;米x是一種事務(wù)非獨(dú)立執(zhí)行時(shí)發(fā)生的。

「不可復(fù)讀:」 一個(gè)事務(wù)兩次讀取了同一行的數(shù)據(jù),結(jié)果得到了不同狀態(tài)的結(jié)果,中間過程的時(shí)候正好有其另外一個(gè)事務(wù)更新了這個(gè)數(shù)據(jù),兩個(gè)結(jié)果不一樣,不可被信任。

Mysql數(shù)據(jù)執(zhí)行過程剖析

Buffer Pool是什么?

Buffer Pool就是數(shù)據(jù)庫的一個(gè)內(nèi)存組件,緩存了磁盤上的真實(shí)數(shù)據(jù),我們的系統(tǒng)對(duì)數(shù)據(jù)庫執(zhí)行增刪改查操作其實(shí)呢就是主要對(duì)這個(gè)內(nèi)存數(shù)據(jù)結(jié)構(gòu)中的緩存數(shù)據(jù)執(zhí)行的。

Mysql的RedoLog和UnidoLog日志

InnoDB使用了undolog、redolog來保證了事務(wù)的原子性、一致性與持久性,同時(shí)的話采用了預(yù)寫日志的方式將隨機(jī)寫入變成順序追加寫入,從而提升了事務(wù)的性能。

「undo log:」 它就是作用于記錄事前變更前的狀態(tài),在對(duì)數(shù)據(jù)進(jìn)行操作之前,會(huì)先把數(shù)據(jù)備份到undu log,然后再進(jìn)行數(shù)據(jù)的修改,如果出現(xiàn)錯(cuò)誤或者是用戶執(zhí)行了rollback語句,則系統(tǒng)就可以利用undo log里備份的數(shù)據(jù)恢復(fù)到事務(wù)開始之前的狀態(tài)。undo log日志是一種邏輯格式的日志,在執(zhí)行undo的時(shí)候,僅僅是將數(shù)據(jù)從邏輯上恢復(fù)到事務(wù)之前的狀態(tài),而不是從物理頁面上操作實(shí)現(xiàn)的。undo log位于數(shù)據(jù)庫的data目錄下的ibdata。

「redo log:」 它的作用就是記錄事務(wù)變更后的狀態(tài)。在提交事務(wù)之前,只要把redo log持久化就可以了,數(shù)據(jù)就在內(nèi)存中變更。當(dāng)系統(tǒng)崩潰的時(shí)候,雖然數(shù)據(jù)沒有了落盤,但是redo log已經(jīng)持久化了,系統(tǒng)就可以根據(jù)redo log的內(nèi)容,把所有的數(shù)據(jù)恢復(fù)到最新的狀態(tài)。redo log是一種物理格式的日志,記錄的是物理數(shù)據(jù)頁面的修改信息,其中redo log是順序?qū)懭雛edo log file的物理文件中去的。它位于數(shù)據(jù)庫的data目錄下的ib_logfile1&ib_logfile2下。

「checkpoint:」 redo log會(huì)隨著時(shí)間的積累,redo log就會(huì)變得很大很大。如果每一次都從第一條記錄開始恢復(fù)數(shù)據(jù)的話,那么恢復(fù)的過程是漫長的。所以為了節(jié)省恢復(fù)時(shí)間,就引入了checkpoint機(jī)制,它會(huì)定期將databuffer的內(nèi)容刷新到磁盤的datafile內(nèi),然后再清除掉checkpoint之前的redo log。其實(shí)就是InnoDB通過加載最新的快照,然后重做checkpoint之后所有的事務(wù)(包括了未提交和回滾的),然后再通過undo log來回滾那些未提交的事務(wù)來完成對(duì)數(shù)據(jù)的恢復(fù)。

MySQL的事務(wù)MVCC結(jié)構(gòu)

InnoDB Multi-Versionnoing-InnoDB是多版本的存儲(chǔ)引擎:它保留了有關(guān)已經(jīng)更改行的舊版本信息,以支持并發(fā)和rollback的事務(wù)功能。像此類的信息稱為rollback segment的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)在table空間當(dāng)中。它的實(shí)現(xiàn)原理就是InnoDB向存儲(chǔ)在數(shù)據(jù)庫里的每一行添加兩個(gè)關(guān)鍵的字段:DATA_TRX_ID和DATA_ROLL_PTR。

「DATA_TRX_ID:」 DATA_TRX_ID是標(biāo)記了最新更新這條行數(shù)據(jù)的transaction id,每處理一個(gè)事務(wù),值會(huì)自動(dòng)+1。

「DATA_ROLL_PTR:」 表示了指向該行回滾段的指針,該行上所有舊的版本,在undo中都有通過鏈表的形式組織,而該值,正式指向undo中該行的歷史記錄鏈表。

MVCC

MVCC的目的就是多版本并發(fā)控制,在數(shù)據(jù)庫的實(shí)現(xiàn),就是為了解決讀寫沖突,它的實(shí)現(xiàn)原理主要依賴記錄中的隱式(DATA_TRX_ID、DATA_ROLL_PTR、Read View)字段。undo log,Read View來實(shí)現(xiàn)的。InnoDB MVCC的實(shí)現(xiàn)基于undo log,通過回滾指針來構(gòu)建需要的版本記錄。通過Read View來判斷哪一些版本的數(shù)據(jù)可見。

MVCC的作用

1、每一行的數(shù)據(jù)都會(huì)存在一個(gè)版本,每一次的數(shù)據(jù)更新的時(shí)候都會(huì)更新該版本。

2、修改時(shí)Copy出當(dāng)前版本隨意修改,各個(gè)事務(wù)之間無干擾。

3、把修改前的數(shù)據(jù)存放于undo log,通過回滾指針的主數(shù)據(jù)關(guān)聯(lián)。

4、修改成功(commit)啥都不做,失敗的話就回復(fù)undo log中的數(shù)據(jù)(rollback)

「Read View:」 它是一個(gè)數(shù)據(jù)結(jié)構(gòu),在SQL開始的時(shí)候被創(chuàng)建。這個(gè)數(shù)據(jù)結(jié)構(gòu)里有三個(gè)主要的成員分別是low_trx_id、up_trx_id、trx_ids,在并發(fā)的情況下,一個(gè)事務(wù)在啟動(dòng)的時(shí)候,trx_sys鏈表里存儲(chǔ)部分還未提交的事務(wù),那么哪些改變對(duì)當(dāng)前的事務(wù)是可見的,哪些又是不可見的,這個(gè)就需要通過這個(gè)ReadView來進(jìn)行判定了。

low_trx_id:表示的是該SQL啟動(dòng)的時(shí)候,當(dāng)前事務(wù)鏈表中最大的事務(wù)id編號(hào),也就是最近創(chuàng)建的除自身以外最大的事務(wù)編號(hào)。

up_trx_id:表示的是該SQL啟動(dòng)的時(shí)候,當(dāng)前的事務(wù)鏈表中最小的事務(wù)id編號(hào),也就是當(dāng)前系統(tǒng)里創(chuàng)建最早但是還沒有提交的事務(wù)。

trx_ids:表示所有的事務(wù)鏈表里事務(wù)id的集合。

 

「ReadView讀取的區(qū)別:」 READ COMMITTED 是每次讀取數(shù)據(jù)前都生成一個(gè)ReadView,REPEATABLE READ 是在第一次讀取數(shù)據(jù)時(shí)生成一個(gè)ReadView

 

責(zé)任編輯:武曉燕 來源: 零零后程序員小三
相關(guān)推薦

2010-02-23 13:47:51

Python正則表達(dá)式

2009-06-30 10:40:25

JSP自定義標(biāo)簽

2009-07-02 15:31:49

JSP標(biāo)簽

2020-04-17 14:49:34

Kafka分區(qū)數(shù)據(jù)

2020-12-08 08:14:11

SQL注入數(shù)據(jù)庫

2017-11-20 10:25:20

數(shù)據(jù)庫MySQL索引

2021-11-11 15:03:35

MySQLSQL索引

2022-10-08 00:24:40

嵌套事務(wù)加入事務(wù)事務(wù)

2021-11-07 23:46:32

MySQLSQL索引

2024-08-28 13:09:50

2014-03-27 15:57:45

Android組件Activity

2023-02-26 00:00:06

JVM深堆支配樹

2017-06-07 18:40:33

PromiseJavascript前端

2021-01-15 18:28:57

Kafka消息系統(tǒng)

2022-03-18 09:45:43

Git分支Linux

2019-07-09 09:19:51

分布式事務(wù)App

2024-03-27 13:33:00

MySQLInnoDB事務(wù)

2018-10-25 14:28:39

網(wǎng)卡虛擬場景

2022-04-07 11:15:22

PulseEventAPI函數(shù)

2019-07-26 10:15:06

Redis數(shù)據(jù)庫
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)