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的文件是否能够删除可以进行取舍。

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

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

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

MySQL purge log简单吗,布布扣,bubuko.com

时间: 2024-10-06 05:31:35

MySQL purge log简单吗的相关文章

mysql slow log 简单统计

众所周知,mysql slow log中很多sql 语句结构和对象是相同,只是其中变量不一样,对于这样的sql,我们完全可以将其归为一类,统计其执行次数.执行时间平均值等参数,而pt-query-digest恰好就是这样一款工具,能够对slow sql 进行归类.分组和分析,统计同一类sql多次运行后的参数:max.min.avg.count等: # Query 6: 0.23QPS, 1.07x concurrency, ID 0x7F4D624CEA244E17 at byte 175919

清除mysql binary log

作为一个oracle dba有时候不得不管理一下mysql数据库,当为主从库时需要阶段性清理mysql binary log,清楚方式如下: 首先查看mysql 的当前日志组 show master status; 确定当前日志组后删除日志文件 purge binary logs to 'mysql-bin.000795'; 删除000795之前的日志 清除mysql binary log,布布扣,bubuko.com

进击的Python【第十二章】:mysql介绍与简单操作,sqlachemy介绍与简单应用

进击的Python[第十二章]:mysql介绍与简单操作,sqlachemy介绍与简单应用 一.数据库介绍 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据.我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢.所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理的大数据量.所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来

基于Servlet、JSP、JDBC、MySQL的一个简单的用户注册模块(附完整源码)

最近看老罗视频,做了一个简单的用户注册系统.用户通过网页(JSP)输入用户名.真名和密码,Servlet接收后通过JDBC将信息保存到MySQL中.虽然是个简单的不能再简单的东西,但麻雀虽小,五脏俱全,在此做一归纳和整理.下面先上源码: 一.index.jsp <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path =

python基于mysql实现的简单队列以及跨进程锁

在我们做多进程应用开发的过程中,难免会遇到多个进程访问同一个资源(临界资源)的状况,必须通过加一个全局性的锁,来实现资源的同步访问(同一时间只能有一个进程访问资源). 举个例子: 假设我们用mysql来实现一个任务队列,实现的过程如下: 1. 在Mysql中创建Job表,用于储存队列任务,如下: create table jobs( id auto_increment not null primary key, message text not null, job_status not null

谁记录了mysql error log中的超长信息

[问题] 最近查看MySQL的error log文件时,发现有很多服务器的文件中有大量的如下日志,内容很长(大小在200K左右),从记录的内容看,并没有明显的异常信息. 有一台测试服务器也有类似的问题,为什么会记录这些信息,是谁记录的这些信息,分析的过程比较周折. Status information: Current dir: Running threads: 2452  Stack size: 262144 Current locks: lock: 0x7f783f5233f0: Key c

mysql数据库很简单操作

进入linux系统 root   >/usr/bin/mysql -u root mysql>show databases;                    #查看数据库 mysql>use  testtable;                        #testtable 为所要查看的库,应用数据库 mysql>show tables;                          #查看所有表 mysql>desc abc_table          

Ubuntu Mysql 安装及简单使用

系统环境:ubuntu 12.04 1.安装 sudo apt-get install mysql-server sudo apt-get install mysql-client 安装过程中会提示设置密码,记住所设置的密码.该密码用于登录mysql数据库.安装成功后mysql服务器会自动启动 2. 检查是否成功安装 在终端中输入命令,sudo netstat -tap | grep mysql 若能看到mysql 端口处于监听状态则表示安装成功. 3.配置服务器 mysql的配置文件放在 /e

mysql中log

mysql的主从模式配置 1.改主库配置文件: [mysqld] log=c:/a.log log-bin=mysql-bin server-id=1 2.授权,导数据: grant replication slave on *.* TO 'replication'@'192.168.234.123' identified by 'replication'; mysqldump --master-data=2 --single-transaction -uroot -p --all-databa