MySQL Replication (MySQL 主从复制) 是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式(一级主从大概50~100 us),这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。
MySQL横向扩展解决方案
在多个从库之间扩展负载以提高性能。在这种环境中,所有写入和更新在主库上进行。但是,读取可能发生在一个或多个从库上。该读写分离模型可以提高写入的性能(由于主库专用于更新),同时在多个从库上读取,可以大大提高读取速度。
1.2、为什么要做主从复制-
架构的横向扩展:业务量越来越大,I/O访问频率过高,单机无法满足,此时做多库的存储,降低磁盘I/O访问的频率,提高单个机器的I/O性能。
-
读写分离:在业务复杂的系统中,如果在生产环境中,有一句sql语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。
-
做数据的热备,数据安全性:由于主库数据被复制到从库,从库可以暂停复制过程,可以在从库上运行备份服务,而不会破坏对应的主库数据。
-
数据分析:可以在主库上创建实时数据,而信息分析可以在从库上进行,而不会影响主服务器的性能。
MySQL主从复制涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread, SQL thread)运行在从节点
主节点 binary log dump 线程
当从节点连接主节点时,主节点会创建一个log dump 线程,用于发送bin-log的内容。在读取bin-log中的操作时,此线程会对主节点上的bin-log加锁,当读取完成,甚至在发动给从节点之前,锁会被释放。
从节点 I/O 线程
当从节点上执行`start slave`命令之后,从节点会创建一个I/O线程用来连接主节点,请求主库中更新的bin-log。I/O线程接收到主节点binlog dump 进程发来的更新之后,保存在本地relay-log中。
从节点 SQL 线程
SQL线程负责读取relay log中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。
对于每一个主从连接,都需要三个进程来完成。当主节点有多个从节点时,主节点会为每一个当前连接的从节点建一个binary log dump 进程,而每个从节点都有自己的I/O进程,SQL进程。从节点用两个线程将从主库拉取更新和执行分成独立的任务,这样在执行同步数据任务的时候,不会降低读操作的性能。比如,如果从节点没有运行,此时I/O进程可以很快从主节点获取更新,尽管SQL进程还没有执行。如果在SQL进程执行之前从节点服务停止,至少I/O进程已经从主节点拉取到了最新的变更并且保存在本地relay日志中,当服务再次起来之后,就可以完成数据的同步。
要实施复制,首先必须打开Master 端的binary log(bin-log)功能,否则无法实现。
整个复制过程实际上就是Slave 从Master 端获取该日志然后再在自己身上完全顺序的执行日志中所记录的各种操作。如下图所示:
复制的基本过程如下:
从节点上的I/O 进程连接主节点,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;主节点接收到来自从节点的I/O请求后,通过负责复制的I/O进程根据请求信息读取指定日志指定位置之后的日志信息,返回给从节点。返回信息中除了日志所包含的信息之外,还包括本次返回的信息的bin-log file 的以及bin-log position;从节点的I/O进程接收到内容后,将接收到的日志内容更新到本机的relay log中,并将读取到的binary log文件名和位置保存到master-info 文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log 的哪个位置开始往后的日志内容,请发给我”;Slave 的 SQL线程检测到relay-log 中新增加了内容后,会将relay-log的内容解析成在祝节点上实际执行过的操作,并在本数据库中执行。
1.4、MySQL主从同步配置的基本步骤有很多种配置主从同步的方法,可以总结为如下的步骤:
-
在主服务器上,必须开启二进制日志机制和配置一个独立的ID,创建一个用来专门复制主服务器数据的账号
-
在每一个从服务器上,配置一个唯一的ID
-
在开始复制进程前,在主服务器上记录二进制文件的位置信息
-
如果在开始复制之前,数据库中已经有数据,就必须先创建一个数据快照(可以使用mysqldump导出数据库,或者直接复制数据文件),备份主服务器原有数据到从服务器
-
配置从服务器要连接的主服务器的IP地址和登陆授权,二进制日志文件名和位置
二、MySQL主从复制配置 2.1、环境准备工作
Mysql版本:MySQL 5.7.19
Master-Server : 192.168.252.123
Slave-Server : 192.168.252.124
首先在两台机器上装上MySQL,保证正常启动可以使用
MySQL 5.7安装参考:Linux基础3:CentOS7安装配置JDK、Mysql 和Tomcat服务器环境
2.2、Master-Server 配置配置 Master 以使用基于二进制日志文件位置的复制,必须启用二进制日志记录并建立唯一的服务器ID,否则则无法进行主从复制。
(1)修改主服务器配置文件my.cnf,开启binlog ,每台服务器设置不同的 server-id
vim /etc/mysql/my.cnf
编辑mysqld下的配置文件,设置log_bin和server-id
[mysqld] #配置唯一的server-id,不设置MySQL5.7以上会报错 server-id=1 #mysql会根据这个配置自动设置log_bin为on状态,即开启binlog log_bin=master-bin #配置log_bin_index文件为你指定的文件名后跟.index获得master二进制文件名及位置 #log_bin_index=master-bin.index #需要同步的数据库,除此之外,其他不同步 binlog-do-db=test #默认情况下备份是主库的全部操作都会备份到从库,实际可能需要忽略某些库,可以在主库中增加如下配置: # 不同步哪些数据库(多个写多行) #binlog-ignore-db=mysql #binlog-ignore-db=information_schema #binlog-ignore-db=performance_schema #binlog-ignore-db=sys # 只同步哪些数据库,除此之外,其他不同步 #binlog-do-db=mysql #自动清理 7 天前的log文件,可根据需要修改 #expire_logs_days=7
(2)进入数据库,创建用于数据同步的账户(目的,让从服务器来复制数据)
mysql -u root -p mysql> create user repl; mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'从服务器xxx.xxx.xxx.xx' IDENTIFIED BY 'yourPassword'; mysql> flush privileges;
这个配置的含义就是创建了一个数据库用户repl,密码是yourPassword, 在从服务器使用repl这个账号和主服务器连接的时候,就赋予其REPLICATION SLAVE的权限, *.* 表面这个权限是针对主库的所有表的,其中xxx就是从服务器的ip地址。
(3) 重启MySQL让配置文件my.cnf生效,查看主库状态
//重启数据库 systemctl restart mysqld
启动成功之后,查看我们的配置是否起作用
查看主库状态
查看 Master-Server中的binlog File 文件名称和 Position值位置,并且记下来。此时主数据库设置完毕。
2.3、Slave-Server 配置
如果要设置多个从库,则每个从库的server-id与主库和其他从库设置不同的唯一值。
(1)修改配置文件my.conf
[mysqld] #配置唯一的server-id,不设置MySQL5.7以上会报错,不能与主库相同 server-id=2 #保证了主从数据的一致性,不论从机怎么出错都能保证,主从一致。 relay_log_recovery = on relay_log_info_repository = TABLE master_info_repository = TABLE #定义relay_log的位置和名称 #relay-log=slave-relay-bin #同bin-log-index #relay-log-index=slave-relay-bin.index #需要同步的数据库名(多数据库使用逗号,隔开) #replicate-do-db=db_name #设定需要复制的表 #replicate-do-table=table_name #设定需要忽略的复制表 #replicate-ignore-table=table_name
重启数据库使配置生效
systemctl restart mysqld
(2)进入数据库,配置主从库通信
要设置从库与主库进行通信复制,使用必要的连接信息配置从库在从库上执行以下代码
change master to master_host='主xxx.xxx.xxx.xx',master_port=3306,master_user='repl',master_password='yourPassword',master_log_file='master-bin.000002',master_log_pos=6744;
这里面的xxx是主服务器ip,同时配置端口,repl代表访问主数据库的用户上述步骤执行完毕后执行
(3) start slave启动从服务器复制线程
mysql> start slave; Query OK, 0 rows affected (0.00 sec) #关闭同步为stop slave
查看复制状态命令,G表示换行查看
show slave status G;
当两个圆圈中的状态显示为yes时,代表配置成功
检查主从复制通信状态
2.4、测试主从复制Slave_IO_State #从站的当前状态
Slave_IO_Running: Yes #读取主程序二进制日志的I/O线程是否正在运行
Slave_SQL_Running: Yes #执行读取主服务器中二进制日志事件的SQL线程是否正在运行。与I/O线程一样
Seconds_Behind_Master #是否为0,0就是已经同步了
在 Master-Server 创建试库和用户表
CREATE DATAbase `test`; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `user_id` int(11) NOT NULL AUTO_INCREMENT, `account` varchar(45) NOT NULL, `nickname` varchar(18) NOT NULL, `password` varchar(45) NOT NULL, `headimage_url` varchar(45) DEFAULT NULL, `introduce` varchar(45) DEFAULT NULL, PRIMARY KEY (`user_id`), UNIQUE KEY `account_UNIQUE` (`account`), UNIQUE KEY `nickname_UNIQUE` (`nickname`) ) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8;
在 Slave-Server 查看是否同步过来
mysql> show databases; +-------------------------+ | Database | +-------------------------+ | information_schema | | mysql | | performance_schema | | sys | | test | +-------------------------+ mysql> use test; mysql> show tables; +-----------------------------------+ | Tables_in_test | +-----------------------------------+ | user | +-----------------------------------+ 1 row in set (0.00 sec)2.5、MySQL主从复制命令总结
#查看主服务器的运行状态 show master status; #查看从服务器主机列表 show slave hosts; #获取binlog文件列表 show binary logs; #只查看第一个binlog文件的内容 show binlog events; #查看指定binlog文件的内容 show binlog events in 'mysql-bin.000001'; #启动从库复制线程 START SLAVE; #停止从库复制线程 STOP SLAVE;
参考链接:
MySQL主从复制+Springboot读写分离
搭建 MySQL 5.7.19 主从复制,以及复制实现细节分析
【MySQL】保证复制高可用的一些重要参数



