主从复制的优点
1. 数据更安全:做了数据冗余,不会因为单台服务器的宕机而丢失数据
2. 性能大大提升:一主多从,不同用户从不同数据库读取,性能提升
3. 扩展性更优:流量增大时,可以方便的增加从服务器,不影响系统使用
4. 负载均衡:一主多从相当于分担了主机任务,做了负载均衡。
主从同步复制的缺点 (注: 一个衍生的配置是双主、互为主从配置,只要双方的修改不冲突,则可以工作良好。)
1. 主从间的数据库不是实时同步,就算网络连接正常,
也存在瞬间主从数据不一致的情况。
2. 如果主从的网络断开,则从库会在网络恢复正常后,批量进行同步。
3. 如果对从库进行修改数据,那么如果此时从库正在在执行主库的bin-log时,
则会出现错误而停止同步,这个是很危险的操作。
所以一般情况下,我们要非常小心的修改从库上的数据。
主从复制的工作过程
(1) Master 节点将数据的改变记录成二进制日志(bin log),
当Master. 上的数据发生改变时,则将其改变写入二进制日志中。
(2) Slave节点会在一定时 间间隔内对Master的二进制日志进行
探测其是否发生改变,如果发生改变,
则开始一个I/0线程请求Master的二进制事件。
(3) 同时Master节点为每个I/O线程启动一个dump线程,
用于向其发送二进制事件,并保存至Slave节点本地的中继日志( Relaylog) 中,
Slave节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,
即解析成sql 语句逐一 执行,使得其数据和Master节点的保持一致,
最后I/0线程和SQL线程将进入睡眠状态,等待下一次被唤醒。
搭建 MySQL 读写分离
1、首先拉取mysql镜像
安装docker(整体运行):
sudo apt-get update && sudo apt-get install
-y apt-transport-https ca-certificates
curl software-properties-common && curl
-fsSL https://download.docker.com/linux/ubuntu/gpg |
sudo apt-key add - && sudo add-apt-repository
"deb [arch=amd64]
http://mirrors.aliyun.com/docker-ce/linux/ubuntu
$(lsb_release -cs)
stable" && sudo apt-get update && sudo apt-get install -y docker-ce
docker pull mysql //拉取最新的镜像
docker pull mysql:5.7 //拉取指定版本镜像
docker ps -a //读取现运行docker镜像
2、启动mysql容器
//参数详解
// -d守护进程
// -p端口映射 -p 宿主机端口:容器端口
// --privileged=true 应用容器 获取宿主机root权限 (个别不需要加权限)
// -v 绑定共享映射目录,-v 宿主机目录:容器目录
// 查看虚拟ip
docker inspect -f '{{.Name}} -
{{.NetworkSettings.IPAddress }}'
$(docker ps -aq)
//主库
docker run -d -p 3308:3306 --privileged=true
-v ~/mysqldata/mysql_master/log:/var/log/mysql
-v ~/mysqldata/mysql_master/data:/var/lib/mysql
-v ~/mysqldata/mysql_master/conf/my.cnf:/etc/mysql/my.cnf
-e MYSQL_ROOT_PASSWORD=123456 --name mysql_master mysql:5.7
//从库
docker run -d -p 3309:3306 --privileged=true
-v ~/mysqldata/mysql_slave/log:/var/log/mysql
-v ~/mysqldata/mysql_slave/data:/var/lib/mysql
-v ~/mysqldata/mysql_slave/conf/my.cnf:/etc/mysql/my.cnf
-e MYSQL_ROOT_PASSWORD=123456 --name mysql_slave mysql:5.7
3、配置my.cnf文件
//**主库配置** 这里在宿主机更新配置文件后,容器也会同步更新
//在刚刚共享映射的宿主机conf目录新建my.cnf 写入以下内容
//我的目录是:/mysqldata/mysql_master/conf/my.cnf
// mysql_master目录 : conf
data
log
// mysql_slave 目录 : conf
data
log
[mysqld]
## 设置server_id 同一局域网中需要唯一
server_id=101
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=mall-mysql-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,stateement,row)
binlog_format=mixed
## 二进制日志过期清理时间 默认值为0 表示不自动清理
expire_logs_days=7
## 跳过主从复制值遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062错误是指一些主键重复 1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
//**从库配置** 这里在宿主机更新配置文件后,容器也会同步更新
//在刚刚共享映射的宿主机conf目录新建my.cnf 写入以下内容
//我的目录是:/mysqldata/mysql_slave/conf/my.cnf
[mysqld]
## 设置server_id 同一局域网中需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=mall-mysql-slave1-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,stateement,row)
binlog_format=mixed
## 二进制日志过期清理时间 默认值为0 表示不自动清理
expire_logs_days=7
## 跳过主从复制值遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062错误是指一些主键重复 1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
## relay_log配置中继日志
relay_log=mall-mysql-relay-bin
## log_slave_updates表示slave将复制事件写进自己的二进制日志中
log_slave_updates=1
## slave设置为只读(具有super权限的用户除外)
read_only=1
4、创建主服务器用户并查询状态
//重启主库容器
docker restart mysql_master
//进入主库容器
docker exec -it mysql_master /bin/bash
//进入容器命令行后进入mysql终端
mysql -uroot -p123456
mysql-uroot -h(主从虚拟id) -P3306 -p(密码)
//新建slave用户
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
//给slave用户分配权限
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'slave'@'%';
//查询主服务器状态
show master status;
5、配置从服务器
//重启从库容器
docker restart mysql_slave
//进入从库容器
docker exec -it mysql_slave /bin/bash
//进入容器命令行后进入mysql终端
mysql -uroot -p123456
mysql-uroot -h(主从虚拟id) -P3306 -p(密码)
//查看从库服务器状态
show slave status \G;
现在这两个状态为No
// slave配置连接master
// master_host 宿主机ip
// master_user 刚刚创建的主库用户
// master_password 刚刚创建的主库用户密码
// master_port 主库端口号
// master_log_file 刚刚在主库通过show master status;查询出来的File名称
// master_log_pos 刚刚在主库通过show master status;查询出来的Position
// master_connect_retry 重连的时间间隔
change master to master_host='172.17.0.2',
master_user='root', master_password='123456',
master_port=3306,master_log_file='mall-mysql-bin.000001',
master_log_pos=154, master_connect_retry=30;
//开启主从复制
start slave;
//查询查询从库状态
show slave status \G;
现在则变为yes
查询主从 server_id
show variables like '%server_id%';
记得测试哦~
主库(写)
//首先进入到主库创建一个库
create database test;
//进入库
use test123;
//创建一个测试表
create table t11(
id int,
name varchar(20));
//新增一条数据
insert into t11 values (1,'test');
//进入从库查询
use test;
select * from t11;
从库(读)