MySQL如何记录binlog

--MySQL如何记录binlog  

-------------------------------2014/07/08

binlog文件的内容 log event 

 

MySQL的binlog文件中记录的是对数据库的各种修改操作,用来表示修改操作的数据结构是Log event。不同的修改操作对应的不同的log event。比较常用的几种log event有:Query event、Row event、Xid event等。其中Query event对应的是一条SQL语句,在DDL操作和STMT格式的binlog中用的比较多。Row event是个基础类,它的派生类有Row insert event、Row update event、Row delete event三种,分别对应ROW格式binlog的增、改、删操作。Xid event 对应的是支持事务的commit操作,对于不支持事务的commit操作,记录的形式是Query event。其他还有一些event,比如Format log event、Rotate event等等,可以查看MySQL的官方文档了解更多相关信息。log event的种类一直在增加,比如InnoSQL中新增的checkpoint event等。要MySQL本身就留有接口以便新增一个Log event,但是新增一个Log event时需要实现几个必要的方法函数,比如print、write、get_code_type等。binlog文件的内容就是各种Log event的集合。

产生Log event

事务在执行DDL,或则update等操作时会记录操作的event到线程的cache_mngr中。

1,执行DDL操作会在db的操作函数中记录event,这些函数有:mysql_upgrade_db,mysql_alter_db,mysql_rm_db等。其他的DDL操作会调用函数write_bin_log来记录binlog。

2,执行修改操作的DML语句会根据binlog格式的不同做不同的操作。若binlog格式是STMT,则记录event的函数是binlog_query,该函数所做的事情是:

1,根据DML操作语句构造一个Query event:

Query_log_event qinfo(this,query_arg,query_len, ...)

2,将event写入缓存中

mysql_bin_log.write(&qinfo)

调用binlog_query的函数有:mysql_insert,mysql_delete,mysql_update等.

3,若binlog格式是ROW,修改操作的DML语句记录event的过程会调用binlog_log_row,每一条行的修改记录一个Row event,所以调用binlog_log_row

的都是对单个行进行修改的引擎层接口函数:ha_write_row、ha_update_row、ha_delete_row。

函数binlog_log_row会根据行操作的具体类型分别调用三个不同的函数:binlog_write_row、binlog_update_row、binlog_delete_row。

这三个函数的功能是:构造相应的Row event,并将行的数据写入到Row event中。

具体过程是:

binlog_write_row

1,binlog_prepare_pending_rows_event(table, server_id, cols,...);

2,ev->add_row_data(row_data, len);

binlog_update_row

1,ev= binlog_prepare_pending_rows_event(table, server_id, cols,...);

2,ev->add_row_data(before_row, before_size)

ev->add_row_data(after_row, after_size)

binlog_delete_row

1,ev= binlog_prepare_pending_rows_event(table, server_id, cols,...);

2,ev->add_row_data(row_data, len);

新构造的Row event会在下一次记录event的时候写入到线程的缓存区中。

IO_CACHE

写binlog的过程都是缓存写,使用的缓存结构是IO_CACHE。

cache_mngr,cache_data

事务在执行过程中产生log event,这些Log event记录在线程相关的一块缓冲区中,每一个事务线程都有这样一个缓存块(前提是事务开启了记录binlog的功能),这块缓存区的名称是binlog_cache_mngr,结构如下:

class binlog_cache_mngr {

binlog_cache_data stmt_cache; //不支持事务的存储引擎使用的binlog缓存区

binlog_cache_data trx_cache;  //支持事务的存储引擎使用的binlog缓存区

。。。

}

Log event保存在cache_mngr的缓存结构cache_data中,cache_data内有一个IO_CACHE缓存空间,Log event实际写入到这个IO_CACHE中binlog_cache_data的结构如下:

class binlog_cache_data{

IO_CACHE cache_log;

。。。

}

事务执行完一个修改操作后,写相应的Log event到线程缓存区的过程是:

1),获得线程的cache_mngr指针:

cache_mngr= (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);

2),获得cache_data缓存区的指针:

cache_data= cache_mngr->get_binlog_cache_data(use_trans_cache(thd, is_transactional));

3),将event写入到IO_CACHE中:

IO_CACHE *file= &cache_data->cache_log;

event->write(file);

写binlog

一个事务在提交阶段会将产生的log event写入到外部binlog文件中。不同事务以串行的方式将log event写入到外部binlog文件中,所以一个事务的所有log event在binlog文件中是连续的,中间不会插入任何其他事务的log event。MySQL整体是一个插件式的结构,binlog也是作为一个引擎插件被上层调用,事务提交的时候MySQL上层会依次调用事务所有引擎的提交接口,binlog的提交接口第一个被调用,然后再调用其它引擎的提交接口。所以事务提交的时候是先写binlog然后再进行底层引擎的提交过程(如InnoDB提交过程的写redo log和刷脏页)

MySQL如何记录binlog,布布扣,bubuko.com

时间: 2024-10-09 21:24:50

MySQL如何记录binlog的相关文章

MySQL从库记录binlog日志出错一例

昨天晚上学习视频"L11-16-配置MySQL从库记录binlog及其生产应用场景w",开头部分就卡住了. 在数据库的配置文件/data/3307/my.cnf里,开启参数"log-bin = /data/3307/mysql-bin",并增加"log-slave-updates"参数之后,重启数据库服务. 测试创建1个新库"create database oldgirl02;"之后,即使过滤新生成的logbin日志文件还是没

MySQL Row格式Binlog的解析(1)

用MySQL 行格式的复制的Slave经常会遇到复制出错1062和1032 错误,一般是镜像异常宕机导致主从复制数据不一致所致,但是有些库本身很大,重建成本很大,并且这些库的数据一致性用户可能都不是太关心的,所以之前的处理办法一般是遇到主键冲突的就跳过,遇到找不到key的就用mysqlbinlog解析一下 把数据补出来,但是这种方法太人肉话,处理起来很慢,所以之前做过一个自动修数据的工具,也是解析binlog日志,然后生成SQL语句去执行. 做这个工具还有另外一个用途,既然能解析BINLOG日志

mysql基于init-connect+binlog完成审计功能

mysql基于init-connect+binlog完成审计功能 目前社区版本的mysql的审计功能还是比较弱的,基于插件的审计目前存在于Mysql的企业版.Percona和MariaDB上,但是mysql社区版本有提供init-connect选项,基于此我们可以用它来完成审计功能. init-connect参数说明: http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_init_connect s

Mysql数据库之Binlog日志使用总结

binlog二进制日志对于mysql数据库的重要性有多大,在此就不多说了.下面根据本人的日常操作经历,并结合网上参考资料,对binlog日志使用做一梳理: 一.binlog日志介绍1)什么是binlogbinlog日志用于记录所有更新了数据或者已经潜在更新了数据(例如,没有匹配任何行的一个DELETE)的所有语句.语句以"事件"的形式保存,它描述数据更改. 2)binlog作用因为有了数据更新的binlog,所以可以用于实时备份,与master/slave主从复制结合. 3)和binl

mysql 5.6 binlog组提交实现原理

mysql 5.6 binlog组提交实现原理 http://blog.itpub.net/15480802/viewspace-1411356 Redo组提交 Redo提交流程大致如下 lock log->mutex write redo log buffer to disk unlock log->mutex fsync Fsync写磁盘耗时较长且不占用log->mutex,也就是其执行期间其他线程可以write log buffer: 假定一次fsync需要10ms,而写buffe

在Linux(CentOS)上安装MySql详细记录

前记:  毕业两年了,前两天换了份工作,由以前的传统行业跳到了互联网行业.之前的公司一直在用WinServer2003+Tomcat+SqlServer/Oracle这套部署环境.对于Linux+Tomcat(或其他容器)+Mysql这套之前没用用过.所以利用这周末的我在阿里云上49元搞了个linux(centos 64位)的服务器. 刚开始先装了JDK1.6,安装了Tomcat6.0.这过程中没有遇到太大的问题, 小问题也google一下就解决了.而周六晚上开始安装Mysql,于是到今天下午为

PHP获取MySql新增记录ID值的方法

今天发现用mysql_insert_id()获取到的新增记录的id不正确, 虽然发现源代码的事务写的有问题,但是最根本的原因是,我插入数据的id类型是bigint型 获取MySql新增记录ID值的方法有 1.使用语句 mysql_query("select max(id) from user",$link); 2.使用函数msyql_insert_id(); (1)mysql版 int mysql_insert_id ([ resource $link_identifier = NUL

让从库记录 binlog 日志

一.什么情况下从库需要记录 binlog 日志 (1) 在主从复制的级联架构下,从库既充当主库又充当从库(2) 在从库做数据库备份,数据库备份必须要有全备和 binlog 日志,才是完整的备份 二.如何让从库记录 binlog 日志 # 加入这些参数并重启服务 log-slave-updates log-bin = /data/3307/mysql-bin expire_logs_days = 7

MySQL问题记录--Can't connect to MySQL server on localhost (10061)解决方法

本文mysql的安装环境为win7 64位,mysql版本为MySQL5.7 问题描述:在命令行输入 mysql -u root -p 登录mysql,返回"Can't connect to MySQL server on localhost (10061)"错误 问题原因:在一番谷歌.百度后,查到问题原因是mysql没有启动. 解决方法:1.将mysql加入到Windows的服务中.切换到mysql安装目录下的bin文件夹,命令行运行"mysqld --install&qu