1、主从配置原理
mysql主从配置的流程大体如图:
1、master会将变动记录到二进制日志里面
2、master有一个I/O线程将二进制日志发送到slave
3、slave有一个I/O线程把master发送的二进制写入到relay日志里面
4、slave有一个SQL线程,按照relay日志处理slave的数据
2、操作步骤
2.1、准备两台装好mysql的服务器
环境 | mysql版本 | ip地址:端口号 |
---|---|---|
主库(master) | 5.7 | 192.168.12.80:33307 |
从库(slave) | 5.7 | 192.168.12.80:33306 |
用docker拉起两个mysql容器,步骤如下
# 拉取mysql5.7镜像
docker pull mysql:5.7
# 在home目录下创建mysql文件夹,下面创建data和conf.d文件夹
mkdir /home/mysql
mkdir /home/mysql/conf.d
mkdir /home/mysql/data/
创建my.cnf配置文件
touch /home/mysql/my.cnf
mkdir /home/mysql2
mkdir /home/mysql2/conf.d
mkdir /home/mysql2/data/
touch /home/mysql2/my.cnf
my.cnf添加如下内容:
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
expire_logs_days=7
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
max_connections=1000
# 主库 ---> start ---> 同一局域网内注意要唯一
server-id=100
# 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin
# 主库 ---> end
# 从库 ---> start
# 设置server_id,注意要唯一
server-id=101
# 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin
# relay_log配置中继日志
relay_log=edu-mysql-relay-bin
# 从库 ---> end
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
# 启动主库容器(挂载外部目录,端口映射成33307,密码设置为123456)
docker run -di -v /home/mysql/data/:/var/lib/mysql -v /home/mysql/conf.d:/etc/mysql/conf.d -v /home/mysql/my.cnf:/etc/mysql/my.cnf -p 33307:3306 --name mysql-master -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
# 启动从库容器(挂载外部目录,端口映射成33306,密码设置为123456)
docker run -di -v /home/mysql2/data/:/var/lib/mysql -v /home/mysql2/conf.d:/etc/mysql/conf.d -v /home/mysql2/my.cnf:/etc/mysql/my.cnf -p 33306:3306 --name mysql-slave -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
2.2、远程连接入主库和从库
# 连接主库
mysql -h 192.168.12.80 -P 33307 -u root -p123456
# 在主库创建用户并授权
# 创建test用户
create user 'test'@'%' identified by '123';
# 授权用户
grant all privileges on *.* to 'test'@'%';
# 刷新权限
flush privileges;
# 查看主服务器状态(显示如下图)
show master status;
# 连接从库
mysql -h 192.168.12.80 -P 33306 -u root -p123456
# 配置详解
/*
change master to
master_host='MySQL主服务器IP地址',
master_user='之前在MySQL主服务器上面创建的用户名',
master_password='之前创建的密码',
master_log_file='MySQL主服务器状态中的二进制文件名',
master_log_pos='MySQL主服务器状态中的position值';
*/
# 命令如下
change master to master_host='192.168.12.80',master_port=33307,master_user='test',master_password='123',master_log_file='mysql-bin.000003',master_log_pos=0;
# 启用从库
start slave;
# 查看从库状态(如下图)
show slave status\G;
切记:防火墙要关闭,主和从上面的server-id不要重复!
2.3、测试主从同步
# 在主库上创建数据库test1
create database test1;
use test1;
# 创建表
create table tom (id int not null,name varchar(100)not null ,age tinyint);
#插入数据
insert tom (id,name,age) values(1,'xxx',20),(2,'yyy',7),(3,'zzz',23);
# 在从库上查看是否同步成功
# 查看数据库
show database;
use test1;
# 查看表
show tables;
# 查看数据
select * from test1;
2、django实现读写分离
前提:主从搭建成功
1、在django框架setting中配置:
DATABASES = {
# 主库
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'book',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '192.168.12.80',
'PORT': 33307,
},
# 从库
'db1': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'book',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '192.168.12.80',
'PORT': 33306,
},
}
2、去models中创建数据模型,并迁移文件
3、方式一
手动指定
# 向default库写,主库
res = models.Book.objects.using('default').create(name='西游记',price=33.4)
# 去从库查
res = models.Book.objects.using('db1').all().first()
print(res.name)
4、方式二
自动指定(写router和配置setting)
class Router1:
def db_for_read(self, model, **hints):
return 'db1'
def db_for_write(self, model, **hints):
return 'default'
# 在setting中注册
DATABASE_ROUTERS = ['db_router.Router1',]
注册完成以后只要是写操作,就会用default,只要是读操作自动去db1
5、更细粒度的控制数据来源
class Router1:
def db_for_read(self, model, **hints):
if model._meta.model_name == 'book':
return 'db1'
else:
return 'default'
def db_for_write(self, model, **hints):
return 'default'
6、在数据库迁移时,可以指定把任意app的表结构迁移到任意库
python manage.py migrate app01 --database=default