日志

分类

  1. 错误日志:记录系统启动,运行及停止过程中出现的问题。
  2. 普通日志:数据库执行的所有语句以及语句开始执行的时间等 。
  3. 慢日志:数据库所有满查询的相关的信息。
  4. 二进制日志:以事件的形式记录了数据库的库表结构以及表数据的所有变更信息。

二进制日志binlog

0:作用:复制和备份

  1. 结构:一系列binlog文件和一个index文件。
  2. index:记录当前使用了哪些binlog文件
  3. 数据库所有的变更信息以事件的形式记录在binlog文件中。
  4. binlog的格式: 1.STATEMENT 2. ROW 3. MIXED。
  5. binlog文件:一个4字节常量作为开头,后面跟着一系列的binlog事件。
  6. binlog事件:公有事件头,私有事件头和事件体3个部分组成。
    7.事件类型:
  • FORMAT_DESCRIPTION_EVENT ,
    定义为解析binlog中其他的事件,出现为第一个事件,仅出现一次。
  • QUERY_EVENT
    使用:1. 事务开始时,在bonlog中记录一个类型为QUERY_EVENT的BEGIN事件。
  1. 在STATEMENT格式的binlog中,具体执行的SQL语句保存在QUERY)EVENT事件中。
  2. 对于ROW格式的binlog中,所有的DDL操作以文本格式记录在QUERY_EVENT事件中。
  • ROWS_EVENT
    使用:
  1. 在STATEMENT格式的binlog中,增删改查的SQL语句保存在QUERY)EVENT事件中。
  2. 对于ROW格式的binlog中,对数据库的更改记录在QUERY_EVENT事件中。
  • TABLE_MAP_EVENT
    ROW格式的binlog文件中,每个ROWS_EVENT事件之前都有一个,用于描述表的内部id和结构定义。
  • XID_EVENT
    当提交事务时,表示事务的结束。在进行崩溃恢复是,根据在binlog中的提交情况来决定是否提交存储引擎种状态为presented的事务。
  • BINLOG_CHECKPOINT_EVENT
    用于崩溃恢复。当某个binlog文件内部的所有事务都在存储引擎内部提交,这时写入该事件;执行恢复时,根据所读取的该事件决定哪些
    binlog文件不用扫描。

binlog group commit技术

  1. 为了持久化操作,系统通过fynsc操作。但是fsync速度有限。
  2. 事务提交3个步骤
  • 事务在存储引擎准备好。处于准备状态的事务可以被回滚,也可以被提交。
  • 事务的所有修改写入binlog中并进行持久化。这一步完成后,当数据库恢复时,存储引擎准备好但是没有提交的事务可以通过binlog恢复。
  • 事务在存储引擎内部提交,这一步完成后对应的binlog对于恢复来说就没有意义了。

binlog group commit原理

  1. 核心思想:多个并发需要提交的事务之间共享一个fsync操作进行数据持久化。

数据结构

  1. bnlog_cache_mngr类
    事务在提交前,他对数据库的修改不会直接写入到binlog中,而是还存在这个类中;commit之后,才写入binlog中。
    位置://sql/loc.cc
  2. group_commit_entry结构
    位置://sql/log.h
    一个该结构体对饮即将写入binlog的一个事务,利用队列结构实现。

代码流程

  1. ha_commit_trans()
    负责:
    *. 事务在引擎内部准备好;
    *. 事务写入binlog中;
    *. 在引擎内部提交该事务。
  2. 事务写到binlog中, 调用 log_and_order()
  1. //sql/log.cc
  2. int MYSQL_BIN_LOG::log_and_order(THD *thd, my_xid xid,bool all.
  3. bool need_prepare_ordered __attribute__((unsed)),
  4. bool need_commit_ordered __attribute__((unsed)),
  5. // 参数:线程上下文;xid是该事务的id;all (true:表示这个事务是用户主要提交或者执行DDL被动提交)
  6. // 最后两个没有执行。

过程:
*. 获取该事务相关的binlog_cache_mngr结构。
*.写入某个binlog文件,调用binlog_commit_flush_xid_caches()函数;
*. 将写入某个binlog文件这一信息放入返回值。

  1. binlog_commit_flush_xid_caches()函数
  1. staticinlineint binlog_commit_commit_flush_xid_caches(THD *thd,
  2. binlog_cache_mngr *cache_mngr,bool all, my_xid xid);
  • xid不为空,一个xid事件作为事务的结束。
  • xid为空时,我们以一个内容为COMMIT的QUERY_EVENT事件来标记该事务结束。
  • 调用binlog_flush_cache() 将事务改写到binlog中。

binlog_flush_cache()

  1. binlog_flush_cache()

功能:

  • 在事务提交时,将还未写入到binlog_cache_mngr的内容全部写入到binlog_cache_mngr中
  • 调用MYSQL_BIN_LOG::write_transaction_to_binlog()函数将该事务产生的所有修改写入到binlog中。

MYSQL_BIN_LOG::write_transaction_to_binlog()

过程:
*. 将事务内容封装到group_commit_entry结构中
*. 调用write_transaction_to_binlog_events函数 写入binlog中。

MYSQL_BIN_LOG::write_transaction_to_binlog()

过程:

  • queue_for_group_commit函数将待提交到binlog的事务加入到组提交队列中。
  • 组提交队列的第一个事务作为leader线程,调用trx_group_commit_leader()函数,负责将该组所有事务提交,然后调用
    一次fsync()对binlog进行持久化,最后唤醒所有的follower线程继续往下执行。
  • 如果该事务被其他的事务所在的线程加入组提交队列中。详细处理下面介绍。

事务排队queue_for_group_commit()

功能:将事务加入到组提交队列中。

  1. // sql/log.cc
  2. MYSQL_BIN_LOG::queue_for_group_commit(group_commit_entry * orig_entry);
  • 等待其他事务提交完毕后才能提交;
  • 如果该事务已被其他的等待提交的事务提交队列中,直接返回;
  • 进入死循环,将事务加入组提交队列。
  • 处理等待当前组提交队列的所有事物。

leader 线程

组提交队列的第一个事务作为leader线程,调用trx_group_commit_leader()函数,负责将该组所有事务提交,然后调用
一次fsync()对binlog进行持久化,最后唤醒所有的follower线程继续往下执行。

trx_group_commit_leader()

  1. sql/log.cc
  2. voif MYSQL_BIN_LOG::trx_group_commit_leader(group_commit_entry *leader);
  • 判断binlog处于开启状态
  • 将队列中的事务按顺序写入binlog中的IO_CACHE缓存中。
  • 将IO_CACHE缓存内容刷新到biinlog中,并调用一次fsync操作对binlog进行持久化。
  • 写完之后,对binlog文件进行检查,是否需要新建文件。
  • 按照食物在binlog中的顺序调到存储引擎的commit_ordered接口,唤醒所有follower线程。





posted @ 2017-05-27 15:32  auyeungcarl  阅读(221)  评论(0编辑  收藏  举报