mysql 异步复制,半同步复制

Mysql复制

什么是Mysql复制?

复制是指将主数据库的 DDLDML 操作通过二进制日志传到复制服务器(也叫从库),然后在从库上对这些日志重新执行(也叫重做),从而使得从库和主库的数据保持同步。MysQL支持一台主库同时向多台从库进行复制,从库同时也可以作为其他服务器的主库,实现链状的复制 。

注意:

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

名称解释:

DMLdata manipulation language)数据操纵语言:

就是我们最经常用到的 SELECTUPDATEINSERTDELETE。 主要用来对数据库的数据进行一些操作。

DDLdata definition language)数据库定义语言:

其实就是我们在创建表的时候用到的一些sql,比如说:CREATEALTERDROP等。DDL主要是用在定义或改变表的结构,数据类型,表之间的链接和约束等初始化工作上

好处

  1. 如果主库出现问题,可以快速切换到从库提供服务。
  2. 可以在从库上执行查询操作, 降低主库的访问压力。
  3. 某些数据库维护工作,比如备份,可以在从库上执行,以避免备份期间影响主库的服务。

原理概述

( 1 )首先, MySQL主库在事务提交时会把数据变更作为事件 Events 记录在二进制日志文件Binlog; MySQL主库上的 sync_binlog参数控制 Binlog日志刷新到磁盘。

( 2 )主库推送二进制日志文件 Binlog中的事件到从库的中继日志 Relay Log, 之后从库根据中继日志 Relay Log重做数据变更操作,通过逻辑复制以此来达到主库和从库的数据一致。

MySQL通过3个线程来完成主从库间的数据复制:其中 Binlog Dump线程跑在主库上, I/0线程和 SQL线程跑在从库上。当在从库上启动复制时,首先创建I/0程连接主库,主库随后创建 Binlog Dump线程读取数据库事件并发送给 I/0线程, I0线程获取到事件数据后更新到从库的中继日志 Relay Log中去,之后从库上的 SQL线程读取中继日志RelayLog中更新的数据库事件并应用。

可以通过 SHOW PROCESSLIST命令在主库上査看 BinlogDump线程,BinlogDump 线程的状态可以看到, Mysql的复制是主库主动推送日志到从库去的,是属于“”日志的方式来做同步。同样地,在从库上通过 SHOW PROCESSLIST可以看到l/O线程和 SQL线程, l/O线程等待主库上的 Binlog Dump线程.发送事件并更新到中继日志 RelayLog, SQL线程读取中继日志并应用变更到数据库。

复制中的各类文件解析

日志文件

复制过程中涉及了两类非常重要的日志文件: 二进制日志文件( Binlog)和中继日志文件( Relay Log)。二进制日志文件( Binlog)会把 MysQL中的所有数据修改操作以二进制的形式记录到日志文件中,包括 CreateDropInsertUpdateDelete 操作等,但二进制日志文件(Binlog) 不会记录 Select操作, 因为 Select操作并不修改数据。

可以通过 show variables査看 Binlog的格式, Binlog支持 StatementRowMixed三种格式,也对应了 MysQL3种复制技术。

中继日志文件 Relay Log的文件格式、 内容和二进制日志文件 Binlog一样, 唯一的区别在于从库上的 SQL线程在执行完当前中继日志文件 Relay Log中的事件之后, SQL线程会自动删除当前中继日志文件 Relay Log,避免从库上的中继日志文件 Relay Log占用过多的磁盘空间。为了保证从库 Crash重启之后,从库的 I/0线程和 SQL线程仍然能够知道从哪里开始复制, 从库上默认还会创建两个日志文件 master.inforelay_log.info用来保存复制的进度。这两个文件在磁盘上以文件形式分别记录了从库的 l/0线程当前读取主库二进制日志 Binlog的进度和SQL线程应用中继日志 RelayLog的进度。

可以通过 show slave status命令能够看到当前从库复制的状态。

主要参数:

Master Host: 主库的 IP.

Master User 主库上, 主从复制使用的用户账号,

Master Port:主库 MySQL的端口号,

Master_Log_File:从库的I/0线程当前正在读取的主库 Binlog的文件 。

Read_Master Log_Pos:从库I/0线程当前读取到的位置。

Relay_Log_File: 从库 SQL线程正在读取和应用的中继日志 Relay Log的文件名 。

Relay_Log_Pos: 从库 SQL线程当前读取并应用的中继日志 Relay Log的位置。

Relay_Master_Log_File:从库 SQL线程正在读取和应用的 Relay Log对应于主库Binlog的文件名 。

Exec_Master_Log_Pos:中继日志 RelayLogRelay_Log_Pos位置对应于主库 Binlog 的位置。

三种复制技术

二进制日志文件 Binlog有三种格式:

Statement:基于 SQL语句级别的 Binlog,每条修改数据的 SQL都会保存到 Binlog里。

Row:基于行级别,记录每一行数据的变化,也就是将每行数据的变化都记录到 Binlog 里面, 记录得非常详细, 但是并不记录原始 SQL; 在复制的时候, 并不会因为存储过程或触发器造成主从库数据不一致的问通, 但是记录的日志量较 Statement格式要大得多 。

Mixed:混合StatementRow模式,默认情况下采用 Statement模式记录,某些情况下会切换到 Row模式

同时也对应了 MysQL复制的3种技术。

binlog_format设置为 Row格式时, MySQL实际上在 Binlog中逐行记录数据的变更, Row格式比 Statement格式更能保证从库数据的一致性(复制的是记录,而不是单纯操作 SQL)。当然, Row格式下的 Binlog的日志量很可能会增大非常多,在设置时需要考虑到磁盘空间间题。

参数 binlog_format可以在全局设置或者在当前 session动态设置: 在全局设置会影响所有session,而在当前 session设置则仅仅影响当前 Session。可以通过 SET命令来实时修改二进日志文件(Binlog)的格式。

相关命令

查看当前复制方式

show variables like '%binlog%format%';

更改复制方式

set global binlog_format = 'ROW';

set global binlog_format = 'STATEMENT';

常用的复制架构

复制的3种常见架构有一主多从复制架构、多级复制架构和双主复制/DrualMaster架构

一主多从

在主库读取请求压力非常大的场景下, 可以通过配置一主多从复制架构实现读写分离, 把大量对实时性要求不是特别高的读请求通过负载均衡分布到多个从库上, 降低主库的读取压力,在主库出现异常宕机的情况下, 可以把一个从库切换为主库继续提供服务 。

多级复制

一主多从的架构能够解决大部分读请求压力特别大的场景的需求, 考虑到 MysQL的复制是主库“推送” Binlog日志到从库,主库的 I/0压力和网络压力会随着从库的增加而增长(每个从库都会在主库上有一个独立的 Binlog Dump线程来发送事件), 而多级复制架构解决了一主多从场景下,主库额外的 I/0和网络压力。

双主复制/Dual Master

其实就是主库 MasterMaster2互为主从, client客户端的写请求都访问主库 Master,而读请求可以选择访问主库 MasterMaster2

双主多级复制架构

当然双主复制还能和主从复制联合起来使用:Master2库下配置从库 SlaveSlave2,这样即可通过从库 Slave等来分担读取压力,MyQL的双主多级复制架构如图所示

复制过程搭建

异步复制

主库执行完Commit后,在主库写入Binlog日志后即可成功返回客户端,无需等Binlog日志传送给从库

步骤:

1、确保主从库安装了相同版本的数据库。

2、在主库上,设置一个复制使用的账户,并授予 REPLICATION SLAVE权限。这里创建一个复制用户repl,可以从IP192.169.56.103的主机进行连接:

 

命令文本:GRANT REPLICATION SLAVE ON *.* To 'rep1'@'192.168.56.103' IDENTIFIED BY '1234test';

3、修改主数据库服务器的配置文件 my.cnf,开启 BINLOG,并设置 server-id的值。这两个参数的修改需要重新启动数据库服务才可以生效

my cnf中修改如下:

 

[mysqld]

log-bin=/home/ mysql/log/mysql-bin. log

server-id= 1

注意:如果mysql目录下无log目录,请先创建log目录

启动

./bin/mysqld_safe  --defaults-file=/home/mysql/mysql3306/my.cnf &

4、然后得到主库上当前的二进制日志名和偏移量值。这个操作的目的是为了在从数据库启动以后,从这个点开始进行数据的恢复。

执行show master status:

 

5、修改从数据库的配置文件 my.cnf,增加 server-id参数。注意 server-id的值必须是唯一的,不能和主数据库的配置相同,如果有多个从数据库服务器,每个从数据库服务器必须有自己唯一的 server-id值。

 

mycnf中修改如下:

[mysqld]

server-id=2

6、在从库上,使用 - -skip-slave- start选项启动从数据库,这样不会立即启动从数据库服务上的复制进程,方便我们对从数据库的服务进行进一步的配置:

 

操作命令:./bin/mysqld_safe  --defaults-file=/home/mysql/mysql3307/my.cnf --skip-slave-start 

7、对从数据库服务器做相应设置,指定复制使用的用户,主数据库服务器的IP、端口

以及开始执行复制的日志文件和位置等,参考代码如下:

mysql> CHANGE MASTER TO

->MASTER_HOST=master host name

->MASTER_USER=replication_user_name

-> MASTER PASSWORD=replication_password

->MASTER_LOG_FILE='recorded_log_file_name

->MASTER_LOG_POS=recorded _log_position

相关参数可以查看主库:

命令 show master status;

举例说明如下:

CHANGE MASTER TO MASTER_HOST='192.168.56.103',MASTER_PORT=3306,MASTER_USER='rep1',MASTER_PASSWORD='1234test' ,MASTER_LOG_FILE='mysql-bin.000001',MASTER_LOG_POS=428;

 

8、在从库上,启动 slave线程:

      start slave;

 

9、这时slave上执行 show processlist命令将显示类似如下的进程:

 

执行show slave status;将显示

 

11、在master上执行 show processlist命令将显示类似如下的进程:

 

12、测试一下:

在主库上新建数据库和表,并插入数据,看看从库中是否会自动创建相关的数据库和表、插入数据。

新建数据库和表之前:

 

 

主库中创建数据库orders和表order_exp,并插入数据

 

检查从库

 

半同步复制

MySQL5.5之前, MySQL的复制是异步操作,主库和从库的数据之间存在一定的延迟,这样存在一个隐患:当在主库上写人一个事务并提交成功,而从库尚未得到主库推送的 Binlog日志时,主库宕机了,例如主库可能因磁盘损坏、内存故障等造成主库上该事务 Binlog丢失,此时从库就可能损失这个事务,从而造成主从不一致。

而半同步复制,是等待其中一个从库也接收到Binlog事务并成功写入Relay Log之后,才返回Commit操作成功给客户端;如此半同步就保证了事务成功提交后至少有两份日志记录,一份在主库Binlog上,另一份在从库的Relay Log上,从而进一步保证数据完整性;半同步复制很大程度取决于主从网络RTT(往返时延),以插件 semisync_master/semisync_slave 形式存在。

安装比较简单,在上一小节异步复制的环境上,安装半同步复制插件即可。

(1)首先,判断 MySQL服务器是否支持动态增加插件:

mysql> select @@have_dynamic_loading;

 

2)确认支持动态增加插件后,检查 MySQL的安装目录下是否存在插件:

 

安装插件:

在主库上安装插件semisync_master.so:

mysql> install plugin rpl_semi_sync_master SONAME 'semisync_master.so'

从库上则安装 semisync_slave.so插件:

mysql> install plugin rpl_semi_sync_slave SONAME 'semisync_slave.so';

安装完成后,plugin表中能够看到刚才安装的插件

mysql> select * from mysql.plugin;

3) 需要分别在主库和从库上配置参数打开半同步semi-sync,默认半同步设置是不打开的,主库上配置全局参数:

     主库设置参数

mysql> set global rpl_semi_sync_master_enabled=1;

mysql> set global rpl_semi_sync_master_timeout=30000;

从库上一样配置全局参数:

mysql> set global rpl_semi_sync_slave_enabled=1;

4)其他步骤同异步复制

猜你喜欢

转载自www.cnblogs.com/zhoufly-blog/p/12363582.html