目录
binlog篇
一,binlog相关sql命令
二,binlog相关的Linux命令
三,查看binlog内容
四,使用binlog恢复数据
五,在my.cnf文件中配置binlog
六,生成新的binlog文件
七,binlog的日志格式
八,关于binlog事件类型
九,关于事件event的组成
MySQL中的日志类型:
1,Error Log,错误日志。
2,General Query Log,查询日志,记录了每条sql的信息,包括查询和修改等,对性能影响比较大。
3,Slow Query Log,慢查询日志,记录查询比较慢的sql。可以设置阈值。
4,Binary Log,也就是binlog,二进制日志,归档日志,记录了数据库改动。包括建表,删表,数据修改等。
5,Redo Log,重做日志。用于恢复提交后的物理数据页。
6,Undo Log,回滚日志。用于回滚行记录到某个版本。
binlog记录的是数据库表结构变更(比如create table和alter table),以及行数据修改(比如update,insert)。
binlog产生于存储引擎的上层。
binlog由日志文件和索引文件组成。索引文件binlog.index记录了各个日志文件的位置和文件名:
1,是否开启了binlog
SHOW VARIABLES LIKE 'log_bin';
ON为开启,OFF为关闭
2,查看binlog文件格式
SHOW VARIABLES LIKE 'binlog_format';
3,查看binlog文件存放位置
SHOW VARIABLES LIKE 'datadir';
4,查看当前服务器binlog日志列表
SHOW binary logs;
5,查看主服务器binlog日志列表
SHOW MASTER logs;
6,查看当前正在使用的binlog日志状况
SHOW MASTER STATUS;
7,查看binlog的event内容
SHOW binlog events [in 'log_name'] [FROM pos] [LIMIT [offset,] row_count];
其中:
in,后面添加要查询的binlog文件名,默认是第一个binlog文件。
from,后面pos位置,默认是文件首个pos。
limit offset,偏移量,默认是0。
row_count,要查看的条数,默认查看所有event。
下面贴上两个sql的查询结果,可以比较一下这几个参数的功能:
第一个sql:
SHOW binlog events in 'binlog.000003' LIMIT 0,10;
查询结果:
第二个sql:
SHOW binlog events in 'binlog.000003' FROM 234 LIMIT 2,10;
查询结果:
在查询结果中的字段:
Log_name,是日志文件名
Pos,是事件起始位置
Event_type,是事件类型
Server_id,是服务器主机标识
End_log_pos,是下一个事件的起始位置
Info,是事件信息
1,导出binlog
mysqlbinlog --no-defaults --database=数据库名 --base64-output=decode-rows -v binlog.000003 > binlog000003.sql
2,按时间导出binlog
mysqlbinlog --no-defaults --database=数据库名 --base64-output=decode-rows -v --start-datetime='2020-08-20 16:00:00' --stop-datetime='2020-08-20 17:00:00' mysql-bin.000526 > binlog000526.sql
3,按位置导出binlog
mysqlbinlog --no-defaults --database=数据库名 --base64-output=decode-rows -v --start-position=123456 --stop-position=65321 mysql-bin.000526 > binlog000526.sql
参数说明:
--base64-output=decode-rows -v,把基于行的事件解码成sql语句
--base64-output=never,不显示binlog项,就是这样的日志:
BINLOG 'PR3yXQ8BAAAAeAAAAHwAAAABAAQAOC4wLjE4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9HfJdEwANAAgAAAAABAAEAAAAYAAEGggAAAAICAgCAAAACgoKKioAEjQACgEgSeVv'
--base64-output=always,只显示binlog项
--base64-output=auto,默认值,只对行事件和格式描述事件显示binlog项
--no-defaults,当在my.cnf中添加default-character-set=utf8mb4配置时,需要此参数以防止报错
--database,可以选择具体库名
--start-position,日志开始位置
--stop-position,日志结束位置
--start-datetime,日志开始时间,闭区间
--stop-datetime,日志结束时间,开区间
-o N,跳过前N个条目来显示
-j N,从编号为N的条目开始显示
-s或--short-form,只显示SQL
比如使用如下命令查看日志内容:
mysqlbinlog --no-defaults --database=jeecg-boot --stop-position 995 --base64-output=auto -v binlog.000003
节选其中一段日志:
# at 1218556
#200902 0:30:00 server id 1 end_log_pos 1218646 CRC32 0x48bf8dcf Query thread_id=7254 exec_time=0 error_code=0
SET TIMESTAMP=1598977800/*!*/;
BEGIN
/*!*/;
# at 1218646
#200902 0:30:00 server id 1 end_log_pos 1218739 CRC32 0x2782eb31 Table_map: `jeecg-boot`.`medicine_control` mapped to number 116
# at 1218739
#200902 0:30:00 server id 1 end_log_pos 1218915 CRC32 0xab939443 Update_rows: table id 116 flags: STMT_END_F
### UPDATE `jeecg-boot`.`medicine_control`
### WHERE
### @1='1266330645672103938'
### @2='爷爷'
### @3='某某'
### @4=0
### @5=2
### @6=0
### @7='liyan'
### @8='2020-05-29 19:28:48'
### @9='job'
### @10='2020-09-01 00:30:00'
### SET
### @1='1266330645672103938'
### @2='爷爷'
### @3='某某'
### @4=0
### @5=2
### @6=0
### @7='liyan'
### @8='2020-05-29 19:28:48'
### @9='job'
### @10='2020-09-02 00:30:00'
# at 1218915
#200902 0:30:00 server id 1 end_log_pos 1218946 CRC32 0x60622100 Xid = 5710556
COMMIT/*!*/;
解读一下其中的部分内容:
第一行的 # at 1218556,位于文件中的位置,说明该事件记录从文件第1218556个字节开始。
第二行的 # 200902 0:30:00,事件发生的时间戳。
server id 1,标识主机id。
end_log_pos 1218646,代表下一个事件的开始位置。
CRC32 0x48bf8dcf,binlog文件完整性校验。
Query,事件类型。
thread_id=7254,代理线程id。
exec_time=0,事件执行的花费时间。
error_code: 错误码,0表示没有错误。
BEGIN,事务开始。
@1='1266330645672103938',其中的@1代表第一列。
Xid = 5710556,事务id。
COMMIT,事务提交。
可以使用如下命令,指定binlog文件并重新执行binlog中记录的sql:
mysqlbinlog mysql-bin.000536 | mysql -uroot -proot
注意binlog文件是有顺序的,需要用多个文件恢复数据时,要按照binlog的时间依次恢复。
1,设置日志格式
binlog_format = mixed
2,设置日志路径
log-bin = /data/mysql/logs/mysql-bin.log
3,设置binlog清理时间(天数)
expire_logs_days = 7
4,binlog每个日志文件大小
max_binlog_size = 100m
默认1G,最大也是1G,最小4096字节
如果最后一条日志很大,整个文件可能略大于1G。
5,binlog缓存大小
binlog_cache_size = 4m
默认32K,每个线程单独分配内存空间
6,最大binlog缓存大小
max_binlog_cache_size = 512m
7,binlog刷盘机制,内存中的日志何时写入磁盘
sync_binlog=0
设为0表示由系统决定,效率较高。
设为正整数N表示每N次事务提交就写入磁盘。
以下场景会产生新的binlog文件
1,MySQL停止或重启。
2,执行flush logs命令
3,binlog文件大小超过max_binlog_size配置。
binlog有三种日志格式:Statement,Row,Mixed,分别介绍一下:
1,Statement,基于SQL语句,记录的是SQL本身,不会记录每一行的具体变化。
这是5.7.7之前的默认格式。
优点是节约空间(相比Row格式),性能略好。
缺点是遇见sysdate()之类的函数时,会多记录一些信息,以保证主从一致性。
2,Row,不记录具体sql,只保存哪行记录被修改成什么值。
这是5.7.7及以后的默认格式。
5.1.5版本开始支持。
优点是复制时能保证一致性。
缺点是日志量太大。
3,Mixed,此格式是Statement和Row格式的结合,一般语句就用Statement格式记录SQL,遇见sysdate()之类影响主从复制的情况就用Row格式保存行修改信息。
5.1.8版本开始支持。
列举一部分事件类型
1,QUERY_EVENT
记录一条query语句,在基于语句的复制和基于行的复制都会有。
2,ROTATE_EVENT
二进制日志更换一个新文件,可能因为文件大小达到限制,或者是mysql重启,亦或者是调用了flush logs命令。
3,XID_EVENT
Commit事件
4,WRITE_ROWS_EVENT, UPDATE_ROWS_EVENT, DELETE_ROWS_EVENT
统称为ROW EVENT, 只有在基于row的复制方式下才会产生。
WRITE_ROWS_EVENT:包含了要插入的数据
UPDATE_ROWS_EVENT:包含了修改前的值,也包含了修改后的值
DELETE_ROWS_EVENT:包含了需要删除行前的值
5,TABLE_MAP_EVENT
ROW EVENT之前产生,为的是对ROW EVENT解析提供依据。
6,FORMAT_DESCRIPTION_EVENT
MySQL根据其定义来解析其他事件
7,INTVAR_EVET
在statement时使用到,用于自增类型auto_increment.
8,STOP_EVENT
MySQL停止时,在文件尾加入STOP_EVENT
event的组成经历了v1到v4,四个版本,MySQL5.0以上都是使用v4,下面以v4为例。
event由event header和event body组成。
event header有19字节,其中包括:
- timestamp,4字节,时间戳
- event_type,1字节
- server_id,4字节,源serverid
- event_size,4字节,event包大小
- log_pos,4字节,下个event包的偏移量
- flags,2字节
- extra_headers,预留字段
event body组成如下:
- binlog-version,2字节,binlog文件版本号
- mysql-server version,50字节,MySQL服务器版本号
- create_timestamp,4字节,创建时时间戳
- event_header_length,1字节,时间头长度,一直是19
本文完