如果您遵循資料庫設計的最佳實務,並針對 SQL 操作調整技術,但由於磁碟 I/O 活動頻繁而導致資料庫仍然緩慢,請考慮以下磁碟 I/O 優化。如果 Unix top
工具或 Windows 工作管理員顯示您的工作負載的 CPU 使用率百分比低於 70%,則您的工作負載可能受限於磁碟。
增加緩衝池大小
當表格資料快取在
InnoDB
緩衝池中時,查詢可以重複存取它,而無需任何磁碟 I/O。使用innodb_buffer_pool_size
選項指定緩衝池的大小。此記憶體區域非常重要,通常建議將innodb_buffer_pool_size
設定為系統記憶體的 50% 到 75%。有關更多資訊,請參閱第 10.12.3.1 節,「MySQL 如何使用記憶體」。調整刷新方法
在某些 GNU/Linux 和 Unix 版本中,使用 Unix
fsync()
呼叫和類似方法將檔案刷新到磁碟的速度異常緩慢。如果資料庫寫入效能是個問題,請使用設定為O_DSYNC
的innodb_flush_method
參數進行基準測試。為作業系統刷新設定臨界值
預設情況下,當
InnoDB
建立新的資料檔案時,例如新的記錄檔案或表空間檔案時,該檔案會完全寫入作業系統快取,然後再刷新到磁碟,這可能會導致一次發生大量的磁碟寫入活動。若要強制從作業系統快取中較小、週期性地刷新資料,您可以使用innodb_fsync_threshold
變數來定義以位元組為單位的臨界值。當達到位元組臨界值時,作業系統快取的內容會刷新到磁碟。預設值 0 會強制執行預設行為,即僅在檔案完全寫入快取後才將資料刷新到磁碟。在多個 MySQL 執行個體使用相同儲存裝置的情況下,指定一個閾值來強制較小的定期刷新可能會有益。例如,建立一個新的 MySQL 執行個體及其相關的資料檔案可能會導致大量的磁碟寫入活動,阻礙使用相同儲存裝置的其他 MySQL 執行個體的效能。設定閾值有助於避免這種寫入活動的激增。
使用 fdatasync() 而非 fsync()
在支援
fdatasync()
系統呼叫的平台上,innodb_use_fdatasync
變數允許使用fdatasync()
而非fsync()
來進行作業系統刷新。fdatasync()
系統呼叫不會刷新檔案的中繼資料變更,除非後續資料擷取需要,這可能會帶來效能上的好處。諸如
fsync
、O_DSYNC
和O_DIRECT
等innodb_flush_method
設定的子集使用fsync()
系統呼叫。當使用這些設定時,innodb_use_fdatasync
變數適用。在 Linux 上使用 noop 或 deadline I/O 排程器與原生 AIO
InnoDB
在 Linux 上使用非同步 I/O 子系統(原生 AIO)來執行資料檔案頁面的預讀和寫入請求。此行為由預設啟用的innodb_use_native_aio
設定選項控制。使用原生 AIO 時,I/O 排程器的類型對 I/O 效能有較大的影響。一般來說,建議使用 noop 和 deadline I/O 排程器。進行基準測試,以確定哪個 I/O 排程器為您的工作負載和環境提供最佳結果。如需更多資訊,請參閱第 17.8.6 節「在 Linux 上使用非同步 I/O」。在 x86_64 架構的 Solaris 10 上使用直接 I/O
在 x86_64 架構 (AMD Opteron) 的 Solaris 10 上使用
InnoDB
儲存引擎時,請針對InnoDB
相關檔案使用直接 I/O,以避免InnoDB
效能下降。若要對用於儲存InnoDB
相關檔案的整個 UFS 檔案系統使用直接 I/O,請使用forcedirectio
選項掛載;請參閱mount_ufs(1M)
。(Solaris 10/x86_64 上的預設值是不使用此選項。)若要僅對InnoDB
檔案操作而非整個檔案系統套用直接 I/O,請設定innodb_flush_method = O_DIRECT
。使用此設定,InnoDB
會呼叫directio()
而非fcntl()
來對資料檔案執行 I/O(不包括對記錄檔執行 I/O)。對 Solaris 2.6 或更新版本使用原始儲存來儲存資料和記錄檔
當在 Solaris 2.6 及更新版本的任何版本以及任何平台 (sparc/x86/x64/amd64) 上,使用具有較大
innodb_buffer_pool_size
值的InnoDB
儲存引擎時,請使用原始裝置或單獨的直接 I/O UFS 檔案系統,針對InnoDB
資料檔案和記錄檔進行基準測試,並使用先前所述的forcedirectio
掛載選項。(如果想要對記錄檔使用直接 I/O,則必須使用掛載選項,而不是設定innodb_flush_method
。)Veritas 檔案系統 VxFS 的使用者應使用convosync=direct
掛載選項。請勿將其他 MySQL 資料檔案(例如
MyISAM
資料表的檔案)放在直接 I/O 檔案系統上。可執行檔或程式庫絕不能放在直接 I/O 檔案系統上。使用額外的儲存裝置
可以使用額外的儲存裝置來設定 RAID 組態。如需相關資訊,請參閱第 10.12.1 節「最佳化磁碟 I/O」。
或者,
InnoDB
資料表空間資料檔案和記錄檔可以放在不同的實體磁碟上。如需更多資訊,請參閱以下章節考慮使用非旋轉式儲存裝置
非旋轉式儲存裝置通常為隨機 I/O 作業提供更好的效能;而旋轉式儲存裝置則為循序 I/O 作業提供更好的效能。在旋轉式和非旋轉式儲存裝置之間分配資料和記錄檔時,請考慮在每個檔案上主要執行的 I/O 作業類型。
以隨機 I/O 為導向的檔案通常包括每個資料表一個檔案和一般資料表空間資料檔案、復原資料表空間檔案和暫時資料表空間檔案。以循序 I/O 為導向的檔案包括
InnoDB
系統資料表空間檔案、雙寫入檔案和記錄檔,例如二進位記錄檔案和重做記錄檔案。使用非旋轉式儲存裝置時,請檢閱下列組態選項的設定
crc32
選項使用更快的檢查總和演算法,建議用於快速儲存系統。最佳化旋轉式儲存裝置的 I/O。針對非旋轉式儲存裝置或旋轉式和非旋轉式儲存裝置的混合停用它。預設情況下已停用。
允許在閒置期間限制頁面刷新,這有助於延長非旋轉式儲存裝置的壽命。
預設設定值 10000 通常已足夠。
預設值 (2 *
innodb_io_capacity
) 適用於大多數工作負載。如果重做記錄在非旋轉式儲存裝置上,請考慮停用此選項以減少記錄。請參閱停用壓縮頁面的記錄。
innodb_log_file_size
(已棄用)如果重做記錄在非旋轉式儲存裝置上,請設定此選項以最大化快取和寫入合併。
如果重做記錄在非旋轉式儲存裝置上,請設定此選項以最大化快取和寫入合併。
考慮使用符合磁碟內部磁區大小的頁面大小。早期 SSD 裝置通常具有 4KB 的磁區大小。一些較新的裝置具有 16KB 的磁區大小。預設的
InnoDB
頁面大小為 16KB。保持頁面大小接近儲存裝置區塊大小,可將重新寫入磁碟的未變更資料量降至最低。如果二進位記錄在非旋轉式儲存裝置上且所有資料表都有主索引鍵,請考慮將此選項設定為
minimal
以減少記錄。
請確保您的作業系統已啟用 TRIM 支援。它通常預設為啟用。
增加 I/O 容量以避免待辦項目
如果因
InnoDB
檢查點作業而導致輸送量定期下降,請考慮增加innodb_io_capacity
組態選項的值。較高的值會導致更頻繁的刷新,避免可能導致輸送量下降的待辦工作。如果刷新沒有落後,則降低 I/O 容量
如果系統的
InnoDB
刷新作業沒有落後,請考慮降低innodb_io_capacity
組態選項的值。通常,您會將此選項值保持在盡可能低的實用值,但不能太低,以至於如前一個項目符號所述,導致輸送量定期下降。在您可以降低選項值的典型情況下,您可能會在SHOW ENGINE INNODB STATUS
的輸出中看到類似的組合歷史記錄清單長度較低,低於數千。
插入緩衝區合併接近插入的資料列數。
緩衝集區中修改的頁面一直遠低於緩衝集區的
innodb_max_dirty_pages_pct
。(在伺服器未執行大量插入時測量;在大量插入期間,修改的頁面百分比顯著上升是正常的。)記錄序列號 - 最後的檢查點
小於InnoDB
記錄檔總大小的 7/8,理想情況下小於 6/8。
將系統資料表空間檔案儲存在 Fusion-io 裝置上
您可以藉由將包含雙寫入儲存區域的檔案儲存在支援原子寫入的 Fusion-io 裝置上,來利用與雙寫入緩衝區相關的 I/O 最佳化。(雙寫入緩衝區儲存區域位於雙寫入檔案中。請參閱第 17.6.4 節「雙寫入緩衝區」。)當雙寫入儲存區域檔案放在支援原子寫入的 Fusion-io 裝置上時,會自動停用雙寫入緩衝區,並將 Fusion-io 原子寫入用於所有資料檔案。此功能僅在 Fusion-io 硬體上受到支援,並且僅在 Linux 上的 Fusion-io NVMFS 上啟用。若要充分利用此功能,建議將
innodb_flush_method
設定為O_DIRECT
。注意因為雙寫入緩衝區設定是全域性的,所以也會針對不在 Fusion-io 硬體上的資料檔案停用雙寫入緩衝區。
當使用
InnoDB
資料表壓縮功能時,如果壓縮資料發生變更,則重新壓縮的頁面影像會寫入重做記錄。此行為由innodb_log_compressed_pages
控制,此選項預設為啟用,以防止在復原期間使用不同版本的zlib
壓縮演算法時可能發生的損毀。如果您確定zlib
版本不會變更,請停用innodb_log_compressed_pages
,以減少修改壓縮資料的工作負載的重做記錄產生。