学习笔记(一)MySQL复制原理及应用场景

MySQL复制原理及应用场景

    • 一、为什么需要主从复制
    • 二、复制架构
      • 1. 复制原理
        • relay log的意义
      • 2. binlog
        • (1) 格式
        • (2) Binlog事件类型
        • (3) 复制基准值
          • 1. File Position
          • 2. GTID
    • 三、复制分类
      • 1. 异步复制
      • 2. 半同步复制
        • after_commit
      • 3. 增强半同步复制
        • after_sync
      • 4. MGR复制
        • (1) 整体架构
        • (2) 搭建
          • 1. 手工搭建
          • 2. mysql shell搭建
        • (3) 错误
        • (4) 要求和限制
    • 四、实战
      • 1. 配置

一、为什么需要主从复制

  1. 使用主从复制,让主库负责写,从库负责读,这样即使主库出现了锁表的情景(暂时不能使用读),通过读从库也可以保证业务的正常运作。
  2. 架构的扩展。业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。
  3. 主从多台服务器,同样也可以当作数据备份的。

二、复制架构

MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库或者特定的表。

1. 复制原理

学习笔记(一)MySQL复制原理及应用场景_第1张图片

  1. 首先从库启动I/O线程,跟主库建立客户端连接
  2. 主库启动binlog dump线程,读取主库上的binlog event发送给从库的I/O线程,I/O线程获取到binlog event之后将其写入到自己的RelayLog中。
  3. 从库启动SQL线程,将等待Relay中的数据进行重放,完成从库的数据更新

注意:

  • Mysql复制最好确保master和slave服务器上的Mysql版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)
  • master和slave两节点间时间需同步。
  • master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启binlog二进制日志功能;通常为了数据安全考虑,slave也开启binlog功能)。
relay log的意义
  • 在MySQL 4.0 之前是没有Relay Log这部分的,整个过程中只有两个线程。但是这样也带来一个问题,那就是复制的过程需要同步的进行,很容易被影响,而且效率不高。例如主库必须要等待从库读取完了才能发送下个binlog事件。这就有点类似于一个阻塞的信道和非阻塞的信道。
  • 在流程中新增Relay Log中继日志后,让原本同步的获取事件、重放事件解耦了,两个步骤可以异步的进行,Relay Log充当了缓冲区的作用。
  • Relay Log包含一个relay-log.info的文件,用于记录当前复制的进度,下个事件从什么Pos开始写入,该文件由SQL线程负责更新。

2. binlog

(1) 格式
  • Statement:基于语句

    statement模式下,复制过程中向slave发送的就是在master上执行的SQL原句,master会将执行的SQL原有发送到slave中

  • Row:基于行✨

    row模式下,master会将每次DML操作引发的数据具体行变化记录在binlog中并复制到slave上,slave根据行的变更记录来对应的修改数据,但DDL类型的操作依然是statement的格式记录。

  • Mixed:基于混合语句和行格式

    MySQL会根据执行的每一条具体的SQL语句来区别对待记录的日志形式,也就是在statement和row之间选择一种。

    这三种模式各有优劣,相对来说,基于Row的行格式被应用的更广泛,虽然这种模式下对资源的开销会偏大,但数据变化的准确性以及可靠性是要强于Statement格式的,同时这种模式下的Binlog提供了完整的数据变更信息,可以使其应用不被局限在MySQL集群系统内,可以被例如Binlogserver,DTS数据传输等服务应用,提供灵活的跨系统数据传输能力,目前互联网业务的在线MySQL集群全部都是基于Row行格式的Binlog.

(2) Binlog事件类型
EVENT类型 作用
GTID_EVENT 事务的起点,仅限开启GTID_MODE=ON时才会出现(5.6以后)
QUERY_EVENT begin/commit/ddl, ddl等同于隐式的commit
XID_EVENT 正常事务序列的结尾,会被ddl替代
TABLE_MAP_EVENT 包含表的元数据信息,字段名、类型、NULL列、主键列等等
ROW_EVENT 仅限ROW格式,记录数据的变更,可以细分为Write, Update, Delete
  • 当发生了DDL类型的QUERY_EVENT,那么也是一次事务的结束提交点,且不会出现XID_EVENT
  • TABLE_MAP_EVENT必定出现在某个表的变更数据前,存在一对多个ROW_EVENT的情况
(3) 复制基准值
1. File Position

只要开启了log_bin,MySQL就会具有File Position的位点记录,这一点不受GTID的影响。

  • File:binlog.00001
  • position:381808617 (Bytes)

基于这种模式开启复制,需要显式地在复制关系中指定对应的File和Position

change master to master_log_file='binlog.00001',master_log_position=381808617;
2. GTID

MySQL会在开启GTID_MODE=ON的状态下,为每一个事务分配唯一的全局事务ID,格式:

GTID=server_uuid:transaction_id
  • 可以定位每个server产生了多少个事务(GTIDs)
  • 从库复制了多少个事务
  • 给每个事务做一个唯一编号

在这里插入图片描述

如果slave上看到和复制的主库不一致的值,则认为是存在errant GTID,这个一般是由于主从切换或强制在从库上执行了写操作引发。

change master to master_auto_position=1;

原则上来讲主从结构的GTID seq应该是连续的

GTID只代表操作的一个事务,不代表删了多少行或者增加了多少数据

slave SQL Thread如何使用索引

三、复制分类

1. 异步复制

异步复制会使得从库的数据落后,而半同步复制则会阻塞主库的写入,影响性能。

2. 半同步复制

MySQL 5.5, 5.6

sync replication -> semi replication

# slave        先开slave,否则master一直等待slave的ack响应,会卡住
install plugin rpl_semi_sync_slave SONAME 'semisync_slave.so';
set global rpl_semi_sync_slave_enabled=1;
stop slave io_thread;
start slave io_thread;

# master
install plugin rpl_semi_sync_master SONAME 'semisync_master.so';
set global rpl_semi_sync_master_enabled=1;
set global rpl_semi_sync_master_timeout=2147483648;    #设成无穷大,不允许退步到异步复制;若半同步进行不了,则不能写入数据

学习笔记(一)MySQL复制原理及应用场景_第2张图片

after_commit

学习笔记(一)MySQL复制原理及应用场景_第3张图片

3. 增强半同步复制

MySQL 5.7,8.0

after_sync

学习笔记(一)MySQL复制原理及应用场景_第4张图片

innodb在有binlog时写入流程

  1. 事务先写引擎redo

  2. 事务在提交时持有redo log中mutex_prepare_lock,并在redo log中写入Xid

  3. 写binlog,待binlog写入成功commit带上xid

    -----------------------------crash---------------------------------------

  4. redo写入binlog filename, position, 释放mutex_perpare_lock

MySQL Crash Recovery机制:

  1. 事务提交完毕的,通过redo进行commit
  2. 事务中持有mutex_prepare_lock的,扫描last binlog,看是不是存在xid,如果不存在,回滚;存在,commit事务
  3. 其它事务回滚

4. MGR复制

MySQL Group Replication (MySQL 5.7, MySQL 8.0)

MGR是MySQL 5.7.17开始引入的,但随着5.7版本逐渐退出历史舞台(MySQL 5.7已于2020年10月起不再做大的功能更新,只有修修补补以及针对安全更新),更多MGR相关特性都只在MySQL 8.0上才有。

(1) 整体架构

学习笔记(一)MySQL复制原理及应用场景_第5张图片

(2) 搭建
1. 手工搭建

学习笔记(一)MySQL复制原理及应用场景_第6张图片

2. mysql shell搭建

非常之方便,但是需要先装好mysql shell,它会自动执行修改配置那些操作
学习笔记(一)MySQL复制原理及应用场景_第7张图片

10.177.54.161:3000
10.177.54.161:3306
10.177.54.159:3000

var c=dba.getCluster('zstCluster')
c.status()
会自动生成一个数据库mysql_innodb_cluster_metadata

在这里插入图片描述

学习笔记(一)MySQL复制原理及应用场景_第8张图片

(3) 错误

学习笔记(一)MySQL复制原理及应用场景_第9张图片

  • study.tb2表缺少主键或等效列

  • binlog_transaction_dependency_tracking 是一个系统变量,用于控制 MySQL 是否跟踪事务之间的依赖关系。

    • COMMIT_ORDER:MySQL 使用事务的提交顺序来确定它们之间的依赖关系。

    • WRITESET :MySQL 使用事务的写集来确定它们之间的依赖关系。

      在 MGR 中,如果使用 COMMIT_ORDER 模式,可能会导致数据同步的问题。这是因为在 MGR 中,由于多个节点同时执行事务,可能会出现事务提交顺序不一致的情况,从而导致数据同步错误。而使用 WRITESET 模式,则会基于事务的写集来确定它们之间的依赖关系,不受事务提交顺序的影响,可以更好地适应 GTID 同步机制。

(4) 要求和限制
  1. 引擎必须为innodb,因为需事务支持在commit时对各节点进行冲突检查
  2. 每个表必须有主键,在进行事务冲突检测时需要利用主键值对比
  3. 必须开启binlog且为row格式
  4. 开启GTID,且主从状态信息存在于表中(–master-info-repository=TABLE, --relay-log-info-repository=TABLE),–log-slave-updates打开
  5. 和普通复制binlog校验不能共存,需设置–binlog-checksum=none
  6. 不支持gap lock(间隙锁),隔离级别需设置为read_commited
  7. 不支持对表进行锁操作(lock/unlock table),不会发送到其他节点执行,影响需要对表进行加锁操作的情况,列入mysqldump全表备份恢复操作
  8. 不支持serializable(序列化)隔离级别
  9. DDL语句不支持原子性,不能检测冲突,执行后需自行校验是否一致,不支持外键:多主不支持,单主模式不存在此问题
  10. 使用奇数个节点,最多支持9个节点:超过9台server无法加入组

四、实战

1. 配置

[mysqld]
server_id=XXXX        #可以是ip的最后一位+port,如1613000
log-bin=
binlog_format=row
gtid-mode=on
enforce_gtid_consistency=on
#注意Datadir下的auto.cnf
#10.177.54.161:3000
1.MySQL初始化
2.创建一个复制使用的账号
	create user 'repl'@'%' identified by 'repl4slave';
	grant replication slave on *.* to 'repl'@'%';
3.clone plugin安装&创建一个clone plugin使用的账号
	INSTALL PLUGIN clone SONAME 'mysql_clone.so';
	create user 'ruamy'@'%' identified by 'ruamyruamy';
	grant all privileges on *.* to 'ruamy';
#10.177.54.159:3001
1.MySQL初始化
2.创建一个复制使用的账号
3.clone plugin安装&创建一个clone plugin使用的账号
4.set global clone_valid_donor_list='10.177.54.161:3000';
5.clone instance from 'ruamy'@'10.177.54.161':3000 identified by 'ruamyruamy';
6.change master to master_host='10.177.54.161',
	master_port=3001,
	master_user='repl',
	master_password='repl4slave',
	master_ssl=1,
	master_auto_position=1;
	
7.show master status;
  start slave;
  show slave status\G

你可能感兴趣的:(MySQL,学习,笔记,mysql)