vim 操作命令:

 vim  文件名                    新建或打开文件: 

i                              进入编辑状态:

u (先按esc退出编辑状态)         上一步操作:

:wq!                       (先按esc退出编辑状态)保存:

主从备份:备份数据,更安全。

读写分离:解决的问题是,数据库的写入,影响了查询的效率。
提高查询效率。

1.准备

2台Centos7 虚拟机:

查看IP:ifconfig

server 主Ip ==192.168.42.133
slave 从Ip ==192.168.42.135

测试:ping 192.168.42.133

2.使用mariadb数据库

安装mariadb:

sudo yum -y install mariadb mariadb-server

操作mariadb:

systemctl start mariadb      #启动mariadb
systemctl stop mariadb       #停止mariadb
systemctl restart mariadb    #重启mariadb

3. 设置mariadb root用户密码:(后续要用)

mysqladmin -u root  -p password 1234
直接回车(不用输入密码)

4.进入mariadb数据库

mysql -uroot -p1234

5.安装telnet,这个工具在mysql主从备份会用到

sudo yum install telnet.x86_64 telnet-server.x86_64

(注意:输入y继续安装;安装失败,检查网络)

--------------------以上步骤,两个centos同步操作---------------------

6.在主centos中创建数据库

mysql -uroot -p1234

create database qqsx_test charset=utf8;

use qqsx_test;

create table goods (name char(2));

insert goods (name) values ('aa'),('bb'),('cc');
	
select * from goods;

数据库导出:(数据库外面输入)

mysqldump -uroot -p1234 qqsx_test > qqsx.sql

7.在从centos中导入数据库

把主备份数据库拷贝过来,在从数据库创建相同名字数据库。

mysql -uroot -p1234

show databases;  

create database qqsx_test charset=utf8;

查看后,没有qqsx_test,退出mariadb,

导入数据库:(数据库外面输入)

mysql -u root -p1234 qqsx_test < qqsx.sql

mysql -uroot -p1234

use qqsx_test;

show tables;

select * from goods;

8.主centos中配置

打开文件:

sudo vim /etc/my.cnf:

socket=/var/lib/mysql/mysql.sock
在此位置下加入4行配置:

innodb_file_per_table=No
log_bin=/var/lib/mysql/master-bin
binlog_format=mixed
server-id=200

授权:(进入数据库操作)

GRANT REPLICATION SLAVE ON *.* TO 'root'@'192.168.42.%' IDENTIFIED BY '1234' with grant option;

刷新权限:(进入数据库操作)

flush privileges;

重启服务器:(数据库外面输入)

systemctl restart mariadb

关防火墙:(数据库外面输入)

systemctl stop firewalld

查看一下主服务器状态:(进入数据库操作)

show master status;

9.从centos配置

打开文件:

sudo vim /etc/my.cnf:

socket=/var/lib/mysql/mysql.sock
在此位置下加入3行配置:

innodb_file_per_table=No
server-id=201
relay-log=/var/lib/mysql/relay-bin

重启服务器:(数据库外面输入)

systemctl restart mariadb

关防火墙:(数据库外面输入)

systemctl stop firewalld

连接主机:(进入数据库操作)

CHANGE MASTER TO MASTER_HOST='192.168.42.133',MASTER_USER='root',MASTER_PASSWORD='1234',MASTER_LOG_FILE='master-bin.000007',MASTER_LOG_POS=245;

(注意:报错,先关闭从服务器,stop slave;)

从机中启动备份:(进入数据库操作)

start slave;

查看状态:

show slave status\G;

连接成功的标志:

==================
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

查看错误日志:

cat /var/log/mariadb/mariadb.log

10.基于mysql的Django读写分离:

实际的生产环境中:由单台Mysql作为独立的数据库是不能满足实际需求的。一般来说都是通过主从复制(Master-Slave)的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。

基本的原理是:让主数据库处理增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。

11.具体在django项目中的应用:

  1. 在项目中的settings文件中配置数据库:
DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.mysql',
         'NAME': 'qqsx_gz',
         'USER':'root',
         'PASSWORD':'1234',
         'PORT':'3306',
         'HOST':'localhost'
    			 },
     'slave': {
         'ENGINE': 'django.db.backends.mysql',
         'NAME': 'qqsx_02',
         'USER': 'root',
         'PASSWORD': '1234',
         'HOST': 'localhost',
         'PORT': '3306'
    		  },
 			}
  1. 在mysql中创建 qqsx_02 数据库:
  2. 将qqsx_gz数据库表同步到qqsx_02数据库:
python manage.py migrate --database slave   # 将主数据库中的数据表迁移到从数据库

12.mysql的读写分离在django框架中有两种方式设置:

  1. 手动方式:
    在使用数据库时,通过.using(db_name)来手动指定要使用的数据库。
    例如:
    GoodInfo.object.using('default').all() 说明default这个设置下的数据库是用来专门读取数据的
    Usermessage.object.using('slave').create() 说明slave这个设置下的数据库是专门来写入数据的
  2. 自动方式:
    2.1 在项目的根目录创建myrouter.py脚本:
    class DBRouter(object):
def db_for_read(self, model, **hints):
 	return 'default'

 def db_for_write(self, model, **hints):
 	return 'slave'

2.2 在项目中的配置文件加上数据库路由相关配置

DATABASE_ROUTERS = ['myrouter.DBRouter']

13.拓展分表

1.一主多从方案:

class Router: 
	def db_for_read(self, model, **hints): 
	""" 读取时随机选择一个数据库 """ 
		import random 
		return random.choice(['db2', 'db3', 'db4']) 

	def db_for_write(self, model, **hints): 
		""" 写入时选择主库 """ 
		return 'default'

2.分库分表

class Router: 

	def db_for_read(self, model, **hints): 
			if model._meta.app_label == 'app01': 
				return 'db1' 
			if model._meta.app_label == 'app02': 
				return 'db2' 

	def db_for_write(self, model, **hints): 
			if model._meta.app_label == 'app01': 
				return 'db1' 
			if model._meta.app_label == 'app02': 
				return 'db2'