mysql innodb 性能優化

默認狀況下,innodb的參數設置的很是小,在生產環境中遠遠不夠用
好比最重要的兩個參數
innodb_buffer_pool_size 默認是8M
innodb_flush_logs_at_trx_commit 默認設置的是1 也就是同步刷新log(能夠這麼理解)

innodb_buffer_pool_size: 這是InnoDB最重要的設置,對InnoDB性能有決定性的影響。默認的設置只有8M,因此默認的數據庫設置下面InnoDB性能不好。在只有 InnoDB存儲引擎的數據庫服務器上面,能夠設置60-80%的內存。更精確一點,在內存容量容許的狀況下面設置比InnoDB tablespaces大10%的內存大小。

innodb_data_file_path:指定表數據和索引存儲的空間,能夠是一個或者 多個文件。最後一個數據文件必須是自動擴充的,也只有最後一個文件容許自動擴充。這樣,當空間用完後,自動擴充數據文件就會自動增加(以8MB爲單位)以 容納額外的數據。例如: innodb_data_file_path=/disk1 /ibdata1:900M;/disk2/ibdata2:50M:autoextend兩個數據文件放在不一樣的磁盤上。數據首先放在ibdata1 中,當達到900M之後,數據就放在ibdata2中。一旦達到50MB,ibdata2將以8MB爲單位自動增加。若是磁盤滿了,須要在另外的磁盤上面 增長一個數據文件。

innodb_data_home_dir:放置表空間數據的目錄,默認在mysql的數據目錄,設置到和MySQL 安裝文件不一樣的分區能夠提升性能。

innodb_log_file_size:該參數決定了recovery speed。太大的話recovery就會比較慢,過小了影響查詢性能,通常取256M能夠兼顧性能和recovery的速度

innodb_log_buffer_size: 磁盤速度是很慢的,直接將log寫道磁盤會影響InnoDB的性能,該參數設定了log buffer的大小,通常4M。若是有大的blob操做,能夠適當增大。

innodb_flush_logs_at_trx_commit=2: 該參數設定了事務提交時內存中log信息的處理。

   1) =1時,在每一個事務提交時,日誌緩衝被寫到日誌文件,對日誌文件作到磁盤操做的刷新。Truly ACID。速度慢。
   2) =2時,在每一個事務提交時,日誌緩衝被寫到文件,但不對日誌文件作到磁盤操做的刷新。只有操做系統崩潰或掉電纔會刪除最後一秒的事務,否則不會丟失事務。
   3) =0時, 日誌緩衝每秒一次地被寫到日誌文件,而且對日誌文件作到磁盤操做的刷新。任何mysqld進程的崩潰會刪除崩潰前最後一秒的事務

innodb_file_per_table: 能夠存儲每一個InnoDB表和它的索引在它本身的文件中。

transaction-isolation=READ-COMITTED: 若是應用程序能夠運行在READ-COMMITED隔離級別,作此設定會有必定的性能提高。

innodb_flush_method: 設置InnoDB同步IO的方式:

   1) Default – 使用fsync()。
   2) O_SYNC 以sync模式打開文件,一般比較慢。
   3) O_DIRECT,在Linux上使用Direct IO。能夠顯著提升速度,特別是在RAID系統上。避免額外的數據複製和double buffering(mysql buffering 和OS buffering)。

innodb_thread_concurrency: InnoDB kernel最大的線程數。

   1) 最少設置爲(num_disks+num_cpus)*2。
   2) 能夠經過設置成1000來禁止這個限制
mysql

=========================================linux

介紹: 
  InnoDB給MySQL提供了具備提交,回滾和崩潰恢復能力的事務安全(ACID兼容)存 儲引擎。InnoDB鎖定在行級而且也在SELECT語句提供一個Oracle風格一致的非鎖定讀。這些特點增長了多用戶部署和性能。沒有在InnoDB 中擴大鎖定的須要,由於在InnoDB中行級鎖定適合很是小的空間。InnoDB也支持FOREIGN KEY強制。在SQL查詢中,你能夠自由地將InnoDB類型的表與其它MySQL的表的類型混合起來,甚至在同一個查詢中也能夠混合。
  Innodb 的創始人:Heikki Tuuri
 Heikki Tuuri在Innodb的Bug社區裏也是很活躍的,若是遇到Bug也能夠直接提到社區,獲得做者的解答。sql

爲何要學習Innodb的調優: 
  目前來講:InnoDB是爲Mysql處理巨大數據量時的最大性 能設計。它的CPU效率多是任何其它基於磁盤的關係數據庫引擎所不能匹敵的。在數據量大的網站或是應用中Innodb是倍受青睞的。
  另外一方 面,在數據庫的複製操做中Innodb也是能保證master和slave數據一致有必定的做用。數據庫

參數調優內容:
  1. 內存利用方面
  2. 日值控制方面
  3. 文件IO分 配,空間佔用方面
  4. 其它相關參數緩存

1.內存利用方面:
首先介紹一個Innodb最重要的參數:
innodb_buffer_pool_size 
   這個參數和MyISAM的key_buffer_size有類似之處,但也是有差異的。這個參數主要緩存innodb表的索引,數據,插入數據時的緩 衝。爲Innodb加速優化首要參數。
  該參數分配內存的原則:這個參數默認分配只有8M,能夠說是很是小的一個值。若是是一個專用DB服務 器,那麼他能夠佔到內存的70%-80%。這個參數不能動態更改,因此分配需多考慮。分配過大,會使Swap佔用過多,導致Mysql的查詢特慢。若是你 的數據比較小,那麼可分配是你的數據大小+10%左右作爲這個參數的值。例如:數據大小爲50M,那麼給這個值分配 innodb_buffer_pool_size=64M
設置方法:
innodb_buffer_pool_size=4G 
這 個參數分配值的使用狀況能夠根據show innodb status/G; 中的
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 4668764894;
 
去確認使用狀況。安全


第二個:
innodb_additional_mem_pool: 
做用:用來存放 Innodb的內部目錄
這個值不用分配太大,系統能夠自動調。不用設置過高。一般比較大數據設置16M夠用了,若是表比較多,能夠適當的增大。如 果這個值自動增長,會在error log有中顯示的。
分配原則:
show innodb status/G; 去 查看運行中的DB是什麼狀態(參考BUFFER POOL AND MEMORY段中),而後能夠調整到適當的值。
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 4668764894; in additional pool allocated 16777216
參考:in additional pool allocated 16777216
根據你的參數狀況,能夠適當的調整。
設置方法:
innodb_additional_mem_pool=16M服務器


2.關於日值方面:
innodb_log_file_size 
做用:指定日值的大小
分 配原則:幾個日值成員大小加起來差很少和你的innodb_buffer_pool_size相等。上限爲每一個日值上限大小爲4G.通常控制在幾個LOG 文件相加大小在2G之內爲佳。具體狀況還須要看你的事務大小,數據大小爲依據。
說明:這個值分配的大小和數據庫的寫入速度,事務大小,異常重啓後 的恢復有很大的關係。
設置方法:
innodb_log_file_size=256M性能


innodb_log_files_in_group
做用:指定你有幾個日值組。
分配 原則: 通常咱們能夠用2-3個日值組。默認爲兩個。
設置方法:
innodb_log_files_in_group=3學習


innodb_log_buffer_size:
做用:事務在內存中的緩衝。
分配原 則:控制在2-8M.這個值不用太多的。他裏面的內存通常一秒鐘寫到磁盤一次。具體寫入方式和你的事務提交方式有關。在Oracle等數據庫瞭解這個,一 般最大指定爲3M比較合適。
參考:Innodb_os_log_written(show global status 能夠拿到)
若是 這個值增加過快,能夠適當的增長innodb_log_buffer_size
另外若是你須要處理大理的TEXT,或是BLOB字段,能夠考慮增 加這個參數的值。
設置方法:
innodb_log_buffer_size=3M大數據

innodb_flush_logs_at_trx_commit 
做用:控制事務的提交方式
分 配原則:這個參數只有3個值,0,1,2請確認一下自已能接受的級別。默認爲1,主庫請不要更改了。
性能更高的能夠設置爲0或是2,但會丟失一秒 鐘的事務。
說明: 
這個參數的設置對Innodb的性能有很大的影響,因此在這裏給多說明一下。
當 這個值爲1時:innodb 的事務LOG在每次提交後寫入日值文件,並對日值作刷新到磁盤。這個能夠作到不丟任何一個事務。
當這個值爲2時:在 每一個提交,日誌緩衝被寫到文件,但不對日誌文件作到磁盤操做的刷新,在對日誌文件的刷新在值爲2的狀況也每秒發生一次。但須要注意的是,因爲進程調用方面 的問題,並不能保證每秒100%的發生。從而在性能上是最快的。但操做系統崩潰或掉電纔會刪除最後一秒的事務。
當這個值爲0時:日誌緩衝每秒一次 地被寫到日誌文件,而且對日誌文件作到磁盤操做的刷新,可是在一個事務提交不作任何操做。mysqld進程的崩潰會刪除崩潰前最後一秒的事務。

從以上分析,當這個值不爲1時,能夠取得較好的性能,但遇到異常會有損失,因此須要根據自已的狀況去衡量。


設置方法:
innodb_flush_logs_at_trx_commit=1

3. 文件IO分配,空間佔用方面
innodb_file_per_table 
做用:使每一個 Innodb的表,有自已獨立的表空間。如刪除文件後能夠回收那部分空間。
分配原則:只有使用不使用。但DB還須要有一個公共的表空間。
設 置方法:
innodb_file_per_table=1

innodb_file_io_threads 
做用:文件讀寫IO數,這個參數只在Windows上起 做用。在LINUX上只會等於4
設置方法:
innodb_file_io_threads=4

innodb_open_files 
做用:限制Innodb能打開的表的數據。
分配原則:若是 庫裏的表特別多的狀況,請增長這個。這個值默認是300。
設置方法:
innodb_open_files=800 
請 適當的增長table_cache


4. 其它相關參數 
這裏說明一個比較重要的參數:
innodb_flush_method 
做 用:Innodb和系統打交道的一個IO模型
分配原則:Windows不用設置。
Unix能夠設置:fsync() or O_SYNC/O_DSYNC
若是系統能夠禁止系統的Cache那就把他禁了。
Linux能夠選擇:O_DIRECT 
直接寫入 磁盤,禁止系統Cache了
設置方法:
innodb_flush_method=O_DIRECT

innodb_max_dirty_pages_pct 
做用:控制Innodb的髒頁在緩衝中在那個 百分比之下,值在範圍1-100,默認爲90.
這個參數的另外一個用處:當Innodb的內存分配過大,導致Swap佔用嚴重時,能夠適當的減少調 整這個值,使達到Swap空間釋放出來。建義:這個值最大在90%,最小在15%。太大,緩存中每次更新須要致換數據頁太多,過小,放的數據頁過小,更新 操做太慢。
設置方法:
innodb_max_dirty_pages_pct=90
動態更改須要有Super權限:
set global innodb_max_dirty_pages_pct=50;

總結: 
  這裏只算是列出了Innodb部分的重要參數,不能認爲是對Mysql的總體調優。 Mysql的參數通常分爲:全局參數,具體引擎的參數。全局參數方面請參考http://imysql.cn/2007_12_08_optimize_mysql_under_linux yejr的那個Mysql調優的PPT。


========================================

經過此次MySQL InnoDB的調優經歷,發現一些和MySQL官方推薦配置不符合的疑惑之處,值得思考和探索:

一、innodb_flush_method究竟應不該該使用O_DIRECT?

全部MySQL調優的建議都說,若是硬件沒有預讀功能,那麼使用O_DIRECT將極大下降InnoDB的性能,由於O_DIRECT跳過了操做系 統的文件系統Disk Cache,讓MySQL直接讀寫磁盤了。

可是在個人實踐中來看,若是不使用O_DIRECT,操做系統被迫開闢大量的Disk Cache用於innodb的讀寫緩存,不但沒有提升讀寫性能,反而形成讀寫性能急劇降低。並且buffer pool的數據緩存和操做系統Disk Cache緩存形成了Double buffer的浪費,顯然從我這個實踐來看,浪費得很是厲害。

說O_DIRECT形成MySQL直接讀寫磁盤形成得性能降低問題,我以爲徹底是杞人憂天。由於從JavaEye的數據庫監測來看,Innodb的 buffer pool命中率很是高,有98%以上,真正的磁盤操做是微乎其微的。爲了1%的磁盤操做可以獲得Disk Cache,而浪費了98%的double buffer內存空間,不管從性能上看,仍是從內存資源的消耗來看,都是很是不明智的。

二、innodb_log_file_size究竟應該大一點,仍是小一點?

全部MySQL調優建議都說,innodb_log_file_size要越大越好,避免無謂的buffer pool的flush操做。

可是在個人實踐中來看,innodb_log_file_size開得太大,會明顯增長innodb的log寫入操做,並且會形成操做系統須要更多 的Disk Cache開銷。

所以從個人經驗來看,innodb_flush_method =O_DIRECT 是必須的,而innodb_log_file_size也不宜太大。

相關文章
相關標籤/搜索