淺談InnoDB隔離模式的使用對MySQL性能造成的影響
在這篇文章里我將討論一個相關(guān)的主題 – InnoDB 事務隔離模式,還有它們與MVCC(多版本并發(fā)控制)的關(guān)系,以及它們是如何影響MySQL性能的。
MySQL手冊提供了一個關(guān)于MySQL支持的事務隔離模式的恰當描述 – 在這里我并不會再重復,而是聚焦到對性能的影響上。
SERIALIZABLE – 這是最強的隔離模式,本質(zhì)上打敗了在鎖管理(設置鎖是很昂貴的)的條件下,多版本控制對所有選擇進行鎖定造成大量的開銷,還有你得到的并發(fā)。這個模式僅在MySQL應用中非常特殊的情況下使用。
REPEATABLE READ – 這是默認的隔離級別,通常它是相當不錯的,對應用程序的便捷性來說也不錯。它在第一次的時候讀入所有數(shù)據(jù) (假設使用標準的非鎖讀)。但是這有很高的代價 – InnoDB需要去維護事務記錄,從一開始就要記錄,它的代價是非常昂貴的。更為嚴重的情況是,程序頻繁地更新和hot rows – 你真的就不想InnoDB去處理rows了,它有成百上千個版本。
在性能上的影響, 讀和寫都能夠被影響。用select查詢遍歷多個行是代價高昂的,對于更新(update)也是,在MySQL 5.6中,尤其是版本控制看起來導致了嚴重的爭用問題。
下面是例子:完全在內(nèi)存中的數(shù)據(jù)集中運行 sysbench,并啟動 transaction 、運行全表、掃描、查詢幾次,同時保持 transaction 是開著的:
sysbench --num-threads=64 --report-interval=10 --max-time=0 --max-requests=0 --rand-type=pareto --oltp-table-size=80000000 --mysql-user=root --mysql-password= --mysql-db=sbinnodb --test=/usr/share/doc/sysbench/tests/db/update_index.lua run
如果有人想測試,可以重復下面我用的查詢集合:
select avg(length(c)) from sbtest1; begin; select avg(length(c)) from sbtest1; select sleep(300); commit;
不只是可復讀(Repeatable Read)的默認隔離級別,同樣也可以用于InnoDB 邏輯備份 – mydumper 或者 mysqldump –single-transaction
這些結(jié)果顯示這個備份的方法恢復的時間太長而不能用于大型數(shù)據(jù)集合,同樣這個方法受到性能影響,也不能用于頻繁寫入(write )的環(huán)境中。
READ COMMITTED 模式和REPEATABLE READ模式很相似,本質(zhì)區(qū)別在于哪個版本都不在transaction中從頭開始讀取,取而代之的從當前語句開始讀取。因此使用這種模式允許InnoDB少維護很多版本,特別是你沒有很長的statements要允運行。如果你有很長的select要運行,如報表查詢對性能的影響仍然很嚴重。
通常我認為好的做法是把READ COMITTED隔離模式做為默認,對于應用程序或者transactions 有必要就改成REPEATABLE READ。
READ UNCOMMITTED – 我覺得這是最難理解的隔離模式(悲催的只有2條文檔),只描述了它的邏輯觀點。如果你使用了這種隔離模式,你會看到數(shù)據(jù)控中所有發(fā)生的變化,即使是那些還沒被提交的transactions 。這種隔離模式一種好的用例是:你能“watch”到大規(guī)模的有臟讀(dirty reads)的UPDATE 語句,顯示了哪行被改變了,哪些沒有改變。
如果transaction 事務在運行的時候出錯了,那么這個聲明會顯示還沒被提交的和可能沒被提交的變化,所以使用這個模式要小心為妙。有一些用例雖然不需要我們100%準確的數(shù)據(jù),在這種情況下,這種模式就變得非常方便。
那么,從性能角度來看,如何體現(xiàn)READ UNCOMMITTED?理論上,InnoDB 可以清除行版本,在READ UNCOMMITTED模式下即便是該語句已經(jīng)開始執(zhí)行之后,也可以創(chuàng)建。在實踐中,由于一個bug或者一些復雜實現(xiàn)的細節(jié)做不到,語句開始仍然是行版本。所以,如果你在READ UNCOMMITTED聲明中運行很長的SELECT,你會得到大量的行版本創(chuàng)建信息,就像你用了READ COMMITTED。No win here。
從SELECT方面還有一個重要的win - READ UNCOMMITTED隔離模式意味著InnoDB 不需要去檢查舊的行版本 - 最后一行總是對的,這會使得性能有明顯的改善,尤其是當undo空間已經(jīng)在磁盤上溢出,查找舊的行版本會造成大量的IO讀寫。
也許上面這個select avg(k) from sbtest1;是我能找到的最好的查詢例子了,能與之類似的更新工作量。假使READ UNCOMMITTED隔離模式在一分鐘左右完成,我認為在READ COMMITTED隔離模式下沒有完成過,因為新索引條目插入的速度要比掃描速度快。
最后思考:正確的使用InnoDB 隔離模式,能夠讓您的應用程序得到最佳性能。你得到的好處可能不同,在某些情況下,也可能沒什么區(qū)別。關(guān)系到InnoDB 的歷史版本,似乎好有好多工作要做,我希望在未來的MySQL中能解決。
- MySQL性能全面優(yōu)化方法參考,從CPU,文件系統(tǒng)選擇到mysql.cnf參數(shù)優(yōu)化
- MySQL性能優(yōu)化的最佳20+條經(jīng)驗
- mysql性能優(yōu)化工具--tuner-primer使用介紹
- 數(shù)據(jù)庫Mysql性能優(yōu)化詳解
- MySQL性能參數(shù)詳解之Skip-External-Locking參數(shù)介紹
- MySQL性能參數(shù)詳解之Max_connect_errors 使用介紹
- MySQL性能瓶頸排查定位實例詳解
- Mysql性能優(yōu)化方案分享
- Mysql性能優(yōu)化案例 - 覆蓋索引分享
- Mysql性能優(yōu)化案例研究-覆蓋索引和SQL_NO_CACHE
- mysql性能優(yōu)化之索引優(yōu)化
- MySQL性能監(jiān)控軟件Nagios的安裝及配置教程
- 19個MySQL性能優(yōu)化要點解析
- 詳解MySQL性能優(yōu)化(二)
- 詳解MySQL性能優(yōu)化(一)
- 10個MySQL性能調(diào)優(yōu)的方法
- 使用FriendFeed來提升MySQL性能的方法
- my.cnf(my.ini)重要參數(shù)優(yōu)化配置說明
相關(guān)文章
mysql中mysql-bin.000001是什么文件可以刪除嗎
這篇文章主要介紹了mysql中mysql-bin.000001是什么文件可以刪除嗎,需要的朋友可以參考下2019-05-05MySQL 性能優(yōu)化的最佳20多條經(jīng)驗分享
今天,數(shù)據(jù)庫的操作越來越成為整個應用的性能瓶頸了,這點對于Web應用尤其明顯。關(guān)于數(shù)據(jù)庫的性能,這并不只是DBA才需要擔心的事,而這更是我們程序員需要去關(guān)注的事情。2010-07-07CentOS 7.2下MySQL的安裝與相關(guān)配置
最近因為工作需要,要在CentOS上安裝MySQL,在安裝的時候遇到了一點問題,花了點時間解決了,感覺不管是官網(wǎng)還是網(wǎng)上的一些教程都不夠完整,不能一次性幫新手解決問題,于是我就結(jié)合官網(wǎng)和網(wǎng)上的資源整理了下,現(xiàn)在分享給大家,希望對有需要的朋友們能有所幫助。2016-11-11Mysql及Navicat中設置字段自動填充當前時間及修改時間實現(xiàn)
這篇文章主要給大家介紹了關(guān)于Mysql及Navicat中設置字段自動填充當前時間及修改時間實現(xiàn)的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2023-07-07在Windows系統(tǒng)上使用壓縮歸檔文件安裝MySQL的步驟
這篇文章主要介紹了在Windows系統(tǒng)上使用壓縮歸檔文件安裝MySQL的步驟,非常不錯,具有一定的參考借鑒加載,需要的朋友可以參考下2018-06-06