您的位置:首页 > 运维架构 > Docker

Docker-Compose实现Mysql主从

2022-06-09 13:13 3951 查看

1. 简介

通过使用

docker-compose
搭建一个主从数据库,本示例为了解耦 将两个server拆分到了两个compose文件中,当然也可以放到一个compose文件中

演示mysql版本:5.7.16

2. 部署流程

master节点:

  1. 安装mysql-server
  2. 修改配置
  3. 创建用于同步的账号并授权
  4. 检查相关配置

slave节点:

  1. 安装mysql-server
  2. 修改配置
  3. 选择主节点
  4. 检查相关配置并验证同步功能

3. master节点

3.1 安装mysql

  1. 创建mysql文件夹并进入文件夹(文件夹名称mysql)

  2. 创建docker-compose文件内容如下

    # docker-compose.yml
    version: '3'
    services:
    mysql:
    restart: "no"
    image: mysql:5.7.16
    container_name: mysql-master
    volumes:
    - ./datadir:/var/lib/mysql
    - ./conf/mysql:/etc/mysql
    environment:
    - "MYSQL_ROOT_PASSWORD=123456"
    - "TZ=Asia/Shanghai"
    ports:
    - 3306:3306
    networks:
    - mysql-net
    networks:
    mysql-net:
    driver: bridge

    注意:因为要把配置文件挂在到服务中去,所以要先把容器中的配置文件copy到宿主机上

    先启动一个用于copy文件的容器

    $ docker run --name mysql-temp -e MYSQL_ROOT_PASSWORD=root --rm -d  mysql:5.7.16
  3. mysql-temp
    容器中的配置文件copy出来,现在conf文件夹中就是mysql自带的所有配置文件

    $ docker cp mysql-temp:/etc/mysql conf

  4. 因为当前conf目录中的

    my.cnf
    还是个link,所以直接使用当前目录中的备份文件作为主要的配置文件

    $ mv my.cnf.fallback my.cnf
  • 修改配置文件

    my.cnf

    在文件的最下方加入配置信息

    [mysqld]
    log-bin=mysql-bin # 开启 binlog
    server-id=1 # 当前server在cluster中的id,必须保证在cluster中唯一
    #只保留7天的二进制日志,以防磁盘被日志占满(可选)
    expire-logs-days = 7
    #不备份的数据库 (可选)
    binlog-ignore-db=information_schema
    binlog-ignore-db=performation_schema
    binlog-ignore-db=sys
  • 启动mysql服务,通过输出内容得知真实的网络名称为

    mysql_mysql-net
    ,也就是当前所在文件夹的名称拼接了文件中指定的网络名称

  • 服务启动完毕后,创建用于同步的用户并授权

    创建的用户名称为

    slave
    密码为
    123456

    CREATE USER 'slave' @'%' IDENTIFIED BY '123456';
    GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave' @'%';
    #刷新权限
    FLUSH PRIVILEGES;
  • 查看master状态信息

    SHOW MASTER STATUS;
    #查看Mater数据有哪些slave
    select * from information_schema.processlist as p where p.command = 'Binlog Dump';

  • 4. slave节点

    安装步骤同master相同,只把需要修改的展示一下,当前的目录结构如下

    docker-compose.yaml
    主要修改了网络相关的信息和container_name(网络名称上面有解释)

    version: '3'
    services:
    mysql:
    restart: "no"
    image: mysql:5.7.16
    container_name: mysql-slave
    volumes:
    - ./datadir:/var/lib/mysql
    - ./conf:/etc/mysql
    environment:
    - "MYSQL_ROOT_PASSWORD=123456"
    - "TZ=Asia/Shanghai"
    ports:
    - 3307:3306
    networks:
    - mysql_mysql-net
    networks:
    mysql_mysql-net:
    external: true # 来自外部

    my.cnf
    添加的内容如下:

    [mysqld]
    server-id=2
    relay_log=relay-log
    #开启只读 意味着当前的数据库用作读,当然这也只会影响到非root的用户,如果使用root用户操作本库是不会有影响的
    read_only=ON

    设置完成后启动salve server,连接slave并关联master节点

    • MASTER_HOST
      :直接使用container_name
    • MASTER_LOG_FILE/MASTER_LOG_POS
      :直接使用安装master步骤中的最后一步的值,其实就是指定同步的bin-log文件名称和Offset
    CHANGE MASTER TO
    MASTER_HOST='mysql-master',
    MASTER_USER='slave',
    MASTER_PASSWORD='123456',
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=154;

    管理完成后 启动

    salve

    START SLAVE;

    最后查看

    slave status

    SHOW SLAVE STATUS;

    5. 验证

    在master上创建test数据库并创建user表,刷新查看salve库,出现了对应的库表

    经验证数据同步也没有问题。

    6. 可能遇到的问题

    SHOW SLAVE STATUS
    时发现
    slave_io_running=No salve_sql_running=No
    ,可能的原因有很多,可以查看如下的字段中输出的内容

    可能的原因:

    1. 主从网络不通
    2. 两台节点的
      server-id
      重复,直接修改对应的id即可
    3. 数据库的uuid相同(可能是因为数据库文件是直接copy过来的导致的),在对应的库下生成不同于master的uuid到
      auto.cnf
      中即可
    4. sql执行失败,可能是slave刚添加进来,也没有master库的数据库instance,导致操作对应的库时slave这边根本没有对应的instance或者table又或是记录,引发的报错。这个只能具体问题具体解决了
    5. master和slave的
      MASTER_LOG_FILE/MASTER_LOG_POS
      值设置的有问题,在slave节点上
      STOP SLAVE;
      然后重新连接下master即可

    7. 同步部分数据库实例或表

    在master节点上添加配置【可选】(如果只希望从库读取到部分实例)

    在my.cnf文件中加入如下配置

    #需要同步的数据库名 有多个库添加多行即可
    binlog-do-db=test
    binlog-do-db=test1
    #排除的数据库
    binlog-ignore-db=sys

    **salve端:**在my.cnf文件中加入如下配置,这样的话salve只会读取配置的db或table,master对其他db的操作也不会影响slave

    #如果salve库名称与master库名相同,使用本配置
    replicate-do-db=test
    #如果master库名[test]与salve库名[test001]不同,使用以下配置[需要做映射]
    #replicate-rewrite-db = test -> test001
    #如果不是要全部同步[默认全部同步],则指定需要同步的表
    #replicate-wild-do-table=test.user
    #replicate-wild-do-table=test.role
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: