並行性能依次下降,安全性依次提升。mysql
時間T1 | 時間T2 | 時間T2 | 時間T3 | 時間T4 | 時間T5 | 時間T6 | 時間T7 | |
---|---|---|---|---|---|---|---|---|
事務A | 啓動事務 | 讀取值1 | 讀取值V1 | 讀取值V2 | 提交事務A | 讀取值V3 | ||
事務B | 啓動事務 | 讀取值1 | 修改值爲2 | 提交事務B |
讀未提交那麼V一、V二、V3值都是2。sql
讀提交那麼V1爲1,V2和V3是2。數據庫
可重複那麼V1和V2都是1,V3是2。安全
串行化事務A執行完後執行事務B,而後讀取值。因此V1和V2是1,V3是2。工具
長事務意味着數據會保留不少老的事務視圖,這些事務視圖是爲了方便事務的回滾。因爲事務隨時均可能回滾,因此數據庫須要使用存儲空間進行保存。性能
在mysql5.5以前的版本,回滾日誌和數據字典放在一塊兒,即便事務提交了,回滾段被清理,空間也不會變小。致使最後爲了清理空間,只好將整個庫給重建。線程
數據參數autocommit=0表示,不自動提交;建議將autocommit值設置1,這樣就能夠儘可能避免長事務。下面這個語句用於查詢事務時間超過120s的。日誌
select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>120orm
避免長事務:一、業務鏈接數據庫時,經過設置set max_execute_time來控制長事務。二、設置set autocommit=1。事務
數據庫鎖能夠分爲全局鎖,表鎖,行鎖。
全局鎖是對整個數據庫實例加鎖。MySQL 提供了一個加全局讀鎖的方法,命令是
Flush tables with read lock
(FTWRL)。當你須要讓整個庫處於只讀狀態的時候,可使用這個命令,以後其餘線程的如下語句會被阻塞:數據更新語句(數據的增刪改)、數據定義語句(包括建表、修改表結構等)和更新類事務的提交語句。
全局鎖是在作全局備份的時候使用。若是你在主庫上備份,那麼在備份期間都不能執行更新,業務基本上就得停擺。官方自帶的邏輯備份工具是 mysqldump。當 mysqldump 使用參數–single-transaction 的時候,導數據以前就會啓動一個事務,來確保拿到一致性視圖。single-transaction 方法只適用於全部的表使用事務引擎的庫。若是有的表使用了不支持事務的引擎,那麼備份就只能經過 FTWRL 方法。這每每是 DBA 要求業務開發人員使用 InnoDB 替代 MyISAM 的緣由之一。
MySQL 裏面表級別的鎖有兩種:一種是表鎖,一種是元數據鎖(meta data lock,MDL)。
舉個例子若是在某個線程 A 中執行 lock tables t1 read, t2 write; 這個語句,則其餘線程寫 t一、讀寫 t2 的語句都會被阻塞。同時,線程 A 在執行 unlock tables 以前,也只能執行讀 t一、讀寫 t2 的操做。連寫 t1 都不容許,天然也不能訪問其餘表。
MDL 不須要顯式使用,在訪問一個表的時候會被自動加上。MDL 的做用是,保證讀寫的正確性。你能夠想象一下,若是一個查詢正在遍歷一個表中的數據,而執行期間另外一個線程對這個表結構作變動,刪了一列,那麼查詢線程拿到的結果跟表結構對不上,確定是不行的。
如何安全地給小表加字段?