InnoDB性能調優基礎(進階)

本文的原文地址在此:http://www.percona.com/blog/2013/09/20/innodb-performance-optimization-basics-updated/,以下是譯文。

-----------------------------------------------------------這是一條分割線-----------------------------------------------------------

September 20, 2013 by Muhammad Irfan

最近偶然發現了Peter Zaitsev在2007年寫的《InnoDB性能調優基礎》。這是一篇很好的文章,它讓我回顧了近6年MySQL和Percona的各種可用架構(這句話後半段不太懂,原文是:It’s a great post and reading it inspired me to examine what’schanged in the nearly six years that have followed in terms of MySQL, PerconaServer – as well as in all of the other now-available infrastructures.)

這6年確實有很多東西發生了變化!在這篇文章,我將會專注於對InnoDB有影響的各種參數——尤其是性能相關的。我是一個技術支持,因此我能夠告訴大家Percona售後中很多與InnoDB基礎參數配置相關問題的答案。希望這篇文章能夠給有類似疑問的朋友帶來幫助。

 

1.      硬件

今天,大數據集(largedatasets)的內存一般都是數以百G,即使是T級別也沒什麼好驚訝。MySQL需要足夠多的內存,以提供最佳性能,如緩存熱點數據、索引、大量變化(ongoing changes)。InnoDB有更短的響應時間,並能以更合理的方式利用磁盤IO。從CPU來看,當然是核越多、速度越快越好。32/64核的CPU已經越來越普遍,最新版本的MySQL在對多核CPU的支持上也比以前的版本要好得多。再來看存儲,SSD正在取代傳統的機械硬盤,並獲得了巨大的成功,當然這是用錢來換最好的性能。RAID 10仍然是多數情況下的首選,但要確保你的RAID控制器能夠很好的支持SSD硬盤,以免成爲瓶頸。當然如果你對IOPS有很高的需求,可以選擇多個PCI-e Flash卡。

1.      操作系統

Linux是最常見的高性能MySQL的服務器。請確保使用最新的內核和現代的文件系統,如EXT 4或XFS。兩種文件系統都有各自的優缺點:如XFS刪大文件時比較快,EXT4卻能讓SSD硬盤有更好的性能。選擇權在你手上。這篇文章(www.ssdperformanceblog.com/2013/04/testing-the-micron-p320h/)(很奇怪這個網站用Firefox、chrome或IE都打不開,翻牆也打不開,實在不知道什麼原因——譯者注)告訴你如何讓EXT4比XFS有更好的性能。當你的表特別多,而你又使用了innodb_file_per_table參數的時候,noatime和nodiratime將會給你帶來一點點的性能提升。Linux的默認I/O調度程序是CFQ(Completely Fair Queuing),實際上多數情況下Noop/Deadline有更好的性能。對於MySQL專用服務器,將swappiness設爲0是一個不錯的選擇,因爲這可以降低swapping的延遲。要確保MySQL的主機不會出現內存不足的情況。swapping對MySQL是有害的,並且會阻止內存中的緩存。想了解更多有關swapping的知識,可以閱讀這篇文章(www.mysqlperformanceblog.com/2008/04/06/should-you-have-your-swap-file-enabled-while-running-mysql/)。

2.      MySQL InnoDB 配置

從5.5開始,InnoDB是默認的引擎,所以這些參數能夠比以前更好的優化性能。最重要的是以下這些:

        innodb_buffer_pool_size:緩衝池對InnoDB的影響很大,一定要配置正確,因此要給這個值分配足夠的內存。通常是可用內存的70%-80%。更確切地說,如果你的內存比數據集大那麼一點,那麼讓這個值比數據庫的大小大一點最好,當然你需要注意數據庫大小的增長,並經常調整innodb緩衝池的大小,使二者大小保證一致。(這句話沒看太懂,原文是:More precisely, if you have RAM bigger than your dataset setting itbit larger should be appropriate with that keep in account of your databasegrowth and re-adjust innodb buffer pool size accordingly.)如果你用的是PerconaServer 5.1或Percona Server 5.5,那麼在代碼級別對InnoDB的緩衝有優化,相關知識可以看這篇文章http://www.percona.com/doc/percona-server/5.5/scalability/innodb_split_buf_pool_mutex.html

        innodb_buffer_pool_instances:InnoDB1.1和MySQL5.5中介紹了多Innodb緩衝池。5.5中這個值默認大小是1,而5.6中是8。這個參數的取值範圍是1-64。在高併發的任務中允許使用innodb_buffer_pool_instances會非常有效,因爲它能夠減少全局互斥鎖(global mutexes)的存在。(這個參數在CentOS版的MySQL-5.5.39的配置文件中沒有,不知原文作者說的5.5中的默認值哪來的——譯者注

        Dump/Restore Buffer Pool:這個參數能夠在重啓時,提高保存、恢復緩衝池內容的速度。這個特性最早出現在Percona Server 5.5中,可以通過這兩篇文章做進一步瞭解(http://www.percona.com/doc/percona-server/5.5/management/innodb_lru_dump_restore.html?id=percona-server:features:innodb_lru_dump_restore,http://www.mysqlperformanceblog.com/2010/01/20/xtradb-feature-save-restore-buffer-pool/)。MySQL 5.6中也加入了該特性,要在數據庫啓動或關閉時自動dump數據,需要將innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup設置爲ON。

        innodb_log_file_size:足夠大的InnoDB事務日誌,對於穩定的、高質量寫性能至關重要。但巨大的日誌文件同樣意味着崩潰以後的恢復會很慢。當然,在5.5進行巨大改進以後,這一點已經不再是經常爭論的重點。MySQL 5.6將默認值從5MB調整到50MB,但這個值對於很多情況依然太小。另外,在MySQL 5.6中,如果這個參數值被改變,那麼MySQL將會在重啓的時候自動調整大小。在MySQL 5.6中,合併後的日誌文件大小從4G調整到512G。有關日誌最佳大小的問題,可以閱讀這篇文章(http://www.mysqlperformanceblog.com/2008/11/21/how-to-calculate-a-good-innodb-log-file-size/

        innodb_log_buffer_size:InnoDB的寫操作,將數據寫入到內存中的日誌緩存中,由於InnoDB在事務提交前,並不將改變的日誌寫入到磁盤中,因此在大事務中,可以減輕磁盤I/O的壓力。通常情況下,如果不是寫入大量的超大二進制數據(a lot of huge blobs),4MB-8MB已經足夠了。

        innodb_flush_log_at_trx_commit:這個值設爲1時,將會在每次日誌提交時,將日誌緩衝(log buffer)中的內容刷入硬盤,以確保數據最大限度的完整性,當然這樣也會對性能帶來影響。如果設爲2,表示每次日誌提交時,僅僅將日誌緩衝中的內容刷入操作系統的文件緩存。如果你對ACID不那麼關注,並且對於OS崩潰前最後一兩秒的事務丟失不那麼在意的話,設爲2將帶來更好的性能。

        innodb_thread_concurrency:隨着InnoDB的改善,現在推薦大家使用默認值0,即由InnoDB引擎自己控制併發。如果你看到併發相關的討論,可以調整這個參數。推薦值的簡單計算方法是(CPU的數量+硬盤數量)*2(2 times the number of CPUs plus the number of disks)。這是一個動態變量,這意味着改變這個值不用重啓MySQL即可生效。

        innodb_flush_method:DIRECT_IO能減輕I/O的壓力。直接I/O不進行緩存,如果設置爲O_DIRECT可以避免緩衝池與文件系統的雙緩衝,但是需要有RAID控制器以及電池備份的寫緩存。(原文不是這樣,但原文沒看太懂Given that you have hardware RAID controller and battery-backedwrite cache.)

        innodb_file_per_table:從MySQL 5.6開始,這個值默認是ON。這個是默認值是因爲可以避免產生巨大的共享表空間,並且可以在drop和truncate一張表的時候,迅速釋放空間。獨立的表空間同樣在Xtrabackup的部分備份時有優勢。

 除了以上這些,Percona Server 5.5和MySQL 5.6對InnoDB有很多增強。在Percona Server 5.5的XtraDB中加入了Persistentoptimizer statistics,通過innodb_use_sys_stats_table參數控制,相關知識可以閱讀這篇文章(http://www.percona.com/doc/percona-server/5.5/diagnostics/innodb_stats.html?id=percona-server:features:innodb_stats&redirect=1#innodb_use_sys_stats_table),在MySQL 5.6中也引入了這個特性。在MySQL5.6中,使用兩個新表mysql.innodb_index_stats和mysql.innodb_table_stats來存儲persistentstats。通過這個,在查詢(query)的時候,能夠保證更精確和一致性。更多細節請閱讀文檔這裏http://dev.mysql.com/doc/refman/5.6/en/innodb-performance.html#innodb-persistent-stats。同樣PerconaServer 5.5裏介紹了來自於線程池的特性,可以閱讀這個官方文檔http://www.percona.com/doc/percona-server/5.5/performance/threadpool.html。另外線程池的知識還可以還可以閱讀這裏http://www.mysqlperformanceblog.com/2013/03/16/simcity-outages-traffic-control-and-thread-pool-for-mysql/

PerconaServer是免費且開源的。是在MySQL基礎上修改的,上面有的特性只有Percona Server纔有。

還有很多參數可以調整,但是在這篇文章我們只關注InnoDB。

3.      爲InnoDB優化應用程序

對於應用程序,尤其是以前使用MyISAM引擎的程序來說,需要進行以下調整。

首先,確保在更新操作(update)時使用事務,這樣既可以保證一致性,也能夠獲得更好的性能。其次,如果你的程序有任何寫操作,都應該要考慮可能發生的死鎖。再次,請檢查你的表結構,以確保他們能從InnoDB屬性中獲得性能改善,如:用主鍵聚集數據,所有索引都有主鍵(因此要保證主鍵短),用主鍵進行快速查找(試着使用join),大的未壓縮的索引(使主鍵儘可能的簡單。)(這一段話不太懂:clustering by primary key, having primary key in all indexes (sokeepprimary key short), fast lookups by primary keys (try to use it in joins),largeunpacked indexes(try to be easy on indexes).)

4.      總結

本文幾乎覆蓋了所有和MySQL性能有關的參數,包括InnoDB的基礎或進階參數、OS的參數和硬件配置。通過這些修改,可以確保所有MySQL服務器的性能都得到優化。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章