InnoDB log file 設置多大合適?


簡介:

數據庫的東西,往往一個參數就牽涉N多知識點。所以簡單的說一下。大家都知道innodb是支持事務的存儲引擎。事務的四個特性ACID即原子性(atomicity),一致性(consistency),隔離性(isolation),持久性(durability)。其中原子性,一致性,持久性通過redo log 和 undo來實現。redo log稱為重做日志,用來保證事務的原子性和持久性。undo log用來保證事務的一致性。 當事務提交時,必須先將該事務的所有日志寫入到重做日志文件(redo log)進行持久化(當然先寫到日志緩沖區,而不是直接寫文件,關於什么時候刷新到磁盤文件,是一個比較復雜的問題,同學們自行查閱資料),待事務提交操作才算完成。innodb的redo log是順序I/O,所以設置合適的值能夠大大提高數據庫性能。那么是不是設置的越大越好呢?

設置的太小:當一個日志文件寫滿后,innodb會自動切換到另外一個日志文件,而且會觸發數據庫的檢查點(Checkpoint),這會導致innodb緩存臟頁的小批量刷新,會明顯降低innodb的性能。

設置的太大:設置很大以后減少了checkpoint,並且由於redo log是順序I/O,大大提高了I/O性能。但是如果數據庫意外出現了問題,比如意外宕機,那么需要重放日志並且恢復已經提交的事務,如果日志很大,那么將會導致恢復時間很長。甚至到我們不能接受的程度。

那么我們如何估算log file該設置為多大?通常我們可以通過觀察show status中innodb_os_log_written狀態變量來查看innodb對日志文件寫出了多少數據。一個好用的經驗是,查看10-100秒間隔的數字,然后記錄峰值。可以用這個判斷日志緩沖是否設置的正好。例如,若看到峰值是每秒寫100kb數據到日志,那么1MB的日志緩沖已經足夠了。也可以使用這個衡量標准來決定日志文件設置多大會比較好。如果峰值是100KB/s,那么256M的日志文件足夠存儲至少2560秒的日志記錄。一般來說,日志文件的全部大小,應該足夠容納服務器一個小時的活動內容。

下面看實際的測試(由於是虛擬機,所以使用sysbench模擬據量寫入,生產環境選擇數據庫最繁忙的時候測試):

[root@yayun-mysql-server ~]# sysbench --test=oltp --oltp-table-size=100000 --oltp-read-only=off --init-rng=on --num-threads=16 --max-requests=0 --oltp-dist-type=uniform --max-time=180 --mysql-user=root --mysql-socket=/tmp/mysqld.sock --mysql-password=123456 --db-driver=mysql --mysql-table-engine=innodb --oltp-test-mode=complex prepare    

1.首先計算innodb每分鍾產生的日志量:

(root@yayun-mysql-server) [(none)]>pager grep sequence
PAGER set to 'grep sequence'
(root@yayun-mysql-server) [(none)]>show engine innodb status\G select sleep(60); show engine innodb status\G
Log sequence number 6377275259
1 row in set (0.00 sec)

1 row in set (1 min 0.00 sec)

Log sequence number 6403945555
1 row in set (0.00 sec)

(root@yayun-mysql-server) [(none)]>nopager
PAGER set to stdout
(root@yayun-mysql-server) [(none)]>select (6403945555 - 6377275259) / 1024 / 1024 as MB_per_min;                    
+-------------+
| MB_per_min  |
+-------------+
| 25.43477631 |
+-------------+
1 row in set (0.02 sec)

(root@yayun-mysql-server) [(none)]>

注意Log sequence number,這是寫入事務日志的總字節數。所以,現在你可以看到每分鍾有多少MB日志寫入(這里的技術適用於所有版本的MySQL,在5.0及更高版本,你可以從SHOW GLOBAL STATUS的輸出看Innodb_os_log_written的值) 。

通過計算后得到每分鍾有25M的日志寫入。

根據經驗法則。通常我們設置redo log size足夠大,能夠容納1個小時的日志寫入量。

1小時日志寫入量=25M * 60=1500M,大約等於1.5G。由於默認有兩個日志重做日志文件ib_logfile0和ib_logfile1。在日志組中的每個重做日志文件的大小一致,並以循環的方式寫入。innodb存儲引擎先寫重做日志文件0,當達到文件的最后時,會切換到重做日志1,並checkpoint。以此循環。

所以我們可以大約設置innodb_log_file_size=800M。注意:在innodb1.2.x版本之前,重做日志文件總的大小不得大於等於4G,而1.2.x版本將該限制擴大到了521G。

innodb_log_file_size = 800M
[root@yayun-mysql-server mysql]# du -sh ib_logfile*
801M    ib_logfile0
801M    ib_logfile1
[root@yayun-mysql-server mysql]# 

對於innodb 1.2.x版本之前如果設置大於4G則報錯

[root@yayun-mysql-server mysql]# tail -n 10 yayun-mysql-server.err  
140511  1:01:15 InnoDB: Completed initialization of buffer pool
140511  1:01:15 InnoDB: Error: combined size of log files must be < 4 GB
140511  1:01:15 [ERROR] Plugin 'InnoDB' init function returned error.
140511  1:01:15 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
140511  1:01:15 [ERROR] Failed to initialize plugins.
140511  1:01:15 [ERROR] Aborting

140511  1:01:15 [Note] /usr/local/mysql/bin/mysqld: Shutdown complete

140511 01:01:15 mysqld_safe mysqld from pid file /data/mysql/yayun-mysql-server.pid ended
[root@yayun-mysql-server mysql]# 

而innodb 1.2.x以后版本則不會:

[root@yayun-mysql-server mysql5.6]# tail -f yayun-mysql-server.err     
2014-05-11 01:06:47 5205 [Note] InnoDB: Using Linux native AIO
2014-05-11 01:06:47 5205 [Note] InnoDB: Initializing buffer pool, size = 128.0M
2014-05-11 01:06:47 5205 [Note] InnoDB: Completed initialization of buffer pool
2014-05-11 01:06:47 5205 [Note] InnoDB: Highest supported file format is Barracuda.
2014-05-11 01:06:47 5205 [Warning] InnoDB: Resizing redo log from 2*3072 to 2*327680 pages, LSN=1085681253
2014-05-11 01:06:47 5205 [Warning] InnoDB: Starting to delete and rewrite log files.
2014-05-11 01:06:47 5205 [Note] InnoDB: Setting log file ./ib_logfile101 size to 5120 MB
InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 3100 3200 3300 3400 3500 3600 3700 3800 3900 4000 4100 4200 4300 4400 4500 4600 4700 4800 4900 5000 5100
2014-05-11 01:12:40 5205 [Note] InnoDB: Setting log file ./ib_logfile1 size to 5120 MB
InnoDB: Progress in MB: 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 2400 2500 2600 2700 2800 2900 3000 3100

 

參考資料

http://www.mysqlperformanceblog.com/2008/11/21/how-to-calculate-a-good-innodb-log-file-size/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM