數據庫主從搭建
為什么要搭建數據庫主從,因為一個項目一般都是讀的操作比寫的操作多很多,所以搭建主從,實現讀寫分離,減輕數據庫壓力。
2.1 主從同步原理
mysql主從配置的流程大體如圖:
1)master會將變動記錄到二進制日志里面;
2)master有一個I/O線程將二進制日志發送到slave;
- slave有一個I/O線程把master發送的二進制寫入到relay日志里面;
4)slave有一個SQL線程,按照relay日志處理slave的數據;
2.2 注意點
1 咱們用docker模擬了兩台服務器,服務器的系統,mysql的版本必須一致
2.3 具體步驟,啟動主庫
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
#寫入
[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---
[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
2.4 啟動從庫
#在home目錄下創建mysql2文件夾,下面創建data和conf.d文件夾
mkdir /home/mysql2
mkdir /home/mysql2/conf.d
mkdir /home/mysql2/data/
#mkdir /home/mysql2 /home/mysql2/conf.d /home/mysql2/data/
# 創建my.cnf配置文件
touch /home/mysql2/my.cnf
[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password
secure_file_priv=/var/lib/mysql
datadir=/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
server-id=101
log-bin=mysql-slave-bin
relay_log=edu-mysql-relay-bin
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
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.5 遠程連接到主庫和從庫
#主庫
mysql -h 101.133.225.166 -P 33307 -u root -p123456
##創建test用戶,設置任意ip地址可以訪問,密碼為123
create user 'test'@'%' identified by '123';
##授權用戶,把所有權限授權給test,他就相當於root了
grant all privileges on *.* to 'test'@'%' ;
###刷新權限
flush privileges;
#查看主服務器狀態(顯示如下圖)
show master status;
#從庫
mysql -h 101.133.225.166 -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='101.133.225.166',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;
2.6 測試
#在主庫上創建數據庫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;
補充:查看容器啟動日志
docker logs b8bdd9c57f22
3 django實現讀寫分離
makemigrations
#同步數據庫
migrate #表示同步到default數據庫
migrate app01 --database=db1
3.2 手動控制讀寫分離
def index(request):
#向數據表中存條數據
#寫到哪個庫中了?默認情況下寫到default
# ret=models.Book.objects.using('default').create(name="xxx")
# print(ret)
#讀第一條數據,默認從哪讀?default
#指定去從庫讀?在queryset對象后加個.using('db1')
# ret=models.Book.objects.all().first()
ret=models.Book.objects.all().using('db1').first()
print(ret.name)
return HttpResponse("ok")
3.3 自動讀寫分離
#第一步:在項目根路徑下創建一個py文件(database_router.py)
class DatabaseAppsRouter(object):
def db_for_read(self, model, **hints):
#讀可能去db1或者db2中讀,
return 'db1'
def db_for_write(self, model, **hints):
print(model)
return 'default'
def allow_migrate(self, db, app_label, model_name=None, **hints):
print(db)
print(app_label)
print(model_name)
if app_label=='app01' and db=="db1":
return False
return None
# 第二部,在setting中配置
DATABASE_ROUTERS = ['mydjangotest.database_router.DatabaseAppsRouter']
3.4 allow_migrate的使用
migrate app01 --database=db1 #不會同步
migrate app01 --database=default #可以同步
#用來控制數據表同步時,不能同步到從庫中