MySQL(3)事務(wù)與存儲引擎

MySQL事務(wù)與存儲引擎

3.1-數(shù)據(jù)庫事務(wù)

事務(wù)的定義

一系列有序的數(shù)據(jù)庫操作。

  • 要么全部成功
  • 要么全部回退到操作前的狀態(tài)
  • 中間狀態(tài)對其他連接不可見

事務(wù)的基本操作

基本操作 說明
start transaction 開始事務(wù)
commit 提交(全部完成)
rollback 回滾(回到初始狀態(tài))
-- 開啟一個(gè)事務(wù)
start transaction;
-- 或者使用(非標(biāo)準(zhǔn)sql)
begin;
insert into t values (1, 1, 1);
-- 事務(wù)結(jié)束,插入成功
commit;

begin;
insert into t values (2, 1, 1);
insert into t values (3, 1, 1);
insert into t values (4, 1, 1);
-- 事務(wù)結(jié)束建丧,沒有插入數(shù)據(jù)
rollback;

begin;

insert into t values (1, 1, 1);
savepoint a1;
insert into t values (2, 1, 1);
-- 回滾到指定的保存點(diǎn)
rollback to a1;
commit;

自動提交

  • autocommit可以在session級別設(shè)置
  • 每個(gè)DML操作都自動提交
  • DDL永遠(yuǎn)都是自動提交狼电,無法通過rollback回滾

事務(wù)的四個(gè)基本屬性(ACID)

  • 原子性(Atomicity)
    一個(gè)事務(wù)包含多個(gè)操作姐帚,這些操作要么全部執(zhí)行旦部,要么全都不執(zhí)行在扰。實(shí)現(xiàn)事務(wù)的原子性霉晕,要支持回滾操作庭再,在某個(gè)操作失敗后(數(shù)據(jù)庫或應(yīng)用發(fā)生異常),回滾到事務(wù)執(zhí)行之前的狀態(tài)牺堰。未提交的事務(wù)都應(yīng)該被回滾拄轻。

  • 一致性(Consistency)

  • 數(shù)據(jù)的正確性,合理性伟葫,完整性

  • 數(shù)據(jù)一致性要符合應(yīng)用應(yīng)該符合的規(guī)則:余額不為負(fù)/交易對象必須先有賬號
    /用戶賬號不重復(fù)

  • 事務(wù)的結(jié)果需要滿足數(shù)據(jù)的一致性約束

  • 隔離性(Isolation)
    并發(fā)的事務(wù)是相互隔離的恨搓。數(shù)據(jù)庫的某一事務(wù)在提交完成前,中間的任何數(shù)據(jù)變化對其他的事務(wù)都是不可見的筏养。
    即一個(gè)事務(wù)內(nèi)部的操作及正在操作的數(shù)據(jù)必須封鎖起來奶卓,不被其它企圖進(jìn)行修改的事務(wù)看到(假如并發(fā)交叉執(zhí)行的多個(gè)事務(wù)任意操縱相同的共享對象,可能引起異常)

  • 持久性(Durability)
    發(fā)生故障時(shí)撼玄,確保已提交事務(wù)的更新不能丟失夺姑。
    一旦事務(wù)提交完成,對數(shù)據(jù)庫中數(shù)據(jù)的影響必須是永久性的(數(shù)據(jù)成功寫入磁盤 即 持久化成功)掌猛。

實(shí)現(xiàn) 事務(wù)的持久化

  • 數(shù)據(jù)文件持久化
    • 隨機(jī)同步刷新(慢)
  • 事務(wù)日志持久化與實(shí)例恢復(fù)
    • 順序同步刷新(快) -> 事務(wù)日志
    • 隨機(jī)異步刷新 -> 磁盤
    • 事務(wù)日志 -> 磁盤(實(shí)例恢復(fù))

數(shù)據(jù)庫隔離現(xiàn)象

隔離現(xiàn)象 描述
臟讀(Dirty Read) 事務(wù)B讀到事務(wù)A尚未提交的數(shù)據(jù)變更
不可重復(fù)讀(NonRepeatable Read) 事務(wù)B讀取前后兩次讀取一條記錄之間該記錄被事務(wù)A修改并提交盏浙,于是事務(wù)B讀到了不一樣的結(jié)果
幻讀(Phantom Read) 事務(wù)B按條件匹配到了若干行記錄并修改。但是由于修改過程中事務(wù)A新插入了符合條件記錄荔茬,導(dǎo)致B更新完成后發(fā)現(xiàn)仍有符合條件卻未被更新的記錄废膘。

數(shù)據(jù)庫隔離等級

隔離等級 臟讀 不可重復(fù)讀 幻讀
未提交讀(Read Uncommitted) 可能 可能 可能
已提交讀(Read Committed) 不可能 可能 可能
可重復(fù)讀(Repeated Read) 不可能 不可能 可能
可串行化讀(Serialization) 不可能 不可能 不可能

只有在事務(wù)提交后,其更新結(jié)果才會被其他事務(wù)看見慕蔚。

 :在一個(gè)事務(wù)中丐黄,對于同一份數(shù)據(jù)的讀取結(jié)果總是相同的,無論是否有其他事務(wù)對這份數(shù)據(jù)進(jìn)行操作

MySQL的事務(wù)隔離級別

  • InnoDB默認(rèn)標(biāo)記為可重復(fù)讀
  • InnoDB并不是標(biāo)準(zhǔn)定義上的課重復(fù)讀
  • InnoDB默認(rèn)在可重復(fù)讀的基礎(chǔ)上避免幻讀

MySQL事務(wù)隔離級別設(shè)置

  • 可在global/session/下個(gè)事務(wù)孔飒,級別分別進(jìn)行設(shè)置
  • 建議使用Read committed(同Oracle)
  • 或者建議使用默認(rèn)的Repeatable read
set tx_isolation = ''
-- 設(shè)置隔離級別

事務(wù)與并發(fā)寫

  • 某個(gè)正在更新的記錄再提交或回滾前不能被其他事務(wù)同時(shí)更新

事務(wù)回滾的實(shí)現(xiàn)

  • 回滾段(rollback segment)與數(shù)據(jù)前像

3.2-存儲引擎概述

MySQL程序?qū)哟渭軜?gòu)

./sorence/images/01.jpg

MySQL存儲引擎

  • 有多種可選方案灌闺,可插拔,可修改存儲引擎
  • 基于表選擇使用何種存儲引擎

主要存儲引擎

存儲引擎 常用度 支持事務(wù)
InnoDB 主要坏瞄,推薦
MyISAM 古老桂对,偶爾有用,系統(tǒng)表
MEMORY 偶爾臨時(shí)表有用鸠匀,純內(nèi)存
BLACKHOLE 不用來存放數(shù)據(jù)蕉斜,個(gè)別特殊用處
TokuDB 新穎,個(gè)別特殊場景有奇效
Cluster 新穎,分布式宅此,內(nèi)存机错,線上不要用

InnoDB存儲引擎

  • 索引組織表
  • 支持事務(wù)
  • 支持行級鎖
  • 數(shù)據(jù)塊緩存
  • 日志持久化
  • 穩(wěn)定可靠,性能好父腕,線上盡量使用InnoDB

MyISAM存儲引擎

  • 堆表
  • 不支持事務(wù)
  • 只維護(hù)索引緩存池毡熏,表數(shù)據(jù)緩存交給操作系統(tǒng)
  • 鎖粒度較大
  • 數(shù)據(jù)文件可以直接拷貝,偶爾可能會用上
  • 不建議線上業(yè)務(wù)數(shù)據(jù)使用

MWMORY存儲引擎

  • 數(shù)據(jù)全內(nèi)存存放侣诵,無法持久化
  • 性能較高
  • 不支持事務(wù)
  • 適合偶爾作為臨時(shí)表使用
  • create temporary table tmp (id int) engine = memory ;

BLACKHOLE存儲引擎

  • 數(shù)據(jù)不作任何存儲
  • 利用MySQL Replicate痢法,充當(dāng)日志服務(wù)器
  • 在MySQL Replicate環(huán)境中充當(dāng)代理主

TokuDB

  • 分形樹存儲結(jié)構(gòu)
  • 支持事務(wù)
  • 行鎖
  • 壓縮效率較高
  • 適合大批量insert的場景

MySQL Cluster

  • 多主分布式集群
  • 數(shù)據(jù)節(jié)點(diǎn)間冗余,高可用
  • 支持事務(wù)
  • 設(shè)計(jì)上易于擴(kuò)展
  • 面向未來杜顺,線上慎用

改變表的存儲引擎

alter table m ENGINE=innodb;

3.3-InnoDB存儲引擎

InnoDB存儲引擎體系架構(gòu)

/sorence/images/02.png

InnoDB相關(guān)的磁盤文件

文件 名稱 數(shù)量 位置
系統(tǒng)表空間 ibdata1 一個(gè)實(shí)例一個(gè) innodb_data_home_dir
日志文件 ib_logfile0/1 一個(gè)實(shí)例兩個(gè)(可配置) innodb_log_group_home_dir
表定義文件 表名.frm 每張表一個(gè) Schema目錄下
表數(shù)據(jù)文件 表名.ibd 如果innodb_file_per_table = 1, 則每張表一個(gè) Schema目錄下

InnoDB系統(tǒng)表空間文件

  • ibdata1里存放了什么:
    • 回滾段
    • 所有InnoDB表元數(shù)據(jù)信息
    • Double Write, Insert buffer dump等等....
  • 自動擴(kuò)展機(jī)制

InnoDB與磁盤文件有關(guān)的參數(shù)

參數(shù) 樣例值 備注
innodb_data_home_dir /data/mysql/node_1 數(shù)據(jù)主目錄
innodb_log_group_home_dir /data/mysql/node_1 一般同上
innodb_data_file_path ibdata1:512M:autoextned 請開啟autoextned
innodb_autoextend_increment 128 MB,勿太大或太小
innodb_file_per_table 1 強(qiáng)烈建議開啟
innodb_log_file_size 100MB 性能相關(guān)
innodb_log_files_in_group 2 性能相關(guān)

InnoDB數(shù)據(jù)文件存儲結(jié)構(gòu)

  • 索引組織表(聚簇表)
  • 根據(jù)表邏輯主鍵排序
  • 數(shù)據(jù)節(jié)點(diǎn)每頁16K
  • 根據(jù)主鍵尋址速度很快
  • 主鍵值遞增的insert插入效率較好
  • 主鍵值隨機(jī)insert插入效率差
  • 因此财搁,InnoDB表必須指定主鍵,建議使用自增數(shù)字

InnoDB數(shù)據(jù)塊緩存池

  • 數(shù)據(jù)的讀寫需要經(jīng)過緩存
  • 數(shù)據(jù)以整頁(16K)為單位讀取到緩存中
  • 緩存中的數(shù)據(jù)以LRU策略換出
  • IO效率高躬络,性能好

InnoDB Buffer Pool相關(guān)參數(shù)

參數(shù) 樣例值 備注
innodb_buffer_pool_size 10G 根據(jù)總物理內(nèi)存設(shè)置

InnoDB數(shù)據(jù)持久化與事務(wù)日志

  • 事務(wù)日志實(shí)時(shí)持久化
  • 內(nèi)存變化數(shù)據(jù)(臟數(shù)據(jù))增量異步刷出到磁盤
  • 實(shí)例故障靠重放日志恢復(fù)
  • 性能好尖奔,可靠,恢復(fù)快

InnoDB日志持久化相關(guān)參數(shù)

參數(shù) 樣例值 備注
innodb_flush_log_at_trx_commit 1 可選:0:每隔1s寫入并持久化一次日志穷当。1:每次commit都寫入并持久化日志提茁。2:每次提交日志寫到內(nèi)存,每1s持久化一次

InnoDB行級鎖

  • 寫不阻塞讀
  • 不同行間的寫互相不阻塞
  • 并發(fā)性能好

InnoDB與事務(wù)ACID

  • 事務(wù)ACID特性完整支持
    • 回滾段失敗回滾
    • 支持主外鍵約束
    • 事務(wù)版本+回滾段=MVCC
    • 事務(wù)日志持久化
  • 默認(rèn)可重復(fù)讀隔離級別馁菜,可以調(diào)整

3.4-InnoDB事務(wù)鎖

什么是計(jì)算機(jī)程序鎖

  • 計(jì)算機(jī)程序鎖
    • 控制對共享資源進(jìn)行并發(fā)訪問
    • 保護(hù)數(shù)據(jù)的完整性和一致性

數(shù)據(jù)庫中的鎖

  • 分為兩個(gè)大類
lock latch/mutex
對象 事務(wù) 線程
保護(hù) 數(shù)據(jù)庫邏輯內(nèi)容 內(nèi)存數(shù)據(jù)結(jié)構(gòu)
持續(xù)時(shí)間 事務(wù)過程中 臨界資源爭搶
  • 我們主要關(guān)心的是事務(wù)鎖

數(shù)據(jù)庫事務(wù)并發(fā)

  • 對同一行記錄的修改必須串行化

事務(wù)鎖粒度

  • 行鎖
    • InnoDB, Oracle
  • 頁鎖
    • SQL Server
  • 表鎖
    • MyISAM, Memory
  • 鎖升級

InnoDB存儲引擎中的鎖模式與粒度

  • 四種基本鎖模式
    • 共享鎖(S) - 讀鎖 - 行鎖
    • 排他鎖(X) - 寫鎖 - 行鎖
    • 意向共享鎖(IS) - 表級
    • 意向排他鎖(IX) - 表級
  • 意向鎖
    • 意向鎖總是自動先加茴扁,并且意向鎖自動加自動釋放
    • 意向鎖提示數(shù)據(jù)庫這個(gè)session將要在接下來施加何種鎖
    • 意向鎖和X/S鎖級別不同,除了阻塞全表級別的X/S鎖外其他任何鎖

InnoDB鎖模式互斥

/sorence/images/03.png

數(shù)據(jù)庫加鎖操作

  • 一般的select語句不加任何鎖汪疮,也不會被任何事物鎖阻塞
    • 讀的隔離性由MVCC確保
  • S鎖
    • 手動:select * from tb_test lock in share mode;
    • 自動:insert前
  • X鎖
    • 手動:select * from tb_test lock for update;
    • 自動:update峭火,delete前

InnoDB行鎖的實(shí)現(xiàn)

  • 通過索引項(xiàng)加鎖實(shí)現(xiàn)
    • 只有條件走索引才能實(shí)現(xiàn)行級鎖
    • 索引上有重復(fù)值,可能鎖住多個(gè)記錄
    • 查詢有多個(gè)索引可以走智嚷,可以對不同索引加鎖
    • 是否對索引加鎖實(shí)際上取決于MySQL執(zhí)行計(jì)劃
  • 自增主鍵做條件更新卖丸,性能最好

沒有索引的話會對整張表加鎖。

InnoDB的gap lock

  • 什么是幻讀
  • gap lock消滅幻讀
    • InnoDB消滅幻讀僅僅為了確保statement模式replicate的主從一致性
  • 小心gap lock
  • 自增主鍵做條件更新盏道,性能最好

死鎖

  • 什么是死鎖

    • A稍浆、B兩個(gè)事務(wù),A先更新t1猜嘱,同時(shí)B更新t2衅枫,A再更新t2,B再更新t1就發(fā)生了死鎖泉坐。
  • 死鎖數(shù)據(jù)庫自動解決

    • 數(shù)據(jù)庫挑選沖突事務(wù)中回滾代價(jià)較小的事務(wù)回滾
  • 死鎖預(yù)防

    • 單表死鎖可以根據(jù)批量更新里的更新條件排序
    • 可能沖突的跨表事務(wù)盡量避免并發(fā)
    • 盡量縮短事務(wù)長度

業(yè)務(wù)邏輯加鎖

  • 業(yè)務(wù)流程中的悲觀鎖

    • 任何的并發(fā)修改都有可能造成我們的業(yè)務(wù)邏輯最終的錯(cuò)誤为鳄,在事務(wù)流程中一開始就加鎖裳仆,最后釋放
  • 如何縮短鎖的時(shí)間

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腕让,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌纯丸,老刑警劉巖偏形,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異觉鼻,居然都是意外死亡俊扭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門坠陈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萨惑,“玉大人,你說我怎么就攤上這事仇矾∮拱” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵贮匕,是天一觀的道長姐仅。 經(jīng)常有香客問我,道長刻盐,這世上最難降的妖魔是什么掏膏? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮敦锌,結(jié)果婚禮上馒疹,老公的妹妹穿的比我還像新娘。我一直安慰自己乙墙,他們只是感情好行冰,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著伶丐,像睡著了一般悼做。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哗魂,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天肛走,我揣著相機(jī)與錄音,去河邊找鬼录别。 笑死朽色,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的组题。 我是一名探鬼主播葫男,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼崔列!你這毒婦竟也來了梢褐?” 一聲冷哼從身側(cè)響起旺遮,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盈咳,沒想到半個(gè)月后耿眉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鱼响,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年鸣剪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丈积。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡筐骇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出江滨,到底是詐尸還是另有隱情拥褂,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布牙寞,位于F島的核電站饺鹃,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏间雀。R本人自食惡果不足惜悔详,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望惹挟。 院中可真熱鬧茄螃,春花似錦、人聲如沸连锯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽运怖。三九已至拼弃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間摇展,已是汗流浹背吻氧。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留咏连,地道東北人盯孙。 一個(gè)月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像祟滴,于是被迫代替她去往敵國和親振惰。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容