mysql优化 个人笔记 (mysql锁机制 ) 非礼勿扰 -m10
鎖機(jī)制
A : undolog 實(shí)現(xiàn)
C :
I :鎖實(shí)現(xiàn)
D :redolog實(shí)現(xiàn)
1. mysql鎖基本介紹
鎖是計(jì)算機(jī)協(xié)調(diào)多個(gè)進(jìn)程或線程并發(fā)訪問(wèn)某一資源的機(jī)制
在數(shù)據(jù)庫(kù)中 除了傳統(tǒng)的計(jì)算機(jī)資源(CPU RAM I/O等)的的爭(zhēng)用外,
數(shù)據(jù)也是一種共享資源,如何保證數(shù)據(jù)訪問(wèn)的一致性,有效性?
是所有數(shù)據(jù)庫(kù)必須要解決的問(wèn)題。
鎖沖突也是影響數(shù)據(jù)庫(kù)訪問(wèn)的一個(gè)重要因素。
從這個(gè)角度看,鎖機(jī)制很重要。
相對(duì)其他數(shù)據(jù)庫(kù)而言,mysql的鎖機(jī)制比較簡(jiǎn)單,不同的存儲(chǔ)引擎支持不同的鎖機(jī)制,
MyISAM 和 memory 存儲(chǔ)引擎采用的表級(jí)鎖(table-level locking)
Innodb 存儲(chǔ)引擎支持行級(jí)別鎖(row-level locking)也支持表級(jí)鎖哦
表級(jí)鎖:
1. 開(kāi)銷小,加鎖快,不會(huì)死鎖,
2. 鎖粒度大,發(fā)生沖突概率高,并發(fā)度低
行級(jí)鎖:
1. 開(kāi)銷大 加鎖慢 鎖定力度小 發(fā)生沖突概率低 并發(fā)高
2. 會(huì)出現(xiàn)死鎖
從上述特點(diǎn)可見(jiàn),很難籠統(tǒng)的說(shuō)那種鎖更好,只能具體場(chǎng)景具體分析
從鎖的角度來(lái)說(shuō):
1 . 表級(jí)鎖更適合查詢 ,只有少量按索引條件更新數(shù)據(jù)的應(yīng)用 web應(yīng)用
2 . 行級(jí)鎖,適合有大量按索引條件并發(fā)更新不同數(shù)據(jù),同時(shí)又有并發(fā)查詢的應(yīng)用
OLTP系統(tǒng)
OLTP : Online Transaction Processing 在線事物處理 (增刪改的多)
OLAP:Online Analytical Processing 在線分析處理 歷史數(shù)據(jù)的分析( 查詢 )
2.MyISAM
串行:
mysql 的表級(jí)鎖有兩種模式: 表共享讀鎖(Table Read Lock) 和 表獨(dú)占寫(xiě)鎖(Table Write Lock)
Mysql安裝目錄下 嘍一眼 是MyISAN存儲(chǔ)引擎的格式
注意:
MyISAM 在執(zhí)行查詢語(yǔ)句之前,會(huì)自動(dòng)給涉及的表加讀鎖,在執(zhí)行更新操作前,會(huì)自動(dòng)給涉及的表加寫(xiě)鎖,這個(gè)過(guò)程不需要用戶干預(yù),因此用戶一般不需要使用命令來(lái)顯示的加鎖,一般只有自己在測(cè)試這個(gè)過(guò)程加鎖過(guò)程的時(shí)候,才會(huì)手動(dòng)加鎖,來(lái)模擬各種場(chǎng)景
并行:
MyISAM 表的讀和寫(xiě)是串行的,這是就總體而言的,
在一定條件下MyISAM也支持查詢和插入操作的并發(fā)執(zhí)行!
MyISAM存儲(chǔ)引擎有一個(gè)系統(tǒng)變量concurrent_insert 專門(mén)用來(lái)控制并發(fā)行為,
值分別是 0(NEVER) 1(AUTO) 2(ALWAYS )
- 當(dāng)值為0(NEVER) 時(shí) 不允許并發(fā)插入
- 當(dāng)值為1(AUTO)時(shí),如果表中沒(méi)有被刪除的行(空洞),允許一個(gè)進(jìn)程讀的同時(shí),另一個(gè)進(jìn)程寫(xiě)操作
- 當(dāng)值為2(ALWAYS) 無(wú)論表中有沒(méi)有空洞,都允許表尾并發(fā)插入記錄
實(shí)驗(yàn):
show VARIABLES like '%concurrent_insert%' -- 顯示AUTO 也就是1 -- 還用上邊的N1 N2 N1:lock table test read local; N1:SELECT * FROM test; -- 可以查詢結(jié)果 N1:INSERT INTO TEST VALUES(7,'G'); -- 失敗 Table 'TEST' was locked with a READ lock and can't be updated N2:INSERT INTO TEST VALUES(7,'G'); -- 成功 N1:SELECT * FROM test; -- 可以查詢結(jié)果 但沒(méi)有 7,G 這條記錄 N2:SELECT * FROM test; -- 可以查詢結(jié)果 有新增的7,G 這條記錄 N2:UPDATE TEST SET NAME='CC' WHERE ID=3; -- 阻塞 N1:UNLOCK tables; --解鎖 N2:上一步update成功 N1:SELECT * FROM test; -- N2的新增 和 update 的行 都可以看到 --說(shuō)明 在N1 lock read locl 的時(shí)候 N1 可以查詢 插入 但是不能更新 刪除可以通過(guò)檢查table_locks_waited 和 table_locks_immidiate 的狀態(tài)變量來(lái)分析系統(tǒng)上的表鎖爭(zhēng)奪:
show status like '%table_locks%'
– 如果table_locks_waited 的值比較大,則說(shuō)明存在嚴(yán)重的表鎖爭(zhēng)用情況
3.InnoDB
1、事物及其ACID屬性
事物是由一組SQL語(yǔ)句組成的邏輯處理單元,事物具有4個(gè)屬性,通常稱之為ACID
- 原子性(Actomicity):事物的原子性,對(duì)數(shù)據(jù)的修改,要么全成功 ,要么全失敗 (undolog)
- 一致性(Consistent):在事物開(kāi)始和完成時(shí),數(shù)據(jù)都必須保持一致?tīng)顟B(tài)(最終結(jié)果)
- 隔離性(Isolation):數(shù)據(jù)庫(kù)系統(tǒng)提供一定的隔離機(jī)制,保證事物在不受外部并發(fā)操作影響的“獨(dú)立”環(huán)境執(zhí)行(鎖)
- 持久性(Durable):事物完成之后,它對(duì)于數(shù)據(jù)的修改是永久的,即使出現(xiàn)系統(tǒng)故障也能夠保持(redolog )
2、并發(fā)事物帶來(lái)的問(wèn)題
相對(duì)于串行來(lái)說(shuō)呢,并發(fā)事物處理能力大大增加了數(shù)據(jù)庫(kù)資源的利用率,提高數(shù)據(jù)庫(kù)系統(tǒng)的事物吞吐量,從而可以支持更多用戶的并發(fā)操作,但與此同時(shí),會(huì)帶來(lái)一些問(wèn)題
- 臟讀:
記錄yy=1 A事務(wù)修改yy=2 未提交 , B事物讀取yy=2 ,A事務(wù)回滾 yy=1 ,這時(shí)B事務(wù)讀取的數(shù)據(jù) 就是臟數(shù)據(jù)
示例:
- 不可重復(fù)讀:
事務(wù)A 讀取一條記錄yy=1 , 事務(wù)B 修改yy=2 提交,
事務(wù)A 又讀取一次yy=2 事務(wù)A兩次讀取的結(jié)果不一致
示例:
- 幻讀:
事務(wù)A 查詢范圍r的數(shù)據(jù) 結(jié)果為10條
事務(wù)B 在這個(gè)范圍R內(nèi)加了幾條數(shù)據(jù) 提交
事務(wù)A 又一次讀取這個(gè)范圍R內(nèi)的數(shù)據(jù) 結(jié)果不是10
兩次讀取的記錄數(shù)不一致,這就是幻讀
示例:
-- 接著上邊表結(jié)構(gòu) 1. N1 開(kāi)啟事務(wù) 查詢數(shù)據(jù) -- 開(kāi)啟事務(wù) start TRANSACTION; -- 查詢數(shù)據(jù) select * from test_innodb where name like '%小%' -- 只有一條數(shù)據(jù)2. N2 開(kāi)啟事務(wù) 新增數(shù)據(jù) 提交事務(wù) -- 開(kāi)啟事務(wù) start TRANSACTION; -- 新增數(shù)據(jù) insert into test_innodb values (1,'小智障'); insert into test_innodb values (1,'小傻瓜'); insert into test_innodb values (1,'小小鳥(niǎo)'); -- 提交事務(wù) commit;3. N1 查詢數(shù)據(jù) -- 查詢數(shù)據(jù) select * from test_innodb where name like '%小%' -- 有4條數(shù)據(jù) 出現(xiàn)幻讀 跟幻覺(jué)一樣 剛剛是1 現(xiàn)在是4| read uncommitted 讀取未提交內(nèi)容 | √ | √ | √ |
| read committed 讀提交內(nèi)容 | √ | √ | |
| repeatable read可重復(fù)讀 | √ | ||
| serializable 可串行化 |
Mysql Innodb默認(rèn)是 repeatable read
- read uncommitted 讀取未提交內(nèi)容
所有事務(wù)都可以看到其他事務(wù)未提交的執(zhí)行結(jié)果 - read committed 讀提交內(nèi)容
一個(gè)事務(wù)只能看到已提交的事務(wù)的執(zhí)行結(jié)果 - repeatable read可重復(fù)讀
Mysql默認(rèn)事務(wù)隔離級(jí)別,事務(wù)A讀取一條數(shù)據(jù)后,事務(wù)B對(duì)這條數(shù)據(jù)進(jìn)行了修改,并提交,事務(wù)A再次讀取這條數(shù)據(jù)還是原來(lái)的內(nèi)容(解決了不可重復(fù)讀) - serializable 可串行化
事務(wù) 串行執(zhí)行
可以通過(guò)檢查Innodb_row_lock狀態(tài)變量來(lái)分析系統(tǒng)上的行鎖的爭(zhēng)奪情況
show status like 'innodb_row_lock%';
如果Innodb_row_lock_waits 和 Innodb_row_lock_time_avg 的值比較大就是鎖爭(zhēng)用比較嚴(yán)重
3、InnoDB的行鎖模式 及 加鎖方式
共享鎖(s):
又叫讀鎖
允許一個(gè)事務(wù)去讀一行,阻止其他事務(wù)獲取相同數(shù)據(jù)集的排它鎖,
若事務(wù)T1對(duì)數(shù)據(jù)對(duì)象O上加了S鎖,則事務(wù)T1可以讀取O,但是不能修改O
其他事務(wù)只能對(duì)O加S鎖,不能加排它鎖 ,這保證了其他事務(wù)可以讀O 但是不能修改O
排它鎖(x):
又叫寫(xiě)鎖
允許獲取排它鎖的事務(wù)更新數(shù)據(jù),阻止其他事務(wù)獲取相同數(shù)據(jù)對(duì)象的排它鎖和共享鎖,
若事務(wù)T1 對(duì)對(duì)象O 加上排它鎖,則事務(wù)T1可以讀取對(duì)象&修改對(duì)象,其他事務(wù)不能對(duì)O 加任何鎖
Mysql的InnoDB引擎默認(rèn)的修改數(shù)據(jù)語(yǔ)句:
update delete insert 都會(huì)自動(dòng)給涉及到的數(shù)據(jù)加上排它鎖
select語(yǔ)句不會(huì)加任何類型的鎖,
如果select加排它鎖可以用select * from table_name for update
如果select加共享鎖 可以用 select * from table_name lock in share mode
所以:加了排它鎖的數(shù)據(jù)行,在其他事務(wù)是不能修改數(shù)據(jù)的,也不能通過(guò)for update和 lock in share mode 鎖的方式查詢數(shù)據(jù)
,但是可以直接通過(guò)select * from table_name 查詢數(shù)據(jù),因?yàn)槠胀ǖ膕leect沒(méi)有任何鎖限制
Innodb行鎖是通過(guò)給索引 上的索引項(xiàng)來(lái)實(shí)現(xiàn)的,
這點(diǎn)mysql與oracle不同,oracle是通過(guò)數(shù)據(jù)塊中對(duì)應(yīng)數(shù)據(jù)行加鎖來(lái)實(shí)現(xiàn)的。
innodb這種行鎖實(shí)現(xiàn)特點(diǎn)意味著:只有通過(guò)索引條件檢索數(shù)據(jù),innodb才會(huì)使用行級(jí)鎖,否則,innodb將使用表鎖
總結(jié)
以上是生活随笔為你收集整理的mysql优化 个人笔记 (mysql锁机制 ) 非礼勿扰 -m10的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: IOS设备恢复模式和DFU模式 区别、进
- 下一篇: SQL注入原理-时间盲注