MySQL二进制日志Binlog

一、MySQL  Binlog

 文件记录了mysql数据库所有的dml,ddl语句事件,不包括select,也可以记录SQL语句,也可以记录行的变化,还可以记录这些操作时间。

比如一条语句   update  t1  set  id=3 where id between 1  and 6;  加入他改了三行数据;

binlog记录的内容有可能是:

       1)可能是这条update语句;

       2)可能是修改的这三行数据;

       3)肯呢个两个都记录;

MySQL中三种日志的区别:

       1、general  log  :记录数据库里边所有SQL操作记录。

       2、redo  log : 知识记录innodb存储引擎级的修改日志。

       3、binlog:只记录数据库server层面内部的修改情况。select和show不记录

1.1 binlog的作用

      1) MySQL主从复制;

       2)数据恢复,如果宕机恢复,异常操作恢复;

      缺点: 大概损失1%的性能,占用空间。

1.2 binlog的三种工作模式

       1)row  level    日志记录每一行的修改情况。优点:可以更方便查看每一条数据修改情况,确定数据量比较大;

                使用场景:数据安全复制强一致;

       2) statement  level     记录每一条修改的SQL; 数据量量小;

                使用场景:使用mysql的功能较少,不适用存储过程,触发器较少

       3)混合模式  结合row 和statement

二 、 MySQL  binlog 二进制格式参数

binlog_format=row   (row,statement,mixed)

binlog_row_image=full   (full,minimal,noblob)

binlog_row_query_log_events=on  (on,off)

2.1  binlog_format=statement

先将binlog的格式设置为statement

mysql> set global binlog_format=statement;
Query OK, 0 rows affected (0.00 sec)

mysql> select @@global.binlog_format;
+------------------------+
| @@global.binlog_format |
+------------------------+
| STATEMENT              |
+------------------------+
1 row in set (0.00 sec)

mysql> 
mysql> set session binlog_format=statement;
Query OK, 0 rows affected (0.00 sec)

mysql> select @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| STATEMENT       |
+-----------------+
1 row in set (0.00 sec)

刷新日志,查看日志状态

mysql> flush logs;
Query OK, 0 rows affected (0.02 sec)

mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| BIN_LOG.000035 |      154 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

创建一个表,并插入数据:

mysql> create table yddl(id int,timepoint datetime not null default current_timestamp); 
Query OK, 0 rows affected (0.06 sec)
mysql> insert into yddl(id) values (1);
Query OK, 1 row affected (0.07 sec)

mysql> select * from yddl;
+------+---------------------+
| id   | timepoint           |
+------+---------------------+
|    1 | 2022-10-13 13:40:02 |
+------+---------------------+
1 row in set (0.01 sec)

查看日志的状态:

mysql> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File           | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| BIN_LOG.000035 |      656 |              |                  |                   |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

日志position从154变为了656,

进入日志目录,查看日志信息:

# cd /mysql/log/binlog/
[root@localhost binlog]# mysqlbinlog  --start-position=154 --stop-position=656 BIN_LOG.000035

日志都是以SQL语句形式记录DDL,DML操作

create table yddl(id int,timepoint datetime not null default current_timestamp)
/*!*/;
# at 368
#221013 13:40:02 server id 6  end_log_pos 433 CRC32 0x1398a8a9     Anonymous_GTID    last_committed=1    sequence_number=2    rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 433
#221013 13:40:02 server id 6  end_log_pos 516 CRC32 0x2298d420     Query    thread_id=3    exec_time=0    error_code=0
SET TIMESTAMP=1665639602/*!*/;
SET @@session.time_zone='SYSTEM'/*!*/;
BEGIN
/*!*/;
# at 516
#221013 13:40:02 server id 6  end_log_pos 625 CRC32 0xf1c535c7     Query    thread_id=3    exec_time=0    error_code=0
SET TIMESTAMP=1665639602/*!*/;
insert into yddl(id) values (1)

对主从复制的影响:

1)对有些参数,在不同服务器执行,结果不一样,会导致主从不一致,特别是一些系统函数,uuid(),user(),now()。

2)性能问题;

3)数据问题。

2.2  binlog_format=row   和 binlog_rows_query_log_events=off

mysql> set binlog_format=row;
Query OK, 0 rows affected (0.00 sec)
mysql> set global binlog_format=row;
Query OK, 0 rows affected (0.00 sec)
mysql> select @@session.binlog_format;
+-------------------------+
| @@session.binlog_format |
+-------------------------+
| ROW                     |
+-------------------------+
1 row in set (0.00 sec)

mysql> select @@global.binlog_format;
+------------------------+
| @@global.binlog_format |
+------------------------+
| ROW                    |
+------------------------+
1 row in set (0.00 sec)

修改表,观察日志的变化

mysql> create table yddl2(id int,timepoint datetime not null default current_timestamp);
Query OK, 0 rows affected (0.04 sec)

mysql> insert into yddl2(id) values (1);
Query OK, 1 row affected (0.01 sec)

执行一条update语句

mysql> update yddl2 set id=2 where id=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

查看日志中的记录

#221013 14:19:03 server id 6  end_log_pos 1141 CRC32 0x9ecde135     Update_rows: table id 226 flags: STMT_END_F

BINLOG '
161HYxMGAAAAMAAAAD0EAAAAAOIAAAAAAAEAAmpsAAV5ZGRsMgACAxIBAAEmnEkf
161HYx8GAAAAOAAAAHUEAAAAAOIAAAAAAAEAAgAC///8AQAAAJmuGuPs/AIAAACZrhrj7DXhzZ4=

ddl的记录是明文的,DML的记录是加密的(只记录行的操作,不记录SQL语句),针对加密的反解析,加参数-v

加参数:

[root@localhost binlog]# mysqlbinlog --base64-output=decode-rows -v  --start-position=154 --stop-position=1172 BIN_LOG.000036

观察日志的变化

# at 1355
#221013 14:36:50 server id 6  end_log_pos 1411 CRC32 0x83d5f8df     Update_rows: table id 226 flags: STMT_END_F
### UPDATE `jl`.`yddl2`
### WHERE
###   @1=2
###   @2='2022-10-13 14:15:44'
### SET
###   @1=5
###   @2='2022-10-13 14:15:44'
# at 1411
#221013 14:36:50 server id 6  end_log_pos 1442 CRC32 0xd3884a48     Xid = 57
COMMIT/*!*/;
# at 1442

binlog_format=row对主从的影响:

1)同步最安全;

2)不管是更新还是删除,或者批量操作,都是按照行进行,依次处理所有的记录,二不是整条SQL;

2.3  binlog_format=row  状态和  binlog_row_query_log_events=on 这样不仅可以记录行的变化,而且可以记录SQL语句

观察日志变化,日志更加详细。

## UPDATE `jl`.`yddl2`
### WHERE
###   @1=4 /* INT meta=0 nullable=1 is_null=0 */
###   @2='2022-10-13 15:01:36' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
### SET
###   @1=6 /* INT meta=0 nullable=1 is_null=0 */
###   @2='2022-10-13 15:01:36' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
# at 1115
#221013 15:02:12 server id 6  end_log_pos 1146 CRC32 0x143854f8     Xid = 74
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
mysql> show binlog events in 'BIN_LOG.000037';
+----------------+------+----------------+-----------+-------------+---------------------------------------+
| Log_name       | Pos  | Event_type     | Server_id | End_log_pos | Info                                  |
+----------------+------+----------------+-----------+-------------+---------------------------------------+
| BIN_LOG.000037 |    4 | Format_desc    |         6 |         123 | Server ver: 5.7.20-log, Binlog ver: 4 |
| BIN_LOG.000037 |  123 | Previous_gtids |         6 |         154 |                                       |
| BIN_LOG.000037 |  154 | Anonymous_Gtid |         6 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| BIN_LOG.000037 |  219 | Query          |         6 |         289 | BEGIN                                 |
| BIN_LOG.000037 |  289 | Rows_query     |         6 |         344 | # update yddl set id=4 where id=1     |
| BIN_LOG.000037 |  344 | Table_map      |         6 |         391 | table_id: 225 (jl.yddl)               |
| BIN_LOG.000037 |  391 | Update_rows    |         6 |         467 | table_id: 225 flags: STMT_END_F       |
| BIN_LOG.000037 |  467 | Xid            |         6 |         498 | COMMIT /* xid=70 */                   |
| BIN_LOG.000037 |  498 | Anonymous_Gtid |         6 |         563 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| BIN_LOG.000037 |  563 | Query          |         6 |         641 | BEGIN                                 |
| BIN_LOG.000037 |  641 | Rows_query     |         6 |         696 | # insert into yddl2(id) values(4)     |
| BIN_LOG.000037 |  696 | Table_map      |         6 |         744 | table_id: 226 (jl.yddl2)              |
| BIN_LOG.000037 |  744 | Write_rows     |         6 |         789 | table_id: 226 flags: STMT_END_F       |
| BIN_LOG.000037 |  789 | Xid            |         6 |         820 | COMMIT /* xid=72 */                   |
| BIN_LOG.000037 |  820 | Anonymous_Gtid |         6 |         885 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'  |
| BIN_LOG.000037 |  885 | Query          |         6 |         955 | BEGIN                                 |
| BIN_LOG.000037 |  955 | Rows_query     |         6 |        1011 | # update yddl2 set id=6 where id=4    |
| BIN_LOG.000037 | 1011 | Table_map      |         6 |        1059 | table_id: 226 (jl.yddl2)              |
| BIN_LOG.000037 | 1059 | Update_rows    |         6 |        1115 | table_id: 226 flags: STMT_END_F       |
| BIN_LOG.000037 | 1115 | Xid            |         6 |        1146 | COMMIT /* xid=74 */                   |
+----------------+------+----------------+-----------+-------------+---------------------------------------+
20 rows in set (0.01 sec)

2.4  binlog_row_image=full,minimal(默认),noblob

binlog_row_image=full,      insert/update语句的set部分是新记录,delete/update的where部分是全部的旧记录;

binlog_row_image=minial,   update语句只有修改的列内容,delete及update的where部分都没有(如果主键或唯一索引会有)

binlog_row_image=noblob ,  不记录

2.5   binlog_format=mixed   

大多数以statement记录binlog,当隔离级别为rc的时候,则为row的方式记录。

2.6  binlog过期清理天数

mysql> show variables like '%expire_log%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| expire_logs_days | 99    |
+------------------+-------+
1 row in set (0.00 sec)

手动清除日志,

mysql> purge binary logs to 'BIN_LOG.000004';   -----------清楚4之前的日志
Query OK, 0 rows affected (0.06 sec)

查看:

mysql> show binary logs;
+----------------+-----------+
| Log_name       | File_size |
+----------------+-----------+
| BIN_LOG.000004 |      1317 |
| BIN_LOG.000005 |       177 |

全部清除日志

mysql> reset master;
Query OK, 0 rows affected (0.00 sec)

mysql> show binary logs;
+----------------+-----------+
| Log_name       | File_size |
+----------------+-----------+
| BIN_LOG.000001 |       154 |
+----------------+-----------+
1 row in set (0.00 sec)

 2.7    show   binlog  events 查看日志

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 | 6 | 123 | Server ver: 5.7.20-log, Binlog ver: 4 |
| BIN_LOG.000002 | 123 | Previous_gtids | 6 | 154 | |
| BIN_LOG.000002 | 154 | Anonymous_Gtid | 6 | 219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| BIN_LOG.000002 | 219 | Query | 6 | 289 | BEGIN |
| BIN_LOG.000002 | 289 | Table_map | 6 | 336 | table_id: 109 (jl.yddl) |
| BIN_LOG.000002 | 336 | Delete_rows | 6 | 381 | table_id: 109 flags: STMT_END_F |
| BIN_LOG.000002 | 381 | Xid | 6 | 412 | COMMIT /* xid=24 */ |
+----------------+-----+----------------+-----------+-------------+---------------------------------------+

show    binlog  events参数:

1)in   ‘日志文件名’   不指定默认查看第一个日志文件

2)from   pos   指定其实日志的起始pos位置

mysql> show binlog events in 'BIN_LOG.000002' from 219;
+----------------+-----+-------------+-----------+-------------+---------------------------------+
| Log_name       | Pos | Event_type  | Server_id | End_log_pos | Info                            |
+----------------+-----+-------------+-----------+-------------+---------------------------------+
| BIN_LOG.000002 | 219 | Query       |         6 |         289 | BEGIN                           |
| BIN_LOG.000002 | 289 | Table_map   |         6 |         336 | table_id: 109 (jl.yddl)         |
| BIN_LOG.000002 | 336 | Delete_rows |         6 |         381 | table_id: 109 flags: STMT_END_F |
| BIN_LOG.000002 | 381 | Xid         |         6 |         412 | COMMIT /* xid=24 */             |
+----------------+-----+-------------+-----------+-------------+---------------------------------+
4 rows in set (0.00 sec)

3) limit  步长,查多少条记录

mysql> show binlog events in 'BIN_LOG.000002' from 219 limit 2;
+----------------+-----+------------+-----------+-------------+-------------------------+
| Log_name       | Pos | Event_type | Server_id | End_log_pos | Info                    |
+----------------+-----+------------+-----------+-------------+-------------------------+
| BIN_LOG.000002 | 219 | Query      |         6 |         289 | BEGIN                   |
| BIN_LOG.000002 | 289 | Table_map  |         6 |         336 | table_id: 109 (jl.yddl) |
+----------------+-----+------------+-----------+-------------+-------------------------+
2 rows in set (0.00 sec)

 2.8  mysqlbinlog查看二进制日志

 1)默认查看日志

[root@localhost binlog]# mysqlbinlog BIN_LOG.000004

2)指定数据库

[root@localhost binlog]# mysqlbinlog -d jl  BIN_LOG.000004>1.txt

  [root@localhost binlog]# mysqlbinlog --database jl BIN_LOG.000005>3.txt

 3)禁止恢复过程中产生日志,查看该日志的时候,不会产生新的日志,不会给该日志写如新的日志

[root@localhost binlog]# mysqlbinlog --disable-log-bin BIN.000005
[root@localhost binlog]# mysqlbinlog -D BIN.000005

4)最后一个日志文件

-t, --to-last-log   Requires -R. Will not stop at the end of the requested
                      binlog but rather continue printing until the end of the
                      last binlog of the MySQL server. If you send the output
                      to the same MySQL server, that may lead to an endless
                      loop.

 5)控制输出的编码格式

  --base64-output=name 
                      Determine when the output statements should be
                      base64-encoded BINLOG statements: 'never' disables it and
                      works only for binlogs without row-based events;
                      'decode-rows' decodes row events into commented
                      pseudo-SQL statements if the --verbose option is also
                      given; 'auto' prints base64 only when necessary (i.e.,
                      for row-based events and format description events).  If
                      no --base64-output[=name] option is given at all, the
                      default is 'auto'.
[root@localhost binlog]# mysqlbinlog --base64-output=decode-rows  -v BIN_LOG.000006

6)跳过行

[root@localhost binlog]# mysqlbinlog -o 10 BIN_LOG.000006

7)起始位置

[root@localhost binlog]# mysqlbinlog --start-position=123  --stop-position=289  BIN_LOG.000004

8)起始时间

[root@localhost binlog]# mysqlbinlog --start-datetime='2022-10-14 22:16:52'  BIN_LOG.000004

 

  

posted @ 2022-10-13 21:56  中仕  阅读(78)  评论(0编辑  收藏  举报