欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MySQL主从复制实现读写分离

程序员文章站 2022-05-08 19:43:07
...

MySQL主从复制实现读写分离

1. 读写分离原理

1.1 什么是主从同步

指一台服务器充当主数据库服务器,另一台或多台服务器充当从数据库服务器,主服务器中的数据自动复制到从服务器之中。其实就是从服务器重放主服务器的操作步骤,实现主从数据一致。

1.2 为什么要实现主从同步

(1)实现服务器负载均衡
通过主、从服务器之前切分处理客户查询符合,从而得到更好的客户相应时间。主要方案有:

  • master处理记录的新增、修改、删除的功能,把查询交给slave去做。
  • master处理记录的新增、修改、删除的功能,并且master还要承担部分查询任务,而slave只负责查询数据。当主服务器比较忙时,部分查询请求会自动发送到从服务器重,以降低主服务器的工作负荷。

(2)实现数据的异地备份
定期的将数据从master 服务器上复制到slave服务器上,实现了异地备份。相对于将数据备份在本地,这种方式可以避免降低master服务器的性能,同时降低了因为master服务器硬盘损坏、服务器异常而导致数据无法恢复的危险。

(3)提高数据库系统的可用性
当主服务器出现问题时,可以马上让从服务器作为主服务器,用来数据的更新与查询服务。

1.3 怎么实现主从同步

mysql支持的复制类型

  • 基于语句的复制: 在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。一旦发现没法精确复制时, 会自动选着基于行的复制。
  • 基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持
  • 混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
    MySQL主从复制实现读写分离

主从复制工作原理剖析

1.Master 数据库只要发生变化,立马记录到Binary log 日志文件中
2.Slave数据库启动一个I/O thread连接Master数据库,请求Master变化的二进制日志
3.Slave I/O获取到的二进制日志,保存到自己的Relay log 日志文件中。
4.Slave 有一个 SQL thread定时检查Realy log是否变化,变化那么就更新数据

2. 数据库环境准备

这里我准备了两台服务器(centos7),在上面都安装了mysql5.7.30,两台服务器网络畅通:

主服务器(master):192.168.0.101
从服务器(slave):192.168.0.105

将主库要同步的数据库数据先同步到从库。

3. master配置

3.1 修改mysql配置文件

在msyql配置文件中添加一下配置(主要配置server-id、log-bin和binlog-do-db):vim /etc/my.cnf

server-id= 1        # 节点ID,确保唯一

# log config
log-bin= mysql-bin     #开启mysql的binlog日志功能
binlog-do-db=oyc      #二进制日志记录的数据库(多数据库用逗号,隔开)
binlog-ignore-db=mysql #不生成日志文件的数据库,多个忽略数据库可以用逗号拼接,或者 复制这句话,写多行

sync_binlog= 1         #控制数据库的binlog刷到磁盘上去 , 0 不控制,性能最好,1每次事物提交都会刷到日志文件中,性能最差,最安全
binlog_format= mixed   #binlog日志格式,mysql默认采用statement,建议使用mixed
expire_logs_days= 7                           #binlog过期清理时间
max_binlog_size= 100m                    #binlog每个日志文件大小
binlog_cache_size= 4m                        #binlog缓存大小
max_binlog_cache_size= 512m              #最大binlog缓存大
auto-increment-offset= 1     # 自增值的偏移量
auto-increment-increment= 1  # 自增值的自增量
slave-skip-errors= all #跳过从库错误

3.2 重启mysql

systemctl restart mysql
或者 service mysqld restart

3.3 创建同步用户并授权

1.进入master的数据库,为master创建复制用户

create user oyc identified by '123456';

2.赋予该用户复制的权利

grant replication slave on *.* to 'oyc'@'192.168.0.105'  identified by '123456';
flush privieges;

3.查看master的状态

show master status;

MySQL主从复制实现读写分离

4. slave配置

4.1 修改从库配置文件

同步表配置说明:

replicate-do-db 设定需要复制的数据库(多数据库使用逗号,隔开) replicate-ignore-db
设定需要忽略的复制数据库 (多数据库使用逗号,隔开) replicate-do-table 设定需要复制的表
replicate-ignore-table 设定需要忽略的复制表 replicate-wild-do-table
同replication-do-table功能一样,但是可以通配符 replicate-wild-ignore-table
同replication-ignore-table功能一样,但是可以加通配符

[mysqld]
server-id = 2 # server_id是必须的,而且唯一。
log-bin=mysql-bin  
relay-log = mysql-relay-bin
replicate-do-db=oyc
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%

4.2 配置从库连接信息

让slave连接master,并开始重做master二进制日志中的事件。

CHANGE MASTER TO MASTER_HOST='192.168.0.100',MASTER_USER='oyc',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=0;

4.3 启动Salve并查看从库状态

START SLAVE;

SHOW SLAVE STATUS;

看到Slave_IO_Running=Yes Slave_SQL_Running=Yes,说明成功了。

5.测试效果

6.同步错误解决

6.1 忽略错误继续同步

该方法适用于主从库数据相差不大,或者要求数据可以不完全统一的情况,数据要求不严格的情况。

stop slave; 

# 表示跳过一步错误,后面的数字可变
set global sql_slave_skip_counter =1;

start slave;

# 查询同步情况
show slave status\G

6.2 忽略不需要的表

replicate-ignore-table=table1,table2,oyc_%

6.3 重新同步数据再实现同步

1.先进入主库,进行锁表,防止数据写入
使用命令:

mysql> flush tables with read lock;

注意:该处是锁定为只读状态,语句不区分大小写

2.进行数据备份
把数据备份到mysql.bak.sql文件
[aaa@qq.com mysql]#mysqldump -uroot -p -hlocalhost > mysql.bak.sql
这里注意一点:数据库备份一定要定期进行,可以用shell脚本或者python脚本,都比较方便,确保数据万无一失

3.查看master 状态
mysql> show master status;
+——————-+———-+————–+——————————-+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————-+———-+————–+——————————-+
| mysqld-bin.000001 | 3260 | | mysql,test,information_schema |
+——————-+———-+————–+——————————-+
1 row in set (0.00 sec)

4.把mysql备份文件传到从库机器,进行数据恢复

使用scp命令
[aaa@qq.com mysql]# scp mysql.bak.sql aaa@qq.com:/tmp/

5.停止从库的状态
mysql> stop slave;

6.然后到从库执行mysql命令,导入数据备份

mysql> source /tmp/mysql.bak.sql

7.设置从库同步,注意该处的同步点,就是主库show master status信息里的| File| Position两项
change master to master_host = ‘192.168.1.206’, master_user = ‘rsync’, master_port=3306, master_password=”, master_log_file = ‘mysqld-bin.000001’, master_log_pos=3260;

8.重新开启从同步
mysql> start slave;

9.查看同步状态
mysql> show slave status\G 查看同步情况