MySQL主从复制技术全面解析:从基础原理到高级架构实践(八)

本文全面解析MySQL数据库主从复制技术的完整体系,涵盖基础原理、实战部署、监控管理、故障诊断,以及多种高级复制架构(包括延时从库、过滤复制、半同步复制、GTID复制、Clone复制、多源复制和数据组复制MGR)。深入探讨主从复制的三种同步机制(异步、半同步、全同步)及其应用场景,为构建高性能、高可用的MySQL数据库架构提供完整解决方案。通过理论结合实践的方式,帮助数据库管理员和架构师深入理解MySQL复制技术,掌握从基础到高级的复制架构设计与运维管理技能。

1.主从复制概述

MySQL数据库服务从3.23版本就开始提供复制的功能,复制是指将主数据库的DDL和DML操作语句通过二进制日志传到复制服务器上;然后在从库上(复制服务器)对这些日志重新执行(也叫重做),从而使得从库和主库的数据保持同步;

MySQL支持一台主库同时向多台从库进行复制,从库同时也可以作为其他服务器的主库,实现链状的复制;

MySQL复制的优点:

  • 如果主库出现问题,可以快速切换到从库提供服务;
  • 从库上执行查询操作,降低主库的访问压力;
  • 从库上执行备份操作,以避免备份期间影响主库的服务;

由于MySQL实现的是异步复制,所以主从之间存在一定的差距,在从库上进行的查询操作需要考虑到这些数据的差异,一般只有更新不频繁的数据或者对实时性要求不高的数据可以通过从库查询,实时性要求高的数据仍然需要从主数据库获得;

2.主从复制原理

2.1 复制原理涉及线程

在进行主从数据复制时,是依靠相应线程信息来完成数据复制同步操作的,具体涉及到的线程信息如下:

所在位置 线程名称 作用说明
主库涉及线程 dump thread 用于将主库binlog日志信息进行传输投递的线程 可以实现与从库的信息交互 可以监控二进制日志的变化 可以进行二进制日志的投递
从库涉及线程 slave IO thread 可以用于连接主数据库服务 可以实现与主库线程的交互 可以接收和存储二进制日志(接收的二进制日志会存储在中继日志中) 接受的二进制日志为主库的binlog日志
从库涉及线程 slave SQL thread 可以解析执行中继日志信息,回放日志
01 主库线程binlog dump
sql 复制代码
mysql> show processlist;
可以通过show processlist命令在主库上查看binlog dump线程,从binlog dump线程的状态可以看到,mysql的复制是主库主动推送
日志到从库去的,是属于推日志的方式来做同步;

说明:如果是一主多从的架构,将会看见多个binlog dump线程信息,实现对多个从库的日志信息投递;

02 从库线程slave IO/slave SQL

在从库上通过show processlist可以看到I/O线程和SQL线程;

  • I/O线程等待主库上的binlog dump线程发送事件并更新到中继日志relay log;

    用此线程和主库建立连接,并与主库的dump thread线程进行交互,以及接收和存储主库推送过来的binlog日志信息到relay log;

  • SQL线程读取中继日志relay log并应用变更到数据库;

    用此线程实现回放relay log中的日志信息,实现对从库的SQL语句操作;

从MySQL的复制流程可以得知MySQL的复制是异步的,从库上的数据和主库存在一定的延时;

2.2 复制原理涉及文件

在进行主从数据复制时,是依靠相应文件信息来完成数据复制过程中的数据保存的,具体涉及到的文件信息如下:

所在位置 文件信息 解释说明
主库涉及文件 binlog 可以利用二进制日志信息变化,实现主从数据库的异步方式同步
从库涉及文件 relaylog 可以利用中继日志进行临时存储或接收主库投递的二进制日志信息,日志信息会定期自动清理
master.info 可以存储主库相关信息(主库地址 端口 用户 密码 二进制位置点-已经获取的 )(和IO线程相关)
relay-log.info 可以存储SQL线程回放过的日志信息(与SQL线程相关)

从库上的后两个文件(matser/relay-log)已经不以文件方式保存在数据库服务的数据目录中,而是以表格形式直接存储在数据库内部

sh 复制代码
mysql> show variables like '%info%';
+---------------------------------+----------------+
| Variable_name                    | Value             |
+---------------------------------+----------------+
| master_info_repository     | TABLE            |
| relay_log_info_repository | TABLE            |
+---------------------------------+----------------+

mysql> use mysql;
mysql> show tables;
+----------------------------------+
| Tables_in_mysql                  |
+----------------------------------+
| slave_master_info               |
| slave_relay_log_info           |
+----------------------------------+
-- 可以获取slave_master_info表中的信息,就是change master to配置指定的相关信息;
-- 可以获取 slave_relay_log_info表中的信息,就是SQL线程已经回放过的日志信息
2.3 复制原理过程详述(Classic Replication)

MySQL的复制原理大致如下:

  1. 从库上执行change master to命令,将主库连接信息和binlog位置信息写入master.info文件或 slave_master_info表中;

  2. 从库上执行start slave命令,用于启动从库的IO和SQL线程功能;

  3. 从库IO线程主要用于读取主库连接信息,实现和主库建立连接,从而使主库派生出binlog dump线程(自动监控binlog);

  4. 从库IO线程根据change master to命令所定义的数据位置点,获取最新的binlog日志信息

  5. mysql主库在事务提交时会把数据变更为事件Events记录在二进制日志文件binlog中;

    mysql主库上的sync_binlog参数控制binlog日志刷新到磁盘;

  6. binlog dump线程会截取binlog日志并投递其日志给从库IO线程,此时主库并不关心投递日志信息的结果;

  7. 此时从库IO线程接收binlog投递信息(缓存),随之会立即更新master.info文件 或 slave_master_info数据表信息;

  8. 从库缓存的binlog日志数据信息会被写入到relay-log中继日志中;

    主库推送二进制日志文件binlog中的事件到从库的中继日志relay -log,之后从库根据中继日志relay log重做数据变更操作

  9. 从库SQL线程将会读取relaylog.info文件或者slave_relay_log_info数据表中信息,获取上次数据回放同步位置点;随之继续向后回放同步数据,一旦回放同步数据完成后,再次更新relay.info或slave_relay_log_info数据表信息;

  10. 在从库中回放过的relaylog日志信息,会被relay_log_purge线程定期删除处理这些日志;

  11. 通过逻辑复制以此来达到主库和从库的数据一致;

简述:

MySQL通过3个线程和两个日志来完成主从复制流程的:3个线程:其中binlog dump线程跑在主库上,I/O线程和SQL线程跑在从库上;2个日志:binlog二进制日志在主库上,relay log日志在从库上;

  • 主库写入数据存储到binlog文件中;
  • 当从库启动复制(START SLAVE)时,首先创建I/O线程连接主库,主库随后创建binlog dump线程读取binlog文件内容,并发送给从库I/O线程,I/O线程收到内容后,将其写入到中继日志relay log中,并将新的binlog文件名和为支点更新到 slave_master_info数据表;
  • 从库还会创建SQL线程,实时检测本地relay log日志是否新增了内容,然后把relay log新增的内容翻译成SQL,按照顺序回放SQL写入到数据库中,回放完更新slave_relay_log_info数据表中日志文件名和位置点信息,从而达到主从数据一致的目的。

简述:在两台以上节点进行复制,通过binlog日志实现同步关系,并且采用异步方式进行数据同步;

3 主从复制实践

3.1 主从复制搭建过程
  • 准备两台以上数据库实例
sh 复制代码
#初始化数据库
[root@db01 ~]#  mysqld_safe --defaults-file=/data/3307/data/my.cnf &
[root@db01 ~]#  mysqld_safe --defaults-file=/data/3308/data/my.cnf &
[root@db01 ~]# ss -lntup |grep 3307
tcp    LISTEN     0      128    [::]:3307               [::]:*                   users:(("mysqld",pid=1840,fd=22))
[root@db01 ~]# ss -lntup |grep 3308
tcp    LISTEN     0      128    [::]:3308               [::]:*                   users:(("mysqld",pid=2010,fd=21))

#添加配置文件
cat >/data/3307/data/my.cnf<<EOF
[mysql]
socket=/tmp/mysql3307.sock
[mysqld]
user=mysql
port=3307
basedir=/usr/local/mysql
datadir=/data/3307/data
socket=/tmp/mysql3307.sock   
server_id=7
EOF

cat >/data/3308/data/my.cnf<<EOF
[mysql]
socket=/tmp/mysql3308.sock
[mysqld]
user=mysql
port=3308
server_id=8
basedir=/usr/local/mysql
datadir=/data/3308/data
socket=/tmp/mysql3308.sock   
EOF

#启动数据库
[root@db01 ~]# mysql -S /tmp/mysql3307.sock
[root@db01 ~]# mysql -S /tmp/mysql3308.sock

server_id的作用:server_id是MySQL服务器的唯一标识符
  01 主从复制:在MySQL主从复制中,server_id用于标识主服务器(也称为主节点)和从服务器(也称为从节点)。主服务器将binlog中的更改记录发送给从服务器,从服务器根据server_id识别来自主服务器的复制事件,并将其应用到本地数据库上。
  02 MySQL集群环境:在MySQL集群环境中,多个服务器协同工作以提供高可用性和负载均衡。每个服务器都必须具有唯一的server_id,以便其他服务器能够准确地识别和与之通信。
  • 主数据库(3307)二进制日志功能开启
sh 复制代码
mysql> show variables like '%log_bin%';
+---------------------------------+------------------------------+
| Variable_name                   | Value                        |
+---------------------------------+------------------------------+
| log_bin                         | ON                           |
| log_bin_basename                | /data/3307/data/binlog       |
| log_bin_index                   | /data/3307/data/binlog.index |
| log_bin_trust_function_creators | OFF                          |
| log_bin_use_v1_row_events       | OFF                          |
| sql_log_bin                     | ON                           |
+---------------------------------+------------------------------+
6 rows in set (0.00 sec)
-- 核实确认binlog日志功能在主库上已经开启
  • 核实主从复制主机的信息情况
sh 复制代码
# 确认多个复制节点的服务标识不同(server id/server_uuid)
mysql> select @@server_id;
+-------------+
| @@server_id |
+-------------+
|           8 |
+-------------+
1 row in set (0.00 sec)
mysql> select @@server_uuid;
+--------------------------------------+
| @@server_uuid                        |
+--------------------------------------+
| 2f89f7fb-5cd9-11ee-8a1b-000c2992b86e |
+--------------------------------------+
1 row in set (0.00 sec)

# 确认多个复制节点的时间信息同步
date
# 确认多个复制节点的版本信息一致
mysql -v
  • 创建主从数据同步的用户信息
sql 复制代码
# 在主库上创建复制同步数据用户
mysql> create user repl@'%' identified with mysql_native_password by '12366';
Query OK, 0 rows affected (0.01 sec)
mysql> grant replication slave on *.* to repl@'%';
Query OK, 0 rows affected (0.00 sec)
-- 从库会利用主库上的同步数据用户,进行数据同步传输操作
  • 进行从库部分数据信息的同步
sh 复制代码
# 将主库上的部分数据在从库上先进行同步
[root@db01 ~]# mysqldump -uroot -A -S /tmp/mysql3307.sock --master-data=2 --single-transaction >/tmp/full.sql
-- 在3307主库上进行数据的全备(模拟企业环境的历史数据全备)
[root@db01 ~]# mysql -S /tmp/mysql3308.sock
mysql> source /tmp/full.sql;
-- 在3308从库上进行数据的恢复(模拟企业环境的历史数据恢复)
-- 将原有主机的数据先备份,然后从库中进行恢复一部分数据,随后再进行数据信息同步追加
-- 同步方式有很多:mysqldump xtrabackup clone_plugin
  • 配置主从节点数据复制的信息(从库配置)
sql 复制代码
1.从库配置master信息
# 设置从库连接主库信息,定义从库连接主库同步位置点自动复制
mysql> help change master to
-- 获取连接主库,以及定义同步位置点的数据库配置模板信息
[root@db01 ~]# head -30 /tmp/full.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000006', MASTER_LOG_POS=659;
-- 通过备份文件获取同步位置点信息
mysql> CHANGE MASTER TO
  MASTER_HOST='10.0.0.51',
  MASTER_USER='repl',
  MASTER_PASSWORD='12366',
  MASTER_PORT=3307,
  MASTER_LOG_FILE='binlog.000006',
  MASTER_LOG_POS=659,
  MASTER_CONNECT_RETRY=10;       
-- 以上配置主从同步信息在从库进行执行

2.激活主从节点数据复制的线程
#在从库上激活数据复制同步功能
mysql> start slave;
...
 Slave_IO_Running: Yes
 Slave_SQL_Running: Yes
...
#从库上查看数据同步状态情况,看到上面的两个Yes信息,就表示主从数据同步功能设置成功了
mysql> show slave status\G;
# 若此时数据同步失败可以重新开启同步功能,重新配置change master to信息,然后重新激活同步复制功能
mysql> stop slave;
mysql> reset slave all;

3.测试同步情况
#主库创建数据库
mysql> create database test1;

#从库测试是否同步
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| liux               |
| mysql              |
| performance_schema |
| sys                |
| test1              |
+--------------------+
3.2 主从复制数据监控
  • 数据库自带命令进行监控
sh 复制代码
mysql> show slave status\G
-- 在主库上也可以实现数据复制监控,但是一般情况下更关注的是从库;
内容分类 输出内容 解释说明
主库的复制信息 Master_Host: 10.0.0.51 表示连接主库地址信息
- 利于IO线程工作方面 Master_User: repl 表示连接主库用户信息
Master_Port: 3307 表示连接主库端口信息
Connect_Retry: 10 表示连接主库重试间隔
Master_Log_File: binlog.000004 表示主从同步日志信息
Read_Master_Log_Pos: 156 表示主从同步位置信息
从库的回放信息 Relay_Log_File: db01-relay-bin.000005 表示中继日志回放文件信息
- 利于SQL线程工作方面 Relay_Log_Pos: 365 表示中继日志回放位置信息
Relay_Master_Log_File: binlog.000004 表示对应主库日志文件信息 可以用于帮助判断主从延时的日志量
Exec_Master_Log_Pos: 156 表示对应主库日志位置信息 可以用于帮助判断主从延时的日志量
从库的线程信息 Slave_IO_Running: Yes 表示从库同步数据时-IO线程状态
- 利于判断同步线程情况 Slave_SQL_Running: Yes 表示从库同步数据时-SQL线程状态
Last_IO_Errno: 0 表示从库IO线程异常错误代码
Last_IO_Error: 表示从库IO线程异常错误原因
Last_SQL_Errno: 0 表示从库SQL线程异常错误代码
Last_SQL_Error: 表示从库SQL线程异常错误原因
过滤复制的相关信息 Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
主从复制的延时情况 Seconds_Behind_Master: 0 表示主从之间延时秒数信息
延时从库的状态情况 SQL_Delay: 0 表示延时同步时间间隔情况
SQL_Remaining_Delay: NULL 表示最近事件延时剩余时间
主从GTID复制状态情况 Retrieved_Gtid_Set:
Executed_Gtid_Set:
3.3 主从复制故障分析

主从异常情况有哪些?

  • 从库线程异常分析-IO(从底层角度分析IO异常原因)
sh 复制代码
1.IO线程主要用于连接数据库,数据库连接不上会导致I0异常,IO状态为connecting,可能原因如下:
   连接地址、端口、用户、密码信息不对
   防火墙安全策略阻止连接建立、网络通讯配置异常
   到达数据库服务连接数上限,造成主从连接产生异常
   
 使用主从复制专用用户进行手工连接测试,核实主从复制用户是否可以远程连接登录数据库
# 正常远程连接测试
[root@db01 ~]#  mysql -urepl -p12366 -h10.0.0.51 -P3307

2.IO线程主要用于进行日志信息请求,以及接收日志信息,并将日志信息进行保存(落地),异常为导致状态为no,可能原因:
   IO线程在请求日志信息失败,有可能日志信息被无意清理了;
     主库日志信息被清理了
   IO线程在请求日志信息失败,有可能主从配置的标识信息重复冲突了;
     主从server_id server_uuid信息配置相同了
  • 从库线程异常分析-SQL(从底层角度分析SQL异常原因)
sh 复制代码
1. SQL线程主要用于回放执行relay log日志信息,即执行相关数据同步SQL语句信息,异常会导致连接状态为no
原因分析:
   创建的对象已经存在,涉及到的对象可能有库、表、用户、索引...;
   插入(insert)的操作对象有异常、修改(update alter)的操作对象有异常、删除(delete drop)的操作对象有异常;
   数据库版本不同可能冲突;
   从库被误写入数据了,与主库同步数据产生冲突;
   主从切换时,没有正确操作锁定源主库和binlog日志信息;

2. 线程异常处理原则:
  主从同步出现数据同步异常,一切数据信息以主库为准;
  尽量不要使用双主架构,避免数据信息双写,造成的数据同步异常;
  主从同步数据信息时候,可以设置从库只读,避免从库误写入冲突;
3.4 主从复制延时分析

延时描述:

  • 在主库操作执行语句信息后,从库经过一段时间后才进行操作执行的同步;
  • 在主库操作执行语句信息后,从库经过一段时间后也没有进行相关的操作;

延时影响:

  • 对于读写分离架构是依赖于主从同步数据环境的,主库作为写节点,从库作为读节点,延时严重会影响从库的读操作体验;
  • 对于高可用架构也是依赖于主从同步数据环境的,主库作为主节点,从库作为备节点,延时严重会影响主备的切换一致性;

延时原因:

  • 外部因素导致的延时问题:

    • 网络通讯不稳定,有带宽阻塞等情况,造成主从数据传输同步延时;
    • 主从硬件差异大,从库磁盘性能较低,内存和CPU资源都不够充足;
    • 主从配置区别大,从库配置没有优化,导致并发处理能力低于主库;(参考了解)
  • 主库因素导致的延时问题(Dump thread工作效率缓慢):

    • 由于主库并发压力比较大;

    • 由于从库数量比较多导致;

    • 由于线程本身串型工作方式;(利用组提交缓解此类问题-5.6开始 group commit

      主库本身可以并发多个事务运行,默认情况下主从同步Dump thread只有一个,只能采用串型方式传输事务日志信息;

  • 从库因素导致的延时问题:

    • 从库产生延迟受SQL线程影响较大,由于线程本身串型工作方式导致;
  • 其他因素导致的延时问题:

    • 由于数据库大事务产生的数据同步延时问题;(更新100W数据/尽量切割事务)
    • 由于数据库锁冲突机制的数据同步延时问题;(资源被锁无法同步/隔离级别配置RR-锁冲突严重,可调整RC降低延时 索引主从一致)
    • 由于数据库过度追求安全配置也会导致同步延时问题(从库关闭双一参数);

延时监控:

sql 复制代码
mysql> show slave status\G;
*************************** 1. row ***************************
Seconds_Behind_Master: 0
-- 表示主从之间延时秒数时间信息
Relay_Master_Log_File: binlog.000004
Exec_Master_Log_Pos: 156
-- 在从库上利用 show slave status\G 获取binlog日志同步执行位置点
-- 在主库上利用 show master status 获取binlog日志同步生成位置点,与从库进行对比,即可判定是否出现主从延迟问题;

4 主从复制扩展

4.1 延时从库

概念说明:

  • 人为主动方式将一个从库进行配置,使从库可以按照指定的时间延时后,再进行和主库完成相应数据信息同步;
  • 人为控制SQL线程回放延时;

**作用说明:**主要解决主库的误操作行为

  • 利用延时从库同步功能,主要是对逻辑原因造成的数据损坏进行弥补修复,从而避免全备数据恢复业务产生的代价较高问题;

  • 当出现逻辑损坏操作时,可以利用延时从库的延时同步特性,将异常操作不做同步,将从库未做破坏的数据信息恢复到主库中;

实践操作:

  • ① 创建从库环境
sh 复制代码
[root@db01 ~]# vim /data/3309/data/my.cnf
[mysqld]
server_id=9
#启动3309实例
[root@db01 ~]# systemctl start mysqld3309.service
#将主库上的部分数据在从库上先进行同步
[root@db01 ~]# mysql -S /tmp/mysql3309.sock
mysql> source /tmp/full.sql;
-- 在3309从库上进行数据的恢复(模拟企业环境的历史数据恢复)
-- 将原有主机的数据先备份,然后从库中进行恢复一部分数据,随后再进行数据信息同步追加
-- 同步方式有很多:mysqldump xtrabackup clone_plugin

# 从库配置master信息
[root@db01 ~]# head -30 /tmp/full.sql 
-- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000006', MASTER_LOG_POS=659;
mysql> CHANGE MASTER TO
  MASTER_HOST='10.0.0.51',
  MASTER_USER='repl',
  MASTER_PASSWORD='12366',
  MASTER_PORT=3307,
  MASTER_LOG_FILE='binlog.000006',
  MASTER_LOG_POS=659,
  MASTER_CONNECT_RETRY=10;
-- 以上配置主从同步信息在从库进行执行;

#从库激活同步功能
mysql> start slave;
#查看io和sql线程状态,确认同步配置是否正常
mysql> show slave status\G;
  • ② 配置延时从库功能
sh 复制代码
# 在从库上配置应用延时同步功能
mysql> stop slave;
mysql> change master to master_delay=300;
mysql> start slave;
mysql> show slave status\G;
*************************** 1. row ***************************
SQL_Delay: 300
SQL_Remaining_Delay: NULL
-- 设置延时时间为300s后同步数据(生产建议延时3~6小时),以及最近事件要做同步的延时剩余时间;
  • ③ 延时从库应用

延时的根本效果是主库执行操作完成后,会经过指定的时间后,从库在执行主库曾经执行的操作;

基于主从同步原理分析,延时同步效果是在SQL线程上进行控制实现的,并非在IO线程上进行控制实现的;

SQL线程的延时控制机制,主要是需要识别同步操作任务的时间戳信息,根据时间戳和延时时间信息结合,判断相关任务是否同步执行;

简述:基于主从同步原理,IO线程同步主库操作事件是持续同步的,只是SQL线程在进行事件信息回放时,进行了延时控制;

利用延时从库恢复数据

sh 复制代码
# 1.核实当前主从同步是完整状态
mysql> show master status;
-- 核实主库应用日志文件和事件位置点情况;
mysql> show slave status\G;
*************************** 1. row ***************************
Master_Log_File: binlog.000004
Read_Master_Log_Pos: 347
Relay_Log_File: db01-relay-bin.000003
Relay_Log_Pos: 277
-- 核实从库应用日志文件和事件位置点情况,确认和主库应用日志信息和事件位置点情况一致;

# 2.延时从库应用效果环境模拟
mysql > create database relaydb;
mysql > use relaydb;
mysql > create table t1 (id int);
mysql > insert into t1 values(1),(2),(3);
mysql > insert into t1 values(11),(12),(13);
mysql > insert into t1 values(111),(112),(113);
mysql > drop database relaydb;
-- 以上操作语句在主库上进行执行;
mysql> show master status;
-- 核实主库应用日志文件和事件位置点情况;
mysql> show slave status\G;
*************************** 1. row ***************************
Master_Log_File: binlog.000004
Read_Master_Log_Pos: 1793
Relay_Log_File: db01-relay-bin.000003
Relay_Log_Pos: 277
SQL_Delay: 300
SQL_Remaining_Delay: 91
-- 核实从库应用日志文件和事件位置点情况,

# 数据信息修复方式一:手工截取日志信息进行回放数据,恢复业务;
# 操作过程01:停止从库SQL线程回放日志事件
mysql > stop slave sql_thread;
-- 停止从库SQL线程,终止持续同步操作,使从库不再回放同步数据;
mysql > show slave status\G;
*************************** 1. row ***************************
Master_Log_File: binlog.000004
Read_Master_Log_Pos: 3239
Relay_Log_File: db01-relay-bin.000003
Relay_Log_Pos: 1723
Slave_IO_Running: Yes
Slave_SQL_Running: No
SQL_Delay: 300
SQL_Remaining_Delay: N
-- 核实从库SQL线程状态是否为NO,以及获取读取的relay_log日志文件信息

# 操作过程02:根据relaylog起点信息以及异常操作位置点信息,截取日志内容信息
起点信息:
Relay_Log_File: db01-relay-bin.000003
Relay_Log_Pos: 1723
mysql> show relaylog events in 'db01-relay-bin.000003';
.. 省略部分...
| db01-relay-bin.000003 | 3056 | Query          |         1 |        3239 | drop database relaydb /* xid=745 */ 
-- 获取终点信息 3056
[root@db01 ~]#  cd /data/3309/data/
[root@db01 ~]#  mysqlbinlog --start-position=1723 --stop-position=3056  liux-01-relay-bin.000003 >/tmp/relay.sql
-- 在从库服务器上完成日志信息的截取操作

# 操作过程03:从库中恢复截取日志数据
mysql> set sql_log_bin=0;
mysql> source /tmp/relay.sql;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| relaydb              |
+--------------------+
-- 核实数据库以及数据表信息已恢复,并且原有主从关系已经彻底奔溃,需要进行主从关系重构
mysql> stop slave;
mysql> reset slave all;
-- 从库身份解除

# 数据信息修复方式二:持续延时从库数据回放同步过程,但同步过程停止在异常操作前;
# 操作过程01:停止从库SQL线程回放日志事件
mysql > stop slave sql_thread;
-- 停止从库SQL线程,终止持续同步操作,使从库不再回放同步数据;
mysql > show slave status\G
*************************** 1. row ***************************
Master_Log_File: binlog.000004
Read_Master_Log_Pos: 4685
Relay_Log_File: db01-relay-bin.000003
Relay_Log_Pos: 3169
Slave_IO_Running: Yes
Slave_SQL_Running: No
SQL_Delay: 300
SQL_Remaining_Delay: NULL
-- 核实从库SQL线程状态是否为NO,以及获取读取的relay_log日志文件信息

# 操作过程02:回放日志事件在异常操作位置点前
mysql> show relaylog events in 'liux-01-relay-bin.000003';
+----------------------------------+------+-------------------+-----------+-----------------+------------------------------------------+
| Log_name                             | Pos   | Event_type     | Server_id | End_log_pos | Info                                                  |
+----------------------------------+------+-------------------+-----------+-----------------+------------------------------------------+
...忽略部分..
| db01-relay-bin.000003 | 4394 | Xid            |         1 |        4495 | COMMIT /* xid=757 */                                        |
| db01-relay-bin.000003 | 4425 | Anonymous_Gtid |         1 |        4572 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                  |
| db01-relay-bin.000003 | 4502 | Query       |         1 |        4685 | drop database relaydb /* xid=759 */               |
+----------------------------------+------+-------------------+-----------+-----------------+------------------------------------------+
-- 获取异常操作日志文件信息和事件位置点信息,其中位置点信息以Pos列显示的为准,并且是提前一个事务位置点;
mysql > change master to master_delay=0;
-- 在从库重启进行日志回放操作前,关闭从库延迟回放的功能
mysql > start slave until relay_log_file="log_name", relay_log_pos=log_pos;
mysql > start slave until relay_log_file='liux-01-relay-bin.000003', relay_log_pos=4425;
-- 启动日志信息回放功能,直到指定位置点结束日志信息回放
mysql > start slave until sql_before_gtids="xxxx3:4";
-- 如果开启了GTID功能,也可以按照GTID位置点进行数据信息回放(参考)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: No
Until_Log_File: liux-01-relay-bin.000003
Until_Log_Pos: 4425
-- 从库重新回放操作恢复数据后,从库状态信息中SQL还是为NO,是正常的,因为直到指定位置点就终止回放;

# 操作过程03:核实异常数据信息是否恢复
mysql > show databases;
+--------------------+
| Database           |
+--------------------+
| relaydb              |
+--------------------+
-- 核实数据库以及数据表信息已恢复,并且原有主从关系已经彻底奔溃,需要进行主从关系重构
mysql> stop slave;
mysql> reset slave all;
-- 从库身份解除
-- 参考官方资料:https://dev.mysql.com/doc/refman/8.0/en/start-replica.html
4.2 过滤复制

概念:

当在企业数据库服务应用当中,如果在主库上有多个数据库业务,希望将不同的数据库业务同步到不同的从库上,实现数据库业务分离;

为了满足以上需求,就可以利用过滤复制功能,将指定的数据信息复制到指定从库上,而不是全备方式同步数据;

基于过滤复制功能,还是可以实现在主从同步数据信息时,排除指定库的数据信息不做主从同步操作;

实现机制:

  • ① 在主库上进行限制(一般不考虑)

在主库上进行复制同步数据时,主库上存在A、B、C三个数据库信息,若只想复制其中A数据库的数据信息;

可以让数据库服务只记录A数据库的事件日志信息,对于B和C数据库信息进行不写入日志操作;

但是利用这种方法实现主从信息同步的过滤,可能会导致B和C库数据一旦损坏,由于没有记录日志,无法进行恢复的情况;

  • ② 在从库上进行限制

在从库上进行复制同步数据时,利用从库上的SQL线程进行控制,只回放同步过来的A库数据信息,屏蔽其他数据库的信息不做回放;

利用从库进行同步数据过滤,不能减轻主库同步数据的压力,但可以减轻从库进行数据回放的压力;

功能应用实践:

  • ① 查看主从限制过滤参数信息
sql 复制代码
1. 查看主库复制过滤限制参数信息 
mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000007 |      156 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
-- 主库状态信息中,Binlog_Do_DB表示同步复制白名单过滤设置,Binlog_Ignore_DB表示同步复制黑名单过滤设置
-- 过滤白名单表示会记录事件日志信息,过滤黑明白表示不会记录事件日志信息,一般选择其一进行应用即可
-- 可以应用主库的过滤同步功能,实现数据库中默认库的同步复制限制;

2. 查看从库复制过滤限制参数信息
mysql> show slave status\G;
			  Replicate_Do_DB: 
          Replicate_Ignore_DB: 
-- 库级别的过滤操作,白名单设置表示回放库级别操作,黑名单设置表示忽略库级别操作
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
-- 表级别的过滤操作,白名单设置表示回放表级别操作,黑名单设置表示忽略表级别操作
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
-- 模糊级别的过滤操作,主要是可以针对多表信息,配置白名单或黑名单;   
-- 以上在从库上线实现数据同步过滤机制的参数信息有6个,主要可以分为3组,一般应用使用一个参数即可;
  • ② 数据同步复制过滤效果配置
sh 复制代码
# 编写配置文件实现过滤
[root@db01 ~]# vim /data/3309/data/my.cnf 
[mysqld]
replicate_do_db=www
replicate_do_db=word
--从库只同步www、word库的数据

# 在线调整参数实现过滤
mysql> help change replication filter
mysql> stop slave sql_thread;
mysql> CHANGE REPLICATION FILTER REPLICATE_DO_DB = (word, www);
mysql> start slave sql_thread;
-- 一般编写配置文件和在线配置都会进行,可以不重启数据库服务生效过滤机制,日后重启数据库后过滤机制依然生效;
# 查看获取从库过滤配置
mysql> show slave status\G
Replicate_Do_DB: word,www
Replicate_Ignore_DB:
  • ③ 进行同步复制过滤效果测试
sql 复制代码
# 在主库上进行数据库创建模拟
mysql> create database word;
mysql> show slave status\G
-- 从库日志信息同步查看
mysql> show databases;
+--------------------+
| Database            |
+--------------------+
| word                   |
+--------------------+
-- 查看从库数据同步情况

mysql> create database www;
mysql> show slave status\G;
-- 从库日志信息同步查看
mysql> show databases;
+--------------------+
| Database            |
+--------------------+
| www                 |
+--------------------+
-- 查看从库数据同步情况

mysql> create database cq;
mysql> show slave status\G;
-- 从库日志信息同步查看
mysql> show databases;
+--------------------+
| Database            |
+--------------------+
|                     |
+--------------------+
-- 查看从库数据同步情况,并未实现cq数据库的复制,即实现了数据同步过滤效果;
4.3 半同步复制

概念说明:

在MySQL5.5版本之前,数据库的复制是异步操作,主库和从库的数据之间存在一定的延迟,这样就存在数据存储不一致的隐患;

假设当主库上写入一个事务并提交成功, 而从库尚未得到主库推送的binlog日志时,主库宕机了;

例如主库可能因磁盘损坏、内存故障等造成主库上该事务binlog丢失,此时从库就可能损失这个事务,从而造成主从不一致;

为了解决这个问题,数据库服务引入了半同步复制机制。

当采用异步方式同步数据,由于从库异常宕机情况出现,造成主从数据不一致情况出现,还会有以下影响情况:

  • 会造成从库可能创建语句没有执行,后续的插入语句也必然失败,形成SQL线程运行故障;

  • 由于主从数据信息不一致,在架构设计上在读取从库数据信息时,就会读取数据信息异常;

说明:利用半同步复制机制,主要是用于解决主从数据复制不一致的问题,即解决主从数据一致性问题,也可以避免SQL线程故障;

实现工作机制:

在MySQL5.5之前的异步复制时,主库执行完commit提交操作后,在主库写入binlog日志后即可成功返回客户端;

无需等待binlog日志传送给从库;

半同步复制时,为了保证主库上的每个binlog事务能够被可靠的复制到从库上,主库在每次事务成功提交时,并不及时反馈给前端用户;

而是等待其中一个从库也接收到binlog事务并成功写入中继日志后,主库才返回commit操作成功给客户端。

半同步复制保证了事务成功提交后,至少有两份日志记录,一份在主库的binlog日志上,另一份在至少一个从库的中继日志relaylog上

从而更进一步保证了数据的完整性。

简单说明:半同步复制技术应用,主要是阻塞主库事务提交的执行过程,从而实现数据最终一致性目的;

半同步复制技术与传统主从复制技术不同之处:

  • 在主库提交操作时候会受到阻塞,等待从库IO线程返回ack确认信号后,才能使主库提交操作成功;

  • 从库IO线程接收到binlog日志信息,当日志信息写入到磁盘上的relaylog文件时,会给主库返回ack信号;

    在主库上会利用ack_receiver线程接收返回的ack信号;

  • 当主库上的ack_receiver线程接收到ack信号信息时,会产生事件触发机制,告诉主库事务提交操作成功了;

  • 如果在接收ack信号时,等待信号时间超过了预设值的超时时间,半同步复制会切换为原始的异步复制方式;

    预设的等待超时时间的数值,由参数rpl_semi_sync_master_timeout设置的毫秒数决定;

功能应用实践:

  • ① 主从数据库安装半同步功能插件
sql 复制代码
# 主库安装半同步插件(3307)
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
-- 主库利用插件控制ack_receiver线程接收ack确认信息,并且会控制commit阻塞,实现半同步复制功能
mysql> show plugins;
| rpl_semi_sync_master  | ACTIVE   | REPLICATION        | semisync_master.so | GPL     |
-- 查看插件是否进行加载

# 从库安装半同步插件(3309)
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
-- 从库利用插件控制IO线程发送ack确认信息;
mysql> show plugins;
-- 查看插件是否进行加载

说明:一般在高可用数据库架构环境中,可以在高可用的两台主机上均安装好主库插件和从库插件;

  • ② 主从数据库启动半同步插件功能
sh 复制代码
# 主库启动半同步功能
mysql> set global rpl_semi_sync_master_enabled =1;

# 从库启动半同步功能
mysql> set global rpl_semi_sync_slave_enabled =1;

# 重启从库上的IO线程
mysql> stop slave IO_THREAD;
mysql> start slave IO_THREAD;

# 核实确认半同步功能状态:
mysql> show status like 'rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+
1 row in set (0.00 sec)
-- 核实主库半同步功能是否激活

mysql> show status like 'rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)
-- 核实从库半同步功能是否激活
  • ③ 主从数据库半同步功能永久配置
sql 复制代码
# 在数据库配置文件中编写以下参数
rpl_semi_sync_master_enabled=on
-- 主库半同步功能启停设置,on为激活设置
rpl_semi_sync_master_timeout=1000
-- 主库接收从库确认信息的超时时间设置(单位毫秒)
rpl_semi_sync_master_trace_level=32
rpl_semi_sync_master_wait_for_slave_count=1
rpl_semi_sync_master_wait_no_slave=on
rpl_semi_sync_master_wait_point=after_sync
binlog_group_commit_sync_delay=1
binlog_group_commit_sync_no_delay_count=1000
-- 实现事务组提交方式,将多个事务合并成组推送到从库上,避免dump线程采用串型方式提交事务,造成主从同步延时;

rpl_semi_sync_slave_enabled=on
-- 从库半同步功能启停设置,on为激活设置
rpl_semi_sync_slave_trace_level=32
4.4 GTID复制-使用GTID构建主从

概念:

GTID(global transaction id)是对于一个已提交事务的唯一编号,并且是一个全局唯一编号(主从复制过程);

是数据库5.6版本开始的一个功能新特性,主要是用于解决主从复制的一致性问题; GTID 实际上 是由UUID+TID 组成的,其中 UUID 是一个 MySQL 实例的唯一标识。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。

复制原理机制:

  • master节点在更新数据的时候,会在事务前产生GTID信息,一同记录到binlog日志中;
  • slave节点的io线程将主库推送的binlog写入到本地relay log中;
  • 然后SQL线程从relay log中读取GTID,设置gtid_next的值为该gtid,然后对比slave端的binlog是否有记录;
  • 如果有记录的话,说明该GTID的事务已经运行,slave会忽略;
  • 如果没有记录的话,slave就会执行该GTID对应的事务,并记录到binlog中。

功能应用实践:

  • ① 主从复制GTID环境准备(db01、db02、db03)
sh 复制代码
# 在所有主从节点均进行清理操作:
[root@db01 ~]# pkill mysqld
[root@db01 ~]# rm -rf /data/3306/*
[root@db01 ~]# mkdir -p /data/3306/data
[root@db01 ~]# chown -R mysql.mysql /data/*
[root@db01 ~]# mv /etc/my.cnf /tmp
  • ② 主从复制GTID功能配置编写
sh 复制代码
# 配置参数信息
gtid-mode=on
-- 启用gtid复制方式,默认采用传统的复制方式
enforce-gtid-consistency=true
-- 开启gtid所有节点的强制一致性
log-slave-updates=1
-- 定义slave更新是否记入二进制日志,从而增强数据一致性,是在高可用架构中重要配置环节

# 主库db01配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=51
port=3306
secure-file-priv=/tmp
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db01 [\\d]>
EOF

# 主库db02配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=52
port=3306
secure-file-priv=/tmp
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db02 [\\d]>
EOF

# 主库db03配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=53
port=3306
secure-file-priv=/tmp
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db03 [\\d]>
EOF

# 所有节点进行初始化数据库操作
[root@db01 ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/3306/data

#所有节点启动数据库服务
[root@db01 ~]# /etc/init.d/mysqld start
  • ③ 主从复制GTID配置重构主从
sh 复制代码
# 重构主从关系-主库操作
db01 [(none)]>create user repl@'10.0.0.%' identified with mysql_native_password by '12366';
db01 [(none)]>grant replication slave on *.* to repl@'10.0.0.%';
-- 主库上创建主从复制用户信息

# 重构主从关系-从库操作
db02 [(none)]>change master to
master_host='10.0.0.51',
master_user='repl',
master_password='12366',
master_auto_position=1;
-- 表示让从库自己找寻复制同步数据的起点;
-- 在第一次启动gtid功能时,会读取从库中的binlog日志信息,根据主库uuid信息,获取从库中执行过的主库gtid信息
-- 从从库中没有执行过的主库gtid信息之后进行进行数据同步操作
db02 [(none)]> start slave;
-- 其他从库一并操作
db02 [(none)]>show slave status\G;
  • ④ 知识扩展:进行全备恢复数据时不要加 set-gtid-purged参数

如果是已经运行很久的数据库,需要构建主从,都是需要备份恢复主库数据后,再开启实现主从功能的;

在mysqldump进行备份数据时,不要加set-gtid-purged参数,否则会造成从库依旧从第一个gtid信息开始同步数据;

造成主从同步数据信息冲突,影响主从构建过程,导致主从同步过程失败;

--set-gtid-purged=on/auto 此为默认参数,即使在备份命令中不写,依旧生效;

它的效果是在mysqldump输出的备份文件中生成 SET@@GLOBAL.GTID_PURGED语句;备份文件中的这条语句记录了GTID号。

sh 复制代码
# 未加set-gtid-purged参数实现的数据备份效果
[root@db01 ~]# mysqldump -A --master-data=2 --single-transaction >/tmp/full.sql
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events. 
[root@db01 ~]# vim /tmp/full.sql
SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN= 0;   恢复数据时不计入binlog日志

SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ 'd3877b7f-df44-11ee-9bad-000c2992b86e:1-2';
-- 表示让从库删除1-2的集合信息,即通过备份文件已经恢复了1-2的数据,可以从1-2之后进行数据信息同步;

# 已加set-gtid-purged参数实现的数据备份效果
[root@db01 ~]# mysqldump -A --master-data=2 --single-transaction --set-gtid-purged=OFF >/tmp/full02.sql
[root@db01 ~]# vim /tmp/full.sql
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '3cfa5898-771a-11ed-b8d7-000c2996c4f5:1-2';
SET SQL_LOG_BIN=0;
-- 以上信息不会出现在备份文件中
-- 表示会让从库把备份文件中的操作语句,再次根据gtid请求执行一遍,容易产生异常冲突问题;
4.5 Clone复制-使用clone方式构建主从

概念:

利用clone plugin方式可以实现数据迁移备份恢复操作,同样也可以利用克隆技术实现主从数据同步操作,即完成快速构建从库;

主要应用于运行一段时间的数据库,需要进行主从架构环境的构建时,可以实现主库数据信息的快速迁移;

利用克隆复制备份恢复迁移数据信息,可以使备份恢复数据的效率提升;

功能应用实践:

  • ① 主从复制克隆功能实现环境(db01、db03)
sh 复制代码
# 清理原有从库配置应用(db03)
db03 [(none)]>stop slave;
db03 [(none)]>reset slave all;

# 准备数据库空白的节点
[root@db01 ~]# pkill mysqld
[root@db01 ~]# rm -rf /data/3306/*
[root@db01 ~]# mv /etc/my.cnf /tmp
[root@db01 ~]# mkdir -p /data/3306/data 
[root@db01 ~]# chown -R mysql.mysql /data/*
-- 在新的数据库节点进行以上清理操作;

cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=53
port=3306
secure-file-priv=/tmp
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db03 [\\d]>
EOF
-- 从库db03配置文件编写

[root@db01 ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/3306/data
-- 进行数据库所有节点初始化操作

[root@db01 ~]# /etc/init.d/mysqld start
-- 启动数据库相应节点服务
  • ② 主从复制克隆环境功能配置
sh 复制代码
# 实现免交互方式安装插件和创建用户(主库操作)
[root@db01 ~]# mysql -e "INSTALL PLUGIN clone SONAME 'mysql_clone.so';create user test@'%' identified by '12366';grant backup_admin on *.* to 'test'@'%';"

# 实现免交互方式安装插件和创建用户(从库操作)
[root@db03 ~]#  mysql -e "INSTALL PLUGIN clone SONAME 'mysql_clone.so';create user test@'%' identified by '12366';grant clone_admin on *.* to 'test'@'%';set global clone_valid_donor_list='10.0.0.51:3306';"
  • ③ 主从复制克隆功能应用启动
sh 复制代码
# 从库上启用克隆功能
[root@db03 ~]# mysql -utest -p12366 -h10.0.0.53 -P3306 -e "clone instance from test@'10.0.0.51':3306 identified by '12366';"

# 实现克隆状态情况监控(可以实现每秒监控)
[root@db03 ~]#  mysql -uroot  -e "select stage,state,end_time from performance_schema.clone_progress;"
+-----------+-----------+----------------------------+
| stage     | state     | end_time                   |
+-----------+-----------+----------------------------+
| DROP DATA | Completed | 2023-10-11 17:29:10.176536 |
| FILE COPY | Completed | 2023-10-11 17:29:10.548651 |
| PAGE COPY | Completed | 2023-10-11 17:29:10.555789 |
| REDO COPY | Completed | 2023-10-11 17:29:10.557767 |
| FILE SYNC | Completed | 2023-10-11 17:29:10.929904 |
| RESTART   | Completed | 2023-10-11 17:29:14.191138 |
| RECOVERY  | Completed | 2023-10-11 17:29:15.416172 |
+-----------+-----------+----------------------------+
-- 可以实现每秒关注监控输出的结果信息,最后看到RECOVERY,并且状态为Completed,表示克隆完毕
  • ④ 主从复制克隆完毕实现主从
sh 复制代码
# 主从方式构建一:利用position
[root@liux-03 ~]# mysql -e "select binlog_file,binlog_position from performance_schema.clone_status;"
+------------------+-----------------+
| binlog_file      | binlog_position |
+------------------+-----------------+
| mysql-bin.000002 |            1210 |
+------------------+-----------------+

# 主从方式构建二:利用gtid
[root@db03 ~]# mysql -e "change master to master_host='10.0.0.51',master_user='repl',master_password='12366',master_auto_position=1;start slave"


# 核实展示最后主从状态结果
[root@db03 ~]# mysql -e "show slave status\G"|grep "Running:"
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

说明:利用clone功能实现主从,可以利用脚本自动化完成,并且可以实现主从的自愈能力,为实现主从功能上云提供方便;

4.6 多源复制(MSR)

概念:

把多个主库的数据同步到一个从库上

在实际企业应用环境中,可能出现下图情况;会有多个企业系统场景,并且每个业务场景会构建不同主从架构,实现网站架构的解耦;

当业务相互独立拆分后,的确读写方面来说,都能感觉到有大量的备份,相比所有业务汇总在一起时,并发效率和性能都有大幅提升;

以上的业务架构设计,相当于进行垂直拆分;但是当需要进行数据信息统一查询分析时,变的非常困难,将会出现数据库孤岛问题;

早期架构上解决此问题,只能采取将所有业务数据汇总到一个到的数据库中,使数据分析工作变得很麻烦,并没有什么自动化解决方案;

当前有了比较好的解决思路,是利用数据中台技术,可以更好的将不同业务数据进行整合:

  • 便于进行数据节点统一管理
  • 便于进行数据信息统一分析(关注)

在mysql应用过程中,为了实现数据中台构建,可以将所有业务的主库数据信息,汇总到一个从库中,即实现多源复制功能(5.7+);

实现多源复制,会对不同业务主库有一定的性能影响,并且对于多源复制的目标从库,并不会做写操作,只用于做数据分析使用;

功能应用实践:

  • ① 主从多源复制功能实现环境(db01、db02、db03)
sh 复制代码
#对原有数据库服务环境清理:(基于GTID环境构建)
#所有主从节点均进行清理操作
[root@db01 ~]# pkill mysqld
[root@db01 ~]# rm -rf /data/3306/*
[root@db01 ~]# mkdir -p /data/3306/data
[root@db01 ~]# chown -R mysql.mysql /data/*
[root@db01 ~]# mv /etc/my.cnf /tmp

# 主库db01配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/3306/data
server_id=51
socket=/tmp/mysql.sock
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
secure-file-priv=/tmp
innodb_flush_method=O_DIRECT
-- 这个参数控制着innodb数据文件及redo log的打开、刷写模式
-- 参考资料:https://blog.csdn.net/h106140873/article/details/125701485
slow_query_log=ON
slow_query_log_file=/data/3306/data/db01-slow.log
long_query_time=0.1
log_queries_not_using_indexes
-- 生成慢日志信息功能配置参数
master_info_repository=TABLE
-- 将master_info信息以表方式记录
relay_log_info_repository=TABLE
-- 将relay_log_info信息以表方式记录
[client]
socket=/tmp/mysql.sock
[mysql]
prompt=db01 [\\d]>
-- 数据库命令提示符设置,可以参考官方设置:https://dev.mysql.com/doc/refman/8.0/en/mysql-commands.html
socket=/tmp/mysql.sock
EOF

# 主库db02配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/3306/data
server_id=52
socket=/tmp/mysql.sock
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
secure-file-priv=/tmp
innodb_flush_method=O_DIRECT
slow_query_log=ON
slow_query_log_file=/data/3306/data/db02-slow.log
long_query_time=0.1
log_queries_not_using_indexes
master_info_repository=TABLE
relay_log_info_repository=TABLE
[client]
socket=/tmp/mysql.sock
[mysql]
prompt=db02 [\\d]>
socket=/tmp/mysql.sock
EOF

# 主库db03配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/3306/data
server_id=53
socket=/tmp/mysql.sock
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
secure-file-priv=/tmp
innodb_flush_method=O_DIRECT
slow_query_log=ON
slow_query_log_file=/data/3306/data/db03-slow.log
long_query_time=0.1
log_queries_not_using_indexes
master_info_repository=TABLE
relay_log_info_repository=TABLE
[client]
socket=/tmp/mysql.sock
[mysql]
prompt=db03 [\\d]>
socket=/tmp/mysql.sock
EOF

# 所有节点进行数据库初始化操作
[root@db03 ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/3306/data

#所有节点启动数据库服务
[root@db01 ~]# /etc/init.d/mysqld start
  • ② 多源复制重构主从环境
sql 复制代码
# 重构主从关系-主库操作(db01,db02)
db01 [(none)]>set sql_log_bin=0;
db01 [(none)]>create user repl@'10.0.0.%' identified with mysql_native_password by '12366';
db01 [(none)]>grant replication slave on *.* to repl@'10.0.0.%';
Query OK, 0 rows affected (0.00 sec)
db01 [(none)]>set sql_log_bin=1;
-- 两个主库上创建主从复制用户信息,并且不要产生创建用户日志信息,因为多个主节点可能用户信息不一致,会导致同步异常

# 重构主从关系-从库操作
db03 [(none)]>change master to
master_host='10.0.0.51',
master_user='repl',
master_password='12366',
master_auto_position=1 for channel 'Master_1';
 --区分时哪个主库
for channel 'Master_1';

db03 [(none)]>change master to
master_host='10.0.0.52',
master_user='repl',
master_password='12366',
master_auto_position=1 for channel 'Master_2';

db03 [(none)]> start slave for channel 'Master_1';
db03 [(none)]> start slave for channel 'Master_2';

#查看监控信息
db03 [(none)]>show slave status\G;
#多源主从状态监控信息分别查看,重点关注Channel_Name信息和IO SQL线程状态
db03 [(none)]> show slave status for channel 'Master_1'\G
db03 [(none)]> show slave status for channel 'Master_2'\G

db03 [(none)]> use performance_schema;
db03 [(none)]> select * from replication_connection_configuration\G
db03 [(none)]> select * from replication_connection_status where channel_name='master_1'\G
db03 [(none)]> select * from replication_connection_status where channel_name='master_2'\G
-- 多源主从状态监控信息汇总查看,或进行单独查看
db03 [(none)]> select * from performance_schema.replication_applier_status_by_worker\G;
-- 多源主从复制线程工作情况查看,了解即可
4.7 数据组复制(MGR)

概述:

MGR全称MySQL Group Replication(MySQL组复制),是MySQL官方于2016年12月推出的一个全新的高可用与高扩展的解决方案;

MGR提供了高可用、高扩展、高可靠的MySQL集群服务;

在MGR出现之前,用户常见的MySQL高可用方式,无论怎么变化架构,本质就是Master-Slave架构;

MySQL 5.7.17版本开始支持无损半同步复制(lossless semi-syncreplication),从而进一步提升数据复制的强一致性。

MySQL Group Replication(MGR)是MySQL官方在5.7.17版本引进的一个数据库高可用与高扩展的解决方案,以插件形式提供。

MGR基于分布式paxos协议,实现组复制,保证数据一致性。

MGR采用多副本,在2N+1个节点集群中,集群只要N+1个节点还存活着,数据库就能稳定的对外提供服务。

数据库组复制功能,可以理解为是数据库主从关系的高可用环境,一般需要三个数据库实例,构成一个具有高可用、高一致性的复制环境

主要涉及的功能应用包含:

  • 具有多节点之间互相通过投票的方式进行监控功能;(基于paxos协议)

  • 具有内置故障检测和自动选主功能,只要不是集群中的大多数节点都宕机,就可以继续正常工作;

    • 如果主节点异常,会自动选举新节点实现故障转移

    • 如果从节点异常,会自动将从节点从复制节点踢除

  • 提供单主模式与多主模式,多主模式支持多点写入;

应用模式说明:

①MGR单主模式(single-primary mode)

单主模式的主服务器通常是引导该组的第一台服务器,所有其它加入的从服务器会自动了解主服务器,并设置为只读模式(自动发生);

MGR单主模式选举原理:

  • 单主模式下,如果主节点挂了,那么其他的成员会自动选举出新的主成员,成员之间可以通过配置权重来确定下一个主成员是谁;
  • 如果没有配置权重,则会对所有在线成员的UUID进行排序,然后选取UUID最小的成员作为主成员。

②MGR多主模式(multi-primary mode)

在多主的模式下,没有单个主概念。无需进行节点选举,所有服务器均设置为读写模式。

MGR多主模式选举原理

  • 多主模式,所有的组内成员对外提供读写服务,是真正意义上的并发,MGR对于高并发有很好的的处理能力。

  • 多主模式下,组内所有成员没有主从之分,对用户来说,就像在操作一个MySQL一样。

  • 所以在多主模式下,不存在选举主节点,因为所有节点都是主节点。

工作机制原理:

组复制是一种可用于实现容错系统的技术,复制组是一个通过消息传递实现相互交互的server集群;

复制组由多个server成员组成,如下图master01、master02、master03,所有成员独立完成各自的事务;

  1. 当客户端发起一个更新事务时,该事务先在本地执行,执行完成之后就要发起对事务的提交操作;

  2. 在还没有真正提交之前,需要将产生的复制写集广播出去,复制到其它所有成员节点;

    主库事务提交时,会将事务修改记录相关的信息和事务产生的binlog事件打包生成一个写集,将写集发送给所有节点;

  3. 如果冲突检测成功,组内决定该事务可以提交,其它成员可以应用,否则就回滚;

    冲突检测成功的标准是:至少半数以上个节点投票通过才能事务提交成功;

  4. 最终,所有组内成员以相同的顺序接收同一组事务;

因此,组内成员以相同的顺序应用相同的修改,保证组内数据强一致性(采用了分布式事务特性)

功能应用实践:

  • ① MGR复制同步功能实现环境(db01,db02,db03)
sh 复制代码
1. 对原有数据库服务环境清理:(基于GTID环境构建)
# 在所有主从节点均进行清理操作
[root@db01 ~]# pkill mysqld
[root@db01 ~]# rm -rf /data/3306/*
[root@db01 ~]# mkdir -p /data/3306/data
[root@db01 ~]# chown -R mysql.mysql /data/*
[root@db01 ~]# mv /etc/my.cnf /tmp

2. 获取随机数信息充当uuid信息
[root@db01 ~]# cat /proc/sys/kernel/random/uuid
8818ab9b-c006-41f6-a2a0-09cf4e8e75a8
-- 借助随机数文件生成uuid信息,因为组复制过程也是通过GTID的uuid号码,达到复制环境中的事务一致性
-- 这里采用内部GTID功能,也就是组复制的各个节点通过同一个GTID的标识,进行事务管理,所以需要给组复制设置唯一号码

3. 配置文件编写
# 主库db01配置文件编写

cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=51
port=3306
secure-file-priv=/tmp
#log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
skip_name_resolve   --跳过反向解析 ip解析为host中域名
master_info_repository=TABLE
-- 将master_info信息以表方式记录
relay_log_info_repository=TABLE
-- 将relay_log_info信息以表方式记录
report_host=10.0.0.51
report_port=3306
socket=/tmp/mysql3306.sock
default_authentication_plugin=mysql_native_password
binlog_checksum=NONE
mysqlx=off
binlog_transaction_dependency_tracking=WRITESET
-- 在数据库8.0之后具有的配置,表示写集合配置信息,可以进一步提升SQL线程回放的并发度;(需要表有主键)
-- 是可以实现跨事务并发执行
transaction_write_set_extraction=XXHASH64
-- 定义写集合的hash算法信息,也属于数据库8.0之后具有的特性配置
-- 以上两行参数信息不加上,就表示与5.7版本数据库可以进行兼容,可以理解为是优化参数
loose-group_replication_group_name="8818ab9b-c006-41f6-a2a0-09cf4e8e75a8"
-- 设置组复制各个节点的统一唯一uuid标识信息,即同一组复制内部的唯一标识;
-- 一样就表示可以加入同一组复制中,不同就表示不加入到相同的组复制中
loose-group_replication_start_on_boot=OFF
-- 在组复制过程中也是需要启动相应线程,完成组复制任务的;
-- 此参数配置表示在服务启动时,不自动运行启动组复制功能,一般都是进行手工启动
-- 主要是防止数据库意外重启后,对组复制之间关系的影响,不能让重启后数据库自动加入到组复制中
loose-group_replication_local_address="10.0.0.51:33061"
-- 表示定义本地主机数据库服务的内部通讯地址和端口
loose-group_replication_group_seeds="10.0.0.51:33061,10.0.0.52:33062,10.0.0.53:33063"
-- 表示定义所有集群主机的内部通讯地址和端口
-- 以上地址和端口信息,表示组复制集群内部通讯时,应用的地址和端口信息;
-- 内部通讯需求:心跳检测、复制关系、日志同步、投票、选举...,都是通过内部地址和端口进行的;
loose-group_replication_bootstrap_group=OFF
-- 表示是否将此节点作为引导节点
-- 组复制在第一次进行配置时,需要先有引导节点,其他节点做为加入节点(joiner),不能都是ON,否则会产生争抢问题
-- 以上参数信息中loose,表示在没有组复制插件时,进行初始化操作只会报警告信息,而不会报错误提示

[mysql]
prompt=db01 [\\d]>
EOF

# 从库db02配置文件编写

cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=52
port=3306
secure-file-priv=/tmp
#log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
skip_name_resolve
master_info_repository=TABLE
relay_log_info_repository=TABLE
report_host=10.0.0.52
report_port=3306
socket=/tmp/mysql3306.sock
default_authentication_plugin=mysql_native_password
binlog_checksum=NONE
mysqlx=off
binlog_transaction_dependency_tracking=WRITESET
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="8818ab9b-c006-41f6-a2a0-09cf4e8e75a8"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address="10.0.0.52:33062"
loose-group_replication_group_seeds="10.0.0.51:33061,10.0.0.52:33062,10.0.0.53:33063"
loose-group_replication_bootstrap_group=OFF

[mysql]
prompt=db02 [\\d]>
EOF

# 从库db03配置文件编写

cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=53
port=3306
secure-file-priv=/tmp
#log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
skip_name_resolve
master_info_repository=TABLE
relay_log_info_repository=TABLE
report_host=10.0.0.53
report_port=3306
socket=/tmp/mysql3306.sock
default_authentication_plugin=mysql_native_password
binlog_checksum=NONE
mysqlx=off
binlog_transaction_dependency_tracking=WRITESET
transaction_write_set_extraction=XXHASH64
loose-group_replication_group_name="8818ab9b-c006-41f6-a2a0-09cf4e8e75a8"
loose-group_replication_start_on_boot=OFF
loose-group_replication_local_address="10.0.0.53:33063"
loose-group_replication_group_seeds="10.0.0.51:33061,10.0.0.52:33062,10.0.0.53:33063"
loose-group_replication_bootstrap_group=OFF

[mysql]
prompt=db03 [\\d]>
EOF

4. 所有节点初始化数据库、启动数据库
[root@db01 ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/3306/data
[root@db01 ~]# /etc/init.d/mysqld start

异常配置信息参数说明:

group_replication变量使用的loose-前缀是指server启用时尚未加载复制插件也将继续启动

num conf_info
01 transaction_write_set_extraction=XXHASH64 指示server为每个事务收集写集合,并使用XXHASH64哈希算法将其编码为散列
02 loose-group_replication_group_name="eb8441e9-8aef-4a86-a4bc-5beea315f04f" 表示将加入或创建的复制组命名为eb8441e9-8aef-4a86-a4bc-5beea315f04f 可以自定义或者通过cat /proc/sys/kernel/random/uuid获取
03 loose-group_replication_start_on_boot=OFF 表示设置server启动时不自动启动组复制
04 loose-group_replication_local_address="10.0.0.51:33061" 表示绑定本地的10.0.0.51:33061端口接受其他组成员的连接,IP地址必须为其他组成员 可正常访问
05 loose-group_replication_group_seeds="10.0.0.51:33061,10.0.0.52:33062, 10.0.0.53:33063" 表示告诉服务器在加入组时,应当连接到这些种子服务器进行配置。本设置可以不是全部的组成员服务地址
06 loose-group_replication_bootstrap_group=OFF 表示配置是否自动引导组
07 loose-group_replication_ip_whitelist="10.30.0.0/16,10.31.0.0/16,10.27.0.0/16" 表示配置白名单,默认情况下只允许10.0.0.51/52/53连接到复制组,如果是其他IP则需要配置
  • ② MGR复制同步功能配置过程(单主模式)
sh 复制代码
# 设置本地root用户密码和密码插件(所有节点)
mysql -S /tmp/mysql3306.sock -e "alter user 'root'@'localhost' identified with mysql_native_password by '12366';"

# 安装部署MGR组复制功能插件(所有节点)
mysql -uroot -p12366 -S /tmp/mysql3306.sock -e "install plugin group_replication SONAME 'group_replication.so';"

# 设置创建MGR组复制功能账号(所有节点)
mysql -uroot -p12366 -S /tmp/mysql3306.sock
set sql_log_bin=0;
create user repl@'%' identified by '12366';
create user repl@'localhost' identified by '12366';
create user repl@'127.0.0.1' identified by '12366';
grant replication slave,replication client on *.* to repl@'%';
grant replication slave,replication client on *.* to repl@'localhost';
grant replication slave,replication client on *.* to repl@'127.0.0.1';
flush privileges;
set sql_log_bin=1;

# 启动MGR单主模式:启动MGR引导节点(主库db01执行)
change master to master_user='repl',master_password='12366' for channel 'group_replication_recovery';
set global group_replication_bootstrap_group=ON;
start group_replication;
set global group_replication_bootstrap_group=OFF;
-- 相当于创建一个组复制集群,并指定集群中的引导节点

#查看集群节点状态信息,以及集群成员信息
db01 [(none)]>select * from performance_schema.replication_group_members;

# db02、db03节点加入MGR(在所有从库上执行)
reset master;
--表示清除从库上所有日志信息,重新做日志信息的复制或生成;
change master to master_user='repl',master_password='12366' for channel 'group_replication_recovery';
start group_replication;
-- 将指定从库节点加入到组复制集群中(企业中最好先备份恢复一定的数据,在进行组复制应用)

#查看集群节点状态信息,以及集群成员信息
#此时可以看到3个节点状态为online,并且主节点为10.0.0.51,只有主节点可以写入,其他节点只读,MGR单主模式搭建成功
db01 [(none)]> select * from performance_schema.replication_group_members;
+-----------+-------------+--------------+-------------+
MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE 
------------+-------------+--------------+-------------
10.0.0.51   |        3306 | ONLINE       | PRIMARY     
10.0.0.52   |        3306 | ONLINE       | SECONDARY   
10.0.0.53   |        3306 | ONLINE       | SECONDARY   
+-----------+-------------+--------------+-------------+
#s此时所有从库节点只能实现只读操作,只有主库可以进行写操作
show variables like '%only%';


# 遇到集群构建异常,可以进行重置操作(重构MGR组)
1.主节点
stop group_replication;
reset master;
change master to master_user='repl',master_password='12366' for channel 'group_replication_recovery';
set global group_replication_bootstrap_group=ON;
start group_replication;
set global group_replication_bootstrap_group=OFF;
2.从节点
stop group_replication;
reset master;
change master to master_user='repl',master_password='12366' for channel 'group_replication_recovery';
start group_replication;
  • ③ MGR复制同步功能配置过程(多主模式)

MGR切换模式需要重新启动组复制,因此需要在所有节点上先关闭组复制,设置group_replication_single_primary_mode=OFF参数

再重新启动组复制功能

sh 复制代码
1. 多主模式需要的参数信息
group_replication_single_primary_mode=0
-- 设置参数表示关闭掉单master模式
group_replication_enforce_update_everywhere_checks=1
-- 这个参数设置表示多主模式下,各个节点进行严格一致性检查

2. 多主模式功能配置(所有节点上执行)
#关闭组复制(所有节点)
db01 [(none)]>stop group_replication;
db01 [(none)]>set global group_replication_single_primary_mode=OFF;
db01 [(none)]>set global group_replication_enforce_update_everywhere_checks=1;
#检查参数配置信息是否生效
db01 [(none)]>select @@group_replication_single_primary_mode,@@group_replication_enforce_update_everywhere_checks;

#重新启动MGR组复制功能,是多主模式生效(主节点操作db01)
db01 [(none)]>set global group_replication_bootstrap_group=ON;
db01 [(none)]>start group_replication;
db01 [(none)]>set global group_replication_bootstrap_group=OFF;

#重新启动MGR组复制功能,是多主模式生效(从节点操作db02、db03)
db02 [(none)]>start group_replication;

#查看集群节点状态信息,以及集群成员信息
db03 [(none)]>select * from performance_schema.replication_group_members;
+-------------+-------------+--------------+-------------+
| MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE |
+-------------+-------------+--------------+-------------+
| 10.0.0.51   |        3306 | ONLINE       | PRIMARY     |
| 10.0.0.52   |        3306 | ONLINE       | PRIMARY     |
| 10.0.0.53   |        3306 | ONLINE       | PRIMARY     |
+-------------+-------------+--------------+-------------+

3. 修改从库只读功能配置(所有从库上执行)
set global read_only=0;
set global super_read_only=0;
-- 默认启动组复制功能都是单master模式,从库节点都是自动设置read_only super_read_only这两个参数,需要手工修改
  • ④ 多主模式切换到单主模式
sh 复制代码
# 所有节点执行以下操作
stop group_replication;
set global group_replication_enforce_update_everywhere_checks=OFF;
set global group_replication_single_primary_mode=ON;

# 在主节点执行以下操作
set global group_replication_bootstrap_group=ON;
start group_replication;
set global group_replication_bootstrap_group=OFF;

# 在从节点执行以下操作
start group_replication;

# 查看MGR组信息:
db02 [(none)]> select * from performance_schema.replication_group_members;
+-------------+-------------+--------------+-------------+
| MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE |
+-------------+-------------+--------------+-------------+
| 10.0.0.51   |        3306 | ONLINE       | PRIMARY     |
| 10.0.0.52   |        3306 | ONLINE       | SECONDARY   |
| 10.0.0.53   |        3306 | ONLINE       | SECONDARY   |
  • ⑤MGR复制同步监控
sh 复制代码
# MGR日常管理监控操作:
select * from performance_schema.replication_group_members;
-- 根据命令信息输出,获取各个节点主机的状态情况;

应用限制说明:

在应用MGR组复制功能时,也存在一些应用的限制条件:

  • 仅支持innodb存储引擎应用组复制功能;

    MGR集群中只支持innodb存储引擎,能够创建非innodb引擎的表,但是无法写入数据,向非innodb表写入数据直接报错;

  • 数据表中必须有主键,或者非null的唯一键;

    MGR集群中只支持innodb存储引擎,并且该表必须有显示的主键,或者非null的唯一键,否则即使能够创建表,也无法向表中写数据

  • 组复制存在网络限制,MGR组通信引擎目前仅支持IPv4网络,并且对节点间的网络性能要求较高;

    对于低延迟、高带宽的网络是部署MGR集群的基础;

  • 组复制功能会自动忽略表锁和命名锁,在MGR中lock tables、unlock tables、get_lock、release_lock等这些表锁和命名锁将忽略

  • MGR多主模式中,默认不支持 SERIALIZABLE 隔离级别,建议使用RC隔离级别;

  • 组复制多主模式中,对同一个对象进行并发是有冲突的,ddl和dml操作导致这种冲突在部分成员节点中无法检测到;

    最终可能导致数据不一致

  • 组复制多主模式中,不支持级联约束的外键,可能造成有冲突的操作无法检查;

  • 组复制功能不支持超大事务同步;

  • 组复制多主模式下可能导致死锁,比如select ... for update在不同节点执行,由于多节点锁无法共享,很容易导致死锁;

  • 组复制是不支持复制过滤的,如果有节点设置了复制过滤功能,将影响节点间决议的达成;

  • 组复制功能最多支持9个节点,当大于9个节点,将拒绝新节点的加入;

5.主从复制的三种机制

5.1 异步复制(Asynchronous replication)

MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给客户端,并不关心从库是否已经接收并处理 ,这样就会有一个问题:主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

5.2 半同步复制(Semisynchronous replication)

介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用

5.3 全同步复制(Fully synchronous replication)

指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。

6.总结

在主从复制技术的实际应用中,没有一种方案适用于所有场景。最有效的策略是根据具体的业务需求、技术架构和资源条件,选择合适的技术组合。随着MySQL版本的不断演进和新技术的发展,主从复制技术也在不断创新和优化。保持持续学习的态度,结合实践不断积累经验,才能构建出真正可靠、高效的数据复制体系,为企业的数字化转型提供坚实的数据基础设施保障。

相关推荐
a程序小傲2 小时前
听说前端又死了?
开发语言·前端·mysql·算法·postgresql·深度优先
小Mie不吃饭2 小时前
MySQL慢查询日志全解析:从配置到优化实践
mysql
代码煮茶君4 小时前
MySQL 数据库死锁及核心机制全解析
android·数据库·mysql
H_unique5 小时前
MySQL数据库操作核心指南
数据库·mysql
IT邦德5 小时前
MySQL 9.6.0 正式GA刚刚发布,有重大变更!
数据库·mysql
unicrom_深圳市由你创科技5 小时前
MySQL 乐观锁的实际落地:避免并发更新冲突的 3 种实现方式
数据库·mysql
無法複制5 小时前
Centos7安装MySQL8.0
linux·mysql
Dxy12393102165 小时前
PostgreSQL与MySQL有哪些区别:从架构到应用场景的深度解析
mysql·postgresql·架构
小码吃趴菜6 小时前
MySQL远程连接
数据库·mysql