百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

Binlog实现MySQL复制,5个关键步骤,务必掌握!

wptr33 2025-03-13 21:05 16 浏览

复制是 MySQL 最重要的功能之一,MySQL 集群的高可用、负载均衡和读写分离都是基于复制来实现的。

Binlog 就是实现主从复制的关键主数据库将修改操作记录到 Binlog 中,从数据库通过解析 Binlog 实现数据的同步

从 MySQL 5.6 起,复制有两种实现方式:基于 Binlog 、或基于 GTID。

本文主要介绍基于 Binlog 的一主一从复制

大家好,我是爱分享的程序员宝妹儿,分享即学习。

本篇我们深入探讨:如何基于 Binlog 去实现 MySQL 复制。

这也是 MySQL 的重要知识点及高频面试点,宝妹儿顺便将这个题目以及答案,整理到2023版《MySQL 大厂高频面试题大全》PDF了,方便系统学习、面试通关。

宝妹儿精编的2023版《MySQL 大厂高频面试题大全》,已收录100+道真题,近30000字,长期迭代、持续更新。吃透它,应付MySQL面试没问题。

公号Java面试题宝,自取。

1. Binlog 复制是什么

在 MySQL 中,Binlog 复制是一种常见的数据库复制技术。

它允许将一个 MySQL 实例上的数据更改操作(写入、更新、删除等)复制到其它的 MySQL 实例上,从而实现数据的冗余备份负载均衡高可用性

除此之外,Binlog 复制还支持一些高级功能。例如:主从切换、多级复制和并行复制等,这些功能可以提供更高的可用性、可扩展性和性能。

2. Binlog 复制的过程

2.1 MySQL 主从复制中的几条主要线程

  • master(Binlog dump thread)
  • slave(I/O thread 、SQL thread)
  • Master 的一条线程
  • Slave 中的两条线程

2.2 Binlog 复制的过程

1)主服务器记录 Binlog

在主服务器上,开启了 Binlog 的功能,它将所有的数据更改操作以二进制格式记录到 Binlog 文件中。

每个 Binlog 文件都包含了一系列的事件,这些事件代表了数据库中执行的更改操作。

2)从服务器连接到主服务器

从服务器通过 MySQL 复制线程建立与主服务器的连接,这个连接通常称为复制通道。

从服务器使用主服务器的 IP 地址和端口号、用户名和密码等信息来连接主服务器。

3) 主服务器发送 Binlog 事件

一旦从服务器与主服务器建立连接,主服务器就开始将 Binlog 事件发送给从服务器。

主服务器会持续将新的Binlog事件发送给从服务器,直到从服务器告知主服务器它已经赶上了。

4) 从服务器应用 Binlog 事件

从服务器接收到 Binlog 事件后,它会按照事件的顺序将其应用于自身的数据库。

从服务器会将这些事件记录在自己的中继日志 Relay log 中,以备将来的从服务器复制。

5) 从服务器向主服务器发送确认信息

从服务器在应用 Binlog 事件后,向主服务器发送确认信息,告知主服务器它已经成功应用了这些事件。主服务器收到确认信息后,就知道从服务器已经完成了当前的复制操作。

6) 重复以上步骤

从服务器会不断地重复以上的步骤,从而实现与主服务器之间的持续复制。

主服务器记录新的 Binlog 事件,而从服务器持续地获取和应用这些事件,从而保持数据的一致性。

需要注意的是,Binlog 复制是异步的,即从服务器不会立即应用主服务器上的每个 Binlog 事件。这意味着在复制过程中,从服务器的数据可能会略有延迟,具体取决于复制的网络延迟和从服务器的处理能力。

Binlog 主从复制的实现步骤

为了便于理解,我们结合示例一起看。

1. 配置 master

主要包括设置复制账号,并授予 REPLICATION SLAVE 权限,具体信息会存储在于 master.info 文件中,然后开启 Binlog;

MySQL> CREATE USER 'test'@'%' IDENTIFIED BY '123456';
MySQL> GRANT REPLICATION SLAVE ON *.* TO 'test'@'%';
MySQL> show variables like "log_bin";
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | log_bin       | ON    |
    +---------------+-------+

查看 master 当前 BinlogMySQL 状态:

MySQL> show master status;

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| MySQL-bin.000003 |      120 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+

建表插入数据:

    CREATE TABLE `tb_person` (
	   `id` int(11) NOT NULL AUTO_INCREMENT,
       `name` varchar(36) NOT NULL,                           
       `address` varchar(36) NOT NULL DEFAULT '',    
       `sex` varchar(12) NOT NULL DEFAULT 'Man' ,
	   `other` varchar(256) NOT NULL ,
       PRIMARY KEY (`id`)
     ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
     
	 insert into tb_person  set name="name1", address="beijing", sex="man", other="nothing";
	 insert into tb_person  set name="name2", address="beijing", sex="man", other="nothing";
	 insert into tb_person  set name="name3", address="beijing", sex="man", other="nothing";
	 insert into tb_person  set name="name4", address="beijing", sex="man", other="nothing";

2. 配置 slave

Slave 需额外设置 relay_log 参数,slave 没有必要开启二进制日志。

如果 slave 为其它 slave 的 master,就要设置 bin_log。

3. 连接 master

MySQL> CHANGE MASTER TO
         MASTER_HOST='10.108.111.14',
         MASTER_USER='test',
         MASTER_PASSWORD='123456',
         MASTER_LOG_FILE='MySQL-bin.000003',
         MASTER_LOG_POS=120;

4. show slave status;

MySQL> show slave status\G
       *************************** 1. row ***************************
                      Slave_IO_State:   ---------------------------- slave io状态,表示还未启动
                         Master_Host: 10.108.111.14  
                         Master_User: test  
                         Master_Port: 20126  
                       Connect_Retry: 60   ------------------------- master宕机或连接丢失从服务器线程重新尝试连接主服务器之前睡眠时间
                     Master_Log_File: MySQL-bin.000003  ------------ 当前读取master Binlog文件
                 Read_Master_Log_Pos: 120  ------------------------- slave读取master Binlog文件位置
                      Relay_Log_File: relay-bin.000001  ------------ 回放Binlog
                       Relay_Log_Pos: 4   -------------------------- 回放relay log位置
               Relay_Master_Log_File: MySQL-bin.000003  ------------ 回放log对应maser Binlog文件
                    Slave_IO_Running: No
                   Slave_SQL_Running: No
                 Exec_Master_Log_Pos: 0  --------------------------- 相对于master从库的sql线程执行到的位置
               Seconds_Behind_Master: NULL
       Slave_IO_State, Slave_IO_Running, 和Slave_SQL_Running为NO说明slave还没有开始复制过程。

启动复制:

start slave

查看 slave 状态:

MySQL> show slave status\G
       *************************** 1. row ***************************
                      Slave_IO_State: Waiting for master to send event -- 等待master新的event
                         Master_Host: 10.108.111.14
                         Master_User: test
                         Master_Port: 20126
                       Connect_Retry: 60
                     Master_Log_File: MySQL-bin.000003
                 Read_Master_Log_Pos: 3469  ---------------------------- 3469  等于Exec_Master_Log_Pos,已完成回放
                      Relay_Log_File: relay-bin.000002                    ||
                       Relay_Log_Pos: 1423                                ||
               Relay_Master_Log_File: MySQL-bin.000003                    ||
                    Slave_IO_Running: Yes                                 ||
                   Slave_SQL_Running: Yes                                 ||
                 Exec_Master_Log_Pos: 3469  -----------------------------3469  等于slave读取master Binlog位置,已完成回放
               Seconds_Behind_Master: 0

如上,slave 的 I/O 和 SQL 线程都已经开始运行,并且Seconds_Behind_Master=0. Relay_Log_Pos 增加,意味着一些事件被获取并执行了。

那么,

怎样去判断 SLAVE 的延迟情况

slave 是否追上 master 的 Binlog

参考思路:

首先,查看下 Relay_Master_Log_File 和 Maser_Log_File 是否有差异。

  • 如果 Relay_Master_Log_File 和 Master_Log_File 一样,再来查看下 Exec_Master_Log_Pos 和 Read_Master_Log_Pos 的差异,对比 SQL 线程比 IO 线程慢了多少个 Binlog 事件。
  • 如果 Relay_Master_Log_File 和 Master_Log_File 不一样,延迟的可能就比较大了,可从 MASTER 上取得 Binlog status,判断当前的 Binlog 和 MASTER 上的差距。

以上都不能发现问题,我们还可以使用 pt_heartbeat 工具来监控主备复制的延迟。

5. 查询 slave 数据,主从一致

MySQL> select * from tb_person;
     +----+-------+---------+-----+---------+
     | id | name  | address | sex | other   |
     +----+-------+---------+-----+---------+
     |  5 | name4 | beijing | man | nothing |
     |  6 | name2 | beijing | man | nothing |
     |  7 | name1 | beijing | man | nothing |
     |  8 | name3 | beijing | man | nothing |
     +----+-------+---------+-----+---------+

总结

通过本文及示例,我们了解并掌握了基于 Binlog 实现 MySQL 主从复制的5个核心步骤。

主从复制有很多不同的复制策略,不同的复制策略,对不同的场景的适应性也是不同的,关于其他复制策略后续再更文补充。

我是爱分享的程序员宝妹儿,分享即学习。

如果觉得有用,请顺手【点赞】支持下哦,这将是对宝妹儿的最大鼓励,谢谢~

PS.

本文收录于宝妹儿精编的 2023版《MySQL 大厂高频面试题大全》PDF。

搞定这100道题,足以应对MySQL面试。

相关推荐

每天一个编程技巧!掌握这7个神技,代码效率飙升200%

“同事6点下班,你却为改BUG加班到凌晨?不是你不努力,而是没掌握‘偷懒’的艺术!本文揭秘谷歌工程师私藏的7个编程神技,每天1分钟,让你的代码从‘能用’变‘逆天’。文末附《Python高效代码模板》,...

Git重置到某个历史节点(Sourcetree工具)

前言Sourcetree回滚提交和重置当前分支到此次提交的区别?回滚提交是指将改动的代码提交到本地仓库,但未推送到远端仓库的时候。...

git工作区、暂存区、本地仓库、远程仓库的区别和联系

很多程序员天天写代码,提交代码,拉取代码,对git操作非常熟练,但是对git的原理并不甚了解,借助豆包AI,写个文章总结一下。Git的四个核心区域(工作区、暂存区、本地仓库、远程仓库)是版本控制的核...

解锁人生新剧本的密钥:学会让往事退场

开篇:敦煌莫高窟的千年启示在莫高窟321窟的《降魔变》壁画前,讲解员指着斑驳色彩说:"画师刻意保留了历代修补痕迹,因为真正的传承不是定格,而是流动。"就像我们的人生剧本,精彩章节永远...

Reset local repository branch to be just like remote repository HEAD

技术背景在使用Git进行版本控制时,有时会遇到本地分支与远程分支不一致的情况。可能是因为误操作、多人协作时远程分支被更新等原因。这时就需要将本地分支重置为与远程分支的...

Git恢复至之前版本(git恢复到pull之前的版本)

让程序回到提交前的样子:两种解决方法:回退(reset)、反做(revert)方法一:gitreset...

如何将文件重置或回退到特定版本(怎么让文件回到初始状态)

技术背景在使用Git进行版本控制时,经常会遇到需要将文件回退到特定版本的情况。可能是因为当前版本出现了错误,或者想要恢复到之前某个稳定的版本。Git提供了多种方式来实现这一需求。...

git如何正确回滚代码(git命令回滚代码)

方法一,删除远程分支再提交①首先两步保证当前工作区是干净的,并且和远程分支代码一致$gitcocurrentBranch$gitpullorigincurrentBranch$gi...

[git]撤销的相关命令:reset、revert、checkout

基本概念如果不清晰上面的四个概念,请查看廖老师的git教程这里我多说几句:最开始我使用git的时候,我并不明白我为什么写完代码要用git的一些列指令把我的修改存起来。后来用多了,也就明白了为什么。gi...

利用shell脚本将Mysql错误日志保存到数据库中

说明:利用shell脚本将MYSQL的错误日志提取并保存到数据库中步骤:1)创建数据库,创建表CreatedatabaseMysqlCenter;UseMysqlCenter;CREATET...

MySQL 9.3 引入增强的JavaScript支持

MySQL,这一广泛采用的开源关系型数据库管理系统(RDBMS),发布了其9.x系列的第三个更新版本——9.3版,带来了多项新功能。...

python 连接 mysql 数据库(python连接MySQL数据库案例)

用PyMySQL包来连接Python和MySQL。在使用前需要先通过pip来安装PyMySQL包:在windows系统中打开cmd,输入pipinstallPyMySQL ...

mysql导入导出命令(mysql 导入命令)

mysql导入导出命令mysqldump命令的输入是在bin目录下.1.导出整个数据库  mysqldump-u用户名-p数据库名>导出的文件名  mysqldump-uw...

MySQL-SQL介绍(mysql sqlyog)

介绍结构化查询语言是高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同数据库系统,可以使用相同...

MySQL 误删除数据恢复全攻略:基于 Binlog 的实战指南

在MySQL的世界里,二进制日志(Binlog)就是我们的"时光机"。它默默记录着数据库的每一个重要变更,就像一位忠实的史官,为我们在数据灾难中提供最后的救命稻草。本文将带您深入掌握如...