MySQL中binlog cache使用流程解惑

摘要: 水平有限整理自己的學習筆記,如果有誤請諒解。 最近老是看到有朋友報錯如下:ERROR 1197 (HY000): Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage; increase this mysqld variable and try again雖然錯誤提示非常明確,但是我還是對binlog cache的使用方式進行了學習整理下來,這部分也是我一直疑惑的地方,也希望通過本文接觸讀者的疑惑。

水平有限整理自己的學習筆記,如果有誤請諒解。

最近老是看到有朋友報錯如下:
ERROR 1197 (HY000): Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage; increase this mysqld variable and try again
雖然錯誤提示非常明確,但是我還是對binlog cache的使用方式進行了學習整理下來,這部分也是我一直疑惑的地方,也希望通過本文接觸讀者的疑惑。

本文約定:

binlog cache:實際上就是參數binlog_cache_size指定的大小,它指定的是一段內存空間用於存儲生成的binlog event,是事物級別的參數。
binlog cache 臨時文件:實際上就是參數max_binlog_cache_size指定的大小,它指定是一個臨時磁盤文件存儲由於binlog cache不足溢出的binlog event,其名字由"ML"打頭,是事物級別的參數。
binlog file:代表就是我們平時說的binglog 文件,由max_binlog_size指定大小。
binlog event:代表是各種各樣的binlog中的記錄比如MAP_EVENT/QUERY EVENT/XID EVENT/WRITE EVENT等。
本文源碼版本:

percona 5.7.14
一、通常事物binlog event的寫入流程
這裏首先給出寫入過程,讓大家有一個大概的理解。

注意這個流程都是對於一個事物來講的。一旦事物提交,binlog cache和binlog 臨時文件都會釋放掉,因爲binlog已經固化到了binlog file。同時如果事物中包含多個DML語句,那麼他們共享的一套的binlog cache和binlog 臨時文件。

事物開啓。
執行dml語句,在dml語句第一次執行的時候會分配內存空間binlog cache。
執行dml語句期間生成的event不斷寫入到binlog cache。
如果binlog cache的空間已經滿了,則將binlog cache的數據寫入到binlog臨時文件,同時清空binlog cache。如果binlog臨時文件的大小大於了max_binlog_cache_size的設置則拋錯ERROR 1197 (HY000)。
事物提交,整個binlog cache和binlog臨時文件數據全部寫入到binlog file中進行固化,釋放binlog cache和binlog臨時文件。但是注意此時binlog cache的內存空間留用供下次事物使用,但是binlog臨時文件被截斷爲0,保留文件描述符。其實也就是IO_CACHE(參考後文)保留,並且保留IO_CACHE中的分配的內存空間,和物理文件描述符。
斷開連接,這個過程會釋放IO_CACHE同時釋放其持有的binlog cache內存空間以及持有的binlog 臨時文件。
本文研究就是步驟3和步驟4的寫入過程,和binlog cache以及binlog 臨時文件的實現方式。同時本文不描述binlog_stmt_cache_size和max_binlog_stmt_cache_size的作用,因爲他們和binlog_cache_size、max_binlog_cache_size參數的函數一致,只是存儲是非事物語句的binlog event,但是在討論數據結構的時候還是給出部分解釋。

二、相關數據結構簡介
binlog_cache_mngr類:
這個類中包含了兩個cache實際上就是binlog cache和binlog stmt cache,如下:

binlog_stmt_cache_data stmt_cache;
binlog_trx_cache_data trx_cache;
其中包含一些方法用於訪問這兩個cache。同時將整個binlog event寫入到binlog file的方法也在其中叫做flush,棧幀如下:
#0 binlog_cache_mngr::flush (this=0x7fff58ca17c0, thd=0x7fff58012930, bytes_written=0x7ffff0358918, wrote_xid=0x7ffff0358917)
at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:739
#1 0x0000000001857152 in MYSQL_BIN_LOG::flush_thread_caches (this=0x2e02c80, thd=0x7fff58012930) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8484
#2 0x0000000001857383 in MYSQL_BIN_LOG::process_flush_stage_queue (this=0x2e02c80, total_bytes_var=0x7ffff0358a88, rotate_var=0x7ffff0358a87,
out_queue_var=0x7ffff0358a78) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8546
#3 0x000000000185899f in MYSQL_BIN_LOG::ordered_commit (this=0x2e02c80, thd=0x7fff58012930, all=false, skip_commit=false)
at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:9189
#4 0x000000000185700c in MYSQL_BIN_LOG::commit (this=0x2e02c80, thd=0x7fff58012930, all=false) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8440
可以說他是一個訪問binlog cache和binlog stmt cache的統一的對外接口。

binlog_trx_cache_data類和binlog_stmt_cache_data類:
他們都繼承來自統一的父類binlog_cache_data。因爲binlog_trx_cache_data要實現更多的功能,因爲要支持事物,支持事物的回滾等功能,所以必須增加額外的功能呢但是。binlog_stmt_cache_data則不需要。

binlog_cache_data類:
實現了主要成員包含:

IO_CACHE cache_log:Cache to store data before copying it to the binary log.實際上所謂的binlog cache(binlog stmt cache)/max binlog cache(max stmt binlog cache)都是他實現的。
Rows_log_event m_pending:Pending binrows event. This event is the event where the rows are currently written.
my_off_t saved_max_binlog_cache_size:參數max_binlog_cache_size/max_binlog_stmt_cache_size的大小。
ulong
ptr_binlog_cache_use:狀態binlog_cache_use/binlog_stmt_cache_use的值的指針。
ulong *ptr_binlog_cache_disk_use:狀態binlog_cache_disk_use/binlog_stmt_cache_disk_use的值的指針。
IO_CACHE類:
實際上binlog event的寫入binlog 或者 binlog臨時文件都是由 IO_CACHE子系統實現的,本子系統實現了類似寫緩存如果緩存不夠寫入物理文件的功能,從而降低了物理寫入的次數,提升了性能。它封裝了包含讀緩存,寫緩存以及物理文件等信息。如下:

讀緩存 uchar buffer;
寫緩存 uchar
write_buffer;
物理文件描述符 File file;
其使用方式也分多種模式如:

READ_CACHE模式
WRITE_CACHE模式
SEQ_READ_APPEND模式
當然IO_CACHE還用到其他地方,比如我們熟悉的filesort,進行內存和磁盤排序也是通過這個子系統作爲存儲方式完成的。棧幀參考結束附錄,對於這個子系統更加詳細的參考信息可以自行百度我發現有朋友寫得很清楚,本文主要說明是binlog cache的使用方式而不是這個子系統。但是在涉及到源碼部分的時候以binlog cache和binlog臨時文件的寫入爲列子。

最後我們畫一張這幾個類的關係圖,同時給出binlog cache(binlog stmt cache)和binlog臨時文件(binlog stmt臨時文件)的表示,如下:

QQ圖片20180703183344.png

這張圖解釋了他們的關係。

三、binlog_cache_size作用及其初始化
本節使用的binlog_cache_size大小爲32678及默認值。

binlog_cache_size參數在官方文檔的描述大概爲如果開啓了binlog功能,則在事物期間用於保存binlog event的緩存。如果經常使用大事物應該加大這個緩存,避免過多的磁盤使用,從Binlog_cache_use和Binlog_cache_disk_use可以看出是否使用了binlog cache或binlog 臨時文件用於保存binlog event。
當然如我開頭所說這部分是完全內存的。
實際上當我們的事物需要記錄事物的binlog event的時候我們就會使用到binlog cache,其初始化棧幀如下:

#0 init_io_cache_ext (info=0x7fff58ca17c8, file=-1, cachesize=32768, type=WRITE_CACHE, seek_offset=0, use_async_io=0 '\000', cache_myflags=20, file_key=10)
at /root/mysql5.7.14/percona-server-5.7.14-7/mysys/mf_iocache.c:154
#1 0x00000000018c8b48 in init_io_cache (info=0x7fff58ca17c8, file=-1, cachesize=32768, type=WRITE_CACHE, seek_offset=0, use_async_io=0 '\000', cache_myflags=20)
at /root/mysql5.7.14/percona-server-5.7.14-7/mysys/mf_iocache.c:299
#2 0x00000000018c6b96 in open_cached_file (cache=0x7fff58ca17c8, dir=0x2fa1d70 "/root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/tmp/mysqld.1",
prefix=0x2277d4e "ML", cache_size=32768, cache_myflags=16) at /root/mysql5.7.14/percona-server-5.7.14-7/mysys/mf_cache.c:60
#3 0x00000000018599b2 in THD::binlog_setup_trx_data (this=0x7fff58012930) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:9641
#4 0x0000000001859cb3 in binlog_start_trans_and_stmt (thd=0x7fff58012930, start_event=0x7ffff0359350) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:9742
#5 0x000000000185a0a6 in THD::binlog_write_table_map (this=0x7fff58012930, table=0x7fff58d98260, is_transactional=false, binlog_rows_query=false)
at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:9835
#6 0x0000000000f7299f in write_locked_table_maps (thd=0x7fff58012930) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:8019
#7 0x0000000000f72bf6 in binlog_log_row (table=0x7fff58d98260, before_record=0x7fff58d99120 "\375\001", after_record=0x0,
log_func=0xf77f7d <Delete_rows_log_event::binlog_row_logging_function(THD, TABLE, bool, uchar const, uchar const)>)
at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:8089
我們可以在THD::binlog_setup_trx_data找到binlog_cache_size的作如下:

open_cached_file(&cache_mngr->trx_cache.cache_log, mysql_tmpdir,
LOG_PREFIX, binlog_cache_size, MYF(MY_WME)))
大概解釋一下部分參數的含義。

&cache_mngr->trx_cache.cache_log 就是一個IO_CACHE實例。
mysql_tmpdir 爲參數tmpdir的定義目錄。
LOG_PREFIX 爲如果使用臨時文件臨時文件的前綴,如果是binlog的臨時磁盤文件則爲"ML",如果是filesort的臨時排序文件則爲"MY"。
cache_size 當然就是你參數binlog_cache_size設置的大小。
最終參數binlog_cache_size的值會通過init_io_cache函數傳入到init_io_cache_ext中。我們關注一下以下幾個傳入到init_io_cache_ext的參數。

file=-1:初始換緩存的情況下,不會非配實際的臨時文件。索引用-1表示文件描述符
cachesize=32768:binlog_cache_size設置的大小。
type=WRITE_CACHE:IO_CACHE的使用模式。
下面是init_io_cache_ext函數關於binlog cache分配的重點代碼部分:

  info->file= file;(-1)
  info->pos_in_file= seek_offset;(0)
  info->pre_close = info->pre_read = info->post_read = 0;
      info->arg = 0;
      info->alloced_buffer = 0;
      info->buffer=0;
      info->seek_not_done= 0;

  buffer_block= cachesize; //他們和binlog_cache_size參數指定相等(有對其操作)
  if ((info->buffer= (uchar*) my_malloc(key_memory_IO_CACHE,
                                        buffer_block, flags)) != 0)//爲binlog cache分配實際的內存其大小就是binlog_cache_size指定的大小(有對其操作)
  {
    info->write_buffer=info->buffer;//write_buffer和buffer指向了同一片內存區域,及我們的binlog cache緩存區域
    info->alloced_buffer=1;
  }
  info->read_length=info->buffer_length=cachesize; //此處將緩存的長度記錄爲binlog_cache_size指定的大小(有對其操作)
  info->request_pos= info->read_pos= info->write_pos = info->buffer;//初始化各種位置爲info->buffer指針指向的位置

  if (type == WRITE_CACHE)
  info->write_end= info->buffer+info->buffer_length- (seek_offset & (IO_SIZE-1));//將緩存的邊界設置爲(info->buffer指針指向位置+binlog_cache_size參數指定的大小)

此後IO_CACHE對象已經分配了一塊binlog_cache_size參數指定相等大小的內存,則使我們說的binlog cache已經初始化分配完成。

四、binlog臨時文件的使用和分配方式
及當我們事物需要存儲的binlog event已經不能在binlog cache中存下的時候,我們需要開啓我們binlong臨時文件來存儲。其文件存放到tmpdir的定義的目錄下,文件名爲”ML”開頭。但是這個文件不能用ls看到,因爲使用了LINUX臨時文件建立的方法,以避免其他進程使用這個文件而破壞這個文件的內容。也就是說,這個文件是mysqld進程內部專用的,在LINUX中MySQL使用mkstemp系統調用完成這個功能。對於這個文件可以使用lsof|grep delete看到最後我會給出一個例子。

分配棧幀如下:

#0 create_temp_file (to=0x7ffff0359040 "/root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/tmp/mysqld.1/MLIdFGCH",
dir=0x7fff580167c0 "/root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/tmp/mysqld.1", prefix=0x7fff58016830 "ML", mode=514, MyFlags=16)
at /root/mysql5.7.14/percona-server-5.7.14-7/mysys/mf_tempfile.c:141
#1 0x00000000018c693d in inline_mysql_file_create_temp (key=10, src_file=0x2296d78 "/root/mysql5.7.14/percona-server-5.7.14-7/mysys/mf_cache.c", src_line=80,
to=0x7ffff0359040 "/root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/tmp/mysqld.1/MLIdFGCH",
dir=0x7fff580167c0 "/root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/tmp/mysqld.1", pfx=0x7fff58016830 "ML", mode=514, myFlags=16)
at /root/mysql5.7.14/percona-server-5.7.14-7/include/mysql/psi/mysql_file.h:1048
#2 0x00000000018c6c87 in real_open_cached_file (cache=0x7fff58ca17c8) at /root/mysql5.7.14/percona-server-5.7.14-7/mysys/mf_cache.c:77
#3 0x00000000018cb4a9 in my_b_flush_io_cache (info=0x7fff58ca17c8, need_append_buffer_lock=0) at /root/mysql5.7.14/percona-server-5.7.14-7/mysys/mf_iocache.c:1528
#4 0x00000000018cad03 in _my_b_write (info=0x7fff58ca17c8, Buffer=0x7fff58de751a "", Count=186) at /root/mysql5.7.14/percona-server-5.7.14-7/mysys/mf_iocache.c:1330
#5 0x00000000018cb156 in my_b_safe_write (info=0x7fff58ca17c8, Buffer=0x7fff58de55e0 "\376\001", Count=8180)
at /root/mysql5.7.14/percona-server-5.7.14-7/mysys/mf_iocache.c:1437
#6 0x000000000180e7b2 in Log_event::wrapper_my_b_safe_write (this=0x7fff58972bb0, file=0x7fff58ca17c8, buf=0x7fff58de55e0 "\376\001", size=8180)
at /root/mysql5.7.14/percona-server-5.7.14-7/sql/log_event.cc:977
#7 0x000000000182b392 in Rows_log_event::write_data_body (this=0x7fff58972bb0, file=0x7fff58ca17c8)
at /root/mysql5.7.14/percona-server-5.7.14-7/sql/log_event.cc:11356
#8 0x0000000001835e63 in Log_event::write (this=0x7fff58972bb0, file=0x7fff58ca17c8) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/log_event.h:825
#9 0x0000000001845899 in binlog_cache_data::write_event (this=0x7fff58ca17c0, thd=0x7fff58012930, ev=0x7fff58972bb0)
at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:1120
#10 0x0000000001853625 in MYSQL_BIN_LOG::flush_and_set_pending_rows_event (this=0x2e02c80, thd=0x7fff58012930, event=0x7fff58954fd0, is_transactional=false)
at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:7075
當我們不斷的寫入binlog event的情況下,我們最終會將binlog cache寫滿(對於小事物肯定不會寫滿)。我們來梳理一下binlog 臨時文件是怎麼打開的,我們從my_b_safe_write函數開始:
注意這裏實際對於IO_CACHE來講是通用的方法我只是以binlog 臨時文件建立的流程爲例子,因爲不同的模式走的邏輯不一樣

my_b_safe_write
這個函數在每次binlog event寫入到binlog cache的時候都會調用。
在WRITE_CACHE的模式下會調用宏my_b_write,這是一個關鍵點宏的定義如下:

#define my_b_write(info,Buffer,Count) \
((info)->write_pos + (Count) <=(info)->write_end ?\
(memcpy((info)->write_pos, (Buffer), (size_t)(Count)),\
((info)->write_pos+=(Count)),0) : \
((info)->write_function)((info),(uchar )(Buffer),(Count)))
很簡單如果binlog cache緩存當前寫入的位置加上本次寫入的總量大於了binlog cache的內存地址的邊界則我們需要進行通過*(info)->write_function這個回調函數將binlog cache的內容寫到磁盤了,這樣才能騰出空間給新的binlog event存放。這裏這個回調函數應該就是_my_b_write。

_my_b_write
這個函數只會在binlog cache不夠用的時候需要進行臨時物理文件寫入的時候調用。
大概邏輯如下:

rest_length= (size_t) (info->write_end - info->write_pos); //統計出此時binlog cache剩餘的空間
memcpy(info->write_pos,Buffer,(size_t) rest_length); //寫滿這些剩餘的空間
Buffer+=rest_length;//既然已經寫了一部分那麼待寫入的數據應該減去寫入的部分
Count-=rest_length;//寫入的總量也應該的減去已經寫入的部分
info->write_pos+=rest_length;//binlog cache的寫入位置應該增加

if (my_b_flush_io_cache(info,1))//創建臨時文件(如果沒有創建的話)並且寫入數據到臨時文件

memcpy(info->write_pos,Buffer,(size_t) Count);//刷新完成後。binlog cache已經騰空可以繼續使用了
info->write_pos+=Count;//簡單的增加binlog cache指針的位置
my_b_flush_io_cache
這個函數主要負責了當binlog cache 寫滿後將binlog cache的數據全部寫入到binlog 臨時文件和清空binlog cache,當然最後會增加Binlog_cache_disk_use。
大概邏輯如下:

if (info->file == -1)//如果是第一次建立臨時文件,這裏的文件描述爲-1,前面已經分析過了
{
if (real_open_cached_file(info))//打開臨時文件返回文件描述符 !!!!!

length=(size_t) (info->write_pos - info->write_buffer)//統計本次寫入臨時文件數據的大小
pos_in_file=info->pos_in_file;
info->pos_in_file+=length;//將當前文件寫入位置加上本次寫入數據的大小及爲下次文件寫入的位置
if (mysql_file_write(info->file,info->write_buffer,length,info->myflags | MY_NABP))//將數據寫入到臨時文件中。
info->append_read_pos=info->write_pos=info->write_buffer; //此處將info->write_pos指針指向到binlog cache緩衝開始的位置及binlog cache緩衝全部釋放
++info->disk_writes;//Binlog_cache_disk_use增加
create_temp_file
這個函數沒什麼說的就是調用mkstemp來完成臨時文件的建立,我們關注一下輸入兩個參數即可
to 臨時文件的絕對路徑
dir 及臨時文件所在的目錄
prefix 臨時文件的前綴,這裏是ML
注意對於filesort的臨時文件也是通過這個函數建立,前綴爲MY。

到這裏我們的binlog cache內存空間已經分配,並且由於事物寫入的binlog event大於了binlog cache設置的大小,binlog 臨時文件已經分配並且進行了一次binlog cache數據寫入到binlog 臨時文件的操作。這就是整個流程。

五、max_binlog_cache_size設置過小的報錯
報錯如下:

(root@localhost)[06:19:12] [test ;]> insert into t1 select * from t1;
ERROR 1197 (HY000): Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage; increase this mysqld variable and try again
當然報錯也很清晰告訴你原因,但是在整個流程中到底是哪裏拋錯出來的呢?實際上就是函數_my_b_write中進行的判斷。先來看看這個錯誤的錯誤碼如下:

{ "ER_TRANS_CACHE_FULL", 1197, "Multi-statement transaction required more than \'max_binlog_cache_size\' bytes of storage; increase this mysqld variable and try again" },
在函數_my_b_write中可以看到如下代碼:

if (pos_in_file+info->buffer_length > info->end_of_file) //判斷binlog臨時文件的位置加上本次需要寫盤的數據大於info->end_of_file的大小則拋錯
{
errno=EFBIG;
set_my_errno(EFBIG);
return info->error = -1;
}
而拋錯的代碼在MYSQL_BIN_LOG::check_write_error函數中如下:

if (is_transactional)
{
  my_message(ER_TRANS_CACHE_FULL, ER(ER_TRANS_CACHE_FULL), MYF(MY_WME));
}

其中info->end_of_file的大小正是來自於我們的參數max_binlog_cache_size,不再給出代碼。

六、如何觀察到binlog 臨時文件的存在
前文已經說過可以使用lsof|grep delete來觀察到這種文件,據我觀察這個文件會以64k的倍數上漲如下:

[root@test ~]# lsof|grep delete|grep ML
mysqld 21414 root 77u REG 252,3 65536 1856092 /root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/tmp/mysqld.1/MLUFzokf (deleted)
[root@test ~]# lsof|grep delete|grep ML
mysqld 21414 root 77u REG 252,3 131072 1856092 /root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/tmp/mysqld.1/MLUFzokf (deleted)
[root@test ~]# lsof|grep delete|grep ML
mysqld 21414 root 77u REG 252,3 163840 1856092 /root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/tmp/mysqld.1/MLUFzokf (deleted)
[root@test ~]# lsof|grep delete|grep ML
mysqld 21414 root 77u REG 252,3 229376 1856092 /root/mysql5.7.14/percona-server-5.7.14-7/mysql-test/var/tmp/mysqld.1/MLUFzokf (deleted)
七、總結
寫了這麼多,這裏需要總結一下參數的具體含義,以及注意點。

binlog_cache_size:事物級別的參數,用於指定存儲整個事物生成的binlog event的內存大小,對於大事物來講很可能超過這個參數的設置,則需要開啓binlog 臨時文件用於存儲。
max_binlog_cache_size:事物級別的參數,用於指定當某個事物的binlog event超過了binlog_cache_size大小的設置開啓binlog 臨時文件的可用大小,如果事物的binlog event生成量超過了max_binlog_cache_size+binlog_cache_size設置的大小則會拋錯:
ERROR 1197 (HY000): Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage; increase this mysqld variable and try again
不管是binlog cache還是binlog 臨時文件都是在事物沒有提交之前用於存儲binlog event的場所,一旦事物提交完成後,所有的binlog event都已經固化到binlog file,則它們可以釋放和重用。
binlog_stmt_cache_size/ max_binlog_stmt_cache_size:這一套參數和上面的兩個參數含義差不多,但是針對的是非事物型的binlog event,顯然對於innodb當道的今天大部分的event還是事物級別的,所以我沒有過多研究,但是根據debug來看DDL語句返回的是非事物級別的,如下判斷
斷點 MYSQL_BIN_LOG::write_event函數,代碼片段如下:
bool is_trans_cache= event_info->is_using_trans_cache();//DDL這裏返回的false
binlog_cache_mngr cache_mngr= thd_get_cache_mngr(thd);//得到cache_mngr指針地址,有了它不管是stmt緩存還是trx緩存都能找到如前文所述
binlog_cache_data
cache_data= cache_mngr->get_binlog_cache_data(is_trans_cache);//這裏如果是非事物級別使用stmt緩存區
八、備註信息
最後留下一些有用的接口信息:

事物提交臨時文件被截斷爲0
這個接口實際上就是binlog_cache_mngr::flush->binlog_cache_data::flush->binlog_cache_data::reset->my_chsize
事物提交binlog cache內存空間留用
這個接口可能是binlog_cache_mngr::flush->bMYSQL_BIN_LOG::write_cache->MYSQL_BIN_LOG::do_write_cache->reinit_io_cache
斷開連接整個IO CACHE全部釋放掉
這個接口就是close_cached_file如下:
File file=cache->file;
cache->file= -1; / Don't flush data /
(void) end_io_cache(cache);//釋放整個IO_CACHE
if (file >= 0)
{
(void) mysql_file_close(file, MYF(0));//關閉臨時文件
}請添加鏈接描述

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