原文来源于:程序员恰恰
如有侵权,联系删除
1.为什么使用 MySQL 主从 ?
2. 主从复制原理解释
3.使用Docker主从搭建步骤
4.配置主服务器
5.配置从服务器
6.验证环节
本文使用docker环境配置mysql主从复制,使用其他环境命令相同,配置方式相同,并无差异.
MySQL主从复制是MysQL数据库自带功能,无需借助第三方工具。底层原理是基于Mysql数据库自带的二进制日志功能。就是一台或多台AysQL数据库(slave,即从库)从另一台MysQL数据库(master,即主库)进行日志的复制然后再解析日志并应用到自身,最终实现从库的数据和主库的数据保持一致。
1.为什么使用 MySQL 主从 ?
大部分系统的访问模型是读多写少,读写请求量的差距可能达到几个数量级,所以我们可以通过一主多从的方式,主库只负责写入和部分核心逻辑的查询,多个从库只负责查询,提升查询性能,降低主库压力。
当主库宕机时,从库可以切成主库,保证服务的高可用,然后主库也可以做数据的容灾备份,整体场景总结如下:
读写分离:从库提供查询,减少主库压力,提升性能;
高可用:故障时可切换从库,保证服务高可用;
数据备份:数据备份到从库,防止服务器宕机导致数据丢失。
2. 主从复制原理解释
MySQL 的主从复制是依赖于 binlog,也就是记录 MySQL 上的所有变化并以二进制形式保存在磁盘上二进制日志文件。
主从复制就是将 binlog 中的数据从主库传输到从库上,一般这个过程是异步的,即主库上的操作不会等待 binlog 同步地完成。
详细流程如下:
主库写 binlog:主库的更新 SQL(update、insert、delete) 被写到 binlog;
主库发送 binlog:主库创建一个 log dump 线程来发送 binlog 给从库;
从库写 relay log:从库在连接到主节点时会创建一个 IO 线程,以请求主库更新的 binlog,并且把接收到的 binlog 信息写入一个叫做 relay log 的日志文件;
从库回放:从库还会创建一个 SQL 线程读取 relay log 中的内容,并且在从库中做回放,最终实现主从的一致性。
3.使用Docker主从搭建步骤
3.1. 新建主服务器容器实例mysql01
docker run --restart=always --privileged=true -d -v /Users/free/code/log/mysqlDockerData/data:/var/lib/mysql -v /Users/free/code/log/mysqlDockerData/conf:/etc/mysql/conf.d -v /Users/free/code/log/mysqlDockerData/myconf/my.cnf:/etc/mysql/my.cnf -p 3308:3306 --name mysql01 -e MYSQL_ROOT_PASSWORD=1234 mysql
3.2.新建从服务器Mysql 实例mysql02
docker run --restart=always --privileged=true -d -v /Users/free/code/log/mysqlDockerData2/data:/var/lib/mysql -v /Users/free/code/log/mysqlDockerData2/conf:/etc/mysql/conf.d -v /Users/free/code/log/mysqlDockerData2/myconf/my.cnf:/etc/mysql/my.cnf -p 3309:3306 --name mysql02 -e MYSQL_ROOT_PASSWORD=1234 mysql
下面这两个目录就是我的宿主机与容器的共享目录.(大家需要换成自己的,不懂的话就学一下docker数据卷)
其中:mysqlDockerDate是master的共享目 ,mysqlDockerDate2是Slaver的共享目录
内部目录分别为:
3.3 容器创建成功
3.4 通过navicate验证链接成功.
4.配置主服务器
4.1 开启binlog
在/Users/free/code/log/mysqlDockerData/myconf
添加数据库配置文件:在myconf中的创建文件 my.cfg 并添加如下配置
[mysqld]
#开启二进制日志
log-bin=mysql-bin
#标识唯一id(必须),一般使用ip最后位
server-id=1
#不同步的数据库,可设置多个
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=mysql
#指定需要同步的数据库(和slave是相互匹配的),可以设置多个
binlog-do-db=test
添加日志存储方式和规则(选填)
#设置存储模式不设置默认
binlog_format=MIXED
#日志清理时间
expire_logs_days=7
#日志大小
max_binlog_size=100m
#缓存大小
binlog_cache_size=4m
#最大缓存大小
max_binlog_cache_size=521m
4.2 修改完配置后重启master实例
[root@k8snode2 conf]# docker restart mysql01
进入主数据库(File :mall-mysql-bin.000003 和Position 371 后面要用 )
[root@k8snode2 conf]# docker exec -it mysql-master /bin/bash
root@079c84d293f0:/# mysql -uroot -proot
mysql> show master status;
+-----------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+----------+--------------+------------------+-------------------+
| mall-mysql-bin.000003 | 371 | | mysql | |
+-----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec
5.配置从服务器
5.1 同理在/Users/free/code/log/mysqlDockerData2/myconf目录下新建my.cnf并添加配置
#开启二进制日志
log-bin=mysql-bin
server-id=2
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=mysql
#与主库配置保持一致
replicate-do-db=test
replicate-ignore-db=mysql
log-slave-updates
slave-skip-errors=all
slave-net-timeout=60
5.2 修改完配置后重启slave实例
[root@k8snode2 conf]# docker restart mysql02
5.3 进入从服务器数据库,执行一下命令
[root@k8snode2 conf]# docker exec -it mysql-slave /bin/bash
root@b4fc23c7d9b4:/# mysql -uroot -proot
mysql> change master to master_host='192.168.248.128', master_user='root', master_password='root',
-> master_port=3307, master_log_file='mall-mysql-bin.000003', master_log_pos=371, master_connect_retry=30;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
注:上面的master_log_file是在配置Master的时候的File字段, master_log_pos是在配置Master的Position 字段。一定要一一对应
master_host:主数据库的IP地址;
master_port:主数据库的运行端口;
master_user:在主数据库创建的用于同步数据的用户账号;
master_password:在主数据库创建的用于同步数据的用户密码;
master_log_file:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数;
master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态,获取Position参数;
master_connect_retry:连接失败重试的时间间隔,单位为秒。
6.验证环节
6.1.主数据库新建库
mysql> ceate database t1;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ceate database t1' at line 1
mysql> create database t1;
Query OK, 1 row affected (0.00 sec)
6.2.从服务器查看库,发现从库已经多了一个库t1数据库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| t1 |
+--------------------+
5 rows in set (0.01 sec)