1. 程式人生 > >MySQL.存儲引擎-事務-隔離級別-鎖

MySQL.存儲引擎-事務-隔離級別-鎖

與此同時 3.1 角色 有用 等待 容易 提供商 復雜度 myisamchk

MySQL.存儲引擎-事務-隔離級別-鎖

1.什麽是存儲引擎?

? MySQL中的數據用各種不同的技術存儲在文件(或者內存)中。這些技術中的每一種技術都使用不同的存儲機制、索引技巧、鎖定水平並且最終提供廣泛的不同的功能和能力。通過選擇不同的技術,你能夠獲得額外的速度或者功能,從而改善你的應用的整體功能

2.存儲引擎有那些?這些引擎有那些特性?

2.1.Mylsam

MyIsam 存儲引擎獨立於操作系統,也就是可以在windows上使用,也可以比較簡單的將數據轉移到linux操作系統上去。這種存儲引擎在創建表的時候,會創建三個文件,一個是.frm文件用於存儲表的定義,一個是.MYD文件用於存儲表的數據,另一個是.MYI文件,存儲的是索引。操作系統對大文件的操作是比較慢的,這樣將表分為三個文件,那麽.MYD這個文件單獨來存放數據自然可以優化數據庫的查詢等操作。

2.1.1.不支持事務,但是並不代表著有事務操作的項目不能用MyIsam存儲引擎,可以在service層進行根據自己的業務需求進行相應的控制。

2.1.2.不支持外鍵。

2.1.3.查詢速度很快。如果數據庫insert和update的操作比較多的話采用表鎖效率低(建議使用innodb

2.1.4.對表進行加鎖。

2.2.Mrg_Mysam

Merge存儲引擎,是一組MyIsam的組合,也就是說,他將MyIsam引擎的多個表聚合起來,但是他的內部沒有數據,真正的數據依然是MyIsam引擎的表中,但是可以直接進行查詢、刪除更新等操作。
比如:我們可能會遇到這樣的問題,同一種類的數據會根據數據的時間分為多個表,如果這時候進行查詢的話,就會比較麻煩,Merge可以直接將多個表聚合成一個表統一查詢,然後再刪除Merge表(刪除的是定義),原來的數據不會影響。

2.3.Memory

Memory采用的邏輯介質是內存,響應速度應該是很快的,但是當mysqld守護進程崩潰的時候數據會丟失,另外,要求存儲的數據是數據長度不變的格式,比如,Blob和Text類型的數據不可用(長度不固定的)。
使用Memory存儲引擎情況

2.4.Blackhole

“黑洞”存儲引擎,他會丟棄所有的插入的數據,服務器會記錄下Blackhole表的日誌,所以可以用於復制數據到備份數據庫。看其他的一些資料說:可以用來充當dummy master,利用blackHole充當一個“dummy master”來減輕master的負載,對於master來說“dummy master” 還是一個slave的角色,還有充當日誌服務器等等。

2.5.CSV

可以將scv文件作為MySql的表來使用,但是不支持索引。CSV引擎表所有的字段都必須為非空的,創建的表有兩個,分別是CSV文件和CSM文件。

2.6.Performance_Schema

MySQL5.5以後新增了一個存儲引擎,就是Performance_Schema,他主要是用來收集數據庫服務器的性能參數。MySQL用戶不能創建存儲該類型的表。
他提供了以下的功能

1.提供進程等待的詳細信息,包括鎖、互斥變量、文件信息。

2.保存歷史的事件匯總信息,為Mysql服務器的性能做出詳細的判斷。

3.對於新增和刪除監控時間點都非常容易,並可以隨意的改變Mysql服務器的監控周期

需要在配置文件my.cnf中進行配置才能開啟。

2.7.Archive

archive是歸檔的意思,僅僅支持插入和查詢兩種功能,在MySQL5.5以後支持索引功能,他擁有很好的壓縮機制,使用zlib壓縮庫,在記錄請求的時候實時的進行壓縮,經常被用來作為倉庫使用。適合存儲大量的獨立的作為歷史記錄的數據。擁有很高的插入速度但是對查詢的支持較差。

2.8.Federated

Federated存儲引擎是訪問MySQL服務器的一個代理,盡管該引擎看起來提供了一個很好的跨服務器的靈活性,但是經常帶來問題,默認是禁用的。

2.9.InnoDB

InnoDB是一個事務型的存儲引擎,有行級鎖定和外鍵約束,適用於以下的場合:

  1. 更新多的表,適合處理多重並發的更新請求。
  2. 支持事務。
  3. 可以從災難中恢復(通過bin-log日誌等)。
  4. 外鍵約束。只有他支持外鍵。
  5. 支持自動增加列屬性auto_increment。
如何修改數據庫默認存儲引擎:

方式一:

修改配置文件my.ini,在linux中為my.conf文件

在[mysqld]後面添加default-storage-engine=InnoDB,重啟服務,數據庫默認的引擎修改為InnoDB

方式二:
在建表的時候指定
create table test( )engine=‘MyISAM‘;
方式三:
建表後更改
‘‘‘MySql alter table table_name engine = ‘InnoDB‘; 數據量很大的情況下可能要等一段時間

怎麽查看修改成功?

方式一:
show table status from database_name;
方式二:
show create table table_name;

3.常用的三種數據引擎的比較

RDBMS(OLTP)關系數據庫管理系統(Relational Database Management System)

4.1.ISAM:ISAM是一個定義明確且歷經時間考驗的數據表格管理方法,它在設計之時就考慮到數據庫被查詢的次數要遠大於更新的次數。因此,ISAM執行讀取操作的速度很快,而且不占用大量的內存和存儲資源。ISAM的兩個主要不足之處在於,它不支持事務處理,也不能夠容錯:如果你的硬盤崩潰了,那麽數據文件就無法恢復了。如果你正在把ISAM用在關鍵任務應用程序裏,那就必須經常備份你所有的實時數據,通過其復制特性,MYSQL能夠支持這樣的備份應用程序。
MyISAM:MyISAM是MySQL的ISAM擴展格式和缺省的數據庫引擎。除了提供ISAM裏所沒有的索引和字段管理的大量功能,MyISAM還使用一種表格鎖定的機制,來優化多個並發的讀寫操作,其代價是你需要經常運行OPTIMIZE
TABLE命令,來恢復被更新機制所浪費的空間。MyISAM還有一些有用的擴展,例如用來修復數據庫文件的MyISAMCHK工具和用來恢復浪費空間的
MyISAMPACK工具。MYISAM強調了快速讀取操作,這可能就是為什麽MySQL受到了WEB開發如此青睞的主要原因:在WEB開發中你所進行的大量數據操作都是讀取操作。所以,大多數虛擬主機提供商和INTERNET平臺提供商只允許使用MYISAM格式。MyISAM格式的一個重要缺陷就是不能在表損壞後恢復數據。
InnoDB
InnoDB數據庫引擎都是造就MySQL靈活性的技術的直接產品,這項技術就是MYSQL+API。在使用MYSQL的時候,你所面對的每一個挑戰幾乎都源於ISAM和MyISAM數據庫引擎不支持事務處理(transaction
process)也不支持外來鍵。盡管要比ISAM和 MyISAM引擎慢很多,但是InnoDB包括了對事務處理和外來鍵的支持,這兩點都是前兩個引擎所沒有的。如前所述,如果你的設計需要這些特性中的一者或者兩者,那你就要被迫使用後兩個引擎中的一個了。
MEMORY:MEMORY是MySQL中一類特殊的存儲引擎。它使用存儲在內存中的內容來創建表,而且數據全部放在內存中。這些特性與前面的兩個很不同。每個基於MEMORY存儲引擎的表實際對應一個磁盤文件。該文件的文件名與表名相同,類型為frm類型。該文件中只存儲表的結構。而其數據文件,都是存儲在內存中,這樣有利於數據的快速處理,提高整個表的效率。值得註意的是,服務器需要有足夠的內存來維持MEMORY存儲引擎的表的使用。如果不需要了,可以釋放內存,甚至刪除不需要的表。MEMORY默認使用哈希索引。速度比使用B型樹索引快。當然如果你想用B型樹索引,可以在創建索引時指定。註意,MEMORY用到的很少,因為它是把數據存到內存中,如果內存出現異常就會影響數據。如果重啟或者關機,所有數據都會消失。因此,基於MEMORY的表的生命周期很短,一般是一次性的。
在實際工作中,選擇一個合適的存儲引擎是一個比較復雜的問題。每種存儲引擎都有自己的優缺點,不能籠統地說誰比誰好。
InnoDB:支持事務處理,支持外鍵,支持崩潰修復能力和並發控制。如果需要對事務的完整性要求比較高(比如銀行),要求實現並發控制(比如售票),那選擇InnoDB有很大的優勢。如果需要頻繁的更新、刪除操作的數據庫,也可以選擇InnoDB,因為支持事務的提交(commit)和回滾(rollback)。
MyISAM: 插入數據快,空間和內存使用比較低。如果表主要是用於插入新記錄和讀出記錄,那麽選擇MyISAM能實現處理高效率。如果應用的完整性、並發性要求比較低,也可以使用。
MEMORY:所有的數據都在內存中,數據的處理速度快,但是安全性不高。如果需要很快的讀寫速度,對數據的安全性要求較低,可以選擇MEMOEY。它對表的大小有要求,不能建立太大的表。所以,這類數據庫只使用在相對較小的數據庫表。

註意,同一個數據庫也可以使用多種存儲引擎的表。如果一個表要求比較高的事務處理,可以選擇InnoDB。這個數據庫中可以將查詢要求比較高的表選擇MyISAM存儲。如果該數據庫需要一個用於查詢的臨時表,可以選擇MEMORY存儲引擎。

4.事務

4.1.MySQL事務主要用於處理操作量大,復雜度高的數據

1).在MySQL中只有使用了Innodb數據庫引擎的數據庫和表才支持事務。
2)事物處理可以用來維護數據庫的完整性,保證成批的SQL語句要麽全部執行,要麽全部不執行。
3)事務用來管理insert,update,delete語句。

4.2.事務(ACID)

1)原子性(Atomicity不可分割性):一個事務(transaction)中的所有操作,要麽全部完成,要麽全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
2)一致性(Consistency):在事務開始之前和事務結束以後,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及後續數據庫可以自發性地完成預定的工作。
3)隔離性(Isolation):數據庫允許多個並發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務並發執行時由於交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串行化(Serializable)。
4)持久性(Durability):事務處理結束後,對數據的修改就是永久的,即便系統故障也不會丟失。

4.4.事務控制語句:

BEGIN或START TRANSACTION:顯示地開啟一個事務:
COMMIT:也可以使用COMMIT WORK,不過二者是等價的。COMMIT提交事務,並使已對數據庫進行的所有修改成為永久性的;
ROLLBACK:有可以使用ROLLBACK WORK,不過二者是等價的。回滾會結束用戶的事務,並撤銷正在進行的所有未提交的修改:
SAVEPOINT identifier:SAVE[POMT 允許在事務中創建一個保存點。一個事務中可以有多個SAVE[POMT;
RELEASE SAVEPOIN identifier: 刪除一個事務的保存點,一個事務中可以有多個SAVEPOINT;
ROLLEASE SAVEPOINT identifier:把事務回滾到標記點;
SET TRANSACTION :用來設置事務的隔離基本。InnoDB存儲引擎提供事務的隔離級別有READ UNCOMMITTED, READ COMMITTED, REPEATABLE READ和SERIALIZABLE.

4.3.MySQL事務處理主要有兩種方法:

4.3.1.用BEGIN,ROLLBACK,COMMIT來實現

BEGIN開始一個事務
ROLLBACK事務回滾
COMMIT事務確認

4.3.2.直接用SET 來改變MySQL的自動提交模式;

SET AUTOCOMMIT=0 禁止自動提交
SET AUTOCOMMIT=1 開啟自動提交

事務測試
> mysql> use RUNOOB;
> Database changed
> mysql> CREATE TABLE runoob_transaction_test( id int(5)) engine=innodb;  # 創建數據表
> Query OK, 0 rows affected (0.04 sec)
>
> mysql> select * from runoob_transaction_test;
> Empty set (0.01 sec)
>
> mysql> begin;  # 開始事務
> Query OK, 0 rows affected (0.00 sec)
>
> mysql> insert into runoob_transaction_test value(5);
> Query OK, 1 rows affected (0.01 sec)
>
> mysql> insert into runoob_transaction_test value(6);
> Query OK, 1 rows affected (0.00 sec)
>
> mysql> commit; # 提交事務
> Query OK, 0 rows affected (0.01 sec)
>
> mysql>  select * from runoob_transaction_test;
> +------+
> | id   |
> +------+
> | 5    |
> | 6    |
> +------+
> 2 rows in set (0.01 sec)
>
> mysql> begin;    # 開始事務
> Query OK, 0 rows affected (0.00 sec)
>
> mysql>  insert into runoob_transaction_test values(7);
> Query OK, 1 rows affected (0.00 sec)
>
> mysql> rollback;   # 回滾
> Query OK, 0 rows affected (0.00 sec)
>
> mysql>   select * from runoob_transaction_test;   # 因為回滾所以數據沒有插入
> +------+
> | id   |
> +------+
> | 5    |
> | 6    |
> +------+
> 2 rows in set (0.01 sec)
>
> mysql>

5.RDBMS關系數據庫管理(Relational Database Managemet System)

5.1.事務的隔離級別

1)Read Uncommitted(讀取未提交內容)

2) Read Committed(讀取提交內容)

3)Repeatable Read(可重讀)

4) Serializable(可串行化)

Scala有8種數據類型:Byte,Char,Short,Int,Long,Float,Double以及Boolean

隔離級別 臟讀 不可重復讀 幻讀
讀未提交(Read uncommitted) true true true
讀已提交(Read committed) false true true
可重復讀(Repeatable read) false false true
可串行化(Serializable) false false false
5.2.事務並發執行的現象

1)第一類丟是更新:在沒有事務隔離的情況下,兩個事務都同時更新一行數據,但是第二個事務卻中途失敗退出,導致對數據的兩個修改都失效了。

例如:

張三的工資為5000,事務A中獲取工資為5000,事務B獲取工資為5000,匯入100,並提交數據庫,工資變5100,
隨後事務A發生異常,回滾了,恢復張三的工資為5000,這樣就導致事務B的更新丟失了。

2)臟讀:臟讀就是指當一個事務正在訪問數據,並且對數據進行了修改,而這種還沒有提交到數據庫種,這是,另外一個事務也訪問這個數據,然後使用了這個數據。

  張三的工資為5000,事務A中把他的工資改為8000,但事務A尚未提交。
  與此同時,
  事務B正在讀取張三的工資,讀取到張三的工資為8000。
  隨後,
  事務A發生異常,而回滾了事務。張三的工資又回滾為5000。
  最後,
  事務B讀取到的張三工資為8000的數據即為臟數據,事務B做了一次臟讀。

3)不可重復讀:是指在一個事務內,多次讀同一個數據。在這個事務還沒有結束時,另外一個事務也訪問該同一個數據。那麽,在第一個事務種的兩此讀數據之間,由於第二個事務的修改,那麽第一個事務兩次讀到的數據可能是不一樣的。這樣就發生了在一個事務內兩次讀到的數據是不一樣的,因此稱為是不可重復讀。

例如:
  在事務A中,讀取到張三的工資為5000,操作沒有完成,事務還沒提交。
  與此同時,
  事務B把張三的工資改為8000,並提交了事務。
  隨後,
  在事務A中,再次讀取張三的工資,此時工資變為8000。在一個事務中前後兩次讀取的結果並不致,導致了不可重復讀。

4)第二類丟失更新:不可重復讀的特例。有兩個並發事務同時讀取同一行數據,然後其中一個對它進行修改提交,而另一個也進行了修改提交。這就會造成第一此寫操作失效。

例如:
在事務A中,讀取到張三的存款為5000,操作沒有完成,事務還沒提交。
  與此同時,
  事務B,存儲1000,把張三的存款改為6000,並提交了事務。
  隨後,
  在事務A中,存儲500,把張三的存款改為5500,並提交了事務,這樣事務A的更新覆蓋了事務B的更新。

5)幻讀:是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麽,以後就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。

例如:
  目前工資為5000的員工有10人,事務A讀取所有工資為5000的人數為10人。
  此時,
  事務B插入一條工資也為5000的記錄。
  這是,事務A再次讀取工資為5000的員工,記錄為11人。此時產生了幻讀。
提醒:

不可重復讀的重點是修改,同樣的條件,你讀取過的數據,再次讀取出來發現值不一樣了
幻讀的種的在於新曾或者刪除,同樣的條件,第1次和第2次讀出來的記錄數不一樣

6 .0.鎖

MySQL各種存儲引擎使用了三種類型(級別)的鎖定制機制:

1.表級鎖定(table-level):表級別的鎖定是MySQL各存儲引擎中最大顆粒度的鎖定機制。該鎖定機制最大的特點是實現邏輯非常簡單,帶來的系統負面影響最小。所以獲取鎖和釋放鎖的速度很快。由於表級鎖一次會將整個表鎖定,所以可以很好的避免困擾我們的死鎖問題。
註意:當然,鎖定顆粒度大所帶來最大的負面影響就是出現鎖定資源爭用的概率也會最高,致使並大度大打折扣。使用表級鎖定的主要是MyISAM,MEMORY,CSV等一些非事務性存儲引擎。
2.行級鎖定(row-level):行級鎖定最大的特點就是鎖定對象的顆粒度很小,也是目前各大數據庫管理軟件所實現的鎖定顆粒度最小的。由於鎖定顆粒度很小,所以發生鎖定資源爭用的概率也最小,能夠給予應用程序盡可能大的並發處理能力而提高一些需要高並發應用系統的整體性能。

雖然能夠在並發處理能力上面有較大的優勢,但是行級鎖定也因此帶來了不少弊端。由於鎖定資源的顆粒度很小,所以每次獲取鎖和釋放鎖需要做的事情也更多,帶來的消耗自然也就更大了。此外,行級鎖定也最容易發生死鎖。使用行級鎖定的主要是InnoDB存儲引擎。

3.頁級鎖定(page-level):頁級鎖定是MySQL中比較獨特的一種鎖定級別,在其他數據庫管理軟件中也並不是太常見。頁級鎖定的特點是鎖定顆粒度介於行級鎖定與表級鎖之間,所以獲取鎖定所需要的資源開銷,以及所能提供的並發處理能力也同樣是介於上面二者之間。另外,頁級鎖定和行級鎖定一樣,會發生死鎖。

在數據庫實現資源鎖定的過程中,隨著鎖定資源顆粒度的減小,鎖定相同數據量的數據所需要消耗的內存數量是越來越多的,實現算法也會越來越復雜。不過,隨著鎖定資源顆粒度的減小,應用程序的訪問請求遇到鎖等待的可能性也會隨之降低,系統整體並發度也隨之提升。
使用頁級鎖定的主要是BerkeleyDB存儲引擎。

共享鎖(S) 排他鎖(X) 意向共享鎖(IS) 意向排他鎖(IX)
共享鎖(S) 兼容 沖突 兼容 沖突
排他鎖(X) 沖突 沖突 沖突 沖突
意向共享鎖(IS) 兼容 沖突 兼容 兼容
意向排他鎖(IX) 沖突 沖突 兼容 兼容

總結:
表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,並發度最低;
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,並發度也最高;
頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,並發度一般。
適用:從鎖的角度來說,表級鎖更適合於以查詢為主,只有少量按索引條件更新數據的應用,如Web應用;而行級鎖則更適合於有大量按索引條件並發更新少量不同數據,同時又有並發查詢的應用,如一些在線事務處理(OLTP)系統。
在數據庫引擎InnoDB中支持行鎖和表鎖用的也比較多,但是Myisam不支持事務,只支持表鎖
[隔離級別]
共享鎖(S):允許一個事務去讀一行,阻止其他事務獲得相同的數據集的排他鎖。
排他鎖(X):允許獲得排他鎖的事務更新數據,阻止其他事務取得相同數據集的共享讀鎖和排他寫鎖。
意向排他鎖(IX):事務打算給數據行加行排他鎖,事務在給一個數據行加排他鎖前必須取得該表的IX鎖
意向共享鎖(IS):事務打算給數據行加行共享鎖,事務在給一個數據行加共享鎖前必須先取的該表的IS鎖

MySQL.存儲引擎-事務-隔離級別-鎖