本篇文章給大家帶來了關于mysql中寫入binary log流程的相關知識,其中包括“sync_binlog”、“binlog_cache_size”和“max_binlog_cache_size”的相關問題,希望對大家有幫助。
Binary Log寫入流程
我們首先還是先看看官方文檔對sync_binlog配置的描述。
sync_binlog
命令行格式 | –sync-binlog=# |
系統變量 | sync_binlog |
影響范圍 | Global |
動態的 | Yes |
SET_VAR提示適用 | No |
類型 | Integer |
默認值 | 1 |
最小值 | 0 |
最大值 | 2^32=4294967295 |
控制 mysql 服務器將二進制日志同步到磁盤的頻率。
-
sync_binlog=0:禁用 MySQL 服務器將二進制日志同步到磁盤。相反,MySQL 服務器依賴操作系統不時將二進制日志刷新到磁盤,就像它對任何其他文件所做的那樣。此設置提供了最佳性能,但如果發生電源故障或操作系統崩潰,服務器可能已提交尚未刷盤的事務。
-
sync_binlog=1:在提交事務之前啟用二進制日志到磁盤的同步。這是最安全的設置,但由于磁盤寫入次數增加,可能會對性能產生負面影響。在電源故障或操作系統崩潰的情況下,二進制日志中丟失的事務僅處于準備狀態。這允許常規自動恢復回滾事務,從而保證不會從二進制日志中丟失事務。
-
sync_binlog=N, 其中是 0 或 1 以外的值:收集到N個二進制日志提交組后,二進制日志會同步到磁盤。在電源故障或操作系統崩潰的情況下,服務器可能已經提交了尚未刷新到二進制日志的事務。由于磁盤寫入次數增加,此設置可能會對性能產生負面影響。較高的值會提高性能,但會增加數據丟失的風險。
InnoDB為了在與事務一起使用?的復制設置中獲得最大可能的持久性和一致性,請使用以下設置:
- sync_binlog=1.
- innodb_flush_log_at_trx_commit=1.
警告許多操作系統和一些磁盤硬件欺騙了刷新到磁盤操作。他們可能會告訴?mysqld已經發生了刷新,即使它還沒有發生。在這種情況下,即使使用推薦的設置也無法保證事務的持久性,在最壞的情況下,斷電可能會損壞InnoDB數據。SCSI 磁盤控制器或磁盤本身中使用電池支持的磁盤緩存可加快文件刷新速度,并使操作更安全。您還可以嘗試禁用硬件緩存中磁盤寫入的緩存。
小結
- sync_binlog設置類型為unsigned Integer。
- 一般不會設置為0,0依賴系統操作不定時fsync,發生電源故障或者系統崩潰的時候比較危險——事務提交了但是Binary Log缺失了。
- 設置為1比較安全,獲得最大可能的持久性和一致性,能保證后面的主從復制、恢復。但是對性能不利,當業務需要的IOPS不高可以設置。
- 設置為大于1的值目的是提高性能不是一個事務提交就fsync下,相當于批量刷盤,是比較聰明的方式,但是如果出現電源故障或者系統崩潰的時候Binary Log缺失的會比較多。如果磁盤本身使用電池支持的磁盤緩存會比較安全。所以當業務需要的IOPS比較高時可以設置,但是一般也不會設置過大,可以在[100,1000]區間中。
另外我們通過sync_binlog=0的描述其實我們也可以大概能感覺到,其實當事務提交的時候雖然沒有馬上fsync,但是其實是已經write到文件系統的page cache中了,那么其實mysql在事務運行的時候也會有一個cache緩存在事務中產生的Binary Log。
下面我們繼續看看Binary Log在事務運行時的cache相關配置。
binlog_cache_size
命令格式 | –binlog-cache-size=# |
系統變量 | binlog_cache_size |
范圍 | Golbal |
動態的 | Yes |
SET_VAR提示適用 | No |
類型 | Integer |
默認值 | 32768 |
最小值 | 4096 |
最大值(64位平臺) | 2^64=18446744073709547520 |
最大值(32位平臺) | 2^32=4294967295 |
塊大小 | 4096 |
在事務期間保存二進制日志更改的內存緩沖區的大小。該值必須是 4096 的倍數。
在服務器上啟用二進制日志記錄(?log_bin系統變量設置為 ON)時,如果服務器支持任何事務存儲引擎,則會為每個客戶端分配一個二進制日志緩存。如果事務的數據超出內存緩沖區中的空間,超出的數據將存儲在臨時文件中。當服務器上的二進制日志加密處于活動狀態時,內存緩沖區未加密,但(從 MySQL 8.0.17 開始)用于保存二進制日志緩存的任何臨時文件都被加密。提交每個事務后,通過清除內存緩沖區并截斷臨時文件(如果使用)來重置二進制日志緩存。
如果您經常使用大型事務,則可以通過減少或消除寫入臨時文件的需要來增加此緩存大小以獲得更好的性能。?Binlog_cache_use(服務狀態變量-使用Binary Log緩存的事務數量)和?Binlog_cache_disk_use?(服務狀態變量-使用臨時二進制日志緩存但超過binlog_cache_size值并使用臨時文件存儲事務語句的事務數。)狀態變量可用于調整此變量的大小。請參閱第 5.4.4 節,“二進制日志”。
binlog_cache_size僅設置事務緩存的大小;語句緩存的大小由?binlog_stmt_cache_size?系統變量控制。
小結
- binlog_cache_size設置類型為unsigned Integer。
- 用來指示每個事務期間用來緩存Binary Log的大小,默認為32k,必須是4096的倍數。如果超過這個值會使用臨時文件存儲。
- 業務中盡量不要使用大事務,如果事務過大需要考慮是否合理。一般不需要對binlog_cache_size進行修改,32k足夠了。
- binlog_cache_size不足夠的時候會使用臨時文件進行存儲,但是性能會變低,我們可以設置max_binlog_cache_size=binlog_cache_size這樣就不會使用臨時文件,下文會介紹。
max_binlog_cache_size
命令格式 | –max-binlog-cache-size=# |
系統變量 | max_binlog_cache_size |
范圍 | Golbal |
動態的 | Yes |
SET_VAR提示適用 | No |
類型 | Integer |
默認值 | 2^64=18446744073709547520 |
最小值 | 4096 |
最大值 | 2^64=18446744073709547520 |
塊大小 | 4096 |
如果一個事務需要超過這么多字節的內存,服務器會生成一個多語句事務需要超過 ‘max_binlog_cache_size’ 字節的存儲錯誤。最小值為 4096。可能的最大值為 16EiB(exbibytes)。最大推薦值為4GB;這是因為 MySQL 目前無法處理大于 4GB 的二進制日志位置。該值必須是 4096 的倍數。
max_binlog_cache_size僅設置事務緩存的大小;語句緩存的上限由?max_binlog_stmt_cache_size?系統變量控制。
會話的可見性?max_binlog_cache_size匹配?binlog_cache_size系統變量的可見性;換句話說,更改其值只會影響更改值后啟動的新會話。
總結
- max_binlog_cache_size是一個安全值,一般根據服務器可分配的內存進行設置。
概述
從上面的配置,我們可以得出,Binary Log大致的寫入流程:
- 事務改在運行時,放入每個事務的Binary Log緩存中。
- 事務提交后根據配置來進行,如果是sync_binlog=1,則每次進行fsync,緩存會釋放。如果是sync_binlog=0,則會直接寫入系統文件的page cache,依賴于操作系統不時地將二進制日志刷盤。如果sync_binlog=N(N>1),則相當于批量刷盤,當然每個事務持有的binlog cache會進行釋放。
所以大致流程如下圖:
總結
至此我們大致了解了Mysql寫入Binary的流程,需要經過:每個事務持有的binlog cache -> 文件系統的page cache -> 磁盤。可以通過sync_binlog進行控制具體執行策略。
使用
- sync_binlog:如果需要獲得最大的持久性和一致性的話就設置成1,至于性能問題可以調整硬件等其他方式;如果運行binary log允許丟失或者丟失通過其他方式控制又想基于目前服務器資源進行優化就設置在[100,1000]區間中。
- binlog_cahe_size:前面已經提到過在實際業務中需要注意對事務粒度進行把控,絕大情況默認的32k足夠了。
推薦學習:mysql視頻教程