目录
1、简介
2、为什么要做主从复制
3、MySQL主从复制的原理是什么
3.1 MySQL主从复制架构
3.1.1 一主多从架构
3.1.2 多主多从架构
3.2 MySQL主从复制的图解与执行流程
3.3 MySQL主从复制的基本原则
4、MySQL主从复制的方式
5、MySQL主从复制的最大问题:主从延时
6、MySQL主从复制的实战
6.1 一主三从架构图
6.2 环境说明(本文搭建一主一从架构)
6.3 实现MySQL主从复制需要进行的配置
7、开始搭建主从复制
7.1 分别在两台centos7系统上安装mysql 5.7(Windows系统)
7.2 master主服务器的配置
7.2.1 在master中,配置文件my.cnf
7.2.2 在master中,创建从服务器的用户和权限
7.2.3 在master中,重启MySQL服务器
7.2.4 在master中,查看主服务器状态
7.3 slave从服务器的配置
7.3.1 在slave中,配置文件my.cnf
7.3.2 在slave中,重启MySQL服务
7.3.3 在slave中,连接master主服务器
7.3.4 在slave中,启动slave数据同步
7.3.5 在slave中,查看slave信息
7.4 MySQL主从复制的测试
7.5 常用语句
7.6 解决错误
7.7 总结
8、读写分离实战-待更新
99、参考
随着互联网技术的发展,在实际的生产环境中,由单台MySQL数据库服务器已经逐渐不能满足实际的需求。此时,数据库集群就很好的解决了这个问题。采用MySQL分布式集群,能够搭建一个高并发、负载均衡的集群服务器。在此之前,我们必须要保证每台MySQL服务器里的数据同步。数据同步,我们可以通过MySQL内部配置就可以轻松完成,主要有【主从复制和主主复制】。
MySQL数据库本身提供的主从复制功能,可以方便的实现数据的多处自动备份,从而实现数据库的拓展。多个数据备份,不仅可以加强数据的安全性;通过实现读写分离还可以进一步提升数据库的负载能力,从而分担主数据库的压力。
下图就描述了一个在多个数据库之间进行主从复制与读写分离的物理模型:
在【一主多从】的数据库架构体系中,多个从服务器采用异步方式感知主数据库的变化。
业务服务器在执行写或者修改数据库的操作 都是在主服务器上进行的;读数据库的操作 则是在各个从服务器上进行的(主服务器也可以提供读能力)。
主从复制可以实现【对数据库进行备份】和实现【读写分离】:
(1)对数据库进行备份:为了避免服务的不可用,以及保障数据的安全可靠性,我们至少需要部署两台或者两台以上的服务器来存储数据库数据。也就是说,我们需要将数据复制多份 部署在多台不同的服务器上,即使有一台服务器出现故障了,其他服务器依然可以继续提供服务。
(2)读写分离:MySQL自身提供了主从复制功能。主从复制,是指服务器分为主服务器和从服务器,主服务器负责读和写,从服务器只负责读,从而分担主服务器的压力。
根据上图,分析一下MySQL主从复制原理(从库=slave节点,主库=master节点,binlog文件=记录SQL操作的二进制文件):
=====================主从复制的另一个文本解释=============================
(1)从库不断的试探主库的binlog文件。如果该binlog文件有更新,则从库会启动IO线程,并发送请求到主库中 以获取主库binlog文件的内容。
(2)向主库中写数据,包括 新增、删除、修改、建库建表 等写操作,主库都会将 “写操作对应的SQL命令” 记录到主库binlog文件中,并更新binlog文件的偏移量。
(3)如果从库试探到主库binlog文件的偏移量和自己本地记录的偏移量不一致,则表示主库中有数据更新,那么,从库将启动IO线程向主库请求从某个偏移量开始的、到binlog文件结束位置 之间的所有数据,这个数据其实就是一批SQL命令数据。
(4)主库将根据从库请求的偏移量来推送命令数据到从库中,从库接收到命令数据之后,会更新从库中之前所记录的偏移量位置,并且,将这些命令数据写入到自己的中继日志文件中,然后,唤醒SQL线程,同时让当前的IO线程挂起,进入休眠等待。
(5)从库的SQL线程将根据偏移量来读取中继日志文件中的命令数据。从库的SQL线程拿到命令数据之后,在从库中进行回放,也即 在从库中执行一遍主库的SQL命令,回放结束之后,将当前的SQL线程挂起,进入休眠等待。以此循环往复。
MySQL主从复制,主要有以下3种方式:
本文说的是在 centos 7 系统上,实现的 MySQL5.7 数据库的主从复制。
MySQL主从复制的最大问题就是 主从延时。
(1)通过MySQL主从复制的实现原理可以知道:MySQL的主从复制,可以保证master主服务器和slave从服务器上的数据库数据一致,但是,在时间上肯定是有延迟的,即 slave从服务器上的数据是滞后的。
(2)为什么会出现这样的问题?主要是因为 master主服务器上的数据库操作可以并发执行,但是,slave从服务器只能从 中继日志 relay log 中一条一条的读取、回放。
(3)如果master主服务器上的写操作很频繁,slave从服务器就很可能就跟不上了,于是就出现了主从延时。
主从延时的原理和解决方案,可以参见这些博客:
https://www.cnblogs.com/cnmenglang/p/6393769.html、如何实现主从复制、如何解决主从延时问题?、MySQL主从延时解决方案
(1)master主服务器:
(2)slave从服务器:
具体的安装步骤可以参考:https://blog.csdn.net/qq_15092079/article/details/81629238
(1)本文中的两台服务器的IP地址分别为:主服务器(192.168.17.130),从服务器(192.168.17.132)。
(2)分别在这两个服务器上创建test数据库,以备后面测试。
找到主库
的配置文件 my.cnf( 或者 my.ini ),我的在 /etc/my.cnf,在 [mysqld] 部分插入如下:Bin-log配置选项参数详解
[mysqld]
server-id=3307
log_bin=master-bin
binlog_do_db=test
#备注:
#编辑my.cnf文件
[root@localhost mysql]# vim /etc/my.cnf
#server-id:设置服务器的唯一标识
#log_bin:启动MySQL二进制日志,即数据同步语句,从数据库会一条一条的执行这些语句。
#binlog_do_db:指定记录二进制日志的数据库,即需要复制的数据库名,如果复制多个数据库,重复设置这个选项即可。
#binlog_ignore_db:指定不记录二进制日志的数据库,即不需要复制的数据库名,如果有多个数据库,重复设置这个选项即可。
#其中需要注意的是,binlog_do_db和binlog_ignore_db为互斥选项,一般只需要一个即可。
#进入mysql数据库
[root@localhost mysql]# mysql -u root -p
Enter password:
#创建从数据库的masterbackup用户和权限
mysql> grant replication slave on *.* to masterbackup@'192.168.17.%' identified by '123456';
#刷新权限
mysql> flush privileges;
#退出mysql
mysql> exit;
#备注:
#192.168.17.%通配符:表示0-255的IP都可访问主服务器,正式环境请配置指定从服务器IP
#若将 192.168.17.% 改为 %:则任何ip均可作为其从数据库来访问主服务器
[root@localhost mysql]# service mysql restart
Shutting down MySQL.... SUCCESS!
Starting MySQL. SUCCESS!
#进入mysql数据库
[root@localhost mysql]# mysql -u root -p
Enter password:
#查看主服务器状态
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 154 | test | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
(1)记录上图结果中 File 和 Position 的值。(2)注意:
执行完此步骤后,不要再操作主服务器,防止主服务器的状态值变化。
#编辑my.cnf文件
[root@localhost mysql]# vim /etc/my.cnf
#在[mysqld]中添加:
[mysqld]
server-id=3308
relay-log=slave-relay-bin
#replicate-do-db=test
#备注:
#server-id:服务器唯一标识,如果有多个从服务器,每个服务器的server-id都不能重复,跟IP一样是唯一标识,如果你没设置server-id或者设置为0,则从服务器不会连接到主服务器。
#relay-log:启动MySQL二进制日志,可以用来做数据备份和崩溃恢复;或主服务器挂掉了,将此从服务器作为其他从服务器的主服务器。
#replicate-do-db:指定同步的数据库,如果复制多个数据库,重复设置这个选项即可。若在master端不指定binlog-do-db,则在slave端可用replication-do-db来过滤。
#replicate-ignore-db:不需要同步的数据库,如果有多个数据库,重复设置这个选项即可。
#其中需要注意的是,replicate-do-db和replicate-ignore-db为互斥选项,一般只需要一个即可。
[root@localhost mysql]# service mysql restart
Shutting down MySQL.... SUCCESS!
Starting MySQL. SUCCESS!
#进入mysql数据库
[root@localhost mysql]# mysql -u root -p
Enter password:
#连接master主服务器
mysql> change master to master_host='192.168.17.130',master_port=3306,master_user='masterbackup',master_password='123456',master_log_file='master-bin.000001',master_log_pos=154;
#备注:
#master_host:对应主服务器的IP地址。
#master_port:对应主服务器的端口。
#master_log_file:对应show master status显示的 File列:master-bin.000001。
#master_log_pos:对应show master status显示的 Position列:154。
#启动slave数据同步
mysql> start slave;
#停止slave数据同步(若有需要)
mysql> stop slave;
mysql> show slave status\G;
只有当看到 Slave_IO_State: Waiting for master ot send event 、Slave_IO_Running: YES、Slave_SQL_Running: YES 才表明MySQL的主从复制架构搭建正常!
(1)在master主服务器上登陆MySQL,且进入test数据库、创建tb_test表、且插入一条数据:提示:这里最好用数据库管理工具(如nacicat、sequel pro)来操作。
#显示所有的数据库
show databases;
#使用之前创建好的test数据库
use test;
#创建tb_test表
create table tb_test(ID varchar(36) primary key comment '主键ID', MEMO varchar(500) not null comment '信息');
#插入一条数据
insert into tb_test(ID,MEMO) values('1','one test');
#提交
commit;
(2)在slave从服务器上登陆MySQL,且进入test数据库,你会发现从数据库中,也出现了tb_test表,且表中还有 one test 数据存在,证明数据同步成功:
至此,一主一从的MySQL主从复制架构就实现了。
-- 查看master的状态,尤其是当前的日志及位置
show master status;
-- 查看slave的状态
show slave status;
-- 暂停master
stop master;
-- 暂停slave,相当于终止从服务器的IO线程和SQL线程
stop slave;
-- 重置slave状态
reset slave;
-- 启动master和slave
start master;
start slave;
-- 在主服务器的客户端上查看主从复制的binlog日志文件内容:
show binlog events in 'mysql-bin.0000001'\G
若在MySQL主从复制的过程中,出现其中一条语句同步失败了,则后面的语句也肯定不能够同步成功了。
例如:主库有一条数据,而从库并没有这一条数据,然而,在主库执行了删除这一条数据的操作,那么,从库没有这一条数据就肯定删除不了,从而报错了。在此时,从数据库的数据同步就失败了,因此,后面的同步语句就无法继续执行。这里提供有两种解决方法:
(1)在slave从数据库中,使用 SET 全局 sql_slave_skip_counter 来跳过事件,跳过这一个错误,然后执行从下一个事件组开始:
#在从数据库上操作
mysql > stop slave;
mysql > set global sql_slave_skip_counter=1;
mysql > start slave;
(2)在slave从数据库中,重新连上master主数据库。这种操作会直接跳过中间的那些同步语句,可能会导致一些数据未同步过去的问题,但这种操作也是最后的绝招。最好就是 令slave从数据库与master主数据库的数据结构和数据都一致了之后,再来恢复主从复制的操作:
#在从数据库上操作
mysql > stop slave;
mysql> change master to master_host='192.168.17.130',master_port=3306,master_user='masterbackup',master_password='123456',master_log_file='master-bin.000001',master_log_pos=2050;
mysql > start slave;
#备注
#master_log_file和master_log_pos可能会不同,需要在主数据库中 show master status 来查看。
至此,MySQL数据库的【一主一从架构】主从复制功能就完成了。至于读写分离,我们可以通过程序来实现,这里简单讲解一下实现思想。
可以在master主服务器上创建一个数据库用户(出于安全,根据需求给予相应的权限)主要用于写操作,在程序中通过这一用户连接主数据库,只用于写操作。
在slave从服务器上创建一个数据库用户(出于安全,只给予读select的权限)主要用于读操作,在程序中通过这一用户连接从数据库, 只用于读操作。
当然,也可以找一个组件来完成MySQL的代理,实现SQL语句的路由,这样就不需要我们在程序上关注哪个数据库是写、哪个数据库是读的了。比如下面的第8节。
8.1 读写分离的实现方式
8.2 使用Mycat实现读写分离
8.3 使用ShardingSphere实现读写分离
(1)https://blog.csdn.net/cmm0401/article/details/107303433
(2)https://blog.csdn.net/weixin_51616026/article/details/114000971
(3)https://blog.csdn.net/mocas_wang/article/details/111593382
(4)https://blog.csdn.net/why15732625998/article/details/80463041
(5)https://www.cnblogs.com/cnmenglang/p/6393769.html
(6)如何实现 MySQL 的读写分离?如何解决 MySQL 主从同步的延时问题:https://zhuanlan.zhihu.com/p/60455737
(7)MySQL主从复制实现:https://blog.csdn.net/qq_15092079/article/details/81672920