并發控制:
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 = LEVEL