2. SHOW binlog EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]
下面来测试一下,在MysqL中执行如下操作
MysqL> flush logs; Query OK,0 rows affected (0.01 sec) MysqL> insert into test.t1 values(1,'a'); Query OK,1); font-weight: bold">1 row affected (0.00use test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MysqL2,1)">b show master status; +------------------+----------+--------------+------------------+-------------------+ | File | Position | binlog_Do_DB | binlog_Ignore_DB | Executed_Gtid_Set | | MysqL-bin.000021 | 546 | | | 1 row in set (0.00 sec)
对应二进制日志中的内容如下
# MysqLbinlog MysqL-bin.000021
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; !40019 SET @@session.max_insert_delayed_threads=0!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0; DELIMITER !;
# at 4 #160817 4:53:02 server id 1 end_log_pos 120 CRC32 0xf9bbe803 Start: binlog v 4,server v 5.6.31-log created 02 # Warning: this binlog is either in use or was not closed properly. binlog ' Ln2zVw8BAAAAdAAAAHgAAAABAAQANS42LjMxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAQPo u/k= '/*!*/;
# at 12006 server 195 CRC32 0x0182ee55 Query thread_id=3 exec_time=0 error_code=0 SET TIMESTAMP=1471380786; SET @@session.pseudo_thread_id=3; SET @@session.foreign_key_checks=1,@@session.sql_auto_is_null=0,@@session.unique_checks=1; SET @@session.sql_mode=1075838976; SET @@session.auto_increment_increment=!\C utf8 *//*; SET @@session.character_set_client=33,@@session.collation_connection=33; SET @@session.lc_time_names=; SET @@session.collation_database=DEFAULT; BEGIN 195298 CRC32 0xf9049380 Query thread_id=; insert into test.t1 values(a) 298329 CRC32 0xdb58b5b4 Xid = 25 COMMIT32915 server 408 CRC32 0xcc370a55 Query thread_id=1471380795408515 CRC32 0x4fa06a6e Query thread_id= use `test`; SET TIMESTAMP=2,1)">b515546 CRC32 0x5f51e8bd Xid = ;
DELIMITER ; # End of log file ROLLBACK added by MysqLbinlog !50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
解析如下:
1. at xxx,不仅仅是事件开始的位置,同样是二进制日志的物理大小
譬如上述日志中,结束位置是end_log_pos 546,则二进制日志的大小也是546.
2. at 4,对应的事件类型是FORMAT_DESCRIPTION_EVENT,是所有binlog文件中的第一个事件,在一个binlog中仅出现一次,MysqL会根据FORMAT_DESCRIPTION_EVENT事件的定义来解析binlog中的其它事件。该事件类型定义了binlog版本,MysqL Server的版本,binlog的创建时间等。
3. at 120,是第一个事务开始的偏移量,对应的事件类型是QUERY_EVENT,实际上也只执行了一个BEGIN操作。
# at */;
该事件对应的事件类型是QUERY_EVENT
QUERY_EVENT类型的事件通常在以下几种情况下使用。
1> 事务开始时的BEGIN操作
2> 对于STATEMENT格式的DML操作
3> 对于ROW格式的DDL操作。
该事件会指明server_id,slave_proxy_id(会话的线程id),execution time(查询从开始执行到记录到binlog所花的时间,单位为秒),error-code(错误码),status-vars(status-vars是以键值对的形式保存起来的一系列由SET命令设置的上下文信息,譬如当前的时间戳),schema(当前选择的数据库),query(原生的DML语句,譬如insert into test.t1 values(1,'a'))
5. 同样是insert操作,一个没有切换schema,直接执行insert into test.t1 values(1,'a'),一个是先use test,再执行insert操作,反映在binlog中的内容也不一样,实际上,这会影响基于库的部分复制的判断逻辑。
6. 在执行基于binlog的部分恢复时,截止的时间点应该是commit操作的end_log_pos,而不是commit操作之前的的at xxx。
譬如,针对上面的commit操作
# at */;
如果要执行第二个insert语句,则--stop-position=546,而不是515。
7. 在用MysqLbinlog查看binlog后都会带上ROLLBACK操作,这个在执行基于binlog的部分恢复时,会有用处。
# MysqLbinlog --stop-position=515 MysqL-bin.000021
.... # at ; DELIMITER ; # End of log */;
我只应用到binlog偏移量为515的位置,这个时候只有insert操作,而没有针对该操作的commit,所以MysqLbinlog会显式增加一个rollback操作,直接回滚事务。
通过SHOW binlog EVENTS查看
通过这种方式查看还是蛮直观的
MysqL> show binlog events in MysqL-bin.000021; ----------------+-----+-------------+-----------+-------------+-----------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | 4 | Format_desc | 1 120 | Server ver: 5.6.31-log,binlog ver: 4 | | Query 195 BEGIN 298 ') | Xid 329 COMMIT xid=25 */ 408 515 use `test`; ') xid=33 7 rows 0.00 sec)
事务的操作是何时写入到binlog中的?
MysqL使用binlog_cache_mngr结构来缓存一个事务的所有操作,如果用户执行commit操作,则将binlog_cache_mngr中的内容写入到binlog中;如果用户执行rollback操作,则直接丢弃binlog_cache_mngr中的内容。否则的话,如果事务中的操作立刻写入到binlog中,那么在回滚时就相当麻烦。
当时有一点需要注意的是,对于非事务的存储引擎,所有的修改会立刻写入到binlog中。
譬如下面的测试中,t_myisam是myisam表,t1是innodb表,在两张表中分别插入一条记录,再执行回滚。
MysqLset autocommit=0; Query OK,1); font-weight: bold">0.05into t_myisam 0.07into t1 4,1)">d0.06rollback0 rows affected,1); font-weight: bold">1 warning ( show warnings; -------+------+---------------------------------------------------------------+ Level | Code | Message | Warning 1196 Some non-transactional changed tables Couldnt be rolled back | +---------+------+---------------------------------------------------------------+
但通过查看binlog日志的内容,即便该事务回滚了,针对t_myisam表的操作还是写入到binlog中了
MysqL> show binlog events MysqL-bin.000017----------------+-----+-------------+-----------+-------------+------------------------------------------------+ | Info 000017 4 199 BEGIN 307 387 COMMIT 4 rows binlog的相关参数max_binlog_size
指定binlog文件的大小,如果当前binlog文件的大小达到了参数指定的阀值,则会创建一个新的binlog文件。
注意:binlog文件的大小可能会超过max_binlog_size的值,因为一个事务所产生的所有事件都必须要记录在同一个binlog文件中,所以即使binlog文件的大小超过max_binlog_size的值,也会等到当前事务的所有操作全部写入到binlog文件中才能切换。
sql_log_bin
会话变量,设置sql_log_bin=0表示禁用当前会话的binlog功能。
sync_binlog
MysqL 5.7.7之前,默认为0,即binlog文件在每次写入内容后并不会立即持久化到磁盘中,具体的持久化操作交给操作系统去处理。如果操作系统崩溃,可能导致对binlog的修改丢失。
为了避免这种情况,可将sync_binlog设置为1,这样在每次事务提交时,该事务的操作写入到binlog后,都会调用fsync操作将binlog的修改同步到磁盘中。但这样会降低MysqL的性能,所以可将sync_binlog设置为N,代表N个事务后才执行一次fsync操作。
实际上,在引入binlog group commit后,上述持久化的单位并不是事务了,而是一组事务。
官档解释如下:
Controls the number of binary log commit groups to collect before synchronizing the binary log to disk. When sync_binlog=disk,and when sync_binlog is set to a value greater than 0 this number of binary log commit groups is periodically synchronized to disk. When sync_binlog=hey are committed.
参考
1. MariaDB原理与实现
2. MysqL 5.7 Reference Manual
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。