mysql主从同步原理与实战

1、什么是mysql主从同步?

当master(主)库的数据发生变化的时候,变化会实时的同步到slave(从)库。

2、主从同步有什么好处?

  • 水平扩展数据库的负载能力。
  • 容错,高可用。Failover(失败切换)/High Availability
  • 数据备份。

3、主从同步的原理是什么?

首先我们来了解master-slave的体系结构。

如下图:

mysql主从同步原理与实战_第1张图片

不管是delete、update、insert,还是创建函数、存储过程,所有的操作都在master上。当master有操作的时候,slave会快速的接收到这些操作,从而做同步。

但是,这个机制是怎么实现的呢?

在master机器上,主从同步事件会被写到特殊的log文件中(binary-log);在slave机器上,slave读取主从同步事件,并根据读取的事件变化,在slave库上做相应的更改。

如此,就实现了主从同步了!

下面我们来详细的了解。

3.1主从同步事件有哪些

上面说到:

在master机器上,主从同步事件会被写到特殊的log文件中(binary-log);

主从同步事件有3种形式:statement、row、mixed。

  1. statement:会将对数据库操作的sql语句写入到binlog中。
  2. row:会将每一条数据的变化写入到binlog中。
  3. mixed:statement与row的混合。Mysql决定什么时候写statement格式的,什么时候写row格式的binlog。

3.2在master机器上的操作

当master上的数据发生改变的时候,该事件(insert、update、delete)变化会按照顺序写入到binlog中。

binlog dump线程

当slave连接到master的时候,master机器会为slave开启binlog dump线程。当master 的 binlog发生变化的时候,binlog dump线程会通知slave,并将相应的binlog内容发送给slave。

3.3在slave机器上的操作

当主从同步开启的时候,slave上会创建2个线程。

  • I/O线程。该线程连接到master机器,master机器上的binlog dump线程会将binlog的内容发送给该I/O线程。该I/O线程接收到binlog内容后,再将内容写入到本地的relay log。
  • SQL线程。该线程读取I/O线程写入的relay log。并且根据relay log的内容对slave数据库做相应的操作。

3.4如何在master、slave上查看上述的线程?

使用SHOW PROCESSLIST命令可以查看。

如图,在master机器上查看binlog dump线程。

mysql主从同步原理与实战_第2张图片

如图,在slave机器上查看I/O、SQL线程。

mysql主从同步原理与实战_第3张图片

4、讲了这么多,一图以蔽之

mysql主从同步原理与实战_第4张图片

1、Introduction

之前写过一篇文章:Mysql主从同步的原理。

相信看过这篇文章的童鞋,都摩拳擦掌,跃跃一试了吧?

今天我们就来一次mysql主从同步实战!

2、环境说明

os:ubuntu16.04

mysql:5.7.17

下面的实战演练,都是基于上面的环境。当然,其他环境也大同小异。

3、进入实战

工具

2台机器:

master IP:192.168.33.22

slave  IP:192.168.33.33

master机器上的操作

1、更改配置文件

我们找到文件 /etc/mysql/mysql.conf.d/mysqld.cnf

配置如下:

?

1

2

3

bind-address = 192.168.33.22 #your master ip

server-id = 1 #在master-slave架构中,每台机器节点都需要有唯一的server-id

log_bin = /var/log/mysql/mysql-bin.log #开启binlog

2、重启mysql,以使配置文件生效。

?

1

sudo systemctl restart mysql

3、创建主从同步的mysql user。

?

1

2

3

4

5

6

7

8

9

10

$ mysql -u root -p

Password:

 

##创建slave1用户,并指定该用户只能在主机192.168.33.33上登录。

mysql> CREATE USER 'slave1'@'192.168.33.33' IDENTIFIED BY 'slavepass';

Query OK, 0 rows affected (0.00 sec)

 

##为slave1赋予REPLICATION SLAVE权限。

mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave1'@'192.168.33.33';

Query OK, 0 rows affected (0.00 sec)

4、为MYSQL加读锁

为了主库与从库的数据保持一致,我们先为mysql加入读锁,使其变为只读。

?

1

2

mysql> FLUSH TABLES WITH READ LOCK;

Query OK, 0 rows affected (0.00 sec)

5、记录下来MASTER REPLICATION LOG 的位置

该信息稍后会用到。

?

1

2

3

4

5

6

7

mysql> SHOW MASTER STATUS;

+------------------+----------+--------------+------------------+-------------------+

| File    | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000001 |  613 |    |     |     |

+------------------+----------+--------------+------------------+-------------------+

1 row in set (0.00 sec)

6、将master DB中现有的数据信息导出

?

1

$ mysqldump -u root -p --all-databases --master-data > dbdump.sql

7、接触master DB的读锁

?

1

mysql> UNLOCK TABLES;

8、将步骤6中的dbdump.sql文件copy到slave

?

1

scp dbdump.sql [email protected]:/home/ubuntu

slave机器上的操作

1、更改配置文件

我们找到文件 /etc/mysql/mysql.conf.d/mysqld.cnf

更改配置如下:

?

1

2

3

bind-address = 192.168.33.33 #your slave ip

server-id = 2 #master-slave结构中,唯一的server-id

log_bin = /var/log/mysql/mysql-bin.log #开启binlog

2、重启mysql,以使配置文件生效

?

1

sudo systemctl restart mysql

3、导入从master DB。 导出的dbdump.sql文件,以使master-slave数据一致

?

1

$ mysql -u root -p < /home/ubuntu/dbdump.sql

4、使slave与master建立连接,从而同步

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

$ mysql -u root -p

Password:

 

mysql> STOP SLAVE;

Query OK, 0 rows affected, 1 warning (0.00 sec)

 

mysql> CHANGE MASTER TO

 -> MASTER_HOST='192.168.33.22',

 -> MASTER_USER='slave1',

 -> MASTER_PASSWORD='slavepass',

 -> MASTER_LOG_FILE='mysql-bin.000001',

 -> MASTER_LOG_POS=613;

Query OK, 0 rows affected, 2 warnings (0.01 sec)

 

mysql> START SLAVE;

Query OK, 0 rows affected (0.00 sec)

MASTER_LOG_FILE='mysql-bin.000001'与MASTER_LOG_POS=613的值,是从上面的 SHOW MASTER STATUS 得到的。

mysql 主从复制原理

主从形式


 

mysql主从复制 灵活

  • 一主一从
  • 主主复制
  • 一主多从---扩展系统读取的性能,因为读是在从库读取的;
  • 多主一从---5.7开始支持
  • 联级复制---

 

 

用途及条件


 

mysql主从复制用途

  • 实时灾备,用于故障切换
  • 读写分离,提供查询服务
  • 备份,避免影响业务

 

主从部署必要条件:

  • 主库开启binlog日志(设置log-bin参数)
  • 主从server-id不同
  • 从库服务器能连通主库

 

主从原理


mysql主从复制原理

 

 

从库生成两个线程,一个I/O线程,一个SQL线程;

 

i/o线程去请求主库 的binlog,并将得到的binlog日志写到relay log(中继日志) 文件中;

主库会生成一个 log dump 线程,用来给从库 i/o线程传binlog;

 

SQL 线程,会读取relay log文件中的日志,并解析成具体操作,来实现主从的操作一致,而最终数据一致;

 

问题及解决方法


 

mysql主从复制存在的问题:

  • 主库宕机后,数据可能丢失
  • 从库只有一个sql Thread,主库写压力大,复制很可能延时

 

解决方法:

  • 半同步复制---解决数据丢失的问题
  • 并行复制----解决从库复制延迟的问题

 

半同步复制


 

mysql semi-sync(半同步复制)

半同步复制:

  • 5.5集成到mysql,以插件的形式存在,需要单独安装
  • 确保事务提交后binlog至少传输到一个从库
  • 不保证从库应用完这个事务的binlog
  • 性能有一定的降低,响应时间会更长
  • 网络异常或从库宕机,卡主主库,直到超时或从库恢复

 

主从复制--异步复制原理

 

半同步复制原理:

 

 

并行复制


 

mysql并行复制

  • 社区版5.6中新增
  • 并行是指从库多线程apply binlog
  • 库级别并行应用binlog,同一个库数据更改还是串行的(5.7版并行复制基于事务组)

设置

set global slave_parallel_workers=10;

设置sql线程数为10

 

 

其他


 

部分数据复制

主库添加参数:

binlog_do_db=db1
binlog_ignore_db=db1
binlog_ignore_db=db2

或从库添加参数

replicate_do_db=db1
replicate_ignore_db=db1
replicate_do_table=db1.t1
replicate_wild_do_table=db%.%
replicate_wild_ignore_table=db1.%

 

联级复制(常用)

A->B->C

B中添加参数:

log_slave_updates
B将把A的binlog记录到自己的binlog日志中

 

复制的监控:

show  slave status \G

 

复制出错处理

常见:1062(主键冲突),1032(记录不存在)

解决:

  • 手动处理
  • 跳过复制错误:set global sql_slave_skip_counter=1

 

 

 

总结


 

  • 主从形式
    • 一主一从
    • 一主多从--扩展系统读取性能
    • 多主一从--5.7开始支持
    • 主主复制
    • 联级复制
  • 用途:实时灾备的故障切换,读写分离,备份
  • 原理
    • 主:log dump线程传binlog;
      • i/o线程接受读取binlog,并写入relay log文件
      • sql线程从relay log 文件中读取binlog并持久化
  • 问题及解决
    • 主库宕机后,数据丢失
      • 半同步复制
    • 主库写压力大,因从库只有一个sql 线程来持久化,复制可能延迟
      • 并行复制
  • 半同步复制:
    • 原理
      • 事务在主库写完binlog后需要从库返回一个已接受,才放回给客户端;
    • 5.5集成到mysql,以插件的形式存在,需要单独安装
    • 确保事务提交后binlog至少传输到一个从库
    • 不保证从库应用完成这个事务的binlog
    • 性能有一定的降低
    • 网络异常或从库宕机,卡主库,直到超时或从库恢复
  • 并行复制
    • 原理:从库多线程apply binlog
    • 在社区5.6中新增
    • 库级别并行应用binlog,同一个库数据更改还是串行的
    • 5.7版本并行复制基于事务组
  • 部分数据复制
  • 联级复制(常用)
    • A->B->C
    • B中添加参数log_slave_updates
    • B将把A的binlog记录到自己的binlog日志中
  • 复制的监控
    • show slave status
  • 复制出错处理
    • 常见:1062(主键冲突),1032(记录不存在)
    • 解决:
      • 手动处理
      • 跳过复制错误:set global sql_slave_skip_counter=1
  • mysql主从复制是mysql高可用性,高性能(负载均衡)的基础
  • 简单,灵活,部署方式多样,可以根据不同业务场景部署不同复制结构
  • 复制过程中应该时刻监控复制状态,复制出错或延时可能给系统造成影响
  • mysql主从复制目前也存在一些问题,可以根据需要部署复制增强功能

参考文献:

【1】Mysql主从同步的实现原理

【2】详解Mysql主从同步配置实战

【3】mysql 主从复制原理

 

 

 

你可能感兴趣的:(数据库,数据库)