zoukankan      html  css  js  c++  java
  • 使用docker 实现MySQL主从同步/读写分离

    1. 利用 docker 实现 mysql 主从同步 / 读写分离

    为了保证数据的完整和安全,mysql 设计了主从同步,一个挂掉还可以用另个。最近重构论坛,想来改成主从吧。担心失误,就先拿 docker 练练手。

    通过本文实际你会操作到。

    1. mysql 的主从同步
    2. docker 镜像和容器的创建
    3. docker 容器间的数据传递
    4. mycat 入门

    以下需要大于 100 的智商和 mysql 基础 docker 基础,linux 基础。

    没有也没事,就是看着会有点吃力。

    环境是 centos,mycat 是 1.6.docker 是 1.12.6

    1.1 下载 mysql 镜像

    docker pull mysql
    // ps:如果下载太慢,请添加腾讯源,依次执行
    echo "OPTIONS='--registry-mirror=https://mirror.ccs.tencentyun.com'" >> /etc/sysconfig/docker
    systemctl daemon-reload
    service docker restart
    

    或者直接去阿里仓库下 https://dev.aliyun.com/search.html 把上面的 --registry-mirror=https://mirror.ccs.tencentyun.com 换成你的专属源就可以

    下载完输入 docker images

    REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
    docker.io/mysql             latest              44a8e1a5c0b2        8 days ago          407 MB
    

    1.2 利用 mysql 镜像,创建用于主从同步的两个新镜像

    我们当前所在的服务器叫宿主服务器

    我们要利用 docker 虚拟两个 docker 容器服务器,一个主服务器,一个从服务器。

    1.2.1 创建 master(主) 和 slave(从) 两个文件夹

    /usr/mysql/master
    /usr/mysql/slave
    

    1.2.2 在 master 和 slave 文件夹下 创建 Dockerfile 内容为

    FROM mysql
    COPY my.cnf /etc/mysql/  
    EXPOSE 3306
    CMD ["mysqld"]
    

    1.2.3 在 master 文件夹下 创建 my.cnf 内容为

    [mysqld]
    log-bin=mysql-bin    //[必须]启用二进制日志
    server-id=1          //[必须]服务器唯一ID,默认是1,一般取IP最后一段,这里看情况分配
    

    1.2.4 在 slave 文件夹下 创建 my.cnf 内容为

    [mysqld]
    log-bin=mysql-bin    //[必须]启用二进制日志
    server-id=2          //[必须]服务器唯一ID,默认是1,一般取IP最后一段,这里看情况分配
    

    1.2.5 切换到 master 目录下构建 master/mysql 镜像

    docker build -t master/mysql .
    

    (命令最后有个.,不要忘记,代表当前目录)

    1.2.6 然后切换到 slave 目录下构建 slave/mysql 镜像

    docker build -t slave/mysql .
    

    (命令最后有个.,不要忘记,代表当前目录)

    1.2.7 查看是否创建成功

    [root@VM_118_220_centos ~]# docker images
    REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
    slave/mysql                 latest              8c496048d7ba        About an hour ago   407 MB
    master/mysql                latest              7be30b0b631b        2 hours ago         407 MB
    docker.io/mysql             latest              44a8e1a5c0b2        8 days ago          407 MB
    

    1.3 用镜像创建容器

    docker run -p 3306 --name mysql-master -e MYSQL_ROOT_PASSWORD=mysql -d master/mysql
    docker run -p 3306 --name mysql-slave -e MYSQL_ROOT_PASSWORD=mysql -d slave/mysql
    

    1.3.1 从这里开始,建议打开两个终端窗口,方便操作

    master 终端执行

    docker exec -it mysql-master bash
    mysql -uroot -p
    

    输入密码 mysql 进入到 mysql 环境

    slave 终端执行

    docker exec -it mysql-slave bash
    mysql -uroot -p
    

    输入密码 mysql 进入到 mysql 环境

    1.4 mysql 主从配置

    mysql 配置

    1.4.1 在主容器 mysql 中输入以下命令:

    mysql>GRANT REPLICATION SLAVE ON *.* TO 'user'@'192.168.99.100' IDENTIFIED BY 'mysql';(指定ip)
    或者
    mysql>GRANT REPLICATION SLAVE ON *.* to 'user'@'%' identified by 'mysql';(所有ip)
    

    然后查看主容器数据库状态:

    mysql> show master status;
    +------------------+----------+--------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+--------------+------------------+-------------------+
    | mysql-bin.000003 |     1338 |              |                  |                   |
    +------------------+----------+--------------+------------------+-------------------+
    1 row in set (0.00 sec)
    

    记录 File 的值和 Position 的值。

    下面要用到,到这里为止,主库千万不要再做任何操作,防止状态改变。

    1.4.2 然后我们配置一下从库

    查看 master/mysql 的对外端口号

    docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
    8d1e3b87d499        slave/mysql         "docker-entrypoint.sh"   2 hours ago         Up 2 hours          0.0.0.0:32769->3306/tcp   mysql-slave
    980e5ea48152        master/mysql        "docker-entrypoint.sh"   2 hours ago         Up 2 hours          0.0.0.0:32768->3306/tcp   mysql-master
    

    0.0.0.0:32768->3306/tcp 其中 32768 为 master 的端口

    mysql>change master to
    master_host='x.x.x.x',
    master_user='user',
    master_log_file='mysql-bin.000003',
    master_log_pos=1201,
    master_port=32768,
    master_password='mysql';
    Query OK, 0 rows affected, 2 warnings (0.03 sec)
    mysql> start slave;
    Query OK, 0 rows affected (0.01 sec)
    

    master_host=’x.x.x.x’ // 这里填 master 主机 ip

    master_log_file=’mysql-bin.000003’, // 这里填写 File 的值

    master_log_pos=1338,// 这里填写 Position 的值。

    mysql> start slave;// 启动从服务器复制功能

    如果不小心配置错, 输入 mysql> stop slave; 然后重新录入一遍

    mysql>change master to
    master_host='x.x.x.x',
    master_user='user',
    master_log_file='mysql-bin.000003',
    master_log_pos=1201,
    master_port=32768,
    master_password='mysql';
    

    就可以了

    1.5 检查主从连接状态

    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: x.x.x.x
                      Master_User: user
                      Master_Port: 32768
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000003
              Read_Master_Log_Pos: 1338
                   Relay_Log_File: 8d1e3b87d499-relay-bin.000002
                    Relay_Log_Pos: 1221
            Relay_Master_Log_File: mysql-bin.000003
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                  Replicate_Do_DB: 
              Replicate_Ignore_DB: 
               Replicate_Do_Table: 
           Replicate_Ignore_Table: 
          Replicate_Wild_Do_Table: 
      Replicate_Wild_Ignore_Table: 
                       Last_Errno: 0
                       Last_Error: 
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 1338
                  Relay_Log_Space: 1435
                  Until_Condition: None
                   Until_Log_File: 
                    Until_Log_Pos: 0
               Master_SSL_Allowed: No
               Master_SSL_CA_File: 
               Master_SSL_CA_Path: 
                  Master_SSL_Cert: 
                Master_SSL_Cipher: 
                   Master_SSL_Key: 
            Seconds_Behind_Master: 0
    Master_SSL_Verify_Server_Cert: No
                    Last_IO_Errno: 0
                    Last_IO_Error: 
                   Last_SQL_Errno: 0
                   Last_SQL_Error: 
      Replicate_Ignore_Server_Ids: 
                 Master_Server_Id: 1
                      Master_UUID: cd327a00-5e18-11e7-98f7-0242ac110006
                 Master_Info_File: /var/lib/mysql/master.info
                        SQL_Delay: 0
              SQL_Remaining_Delay: NULL
          Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
               Master_Retry_Count: 86400
                      Master_Bind: 
          Last_IO_Error_Timestamp: 
         Last_SQL_Error_Timestamp: 
                   Master_SSL_Crl: 
               Master_SSL_Crlpath: 
               Retrieved_Gtid_Set: 
                Executed_Gtid_Set: 
                    Auto_Position: 0
             Replicate_Rewrite_DB: 
                     Channel_Name: 
               Master_TLS_Version: 
    1 row in set (0.00 sec)
    

    这两个必须是 Yes 为 No 或者 connect 说明没有连接上

    Slave_IO_Running: Yes

    Slave_SQL_Running: Yes

    1.6 测试主从连接

    注意设置主从后,操作只能在 master 终端上,slave 上的操作不会同步到 master 上。

    1.6.1 登陆 master 终端

    mysql> create database sunhao;
    Query OK, 1 row affected (0.01 sec)
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sunhao             |
    | sys                |
    +--------------------+
    5 rows in set (0.00 sec)
    mysql> use sunhao
    Database changed
    mysql>  create table sunhao(id int(3),name char(10));
    Query OK, 0 rows affected (0.04 sec)
    mysql> insert into sunhao values(1,'xiaoshuai');
    Query OK, 1 row affected (0.01 sec)
    mysql> select * from sunhao;
    +------+-----------+
    | id   | name      |
    +------+-----------+
    |    1 | xiaoshuai |
    +------+-----------+
    1 row in set (0.00 sec)
    

    1.6.2 登陆 slave 服务器

    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sunhao             |
    | sys                |
    +--------------------+
    5 rows in set (0.00 sec)
    mysql> use sunhao
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    Database changed
    mysql> select * from sunhao;
    +------+-----------+
    | id   | name      |
    +------+-----------+
    |    1 | xiaoshuai |
    +------+-----------+
    

    1.6.3 如果主服务器已经存在应用数据,则在进行主从复制时,需要单独复制处理(注意此操作,如果对从服务器单独录入的数据,会被覆盖掉。):

    这里我们做一次完整的测试

    (1) 在主服务器数据库插入新的数据,并进行锁表操作,不让数据再进行写入动作

    mysql> insert into sunhao values(2,'xiaoshuai');
    Query OK, 1 row affected (0.01 sec)
    mysql> select * from sunhao;                   
    +------+-----------+
    | id   | name      |
    +------+-----------+
    |    1 | xiaoshuai |
    |    2 | xiaoshuai |
    +------+-----------+
    2 rows in set (0.00 sec)
    mysql> FLUSH TABLES WITH READ LOCK;
    mysql> show full processlist; 
    

    (2) 退出 mysql,用 mysqldump 备份数据文件到 / var/lib, 然后顺便多余的用 tar 打包一下玩。哈哈。

    mysql> exit
    Bye
    root@980e5ea48152:/var/lib/mysql# mysqldump -u root -p  sunhao > /var/lib/sunhao.dump    
    Enter password: 
    root@980e5ea48152:/var/lib# tar -zcvf ./sunhao.dump .tar  ./sunhao.dump
    

    (3) 打开宿主服务器,复制 mysql 主服务器文件 sunhao.dump.tar。到宿主服务器

    [root]# docker ps 
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
    8d1e3b87d499        slave/mysql         "docker-entrypoint.sh"   4 hours ago         Up 4 hours          0.0.0.0:32769->3306/tcp   mysql-slave
    980e5ea48152        master/mysql        "docker-entrypoint.sh"   4 hours ago         Up 4 hours          0.0.0.0:32768->3306/tcp   mysql-master
    mkdir -p /var/mydata
    docker cp 980e:/var/lib/sunhao.dump.tar /var/mydata/
    cd /var/mydata
    [root@VM_128_230_centos mydata]# ls
    sunhao.dump.tar
    

    解释: docker cp 980e:/var/lib/sunhao.dump.tar /var/mydata/

    980e 是 980e5ea48152 的缩写。保证不重复简写就可以

    980e:/var/lib/sunhao.dump.tar 意思就是选中的容器下面你的文件下的 sunhao.dump.tar 文件

    /var/mydata/ 目标文件

    (4) 在宿主主机上输入

    [root]# docker cp /var/mydata/sunhao.dump.tar 8d1e3b87d49936414c0e91ffdc60a054e7f4ef8b15baee295350565519abba0e:/var/lib/
    

    (5) 在从服务器上输入

    root@8d1e3b87d499:/# cd /var/lib/
    root@8d1e3b87d499:/var/lib# tar -zcvf sunhao.dump.tar
    

    (6) 在从服务器上输入

    tar -zxvpf /var/lib/mysqlbak.sql.tar
    mysql -uroot -pmysql sunhao < /var/lib/sunhao.dump;
    

    如果写入成功, 这个时候就可以用 select 查询到数据。

    (2) 取消主服务器数据库锁定

    mysql> UNLOCK TABLES;



    作者:y0ngb1n
    链接:https://www.jianshu.com/p/0439206e1f28
    来源:简书

  • 相关阅读:
    HDU5418.Victor and World(状压DP)
    POJ2686 Traveling by Stagecoach(状压DP)
    POJ3254Corn Fields(状压DP)
    HDU5407.CRB and Candies(数论)
    CodeForces 352D. Jeff and Furik
    CodeForces 352C. Jeff and Rounding(贪心)
    LightOj 1282 Leading and Trailing
    Ural 1057. Amount of Degrees(数位DP)
    HDU 2089 不要62 (数位DP)
    HDU5366 The mook jong (DP)
  • 原文地址:https://www.cnblogs.com/djj123/p/11289043.html
Copyright © 2011-2022 走看看