一 前言

bin log 是 MySQL 的一种二进制日志,记录引起或可能(更新删除没有匹配的记录)引起数据库变动的事件信息。

bin log 以事件形式记录,不是事务日志。对于非事务表的操作,每当语句执行完成则直接写入;对于事务表的操作则会在事务提交时(先记录到缓存中)一次性写入。

二 用途

主要用于数据备份和恢复、主从同步、审计、数据异构、基于数据的任务分发等等。

2.1 主从同步

slave 从服务器 I/O 线程将主服务器的二进制日志读取过来记录到从服务器本地文件,然后SQL线程会读取 relay log 日志的内容并应用到从服务器,从而使从服务器和主服务器的数据保持一致。

2.2 数据异构

把数据按需(数据结构、存取方式、存取形式)异地构建存储。

2.3 基于数据的任务分发

多服务依赖相同数据而不侵占其他服务的实现。

三 开启 binlog

MariaDB/MySQL默认没有启动二进制日志,要启用二进制日志使用 --log-bin=[on|off|file_name] 或配置文件中 log-bin=[on|filename]选项指定。

如果没有给定file_name,则默认为datadir下的主机名加"-bin",并在后面跟上一串数字表示日志序列号,如果给定的日志文件中包含了后缀(logname.suffix)将忽略后缀部分。

mysqld 会创建一个二进制日志索引文件,当二进制日志文件滚动的时候会向该文件中写入对应的信息。所以该文件包含所有使用的二进制日志文件的文件名。

默认情况下该文件与二进制日志文件的文件名相同,扩展名为’.index’。要指定该文件的文件名使用 --log-bin-index[=file_name] 选项。

当 mysqld 在运行时不应手动编辑该文件,免得 mysqld 变得混乱或重启失败。

-rw-r-----  1 mysql mysql       340 Jun 26 09:25 bin-log.000003
-rw-r-----  1 mysql mysql        17 Jun 26 09:25 bin-log.index
  1. 最大值通过变量 max_binlog_size 设置(默认值为1G)。但由于二进制日志可能是基于事务来记录的(如innodb表类型),而事务是绝对不可能也不应该跨文件记录的,如果正好二进制日志文件达到了最大值但事务还没有提交则不会滚动日志,而是继续增大日志,所以 max_binlog_size 指定的值和实际的二进制日志大小不一定相等。
  2. 出于安全和性能考虑,极不建议将二进制日志和datadir放在同一磁盘上。

四 查看 binlog

MySQL 中查看二进制日志的方法主要有几种。

4.1 mysqlbinlog 命令

格式:mysqlbinlog [option] log-file1 log-file2…

# 常用选项-d,--database=name:只查看指定数据库的日志操作
-o,--offset=#:忽略掉日志中的前n个操作命令
-r,--result-file=name:将输出的日志信息输出到指定的文件中,使用重定向也一样可以。
-s,--short-form:显示简单格式的日志,只记录一些普通的语句,会省略掉一些额外的信息如位置信息和时间信息以及基于行的日志。可以用来调试,生产环境千万不可使用
--set-charset=char_name:在输出日志信息到文件中时,在文件第一行加上set names char_name
--start-datetime,--stop-datetime:指定输出开始时间和结束时间内的所有日志信息
--start-position=#,--stop-position=#:指定输出开始位置和结束位置内的所有日志信息
-v,-vv:显示更详细信息,基于row的日志默认不会显示出来,此时使用-v或-vv可以查看

在一个新开的实例中创建一个 test 数据库、test 数据表并插入一条数据为例子查看 bin log 记录情况。

root@565bf1f8399a:/var/lib/mysql# mysqlbinlog bin-log.000002
/*!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 /*!*/;1. 初始信息,可以看到记录了时间和位置信息(at 4)。# at 4
#220626  9:43:32 server id 1  end_log_pos 256 CRC32 0x1485ea02  Start: binlog v 4, server v 10.5.12-MariaDB-1:10.5.12+maria~focal-log created 220626  9:43:32 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
RCq4Yg8BAAAA/AAAAAABAAABAAQAMTAuNS4xMi1NYXJpYURCLTE6MTAuNS4xMittYXJpYX5mb2Nh
bC1sb2cAAAAAAAAAAABEKrhiEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAEEwQADQgICAoKCgEC6oUU
'/*!*/;
# at 256
#220626  9:43:32 server id 1  end_log_pos 299 CRC32 0x6468dccc  Gtid list [0-1-6]
# at 299
#220626  9:43:32 server id 1  end_log_pos 340 CRC32 0x418a9234  Binlog checkpoint bin-log.000002
# at 340
#220626  9:44:47 server id 1  end_log_pos 382 CRC32 0x5ad3b3b6  GTID 0-1-7 ddl
/*!100101 SET @@session.skip_parallel_replication=0*//*!*/;
/*!100001 SET @@session.gtid_domain_id=0*//*!*/;
/*!100001 SET @@session.server_id=1*//*!*/;
/*!100001 SET @@session.gtid_seq_no=7*//*!*/;
# at 382
#220626  9:44:47 server id 1  end_log_pos 471 CRC32 0xd1fa3319  Query   thread_id=4    exec_time=0    error_code=0
SET TIMESTAMP=1656236687/*!*/;
SET @@session.pseudo_thread_id=4/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1, @@session.sql_if_exists=0/*!*/;
SET @@session.sql_mode=1411383296/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8mb4 *//*!*/;
SET @@session.character_set_client=45,@@session.collation_connection=45,@@session.collation_server=45/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;2. 创建 test 数据库。
CREATE DATABASE `test`
/*!*/;
# at 471
#220626  9:45:20 server id 1  end_log_pos 513 CRC32 0x54820548  GTID 0-1-8 ddl
/*!100001 SET @@session.gtid_seq_no=8*//*!*/;
# at 513
#220626  9:45:20 server id 1  end_log_pos 711 CRC32 0x408eb615  Query   thread_id=4    exec_time=0    error_code=03. 创建 test 数据表。
use `test`/*!*/;
SET TIMESTAMP=1656236720/*!*/;
CREATE TABLE `test`.`test`  (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(255) NOT NULL DEFAULT '',PRIMARY KEY (`id`)
)
/*!*/;
# at 711
#220626  9:45:46 server id 1  end_log_pos 753 CRC32 0x29248341  GTID 0-1-9 trans
/*!100001 SET @@session.gtid_seq_no=9*//*!*/;开启事务
START TRANSACTION
/*!*/;
# at 753
#220626  9:45:46 server id 1  end_log_pos 785 CRC32 0x1538c98f  Intvar自增锁
SET INSERT_ID=1/*!*/;
# at 785
#220626  9:45:46 server id 1  end_log_pos 903 CRC32 0xb1a7f07c  Query   thread_id=4    exec_time=0    error_code=0
SET TIMESTAMP=1656236746/*!*/;
4. 插入一条数据
INSERT INTO `test`.`test`(`name`) VALUES ('测试')/*!*/;
# at 903
#220626  9:45:46 server id 1  end_log_pos 934 CRC32 0x503162f1  Xid = 51
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

4.2 show binary logs

用于查看当前使用了哪些二进制日志文件。

  1. cat mysql-bin.index
  2. show {binary | master} logs

4.3 show binlog events

用于查看日志中进行了哪些操作,show binlog events in ‘bin-log’;

mysql> show binlog events in 'bin-log.000002';
+----------------+-----+-------------------+-----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name       | Pos | Event_type        | Server_id | End_log_pos | Info                                                                                                                                            |
+----------------+-----+-------------------+-----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------+
| bin-log.000002 |   4 | Format_desc       |         1 |         256 | Server ver: 10.5.12-MariaDB-1:10.5.12+maria~focal-log, Binlog ver: 4                                                                            |
| bin-log.000002 | 256 | Gtid_list         |         1 |         299 | [0-1-6]                                                                                                                                         |
| bin-log.000002 | 299 | Binlog_checkpoint |         1 |         340 | bin-log.000002                                                                                                                                  |
| bin-log.000002 | 340 | Gtid              |         1 |         382 | GTID 0-1-7                                                                                                                                      |
| bin-log.000002 | 382 | Query             |         1 |         471 | CREATE DATABASE `test`                                                                                                                          |
| bin-log.000002 | 471 | Gtid              |         1 |         513 | GTID 0-1-8                                                                                                                                      |
| bin-log.000002 | 513 | Query             |         1 |         711 | use `test`; CREATE TABLE `test`.`test`  (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(255) NOT NULL DEFAULT '',PRIMARY KEY (`id`)
) |
| bin-log.000002 | 711 | Gtid              |         1 |         753 | BEGIN GTID 0-1-9                                                                                                                                |
| bin-log.000002 | 753 | Intvar            |         1 |         785 | INSERT_ID=1                                                                                                                                     |
| bin-log.000002 | 785 | Query             |         1 |         903 | use `test`; INSERT INTO `test`.`test`(`name`) VALUES ('测试')                                                                                 |
| bin-log.000002 | 903 | Xid               |         1 |         934 | COMMIT /* xid=51 */                                                                                                                             |
+----------------+-----+-------------------+-----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------+# 可以指定起始位置。同样,起始位置必须指定正确,不能指定不存在的位置。mysql> show binlog events in 'bin-log.000002' from 711;
+----------------+-----+------------+-----------+-------------+-----------------------------------------------------------------+
| Log_name       | Pos | Event_type | Server_id | End_log_pos | Info                                                            |
+----------------+-----+------------+-----------+-------------+-----------------------------------------------------------------+
| bin-log.000002 | 711 | Gtid       |         1 |         753 | BEGIN GTID 0-1-9                                                |
| bin-log.000002 | 753 | Intvar     |         1 |         785 | INSERT_ID=1                                                     |
| bin-log.000002 | 785 | Query      |         1 |         903 | use `test`; INSERT INTO `test`.`test`(`name`) VALUES ('测试') |
| bin-log.000002 | 903 | Xid        |         1 |         934 | COMMIT /* xid=51 */                                             |
+----------------+-----+------------+-----------+-------------+-----------------------------------------------------------------+

4. show master status
用于显示主服务器中的二进制日志信息。如果是主从结构,它只会显示主从结构中主服务器的二进制日志信息。

可以查看到当前正在使用的日志及下一事件记录的开始位置,还能查看到哪些数据库需要记录二进制日志,哪些数据库不记录二进制日志。mysql> show master status;
+----------------+----------+--------------+------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+----------------+----------+--------------+------------------+
| bin-log.000002 |      934 |              |                  |
+----------------+----------+--------------+------------------+
1 row in set (0.00 sec)

五 刷新 binlog

可使用命令:mysqladmin -uroot -p refresh

六 删除 binlog

1. reset master
删除所有日志,并让日志文件重新从000001开始。

2. PURGE { BINARY | MASTER } LOGS { TO ‘log_name’ | BEFORE datetime_expr }
purge master logs to “binlog_name.00000X” 将会清空00000X之前的所有日志文件,正在使用中的日志文件中,将无法进行 purge。

1.例如删除000004之前的日志文件:

mysql> purge master logs to "mysql-bin.000004";

2.删除指定日期之前的所有日志:

purge master logs before '2022-06-25 12:36:40';

3. --expire_logs_days=N
使用–expire_logs_days=N选项指定过了多少天日志自动过期清空。

七 记录格式

MySQL 5.1之前,只有一种基于语句 statement 形式的日志记录格式。即将所有的相关操作记录为SQL语句形式。

但是这样的记录方式对某些特殊信息无法同步记录,例如uuid,now()等这样动态变化的值。

MySQL 5.1开始,MySQL支持 statement、row、mixed 三种形式的记录方式,由变量 binlog_format 来指定。

  1. row 形式是基于行来记录,也就是将相关行的每一列的值都在日志中保存下来,这样的结果会导致日志文件变得非常大,但是保证了动态值的确定性。 innodb引擎的创始人之一推荐使用row格式。
  2. mixed 形式,如何记录日志由MySQL自己来决定。

以本节第二小节内容为例,各种格式如下所示:

7.1 statement

7.2 row格式

记录内容不可直接阅读,需要加 -vv 选项。记录的非常详细,所以日志文件相对大。

7.3 mixed格式

默认会采用 statement 的方式记录,部分特殊情况会采用row的形式来记录日志。

  1. 存储引擎为NDB,对表的DML操作都会以row的格式记录。
  2. 使用了uuid()、user()、current_user()、found_rows()、row_count()等不确定函数。
  3. 使用了insert delay语句。
  4. 用了临时表。
mysqlbinlog mysql-bin.000001 -vv

八 刷新时机

事务执行过程中,先把日志写到 bin log cache,事务提交的时候,再把 bin log cache 写到 bin log 文件中。

一个事务的 bin log 不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为 bin log cache。刷盘流程如下:

需要注意上图中标红的两个写操作,设置不当可能导致日志丢失。两个写入时机由参数:sync_binlog 控制。

  1. sync_binlog=0 :每次提交事务都只写到 page cache,由系统自行判断什么时候执行fsync 到 binlog 文件。若机器宕机,page cache 里面的 binglog 会丢失。
  2. sync_binlog=1:每次提交事务都会执行 fsync,要保证事务的一致性和持久性的时候,必须将sync_binlog的值设置为1。
  3. sync_binlog=N(N >= 1):每次提交事务都只写到 page cache,但累积N个事务后才fsync。若机器宕机,page cache 里面的 N个事务的 binglog 会丢失。

九 相关参数

#指定是否启用记录二进制日志或者指定一个日志路径(路径不能加.否则.后的被忽略).
log_bin = {on | off | base_name} #指定是否启用记录二进制日志,只有在log_bin开启的时候才有效
sql_log_bin ={ on | off } #指定自动删除二进制日志的时间,即日志过期时间
expire_logs_days = #明确指定要记录日志的数据库
binlog_do_db = #指定不记录二进制日志的数据库
binlog_ignore_db = #指定mysql-bin.index文件的路径
log_bin_index = #指定二进制日志基于什么模式记录
binlog_format = { mixed | row | statement } # MySQL5.6.2添加了该变量,当binlog format为row时,默认不会记录row对应的SQL语句,设置为1或其他true布尔值时会记录,但需要使用mysqlbinlog -v查看,这些语句是被注释的,恢复时不会被执行。
binlog_rows_query_log_events = { 1|0 }#指定二进制日志文件最大值,超出指定值将自动滚动。但由于事务不会跨文件,所以并不一定总是精确。
max_binlog_size = #基于事务类型的日志会先记录在缓冲区,当达到该缓冲大小时这些日志会写入磁盘。
binlog_cache_size = 32768 #指定二进制日志缓存最大大小,硬限制。默认4G,建议不要改。
max_binlog_cache_size = #一般等同于且决定binlog_cache_size大小,所以修改缓存大小时只需修改这个而不用修改binlog_cache_size
binlog_stmt_cache_size = 32768#binlog_cache_size的值
binlog_stmt_cache_disk_use: #使用缓存写二进制日志的次数(这是一个实时变化的统计值)
binlog_cache_use:#使用临时文件写二进制日志的次数,当日志超过了binlog_cache_size的时候会使用临时文件写日志,如果该变量值不为0,则考虑增大binlog_cache_size的值。
binlog_cache_disk_use:#使用缓存写二进制日志的次数
binlog_stmt_cache_use:#使用临时文件写二进制日志的次数,当日志超过了binlog_cache_size的时候会使用临时文件写日志,如果该变量值不为0,则考虑增大#这个参数直接影响mysql的性能和完整性
sync_binlog = { 0 | n } sync_binlog=0: 不同步,日志何时刷到磁盘由FileSystem决定,这个性能最好。sync_binlog=n: 每写n次事务(注意,对于非事务表来说,是n次事件,对于事务表来说,是n次事务,而一个事务里可能包含多个二进制事件),MySQL将执行一次磁盘同步指令fdatasync()将缓存日志刷新到磁盘日志文件中。Mysql中默认的设置是sync_binlog=0,即不同步,这时性能最好,但风险最大。一旦系统奔溃,缓存中的日志都会丢失。要保证事务的一致性和持久性的时候,必须将sync_binlog的值设置为1。
因为每次事务提交都会写入二进制日志,设置为1就保证了每次事务提交时二进制日志都会写入到磁盘中,从而立即被从服务器复制过去。

要保证事务的一致性和持久性的时候,必须将sync_binlog的值设置为1。
因为每次事务提交都会写入二进制日志,设置为1就保证了每次事务提交时二进制日志都会写入到磁盘中,从而立即被从服务器复制过去。

十 恢复重做

指定二进制日志的起始位置(可指定终止位置)并将其保存到 sql 文件中,由 mysql 命令来载入恢复即可。当然也可以直接通过管道送给mysql。

基于位置来恢复还是基于时间点来恢复,这两种行为都可以。选择时间点来恢复比较直观些,并且跨日志文件恢复时更方便。

mysqlbinlog --stop-datetime="2022-06-25 12:17:44" /tmp/mysql-bin.000005 | mysql -u user -p password# 恢复多个二进制日志文件时:
mysqlbinlog mysql-bin.[*] | mysql -uroot -p password# 入到一个文件中后恢复。
mysqlbinlog mysql-bin.000001 > /tmp/1.sql
mysqlbinlog mysql-bin.000002 >>/tmp/2.sql
mysql -u root -p password -e "source /tmp/1.sql"

MySQL - binlog 图文详解相关推荐

  1. snort + barnyard2如何正确读取snort.unified2格式的数据集并且入库MySQL(图文详解)...

    不多说,直接上干货! 为什么,要写这篇论文? 是因为,目前科研的我,正值研三,致力于网络安全.大数据.机器学习研究领域! 论文方向的需要,同时不局限于真实物理环境机器实验室的攻防环境.也不局限于真实物 ...

  2. 【必知必会】手把手教你配置MySQL环境变量——图文详解

    一.先决条件 假设我们已经成功安装MySQL数据库.如果还有小伙伴不知道如何安装MySQL数据库,可以在本文下留言,留言数超20,则出一期"手把手教你安装MySQL数据库--图文详解&quo ...

  3. mysql拷贝文件安装_Mysql5.7.18的安装与主从复制图文详解

    CentOS6.7安装mysql5.7.18 1.  解压到/usr/local目录 # tar -zxvf mysql-5.7.18-linux-glibc2.5-i686.tar.gz -C /u ...

  4. mysql安装教程8.0.21安装_mysql8.0.21安装教程图文详解

    1.下载 下载链接 点击download,这里可能需要登录甲骨文的账号,登录一下即可 2.解压 下载好会得到一个安装包 把它解压到一个能找到的目录下即可,我的是这样(my.ini文件你们应该没有) 3 ...

  5. mysql 5.5.18下载_MySQL5.7.18下载和安装过程图文详解

    MySql下载 1.打开官网找到下载路口,这里直接给出下载的地址 2.选择64位版本 3.直接下载 MySql5.7.18.1安装过程 1   .运行安装软件,接受协议 2.选择默认安装 3.下一步到 ...

  6. mysql数据库主主_MySQL主主复制(图文详解)

    MySQL主主复制(图文详解) 发布时间:2020-07-12 23:10:25 来源:51CTO 阅读:218 作者:BonnieJason 一.实现原理 主主复制即在两台MySQL主机内都可以变更 ...

  7. MySQL Installer 8.0.21安装教程图文详解 转载

    MySQL Installer 8.0.21安装教程图文详解 原地址 1. 缘由 刚好需要在新系统上重新安装MySQL,便写了一份的下载安装教程,供查阅,以防日后细节有所遗忘. 2. 版本说明 MyS ...

  8. mysql 5.6 安装库_MySQL5.6安装步骤图文详解

    MySQL是一个开放源码的小型关系型数据库管理系统,目前MySQL被广泛地应用在Internet上的中小型网站中.由于其体积小.速度快.总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网 ...

  9. mysql8.0.20 64位安装教程_windows 64位下MySQL 8.0.15安装教程图文详解

    先去官网下载点击的MySQL的下载 下载完成后解压 解压完是这个样子 配置系统环境变量 复制解压后的mysql到C盘或者其他磁盘下 我们去系统的环境变量的path里添加一个mysql的配置  指向my ...

最新文章

  1. Python TypeError: ‘int‘ object is not iterable
  2. Java虚拟机new和newarray相关指令学习
  3. javax.websocket.DeploymentException: The path [webScoketServiceBaidu/{appID}] is not valid.
  4. JavaScript学习随记——面向对象编程(继承)
  5. echarts饼状图mysql_echarts饼状图位置设置
  6. java kryo register_java相关:Kryo框架使用方法代码示例
  7. 嫌Python太慢了?让Cython带你飙车吧
  8. Adobe 2022软件安装错误代码107解决办法
  9. Javascript 操作select控件大全(新增、修改、删除、选中、清空、判断存在等)...
  10. 如何在您的笔记本上搭建View 演示环境 -7.无线配置与连接
  11. 【车间调度】基于matlab改进的遗传算法求解车间调度问题【含Matlab源码 H002期】
  12. spring事务源码执行过程分析
  13. 为win10的todo应用配置altrun快捷键
  14. Linux中访问tomcat方式,linux软连接_Linux中为Tomcat启用软链接的三种方式
  15. 韩天峰php教程,韩天峰 - Swoole4-全新的PHP编程模式
  16. excel表格拆分多个表
  17. leetcode 栈739. 每日温度
  18. SCI、EI论文检索,引用格式
  19. 阿里云视觉AI训练营_Class3_文字识别项目讲解及使用说明
  20. 如何在日志中查找mysql日志临时密码_通过查询日志定位持有锁的SQL语句

热门文章

  1. 【JDBC上篇】什么是JDBC
  2. Doris安装问题记录连续更新
  3. [美国签证]准备材料及面签过程
  4. 计算机出现蓝屏怎么解决,电脑出现蓝屏,什么原因,怎么办?
  5. Java毕业设计_基于SSM的美食食谱分享网站的设计与实现
  6. 解决office2003,无法卸载也无法安装问题
  7. SQL Server中,备份数据表
  8. 3GPP 首个5G标准
  9. Linux驱动程序安装步骤
  10. 8051单片机Proteus仿真与开发实例-ULN2003A驱动步进电机仿真