00.本章目标
    基于docker实现MySQL主从集群搭建,实现读写分离
 01.为什么需要进行mysql的集群
    MySQL 提供自带的主从同步功能,可以轻松实现读写分离,保证系统性能的稳定性和数据安全性。
 02.MySQL主从配置原理
    1.master会将变动记录到二进制日志里面;
    2.master有一个I/O线程将二进制日志发送到slave;
    3.slave有一个I/O线程把master发送的二进制写入到relay日志里面;
    4.slave有一个SQL线程,按照relay日志处理slave的数据;    
   注1:relay英文意思:接转,转送,转发
    注2:主从配置原理可参考:images/01 MySQL主从配置原理图.jpg
 03.如何使用Docker搭建MySQL的主从复制功能
    01.拉取MySQL容器镜像
       docker pull mysql/mysql-server:5.7  
       注:后面的mysql标签是版本号,可选择,有:5.5/5.6/5.7/8.0 
       #下载完成之后我们可以先查看一下镜像是拉取成功
       docker images 
    02.创建主数据库容器mysql-master
       1.在宿主机中创建相关目录,用于挂载容器的相关数据bak
         mkdir -p /data/mysql-master/{conf,data}
      2.上传主数据库容器的配置文件my.cnf到/data/mysql-master/conf目录下
         ###与单机不同的地方,必须在[mysqld]段添加以下配置:
         ##[必须]启用二进制日志
         log-bin=mysql-bin
         ###[必须]指定服务器标识ID,每台服务器唯一
         server-id=1          
         详情见:资料/mysql-master/my.cnf
      3.启动master节点
         docker run -p 3306:3306 \
           --name mysql-master \
           -v /data/mysql-master/conf/my.cnf:/etc/my.cnf \
           -v /data/mysql-master/data:/var/lib/mysql \
           --privileged=true \
           --restart=always \
           -e MYSQL_ROOT_PASSWORD=123456 \
           -d mysql/mysql-server:5.7   
注:netstat -anp|grep 3306 查询指定端口是否被占用
        参数说明:
         -p 3306:3306:宿主机端口:容器端口
         --name mysql-master:容器名字
         -v:挂载宿主机的一个文件或目录到容器, 持久化存储的关键所在,
             将主机目录挂载到容器对应目录,分别是:配置文件、日志文件、数据文件
         -v /data/mysql-master/conf:/etc/mysql/conf.d
         -v /data/mysql-master/data:/var/lib/mysq
         --privileged=true:使用该参数,container内的root拥有真正的root权限, 
                        否则,container内的root只是外部的一个普通用户权限
         --restart=always:容器自动启动参数,其值可以为[no,on-failure,always]
                       no为默认值,表示容器退出时,docker不自动重启容器
                       on-failure表示,若容器的退出状态非0,则docker自动重启容器,
                       还可以指定重启次数,若超过指定次数未能启动容器则放弃
                       always表示,只要容器退出,则docker将自动重启容器
         -e MYSQL_ROOT_PASSWORD=123456:设置root的密码
         -d mysql/mysql-server:5.7:后台启动模式及使用的镜像  
 
       3.修改root可以通过任何客户端连接
         docker exec -it mysql-master /bin/bash  #进入mysql5.7容器
         mysql -u root -p;                       #登录mysql服务器,之后输入mysql密码:123456  
                                                 #给用户授权    
         grant all privileges on *.* to root@'%' identified by '123456';    
         flush privileges;                       #更新权限后,外部就可以使用native进行连接了
         注1:连接失败请查看防火墙端口是否启用
              firewall-cmd --zone=public --add-port=3306/tcp --permanent && \
              firewall-cmd --reload && \
              firewall-cmd --list-port           
    03.创建从数据库容器mysql-slave 
       1.在宿主机中创建相关目录,用于挂载容器的相关数据
         mkdir -p /data/mysql-slave/{conf,data}
      2.上传从数据库容器的配置文件my.cnf到/data/mysql-slave/conf目录下
         ###与单机不同的地方,必须在[mysqld]段添加以下配置:
         ##[必须]启用二进制日志
         log-bin=mysql-bin
         ###[必须]指定服务器标识ID,每台服务器唯一,[必须]与主数据库容器的ID不同
         server-id=2          
         详情见:资料/mysql-slave/my.cnf
      3.启动slave节点
         docker run -p 3307:3306 \
           --name mysql-slave \
           -v /data/mysql-slave/conf/my.cnf:/etc/my.cnf \
           -v /data/mysql-slave/data:/var/lib/mysql \
           --privileged=true \
           --restart=always \
           -e MYSQL_ROOT_PASSWORD=123456 \
           -d mysql/mysql-server:5.7   
         注1:宿主机的3306端口已经被mysql-master占用了,只能绑定其它端口了
          注2:实际开发中其实不用将宿主机的3307端口与容器的3306端口进行映射,
               只是为了之后测试查看数据时方便
  
       3.修改root可以通过任何客户端连接
         docker exec -it mysql-slave /bin/bash   #进入mysql5.7容器
         mysql -u root -p;                       #登录mysql服务器,之后输入mysql密码:123456  
                                                 #给用户授权    
         grant all privileges on *.* to root@'%' identified by '123456';    
         flush privileges;                       #更新权限后,外部就可以使用native进行连接了
        注1:连接失败请查看防火墙端口是否启用
              firewall-cmd --zone=public --add-port=3307/tcp --permanent && \
              firewall-cmd --reload && \
              firewall-cmd --list-port  
   04.配置MySQL主从复制
       1.先进入mysql-master容器
         docker exec -it mysql-master /bin/bash
      2.连接master数据库,查看数据库状态
         #1.登陆主节点 
         mysql -u root -p;
         #2.查看主节点关键参数
         show master status;
          
         注1:记录 File 的值和 Position 的值(此值重启后会变化),等会配置 slave 服务器的时候要用
             +------------------+----------+--------------+------------------+-------------------+
             | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
             +------------------+----------+--------------+------------------+-------------------+
             | mysql-bin.000003  |      586  |              |                  |                   |
             +------------------+----------+--------------+------------------+-------------------+   
         注2:A.因为mysql-master容器与宿主机作了端口映射3306:3306,且防火墙3306端口也启动
              B.因为本人的笔记本电脑也安装了mysql,所以还可以在window的doc窗口下通过mysql的命令
              进行远程访问,并查看master数据库状态 
              #切换到mysql安装目录下的bin目录,
              cd D:\tools\mysql-5.7.23-winx64\bin
              mysql -u root -p -h 192.168.183.144 -P 3306      
      3.进入slave节点,关联master节点
         1.先进入mysql-slave容器
           docker exec -it mysql-slave /bin/bash
        2.连接slave数据库,关联master节点
           #1.登陆从节点
           mysql -u root -p;
           #2.配置主从复制
           CHANGE MASTER TO MASTER_HOST='172.17.0.2', MASTER_PORT=3306, MASTER_USER='root',
             MASTER_PASSWORD='123456', MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=586;
           注:各参数说明:
               master_host='192.168.183.144' // 这里填master主机ip,除了填写住宿主机IP,还可以填写bridge网络中的IP
               master_log_file='mysql-bin.000003', // 这里填写 File 的值就是前面我们show master status;命令的执行结果
               master_log_pos=586;// 这里填写 Position 的值就是前面我们show master status;命令的执行结果
           #3.在从节点中开启主从复制   
           start slave;
           注1:开启完成之后,我们可以通过如下命令查看从服务器的连接状态:
               show slave status\G;
               这里只要看到两个参数Slave_IO_Running和Slave_SQL_Running都为true,则表示复制是正常进行的,
               到这里我们的主从结构也就搭建完成了
           注2:集群成功后,在mysql-master容器重启后虽然File的值和Position的值会变化,
                但在mysql-slave可以进行跟踪,所以不需要重新进行配置
                
       4.测试主从服务
         在master服务器上执行相关的命令,然后检查slave服务器上是否存在相应的更新即可,测试代码如下:  
         create database test;
         use test;  
         create table t_user(id bigint, name varchar(255)); 
         insert into t_user(id, name) value (1, 'Mary');  
04.linux中使用命令导入导出数据
    1.导出数据库
      1.导出数据和表结构:
        mysqldump -u 用户名 -p 密码 数据库名 > 数据库名.sql
        mysqldump -u root -p dbname > dbname .sql
       敲回车后会提示输入密码 
     2.只导出表结构
        mysqldump -u 用户名 -p 密码 -d 数据库名 > 数据库名.sql
        mysqldump -u root -p -d dbname > dbname .sql
        敲回车后会提示输入密码
   2.导入数据库
      1.首先建空数据库
        mysql>create database dbname ;
      2.导入数据库
        方法一:
        1.选择数据库
          mysql>use dbname ;
        2.设置数据库编码(可选)
          mysql>set names utf8;
        3.导入数据(注意sql文件的路径)
          mysql>source /home/xxxx/dbname .sql;
        方法二:
          mysql -u 用户名 -p密码 数据库名 < 数据库名.sql
 附录X:读写分离
 MySQL的主从复制,只会保证主机对外提供服务,而从机是不对外提供服务的,只是在后台为主机进行备份。 
 数据库读写分离对于大型系统或者访问量很高的互联网应用来说,是必不可少的一个重要功能。
 对于MySQL来说,标准的读写分离是主从模式,一个写节点Master后面跟着多个读节点,
 读节点的数量取决于系统的压力,通常是1-3个读节点的配置。 Mycat的读写分离是建立在MySQL的主从复制基础上的。
 对MySQL进行读写分离控制的方法和中间件有很多,如MySQL-Proxy、Mycat等,
 这里介绍利用Mycat对MySQL数据库的访问进行的读写分离
 详情见:03 MySQL——主从复制与读写分离 - 知乎.mht
除此之外还有MySQL数据库集群之PXC方案










