• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

mysql expire_logs_days是如何生效的

mysql 搞代码 7年前 (2018-06-06) 139次浏览 已收录 0个评论

mysql expire_logs_days是怎么生效的

       mysql主备复制是通过binlog完成的。在开启binlog的情况下,expire_logs_days参数可以让mysql自动清理若干天前的binlog。那么expire_logs_days是在什么时候生效的呢?初步猜想实在每次产生一个新的binlog的时候去判断一次。查了一下具体的实现,确实是这样的:(5.1.58, log.cc)

int MYSQL_BIN_LOG::rotate_and_purge(uint flags) { ...   if (!error && check_purge && expire_logs_days)   {     time_t purge_time= my_time(0) - expire_logs_days*24*60*60;     if (purge_time >= 0)       purge_logs_before_date(purge_time);   } ... }

欢迎大家阅读《mysql expire_logs_days是如何生效的》,跪求各位点评,by 搞代码

        如果设置了expire_logs_days,每次binlog rotate的时候都去计算一下purge_time(当前时间-expire_logs_days;这个计算似乎是可以省去的: expire_logs_days是以天为单位,范围是0~99, 0表示不会清理,自然不会进入if块内:),以99来计算,my_time(0) – 99*24*60*60>=0也是恒真的了),调用purge_logs_before_date(purge_time), purge_logs_before_date会从log index文件中的第一个binlog文件开始循环: 比较文件的最后修改时间,如果小于purge_time,就放入数组to_log中。然后调用purge_logs,清理所有满足条件的binlog。

int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time) { ...   MY_STAT stat_area; ...   pthread_mutex_lock(&LOCK_index);   to_log[0]= 0;   if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/)))     goto err;    while (strcmp(log_file_name, log_info.log_file_name) &&   !is_active(log_info.log_file_name) &&          !log_in_use(log_info.log_file_name))   { ...       if (stat_area.st_mtime < purge_time)          strmake(to_log,                  log_info.log_file_name,                  sizeof(log_info.log_file_name) - 1);       else         break; ...    }

       下面看一下purge_logs的实现:

int MYSQL_BIN_LOG::purge_logs(const char *to_log,                            bool included,                           bool need_mutex,                            bool need_update_threads,                            ulonglong *decrease_log_space) { ...   while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) &&          !is_active(log_info.log_file_name) &&          !log_in_use(log_info.log_file_name))   {     if ((error= register_purge_index_entry(log_info.log_file_name))) ...   } ...   /* We know how many files to delete. Update index file. */   if ((error=update_log_index(&log_info, need_update_threads))) ...   /* Read each entry from purge_index_file and delete the file. */   if (is_inited_purge_index_file() &&       (error= purge_index_entry(thd, decrease_log_space, FALSE))) ...

 

        purge_logs会将需要清理的binlog文件名放入purge_index_file(IO_CACHE)中,然后更新index文件,最后再调用purge_index_entry删除binlog文件:

int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space,                                      bool need_mutex) { ...   for (;;)   { ...         if (!my_delete(log_info.log_file_name, MYF(0)))         {           if (decrease_log_space)             *decrease_log_space-= s.st_size;         } ... }

       my_delete调用unlink()删除binlog文件。至此,完成了自动清理binlog的过程。另外当mysql启动的时候,mysql也会执行purge_logs_before_date(purge_time)的过程(其它的操作,如果会引起binlog rotate,自然也会触发这个过程,如flush logs)。

       梳理一下整个过程,不难发现,在压力比较大的mysql上或生产环境,我们不应该启动这个参数(my.cnf中不显式设置该参数或设置expire_logs_days=0):mysql每天产生十几个或更多的binlog文件,启用这个参数后,一次清理这么多文件,必定会导致磁盘io被占满,mysql出现抖动或hang住。因此建议自己编写脚本,每次purge完一个binlog后,sleep几秒。

 

 

 

参考链接:

http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_expire_logs_days

http://dev.mysql.com/doc/refman/5.5/en/log-file-maintenance.html

http://www.mysqlinfo.com/2011/11/15/expire_logs_days%E8%AF%A5%E5%8F%82%E6%95%B0%E7%9A%84%E7%90%86%E8%A7%A3/

 

 

 

 


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:mysql expire_logs_days是如何生效的
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址