复制1-复制基础

线上必须设置为binlog_format = row,如果希望通过binlog实现flashback的功能(网易的mysqlbinlog -B ),则必须设置 binlog_row_image=FULL(默认),保证所有的列都出现在binlog中。(FULL对性能影响不大,仅仅对空间占用较多)

 

一. binlog

1. binlog格式

  • Table Map:记录了一些元数据,比如列的类型等等
  • 如果没有这个记录,就不知道第一列(@1)是哪个列,是什么类型等等信息
  • Rotate:binlog日志分割
  • Query:查询
  • Update/Write/Delete Rows:对行的操作

  • 命令 flush binary logs; 可以强制刷新binlog到磁盘,并且产生一个新的日志( 重启MySQL 也会产生新的日志)
  • 参数 max_binlog_size 可以设置一个binlog日志的最大的 大小 是多少(为了保证一个 事物在一个binlog 中,可能会超过该阈值)
[root@vm-1 mysql_data]# mysqlbinlog mysql-bin.000007 -vv
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
---
--- at后面的数字表示的是文件的偏移量,也就是常用的start-position
---

#230515  9:39:19 server id 11  end_log_pos 123 CRC32 0x34caff77         Start: binlog v 4, server v 5.7.9-log created 230515  9:39:19
---
--- 230515  9:39:19表示的是该event开始的时间,YYMMDD HH:MM:SS(如果是备机,就是传递到备机上的时间)
--- server id 表示MySQL服务器ID
--- end_log_pos 表示下一个event的position
---
# Warning: this binlog is either in use or was not closed properly.
BINLOG '
BzZiZA8LAAAAdwAAAHsAAAABAAQANS43LjktbG9nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
AXf/yjQ=
'/*!*/;
# at 123
#230515  9:39:19 server id 11  end_log_pos 154 CRC32 0x058b0d24         Previous-GTIDs
# [empty]
# at 154
#230515  9:41:27 server id 11  end_log_pos 219 CRC32 0x8e681f5c         Anonymous_GTID  last_committed=0        sequence_number=1
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 219
#230515  9:41:27 server id 11  end_log_pos 326 CRC32 0xfcdd6eab         Query   thread_id=2     exec_time=0     error_code=0
---
--- Query 表示事件的类型
--- thread_id 表示执行的线程ID
--- exec_time 表示执行的时间
--- error_code 表示执行的code,0表示没有错误
---
use `test`/*!*/;
SET TIMESTAMP=1684158087/*!*/;
SET @@session.pseudo_thread_id=2/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1142947840/*!*/;
SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=45/*!*/;
SET @@session.lc_time_names=0/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
create table test_2(a int, b int)
/*!*/;
# at 326
#230515  9:41:40 server id 11  end_log_pos 391 CRC32 0x31f68e24         Anonymous_GTID  last_committed=1        sequence_number=2
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 391
#230515  9:41:40 server id 11  end_log_pos 463 CRC32 0xa10cb0a4         Query   thread_id=2     exec_time=0     error_code=0
SET TIMESTAMP=1684158100/*!*/;
BEGIN
/*!*/;
# at 463
#230515  9:41:40 server id 11  end_log_pos 513 CRC32 0x42f9de02         Table_map: `test`.`test_2` mapped to number 111
# at 513
#230515  9:41:40 server id 11  end_log_pos 557 CRC32 0x72cb126e         Write_rows: table id 111 flags: STMT_END_F

BINLOG '
lDZiZBMLAAAAMgAAAAECAAAAAG8AAAAAAAEABHRlc3QABnRlc3RfMgACAwMAAwLe+UI=
lDZiZB4LAAAALAAAAC0CAAAAAG8AAAAAAAEAAgAC//wBAAAAAgAAAG4Sy3I=
'/*!*/;
### INSERT INTO `test`.`test_2`
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
###   @2=2 /* INT meta=0 nullable=1 is_null=0 */
---
--- 这些注释通过参数-vv获取,并不是SQL语句,而是row变化,TABLE-MAP的event记录了这些映射关系
---
# at 557
#230515  9:41:40 server id 11  end_log_pos 588 CRC32 0x69dd8a06         Xid = 17
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

 

2. binlog恢复

注意,如果你有多个binlog文件想要恢复,不要一个一个恢复

mysqlbinlog mysql-bin.000006 | mysql -uroot -p ## DENGER!!
mysqlbinlog mysql-bin.000007 | mysql -uroot -p ## DENGER!!

上面这种恢复方式是错误的,如果binlog.000006中创建了一个临时表(CREATE TEMPORARY TABLE),而 binlog.000007中要使用这个临时表,但是第一个线程(binlog.000001)在释放的时候会删除临时表,此时第二个线程(binlog.000007) 就无法使用这个临时表了。

正确的做法如下:

mysqlbinlog mysql-bin.000006 mysql-bin.000007 | mysql -uroot -p

## ---------------OR----------------

mysqlbinlog mysql-bin.000006 > temp.sql
mysqlbinlog mysql-bin.000007 >> temp.sql

## ---------------OR----------------

mysqlbinlog mysql-bin.00000[6-7] > temp.sql

 

注意:mysqlbinlog的参数start/stop-position不能是中间位置,必须是在binlog文件中at后面跟着的一个数字(必须是一个边界值)

参数start/stop-datetime可以通过时间戳来恢复

  • 基于position
mysqlbinlog mysql-bin.000007 --start-position=391 --stop-position=588 -vv > /tmp/a.sql
  • 基于datetime(需要再详细看看)
mysqlbinlog -vv --start-position=903965298 --stop-position=903965402 binlog.000013 > tmp.sql
mysql -u root -p < a.sql

start和stop的范围是 [start, stop)

 

-- 在mysql中查看events信息 (from pos limit N,[M])
[root@mysql.sock][test]> show binlog events in 'mysql-bin.000007' from 123 limit 5;
+------------------+-----+----------------+-----------+-------------+-----------------------------------------------+
| Log_name         | Pos | Event_type     | Server_id | End_log_pos | Info                                          |
+------------------+-----+----------------+-----------+-------------+-----------------------------------------------+
| mysql-bin.000007 | 123 | Previous_gtids |        11 |         154 |                                               |
| mysql-bin.000007 | 154 | Anonymous_Gtid |        11 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'          |
| mysql-bin.000007 | 219 | Query          |        11 |         326 | use `test`; create table test_2(a int, b int) |
| mysql-bin.000007 | 326 | Anonymous_Gtid |        11 |         391 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'          |
| mysql-bin.000007 | 391 | Query          |        11 |         463 | BEGIN                                         |
+------------------+-----+----------------+-----------+-------------+-----------------------------------------------+
5 rows in set (0.01 sec)

 

二. MySQL主从复制架构

  • 主服务器
    • 在 MySQL 5.7 版本中, prepare log 部分的日志也是 组提交 的
      • prepare log 和commit log 写redo file(iblogfile1、iblogfile2)
      • binlog 写binlig.00000X 文件
    • MySQL Dump Thread 把binlog推送到远程的Slave服务器
      • 每一个Slave,就会对应有一个dump线程
    • 同时,在MySQL主机上还有一个 Master Thread 在每隔1秒从redo log buffer中 写入redo file
  • 从服务器
    • IO Thread 负责接收Dump线程发送过来的binlog,并且记录到本地的relay log
      • 接受的 单位 是 event
    • SQL Thread/Coordinator Thread 负责将relay log中的日志回放到从机
      • 回放的 单位 也是 event
      • 有了多线程以后,coordinator线程负责任务指派,work thread负责回放
    • 在MySQL5.6 中的多线程回放是基于库的,单个库还是单线程
    • 在MySQL5.7 中的多线程是在主上如何并行执行的,从机上也是如何并行回放的
    • master-info.log 存放了接受到的binlog的位置(event的位置)
    • relay-info.log 存放了回放到的relay log的位置(event的位置)
posted @ 2023-05-15 22:41  BinBin-HF  阅读(66)  评论(0)    收藏  举报