Files
rikako-note/mysql/mysql文档/bin log.md
2024-09-20 20:07:38 +08:00

129 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

- [bin log](#bin-log)
- [Introduce](#introduce)
- [binary log构成](#binary-log构成)
- [binary log用途](#binary-log用途)
- [binary log variable](#binary-log-variable)
- [binlog\_encryption](#binlog_encryption)
- [log\_bin](#log_bin)
- [binlog\_checksum](#binlog_checksum)
- [binary log format](#binary-log-format)
- [mysqlbinlog](#mysqlbinlog)
- [sync\_binlog](#sync_binlog)
- [Binary Logging Format](#binary-logging-format)
- [STATEMENT](#statement)
- [ROW](#row)
- [MIXED](#mixed)
- [mysql表更新操作的binary log记录格式](#mysql表更新操作的binary-log记录格式)
# bin log
## Introduce
### binary log构成
binary log由一系列描述数据库变动的事件构成例如table creation操作或对table data进行的修改操作。
除上述对数据库造成修改的事件外binary log中还包含`可能会潜在对数据库造成修改的statement`所对应的事件例如一个没有匹配任何行的delete语句
binary log中还会包含每条statement更新数据所花费的时间。
### binary log用途
binary log用途主要用于如下方面
- `for replication`source replication server中的binary log提供了要发送给replicas的数据变动。source replication server会将binary log中包含的消息发送给replciasreplicas则是会重新执行这些变动。
- `for data recovery`某些data recovery操作需要使用binary log。当backup被恢复后需要对binary log中位于backup之后的时间进行重新执行操作
binary log不会记录`SELECT``SHOW`这些并不会对数据库数据进行修改的动作。如果想要对所有statement做记录需要使用general query log。
在运行mysql server时开启binary log通常会令性能有所降低但是能带来主从复制和数据恢复方面的好处。
binary log能兼容程序的意外中止只有已完成的event或transaction才能记录到binary log或从binary log中read back。
写入binary log中的statement如果包含密码密码将会被server重写binary log中不会出现密码的明文。
### binary log variable
#### binlog_encryption
binary log和relay log可以被加密用于保护这些日志文件的数据安全。可以通过`binlog_encryption`变量来设置binary log是否被加密。
#### log_bin
通过`log_bin`可以设置binary log是否被启用`log_bin`环境变量默认为`ON`,是启用的。
如果要在启动mysqld时禁用binary log可以在`my.cnf`中指定`skip-log-bin``disable-log-bin`
可以通过`--log-bin[=base_name]`来指定binary log file的base name。如果没有指定`--log-bin`选项那么base name默认为`binlog`binary log文件名为`binlog.xxxxx`
mysqld会在base name之后追加数字将其作为binlog的文件名称每次创建新的binlog文件时数字都会递增。mysqld会在如下场景下创建新的binlog文件
- mysql server执行`start``restart`操作
- server对log进行`flush`操作
- 当前log大小达到`max_binlog_size`的大小
如果在事务中写入大量数据那么binlog的大小可能会大于`max_binlog_size`因为同一个事务中的event只会被记录到一个binlog中不会写入到多个binlog中。
> #### binary log index
> 为了追踪当前mysql使用了哪些binary log文件mysqld创建了一个`binary log index`文件,其中包含了`binary log`文件的文件名。可以通过`--log-bin-index[=filename]`来指定`log index file`的名称。
#### binlog_checksum
默认情况下server在输出event到日志时会同时输出event的长度并且用event长度来校验是否输出正确。除此之外可以通过设置`binlog_checksum`来让server在输出event的同时输出event的checksum。在从binlog中read back时source默认会使用event length但是可以通过设置`source_verify_checksum`为启用来使用checksum。作为接收方的replica会校验从source接收到的event。
### binary log format
binary log中event目前支持三种格式
- row-based-logging
- statement-based-logging
- mixed-based-logging
### mysqlbinlog
当想要展示binary log文件中的内容时可以使用mysqlbinlog工具如果想要重新执行binlog中对应的statement该工具将十分有用。
```bash
mysqlbinlog /var/lib/mysql/binlog.000503 | less
```
通过上述命令可以查看binlog的内容。
可以通过如下命令来根据binlog内容更新数据库信息
```bash
mysqlbinlog log_file | mysql -h server_name
```
binary logging操作会在statement或transaction执行完成后立马被执行但是logging操作在`锁释放``commit提交`之前。这将会保证日志将会按照commit的顺序来打印。
对非事务引擎不支持事务的表进行操作在执行后会立即将log打印到binary log file中。
对于事务的表例如innodb在一个尚未提交的事务中所有更新操作update/insert/delete将会被缓存直到执行commit操作。在执行commit前会将缓存中的整个事务都写入到binary log中。
### sync_binlog
默认情况下在每次写操作后binary log都会被同步到磁盘中sync_binlog为1。如果`sync_binlog`没有被启用并且系统发生宕机那么位于binary log末尾的statements可能会丢失。为了保证不发生binlog文件丢失的情况`sync_binlog`会设置每经过`N`次commit group之后将binary log同步到disk中。
在早期的mysql版本中即使将`sync_binlog`设置为1也有可能发生table content和binlog content不一致的情况。在使用innodb tables并且mysql server处理了commit statement那么其会将所有prepared transactions按顺序写入到binary log并将binary log同步到disk中并且提交innodb事务。
但是,在`同步binary log到disk``提交innodb事务`之间server有可能会宕机在server重启之后transaction会被回滚但是事务对应event已经被写入到了binary log中此时会发生binary log和table content不一致的情况。
上述情况在之前的mysql发行版中已经被解决只需启用XA两阶段事务即可。在mysql 8.4中innodb针对两阶段提交的XA事务支持一直是被启用的。
Innodb在XA事务中对两阶段提交的支持确保了binary log和innodb data files的一致性。在innodb隐式支持了XA两阶段事务之后如果sync_binlog被设置那么当server崩溃后重启时会对未提交事务做回滚同时会扫描binlog中最后的部分来收集`xid`从而计算出binary log file中的`最后有效位置`。mysql server会告知innodb完成所有写入到binary log中的prepared transactions并且将binary log file截取到最后有效位置。这将会保证table content和binary log的一致性。
## Binary Logging Format
在binary log中会采用如下集中格式来记录消息
### STATEMENT
mysql中的复制功能最初是基于sql statement的传播sql statement将会从source实例发送到replica实例。这种行为被称作`statement-based logging`
在启动server时可以通过指定`--binlog-format=STATEMENT`来使用`statement-based logging`
### ROW
默认情况下,使用的是`row-based logging`。source实例会在`行数据如何被修改`的维度向binary log中写入事件。
在启动server时可以通过指定`--binlog-format=ROW`来使用`row-based logging`
### MIXED
在使用mixed-based logging时`statement-based logging`会被默认使用,但是遇到下列描述的场景时,会自动切换到`row-based-logging`
在启动server时可以通过指定`--binlog-format=MIXED`来使用`mixed-based logging`
随着使用的存储引擎不同logging format也会收到影响和限制。
### mysql表更新操作的binary log记录格式
对数据库中表数据的更改可以通过直接或间接的方式完成:
- 直接: `INSERT, UPDATE, DELETE, REPLACE, DO, LOAD DATA, SELECT, and TRUNCATE TABLE`
- 间接:`GRANT, REVOKE, SET PASSWORD, RENAME USER`
对于直接修改mysql表内容的语句`log format`将会基于`binlog_format`配置。
对于间接修改表内容的语句,将会忽略`binlog_format`配置,直接以`STATEMENT`的形式写入到binary log中。