基于docker搭建mysql主从集群

在这里插入图片描述

github学习笔记

mysql 中的主从复制

1. 主从复制的介绍
/*
主从复制至少需要两台服务器,一台作为主库,一台作为从库.
主库: Master
从库: Slave

1) MySQL 的主从复制又叫 Replication、AB 复制。至少需要两个 MySQL 服务(可以是同一台机器,也可以是不同机器之间进行)。

    比如A服务器做主服务器,B服务器做从服务器,在A服务器上进行数据的更新,通过 binlog 日志记录同步到B服务器上,并重新执行(也叫重做)同步过来的 binlog 数据,从而达到两台服务器数据一致。

2) MySQL 数据库的主从复制方案,与使用 scp/rsync 等命令进行的文件级别复制类似,都是数据的远程传输。

    只不过 MySQL 的主从复制是其自带的功能,无需借助第三方工具,而且MySQL的主从复制并不是数据库磁盘上的文件直接拷贝,而是通过逻辑的 binlog 日志复制到要同步的服务器本地,然后由本地的线程读取日志里面的 SQL 语句,重新应用到 MySQL 数据库中。

3) mysql 支持一台主库同时向多态从库复制,从库也可以同时作为其他从服务器的主库,形成一个链式结构.



作用:
    1. 可以实时灾备,用于故障切换(主库出现问题,可以快速切换到从库提供服务)
    2. 读写分离,提供查询服务,实现负载均衡(降低主库的访问压力)
    3. 数据热备,避免影响业务(在从库中执行数据备份,不影响主库提供服务)

*/

2. 主从复制的原理
/*
主从复制主要有三步,其中和前边所讲的bin log 有关:
    1) Master 主库在事务提交时,会将数据变更记录到binlog中;
    2) Slave 从库会有一个IOThread的线程定时读取Master的binlog,写入到Slave从库的中继日Relay log中;
    3) Slave 会有一个SQLThread的线程对中继日志(Relay log)进行重做,从而改变自己的数据,使主从数据一致;
*/

主从复制原理图
在这里插入图片描述

3. 主从复制的搭建流程
/*
1) 服务器的准备,关闭防火墙或者开放指定端口,保证服务器mysql正常运行(可以使用 'systemctl status msyqld' 查看)

准备好服务器,至少需要两台,开放服务器端口
    A) firewall-cmd --zone=public --add-port=3306/tcp -premanent
    B) firewall-cmd reload
or
    A) systemctl stop firewalld
    B) systemctl disable firewalld

2) 修改服务器的配置文件
/etc/my.con

[mysqld]
server-id = 1
# 1 代表只读,0代表读写
read-only=0
#要生成二进制日志文件 主服务器一定要开启
log-bin = mysql-bin

3) 创建访问用户
*/
# 1 创建用户
mysql> create user '$username'@'%' identified by '$password';

# 2 设置用户权限
mysql> grant replication slave,replication client on *.* to '$username'@'%';

# 3 刷新权限
mysql> flush privileges;

# 4 查看用户权限
mysql> show grants for '$username'@'%';


/*
4) 开启主从同步
*/
# 从库关联主库
mysql> change master to master_host='$master_host',master_user='$master_user',master_password='$master_password',master_log_file='$bin_log_file',master_log_pos=$bin_log_index;

# 启动主从复制
mysql> start slave;


# 查看从库状态
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.2
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 769
               Relay_Log_File: f2229f66966b-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000001
        -- 这两个参数正常表示主从服务正常
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

.....

下面使用docker创建主从服务

  • Master
# Master

# 创建Master容器配置
# 创建宿主机挂载配置目录
[root@iZ2ze58f53sxjm9z7mgn5xZ ~]# mkdir mysql_test
[root@iZ2ze58f53sxjm9z7mgn5xZ ~]# cd mysql_test/
[root@iZ2ze58f53sxjm9z7mgn5xZ mysql_test]# mkdir -p master/conf master/data master/logs


# 指定镜像版本启动docker容器
[root@iZ2ze58f53sxjm9z7mgn5xZ mysql_test]#  docker run --name mysql-master -p 3310:3306 -v /root/mysql_test/master/conf:/etc/mysql/conf.d -v /root/mysql_test/master/data:/var/lib/mysql -v /root/mysql_test/master/logs:/var/log/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 

# 查看docker容器是否可以进入mysql
[root@iZ2ze58f53sxjm9z7mgn5xZ mysql_test]# docker exec -it mysql-master bash
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
bash-4.2# mysql -uroot -p123456

# --------配置/etc/mysql/conf.d/my.cnf,没有创建一个--------------
[mysqld]
server-id = 1
# 1 代表只读,0代表读写
read-only=0
#要生成二进制日志文件 主服务器一定要开启
log-bin = mysql-bin
# 指定同步的数据库,不指定则全部同步
# binlog-do-db=$db_name
# 如果从数据库有写入操作,也需要更新binlog
# log-slave-updates

# 配置文件修改完成重新启动mysql
[root@iZ2ze58f53sxjm9z7mgn5xZ mysql_test]# docker restart mysql-master

# ------------创建主服务器复制用户及相关权限-------------------

# 1 创建用户
mysql> create user 'slave'@'%' identified by '123456';
Query OK, 0 rows affected (0.00 sec)
# 2 设置用户权限
mysql> grant replication slave,replication client on *.* to 'slave'@'%';
Query OK, 0 rows affected (0.00 sec)
# 3 刷新权限
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
# 4 查看用户权限
mysql> show grants for 'slave'@'%';
+-------------------------------------------------------------------+
| Grants for slave@%                                                |
+-------------------------------------------------------------------+
| GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%' |
+-------------------------------------------------------------------+
1 row in set (0.00 sec)

#--------------------查看master对应的ip,slave会用到------------------------------------
[root@iZ2ze58f53sxjm9z7mgn5xZ ~]# docker inspect mysql-master
....
 "Networks": {
    "bridge": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": null,
        "NetworkID": "898ecd79eef9bfbc6fbe347f72da2784ccdfff92998af06a464601391d75bec2",
        "EndpointID": "8ce221372a3c9e697c42cdecbbb4fe50c24b067b45c17204af6756c3204058ee",
        "Gateway": "172.17.0.1",
        "IPAddress": "172.17.0.2",# 地址
....


  • Slave
# Slave

# 创建挂载目录
[root@iZ2ze58f53sxjm9z7mgn5xZ ~]# cd mysql_test/
[root@iZ2ze58f53sxjm9z7mgn5xZ mysql_test]# mkdir -p slave/data slave/conf slave/logs

# 创建slave从库容器
[root@iZ2ze58f53sxjm9z7mgn5xZ mysql_test]# docker run --name mysql-slave  -p 3333:3306 -v /root/mysql_test/slave/conf:/etc/mysql/conf.d -v /root/mysql_test/slave/data:/var/lib/mysql -v /root/mysql_test/slave/logs:/var/log/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7 

# 查看是否可以正常进入容器,如果启动失败,可以查看使用docker logs -f $container_name日志原因
[root@iZ2ze58f53sxjm9z7mgn5xZ mysql_test]# docker exec -it mysql-slave bash
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
bash-4.2# mysql -uroot -p123456


# --------配置/etc/mysql/conf.d/my.cnf,没有创建一个--------------
[mysqld]
server-id = 2
#要生成二进制日志文件 主服务器一定要开启
log-bin = mysql-bin


[root@iZ2ze58f53sxjm9z7mgn5xZ mysql_test]# docker restart mysql-slave bash

# 关联主从库
mysql> change master to master_host='172.17.0.2',master_user='slave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=769;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

# 启动主从复制
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

# 查看从库状态
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.2
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 769
               Relay_Log_File: f2229f66966b-relay-bin.000002
                Relay_Log_Pos: 320
.....
4. 主从复制测试

Master

-- 查询原有的数据
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

-- 创建一个数据库
mysql> create database my_test;
Query OK, 1 row affected (0.00 sec)

-- 创建成功
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| my_test            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)


Slave

-- 查看从库的原本数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)

-- master创建成功之后查看,成功同步过来
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| my_test            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

5. 切换主从
/*
1) SHOW PROCESSLIST; 检查slave是否已经应用完从Master读取过来的在relay log中的操作,如果未应用完不能stop slave,否则会造成数据会有丢失
*/

mysql> SHOW PROCESSLIST;
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time | State                                                  | Info             |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
|  5 | root        | localhost | NULL | Query   |    0 | starting                                               | SHOW PROCESSLIST |
|  6 | system user |           | NULL | Connect |  152 | Waiting for master to send event                       | NULL             |
|  7 | system user |           | NULL | Connect |  152 | Slave has read all relay log; waiting for more updates | NULL             |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
3 rows in set (0.00 sec)

-- 停止slave
mysql> stop slave;

-- 重新reset slave 为master
mysql> reset master;

-- 将其他slave的master设置为当前服务结点

-- 停止其他的slave
mysql> stop slave;

-- 更改关联
mysq> change master to ...
6. 主从集群中的错误
/*
1)  Error 'Character set '#255' is not a compiled character set and is not specified in the '/usr/share/mysql/charsets/Index.xml' file' on query. Default database: 'my_test'. Query: 'DROP TABLE `t` /* generated by server *\/'

该错误可能是从库的数据库版本比主库,导致复制过来的binlog解析不成功
*/

/*
2) Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'ANONYMOUS' at master log mysql-bin.000001, end_log_pos 1269. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.

复制过来的binlog在主库中找不到记录,也就是最后关联设置的master_log_pos太靠前了,然后执行删除或者什么其他操作,导致找不到对应需要同步的数据
*/
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值