zoukankan      html  css  js  c++  java
  • 青蛙学Linux—MySQL主从复制

    MySQL主从复制基于MySQL官方提供的MySQL Replication技术,实现了数据从一个主服务器向一个或多个从服务器的同步。主从复制不仅是一种备份方式,更为MySQL高可用提供了数据同步的基础。

    1、MySQL Replication原理

    在MySQL Replication中,主服务器称为Master,从服务器称为Slave。Slave会从Master上拉取MySQL的二进制日志文件(Binary Log),然后将该日志解析为SQL语句并完全顺序的执行这些SQL语句以达到与Master上执行同样的SQL的效果,保证数据的一致性。

    整个过程具体如下:

    1. Slave上起一个IO线程,连接Master,然后请求从指定位置开始的Binary Log内容
    2. Master在接收请求之后读取指定位置开始的Binary Log内容并通过自身的IO线程返回给Slave的IO线程,返回的信息不仅包括Binary Log日志中的内容,还包括Binary Log日志的名称和这些信息在Binary Log中的位置
    3. Slave在接收到信息后,将获取到的Binary Log内容写入Relay Log中(名为mysql-relay-bin.xxx的文件),并将Binary Log的文件名和这些信息在Binary Log中的位置记录到名为master-info的文件中
    4. Slave的SQL线程在监测到Relay Log的更新后会马上解析Relay Log并生成SQL语句,然后执行这些SQL语句。至此,整个主从复制过程结束

    虽然MySQL Replication是异步的,但其性能非常高效,延时非常小。同时MySQL Replication支持链式复制,即Slave下还可以再链接Slave,Slave也可以充当Master的角色。

    注意:Slave会从Master上拉取Binary Log,所以在Master上必须开启MySQL的Binary Log功能。

    注意:在MySQL Replication中,只能在Master上更新数据库的数据,Slave只提供查询操作。

    2、MySQL Replication数据复制方式和常用架构

    2.1、数据复制方式

    MySQL Replication支持多种类型的数据复制方式,常见的有一下三种方式:

    • 基于语句的复制:默认采用的方式,效率非常高。是将在Master上执行的SQL语句在Slave上重新执行一次。一旦MySQL发现无法进行精确复制时,会自动选择基于行的复制
    • 基于行的复制:将Master上改变的内容复制到Slave,而不是执行SQL语句。MySQL 5.0版本起开始支持基于行的复制
    • 混合类型的复制:基于以上两种复制方式,一旦发现基于语句的复制无法精确完成,就会采用基于行的复制

    2.2、主从复制的常用架构

    MySQL Replication常见的实现架构有以下几种:

    • 一主一从:即一个Master和一个Slave,是最常见的架构
    • 一主多从:即一个Master和多个Slave。经常用在写操作不频繁,查询量比较大的业务环境
    • 主主互备:双主互备,两个MySQL相互将对方做为自己的Master,自己同时又是对方的Slave。主要用于对MySQL写操作要求比较高的环境中,避免MySQL的单点故障
    • 双主多从:在双主互备的基础上再加上多个Slave。主要用于MySQL写操作要求较高,同时查询量比较大的环境中

    MySQL Replication必须遵从以下原则:

    • 同一时刻只能有一个Master进行写操作
    • 每台MySQL要确保各自的Server ID唯一
    • 一个Slave可以将从Master获取的信息传递给其他的Slave
    • 必须保证MySQL版本的一致

    3、MySQL Replication一主一从架构的实现

    这里通过一个例子来演示如何配置MySQL以实现一主一从的主从复制架构。

    实验环境:

    • DB1:操作系统CentOS 7.6.1810,IP地址192.168.0.110,MySQL版本5.7.25
    • DB2:操作系统CentOS 7.6.1810,IP地址192.168.0.88,MySQL版本5.7.25

    配置DB1为Master,DB2为Slave。

    1、配置DB1和DB2的/etc/my.cnf

    在DB1上的/etc/my.cnf中添加以下内容:

    # 在[mysqld]下添加以下内容
    server-id=110
    log-bin=mysql-bin
    replicate-wild-ignore-table=mysql.%
    replicate-wild-ignore-table=information_schema.%
    • server-id:设置MySQL的Server ID,自行指定,只要两台MySQL不同即可
    • log-bin:开启MySQL的Binary Log并设置Binary Log文件名的前缀,这样会生成类似mysql-bin.000001的日志文件
    • replicate-wild-ignore-table:复制过滤选项,用于排除不需要复制的数据库和表,%表示指定数据库的所有表;另有一个replicate_wild_do_table选项,用于指定需要复制的数据库和表

    在DB2上的/etc/my.cnf中添加以下内容:

    # 在[mysqld]下添加以下内容
    server-id=88
    read-only=1
    log-bin=mysql-bin
    relay-log=mysql-relay-bin
    replicate-wild-ignore-table=mysql.%
    replicate-wild-ignore-table=information_schema.%
    • read-only:设置MySQL只读
    • relay-log:开启Slave上的Relay Log并设置Relay Log文件名的前缀

    2、手动同步数据库

    如果DB1上已经有数据库存在,则必须将这些库同步到DB2上。线上环境可以给MySQL加锁以阻止写入,或者停止MySQL服务。

    这里通过加锁的方式阻止数据写入,在MySQL交互模式使用以下命令加锁:

    mysql> flush tables with read lock;

    注意:此时不要关闭这个终端,关闭终端会导致锁失效,另外打开一个终端以进行下一步的操作。

    打包位于/db下的MySQL数据文件目录mysql:

    [root@localhost db]# tar -zcvf mysql.tar.gz mysql

    将这个压缩包通过scp发送到DB2上:

    [root@localhost db]# scp mysql.tar.gz root@192.168.0.88:/db

    将压缩包解压并覆盖DB2上的MySQL数据存储目录。然后依次重启DB1和DB2。

    关于server-uuid的问题

    在将BD1上的MySQL存储目录应用到DB2时,可能会产生因为server-uuid相同而导致DB2的MySQL无法启动的问题。这里可以通过删除DB2上MySQL数据存储目录下的auto.cnf文件解决,该文件删除后启动MySQL时会重新生成。

    3、在DB1上创建复制用户

    在DB1上创建专门的用户用于DB2复制Binary Log,该用户必须有从DB2登录的权限:

    mysql> grant replication slave on *.* to 'repl'@'192.168.0.88' identified by '123456';

    4、查看DB1上的Binary Log文件名和Position值

    在DB1上通过以下命令查看需要的内容:

    mysql> show master status;

    显示如下内容:

    +------------------+----------+--------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+--------------+------------------+-------------------+
    | mysql-bin.000001 |      448 |              |                  |                   |
    +------------------+----------+--------------+------------------+-------------------+

    这里记录下File栏和Position栏的内容,以便DB2使用。

    5、DB2上将DB1设置为Master并开启Slave

    在DB2上使用以下命令将DB1设置为自己的Master:

    mysql> change master to master_host='192.168.0.110',master_user='repl',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=448;

    使用以下命令在DB2上开启Slave:

    mysql> start slave;

    执行以下命令查看Slave运行状态:

    mysql> show slave statusG

    显示的信息如下:

    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.0.110
                      Master_User: repl
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000001
              Read_Master_Log_Pos: 900
                   Relay_Log_File: mysql-relay-bin.000002
                    Relay_Log_Pos: 320
            Relay_Master_Log_File: mysql-bin.000001
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes

    只要Slave_IO_Running和Slave_SQL_Running显示的是Yes,就说明Slave正常运行。至此,MySQL的主从复制配置完毕。

  • 相关阅读:
    Git 命令 stash cherry-pick reset rebase
    【操作系统】不同语言的线程实现机制对比及数据库锁问题
    【数据结构】搜索二叉树(BST)和普通二叉树的序列化与反序列化
    【自制编译器】读书笔记 -- JavaCC使用的JJ文件格式
    leetcode 874 Robot Simulation
    hihocoder 编程挑战赛75
    浪漫主义的起源--以赛亚柏林
    【美团笔试 2018-4-20 】编程题-1 测例100%通过 欧拉函数求解gcd
    【POJ SOJ HDOJ】HDU 2196 Computer 树中的最长路径
    【Java 核心】多线程笔记
  • 原文地址:https://www.cnblogs.com/yu2006070-01/p/10336146.html
Copyright © 2011-2022 走看看