zoukankan      html  css  js  c++  java
  • 基于Docker实现MYSQL主从复制

    前言

      文章来源:ytao微信公众号

    MySQL的主从复制是实现应用的高性能,高可用的基础。对于数据库读操作较密集的应用,通过使数据库请求负载均衡分配到不同 MySQL服务器,可有效减轻数据库压力。当遇到 MySQL单点故障中,也能在短时间内实现故障切换。本文就 MySQL的内建的复制功能进行阐述。

    版本

    • MySQl5.7.17

    • CentOS7.4.1708

    • Docker1.13.1

    概述

    MySQL复制数据流程:

    1. 主库在数据更新提交事务之前,将事件异步记录到binlog二进制日志文件中,日志记录完成后存储引擎提交本次事务

    2. 从库启动一个I/O线程与主库建立连接,用来请求主库中要更新的binlog。这时主库创建的binlog dump线程,这是二进制转储线程,如果有新更新的事件,就通知I/O线程;当该线程转储二进制日志完成,没有新的日志时,该线程进入sleep状态。

    3. 从库的I/O线程接收到新的事件日志后,保存到自己的relay log(中继日志)中

    4. 从库的SQL线程读取中继日志中的事件,并执行更新保存。 

    配置主从库

    主库my.cnf配置

    在主库的my.cnf中打开二进制日志,并设置服务Id。

    log-bin = mysql-bin
    
    server-id = 1

    注意 server-id必须是一个唯一的数字,必须主从不一致, 且主从库必须设置项。

    从库my.cnf配置

    log-bin = mysql-bin
    server-id = 2
    log-slave-updates = 1
    read-only = 1

    从库也开启 log-binlog-slave-updates设置为从库重放中继日志时,记录到自己的二进制日志中,可以让从库作为其他服务器的主库,将二进制日志转发给其他从库,在做一主多从方案时可考虑该种方案。

    Dockerfile构建MySQL镜像

    构建所需文件

    这里masterslave文件各自保存不共用,先创建文件夹/usr/local/mysql然后在目录创建masterslave两个目录,再各自创建data文件夹

    • data 目录用来保存数据文件的目录

    • Dockerfile 保存Dockerfile内容

    • init.sql 初始化数据库的SQL

    • my.cnf 数据库配置文件,配置方式上面已提到

    • start.sh Dockerfile构建MySQL时的脚本

    Dockerfile 内容

    # 利用 mysql 镜像创建新的镜像
    
    FROM mysql:5.7.17
    
    ENV MYSQL_ROOT_PASSWORD ytao
    
    COPY start.sh /mysql/start.sh
    
    COPY my.cnf /etc/mysql/my.cnf
    
    COPY init.sql /mysql/init.sql
    
    EXPOSE 3306
    
    CMD ["sh", "/mysql/start.sh"]

    这里的masterslave都是基于同一个镜像构建,使用的存储引擎和其他的组件最好是同一中,不然在复制过程中可能会出现异常。

    init.sql 初始化数据

    -- 创建 data_copy 数据库
    
    DROP DATABASE IF EXISTS `data_copy`;
    
    CREATE DATABASE `data_copy` /*!40100 DEFAULT CHARACTER SET utf8mb4 collate utf8mb4_general_ci */;
    
    -- 创建 person 表
    
    USE `data_copy`;
    
    DROP TABLE IF EXISTS `person`;
    
    CREATE TABLE `person` (
    
    `id` int(32) NOT NULL,
    
    `name` varchar(255) DEFAULT NULL,
    
    PRIMARY KEY (`id`)
    
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

    创建data_copy数据库和person表。

    start.sh 脚本

    #!/bin/sh
    
    echo '启动mysql'
    
    service mysql start
    
    sleep 5
    
    echo '初始化数据库'
    
    mysql -uroot -pytao < /mysql/init.sql
    
    echo '初始化完成!'
    
    tail -f /dev/null

    构建masterslave镜像并运行容器

    构建master镜像

    docker build -t master/mysql .

    构建slave镜像

    docker build -t slave/mysql .

    构建成功会返回Successfuly,或通过docker images命令查看镜像

    使用刚构建的镜像来运行容器

    # master 容器
    
    docker run --name master -p 3306:3306 -v /usr/local/mysql/master/data/:/var/lib/mysql -d master/mysql
    
    
    # slave 容器
    
    docker run --name slave -p 3307:3306 -v /usr/local/mysql/slave/data/:/var/lib/mysql -d slave/mysql

    指定 master端口为 3306, slave端口为 3307,挂载data目录为保存数据的目录。

    连接到数据库后验证数据库是否初始化成功

    查看 log-bin 是否开启

    创建复制账号

    前面有提到从库I/O线程要与主库建立连接,所以需要用到账号进行验证。账号除了要有连接权限(REPLICATION CLIENT),同时还要有复制权限(REPLICATION SLAVE)。

    GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO muser@'%' IDENTIFIED BY 'ytao';

    这里设置的访问地址是开放的,实际使用过程中安全起见一定要指定访问地址。

    从库启动复制

    从库连接到主库,获取到二进制日志后重放。这里首先要配置上面创建的账号进行连接,使用命令进行相应的设置。

    CHANGE MASTER TO
    
    MASTER_HOST = '47.107.xx.xxx',
    
    MASTER_PORT = 3306,
    
    MASTER_USER = 'muser',
    
    MASTER_PASSWORD = 'ytao',
    
    MASTER_LOG_FILE = 'mysql-bin.000006';

    到这里复制还没有启动,需要再从库中启动

    START SLAVE;

    使用SHOW SLAVE STATUSG;命令查看启动后的情况

    上面标记的输出信息Slave_IO_Running:YesSlave_SQL_Running:Yes可以看到I/O线程和SQL线程已启动运行中。

    测试同步数据

    如果在主库中添加,更新或删除一个数据,那么从库中应该也有与主库对应的数据变化。向主库添加一条数据

    INSERT INTO `data_copy`.`person` (`id`, `name`) VALUES ('1', 'ytao');

    查询从库数据,数据已被同步过来。

    总结

    上述是最简单最基本的配置,但是理解上面的配置过程,就可以根据自身情况定制不同方案,实现一主多从,主主复制(主动-主动或主动-被动模式)等等来满足自身需求。MySQL的复制虽然使用简单方便,但也伴随着一些问题需要我们在使用中进行解决,比如:不能从服务器异常停止中恢复,数据同步的延迟等等,还好现在遇到的大部分问题在行业中已得到相应的解决。对这方面感兴趣的可以去了解下现在解决这些问题的中间件实现方案。

    冷眉横对千夫指,俯首甘为孺子牛。
  • 相关阅读:
    使用js获取表单元素的值
    分页问题
    空值转换问题
    MySQL数据库操作基础
    二叉树DFS遍历递归和非递归做法
    BFS经典算法
    stack & queue及经典例题
    Recursion & Binary search
    Leetcode之SpiralMatrix(I,II)
    Leetcode之贪心算法
  • 原文地址:https://www.cnblogs.com/yujian0817/p/13038917.html
Copyright © 2011-2022 走看看