Mysql之主从同步

news2024/10/5 16:10:16

1.BinLog同步机制

Mysql要去保证高可用,或者去分担请求压力,一般会去主从部署,读写分离。写库只负责写,而读库更多的去承担读的请求,从库不写数据,数据从主库同步,那么到底是怎么同步的呢?

同步,一定十把数据同步给从,它得有个载体,比如redis里面有rdb文件,在Mysql里面充当这个载体得就是BinLog.

BinLog又称二进制文件,属于Mysql Server层去记录得,所以,不管是什么存储引擎进行的数据存储,如果binLog开启,都会进行记录。

二进制日志包含描述数据库更改 ( 如表创建操作或表数据更改 ) 事件 。它还包含可能发生更改的语句的事件( 例如,不匹配任何行的 DELETE) ,二进制日志还包含关于每条语句花费更新数据的时间的信息。

只有完整的事件或事务才会被记录或回读。

但是,BinLog不用在非修改语句,比如SELECT、SHOW,如果需要查询这些日志,可以参考通用日志: MySQL :: MySQL 8.0 Reference Manual :: 7.4.3 The General Query Log

1.1 BinLog用途

a.主从复制

b.数据恢复

redoLog BinLog 都是去保证数据一致性的,但是 RedoLog innoDB 层面,并且是覆盖写的,所以不能保证全数据备份。
还有因为备份的方式不一样,一个是二进制日志, server 层去做的,一种是物理日志,InnoDB 做的,所以 BinLog 也替代不了 RedoLog

 1.2 BinLog配置

BinLog会有很多相关的配置,这些配置决定了要不要开启、以什么方式存储、存储在哪里等等!

show variables like '%log_bin%'; -- log_bin相关配置
log_bin -- 默认on 开启 可以对binlog进行关闭
log_bin_basename -- bin文件前缀 默认
/var/lib/mysql/mysql-bin
log_bin_index -- bin文件索引 /var/lib/mysql/mysql-bin.index

binlog_cache_size -- binlog日志 事务缓存大小
binlog_encryption -- 内容是否加密 我们的内容为了安全性可能需要加密
binlog_format -- binlog格式
binlog_expire_logs_seconds -- 多久后binlog删除 默认2592000s 也就是30天

1.3 BinLog格式

STATEMENT

基于语句记录,记录的是语句,后续去执行binLog的执行语句

比如:

update table set time=now() where id=1;

binlog就会记录这条语句,然后拿这条语句去执行。

问题: 有些场景,比如获取当前系统时间就会导致根据Binlog同步、恢复的数据跟之前的数据不一致。  因此,又有了Row的格式。

ROW

基于行格式记录,binlog记录的是单个表行是如何更改的

以刚才那个例子为例,会直接记录1这条数据改成了什么时间,并且能确定是哪条数据

update table set time=1675778373 where @1=1 and @2=.. and @3=...;

但是row格式的缺点是更加复杂,占用的空间比较大,恢复起来也相对来讲比较慢。

所以又有了一个折中的混合模式。混合模式就是去看下STATEMENT格式下会不会导致一致性问题,如果会,就用row,如果不会,就用STATEMENT

MIXED

混合模式,默认是语句,在下列场景下会切换成行模式

MySQL :: MySQL 8.0 Reference Manual :: 7.4.4.3 Mixed Binary Logging Format

1.4 查询BinLog

show master status; // 当前在写哪个binlog

知道了正在写哪个BinLog后,我们想去看下之前binLog的日志内容

[root@localhost mysql]# mysqlbinlog -vv --base64-output=decode-rows --database=zsc_edu --start-datetime='2023-02-05 00:00:00' mysql-bin.000003

指定编码格式,库名,开始时间和要查询的binlog文件名

1.5 BinLog同步机制 

binLog记录完整的日志,在开启事务后,事务语句中的二进制日志先放入内存缓存,这个内存缓存就是存储我事务没有提交的数据。具体缓存大小由binlog_cache_size设置(如果超过这个值,就会暂存到磁盘)。

show variables like '%binlog_cache_size%'; -- 事务期间用于保存二进制日志更改的内存缓冲区的大小。

commit的时候,会同步到文件系统缓存。那么为例性能与数据一致性方面的考虑,也会有不同的同步策略来让文件系统缓存同步到磁盘

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

sync_binlog配置选项

 1.sync_binlog=0,不同步刷新到磁盘,交给操作系统去操作,断电或者操作 系统异常,可能导致数据丢失

2.sync_binlog=1 ,能保证数据的一致性,每次提交都必须同步到磁盘,但是对性能有影响
3. sync_binlog=N,N 默认是 1 ,最大 4294967295 ,代表我达到 N binLog 后, 再同步到磁盘,能够灵活的来设置数据的一致性与性能之间的平衡

官网给的建议是,为了数据的一致性,来保证持久性跟一致性请设置 

sync_binlog= 1
innodb_flush_log_at_trx_commit= 1

 2. BinLog、RedoLog、UndoLog

2.1 BinLog跟RedoLog的二阶段机制

binLog是Mysql服务所提供的日志,并且是二进制日志,也就是说我不管你是什么存储引擎,只要你开启了,我都会记录。

那么既然有了binLog,为什么还要有RedoLog呢?

1. 首先 BinLog 只记录提交的完整的事务日志,而 RedoLog 一直在执行同步。
2.BinLog 是追加的二进制日志,不知道里面哪些已经持久化哪些没有持久化,而RedoLog 已经持久化的记录会从 RedoLog 删除。
3. 记录方式不一样, BinLog 是二进制日志,而 RedoLog 是物理日志,所以恢复的方式也会不一样。

当然。RedoLog也替代不了BinLog,因为RedoLog是InnoDB独有的,用其他存储引擎的时候,如果没有BinLog,同步跟恢复都没法完成。

所以,虽然BinLog跟RedoLog虽然作用稍微有些重合,但是缺一不可。

Mysql里面就采用了二阶段提交的形式,来保证这两个事务都是成功的,也尽可能保证我们的表数据跟日志数据一致(如果不一致,恢复的数据,以及主从同步的数据都会不一样)

所谓二阶段提交,就是我们的提交分2次进行,目的: 保证数据的一致性。

 Mysql里面保证BinLog跟RedoLog的一致性,就用了二阶段提交方案,如图:

1.在更新数据的时候,还没有提交事务的时候,提交的RedoLogprepare 状态

2. commit 事务后,会将 BinLog Cache 缓存的 bin 日志,同步到磁盘。
3. RedoLog 状态更改成 Commit 状态,整个流程结束。

 那么如果发生异常,怎么保证数据的一致性

1. 如果操作①失败,数据回滚, RedoLog binlog 都不会有
2. 如果②失败,有 RedoLog prepare 状态,但是没有 binlog 落盘,数据回滚,操作失败
3. 当③失败,这个时候,有 RedoLog 并且有 binlog ,数据都会有,并且数据是一致的,成功。

 2.2 三大日志的区别

两个事务日志 

a. RedoLog 重做日志,覆盖写的方式,保证内存缓存与数据库表中的一致性

b. undoLog  回滚日志,在事务里面,如果发生异常的,记录的是回滚的值, 在mvcc中也有应用

c. Binlog MysqlServer层的,二进制日志,主要两个作用 主从同步,数据恢复,binlog找到之前的数据。

3. 主从同步机制

3.1 主从安装流程

a. 创建负责同步数据给slave的用户

mysql> CREATE USER 'repl' @'%.mysql.slave' IDENTIFIED BY 'password' ;
mysql> GRANT REPLICATION SLAVE ON *.* TO   'repl' @'%.mysql.slave' ;
mysql> flush privileges ; -- 刷新权限

 2. 查看master信息

show master status \G -- 查看 master 信息

 3. 配置从库节点 如果不希望从库自己写数据,可以更改为只读

SHOW VARIABLES LIKE '%read_only%' ;
SET GLOBAL super_read_only= 1 ; -- super 账号也只读
SET GLOBAL read_only= 1 ; -- 只读

 4. 创建主从关系

mysql> CHANGE MASTER TO
-> MASTER_HOST= 'source_host_name' ,
-> MASTER_USER= 'replication_user_name' ,
-> MASTER_PASSWORD= 'replication_password' ,
-> MASTER_LOG_FILE= 'recorded_log_file_name' ,
-> MASTER_LOG_POS=recorded_log_position; -- 我要
binlog 的哪个位置开始同步
这个为8.0.23 的版本
Or from MySQL 8.0.23 :
mysql> CHANGE REPLICATION SOURCE TO
-> SOURCE_HOST= 'source_host_name' ,
-> SOURCE_USER= 'replication_user_name' ,
-> SOURCE_PASSWORD= 'replication_password' ,
-> SOURCE_LOG_FILE= 'recorded_log_file_name' ,
-> SOURCE_LOG_POS=recorded_log_position; --
我要从 binlog 的哪个位置开始同步

 5. 开启主从同步

mysql> start replica; -- 开启主从同步

 6.查看从库信息 show replica status

mysql> show replica status \G
*************************** 1. row ***************************
Replica_IO_State: Waiting for source to send event
Source_Host: 192.168.8.127
Source_User: replica
Source_Port: 3306
Connect_Retry: 60
Source_Log_File: mysql-bin .000004
Read_Source_Log_Pos: 9285
Relay_Log_File: localhost-relay-bin .000003
Relay_Log_Pos: 1334
Relay_Source_Log_File: mysql-bin .000004
Replica_IO_Running: Yes //IO线程
Replica_SQL_Running: Yes //sql执行线程
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0 //跳过的事务数,还有这个数值的事务不会执行
Exec_Source_Log_Pos: 9285
Relay_Log_Space: 2002
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Source_SSL_Allowed: No
Source_SSL_CA_File:
Source_SSL_CA_Path:
Source_SSL_Cert:
Source_SSL_Cipher:
Source_SSL_Key:
Seconds_Behind_Source: 0 //主从延迟时间
Source_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Source_Server_Id: 129
Source_UUID: 978861 d8- 232 d- 11 ed-bc6f- 000 c2928fa99
Source_Info_File: mysql .slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Replica_SQL_Running_State: Replica has read all
relay log; waiting for more updates
Source_Retry_Count: 86400
Source_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Source_SSL_Crl:
Source_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Source_TLS_Version:
Source_public_key_path:
Get_Source_public_key: 0
Network_Namespace:
1 row in set ( 0.01 sec)

Replica_IO_Running 线程以及 Replica_SQL_Running线程都为yes代表跟主建立关系,并且能进行主从同步。

如果从库同步报错,数据又不是特别重要,可以跳过事务

set GLOBAL SQL_replica_SKIP_COUNTER=100000; 跳过多少事务,设置后,后续的100000个事务讲不会执行
我们可以在主从中查看 Skip_Counter 还有多少事务是跳过的 跳过的事务从不会去执行

3.2 建立主从的必要条件

我们知道主从是怎么同步数据的了,那我怎么给2个服务建立主从关系。

我们来看两个必要的条件

a. 确保有唯一的server_id,server_id不能重复,如果实例ID都一样了,那就没法区分实例的唯一性了。

从文件中配置或SQL配置

-- vim /etc/my.cnf
server-id=128

或者

SET GLOBAL server_id = 128; -- 更改server_id

查询一下

mysql> SHOW GLOBAL VARIABLES like '%server_id%' ;
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| server_id | 128 |
| server_id_bits | 32 |
+----------------+-------+
2 rows in set ( 0.01 sec)

b.  数据源必须开启bin_log

因为主从复制是基于binLog去做的,所以如果想要把数据源的数据同步给副本,那么必须开启binLog。

但是副本不需要开启BinLog,除非这个副本想成为另外一个实例的数据源,也就是A->B->C的架构,A同步给B。B同步给C

同时,如果副本想成为别的实例数据源,还必须开启

SHOW GLOBAL VARIABLES like '%log_replica_updates%'; -- 版本8.0.6之后
SHOW GLOBAL VARIABLES like '%log_slave_updates%'; -- 版本8.0.6之前

该配置代表,从库能否把从主拿到的binlog事务写入自己的binlog

3.3 主从复制

我们先去看下主从同步用到的线程。官网MySQL :: MySQL 8.0 Reference Manual :: 19.2.3 Replication Threads

官网上提供了3种线程:其中replica 2个  master 1个

slave

a. I/O receiver thread

IO 接收线程,负责从 master 里面获取 binLog 日志,并且将日志加载到replica本地的文件,这个文件也叫作 replica's relay log ,俗称中继日志。
可以在 SHOW SLAVE STATUS 指令中查看 Replica_IO_Running

b.SQL applier thread

 slave接收到binLog日志后,得去执行到replica数据库。就是依靠SQL applier thread线程去执行

可以在 SHOW SLAVE STATUS 指令中查看 Replica_SQL_Running

master

 master收到I/O receiver thread线程发起的同步指令后,master会创建一个Binary log dump thread线程,将binLog内容发送给slave

可以通过 SHOW PROCESSLIST 查看线程状态

整体的主从复制流程图如下:

 

 3.4 同步方式

我们知道了主从数据是怎么同步的,是由异步线程去进行同步的,那么假如我主成功了,但是主从因为网络断开等异常没有进行同步,不就数据不一致了么?

所以为了主从的数据一致性,同步方式分为异步同步、半同步

MySQL :: MySQL 8.0 Reference Manual :: 20.1.1.1 Source to Replica Replication

异步同步

 利用额外的线程去dump我们的binLog然后传送给slave,并且我们master的用户线程是不会等待同步结果的。所以,默认的同步方式是异步同步。

性能比较高,但是数据一致性低(如果主挂了,没有同步到从,那么这个从就不会有最新的数据),因为会有延迟。

半同步

 由于异步同步会存在一定的数据丢失,并且会有延迟,所以Mysql的主从复制有一个半同步的概念,所谓半同步,就是我的主必须等待数据至少有一个副本(具体数量可以进行配置),接收并记录了,才会运行提交事务。

半同步不是默认的,如果要开启半同步,必须要安装半同步的插件

插件安装: MySQL :: MySQL 8.0 Reference Manual :: 7.6.1 Installing and Uninstalling Plugins

半同步插件: MySQL :: MySQL 8.0 Reference Manual :: 19.4.10.1 Installing Semisynchronous Replication

3.5 主从数据一致性不同步、或者同步慢的解决思路

网络延迟: 检查网络、优化网络能够让网络能够支撑数据量的传输。可以采用半同步的方式,确保数据不会丢失,或者最少有一个从能同步到数据,但是会牺牲一定的性能。

主库负载很高:  当主库有大量的操作的时候,有大量需要同步给从,也可能会延迟。 可以做负载、缓存减少主的压力
大事务导致:  binlog 太大太多,从库需要执行的时间越久,也会导致可能会延迟,尽量减 少大事务。
从库的机器跟不上: 从库的 cpu 、内存要跟主库能够匹配。不然从的处理性能会跟主不一致

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1698074.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【2024】HNCTF

Web Please_RCE_Me GET传参输入?moranflag&#xff0c;之后获取源码&#xff1a;<?php if($_GET[moran] flag){highlight_file(__FILE__);if(isset($_POST[task])&&isset($_POST[flag])){$str1 $_POST[task];$str2 $_POST[flag];if(preg_match(/system|eval|a…

【C#】未能加载文件或程序集“CefSharp.Core.Runtime.dll”或它的某一个依赖项。找不到指定的模块。

欢迎来到《小5讲堂》 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 背景错误提示分析原因解决方法Chromium知识点相关文章 背景 最近在使…

RabbitMQ-默认读、写方式介绍

1、RabbitMQ简介 rabbitmq是一个开源的消息中间件&#xff0c;主要有以下用途&#xff0c;分别是&#xff1a; 应用解耦&#xff1a;通过使用RabbitMQ&#xff0c;不同的应用程序之间可以通过消息进行通信&#xff0c;从而降低应用程序之间的直接依赖性&#xff0c;提高系统的…

有什么普通人可以做的赚钱软件?盘点9个适合普通人长期做的软件

在这个互联网高速发展的时代&#xff0c;智能手机已经成为我们生活中不可分割的一部分。众多APP的涌现&#xff0c;使得许多朋友都在寻求通过手机赚钱的方法。 然而&#xff0c;面对市面上琳琅满目的网上赚钱APP&#xff0c;我们该如何挑选呢&#xff1f;别担心&#xff0c;今…

python web自动化(验证码处理)

1.解决验证码问题的常⻅⼏种⽅式 1&#xff09; Debug模式启动浏览器&#xff08;浏览器复⽤&#xff09;&#xff1a; 原理&#xff1a;浏览器是有缓存记录的&#xff0c;只需要 沿⽤已经保存有登录记录的浏览器 进⾏后续的操作就⾏ 2&#xff09;识别法&#xff1a; 原理…

pycharm中,出现SyntaxError: Non-ASCII character ‘\xe4‘ in file... 的问题以及解决方法

文章目录 一、问题描述二、解决方法 一、问题描述 在pycharm中&#xff0c;使用python中编写中文字符时&#xff0c;会提示如下错误信息&#xff1a; SyntaxError: Non-ASCII character \xe4 in file ...... on line 8, but no encoding declared; see http://python.org/dev…

网上比较受认可的赚钱软件有哪些?众多兼职选择中总有一个适合你

在这个互联网高速发展的时代&#xff0c;网上赚钱似乎成了一种潮流。但是&#xff0c;你是否还在靠运气寻找赚钱的机会&#xff1f;是否还在为找不到靠谱的兼职平台而苦恼&#xff1f; 今天&#xff0c;就为你揭秘那些真正靠谱的网上赚钱平台&#xff0c;让你的赚钱之路不再迷…

MySQL--InnoDB体系结构

目录 一、物理存储结构 二、表空间 1.数据表空间介绍 2.数据表空间迁移 3.共享表空间 4.临时表空间 5.undo表空间 三、InnoDB内存结构 1.innodb_buffer_pool 2.innodb_log_buffer 四、InnoDB 8.0结构图例 五、InnoDB重要参数 1.redo log刷新磁盘策略 2.刷盘方式&…

S1E45:单链表1 课后作业

测试题&#xff1a;0. 相比起数组来说&#xff0c;单链表具有哪些优势呢&#xff1f; 答&#xff1a;长度非固定&#xff0c;可以申请添加长度 答案&#xff1a;对于数组来说&#xff0c;随机插入或者删除其中间的某一个元素&#xff0c;都是需要大量的移动操作&#xff0c;而…

基于tcp实现自定义应用层协议

认识协议 协议&#xff08;Protocol&#xff09; 是一种通信规则或标准&#xff0c;用于定义通信双方或多方之间如何交互和传输数据。在计算机网络和通信系统中&#xff0c;协议规定了通信实体之间信息交换的格式、顺序、定时以及有关同步等事宜的约定。简易来说协议就是通信…

网络工程师---第三十八天

ISIS&#xff1a; ISIS含义&#xff1a;中间系统到中间系统IS-IS。 ISIS特点&#xff1a;①内部网关协议IGP&#xff08;Interior Gateway Protocol&#xff09;&#xff0c;用于自治系统内部&#xff1b; ②IS-IS也是一种链路状态协议&#xff0c;使用最短路径优先SPF算法进…

电子阅览室在管理时需注意什么

关于如今的绝大多数人来说&#xff0c;想必都听说过“电子阅览室”这一概念。它首要运用在校园中&#xff0c;给学生们供给愈加丰厚的常识储藏。它也是一个独立的局域网&#xff0c;在校园网络中作为重要的一个组成部分而存在。但是&#xff0c;一个好的电子阅览室是需求满意运…

python文件IO基础知识

目录 1.open函数打开文件 2.文件对象读写数据和关闭 3.文本文件和二进制文件的区别 4.编码和解码 读写文本文件时 读写二进制文件时 5.文件指针位置 6.文件缓存区与flush()方法 1.open函数打开文件 使用 open 函数创建一个文件对象&#xff0c;read 方法来读取数据&…

Docker学习(4):部署web项目

一、部署vue项目 在home目录下创建项目目录 将打包好的vue项目放入该目录下&#xff0c;dist是打包好的vue项目 在项目目录下&#xff0c;编辑default.conf 内容如下&#xff1a; server {listen 80;server_name localhost; # 修改为docker服务宿主机的iplocation / {r…

[JAVASE] 类和对象(六) -- 接口(续篇)

目录 一. Comparable接口 与 compareTo方法 1.1 Comparable接口 1.2 compareTo方法的重写 1.2.1 根据年龄进行比较 1.2.2 根据姓名进行比较 1.4 compareTo 方法 的使用 1.3 compareTo方法的缺点(重点) 二. Comparator接口 与 compare方法 2.1 Comparator接口 2.2 compare 方法…

使用AWR对电路进行交流仿真---以整流器仿真为例

使用AWR对电路进行交流仿真—以整流器仿真为例 生活不易&#xff0c;喵喵叹气。马上就要上班了&#xff0c;公司的ADS的版权紧缺&#xff0c;主要用的软件都是NI 的AWR&#xff0c;只能趁着现在没事做先学习一下子了&#xff0c;希望不要裁我。 本AWR专栏只是学习的小小记录而…

2024.5.25期末测试总结

成绩&#xff1a; 配置&#xff1a; 可能与实际有些出入 题目&#xff1a; 第一题&#xff1a; 代码思路&#xff1a; 一道模拟题&#xff0c;按照公式计算出sumpow(2,i)&#xff0c;判断sum>H&#xff0c;输出 代码&#xff1a; #include<bits/stdc.h> using name…

LiveGBS流媒体平台GB/T28181用户手册-基础配置:信令服务配置、流媒体服务配置、白名单、黑名单、更多配置

LiveGBS流媒体平台GB/T28181用户手册-基础配置:信令服务配置、流媒体服务配置、白名单、黑名单、更多配置 1、基础配置1.1、信令服务配置1.2、白名单1.3、黑名单1.4、流媒体服务配置 2、搭建GB28181视频直播平台 1、基础配置 LiveGBS相关信令服务配置和流媒体服务配置都在这里…

Spark运行模式详解

Spark概述 Spark 可以在多种不同的运行模式下执行&#xff0c;每种模式都有其自身的特点和适用场景。 部署Spark集群大体上分为两种模式&#xff1a;单机模式与集群模式。大多数分布式框架都支持单机模式&#xff0c;方便开发者调试框架的运行环境。但是在生产环境中&#xff…

机器人支持回调接口配置(详细教程)

大家伙&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 一、前言 今天&#xff0c;给大家介绍一下&#xff0c;如何在机器人中配置回调地址和接口编写。很多时候我们可能有这样的场景&#xff0c;收到消息后&#xff0c;想自己处理一下消息的内…