Replication进阶(九) MySQL如何自动清理过期binlog

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sun_ashe/article/details/84327894

Replication进阶(九) MySQL如何自动清理过期的binlog

可以通过expire_logs_days设置binlog的过期时间,超过此天数的binlog会被自动purge掉,这个purge的动作是怎么完成的呢?难道MySQL单独开辟了一个线程来不停的看binlog是不是过期了?如果是你,又会如何设计呢?之所以探究这个问题是因为在设计logserver时,也存在相同的问题,日志服务不可能永久保留binlog,和MySQL一样,存在过期清理策略。

今天就来看下MySQL到底是怎么清理过期的binlog的。

  • 数据库重启时
    在数据库启动初始化的过程中,会对已存在的binlog进行检测,如果符合过期条件,则会自动进行清理
~/github/mysql-server/sql/mysqld.cc:init_server_components()

4232 #ifdef HAVE_REPLICATION                      
4233   if (opt_bin_log && expire_logs_days)       
4234   {
4235     time_t purge_time= server_start_time - expire_logs_days*24*60*60;
4236     if (purge_time >= 0)
4237       mysql_bin_log.purge_logs_before_date(purge_time, true);
4238   }
4239 #endif

  • 人为操作:flush logs,触发过期检测,自动清理
Thread 23 "mysqld" hit Breakpoint 2, MYSQL_BIN_LOG::purge_logs_before_date (this=0x1df3e00 <mysql_bin_log>, purge_time=1496221928, auto_purge=true)
    at /data/mysql-5.7.18/sql/binlog.cc:6313
6313	{
(gdb) bt
#0  MYSQL_BIN_LOG::purge_logs_before_date (this=0x1df3e00 <mysql_bin_log>, purge_time=1496221928, auto_purge=true) at /data/mysql-5.7.18/sql/binlog.cc:6313
#1  0x0000000000e0db68 in MYSQL_BIN_LOG::rotate_and_purge (this=0x1df3e00 <mysql_bin_log>, thd=thd@entry=0x7fde00000ae0, 
    force_rotate=force_rotate@entry=true) at /data/mysql-5.7.18/sql/binlog.cc:7236
#2  0x0000000000c6c6ab in reload_acl_and_cache (thd=thd@entry=0x7fde00000ae0, options=16130, tables=tables@entry=0x0, 
    write_to_binlog=write_to_binlog@entry=0x7fde38271780) at /data/mysql-5.7.18/sql/sql_reload.cc:161
#3  0x0000000000c37bbb in mysql_execute_command (thd=thd@entry=0x7fde00000ae0, first_level=first_level@entry=true)
    at /data/mysql-5.7.18/sql/sql_parse.cc:4210
#4  0x0000000000c3e155 in mysql_parse (thd=thd@entry=0x7fde00000ae0, parser_state=parser_state@entry=0x7fde38272540)
    at /data/mysql-5.7.18/sql/sql_parse.cc:5612
#5  0x0000000000c3f243 in dispatch_command (thd=thd@entry=0x7fde00000ae0, com_data=com_data@entry=0x7fde38272de0, command=COM_QUERY)
    at /data/mysql-5.7.18/sql/sql_parse.cc:1461
#6  0x0000000000c40817 in do_command (thd=thd@entry=0x7fde00000ae0) at /data/mysql-5.7.18/sql/sql_parse.cc:999
#7  0x0000000000d00488 in handle_connection (arg=arg@entry=0x2d406b0) at /data/mysql-5.7.18/sql/conn_handler/connection_handler_per_thread.cc:300
#8  0x0000000000eebd81 in pfs_spawn_thread (arg=0x2dcf140) at /data/mysql-5.7.18/storage/perfschema/pfs.cc:2188
#9  0x00007fde59ef66ba in start_thread (arg=0x7fde38273700) at pthread_create.c:333
#10 0x00007fde5938b82d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

  • 事务提交,但是会导致日志轮换,自动清理
(gdb) bt
#0  MYSQL_BIN_LOG::purge (this=0x1df3e00 <mysql_bin_log>) at /data/mysql-5.7.18/sql/binlog.cc:7181
#1  0x0000000000e0eea6 in MYSQL_BIN_LOG::ordered_commit (this=this@entry=0x1df3e00 <mysql_bin_log>, thd=thd@entry=0x7fe9840121f0, all=all@entry=false,
    skip_commit=<optimized out>) at /data/mysql-5.7.18/sql/binlog.cc:9194
#2  0x0000000000e0fecd in MYSQL_BIN_LOG::commit (this=0x1df3e00 <mysql_bin_log>, thd=0x7fe9840121f0, all=<optimized out>)
    at /data/mysql-5.7.18/sql/binlog.cc:8260
#3  0x00000000007c70c4 in ha_commit_trans (thd=thd@entry=0x7fe9840121f0, all=all@entry=false, ignore_global_read_lock=ignore_global_read_lock@entry=false)
    at /data/mysql-5.7.18/sql/handler.cc:1795
#4  0x0000000000ce4202 in trans_commit_stmt (thd=thd@entry=0x7fe9840121f0) at /data/mysql-5.7.18/sql/transaction.cc:458
#5  0x0000000000c3a022 in mysql_execute_command (thd=thd@entry=0x7fe9840121f0, first_level=first_level@entry=true)
    at /data/mysql-5.7.18/sql/sql_parse.cc:5044
#6  0x0000000000c3e155 in mysql_parse (thd=thd@entry=0x7fe9840121f0, parser_state=parser_state@entry=0x7fe9d004e540)
    at /data/mysql-5.7.18/sql/sql_parse.cc:5612
#7  0x0000000000c3f243 in dispatch_command (thd=thd@entry=0x7fe9840121f0, com_data=com_data@entry=0x7fe9d004ede0, command=COM_QUERY)
    at /data/mysql-5.7.18/sql/sql_parse.cc:1461
#8  0x0000000000c40817 in do_command (thd=thd@entry=0x7fe9840121f0) at /data/mysql-5.7.18/sql/sql_parse.cc:999
#9  0x0000000000d00488 in handle_connection (arg=arg@entry=0x3104e70) at /data/mysql-5.7.18/sql/conn_handler/connection_handler_per_thread.cc:300
#10 0x0000000000eebd81 in pfs_spawn_thread (arg=0x2f59a90) at /data/mysql-5.7.18/storage/perfschema/pfs.cc:2188
#11 0x00007fe9ef38d6ba in start_thread (arg=0x7fe9d004f700) at pthread_create.c:333
#12 0x00007fe9ee82282d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

第四种属于题外话,非自动清理,而是手动的让mysql清理掉指定时间之前的日志。

  • purge binary logs to
Thread 23 "mysqld" hit Breakpoint 4, MYSQL_BIN_LOG::purge_logs_before_date (this=this@entry=0x1df3e00 <mysql_bin_log>, purge_time=1496699186, 
    auto_purge=auto_purge@entry=false) at /data/mysql-5.7.18/sql/binlog.cc:6313
6313	{
(gdb) bt
#0  MYSQL_BIN_LOG::purge_logs_before_date (this=this@entry=0x1df3e00 <mysql_bin_log>, purge_time=1496699186, auto_purge=auto_purge@entry=false)
    at /data/mysql-5.7.18/sql/binlog.cc:6313
#1  0x0000000000e0d99f in purge_master_logs_before_date (thd=thd@entry=0x7fde00000ae0, purge_time=<optimized out>) at /data/mysql-5.7.18/sql/binlog.cc:2784
#2  0x0000000000c3b74e in mysql_execute_command (thd=thd@entry=0x7fde00000ae0, first_level=first_level@entry=true)
    at /data/mysql-5.7.18/sql/sql_parse.cc:2863
#3  0x0000000000c3e155 in mysql_parse (thd=thd@entry=0x7fde00000ae0, parser_state=parser_state@entry=0x7fde38272540)
    at /data/mysql-5.7.18/sql/sql_parse.cc:5612
#4  0x0000000000c3f243 in dispatch_command (thd=thd@entry=0x7fde00000ae0, com_data=com_data@entry=0x7fde38272de0, command=COM_QUERY)
    at /data/mysql-5.7.18/sql/sql_parse.cc:1461
#5  0x0000000000c40817 in do_command (thd=thd@entry=0x7fde00000ae0) at /data/mysql-5.7.18/sql/sql_parse.cc:999
#6  0x0000000000d00488 in handle_connection (arg=arg@entry=0x2d406b0) at /data/mysql-5.7.18/sql/conn_handler/connection_handler_per_thread.cc:300
#7  0x0000000000eebd81 in pfs_spawn_thread (arg=0x2dcf140) at /data/mysql-5.7.18/storage/perfschema/pfs.cc:2188
#8  0x00007fde59ef66ba in start_thread (arg=0x7fde38273700) at pthread_create.c:333
#9  0x00007fde5938b82d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

如上就是MySQL清理binlog的所有的触发逻辑,并非一开始想象的单独的线程操作。

猜你喜欢

转载自blog.csdn.net/sun_ashe/article/details/84327894