https://www.cnblogs.com/gl-developer/p/6170423.html
docker 安装两个数据库并设置主从备份
1.创建数据库配置文件
因为实验室机房限制无法准备多个机器,此处使用docker创建数据库模拟多个机器,可以在宿主机上创建配置文件目录,本次采用如下两个s目录用于存放配置文件
- Master:/root/db1/my.cnf
- Slave: /root/db2/my.cnf
Master配置文件如下:
[mysqld]
## 同一局域网内注意要唯一
server-id=100
## 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin
Slave配置文件如下:
和配置Master(主)一样,在Slave配置文件my.cnf中添加如下配置:
[mysqld]
## 设置server_id,注意要唯一
server-id=101
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin
2 拉取镜像并创建数据库
- docker pull mysql:5.7
- docker run --name db1 -p 3316:3306 -v /root/db1/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
- docker run --name db2 -p 3326:3306 -v /root/db2/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
[root@mycat ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
69692152171a: Pull complete
1651b0be3df3: Pull complete
951da7386bc8: Pull complete
0f86c95aa242: Pull complete
37ba2d8bd4fe: Pull complete
6d278bb05e94: Pull complete
497efbd93a3e: Pull complete
a023ae82eef5: Pull complete
e76c35f20ee7: Pull complete
e887524d2ef9: Pull complete
ccb65627e1c3: Pull complete
Digest: sha256:a682e3c78fc5bd941e9db080b4796c75f69a28a8cad65677c23f7a9f18ba21fa
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
[root@mycat db1]# docker run --name db1 -p 3316:3306 -v /root/db1/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
9eb8623c5497eb8abb16494e1820095043fb00ac69a8ec15646176e88372ba3d
[root@mycat db1]# docker run --name db2 -p 3326:3306 -v /root/db2/my.cnf:/etc/mysql/my.cnf -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
81acbc129d8317d152dcceeed1140c6948d40c25c7c8cacfaf30788e0239a63f
[root@mycat db1]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
81acbc129d83 mysql:5.7 "docker-entrypoint.s…" 5 seconds ago Up 2 seconds 33060/tcp, 0.0.0.0:3326->3306/tcp, :::3326->3306/tcp db2
9eb8623c5497 mysql:5.7 "docker-entrypoint.s…" 19 seconds ago Up 17 seconds 33060/tcp, 0.0.0.0:3316->3306/tcp, :::3316->3306/tcp db1
Master对外映射的端口是3316,Slave对外映射的端口是3326。因为docker容器是相互独立的,每个容器有其独立的ip,所以不同容器使用相同的端口并不会冲突。
3 使用客户端工具测试
4.MySQL主从复制原理
1、为什么需要主从复制?
1、 在业务复杂的系统中,有这么一个情景,有一句sql语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作;
2、 做数据的热备;
3、 架构的扩展业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能;
2、什么是mysql的主从复制?
MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。
3、mysql复制原理
原理:
(1)master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;
(2)slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件
(3)同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。
也就是说:
- 从库会生成两个线程,一个I/O线程,一个SQL线程;
- I/O线程会去请求主库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中;
- 主库会生成一个log dump线程,用来给从库I/O线程传binlog;
- SQL线程,会读取relay log文件中的日志,并解析成sql语句逐一执行;
注意:
1–master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启binlog二进制日志功能;通常为了数据安全考虑,slave也开启binlog功能)。
2–slave开启两个线程:IO线程和SQL线程。其中:IO线程负责读取master的binlog内容到中继日志relay log里;SQL线程负责从relay log日志里读出binlog内容,并更新到slave的数据库里,这样就能保证slave数据和master数据保持一致了。
3–Mysql复制至少需要两个Mysql的服务,当然Mysql服务可以分布在不同的服务器上,也可以在一台服务器上启动多个服务。
4–Mysql复制最好确保master和slave服务器上的Mysql版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)
5–master和slave两节点间时间需同步
4、延时问题
mysql的主从复制都是单线程的操作,主库对所有DDL和DML产生的日志写进binlog,由于binlog是顺序写,所以效率很高,slave的sql thread线程将主库的DDL和DML操作事件在slave中重放。DML和DDL的IO操作是随机的,不是顺序,所以成本要高很多,另一方面,由于sql thread也是单线程的,当主库的并发较高时,产生的DML数量超过slave的SQL thread所能处理的速度,或者当slave中有大型query语句产生了锁等待,那么延时就产生了。
解决方案:
1、 业务的持久化层的实现采用分库架构,mysql服务可平行扩展,分散压力;
2、 单个库读写分离,一主多从,主写从读,分散压力这样从库压力比主库高,保护主库;
3、 服务的基础架构在业务和mysql之间加入memcache或者redis的cache层降低mysql的读压力;
4、 不同业务的mysql物理上放在不同机器,分散压力;
5、 使用比主库更好的硬件设备作为slave,mysql压力小,延迟自然会变小;
6、 使用更加强劲的硬件设备;
5 配置主从复制
在Master数据库创建数据同步用户,授予用户 slave REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据。
通过docker exec -it db1 /bin/bash
命令进入到Master容器内部执行mysql客户端执行如下脚本。
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
在Master进入mysql,执行show master status;
mysql> show master status ;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 617 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)
File和Position字段的值后面将会用到,在后面的操作完成之前,需要保证Master库不能做任何操作,否则将会引起状态变化,File和Position字段的值变化。
退出master数据库,回到宿主机执行docker命令查看两个容器的ip
mysql> exit
Bye
root@9eb8623c5497:/# exit
exit
[root@mycat ~]# docker inspect --format '{
{ .NetworkSettings.IPAddress }}' db1
172.17.0.2
[root@mycat ~]# docker inspect --format '{
{ .NetworkSettings.IPAddress }}' db2
172.17.0.3
[root@mycat ~]#
在Slave 中进入 mysql,执行change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos= 2830, master_connect_retry=30;
命令说明:
master_host :Master机器的地址,此处指的是容器的独立ip(生产上应该是Master机器的ip),可以通过如下命令查询容器的ip
docker inspect --format='{
{.NetworkSettings.IPAddress}}' 容器名称|容器id
master_port:Master的端口号,指的是容器的端口号
master_user:用于数据同步的用户
master_password:用于同步的用户的密码
master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒
在Slave 中的mysql终端执行show slave status \G;
用于查看主从同步状态。
[root@mycat ~]# docker exec -it db2 /bin/bash
root@81acbc129d83:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.34-log MySQL Community Server (GPL)
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000003', master_log_pos= 617, master_connect_retry=30;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: 172.17.0.2
Master_User: slave
Master_Port: 3306
Connect_Retry: 30
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 617
Relay_Log_File: edu-mysql-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: No
Slave_SQL_Running: No
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: 617
Relay_Log_Space: 154
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: NULL
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: 0
Master_UUID:
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
ERROR:
No query specified
mysql>
正常情况下,SlaveIORunning 和 SlaveSQLRunning 都是No,因为我们还没有开启主从复制过程。使用start slave
开启主从复制过程,然后再次查询主从同步状态show slave status \G;
。
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: 30
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 617
Relay_Log_File: edu-mysql-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000003
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: 617
Relay_Log_Space: 531
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: 100
Master_UUID: 0be39b8d-ccec-11eb-9573-0242ac110002
Master_Info_File: /var/lib/mysql/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:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
ERROR:
No query specified
mysql>
SlaveIORunning 和 SlaveSQLRunning 都是Yes,说明主从复制已经开启。此时可以测试数据同步是否成功。
使用start slave
开启主从复制过程后,如果SlaveIORunning一直是Connecting,则说明主从复制一直处于连接状态,这种情况一般是下面几种原因造成的,我们可以根据 Last_IO_Error提示予以排除。
1、 网络不通;
检查ip,端口
2、 密码不对;
检查是否创建用于同步的用户和用户密码是否正确
3、 pos不对;
检查Master的 Position
6.测试主从复制
测试主从复制方式就十分多了,最简单的是在Master创建一个数据库,然后检查Slave是否存在此数据库。
7.安装在宿主机上安装mysql客户端,测试连通性
- yum install -y mysql
- mysql -uroot -p123456 -h 172.17.0.2 -P 3306
- mysql -uroot -p123456 -h 172.17.0.3 -P 3306
[root@mycat bin]# yum install mysql
已加载插件:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
* epel: mirrors.neusoft.edu.cn
base | 3.6 kB 00:00:00
docker-ce-stable | 3.5 kB 00:00:00
extras | 2.9 kB 00:00:00
updates | 2.9 kB 00:00:00
(1/2): extras/7/x86_64/primary_db | 242 kB 00:00:00
(2/2): updates/7/x86_64/primary_db | 8.8 MB 00:00:01
正在解决依赖关系
There are unfinished transactions remaining. You might consider running yum-complete-transaction, or "yum-complete-transaction --cleanup-only" and "yum history redo last", first to finish them. If those don't work you'll have to try removing/installing packages by hand (maybe package-cleanup can help).
--> 正在检查事务
---> 软件包 mariadb.x86_64.1.5.5.68-1.el7 将被 安装
--> 解决依赖关系完成
依赖关系解决
===============================================================================================================================================================================================
Package 架构 版本 源 大小
===============================================================================================================================================================================================
正在安装:
mariadb x86_64 1:5.5.68-1.el7 base 8.8 M
事务概要
===============================================================================================================================================================================================
安装 1 软件包
总下载量:8.8 M
安装大小:49 M
Is this ok [y/d/N]: y
Downloading packages:
mariadb-5.5.68-1.el7.x86_64.rpm | 8.8 MB 00:00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
正在安装 : 1:mariadb-5.5.68-1.el7.x86_64 1/1
验证中 : 1:mariadb-5.5.68-1.el7.x86_64 1/1
已安装:
mariadb.x86_64 1:5.5.68-1.el7
完毕!
[root@mycat bin]# mysql -uroot -p123456 -h 172.17.0.2 -P 3306
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.34-log MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
MySQL [(none)]> exit
Bye
[root@mycat bin]# mysql -uroot -p123456 -h 172.17.0.3 -P 3306
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 5.7.34-log MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
MySQL [(none)]>
关注公众号,获取等多资讯
版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: