Mysql数据库集群搭建

Docker搭建Mysql数据库集群

1. 主从复制概述

复制是指将主数据库的DDL 和 DML 操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做),从而使得从库和主库的数据保持同步。

MySQL支持一台主库同时向多台从库进行复制, 从库同时也可以作为其他从服务器的主库,实现链状复制。

1.1 复制原理

 MySQL 的主从复制原理如下。

 1554423698190

 从上层来看,复制分成三步:

  • Master 主库在事务提交时,会把数据变更作为时间 Events 记录在二进制日志文件 Binlog 中。

  • 主库推送二进制日志文件 Binlog 中的日志事件到从库的中继日志 Relay Log 。

  • slave重做中继日志中的事件,将改变反映它自己的数据。

1.2复制优势

MySQL 复制的有点主要包含以下三个方面:

  • 主库出现问题,可以快速切换到从库提供服务。

  • 可以在从库上执行查询操作,从主库中更新,实现读写分离,降低主库的访问压力。

  • 可以在从库中执行备份,以避免备份期间影响主库的服务。

1.3 搭建步骤

1.3.1 docker安装mysql

  • 首先适用docker 拉去mysql镜像(需要在虚拟机上安装docker,才能适用docker命令)

docker pull mysql
  • 查看下载的mysql镜像

    docker images 

    image-20210608195958518

  • 然后使用mysql镜像,分别启动两个容器

    #Master(主)
    docker run -d -p 3307:3306 --name mysql_master -e MYSQL_ROOT_PASSWORD=root docker.io/mysql:latest
    #Slave(从)
    docker run -d -p 3308:3306 --name mysql_slave -e MYSQL_ROOT_PASSWORD=root docker.io/mysql:latest

Master对外映射的端口是3307,Slave对外映射的端口是3308。因为docker容器是相互独立的,每个容器有其独立的ip,所以不同容器使用相同的端口并不会冲突。这里我们应该尽量使用mysql默认的3306端口,否则可能会出现无法通过ip连接docker容器内mysql的问题

  • 查看正在运行的2个mysql容器情况

    docker ps

    image-20210608200456794

1.3.2 配置Master(主)

docker exec -it mysql_master /bin/bash

通过docker exec -it a6ede3b2a5b9 /bin/bash命令进入到Master容器内部,也可以通过docker exec -it mysql——master /bin/bash命令进入。a6ede3b2a5b9 是容器的id,而mysql-master是容器的名称

cd /etc/mysql切换到/etc/mysql目录下,然后vi my.cnf对my.cnf进行编辑。

此时会报出bash: vi: command not found,需要我们在docker容器内部自行安装vim。使用apt-get install vim命令安装vim

会出现如下问题:

image-20210608201249366

执行apt-get update,然后再次执行apt-get install vim即可成功安装vim。然后我们就可以使用vim编辑my.cnf,在my.cnf中添加如下配置:

#mysql 服务ID,保证整个集群环境中唯一
server-id=1
​
#mysql binlog 日志的存储路径和文件名
log-bin=/var/lib/mysql/mysqlbin
​
#错误日志,默认已经开启
#log-err
​
#mysql的安装目录
#basedir
​
#mysql的临时目录
#tmpdir
​
#mysql的数据存放目录
#datadir
​
#是否只读,1 代表只读, 0 代表读写
read-only=0
​
#忽略的数据, 指不需要同步的数据库
binlog-ignore-db=mysql
​
#指定同步的数据库
#binlog-do-db=db01
  • 配置完成之后,需要重启mysql服务使配置生效

    image-20210608201725620

  • 输入service mysql restart 不能识别的话,就退出容器,然后重新启动容器就行

exit;#退出当前容器
docker restart a6ede3b2a5b9 ;#重启master容器
docker exec -it a6ede3b2a5b9 /bin/bash;#进入master容器
  • 重新进入mysql,查看master的状态

    show master status;

    image-20210608202336531

  • 下一步在Master数据库创建数据同步用户,授予用户 slave REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据。

    CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
    
    GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';

到此Master主服务器就搭建成功。

1.3.3 配置Slave(从)

  • 上一步已经运行了主、从两台MySQL服务器,现在进入到MySQL从服务器

docker exec -t mysql_slave /bin/bash
  • 进入到mysql 的配置文件目录 ,然后vi my.cnf对my.cnf进行编辑(可能遇到找不到vim错误,请参考上一步)

cd /etc/mysql

image-20210609100039220

  • 配置如下参数

    #mysql服务端ID,唯一
    server-id=2
    
    #指定binlog日志
    log-bin=/var/lib/mysql/mysqlbin

    保存并退出配置文件的编辑模式,并重启mysql服务

    image-20210609103747662 

  • 配置主服务器时,检查过master的状态

    image-20210608202336531

    执行以下命令,配置从服务器,指定当前从库对应的主库的IP地址,用户名,密码,从哪个日志文件开始的那个位置开始同步推送日志。

    change master to master_host= '172.17.0.2', master_user='slave', master_password='123456', master_log_file='mysqlbin.000001', master_log_pos=711;

    命令说明:

    master_host :Master的地址,指的是容器的独立ip,可以通过docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称|容器id查询容器的ip

    image-20210609120100118

    master_port:Master的端口号,指的是容器的端口号

    master_user:用于数据同步的用户(上一步在主服务器配置的slave用户)

    master_password:用于同步的用户的密码(上一步在主服务器配置的password)

    master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值

    master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值

    master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒

  • 开启主从复制过程,并且查看状态

    start slave;#开启主从复制
    show slave status G;#查看主从复制状态

    image-20210609120613972

Slave_IO_Running 和 Slave_SQL_Running 都是Yes,说明主从复制已经开启。此时可以测试数据同步是否成功

 

1.3.4 验证主从复制

 1. 在主库中创建数据库,创建表,并插入数据

create database db01;

user db01;

create table user(
    id int(11) not null auto_increment,
    name varchar(50) not null,
    sex varchar(1),
    primary key (id)
)engine=innodb default charset=utf8;

insert into user(id,name,sex) values(null,'Tom','1');
insert into user(id,name,sex) values(null,'Trigger','0');
insert into user(id,name,sex) values(null,'Dawn','1');

2. 在从库中查询数据,进行验证 :

  • 在从库中,可以查看到刚才创建的数据库:

    1554544658640

    在该数据库中,查询user表中的数据:

    1554544679538

 

1.3.5 遇到的问题

  1. 使用docker重启mysql从服务器,docker ps -a 命令后发现启动失败,然后使用docker logs containerId检查失败原因

image-20210609102123719

从日志中可以看出是我们刚才在配置文件的适合把server-id写成了server_id造成的。

解决方法:

  • 方法一:直接修改容器内文件

    使用如下命令,获取到容器的元数据中找到对应数据

    docker inspect 84335f13e9e2

    image-20210609102948287

找到mysql的配置文件的存放位置,往下翻找到如下图位置,其中UpperDir就是存放MySQL配置文件的地方

image-20210609103118330

重新修改配置文件

cd /var/lib/docker/overlay2/818b484734608ddc6f672e125d495bc945d3b51855e87a104b20cf0a0d8f2010/diff
cd /etc/mysql
vim my.cnf

image-20210609103403388

  1. 使用命令show slave status G;后发现Slave_IO_Running= Connecting 和Slave_SQL_Running=Yes

    可以参考该博客:https://blog.csdn.net/weixin_39359455/article/details/104220723

3. 使用Navicat连接不上docker上的mysql服务器,出现如下错误

  1. image-20210609142901988

解决方案:

  • 首先检查虚拟机是否开放了该端口

    docker ps;#查看运行中的容器,查看docker容器外部访问端口

    image-20210609143122719

  • 检查虚拟机防火墙

    firewall-cmd --zone=public --list-ports;#查看开放的端口

    image-20210609143436407

    可以看到已经开放了3339/3340端口,如果没有开放这两个端口,可以使用如下命令

    firewall-cmd --zone=public --add-port=3339/tcp --premanent;
    firewall-cmd --zone=public --add-port=3339/tcp --premanent;
    firewall-cmd --reload;

    image-20210609143831755

  • 进入到mysql里面,查看远程登陆账户(参考连接:https://blog.csdn.net/seventopalsy/article/details/80195246)

    alter user 'root'@'%' identified with mysql_native_password by 'root';

    image-20210609144646274

4. MySQL同步故障:" Slave_SQL_Running:No" 两种解决办法

https://blog.csdn.net/heng_ji/article/details/51013710 

补充知识:centos7 相关

参考链接:https://www.cnblogs.com/heqiuyong/p/10460150.html

原文地址:https://www.cnblogs.com/seanRay/p/12831783.html