併發控制:
MVCC 多版本併發控制。
用戶在操做時操做的是帶有時間點的快照。而不是表自己。最後將快照進行合併。
鎖:
讀鎖:共享鎖。讀取操做不會對用戶之間產生影響。
寫鎖:獨佔鎖。一個用戶寫入時,其餘用戶就不能寫入。
能夠手動設置:
LOCK TABLES TBNAME [AS AILAS] LOCK_TYPE,... 給表加鎖
LOCK_TYPE
READ 讀鎖
WRITE 寫鎖
UNLOCK TABLES 解除全部表的鎖,注意不能指定TBNAME。
鎖力度:
表鎖:鎖定整張表
頁鎖:鎖定頁塊,一個頁塊中包含多個行。
行鎖:鎖定行
mysql服務器僅支持表鎖,行鎖須要存儲引擎支持。每一個引擎對鎖的策略都不一樣。
力度越精細越能提升併發,越粗糙越能方便管理。
實例:
1.給tutors表建立讀鎖:
mysql>LOCK TABLES tutors read;
2.解鎖:
mysql>UNLOCK TABLES;
事務:
事務就是將多個涉及到大量的cpu操做和io操做的多個操做看作一組。這樣的組被稱做事務。
事務的流程:
啓動(START TANSACTION)-->寫入撤銷日誌中 --> 執行操做(一堆SQL語句)|執行過程當中斷後根據撤銷日誌回滾(ROLLBACK)--> 寫入重作日誌中--> 根據重作日誌進行磁盤操做 (提交COMMINT)
多事務併發:
例如進行io操做時cpu空閒,能夠利用cpu進行新的事務,這是多事務併發的基本思想。可是多事務併發有可能形成事物之間進行交互。因此此時要使用隔離機制保證數據庫的一致性。
依賴的技術手段:
鎖
時間戳
多版本和快照隔離
多事務交互:
經過io產生的數據集,事務之間就能夠進行交互。可是數據集是實時變更的。因此這種交互會產生不一致狀態。在這種狀態下,交互的結果可能產生差錯
髒讀:
一個事務未提交前,另外一個事務進行讀取操做。讀操未提交的內容稱爲髒讀。
幻讀:
一個事務對某個表執行查詢操做時,另外一個事務對此表進行修改,會形成先後查詢不一致。
事務的狀態:
活動的:正在執行的。
部分提交的:執行完成,可是最後一條語句正在提交中。
失敗的:執行完成,提交未能完成。
終止的:執行過程當中終止,未提交。
提交的:執行完成,提交完成。
鎖飢餓:
死鎖:
注意:事務一旦提交就沒法撤銷,只能經過補償事務。
事務調度:
1.可恢復調度:
2.無級聯調度:
保存點(SAVEPOINT):用於在事務中建立保存點,這樣回滾的時候不會所有回滾,只回滾到保存點以前的全部狀態。
使用SAVEPOINT SPNAME建立保存點。
使用ROLLBACK TO SPNAME回滾到保存點。
支持事務要先支持ACID特性
ACID特性:
原子性(Automicity):一個事務當中的操做語句要麼都執行完成,要麼都不執行。
一致性(Consistency):事務完成前和完成後,對數據庫來講狀態是沒有改變的。一致性要在隔離狀態下才能保證。
隔離性(Isolation):如有2個事務同時執行,其中一個在提交錢前都不被另外一個察覺到。即一個事務的中間過程不影響到其餘操做。服務器使用事務調度(例如MVCC)來使事務間影響最小。
持久性(Durability):一個事務提交後,即使服務器出現任何故障,也必須保證不引發事務出現不一致性。即事務的操做是持續有效的。
實現手段:
1.事務提交前已經將數據寫入硬盤。要消耗大量的磁盤io。
2.結合事務日誌完成。使用的是順序io而不是向數據文件那樣使用隨機io。速度很是快。
存儲引擎對事務的支持:
mysql中,是否支持事務,是根據存儲引擎來定義的。
MyISAM不支持事務。
InnoDB支持事務。若不明確啓動事務,默認autocommit是啓動的,會自動提交。建議明確使用事務,並關閉自動提交。關閉後若不明確事務,則執行的全部操做都被當作在一個事務中。
事務日誌:
重作日誌(redo log):
每次操做都在內存中操做,並寫入重作日誌中記錄。一旦操做完成則表示事務提交。一段時間後,根據日誌內容將操做寫入硬盤。
撤銷日誌(undo log):
保留每一次操做前的狀態。以便恢復。
日誌組:
日誌也是文件,文件中只記錄操做,不記錄對應的數據。
多個日誌文件構成日誌組。
日誌文件是輪流使用。一個記錄滿之後自動記錄到下個文件中。記錄滿的日誌文件會將操做同步到硬盤。而後清空日誌。
日誌文件的大小要根據具體需求定義。
詳細請參考日誌相關。
事務隔離等級:
爲了解決多事務交互中出現的各類問題。採用此機制
級別越高,安全性越好,併發能力越弱。
READ-UNCOMMITED 讀未提交。最低級別。一個事務執行完成後另外一個事務立刻能看到。此時前一個事務還未能提交。事務之間干擾最大。
READ-COMMITTED 讀提交。一個事務提交後才能看到。不提交其餘事務看到的不變化。
REPEATABLE-READ 可重讀。一個事務不管提交與否,另外一個事務在提交前看到的不變化,一旦該事務提交,則看到的是最終值。InnoDB默認級別爲此。
SERIALIZABLE 可串行。最高級別。能夠同時啓動多個事務,但一個時間內只能執行一個事務。另外一個事務想要操做必須等前面的事務提交完畢後才行。
mysql默認是REPEATABLE-READ。大多數SQL默認是READ-COMMITTED
使用SHOW GOBAL VARIABLES LIKE ‘tx_isolation’查看。
分佈式事務(XA):
是一種高層次的事務,使用兩段式方式(準備-提交 prepare-then-commit)將ACID屬性擴展到存儲引擎的外幣,甚至是數據庫外部。
準備階段:
事務協調員同時全部參與者準備提交事務
提交階段:
事務協調員在收到全部參與者發出的就緒信息是,會指示全部參與者進行真正的提交操做。
默認InnoDB是啓用分佈式事務的,使用SHOW GLOBAL VARIABLES LIKE ‘innodb_support_xa’查看
實例:
1.啓動一個事務:
mysql>START TRANSACTION;
啓動後的操做都被認爲是事務中的操做
2.執行操做:
mysql> DELETE FROM students WHERE Name LIKE 'stu%';
3.完成操做後提交:
mysql>COMMIT;
注意:一旦提交將不能回滾。
4.或者是回滾:
mysql>ROLLBACK;
5.修改服務器設置,禁用自動提交
mysql默認是啓動自動提交的,即執行操做後立刻提交,這樣會佔用大量的磁盤io,下降性能。
mysql> SELECT @@autocommit;
mysql> SET autocommit=0;
6.建立保存點:
使用
mysql>SAVEPOINT abc;
7.回滾到某個保存點:
mysql>ROLLBACK TO abc;
8.查看當前的隔離級別:
mysql>SELECT @@tx_isolation;
9.修改當前會話隔離級別:
mysql>SET tx_isolation=‘LEVEL’;
10.修改全局隔離級別:
#vim /etc/my.cnf
[mysqld]
...
transaction-isolation = LEVELmysql