• 使用Docker-compose部署MySQL测试环境


    1.题目部分

    • 参考文档: https://hub.docker.com/_/mysql
    • 使用docker-compose, 创建两个MySQL容器, 满足如下条件:
      • 使用自定义的my.cnf
      • 形成主从复制关系
      • 容器销毁后, 主实例的数据仍保留, 从实例的数据清零销毁
      • 重建两个容器, 主实例沿用之前的数据, 从实例重建数据, 并建立复制

    2.解答部分

    2.1 docker安装

    docker-compose依赖docker环境,需要先安装好docker,本实验环境为在CentOS7虚拟机中安装docker,参考链接:https://docs.docker.com/install/linux/docker-ce/centos/

    ## 卸载旧版本的docker及相关组件
    [root@10-186-61-162 ~]# yum remove docker 
        docker-client 
        docker-client-latest 
        docker-common 
        docker-latest 
        docker-latest-logrotate 
        docker-logrotate 
        docker-engine
    
    ## 安装yum工具包及docker相关依赖包
    [root@10-186-61-162 ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
     
    ## 添加docker社区版的软件源(这里将软件源替换为了阿里云提供的软件源,加快镜像下载速度)
    [root@10-186-61-162 ~]# yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
     
    ## 安装并启动docker-ce
    [root@10-186-61-162 ~]# yum install docker-ce docker-ce-cli containerd.io
    [root@10-186-61-162 ~]# systemctl start docker
    [root@10-186-61-162 ~]# systemctl status docker
     
    ## 验证docker运行正常
    [root@10-186-61-162 ~]# docker --version
    Docker version 19.03.6, build 369ce74a3c
    
    [root@10-186-61-162 ~]# docker run hello-world
    Unable to find image 'hello-world:latest' locally
    latest: Pulling from library/hello-world
    1b930d010525: Pull complete
    Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f
    Status: Downloaded newer image for hello-world:latest
    
    ## 有以下输出表示docker安装且运行正常
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    
    To generate this message, Docker took the following steps:
     1. The Docker client contacted the Docker daemon.
     2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
        (amd64)
     3. The Docker daemon created a new container from that image which runs the
        executable that produces the output you are currently reading.
     4. The Docker daemon streamed that output to the Docker client, which sent it
        to your terminal.
    
    To try something more ambitious, you can run an Ubuntu container with:
     $ docker run -it ubuntu bash
    
    Share images, automate workflows, and more with a free Docker ID:
     https://hub.docker.com/
    
    For more examples and ideas, visit:
     https://docs.docker.com/get-started/
    

    2.2 docker-compose 安装

    docker-compose是一个用来编排多个容器的工具,我们可以编辑一个YMAL格式的配置文件,将多个容器的配置写入,使用compose工具来统一启停维护。安装参考链接:

    ## 直接使用官方链接提供的下载命令下载1.23.3版本docker-compose并保存到/usr/local/bin/docker-compose
    curl -L "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
     
    ## 对docker-compose增加可执行权限
    chmod +x /usr/local/bin/docker-compose
     
    ## 验证docker版本
    [root@10-186-61-162 ~]# docker-compose --version
    docker-compose version 1.25.3, build d4d1b42b
    

    2.3 docker-compose 配置

    在编排前需规划好相关运行目录及my.cnf配置文件

    ## 创建docker-compose编排MySQL的系统目录便于维护管理
    [root@10-186-61-162 mysql]# mkdir -p /data/docker-compose/mysql
     
    ## 在该目录下创建主从需要的文件及目录
    [root@10-186-61-162 mysql]# pwd
    /data/docker-compose/mysql
    [root@10-186-61-162 mysql]# tree -L 2
    .
    ├── docker-compose.yml ## MySQL主从编排的配置文件
    ├── master
    │   ├── data 	## master节点保留数据,数据用volumes的方式保留在宿主机本地,需要额外创建data目录
    │   ├── init_sql ## 在MySQL初始化完成后需要执行的SQL文件目录,目录下包含创建的初始化用户、数据库、表及测试数据等。
    │   └── my.cnf   ## 自定义的MySQL配置文件
    └── slave
        ├── init_sql
        └── my.cnf
    

    2.3.1 init.sql内容

    • master节点
      • 创建一个repl用户做复制同步使用
      • 创建一个测试库zhenxing并在其中创建一张t1表插入少量数据
    • slave节点
      • reset master清除执行的基础操作产生的GTID信息
      • change master to指向master节点建立主从复制同步连接
    ## master节点的初始化sql文件
    [root@10-186-61-162 init_sql]# pwd
    /data/docker-compose/mysql/master/init_sql
    [root@10-186-61-162 init_sql]# cat init.sql
    create user 'repl'@'%' identified by 'repl';
    grant replication client,replication slave on *.* to 'repl'@'%';
    create database zhenxing;
    use zhenxing;
    create table t1(id int primary key auto_increment,username varchar(20));
    insert into t1(username) values('yuzhenxing'),('zhenxingyu');
     
    ## slave节点的初始化sql文件
    [root@10-186-61-162 init_sql]# pwd
    /data/docker-compose/mysql/slave/init_sql
    [root@10-186-61-162 init_sql]# cat init.sql
    reset master;
    CHANGE MASTER TO MASTER_HOST='172.20.0.10',MASTER_USER='repl',MASTER_PASSWORD='repl',MASTER_PORT=3306,MASTER_AUTO_POSITION=1;
    start slave;
    

    2.3.2 my.cnf配置文件

    其中除server_id与从库不一样以外,其他参数均一致

    [mysqld]
    # Base Config
    server_id 						= 1623306
    user							= mysql
    port							= 3306
    default_storage_engine					= InnoDB
    character_set_server					= utf8mb4
    # skip_slave_start					= 1 ## 该参数需要注释,不然docker调用初始化脚本时不会触发start slave开启主从复制同步
    skip-name-resolve					= 1
    skip-external-locking					= 1
    lower_case_table_names					= 1
    query_cache_type           				= 0
    query_cache_size            				= 0
    max_connections						= 1000
    default-time-zone 					= '+8:00'
    log_timestamps						= SYSTEM
    
    # InnoDB config
    innodb_strict_mode					= 1
    innodb_file_per_table					= 1
    innodb_stats_on_metadata				= 0
    innodb_flush_method					= O_DIRECT
    innodb_log_files_in_group				= 3
    innodb_data_file_path					= ibdata1:128M:autoextend
    innodb_buffer_pool_size					= 128M
    innodb_log_file_size					= 32M
    innodb_log_buffer_size					= 8M
    innodb_max_dirty_pages_pct				= 60
    innodb_io_capacity					= 200
    innodb_buffer_pool_instances				= 8
    innodb_buffer_pool_load_at_startup			= 1
    innodb_buffer_pool_dump_at_shutdown			= 1
    innodb_undo_logs 					= 128
    innodb_undo_tablespaces					= 3
    innodb_flush_neighbors					= 1
    
    # Cache config
    key_buffer_size						= 8M
    tmp_table_size						= 8M
    max_heap_table_size					= 8M
    thread_cache_size					= 1000
    table_open_cache					= 2048
    open_files_limit					= 65535
    max_allowed_packet					= 64M
    
    # Log config
    log_error						= mysql-error.log
    slow_query_log_file					= mysql-slow.log
    relay-log						= mysql-relay
    log-bin							= mysql-bin
    slow_query_log						= 1
    long_query_time						= 0.2
    #log_slow_admin_statements				= 1
    #log_slow_slave_statements				= 1
    
    # Replication config
    slave-parallel-type					= LOGICAL_CLOCK
    slave-parallel-workers					= 4
    expire_logs_days					= 14
    binlog_format						= row
    log_slave_updates					= ON
    binlog_checksum						= NONE
    max_binlog_size						= 250M
    binlog_cache_size					= 2M
    sync_binlog						= 1
    innodb_flush_log_at_trx_commit		 		= 1
    relay-log-info-repository				= TABLE
    master_info_repository					= TABLE
    relay_log_recovery					= 1
    binlog_rows_query_log_events				= 1
    log_bin_trust_function_creators                         = 1
    
    # GTID
    gtid-mode						= ON
    enforce-gtid-consistency				= 1
    
    
    # Performance Schema
    performance-schema-instrument           		= 'wait/lock/metadata/sql/mdl=ON'
    

    2.3.3 docker-compose.yml

    1. 采用MySQL5.7.29版本数据库
    2. 主从配置文件均采用自定义的配置文件
    3. 主库的数据目录采用宿主机上创建的data目录
    4. 将init_sql下的文件映射到/docker-entrypoint-initdb.d下(注:/docker-entrypoint-initdb.d下以sql或sh结尾的文件会在数据库初始化完成后自动执行)
    [root@10-186-61-162 mysql]# cat docker-compose.yml
    version: '3.7'
    networks:
      mysql_net:
        name: mysql_net
        driver: bridge
        ipam:
          driver: default
          config:
            - subnet: 172.20.0.1/24
    services:
      master:
        networks:
          mysql_net:
            ipv4_address: 172.20.0.10
        image: mysql:5.7.29
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: oracle
        hostname: 172-20-0-10
        container_name: 172-20-0-10
        volumes:
          - "./master/my.cnf:/etc/my.cnf"
          - "./master/data:/var/lib/mysql"
          - "./master/init_sql:/docker-entrypoint-initdb.d/"
      slave:
        networks:
          mysql_net:
            ipv4_address: 172.20.0.11
        image: mysql:5.7.29
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: oracle
        hostname: 172-20-0-11
        container_name: 172-20-0-11
        volumes:
          - "./slave/my.cnf:/etc/my.cnf"
          - "./slave/init_sql:/docker-entrypoint-initdb.d/"
    

    2.4 docker-compose运行

    当相关配置文件编辑完成后,即可启动docker-compose

    ## 使用docker-compose后台方式创建容器
    [root@10-186-61-162 mysql]# cd /data/docker-compose/mysql
    [root@10-186-61-162 mysql]# docker-compose up -d
    Creating network "mysql_net" with driver "bridge"
    Creating 172-20-0-11 ... done
    Creating 172-20-0-10 ... done
     
    ## 查看mysql_net自定义网络
    [root@10-186-61-162 mysql]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    d5072726a5c8        bridge              bridge              local
    3443080f11fc        host                host                local
    deda6b29ddd0        mysql_net           bridge              local
    25391fba169c        none                null                local
    c4aeb18be8c4        root_default        bridge              local
     
    ## 查看当前网络组下各节点对应具体IP
    [root@10-186-61-162 mysql]# docker network inspect mysql_net |egrep "IPv4Address|Name"
            "Name": "mysql_net",
                    "Name": "172-20-0-10",
                    "IPv4Address": "172.20.0.10/16",
                    "Name": "172-20-0-11",
                    "IPv4Address": "172.20.0.11/16",
    
    ## 使用docker ps命令可以看到当前运行的容器状态
    [root@10-186-61-162 mysql]# docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
    e1f7ff7f1e2e        mysql:5.7.29        "docker-entrypoint.s…"   4 minutes ago       Up 4 minutes        3306/tcp, 33060/tcp   172-20-0-11
    af1fe13e199d        mysql:5.7.29        "docker-entrypoint.s…"   4 minutes ago       Up 4 minutes        3306/tcp, 33060/tcp   172-20-0-10
     
    ## 也可使用docker-compose的ps命令查看状态
    [root@10-186-61-162 mysql]# docker-compose ps
       Name                 Command             State          Ports
    -----------------------------------------------------------------------
    172-20-0-10   docker-entrypoint.sh mysqld   Up      3306/tcp, 33060/tcp
    172-20-0-11   docker-entrypoint.sh mysqld   Up      3306/tcp, 33060/tcp
     
    ## 访问数据库主节点,数据均初始化成功
    [root@10-186-61-162 mysql]# mysql -h172.20.0.10 -uroot -P3306 -poracle
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | zhenxing           |
    +--------------------+
    5 rows in set (0.01 sec)
    
    mysql> select * from zhenxing.t1;
    +----+------------+
    | id | username   |
    +----+------------+
    |  1 | yuzhenxing |
    |  2 | zhenxingyu |
    +----+------------+
    2 rows in set (0.01 sec)
     
    ## 访问MySQL从库,从库为空实例
    [root@10-186-61-162 mysql]# mysql -h172.20.0.11 -uroot -P3306 -poracle
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    4 rows in set (0.00 sec)
    
    ## 主从同步正常
    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 172.20.0.10
                      Master_User: repl
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000004
              Read_Master_Log_Pos: 190
                   Relay_Log_File: mysql-relay.000006
                    Relay_Log_Pos: 395
            Relay_Master_Log_File: mysql-bin.000004
                 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: 190
                  Relay_Log_Space: 835
                  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: 1623306
                      Master_UUID: 72aa5e86-51ff-11ea-8a5a-0242ac14000a
                 Master_Info_File: mysql.slave_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: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:2-10
                Executed_Gtid_Set: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:1-10
                    Auto_Position: 1
             Replicate_Rewrite_DB:
                     Channel_Name:
               Master_TLS_Version:
    1 row in set (0.00 sec)
    

    2.5 重置容器并保存master节点数据

    • 因为主节点数据保存在容器外宿主机上,可直接将容器删除,再重新构建时指定容器使用已存在的数据即可完成构建。不会对已存在的数据库做改变,
      • If you start your mysql container instance with a data directory that already contains a database (specifically, a mysql subdirectory), the $MYSQL_ROOT_PASSWORD variable should be omitted from the run command line; it will in any case be ignored, and the pre-existing database will not be changed in any way
    ## 在删除容器前在主节点新增一条数据验证是否会在重建后保留
    [root@10-186-61-162 mysql]# mysql -h172.20.0.10 -uroot -P3306 -poracle
    mysql> insert into zhenxing.t1 select null,'xingzhenyu';
    mysql> select * from t1;
    +----+------------+
    | id | username   |
    +----+------------+
    |  1 | yuzhenxing |
    |  2 | zhenxingyu |
    |  3 | xingzhenyu |
    +----+------------+
    3 rows in set (0.00 sec)
     
    ## 停止并删除容器
    ## 使用docker-compose stop && docker-compose rm不会删除创建的网络,如需要一并删除网络可使用docker-compose down
    [root@10-186-61-162 mysql]# docker-compose stop && docker-compose rm
    Stopping 172-20-0-11 ... done
    Stopping 172-20-0-10 ... done
    Going to remove 172-20-0-11, 172-20-0-10
    Are you sure? [yN] y
    Removing 172-20-0-11 ... done
    Removing 172-20-0-10 ... done
     
    ## 重新构建容器
    [root@10-186-61-162 mysql]# docker-compose up -d
    Creating 172-20-0-11 ... done
    Creating 172-20-0-10 ... done
     
    ## 登录主库查看数据
    [root@10-186-61-162 mysql]# mysql -h172.20.0.10 -uroot -P3306 -poracle
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | zhenxing           |
    +--------------------+
    5 rows in set (0.00 sec)
    
    mysql> show master status;
    +------------------+----------+--------------+------------------+-------------------------------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                         |
    +------------------+----------+--------------+------------------+-------------------------------------------+
    | mysql-bin.000004 |      190 |              |                  | 036a86a3-516e-11ea-9394-0242ac130003:1-10 |
    +------------------+----------+--------------+------------------+-------------------------------------------+
    1 row in set (0.00 sec)
    
    ## 验证主库数据仍保留完整
    mysql> select * from zhenxing.t1;
    +----+------------+
    | id | username   |
    +----+------------+
    |  1 | yuzhenxing |
    |  2 | zhenxingyu |
    |  3 | xingzhenyu |
    +----+------------+
    3 rows in set (0.01 sec)
     
    ## 登录slave查看与主库的同步
    [root@10-186-61-162 mysql]# mysql -h172.20.0.11 -uroot -P3306 -poracle
    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 172.20.0.10
                      Master_User: repl
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000005
              Read_Master_Log_Pos: 190
                   Relay_Log_File: mysql-relay.000007
                    Relay_Log_Pos: 395
            Relay_Master_Log_File: mysql-bin.000005
                 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: 190
                  Relay_Log_Space: 1158
                  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: 1623306
                      Master_UUID: 72aa5e86-51ff-11ea-8a5a-0242ac14000a
                 Master_Info_File: mysql.slave_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: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:2-11
                Executed_Gtid_Set: 72aa5e86-51ff-11ea-8a5a-0242ac14000a:1-11
                    Auto_Position: 1
             Replicate_Rewrite_DB:
                     Channel_Name:
               Master_TLS_Version:
    1 row in set (0.00 sec)
     
    ## 数据同步正常
    mysql> select * from zhenxing.t1;
    +----+------------+
    | id | username   |
    +----+------------+
    |  1 | yuzhenxing |
    |  2 | zhenxingyu |
    |  3 | xingzhenyu |
    +----+------------+
    3 rows in set (0.00 sec)
    ## 也可使用dump方式导出导入到slave后再建立主从同步
    docker exec -i master sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > all.sql
    docker exec -i slave sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' <all.sql
     
    ## 或将master的宿主机上的数据拷贝一份供从库使用
    

    2.6 参考链接

    转载请说明出处 |QQ:327488733@qq.com
  • 相关阅读:
    DIV 设置垂直居中
    JavaScript--什么是函数
    JavaScript--引用JS外部文件
    JavaScript--如何插入JS
    CSS-类和ID选择器的区别
    CSS-ID选择器
    CSS类选择器
    CSS样式介绍
    HTML--使用mailto在网页中链接Email地址
    HTML--form表单中的label标签
  • 原文地址:https://www.cnblogs.com/zhenxing/p/12509436.html
Copyright © 2020-2023  润新知