专题:Linux应用服务配置
各类Linux软件安装配置
更多内容请点击 我的博客 查看,欢迎来访。
MySQL主从同步配置
主从配置
主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服务器(master),其余的服务器充当从服务器(slave)。
异步复制,从服务器不需要一直连接着主服务器,从服务器甚至可以通过拨号断断续续地连接主服务器。通过配置文件,可以指定复制所有的数据库,某个数据库,甚至是某个数据库上的某个表。
主从配置好处
- 如果主服务器出现问题, 可以快速切换到从服务器提供的服务
- 通过增加从服务器来提高数据库的性能,在主服务器上执行写入和更新,在从服务器上向外提供读功能,可以动态地调整从服务器的数量,从而调整整个数据库的性能。
- 提高数据安全,因为数据已复制到从服务器,从服务器可以终止复制进程,所以,可以在从服务器上备份而不破坏主服务器相应数据。
在主服务器上生成实时数据,而在从服务器上分析这些数据,从而提高主服务器的性能。
主从同步步骤
- master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events);
- slave将master的binary log events拷贝到它的中继日志(relay log);
- slave重做中继日志中的事件,将改变反映它自己的数据。
主从配置的原理
主从配置是基于二进制日志来实现的,主服务器在执行增删改查时会将相关指令都记录在二进制日志文件中,然后从服务器通过读取和执行该文件来保持和主服务器一致。
安装Docker
环境为CentOS7
[root@centos7 ~]# yum install docker
# 启动
[root@centos7 ~]# service docker start
Redirecting to /bin/systemctl start docker.service
# docker开机自启
[root@centos7 ~]# chkconfig docker on
注意:正在将请求转发到“systemctl enable docker.service”。
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
Docker启动MySQL
下载镜像
# 搜索
[root@centos7 ~]# docker search mysql
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/mysql MySQL is a widely used, open-source relati... 8605 [OK]
docker.io docker.io/mariadb MariaDB is a community-developed fork of M... 2991 [OK]
docker.io docker.io/mysql/mysql-server Optimized MySQL Server Docker images. Crea... 635 [OK]
docker.io docker.io/percona Percona Server is a fork of the MySQL rela... 450 [OK]
# 下载镜像
[root@centos7 ~]# docker pull docker.io/mysql
# 查看镜像
[root@centos7 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/mysql latest b8fd9553f1f0 8 days ago 445 MB
启动主mysql
[root@centos7 ~]# docker run -d --name mysql_master -p 33061:3306 -e MYSQL_ROOT_PASSWORD=mysql_pswd -v /home/appdata/mysql/master/data:/var/lib/mysql -v /home/appdata/mysql/master/conf/my.cnf:/etc/mysql/my.cnf mysql
1d89bf3ffaf57c613df7df9b968d951934bd23776064037ea4b5ae84f9c8fd03
1、-d
:后台启动;这里直接后台启动即可,如果需要前台调试,用-it
,或者直接不写。
2、-p
:映射端口,容器的端口和宿主机的端口一一映射。
3、-v
:文件系统共享。本地的/home/appdata/mysql
目录和容器的/var/lib/mysql
目录映射共享。
4、–name
:给容器命名,便于后续直接通过docker start mysql_master
来快速启动
5、-e
:初始化mysql的root
密码。
[root@centos7 ~]# ls /home/appdata/mysql/
[root@centos7 ~]# 并没有东西,说明真的要手动创建,容器才能正常运行
[root@centos7 ~]#
[root@centos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@centos7 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1d89bf3ffaf5 mysql "docker-entrypoint..." About a minute ago Exited (1) About a minute ago mysql_master
# 删除容器后重新创建,不指定文件映射
[root@centos7 ~]# docker rm mysql_master
mysql_master
# 启动mysql
[root@centos7 ~]# docker run -d --name mysql_master -p 33061:3306 -e MYSQL_ROOT_PASSWORD=mysql_pswd mysql
955c8fa369cbad14455885f1c397da134fcd0c54bbf297652c065eff05015036
[root@centos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
955c8fa369cb mysql "docker-entrypoint..." 5 seconds ago Up 4 seconds 33060/tcp, 0.0.0.0:33061->3306/tcp mysql_master
[root@centos7 ~]# docker port mysql_master
3306/tcp -> 0.0.0.0:33061
启动从mysql
# 启动从mysql
[root@centos7 ~]# docker run -d --name mysql_slave -p 33062:3306 -e MYSQL_ROOT_PASSWORD=mysql_pswd mysql
efa85a2ff4f59a34eb467bdc0ee3cc105e3621fd3d662b68b689b593e1e6941f
# 查看启动好的主从mysql
[root@centos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
efa85a2ff4f5 mysql "docker-entrypoint..." 34 seconds ago Up 32 seconds 33060/tcp, 0.0.0.0:33062->3306/tcp mysql_slave
955c8fa369cb mysql "docker-entrypoint..." 22 hours ago Up 4 seconds 33060/tcp, 0.0.0.0:33061->3306/tcp mysql_master
- IP:33061 连接到主mysql:
docker start mysql_master
- IP:33062 连接到从mysql:
docker start mysql_slave
但是不允许root直接外部连接。
进入Docker配置mysql_master
[root@centos7 ~]# docker exec -it mysql_master /bin/bash
# 修改主mysql配置
root@955c8fa369cb:/# vim /etc/mysql/my.cnf
# 但是这儿提示vim没有安装,在安装之前还需要进行update
root@955c8fa369cb:/# apt-get update
root@955c8fa369cb:/# apt-get install vim
修改主mysql配置
# 修改mysql配置
root@955c8fa369cb:/# cd /etc/mysql/
root@955c8fa369cb:/etc/mysql# vim my.cnf
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# master config
# 启动二进制日志系统【必要】
log-bin=mysql-bin
# 服务器id,标识服务器实例,默认为1,主服务器server-id比从服务器server-id小,需要为唯一的值【必要】
server-id=1
# 值为0表示支持可读写、1的话表明仅支持可读
read-only=0
# 主从同步针对的数据库(除了mysql,sys,information_schema,performance_schema这些以外)的其它所有数据库都会进行同步(含数据库、表、数据等)
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
# Custom config should go here
!includedir /etc/mysql/conf.d/
配置参考
binlog-do-db=mysqldb # 表示只备份mysqldb,为数据表的名字,如果多个,则添加多行。
binlog_ignore_db=mysql # 表示忽略备份mysql。
# 不加binlog-do-db和binlog_ignore_db,那就表示备份全部数据库。
创建mysql同步账户并授权
# 进入mysql创建同步账号,并赋予权限
root@955c8fa369cb:/etc/mysql# mysql -uroot -p
Enter password: mysql_pswd
# 创建用户 CREATE USER 'user'@ 'X.X.X.X' IDENTIFIED BY '密码';
mysql> CREATE USER 'sync'@'%' IDENTIFIED BY 'sync_pswd';
Query OK, 0 rows affected (0.02 sec)
# 查看指定用户的权限
mysql> show grants for 'sync'@'%';
+----------------------------------+
| Grants for sync@% |
+----------------------------------+
| GRANT USAGE ON *.* TO `sync`@`%` |
+----------------------------------+
1 row in set (0.00 sec)
# 主库上创建同步用户并授权
mysql> GRANT REPLICATION SLAVE ON *.* TO 'sync'@'%';
Query OK, 0 rows affected (0.01 sec)
# 刷新权限,并查看该用户的权限
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)
mysql> show grants for 'sync'@'%';
+----------------------------------------------+
| Grants for sync@% |
+----------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO `sync`@`%` |
+----------------------------------------------+
1 row in set (0.00 sec)
查看master状态
# 查询master的状态,这儿的File,Position数据在配置从库时需要用到
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 542 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
进入Docker配置mysql_slave
[root@centos7 ~]# docker exec -it mysql_slave /bin/bash
root@efa85a2ff4f5:/# apt-get update
root@efa85a2ff4f5:/# apt-get install vim
修改从mysql配置
从库只需要开启server-id
且值不能和主库相同,一般做备份仅开启这个就行了,如果计划在主库故障时,从库要替代主库,那么还需要开启log-bin
。
如果要指定只同步的数据库,需要添加binlog-do-db=数据库名
,如果多个,添加多行即可;如果要指定忽略的数据库,指定replicate-ignore-db
# 修改从库mysql配置
oot@efa85a2ff4f5:/# vim /etc/mysql/my.cnf
# 在[mysqld]中添加
# slave config
log-bin=mysql-bin
server-id=2
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
# 重启Docker中的mysql
root@efa85a2ff4f5:/# exit
exit
[root@centos7 ~]# docker restart mysql_slave
mysql_slave
# 重启进入
[root@centos7 ~]# docker exec -it mysql_slave /bin/bash
root@efa85a2ff4f5:/# mysql -uroot -p
Enter password: mysql_pswd
配置从mysql连接到master
在从mysql中使用change master to
命令就同步配置,意思就是指定谁是master
,即同步谁的数据。需要指定主库当前的状态,即File
,Position
,如果change
失败,需要先mysql> stop slave;
再执行。
# 配置从服务器slave
mysql> change master to master_host='192.168.99.100',master_port=33061,master_user='sync',master_password='sync_pswd',master_log_file='mysql-bin.000002',master_log_pos=542;
Query OK, 0 rows affected, 2 warnings (0.03 sec)
开启slave
在从mysql中使用start slave
命令来启动slave。
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
查看slave状态
在从mysql中通过show slave status\G
命令查看状态。
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Connecting to master
Master_Host: 192.168.99.100
Master_User: sync
Master_Port: 33061
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 542
Relay_Log_File: efa85a2ff4f5-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql,sys,information_schema,performance_schema
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 542
Relay_Log_Space: 155
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 2003
Last_IO_Error: error connecting to master '[email protected]:33061' - retry-time: 60 retries: 1 message: Can`t connect to MySQL server on '192.168.99.100' (113)
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
Master_UUID:
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp: 190925 12:24:50
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set (0.00 sec)
此时发现错误
Last_IO_Error: error connecting to master '[email protected]:33061' - retry-time: 60 retries: 1 message: Can`t connect to MySQL server on '192.168.99.100' (113)
另外两个进程状态,IO进程和SQL进程状态:
Slave_IO_Running: Connecting # 该状态表示会一直尝试重连主,如果主正常了,该进程状态会自动变成Yes
Slave_SQL_Running: Yes
处理slave连接不上master问题
防火墙允许主mysql被连接
# 报错问题:Can't connect to MySQL server on '192.168.99.100' (113)
# 在从mysql的Docker中测试连接主mysql
root@efa85a2ff4f5:/# mysql -usync -psync_pswd -h 192.168.99.100 --port=33061
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 2003 (HY000): Can't connect to MySQL server on '192.168.99.100' (113)
关闭宿主机防火墙,或者允许防火墙,由于测试CentOS,直接配置firewall-cmd
即可
[root@centos7 ~]# firewall-cmd --zone=public --add-port=33061/tcp --permanent
success
[root@centos7 ~]# firewall-cmd --reload
success
测试连接主mysql及主从状态
在从mysql的Docker中,测试连接主mysql,看是否能连接上,如果能连接,证明防火墙修改成功。
root@efa85a2ff4f5:/# mysql -usync -psync_pswd -h 192.168.99.100 --port=33061
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 8.0.17 MySQL Community Server - GPL
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
登录从mysql,查看状态
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.99.100
Master_User: sync
Master_Port: 33061
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 542
Relay_Log_File: efa85a2ff4f5-relay-bin.000003
Relay_Log_Pos: 322
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql,sys,information_schema,performance_schema
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 542
Relay_Log_Space: 704
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: aee839e0-dbaf-11e9-9b84-0242ac110002
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set (0.00 sec)
ERROR:
No query specified
从状态结果可以看到
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates # 表示所有的relay log全部读取完毕
当这两个值都是Yes
是,表明主从同步已正常运行。
测试主mysql创建数据表后从mysql变化
登录主mysql,查看数据表
# 主mysql
root@955c8fa369cb:/etc/mysql# mysql -uroot -pmysql_pswd
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.03 sec)
在从mysql上查看数据表
# 从mysql
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.07 sec)
在主mysql随意创建一个数据表
# 主mysql
mysql> create database example;
Query OK, 1 row affected (0.01 sec)
# 查看状态
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 736 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
然后在从mysql查看
# 从mysql
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| example |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
# 查看状态
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.99.100
Master_User: sync
Master_Port: 33061
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 736
Relay_Log_File: efa85a2ff4f5-relay-bin.000003
Relay_Log_Pos: 516
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql,sys,information_schema,performance_schema
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 736
Relay_Log_Space: 898
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: aee839e0-dbaf-11e9-9b84-0242ac110002
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set (0.00 sec)
ERROR:
No query specified
主库因修改了数据,Position
会发生变化,同时从库中Read_Master_Log_Pos: 736
也会指向主库的Position
,如果结果不一致,且Slave_IO_Running、Slave_SQL_Running
都值都为Yes
时,则表明数据有延迟,还未同步完成。
Docker重启主mysql导致File变化
另一种情况是,每次Docker重启后,mysql_master中状态的File
会发生变化。
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 | 155 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
# 停止Docker再开启
[root@centos7 ~]# docker stop mysql_master
mysql_master
[root@centos7 ~]# docker start mysql_master
mysql_master
[root@centos7 ~]# docker exec -it mysql_master /bin/bash
root@955c8fa369cb:/# mysql -uroot -pmysql_pswd
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 | 155 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
也就是每次重新生成了binlog文件,所以从数据库需要修改关联的master。
所以从数据库需要进行修改
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
mysql> change master to master_host='192.168.99.100',master_port=33061,master_user='sync',master_password='sync_pswd',master_log_file='mysql-bin.000004',master_log_pos=155;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
注意,此时容易出现下面的错误,请等待一下
mysql> show slave status\G;
# ...
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
# ...
Last_IO_Error: error connecting to master '[email protected]:33061' - retry-time: 60 retries: 2 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.
# 过一会就正常了
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
主mysql中查看mysql-bin文件内容
可以通过mysqlbinlog
命令查看
root@955c8fa369cb:/# cd /var/lib/mysql/
root@955c8fa369cb:/var/lib/mysql# ls
#innodb_temp binlog.000002 binlog.index client-cert.pem ib_buffer_pool ibdata1 mysql-bin.000001 mysql-bin.000004 performance_schema server-cert.pem undo_001
auto.cnf binlog.000003 ca-key.pem client-key.pem ib_logfile0 ibtmp1 mysql-bin.000002 mysql-bin.index private_key.pem server-key.pem undo_002
binlog.000001 binlog.000004 ca.pem example ib_logfile1 mysql mysql-bin.000003 mysql.ibd public_key.pem sys
root@955c8fa369cb:/var/lib/mysql# mysqlbinlog mysql-bin.000004 | more
可以看到里面有很多对数据库操作的命令,如果数据量很多,这将会有很多行,也就是一般恢复数据不会直接读取该文件。
当业务从master转移到slave
从master转移到slave,即master因为某种原因宕机,业务已经连接slave进行读写,那么同步就会出错。
从mysql添加了新数据
例如在从mysql的example数据库中添加了新的表
# 从mysql
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| example |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
# 在example数据库中添加student表
mysql> use example;
Database changed
mysql> creat table student (
-> id int,
-> name varchar(20)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
+-------------------+
| Tables_in_example |
+-------------------+
| student |
+-------------------+
1 row in set (0.00 sec)
# 也就是从库更新了数据,状态也是正常的
mysql> show slave status\G;
# ...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
主mysql也添加了新数据
测试进入主库更新数据
# 主mysql
mysql> use example;
Database changed
mysql> show tables;
Empty set (0.00 sec)
mysql> create table course (id int, name varchar(20));
Query OK, 0 rows affected (0.03 sec)
mysql> show tables;
+-------------------+
| Tables_in_example |
+-------------------+
| course |
+-------------------+
1 row in set (0.00 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 | 372 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)
从mysql同步了主mysql新创建的数据
查看从mysql状态变化
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.99.100
Master_User: sync
Master_Port: 33061
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 372
Relay_Log_File: efa85a2ff4f5-relay-bin.000002
Relay_Log_Pos: 539
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
# 而实际它有另外一张表,也就是假定master故障后slave创建的student表,当master启动后,会把master新创建的course表同步过来。
mysql> use example;
Database changed
mysql> show tables;
+-------------------+
| Tables_in_example |
+-------------------+
| course |
| student |
+-------------------+
2 rows in set (0.00 sec)
Django配置读写分离
添加数据库
在 settings.py 添加主从数据库信息
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '192.168.99.116',
'PORT': 3306, # 主
'USER': 'root', # 主数据库用户名
'PASSWORD': 'password', # 主数据库密码
'NAME': 'database_name' # 主数据库名字
},
'slave': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '192.168.99.118',
'PORT': 3306, # 从数据库
'USER': 'root', # 从数据库用户名
'PASSWORD': 'password', # 从数据库密码
'NAME': 'database_name' # 从数据库名字
}
}
创建数据库操作路由分发类
在项目中创建一个utils文件夹,添加 db_router.py 文件
class MasterSlaveDBRouter(object):
"""数据库主从读写分离路由"""
def db_for_read(self, model, **hints):
"""读数据库"""
return "slave"
def db_for_write(self, model, **hints):
"""写数据库"""
return "default"
def allow_relation(self, obj1, obj2, **hints):
"""是否运行关联操作"""
配置读写分离路由
在 settings.py 中添加
# 配置读写分离
DATABASE_ROUTERS = ['ProjectName.utils.db_router.MasterSlaveDBRouter'] # 指定路由分发类