• mysql8-基于docker搭建主从同步


    一、环境信息

    • 系统版本:CentOS Linux release 7.9.2009 (Core)
      • cat /etc/centos-release
    • Docker版本:Docker version 20.10.6, build 370c289
      • docker --version
    • Docker-compose版本:Docker Compose version v2.10.2
      • docker-compose --version
    • MySQL版本:8
      • mysql> select version()
    • 主机两台 或者 单台部署两个容器

    二、主从复制说明

    1、简单了解下binlog

    • binlog是记录所有数据库表结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志。
    • binlog日志包括两类文件:二进制日志索引文件(文件名后缀为.index)用于记录所有的二进制文件,二进制日志文件(文件名后缀为.00000*)记录数据库所有的DDL和DML(除了数据查询语句)语句事件。
    • binlog有三种格式:statement基于sql语句复制、row基于行数据变更的复制、mixed混合前两种格式的复制。

    2、主从复制原理

    1. Master将改变记录到二进制日志(binary log)中
    2. Slave将Master的二进制日志事件(binary log events)拷贝到它的中继日志(relay log)
    3. Slave重做中继日志(Relay Log)中的事件,将Master上的改变反映到它自己的数据库中
    4. 这些是由从库在做,所以是异步的数据同步

    3、主从复制应用场景

    1. 主从服务器互为备份,加强数据库架构的健壮性
    2. 主从服务器读写分离,分担网站压力,从服务器只处理用户的查询请求
    3. 将从服务器,按照业务拆分,分担压力

    三、master主节点配置

    1、目录结构

    .
    ├── docker-compose.yml
    └── mysql
        └── conf
        │   └── my.cnf
        └── data
        └── log
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    需要 docker-compose.ymlmy.cnf 两个文件

    2、my.cnf配置文件

    创建文件夹

    mkdir -p mysql/conf
    
    • 1

    配置文件

    cat >> mysql/conf/my.cnf <<EOF
    
    # @Author: Johnny
    # master
    
    [mysqld]
    
    # [必须]服务器唯一ID
    server-id=888
    
    # [必须]启用二进制日志
    log-bin=mysql-bin 
    
    # 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
    binlog-ignore-db=mysql
    
    # 确保binlog日志写入后与硬盘同步
    sync_binlog = 1
    
    # 跳过所有的错误,继续执行复制操作
    slave-skip-errors = all     
    
    # default
    skip-host-cache
    skip-name-resolve
    datadir=/var/lib/mysql
    socket=/var/run/mysqld/mysqld.sock
    secure-file-priv=/var/lib/mysql-files
    user=mysql
    
    # Disabling symbolic-links is recommended to prevent assorted security risks
    symbolic-links=0
    
    #log-error=/var/log/mysqld.log
    pid-file=/var/run/mysqld/mysqld.pid
    [client]
    socket=/var/run/mysqld/mysqld.sock
    
    !includedir /etc/mysql/conf.d/
    
    EOF
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    3、docker-compose.yml

    
    # @Author: Johnny
    
    version: '3'
    services:
      mysql:
        container_name: mysql-master
        image: mysql:8
        restart: always
        volumes:
          - $PWD/mysql/log:/var/log/mysql  
          - $PWD/mysql/conf/my.cnf:/etc/my.cnf
          - $PWD/mysql/data:/var/lib/mysql
        ports:
          - '3306:3306'
        command: [
            '--explicit_defaults_for_timestamp=true',
            '--character-set-server=utf8mb4',
            '--collation-server=utf8mb4_general_ci',
            '--max_connections=3000'
        ]
        environment:
          MYSQL_ROOT_PASSWORD: "shield"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    将上面的内容准备好后,安装:

    docker-compose up -d
    
    • 1

    4、配置主从同步账号和权限

    进入容器

    docker exec -it mysql-master bash
    
    • 1

    登录mysql

    mysql -uroot -pshield
    
    • 1

    执行sql

    # 查看配置的服务ID,显示的应该是配置的ID
    mysql> show variables like '%server_id%';
    +----------------+-------+
    | Variable_name  | Value |
    +----------------+-------+
    | server_id      | 888   |
    | server_id_bits | 32    |
    +----------------+-------+
    
    # 看master信息 File 和 Position 从服务上要用
    mysql> show master status;
    +------------------+----------+--------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+--------------+------------------+-------------------+
    | mysql-bin.000001 |      154 |              | mysql            |                   |
    +------------------+----------+--------------+------------------+-------------------+
    
    # 创建同步账户并开启权限,只是同步账号
    mysql> create user 'sync'@'%' identified by '123456';
    mysql> grant replication slave,replication client on *.* to 'sync'@'%';
    
    # 刷新信息生效
    mysql> flush privileges;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    5、配置用户的的密码正常访问

    mysql8默认的加密插件caching_sha2_password,所以直接使用上面的密码无法进行链接

    详情可参考这篇文章

    解决办法

    
    mysql> use mysql;
    
    mysql> update user set host='%' where user='root';
    
    mysql> alter user 'root'@'%' identified with mysql_native_password by'用户密码';
    
    # 刷新权限
    mysql> FLUSH PRIVILEGES;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    四、slave从节点配置(备份节点)

    如果是一台主机安装2个mysql,注意更新 docker-compose.yml 中的端口,避免端口冲突

    1、目录结构

    .
    ├── docker-compose.yml
    └── mysql
        └── conf
        │   └── my.cnf
        └── data
        └── log
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    需要 docker-compose.ymlmy.cnf 两个文件

    2、my.cnf配置文件

    创建文件夹

    mkdir -p mysql/conf
    
    • 1

    配置文件

    cat >> mysql/conf/my.cnf <<EOF
    
    cat >> mysql/conf/my.cnf <
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    3、docker-compose.yml

    
    # @Author: Johnny
    
    version: '3'
    services:
      mysql:
        container_name: mysql-slave
        image: mysql:8
        restart: always
        volumes:
          - $PWD/mysql/log:/var/log/mysql  
          - $PWD/mysql/conf/my.cnf:/etc/my.cnf
          - $PWD/mysql/data:/var/lib/mysql
        ports:
          - '3306:3306'
        command: [
            '--explicit_defaults_for_timestamp=true',
            '--character-set-server=utf8mb4',
            '--collation-server=utf8mb4_general_ci',
            '--max_connections=3000'
        ]
        environment:
          MYSQL_ROOT_PASSWORD: "shield"
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    将上面的内容准备好后,安装:

    docker-compose up -d
    
    • 1

    4、链接master节点

    docker exec -it mysql-slave bash
    
    • 1
    mysql -uroot -pshield
    
    • 1

    执行sql

    #查看server_id是否生效
    mysql> show variables like '%server_id%';
    +----------------+-------+
    | Variable_name  | Value |
    +----------------+-------+
    | server_id      | 999   |
    | server_id_bits | 32    |
    +----------------+-------+
    
    # 连接主mysql服务 master_log_file 和 master_log_pos的值要填写主master里查出来的值 注意这里使用的docker-compose 内部服务的端口和ip,实际应该为真实的master_host,参数看后面的介绍
    mysql> change master to master_host='mysql-master',master_user='sync',master_password='123456',master_port=3306,master_log_file='mysql-bin.000001', master_log_pos=154,master_connect_retry=30;
    
    ######################################################
    ###  连接主mysql参数说明:
    ###  master_port:Master的端口号,指的是容器的端口号
    ###  master_user:用于数据同步的用户
    ###  master_password:用于同步的用户的密码
    ###  master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
    ###  master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
    ###  master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒
    ######################################################
    
    
    # 开启slave
    mysql> start slave;
    
    mysql> show slave status \G   
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for source to send event
                      Master_Host: mysql-master
                      Master_User: sync
                      Master_Port: 3306
                    Connect_Retry: 30
                  Master_Log_File: mysql-bin.000001
              Read_Master_Log_Pos: 1166
                   Relay_Log_File: mysql-relay-bin.000002
                    Relay_Log_Pos: 1334
            Relay_Master_Log_File: mysql-bin.000001
                 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: 1166
                  Relay_Log_Space: 1543
                  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: 888
                      Master_UUID: 05f48dfa-4afd-11ee-821c-0242ac170002
                 Master_Info_File: mysql.slave_master_info
                        SQL_Delay: 0
              SQL_Remaining_Delay: NULL
          Slave_SQL_Running_State: Replica 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: 
           Master_public_key_path: 
            Get_master_public_key: 0
                Network_Namespace: 
    1 row in set, 1 warning (0.01 sec)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    看到下列信息代表链接成功

    Slave_IO_Running:Yes;
    Slave_SQL_Running:Yes;
    
    • 1
    • 2
  • 相关阅读:
    Python语法
    14.3.1 语法格式
    【每日一题】补档 CF1678B-Tokitsukaze and Good 01-String | 思维 | 简单
    2023年中国家用智能门锁市场发展概况分析:家用智能门锁线上市场销量290.4万套[图]
    商城系统功能需求分析_免费搭建方式介绍_OctShop
    基于Springboot实现毕业生信息招聘平台管理系统演示【项目源码+论文说明】分享
    java图(含java图的代码)
    使用jmeter进行接口测试
    Redisson的基本使用
    React 学习笔记:JSX 语法
  • 原文地址:https://blog.csdn.net/z_johnny/article/details/132713558