⾯试之MYSQL主从复制(详细)
⼀、什么是主从复制:
主从复制:是⽤来建⽴⼀个和主数据库完全⼀样的数据库环境,称为从数据库;主数据库⼀般是准实时的业务数据库。
⼆、主从复制的作⽤(好处或者说为什么要做主从)
1、做数据的热备,作为后备数据库,主数据库服务器故障后,可切换到从数据库继续⼯作,避免数据丢失。
2、架构的扩展。业务量越来越⼤,I/O访问频率过⾼,单机⽆法满⾜,此时做多库的存储,降低磁盘I/O访问的频率,提⾼单个机器的I/O 性能。
foreach删除元素3、读写分离,使数据库能⽀撑更⼤的并发。在报表中尤其重要。由于部分报表sql语句⾮常的慢,导致锁表,影响前台服务。如果前台使⽤master,报表使⽤slave,那么报表sql将不会造成前台锁,保证了前台速度。
三、主从复制的原理(重中之重,⾯试必问):
1.数据库有个bin-log⼆进制⽂件,记录了所有sql语句。
2.我们的⽬标就是把主数据库的bin-log⽂件的sql语句复制过来。
3.让其在从数据的relay-log重做⽇志⽂件中再执⾏⼀次这些sql语句即可。
4.下⾯的主从配置就是围绕这个原理配置
5.具体需要三个线程来操作:
binlog输出线程。每当有从库连接到主库的时候,主库都会创建⼀个线程然后发送binlog内容到从库。
在从库⾥,当复制开始的时候,从库就会创建两个线程进⾏处理:
从库I/O线程。当START SLAVE语句在从库开始执⾏之后,从库创建⼀个I/O线程,该线程连接到主库并请求主库发送binlog⾥⾯的更新记录到从库上。从库I/O线程读取主库的binlog输出线程发送的更新并拷贝这些更新到本地⽂件,其中包括relay log⽂件。
从库的SQL线程。从库创建⼀个SQL线程,这个线程读取从库I/O线程写到relay log的更新事件并执⾏。
可以知道,对于每⼀个主从复制的连接,都有三个线程。拥有多个从库的主库为每⼀个连接到主库的从库创建⼀个binlog输出线程,每⼀个从库都有它⾃⼰的I/O线程和SQL线程。
或者
分为四步⾛:
1. 主库对所有DDL和DML产⽣的⽇志写进binlog;
2. 主库⽣成⼀个 log dump 线程,⽤来给从库I/O线程读取binlog;
3. 从库的I/O Thread去请求主库的binlog,并将得到的binlog⽇志写到relay log⽂件中;
4. 从库的SQL Thread会读取relay log⽂件中的⽇志解析成具体操作,将主库的DDL和DML操作事件重放。
关于DDL和DML
SQL语⾔共分为以下⼏⼤类:查询语⾔DQL,控制语⾔DCL,操纵语⾔DML,定义语⾔DDL。事务控制TCL.
DQL(Data QUERY
Languages)语句:即数据库定义语句,⽤来查询SELECT⼦句,FROM⼦句,WHERE⼦句组成的查询块,⽐如:select–from–where–grouop
by–having–order by–limit
DDL(Data Definition
Languages)语句:即数据库定义语句,⽤来创建数据库中的表、索引、视图、存储过程、触发器等,常⽤的语句关键字有:CREATE,ALTER,DROP,TRUNCATE,COMMENT,RENAME。增删改表的结构
DML(Data Manipulation
Language)语句:即数据操纵语句,⽤来查询、添加、更新、删除等,常⽤的语句关键字有:
SELECT,INSERT,UPDATE,DELETE,MERGE,CALL,EXPLAIN
PLAN,LOCK TABLE,包括通⽤性的增删改查。增删改表的数据
DCL(Data Control Language)语句:即数据控制语句,⽤于授权/撤销数据库及其字段的权限(DCL is short
name of Data Control Language which includes commands such as GRANT
and mostly concerned with rights, permissions and other controls of
the database system.)。常⽤的语句关键字有:GRANT,REVOKE。
TCL(Transaction Control
Language)语句:事务控制语句,⽤于控制事务,常⽤的语句关键字有:COMMIT,ROLLBACK,SAVEPOINT,SET TRANSACTION。
电脑杀进程快捷键>表格下拉框选项怎么设置主从复制如图:
原理图
四、其实主从复制也存在⼀些问题:
1. 负载均衡,由于复制的时间差,不能保证同步读,⽽且写仍然单点,没法多点写,我对这个理解就是半吊⼦的读写均衡。
2. 容灾,基本都是有损容灾,因为数据不同步,谁⽤谁知道,半吊⼦的容灾。
可能只是提供⼀种成本较低的数据备份⽅案加不完美的容灾和负载均衡吧,这种⽅案注定是⼀种过渡⽅案,个⼈认为必须更新了。当然,在不是体量巨⼤的情况下,还是不失为⼀个优化的解决办法。
五、⾯试题分析(如果问到数据库主从问题,必问以下问题)
1、主从的好处是?
2、主从的原理是?
3、从数据库的读的延迟问题了解吗?如何解决?
原因:当主库的TPS并发较⾼时,产⽣的DDL数量超过slave⼀个sql线程所能承受的范围,那么延时就产⽣了,当然还有就是可能与slave 的⼤型query语句产⽣了锁等待,还有⽹络延迟。
(谈到MySQL数据库主从同步延迟原理,得从mysql的数据库主从复制原理说起,mysql的主从复制都是单线程的操作,主库对所有DDL 和DML产⽣binlog,binlog是顺序写,所以效率很⾼;slave的Slave_IO_Running线程会到主库取⽇志,效率会⽐较⾼,slave的
Slave_SQL_Running线程将主库的DDL和DML操作都在slave实施。**DML和DDL的IO操作是随机的,不是顺序的,**因此成本会很⾼,还可能是slave上的其他查询产⽣lock争⽤,由于Slave_SQL_R
unning也是单线程的,所以⼀个DDL卡主了,需要执⾏10分钟,那么所有之后的DDL会等待这个DDL执⾏完才会继续执⾏,这就导致了延时。有朋友会问:“主库上那个相同的DDL也需要执⾏10分,为什么slave 会延时?”,答案是master可以并发,Slave_SQL_Running线程却不可以。)
常见原因:Master负载过⾼、Slave负载过⾼、⽹络延迟、机器性能太低、MySQL配置不合理。
解决⽅法⼀ :最简单的减少slave同步延时的⽅案就是在架构上做优化,尽量让主库的DDL快速执⾏。还有就是主库是写,对数据安全性较⾼,⽐如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之类的设置,⽽slave则不需要这么⾼的数据安全,完全可以讲
sync_binlog设置为0或者关闭binlog,innodb_flushlog也可以设置为0来提⾼sql的执⾏效率。另外就是使⽤⽐主库更好的硬件设备作为slave。
对于上⾯MYSQL参数 sync_binlog=1 说明:
MySQL提供⼀个sync_binlog参数来控制数据库的binlog刷到磁盘上去。
----默认,sync_binlog=0,表⽰MySQL不控制binlog的刷新,由⽂件系统⾃⼰控制它的缓存的刷新。这时候的性能是最好的,但是风险也是最⼤的。因为⼀旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。
mysql是什么系统
----如果sync_binlog>0,表⽰每sync_binlog次事务提交,MySQL调⽤⽂件系统的刷新操作将缓存刷下去。最安全的就是
sync_binlog=1了,表⽰每次事务提交,MySQL都会把binlog刷下去,是最安全但是性能损耗最⼤的设置。这样的话,在数据库所在的主机操作系统损坏或者突然掉电的情况下,系统才有可能丢失1个事务的数据。但是binlog虽然是顺序IO,
----但是设置sync_binlog=1,多个事务同时提交,同样很⼤的影响MySQL和IO性能。虽然可以通过group commit的补丁缓解,但是刷新的频率过⾼对IO的影响也⾮常⼤。对于⾼并发事务的系统来说,“sync_binlog”设置为0和设置为1的系统写⼊性能差距可能⾼达5倍甚⾄更多。
----所以很多MySQL DBA设置的sync_binlog并不是最安全的1,⽽是100(注:每写N次操作系统缓冲就执⾏⼀次刷新操作)或者是0。
这样牺牲⼀定的⼀致性,可以获得更⾼的并发和性能。
对于上⾯MYSQL参数 innodb_flush_log_at_trx_commit = 1说明:
-----提交事务的时候将 redo ⽇志写⼊磁盘中,所谓的 redo ⽇志,就是记录下来你对数据做了什么修改,⽐如对 “id=10 这⾏记录修改了 name 字段的值为 xxx”,这就是⼀个⽇志。如果我们想要提交⼀个
事务了,此时就会根据⼀定的策略把 redo ⽇志从 redo log buffer ⾥刷⼊到磁盘⽂件⾥去。此时这个策略是通过 innodb_flush_log_at_trx_commit 来配置的,他有⼏个选项。
-----值为0 : 提交事务的时候,不⽴即把 redo log buffer ⾥的数据刷⼊磁盘⽂件的,⽽是依靠 InnoDB 的主线程每秒执⾏⼀次刷新到磁盘。此时可能你提交事务了,结果 mysql 宕机了,然后此时内存⾥的数据全部丢失。
-----值为1 : 提交事务的时候,就必须把 redo log 从内存刷⼊到磁盘⽂件⾥去,只要事务提交成功,那么 redo log 就必然在磁盘⾥了。注意,因为操作系统的“延迟写”特性,此时的刷⼊只是写到了操作系统的缓冲区中,因此执⾏同步操作才能保证⼀定持久化到了硬盘中。
-----值为2 : 提交事务的时候,把 redo ⽇志写⼊磁盘⽂件对应的 os cache 缓存⾥去,⽽不是直接进⼊磁盘⽂件,可能 1 秒后才会把os cache ⾥的数据写⼊到磁盘⽂件⾥去。
-----可以看到,只有1才能真正地保证事务的持久性,但是由于刷新操作 fsync() 是阻塞的,直到完成后才返回,我们知道写磁盘的速度是很慢的,因此 MySQL 的性能会明显地下降。如果不在乎事务丢失,0和2能获得更⾼的性能。
解决⽅法⼆ :数据放⼊缓存中,更新数据库后,在预期可能马上⽤到的情况下,主动刷新缓存->(Redis的⾓度)
解决办法三:对于⽐较重要且必须实时的数据,⽐如⽤户刚换密码(密码写⼊ Master),然后⽤新密码登录(从 Slaves 读取密码),会造成密码不⼀致,导致⽤户短时间内登录出错。所以在这种需要读取实时数据的时候最好从 Master 直接读取,避免 Slaves 数据滞后现象发⽣。
4、做主从后主服务器挂了怎么办?
⼀、Mysql主库宕机情况分类:
1)硬件问题,(服务器、ecs、虚拟主机等等)宕机
2)service问题,Mysql宕机,服务异常,端⼝异常等批处理文件脚本
⼆、硬件问题处理思路
硬件问题我们可以查看IDC巡检记录,或通过远程控制卡查看硬件运⾏状态,根据事实情况就⾏硬件故障报修进⾏处理,恢复业务步骤:查看报警信息,确认业务是否收到影响,必要时切从库进⾏数据交互
IDC询问排查
确认硬件故障,短时间⽆法修复开Case处理
通知部门领导,处理进度,并实时记录
事件处理完成后,拟写故障报告,会议通报。
spring boot mybatis elipce三、MySQL service问题处理思路
1)⾸先要做的就是判断是否影响业务,是否需要切库,保证业务运⾏时⾸要任务
2)如果此时需要切从库,按照如下步骤进⾏:
1> 先查看MySQL 从库状态
show processlistG
##如果看到两个状态,说明此时的从库和主库是同步的 =====[如果不同步,建议考出binlog进⾏同步]
#state: waiting for master to send event I/O线程
#state:has read all relay log;waiting for the slave I/O thread to update it sql线程
2> 登录从库分别查看:【多个从库 哪个替代主库呢??】
cat /data/3306/data/master.info
cat /data/3307/data/master.info
##看哪个从库的哪个master.info哪个更新,就说明哪个从库⼀致性更⾼,所以此时就确定最新的库为主库。
选个pos最⼤的作为主库

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。