03 | 事務(wù)隔離:為什么你改了我還看不見?

引擎層實(shí)現(xiàn)事務(wù)鳞仙。MySQL 支持多引擎寇蚊,MyISAM 不支持事務(wù), InnoDB 支持棍好。

一仗岸、隔離性(Isolation)與隔離級(jí)別

隔離級(jí)別解決:多事務(wù)同時(shí)執(zhí)行,臟讀梳玫、不可重復(fù)讀(non-repeatable read)爹梁、幻讀(phantom read)的問題

四種隔離級(jí)別http://www.reibang.com/p/6ed305b67c8c

1、讀未提交提澎,事務(wù)沒提交時(shí)姚垃,變更被看到。

2盼忌、讀提交积糯,事務(wù)提交,變更才被看到谦纱。

3看成、可重復(fù)讀,事務(wù)執(zhí)行過程中跨嘉,啟動(dòng)時(shí)看到數(shù)據(jù)是一致川慌。未提交變更對(duì)其他事務(wù)也是不可見。

4、串行化梦重,對(duì)同一行記錄兑燥,“寫”加“寫鎖”,“讀”加“讀鎖”琴拧。沖突時(shí)降瞳,等前一個(gè)完成,才可繼續(xù)蚓胸。

表 T 中只有一列挣饥,其中一行的值為 1,按照時(shí)間順序執(zhí)行兩個(gè)事務(wù)的行為沛膳。

mysql> create? table T(c int) engine=InnoDB;? ? insert into T(c)? values(1);

讀未提交”扔枫, V1 = 2。 B 雖沒提交于置, A 看到了茧吊。V2、V3 = 2八毯。

“讀提交”搓侄,V1 = 1,V2 = 2话速。B 更新提交后, A 看到讶踪。 V3 = 2。

“可重復(fù)讀”泊交,V1乳讥、V2 = 1,V3 = 2廓俭。

“串行化”云石,V1、V2 = 1研乒,V3 = 2汹忠。

db里創(chuàng)建視圖,訪問時(shí)候以邏輯結(jié)果為準(zhǔn)雹熬。

? ? “讀未提交”返回記錄上最新值宽菜,沒有視圖概念;

? ?“讀提交” SQL 語句執(zhí)行時(shí)創(chuàng)建竿报。

? ??“可重復(fù)讀”啟動(dòng)時(shí)創(chuàng)建(可認(rèn)為是靜態(tài)铅乡,不受其他事務(wù)更新影響),整個(gè)事務(wù)存在期間都用烈菌。阵幸。

? ? “串行化”加鎖避免并行

Oracle 默認(rèn)“讀提交”花履,從 Oracle 遷移到MySQL 的應(yīng)用,為保證一致挚赊, MySQL設(shè)置為“讀提交”臭挽。

配置的方式,啟動(dòng)參數(shù)transaction-isolation 設(shè)置 READ-COMMITTED

mysql> show? variables like 'transaction_isolation';

| Variable_name |? Value |

|? transaction_isolation | READ-COMMITTED |

可重復(fù)讀場(chǎng)景呢:

銀行月底對(duì)賬咬腕,判斷上個(gè)月和當(dāng)前差額,與本月賬單明細(xì)是否一致葬荷。過程中涨共,新交易,不影響結(jié)果宠漩。

二举反、事務(wù)隔離的實(shí)現(xiàn)

展開說明“可重復(fù)讀”。MySQL 更新時(shí)記錄回滾操作扒吁。

從 1 被按順序改成 2火鼻、3、4雕崩,回滾日志:

當(dāng)前值是 4魁索,查詢有不同 read-view。同一記錄在系統(tǒng)中可多版本(MVCC)盼铁。read-view A得到 1粗蔚,依次執(zhí)行所有的回滾

即將 4 改成 5,跟A饶火、B鹏控、C 會(huì)沖突

系統(tǒng)判斷,沒有事務(wù)用回滾日志時(shí)(例:沒有比這個(gè)回滾日志更早 read-view)肤寝、刪除当辐。

盡量不要使用長(zhǎng)事務(wù)

提交之前,回滾記錄保留鲤看,占大量存儲(chǔ)空間缘揪、鎖資源,可能拖垮整個(gè)庫(kù)

在 MySQL 5.5 及以前的版本刨摩,回滾日志是跟數(shù)據(jù)字典一起放在ibdata文件里的寺晌,即使長(zhǎng)事務(wù)最終提交,回滾段被清理澡刹,文件也不會(huì)變小呻征。我見過數(shù)據(jù)只有 20GB,而回滾段有 200GB 的庫(kù)罢浇。最終只好為了清理回滾段陆赋,重建整個(gè)庫(kù)沐祷。

三、事務(wù)的啟動(dòng)方式

MySQL 的事務(wù)啟動(dòng)方式有以下幾種:

1.? 顯式啟動(dòng)事務(wù)語句攒岛, begin 或 start transaction赖临。配套的提交語句是 commit,回滾語句是 rollback灾锯。

2.? set auto commit=0兢榨,線程自動(dòng)提交關(guān)掉。執(zhí)行select 語句顺饮,事務(wù)啟動(dòng)不會(huì)提交吵聪。直到 commit 或 rollback或斷開連接。

如果是長(zhǎng)連接兼雄,導(dǎo)致意外長(zhǎng)事務(wù)吟逝。建議 set auto commit=1,顯式啟動(dòng)事務(wù)。

auto commit 為 1 情況赦肋,begin 顯式啟動(dòng)块攒,commit 。如果執(zhí)行 commit work and chain佃乘,提交事務(wù)并自動(dòng)啟動(dòng)下一個(gè)事務(wù)囱井,省去再次begin開銷。知道每個(gè)語句是否處于事務(wù)中恕稠。

查找持續(xù)時(shí)間超過 60s 的事務(wù):

select * from? information_schema.innodb_trx where? TIME_TO_SEC (time diff(now(),trx_started) )>60

問題

長(zhǎng)事務(wù)風(fēng)險(xiǎn)琅绅,如何避免

應(yīng)用開發(fā)端來看:

1.? 是否set autocommit=0《煳。可在測(cè)試環(huán)境中千扶,把 MySQL 的 general_log 開起來,然后隨便跑一個(gè)業(yè)務(wù)邏輯骆捧,通過 general_log 的日志來確認(rèn)澎羞。改成 1。

2.? 是否有不必要只讀事務(wù)敛苇。有些框架不管什么先用 begin/commit框起來妆绞。我見過有些是業(yè)務(wù)并沒有這個(gè)需要,但是也把好幾個(gè) select 語句放到了事務(wù)中枫攀。這種只讀事務(wù)可以去掉括饶。

3.? 業(yè)務(wù)連接數(shù)據(jù)庫(kù)的時(shí)候,根據(jù)業(yè)務(wù)本身的預(yù)估来涨,通過 SET MAX_EXECUTION_TIME 命令图焰,來控制每個(gè)語句執(zhí)行的最長(zhǎng)時(shí)間,避免單個(gè)語句意外執(zhí)行太長(zhǎng)時(shí)間蹦掐。(為什么會(huì)意外技羔?在后續(xù)的文章中會(huì)提到這類案例)

數(shù)據(jù)庫(kù)端來看:

1.? 監(jiān)控information_schema.Innodb_trx 表僵闯,設(shè)置長(zhǎng)事務(wù)閾值,超過就報(bào)警 / 或者 kill藤滥;

2.? Percona 的 pt-kill 這個(gè)工具不錯(cuò)

3. 在業(yè)務(wù)功能測(cè)試階段要求輸出所有的 general_log鳖粟,分析日志行為提前發(fā)現(xiàn)問題;

4. 如果使用的是 MySQL 5.6 或者更新版本拙绊,把innodb_undo_tablespaces 設(shè)置成 2(或更大的值)向图。如果真的出現(xiàn)大事務(wù)導(dǎo)致回滾段過大,這樣設(shè)置后清理更方便标沪。

評(píng)論1

SET GLOBAL MAX_EXECUTION_TIME=3000. 確保單條語句執(zhí)行時(shí)間

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末张漂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子谨娜,更是在濱河造成了極大的恐慌,老刑警劉巖磺陡,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趴梢,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡币他,警方通過查閱死者的電腦和手機(jī)坞靶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝴悉,“玉大人彰阴,你說我怎么就攤上這事∨墓冢” “怎么了尿这?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)庆杜。 經(jīng)常有香客問我射众,道長(zhǎng),這世上最難降的妖魔是什么晃财? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任叨橱,我火速辦了婚禮,結(jié)果婚禮上断盛,老公的妹妹穿的比我還像新娘罗洗。我一直安慰自己,他們只是感情好钢猛,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布伙菜。 她就那樣靜靜地躺著,像睡著了一般厢洞。 火紅的嫁衣襯著肌膚如雪仇让。 梳的紋絲不亂的頭發(fā)上典奉,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音丧叽,去河邊找鬼卫玖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛踊淳,可吹牛的內(nèi)容都是我干的假瞬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼迂尝,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼脱茉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起垄开,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤琴许,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后溉躲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體榜田,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年锻梳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了箭券。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡疑枯,死狀恐怖辩块,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情荆永,我是刑警寧澤废亭,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站具钥,受9級(jí)特大地震影響滔以,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜氓拼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一你画、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桃漾,春花似錦坏匪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至恋追,卻和暖如春凭迹,著一層夾襖步出監(jiān)牢的瞬間罚屋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工嗅绸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脾猛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓鱼鸠,卻偏偏與公主長(zhǎng)得像猛拴,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蚀狰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

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