MySQL主从复制:半同步、异步

MySQL主从复制:半同步、异步



大纲

  • 前言
  • 如何对MySQL进行扩展?
  • MySQL Replication WorkFlow
  • MySQL主从复制模式
  • 实战演练
    • MySQL异步复制实现
    • MySQL半同步复制实现
  • 实验中的思考
  • 总结

前言

本篇我们介绍MySQL Replication的相关内容, 我们首先介绍MySQL CLuster的实现原理和如何一步步构建一个MySQL Replication Cluster

看懂本文需要了解: MySQL基本操作,MySQL日志类型及其作用

如何对MySQL进行扩展?

大家之前应该了解; 在单台服务器性能不足时, 有两种方式进行扩展

  • Scale Up ; 垂直扩展
  • Scale Out ; 水平扩展

    垂直扩展: 指的是提升单台服务器的性能(硬件)来提升服务的性能 
    水平扩展: 指的是添加服务器通过负载均衡的方式来分担单台服务器的负载, 从而提升服务的性能

我们可以通过LVS, HAProxy, Nginx等软件实现一些服务的负载均衡, 但是如果要用到MySQL上就会有一些问题, 如下

  • 如何保证多台MySQL服务器数据的一致性
  • 如何保证多台服务器同时提交事务导致数据的完整性
  • 如何保证一台服务器宕机时, 其的事务能够正常提交或ROLLBACK

我们需要考虑的问题比扩展WEB服务多太多了, 毕竟大家都知道, 数据无价, 在很多重要场景中, 数据不能有半点闪失, 但是MySQL对这方面做得并不是很好, 而Oracle数据库在这方面特别的厉害, 所以众多的银行都采用Oracle数据库存储客户的账户信息等, 这么说, 难道我们就不用MySQL了么? 这显然不可能, 我们首先来介绍一下MySQL Replication Cluster的几种同步数据方式

  • Synchronous Replication 同步复制
  • Asynchronous Replication 异步复制
  • Semisynchronous Replication 半同步复制

    同步复制: 指的是客户端连接到MySQL主服务器写入一段数据, MySQL主服务器同步给MySQL从服务器需要等待从服务器发出同步完成的响应才返回客户端OK, 这其中等待同步的过程是阻塞的, 如果有N台从服务器, 效率极低 
    异步复制: 指的是客户端连接到MySQL主服务器写入一段数据, MySQL主服务器将写入的数据发送给MySQL从服务器, 然后直接返回客户端OK, 可能从服务器的数据会和主服务不一致 
    半同步复制:指的是客户端连接到MySQL主服务器写入一段数据, MySQL主服务器只将数据同步复制给其中一台从服务器, 半同步复制给其他的从服务器, 来达到其中一台从服务器完全同步的效果

MySQL Replication WorkFlow

Master/Slave工作流程

建立主从关系后, 主服务器如果有数据修改之后, BINLOG会更新, 从服务通过IO-Thread读取主服务器的BINLOG到本地的Relay Log, 再通过SQL-Thread对其进行重放(replay), 从而同步到本地

MySQL主从复制模式

在不同的业务模型中我们可以采用不同的MySQL主从复制架构, 一般分为以下两种

  • Master/Slave
  • Master/Master

    Master/Slave: 指的是一主多从模式, 这种模式下可以有效的分担读请求, 但是写请求并不能完成负载分担、从节点可能数据不一致, 并且如果Master宕机了客户端就无法进行写操作了, 还是有很多问题的 
    Master/Master: 指的是多主模式, 这种模式中的多台MySQL服务器都是Master, 也就意味着都可以进行读写操作, 但是有着更为严重的问题, 多个客户端同时写入数据时由于复制延迟可能到导致数据冲突等严重问题

常用的架构图

我们可以使用keepalived实现Master高可用, 并且使用半同步模式实现数据的完全同步

上面那种方式太占用Master的带宽, 我们可以让一台Slave扮演为Master, 为其他Slave同步数据

实战演练

MySQL异步复制实现

实验拓扑

环境部署

我们需要在各台服务器上安装MySQL, 这里使用的是rpm包安装, 版本为5.1

[root@node1 ~]# yum install mysql-server -y[root@node2 ~]# yum install mysql-server -y[root@node3 ~]# yum install mysql-server -y

配置文件

node1配置文件(master)

    [mysqld]    datadir=/var/lib/mysql    socket=/var/lib/mysql/mysql.sock    user=mysql    # Disabling symbolic-links is recommended to prevent assorted security risks    symbolic-links=0    innodb_file_per_table = 1    log_bin=master-log    #开启二进制日志    log_bin_index=1    server_id=1           #设置serverid

    [mysqld_safe]    log-error=/var/log/mysqld.log    pid-file=/var/run/mysqld/mysqld.pid

node2配置文件(slave1)

    [mysqld]    datadir=/var/lib/mysql    socket=/var/lib/mysql/mysql.sock    user=mysql    # Disabling symbolic-links is recommended to prevent assorted security risks    symbolic-links=0    relay-log=relay-log         #开启relay日志    innodb_file_per_table = 1    read-only = 1               #设置只读    server_id = 2               #设置serverid

    [mysqld_safe]    log-error=/var/log/mysqld.log    pid-file=/var/run/mysqld/mysqld.pid

node3配置文件(slave2)

    [mysqld]    datadir=/var/lib/mysql    socket=/var/lib/mysql/mysql.sock    user=mysql    # Disabling symbolic-links is recommended to prevent assorted security risks    symbolic-links=0    relay-log=relay-log    innodb_file_per_table = 1    read-only = 1    server_id = 3

    [mysqld_safe]    log-error=/var/log/mysqld.log    pid-file=/var/run/mysqld/mysqld.pid

##启动mysql##注意: serverid一定不能相同

配置Master

Slave节点进行同步需要通过一个特定的用户进行, 所以我们需要创建一个用户并赋予REPLICATION SLAVE, REPLICATION CLIENT权限

mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO ‘rpuser‘@‘%‘ IDENTIFIED BY ‘passwd‘;Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;Query OK, 0 rows affected (0.00 sec)

mysql> SHOW MASTER STATUS;   我们要记录下pos的数值+-------------------+----------+--------------+------------------+| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |+-------------------+----------+--------------+------------------+| master-log.000005 |      523 |              |                  |+-------------------+----------+--------------+------------------+1 row in set (0.00 sec)

配置Slave(1)

mysql> CHANGE MASTER TO    -> MASTER_HOST=‘172.16.1.2‘,    -> MASTER_USER=‘rpuser‘,    -> MASTER_PASSWORD=‘passwd‘,    -> MASTER_LOG_FILE=‘master-log.000005‘,    -> MASTER_LOG_POS=523;Query OK, 0 rows affected (0.01 sec

mysql> SHOW SLAVE STATUS\G;  #查看相应信息#########省略##################Master_Log_File: master-log.000005Read_Master_Log_Pos: 523Relay_Log_File: relay-log.000001Relay_Log_Pos: 4Relay_Master_Log_File: master-log.000005Slave_IO_Running: No    #IO-thread没有启动Slave_SQL_Running: No   #SQL-thread没有启动#########省略##################

mysql> START SLAVE;  #启动sql-thread和io-thred

mysql> SHOW SLAVE STATUS\G;  #查看相应信息 Query OK, 0 rows affected (0.00 sec)#########省略##################Master_Log_File: master-log.000005Read_Master_Log_Pos: 523Relay_Log_File: relay-log.000002Relay_Log_Pos: 252Relay_Master_Log_File: master-log.000005Slave_IO_Running: Yes     #IO-thread启动Slave_SQL_Running: Yes    #SQL-thread启动#########省略##################

配置slave(2)

过程和配置slave(1)相同, 不做演示

测试主从复制

##在主服务器上创建数据库和表

[[email protected] ~]# mysql

mysql> SHOW DATABASES;+--------------------+| Database           |+--------------------+| information_schema || mysql              || test               |+--------------------+3 rows in set (0.00 sec)

mysql> CREATE DATABASE replication;Query OK, 1 row affected (0.00 sec)

mysql> USE replication;Database changedmysql> CREATE TABLE t1 (id int unsigned auto_increment primary key, name char(30));Query OK, 0 rows affected (0.01 sec)

mysql> DESC t1;+-------+------------------+------+-----+---------+----------------+| Field | Type             | Null | Key | Default | Extra          |+-------+------------------+------+-----+---------+----------------+| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment || name  | char(30)         | YES  |     | NULL    |                |+-------+------------------+------+-----+---------+----------------+2 rows in set (0.00 sec)

mysql> SHOW MASTER STATUS;+-------------------+----------+--------------+------------------+| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |+-------------------+----------+--------------+------------------+| master-log.000005 |      765 |              |                  |+-------------------+----------+--------------+------------------+1 row in set (0.00 sec)
##在slave服务器测试

[[email protected] ~]# mysql

mysql> SHOW DATABASES;+--------------------+| Database           |+--------------------+| information_schema || mysql              || replication        || test               |+--------------------+4 rows in set (0.00 sec)

mysql> use replication;Reading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -A

Database changedmysql> DESC t1;+-------+------------------+------+-----+---------+----------------+| Field | Type             | Null | Key | Default | Extra          |+-------+------------------+------+-----+---------+----------------+| id    | int(10) unsigned | NO   | PRI | NULL    | auto_increment || name  | char(30)         | YES  |     | NULL    |                |+-------+------------------+------+-----+---------+----------------+2 rows in set (0.00 sec)

mysql> SHOW SLAVE STATUS\G;

#########省略##################Master_Log_File: master-log.000005Read_Master_Log_Pos: 765   #已经同步Relay_Log_File: relay-log.000002Relay_Log_Pos: 494Relay_Master_Log_File: master-log.000005Slave_IO_Running: YesSlave_SQL_Running: Yes#########省略##################

MySQL半同步复制实现

由于MySQL半同步复制在MySQL5.5以后才以插件的形式进行提供, 所以这里我们的MySQL要换成5.5版本的MariaDB

由于很多步骤和上面重复,我就不写出来了,先配置成M/S然后再按照我下面操作

实验拓扑

配置master

半同步的插件在/usr/lib64/mysql/plugin下, master用的semisync_master.so,slave用的semisync_slave.so,

MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so‘;Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_enabled = 1;Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_timeout = 2000;   #设置超时时间为2SQuery OK, 0 rows affected (0.00 sec)

配置slave

MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so‘;Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> SET GLOBAL rpl_semi_sync_slave_enabled=1;Query OK, 0 rows affected (0.00 sec)

验证

因为在我的环境中,即使是半同步复制,也是直接就完成,看不出效果,所以我们故意将slave节点关闭[[email protected] ~]# service mysql stop

##master创建数据库MariaDB [(none)]> CREATE DATABASE TEST3;Query OK, 1 row affected (2.00 sec)        #等待2s, 超时不再等待,直接创建

MariaDB [(none)]> CREATE DATABASE TEST4;Query OK, 1 row affected (0.00 sec)

##完成,这个可能不是特别直观,但是由于我这边环境实在做不出效果,望大家理解

实验中的思考

  • 如果主从服务器数据相差较大, 最好先使用主服务器的二进制日志在从服务器上replay一篇, 然后再进行同步

总结

这篇其实还打算写SSL复制的,但是因为时间比较紧,就没有写了,总体来说不是特别的满意,有很多地方没有说明白,还望大家谅解。

作者水平很低, 如果有错误及时指出, 如果你觉得本文写的好请点一波赞~(≧▽≦)/~ 
作者: AnyISaIln QQ: 1449472454 
感谢: MageEdu

时间: 2024-10-14 12:13:37

MySQL主从复制:半同步、异步的相关文章

MySQL主从复制半同步复制原理及搭建

在MySQL5.5之前的版本中,MySQL的复制是异步复制,主库和从库的数据之间存在一定的延迟,比如网络故障等各种原因,这样子容易存在隐患就是:当在主库写入一个事务成功后并提交了,但是由于从库延迟没有及时得到主库推送的Binlog日志时,主库突然宕机了,那么此时从库就可能损失这个事务,从而造成主从不一致的状况. 因此我们MySQL5.5版本之后引入了半同步复制的概念 半同步复制的原理: 半同步复制时,为了保证主库上的每一个Binlog事务都能够被可靠的复制到从库上,主库在每次事务成功提交时,并不

MariaDB(MySQL):半同步复制+ssl+复制过滤

一.半同步复制   1.mysql的复制 通过记录主服务器的二进制日志,并在从服务器上进行重放(replay)完成复制,默认都是异步进行的. 2.半同步复制 半同步复制是google贡献给MySQL的一个补丁,在MySQL 5.5之后就支持了,MariaDB都是支持的. MySQL的插件,一般在MySQL安装目录下; 半同步复制插件默认没有启用,需要自己安装,/usr/local/mysql/lib/plugin可以看到semisync_master.so和semisync_slave.so和其

mysql 主从半同步模式和数据库同步过滤

在mysql主从架构中,默认采用的是异步模式,也就是在master中将数据保存在数据库,再将操作写到bin-log中即响应给客户端.至于slave是否同步了二进制文件,是否完成了本地操作,master无从得知.异步模式固然能以最快的速度响应给客户端,减少用户的等待时间,但在一些数据同步.安全性较高的场景,要求slave中的数据要尽最大能力与master保持一致,那么半同步模式就可以用上了. mysql的半同步模式是以插件的方式由google提供的.主要文件在${mysql_home}/lib/p

PostgreSQL的同步级别与MySQL的半同步after_sync比较

MySQL的半同步中通过binlog进行流复制,同步级别和PostgreSQL对比可以发现: PostgreSQL                MySQL off local                         after_commit          remote_write            after_sync remote_apply on 所以,整体来说MySQL的日志同步上还是没有PostgreSQL做的严谨,在金融系统中,PostgreSQL的日志同步级别都是设

mysql主从复制--mysql-5.5异步、半同步配置

背景介绍 mysql5.5之前版本,mysql主从复制比较简单 mysql5.6:gtid,multi-thread replication master 1 启用二进制日志 log-bin = master-bin log-bin-index = master-bin.index 2 选择一个唯一的server id server-id = [0~2^32] 3 创建具有复制权限的用户 replication slave,复制的从节点 replication client,联系master,获

MySQL主从复制--MySQL5.5异步、半同步配置

大纲 一.主从复制复制原理 二.主从复制的作用及复制类型 三.MySQL5.5异步复制的实现 四.MySQL5.5半同步复制的实现 一.主从复制原理 工作原理 1.当Master接收到了一个写请求,处理写请求,将结果保存至磁盘中,并且会将此操作记录到二进制日志文件中 2.Slave会从Master的二进制日志中读取其中的事件保存至本地的中继日志中 3.Slave会启动一个线程来逐条读取中继日志中的事件并应用于本地的 二.主从复制的作用及复制类型 复制的作用 辅助实现备份 提供类似高可用的机制 异

Mysql的ssl主从复制+半同步主从复制

准备工作 1.主从服务器时间同步 [[email protected] ~]# crontab -e */30 * * * * /usr/sbin/ntpdate 172.16.0.1 &>/dev/null ? ? MariaDB(10以上版本)的编译安装 部署配置 2.mysql说明 (1) 主服务器 hostname:master ? ?IP:172.16.21.2 ? (1) 从服务器 hostname:master ? ?IP:172.16.21.3 ? (3) 数据目录 ? /m

MySQL-5.5之主从复制 + 半同步

环境: [[email protected] ~]# cat /etc/redhat-release CentOS release 6.8 (Final) [[email protected] ~]# uname -r 2.6.32-642.el6.x86_64 Master  IP  192.168.0.88/24  eth0 Slave   IP  192.168.0.90/24  eth0 主从复制原理: 当用户对数据有增删改操作时,主库本地存一份,另外会把用户增删改的操作记录在 binl

MySQL数据库半同步复制

半同步复制,是有一个从节点或者一部分从节点与主节点之间是同步复制的,其他的从节点仍是异步复制 半同步复制是谷歌公司贡献给MySQL的一个插件,默认在MySQL中没有此插件,所以要实现主从的版同步复制需要安装此插件 rpm -ql mariadb-server| grep semi #找到需要安装的插件,以so结尾 SHOW PLUGINS; #查看当前支持的插件,此处也能看到myisam和innodb也是插件类型 下面开始介绍如何配置主从版同步复制: 1.创建传统的主从复制功能的mysql,请参

MySQL增强半同步的搭建实验,和一些参数的个人理解

环境信息 role ip port hostname master 192.168.188.101 4306 mysqlvm1 slave 192.168.188.201 4306 mysqlvm1-1 5306 6306 7306 MySQL版本 5.7.26 前置条件 已配置好主从复制. 配置增强半同步 1.加载lib,所有主从节点都要配置. 主库:install plugin rpl_semi_sync_master soname 'semisync_master.so'; 从库:inst