zoukankan      html  css  js  c++  java
  • MySQL purge log简单吗

    MySQL purge log简单吗?

    简单: purge log的功能很简单,purge master logs to 指定一个binlog,然后删除之前的文件系统上的binlog文件,并更新binlog.index文件。

    复杂: 需要保证purge的原子操作吗, 怎么保证, 有崩溃恢复吗?

    之前没有读过代码,想到代码实现上会遇到的问题:

    问题1:   如果删除文件比较多,怎么平衡加锁的时间?
    问题2:   怎么保证os文件删除和index文件的同步?
    问题3:   怎么保证index文件写入是完整的?
    问题4:   如果index更新了,文件没有删除,或者相反的情形发生会怎么样?
    问题5:   最后如何清理index文件的前面n个字节,然后更改文件大小?

    总体来说,也就是,在没有使用事务引擎来保证的一系列操作(purge log包括了多步操作),如何保证ACID或者进行了什么取舍?

    1. purge log的测试:

      purge master logs to 'binlog.000012';

    2. 主要的数据结构:

    typedef struct st_log_info
    {
    char log_file_name[FN_REFLEN];
    my_off_t index_file_offset, index_file_start_offset;
    my_off_t pos;
    bool fatal; 
    mysql_mutex_t lock;
    }

    3. purge的简略步骤: 

      

    step 1: 为命令行输入的binlog.000012补充目录成一个绝对路径文件。
           函数: MYSQL_BIN_LOG::make_log_name
          根据当前的log_file_name, 计算目录的长度,最后生成完整的to_log.

    step 2: 在binlog.index文件中查找binlog.000012文件。
          函数: find_log_pos: 如果没有找到这个文件,就报错。比如文本文件格式不对,就无法删除。

    step 3: 初始化index 文件的io cache。最终找到binlog.000012在index的位置。

    step 4: 创建purge index临时文件
          创建binlog.~rec~ 保存要删除的binlog文件。

    step 5: 重新init index_file, 从开始位置读取。匹配每一个binlog,写入到purge index file。

    step 6: 写入purge index file,并刷新
        1. 先flush io把在内存中的数据写入文件系统标准IO缓存。
        2. sync purge_index_file, 使用fdatasync。持久化到磁盘上。

    step 7: 更新index文件。
          1. mysql_file_seek,
          2. mysql_file_read,
          3. mysql_file_seek,
          4. mysql_file_write
            使用 1->2->3->4的时序删除文件的前n个字节。
          5. ftruncate改变index文件的大小

    step 8: 删除os上的文件,并删除purge index log临时文件

    4. 现在再来看看这些问题:

    问题1:
        binlog.index文件是share的,purge的整个过程如果一直锁住,那主库这时要flush log就无法获取锁。
        所以使用类似copy on write的策略,释放锁后,异步慢慢删除os上的文件。

        即保证了index文件的加锁完整写入,又没有长时间影响主库切换binlog日志。

    问题2:
        因为异步化了os文件删除动作,这里无法保证index文件记录删除和os文件删除的同步。这里依赖purge index file
        来完成同步和崩溃恢复。

    问题3: index文件的写入是无法保证一行是一个完整的binlog文件,这个依赖文件系统。
        但index文件是文本文件,当purge解析出错的时候,运维是可以修改这个文件来修复的。

        注:如果是二进制文件,这样取舍可行吗,恐怕要使用事务引擎来保证了。

    问题4:
        1. 如果index文件更新了,os文件没有删除
          当MySQL crash恢复的时候,会读取purge index file继续删除
        2. 如果文件删除,index文件没有更新
          从上面的步骤上看,不允许这中情况发生

    问题5:
        文件删除前面n字节的问题,本身可以使用另外一种策略,新建一个表,copy数据,rename。
        但binlog.index是share的,不允许在线rename,所以使用步骤7的过程,在一个file handler上完成。

    取舍: index file作为MySQL binlog文件的数据字典,首先要保证其数据的一致性,而os的文件是否能够删除可以进行取舍。

    不知道实现的时候觉得命令很简单。

    在想那些实现问题的时候,觉得又有点复杂。

    看了源码后,觉得是自己又想复杂了。

  • 相关阅读:
    oracle_jdbc_insert_into
    MySQL 性能比较测试:MySQL 5.6 GA -vs- MySQL 5.5
    centos去下载mysql应该怎么选择linux版本
    centos_radhat升级系统
    phpmyadmin 配置方法
    js 判断js函数,变量是否存在
    mysqlbinlog- 处理二进制日志文件的实用工具 学习笔记
    linux基本命令
    4 MySQL程序概述(包含mysql配置文件配置原理)-学习笔记
    Python学习笔记4 高级特性_20170618
  • 原文地址:https://www.cnblogs.com/xpchild/p/3811944.html
Copyright © 2011-2022 走看看