一、什么是主从复制:
通过将MySQL的某一台主机(master)的数据复制到其他主机(slaves)上。从主机根据主(master)的二进制文件在本机上执行sql实现数据复制。
意义or作用:
解决单点故障服务不可用 ---如果主节点出现故障,那么我们就直接将服务切到从节点,来保证服务立马可用。
处理大量的并发数据请求 ---如果并发请求特别大的时候,我们可用进行读写分离操作,让主库负责写,从库负责读。
以防数据丢失 ---如果主库数据丢失,但从库还保存一份,减少数据丢失的风险。
主从复制的原理:
主服务器(master):启用二进制日志,将发生在服务器上的所有数据更改操作(包括插入、更新和删除)记录到二进制文件当中。
从服务器(slave):根据手动配置的信息连接到指定的masetr,同时开启I/O线程与master的dump线程建立连接;slave根据提供的二进制文件名和位置号进行二进制日志(binlog)请求。
主服务器:主节点根据slave的请求,通过dump线程将本地的binlog以events方式发送给slave的I/O线程。
从服务器:接收到master发送的binlog,将其存放到中继日志(relay log)中(发送的记录在master.info文件中)。最后slave启动SQL线程从relay log中读取数据并执行写入到本地库中(应用过的信息记录在relay-log.info文件中)。
master二进制日志继续记录新的数据操作,并将其传输给salve进行处理。从服务器周期性地向主服务器汇报复制的进度,以确保与主服务器的同步状态
二、主从复制的进阶用法:
1、延时同步:
当主库发生意外故障时,从库因为延时利用时间差保护了数据;就可以将延时从库作为主库或用来恢复数据(延时:3-6h)
实现手段:
mysql>CHANGE MASTER TO MASTER_DELAY = 300; ---单位秒(s)
延时应用于故障恢复思路:
设置好延时x后;
在x时间内检测到主库误删操作;
丛库停止SQL线程;
截取relay log :起点--停止sql线程时relay最后的应用位置;终点--误删之前的position(GID)
恢复截取的日志到从库;
从库身份解除,代替主库进行工作。
2、过滤复制:
两种方式:1、配置主库的dump线程,master只发送需要同步的db二进制。2、配置从库sql线程,slave只加载需要同步的db二进制文件。
3、GTID复制:
GTID用于在binlog中唯一标识一个事务。当事务提交时,MySQL Server在写binlog的时候,会先写一个特殊的Binlog Event,类型为GTID_Event,指定下一个事务的GTID,然后再写事务的Binlog。
主从同步时GTID_Event和事务的Binlog 都会传递到从库,从库在执行的时候也是用同样的GTID写binlog,这样主从同步以后,就可通过GTID确定从库同步到的位置了。也就是说,无论是级联情况,还是一主多从情况,都可以通过GTID自动找点儿,而无需通过File_name和File_position找点。
实现逻辑:
master更新数据时,会在事务前产生GTID,一同记录到binlog日志中。
slave端的i/o 线程会将变更的binlog,写入到本地的relay log中。
sql线程从relay log中获取GTID,然后对比slave端的binlog是否有记录。
如果有记录,说明该GTID的事务已经执行,slave会忽略。
如果没有记录,slave就会从relay log中执行该GTID的事务,并记录到binlog。
配置文件主要参数:
gtid-mode=on --启用gtid类型,否则就是普通的复制架构
enforce-gtid-consistency=true --强制GTID的一致性
log-slave-updates=1 --slave更新是否记入日志
主库:
show master status;
Binlog_Do_DB # 该参数用来指定需要同步的db
Binlog_Ignore_DB # 该参数用来指定不需要同步的db
从库:
show slave status\G
Replicate_Do_DB: # 指定的回放db
Replicate_Ignore_DB: # 指定不回放的db
Replicate_Do_Table: # 指定回放的表
Replicate_Ignore_Table: # 指定不回放的表
Replicate_Wild_Do_Table: # 模糊指定回放的表
Replicate_Wild_Ignore_Table: # 模糊指定不回放的表
三、MySQL主从复制同步方式
1、异步复制
MySQL主从同步 默认是异步复制的。只有也就是Mater写入bin log日志是同步的(就是主库写入binlog日志后即可成功返回客户端,无须等待binlog)。
日志传递给从库的过程。Master 不关心 Slave 的数据有没有写入成功。因此如果Master和Slave之间有网络延迟,就会造成暂时的数据不一致的现象;如果Master出故障,而数据还没有复制过去,则会造成数据丢失;但也有好处,效率较其他两种复制方式最高。
2、同步复制
对于同步复制而言,Master主机将事件发送给Slave主机后会触发一个等待,直到所有Slave节点(如果有多个Slave)返回数据复制成功的信息给Master。这种复制方式最安全,但是同时,效率也是最差的。
3、半同步复制
对于半同步复制而言,Master主机将事件发送给Slave主机后会触发一个等待,直到其中一个Slave节点(如果有多个Slave)返回数据复制成功的信息给Master。由此增强了数据的一致性,但是因为Master主机的确认开销,会损耗一部分的性能。
另外,半同步复制除了不需要等待所有Slave主机确认事件的接收外,半同步数据复制并不要求那些事件完全地执行,因此,仍有可能看到在Slave主机上数据复制延迟的发生,如果因为网络延迟等原因造成Slave迟迟没有返回复制成功的信息,超过了Master设置的超时时长,半同步复制就降级为异步复制方式,而后继续数据复制。
2.完成MySQL主从复制。
2.1环境准备
两台机器,一主一从。
主(master):192.168.136.134 port:3306
从(slave):192.168.136.135 port:3306
2.2主库配置
设置server-id值并开启binlog参数
[mysqld]
log_bin = mysql-bin
server_id = 120
设置完成并保存后记得重启服务
systemctl restart mysqld
建立同步账号
grant replication slave on *.* to 'slave_test'@'192.168.136.%' identified by '123456';
grant replication slave: 授予复制从服务器权限
on *.*: 应用于所有数据库
to ‘slave_test’@‘192.168.136.%’: 授权给用户名为’slave_test’,只能从IP地址为192.168.136.开头的主机访问
identified by ‘123456’: 设置用户的密码为’123456’
注:这里的密码为简易密码,需要更改密码策略否则会报错,可以使用上一步骤中的validate_password=off关闭密码策略(同样地方修改)。
mysql> show grants for 'slave_test'@'192.168.136.%'; 查看用户的授权信息。
锁表设置只读
为后面备份准备,注意生产环境要提前申请停机时间;
mysql> flush tables with read lock;
#提示:如果超过设置时间不操作会自动解锁。
mysql> show variables like '%timeout%';
FLUSH TABLES WITH READ LOCK; 是一个MySQL语句,它的作用是在当前会话中锁定所有表,并使它们处于只读状态。这个命令常用于备份数据库或进行一些需要确保数据一致性的操作。
当执行这个命令时,MySQL将锁定所有的表,防止其他会话对这些表进行写入操作,从而保证了数据的一致性。只有在当前会话释放这些表的锁之后,其他会话才能对这些表进行写入操作。
需要注意的是,执行FLUSH TABLES WITH READ LOCK;之后,如果需要对表进行任何修改操作,都需要先执行UNLOCK TABLES;来释放表的锁定状态。这样其他会话才能对表进行写入操作。
SHOW VARIABLES LIKE ‘%timeout%’; 是一个MySQL查询语句,用于查看与超时相关的变量配置。执行该语句后,MySQL将返回所有包含"timeout"关键字的系统变量和它们的值。
查看主库状态
查看主库状态,即当前日志文件名和二进制日志偏移量
show master status;
备份数据库数据
mysqldump -uroot -p -A -B | gzip > /backup/mysql_bak.$(date +%F).sql.gz
mysqldump: 是一个MySQL提供的工具,用于导出数据库结构和数据。
-uroot: 指定了MySQL的用户名为"root",用于授权访问数据库。
-p: 告诉mysqldump以交互方式提示输入密码。
-A: 表示导出所有数据库。
-B: 表示导出全部表结构和数据。
|: 管道操作符,将前一个命令的输出作为后一个命令的输入。
gzip: 使用gzip工具对数据进行压缩。
> : 重定向操作符,将输出结果保存到指定的文件中。
/backup/mysql_bak.$(date +%F).sql.gz: 指定了备份文件的路径和名称,其中使用了date命令的参数+%F表示当前日期的完整格式(例如:2023-07-25),以保证每次备份都有唯一的文件名。
mysql> unlock tables;
主库备份数据上传到从库
scp /backup/mysql_bak.2023-07-17.sql.gz 192.168.136.135:/backups/
scp: 是一个用于在不同主机之间安全地进行文件传输的命令。
/backup/mysql_bak.2023-07-17.sql.gz: 是本地的要传输的文件路径和名称。
192.168.136.135: 是远程服务器的IP地址或主机名。
:/backups/: 是远程服务器上接收文件的目录路径。
2.3从库上设置
设置server-id值并关闭binlog参数
[mysqld]
server-id=130
还原从主库备份数据
cd /server/backup/
gzip -d mysql_bak.2015-11-18.sql.gz
mysql -uroot -p < mysql_bak.2015-11-18.sql
#检查还原:
mysql -uroot -p -e 'show databases;'
主库的数据库如下:
从库的数据库:
设定从主库同步
mysql> change master to
MASTER_HOST='192.168.136.134',
MASTER_PORT=3306,
MASTER_USER='slave_test',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=455;
启动从库同步开关
mysql> start slave;
# 检查状态:
mysql> show slave status\G