MySQL面经知识整理
一、查询相关
1.什么是MySQL的连接查询,左连接,右连接,内外连接
-
内连接(INNER JOIN):
返回两张表中联结字段匹配的行。
-
左连接(LEFT JOIN):
返回左表所有的行,即使右表中没有匹配的行。
-
右连接(RIGHT JOIN):
返回右表所有的行,即使左表中没有匹配的行。
-
全外连接(FULL OUTER JOIN):
返回两张表中的所有行,左右表没有匹配的行时,结果为NULL。
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
SELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.id
SELECT * FROM table1 FULL OUTER JOIN table2 ON table1.id = table2.id
2.SQL慢查询优化的方法
- 查看慢查询日志,找到执行时间超长的SQL。
- 加索引,特别是加上经常用于查询条件、排序、分组、连接的字段索引。
- 调优SQL,简化复杂查询,避免全表扫描和不必要的排序、临时表。
- 修改查询方式,例如 EXISTS 代替 IN, UNION ALL 代替 UNION。
- 对大表数据进行拆分,减少单表数据量,可提高查询效率。
- 缓存频繁查询的数据,利用缓存降低数据库访问。
- 配置数据库参数,适当增加配置以提高效率。
- 升级数据库服务器硬件配置,使用SSD、增加CPU和内存。
- 对于大数据量的报表查询,建议使用数据仓库,并适当拆分数据。
- 避免在高峰期运行大查询,选择在低峰时段运行。
3.大表查询如何优化
对于MySQL中大表的查询优化,可以从以下几个方面进行:
- 加索引,特别是联合索引,减少扫描行数。
- 对查询进行优化,使用条件筛选,避免全表扫描,在索引列上进行计算。
- 优化关联查询,使被关联的表大小尽可能小。
- 对大表进行拆分,拆分为多个小表,避免单表数据过大。
- 采用分页查询,避免一次性取出过多数据。
- 缓存热点数据到Redis等缓存系统。
- 对于分析类的大查询,建议使用数据仓库进行查询。
- 配置MySQL参数,适当调高缓存大小,调低磁盘IO影响。
- 使用explain查看执行计划,根据结果进一步优化查询。
- 在业务层面进行优化,比如异步化查询,合理控制查询频率等。
综合运用以上手段可以大幅优化MySQL大表查询。
二、索引相关
1.在MySQL中,可以通过哪些命令来查看查询是否使用了索引
- EXPLAIN:使用EXPLAIN或者EXPLAIN EXTENDED前置于查询语句,可以分析查询执行计划,从中可以看到是否使用了索引。
- SHOW INDEXES:显示表的索引信息,可以查看表上索引的详细情况。
- SHOW STATUS:包含Index_searches值,表示执行索引查找的次数,可以和Questions值作对比。
- SHOW PROFILE:显示执行每个查询阶段的时间,可以看到索引查询的时间。
- USE INDEX:SQL提示,强制查询使用索引。
2.MySQL的最左匹配原则
MySQL中的最左匹配原则(Leftmost Prefix Principle)指的是:
当查询条件使用了联合索引的最左前缀列作为条件时,索引才能被查询使用。
例如存在索引 (col1, col2, col3):
- WHERE col1 = ‘value’ 可以使用索引
- WHERE col1 = ‘value’ AND col2 = ‘value2’ 可以使用索引
- WHERE col2 = ‘value2’ 无法使用索引 (未使用最左列)
最左匹配原则的原因是MySQL索引结构是B+树,B+树叶子节点存储数据指针。
对索引的搜索都从树根开始,逐级搜索直至叶子节点,叶子节点数据顺序与索引顺序一致。
所以最左列确定后,叶子节点范围也确定,可以高效查找,否则无法利用已排序的叶子节点。
这决定了MySQL的索引需要按最频繁作为条件的列作为最左前缀列,以满足最左匹配原则,使索引生效。
3.MySQL什么情况下会索引失效
在MySQL中,索引可能会出现失效的情况,常见的原因包括:
- 索引列参与计算,计算结果无法使用索引。
- 查询使用索引列的别名,导致索引不可用。
- LIKE语句的通配符出现在查询条件的最前面。
- 字符串类型的索引列查询使用不等于非法值时。
- 查询条件是一个范围,但范围条件不是索引列的前缀。
- 复合索引的查询没有按照索引顺序使用索引列。
- 使用OR条件,使得索引无法评估。
- 数据类型转换导致索引不能使用,如字符串转数值。
- 返回结果来自多个表的联合查询。
- 使用了MySQL函数,索引失效。
- 某些MySQL优化策略选择了全表扫描。
4.索引的优缺点
优点:
- 加速查询,直接找到目标记录,减少IO操作。
- 通过索引进行排序,避免使用文件排序。
- 使用索引条件过滤获取更少记录,减少读取记录数。
- 加速表和表之间的连接,使用索引列进行关联。
- 在存储引擎层面,索引可保持数据的有序性。
缺点:
- 建立和维护索引需要额外存储空间。
- 索引会增加写操作开销,需要更新索引。
- 过多索引会造成查询优化器无法选择最优查询计划。
- 一些情况索引会失效,需要注意索引使用场景。
- 索引维护需要碎片整理,会产生额外开销。
5.什么情况下需要建立索引
- 主键列需要建立主键索引。
- 经常用于查询条件的字段,可以大幅提升查询效率。
- 经常用于连接的字段,这些列主要optimize join操作。
- 经常需要排序的字段,可以通过索引排序避免全表扫描。
- 查询中统计或分组字段,这些字段通常需要建立索引。
- 经常更新的字段通常不适合创建索引,会降低更新速度。
- Where条件里用到的字段需要建立索引。
- 查询中与其他表关联的字段,可以加速关联查询。
- 字符串类型的字段如果用到了前缀查找也可以建立索引。
6.什么情况下不需要建立索引
- 数据量很小的表。索引需要占用额外存储空间,在小表中查询本身很快,不需要索引。
- 主键列已建立索引,则其他列不需要建立索引,避免冗余。
- 频繁更新的字段不适合创建索引,维护索引的开销很高。
- Where条件里用不到的字段不需要创建索引。
- 很少使用的表可以不创建索引,提高写操作速度。
- 对于频繁增长且需要定期清理的日志表也不需要建索引。
- 文本、图像等大lob字段不适合建立索引。
- 频繁查询的表可以只建立部分索引而不是全部字段创建索引。
- 冗余和重复数据可以不建索引。
7.索引有什么分类
数据库索引可以分以下几类:
1、单列索引
只针对一列建立的索引,一张表可以有多个单列索引。
2、唯一索引
索引列的值必须唯一,但允许有空值。
3、复合索引
基于多列建立的索引,只有使用了第一个字段才能生效。
4、前缀索引
只索引字段的前几个字符,提高查询效率。
5、全文索引(只有在MyISAM
引擎上才能使用)
针对文本的内容进行索引,用于全文搜索。
6、空间索引
MYSQL 5.7版本支持的空间数据索引。
7、哈希索引
将值进行哈希计算,然后索引哈希值,只支持精确等值查询。
8、主键索引
- 主键列上的索引,确保主键的唯一性。
- 一张表只能有一个主键。
- 主键索引是一种特殊的唯一索引。
- 查询时主键索引提供高效访问表数据的途径。
- 主键索引都会默认创建,不需要手动建立。
8.索引的设计原则
设计数据库索引的常见原则:
- 对查询频繁的字段建立索引,这是设计索引的首要原则。
- 唯一性索引要注意选择合适的字段,不要对可能重复的数据建唯一索引。
- 对字符串类型数据要根据查询情况决定建立普通索引还是前缀索引。
- 限制索引的个数,避免冗余索引和重复索引。
- 对于大表要注意区分主键索引和非主键索引。
- 不要对更新频繁的字段建索引,会降低更新速度。
- 尽量使用连续整数作为主键索引代替UUID,可以减少数据文件碎片。
- 正确选择索引策略,在合适时机建立和删除索引,以便数据库优化。
- 参考数据库执行计划选择合适的索引。
- 根据系统实际查询情况不断测试和优化现有索引。
9.索引的数据结构
MySQL中的索引主要使用以下两种数据结构实现:
-
B+树
这是MySQL中最常见的索引结构,理由如下:
- B+树的叶子节点存放数据指针,提高搜索效率。
- B+树内部节点存储键值信息,树较平衡,查找性能好。
- 相对红黑树来说,B+树磁盘IO次数更少。
- 支持顺序扫描及区间查找。
-
哈希表
InnoDB引擎支持哈希索引,原理是通过哈希函数计算索引键值的哈希值,然后映射到存储引擎页。
- 只支持精确匹配查询,不支持范围查询。
- 查找性能极高,通常只需要一次查找。
- 只能用于等值比较查询。
- 不支持排序等其它用途。
10.为什么B+树比B树更适合实现数据库索引
B+树比B树更适合实现数据库索引的原因有:
- B+树的叶子节点存放数据记录的指针,提高检索效率。B树的叶子节点需要遍历才能找到数据。
- B+树内部节点只存储键值信息,可以拥有更大的枝干,树更加平衡。B树内部节点存储数据记录,树相对更不平衡。
- B+树的叶子节点使用指针连接,方便区间查找和遍历。B树需要回溯内部节点。
- 由于不存数据记录,B+树的节点大小固定,便于缓存。B树节点大小不固定,缓存不友好。
- B+树的插入效率更稳定。B树可能需要拆分节点。
- B+树只需访问叶子节点就可完成查找,IO次数少。B树需要从根访问到叶子。
11.什么是覆盖索引
覆盖索引(Covering Index)指的是查询只通过访问索引就可以返回所需数据,而无需再次访问数据表,这可以大大提高查询效率。
是否覆盖索引的判断依据是:
- 查询的字段都出现在索引中
- 查询结果来自索引,而不是数据表
形成覆盖索引的原因:
- 索引包含了所查询的所有字段值
- 数据行存在于索引页中,索引是聚簇索引
覆盖索引的优点:
- 避免访问表,减少IO次数
- 利用索引的优化查找算法
- 避免关联其他索引
12.聚簇索引(Clustered Index)和非聚簇索引(Non-clustered Index)的区别
- 数据存储位置不同
- 聚簇索引的数据存储与索引放在一起。
- 非聚簇索引的数据存储在表中,索引处于另外的结构中。
- 索引组织方式不同
- 聚簇索引的叶子节点存放数据,按照索引排列数据。
- 非聚簇索引的叶子节点存储指向数据的指针。
- 数据访问方式不同
- 聚簇索引支持直接定位到具体数据。
- 非聚簇索引需要先定位到索引,再访问数据页面。
- 主键区别
- 主键若设为聚簇索引,数据存储与主键索引在一起。
- 主键若为非聚簇,主键和数据分开存储。
13.索引为什么不是二叉树,为什么不是平衡二叉树
主要原因如下:
-
磁盘IO是影响索引效率的主要因素。多路平衡查找树能减少磁盘IO次数。
-
数据库索引需要支持范围查找和顺序扫描,而非简单的点查找。B树可以高效支持区间查找。
-
数据库中的数据经常需要插入更新,B树对动态数据的支持更好。
-
B+树只在叶子节点存储数据,可以减少磁盘IO。
-
红黑树等平衡二叉树虽平衡,但磁盘IO次数较高。
-
数据库索引节点大小影响高速缓存效率。B树节点大小固定,有利于缓存。
-
B+树叶子节点链表支持高效地顺序访问索引。
所以数据库系统选择B树或B+树作为索引结构,主要是为了减少IO消耗,提高多用户高并发环境下的查询效率。
14.什么是回表
回表(Index Join Backward Scan) 是数据库系统优化器的一种执行计划。
当查询使用了覆盖索引,需要取得额外的列数据时,会触发回表机制:
-
根据索引条件,定位主键或唯一索引记录
-
拿到主键或唯一索引值
-
用该值到数据表中进行KEY Lookup,查看完整记录
-
获取需要的额外列数据
回表的优点是直接定位到所需记录,避免全表扫描。
回表的劣势是需要额外的JOIN操作,如果大批数据会增加开销。
是否回表由优化器决定,可以通过explain查看执行计划。
在索引设计时,使用覆盖索引可以有效减少回表情况。
三、事务相关
1.事务的四大特性
事务的四大特性:
-
原子性(Atomicity):
事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
-
一致性(Consistency):
事务必须使数据库从一个一致性状态变换到另一个一致性状态。
-
隔离性(Isolation):
一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的。
-
持久性(Durability):
一旦事务完成,无论系统发生什么错误,其结果都不会受到影响,该事务的修改将会永久保存在数据库中。
综合起来,事务的这四大特性简称为ACID,指事务具备原子性、一致性、隔离性和持久性这四个特点。这能确保事务在高并发环境中数据的完整性和一致性。
2.什么是脏读、不可重复读、幻读
脏读(Dirty read): 一个事务读取了另一个未提交事务修改的数据。
不可重复读(Nonrepeatable read): 一个事务多次读取同一数据,但读取结果不一致。
幻读(Phantom read):一个事务按相同查询条件重新读取数据,发现其他事务插入了新数据。
原因:
- 脏读是读取了未提交数据
- 不可重复读是同一事务重复读取数据值被修改
- 幻读是同一事务读取到了其他事务插入的数据
3.事务的隔离级别
- 读未提交(Read Uncommitted) 最低级别,允许脏读、不可重复读、幻读的发生。
- 读提交(Read Committed) 只允许读取已经提交的数据。可以避免脏读,但不可重复读和幻读可能会发生。
- 可重复读(Repeatable Read) 确保同一个事务中多次读取的数据都是一致的。可以避免脏读和不可重复读。
- 串行化(Serializable) 最高隔离级别,强制事务串行顺序执行,完全避免上述问题。
隔离级别越高,数据一致性就越好,但并发性越弱。 需要根据业务需求选择合适的隔离级别。 MySQL默认使用可重复读隔离级别,能避免常见的一致性问题。
-
查看隔离级别
select @@transaction_isolation;
-
设置隔离级别
set session transaction isolation level read uncommitted;
4.MySQL的事务在高并发下会遇到什么问题,会用到哪些锁,有没有解决方案
MySQL的事务在高并发下主要会遇到以下问题:
- 长事务会产生锁等待,阻塞其他事务,降低并发性。
- 读写锁冲突频繁,导致请求积压。
- 幻读问题,导致事务隔离性受损。
MySQL的事务会使用以下几种锁:
- 共享锁(S):允许同时读,阻止写。
- 排他锁(X):只允许单个线程访问。
- 意向锁:事先申请锁类型的意向。
解决方案:
- 缩短事务范围,减少锁持有时间。
- 避免长事务和表锁,最小化锁粒度。
- 写操作前获取意向锁,避免冲突。
- 尽量使用乐观锁,而非悲观锁。
- 将冲突操作分布到不同物理节点。
- 设置事务隔离级别避免幻读问题。
四、锁相关
1.InnoDB有哪几种锁
InnoDB 的几种锁的细节如下:
- 共享锁(S):
-
允许多个事务同时对记录进行读取操作。
-
其他事务只能再获得共享锁,不能获得排他锁。
- 排他锁(X):
-
只允许当前事务访问资源,其他事务不能访问。
-
保证事务隔离性,用于 update、delete 等修改操作。
- 意向共享锁(IS):
-
事务在申请共享锁前需要获得的锁。
-
提升并发性, notified锁可以先获取IS锁。
- 意向排他锁(IX):
-
在获取排他锁前需要获得的意向锁。
-
如果事务T1持有IX锁,其他事务只能获取IS锁,不能直接获取X锁,避免死锁。
- 自动增长锁:
-
对AUTO_INCREMENT类型的字段进行修改时,会加自动增长锁。
-
只允许一个事务进行自增操作,实现序列的唯一性。
- 插入意向锁:
-
对即将插入的数据行加插入意向锁,表示插入意图。
-
避免同一关键字的重复插入。
2.不同的事务隔离级别下分别用了哪些锁
在不同的事务隔离级别下,InnoDB使用的锁机制有所不同:
- 读未提交(read uncommitted):
-
只会对修改的行加排他锁,不会加任何读锁。
-
会出现脏读、不可重复读、幻读情况。
- 读提交(read committed):
-
对读取的行加共享锁,对修改的行加排他锁。
-
可以防止脏读,但幻读、不可重复读可能发生。
- 可重复读(repeatable read):
-
对读取的行加共享锁,对修改的行加排他锁。
-
再加上间隙锁,可以防止幻读。
- 序列化(serializable):
-
对读取查询范围加共享锁,对修改的行加排他锁。
-
加上间隙锁和Next-Key锁,完全串行化。
隔离级别越高,并发性越低,但数据一致性更好。需要根据业务需求折中考虑。
3.MySQL什么情况下会形成死锁,以及相应的解决方案
MySQL中可能出现死锁的典型情况:
-
两个事务以不同顺序请求锁资源,形成互相等待。
-
一个事务占用锁资源的同时,请求其他锁资源。
-
锁资源范围不明确,一个事务锁定范围过广。
-
锁粒度过细,事务在同一资源的不同数据行申请锁。
-
事务在锁资源时进行了DML操作。
解决死锁的方法:
-
尽量减少锁粒度,避免不必要的锁定资源范围。
-
避免事务中的锁竞争,按固定顺序或锁分段申请。
-
降低隔离级别,使用乐观锁等手段。
-
设置锁超时,防止无限等待。
-
死锁检测机制,事务回滚重试。
-
合理设计 schema,减少锁冲突。
-
根据业务分离操作集中在一个事务中,分段提交。
4.什么是乐观锁,什么悲观锁
悲观锁和乐观锁是两种不同的并发控制方法:
悲观锁:
-
假设会发生并发冲突,屏蔽一切可能违反数据完整性的操作。
-
主要方式是通过数据库的锁机制控制并发访问。
-
线程在访问数据时需要先获得锁,操作完成后释放锁。
乐观锁:
-
假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。
-
主要方式是通过版本控制实现并发控制。
-
不对数据加锁,但在更新时检查版本是否发生变化。
-
更新失败时,重试更新操作。
相比之下,乐观锁适合高并发低冲突情况,不需要锁的开销,提高了吞吐量。
5.乐观锁和悲观锁的实现
悲观锁和乐观锁的实现方式:
悲观锁:
-
使用 synchronized 或者 lock 进行锁定;
-
读取数据时上锁,更新完成后释放锁;
-
线程等待锁释放,可能造成线程阻塞。
乐观锁:
-
在数据表中新增版本号version字段;
-
更新时检查版本号是否变化,如果没变化则更新,否则重试。
-
不需要锁定资源,通过 retrying 来确保一致性。
具体实现:
-
悲观锁通过语言原生的lock来控制;
-
乐观锁在应用级别实现,在数据字段中加入版本来控制。
-
数据库的悲观锁通过锁机制实现。
-
MVCC则是一种优化的乐观锁理念。
五、存储引擎相关
1.MySQL的常见存储引擎
MySQL常见的存储引擎包括:
MyISAM:
- 不支持事务和行级锁
- 读写效率高,节省系统资源
- 不支持外键
- 只有表锁,并发写效率低
InnoDB:
- 支持事务与外键
- 行级锁设计,并发效率高
- 内存占用高,表锁开销较大
- 可靠性好,支持故障恢复
Memory:
- 将所有数据放到内存中
- 读写速度快,但数据无法持久化
- 响应时间极短,非常适合临时表
Archive:
- 只支持插入和查询操作
- 数据高度压缩,磁盘空间占用极低
- 不支持索引,无法进行修改、删除
各引擎有自己的优势场景,MyISAM适合干净快速读写,InnoDB带事务支持;Memory用于临时表,Archive用于归档存储。
2.InnoDB内存结构包含的四大核心组件
InnoDB存储引擎的内存结构主要包含以下4大组件:
-
Buffer Pool
缓冲池,用于缓存数据和索引,避免频繁访问磁盘。它占用了InnoDB内存的大部分。
-
Log Buffer
红日志缓冲区,用于临时缓冲日志数据,提高写性能。
-
Lock System
锁管理系统,存储锁信息,管理事务并发控制。
-
Change Buffer
变更缓冲区,用于暂时记录对二级索引的变更,提高写入速度。
这4个组件各司其职,共同提高InnoDB的并发性能:
- Buffer Pool减少磁盘I/O
- Log Buffer加速日志写入
- Lock System实现并发控制
- Change Buffer延迟二级索引更新
它们保证了InnoDB的事务支持与高性能。
3.MVCC机制
MySQL InnoDB存储引擎通过MVCC(多版本并发控制)来支持事务并实现隔离级别,其基本原理是:
- 每行记录包含两个隐藏字段:
- 事务id:标记最后修改该记录的事务id
- 回滚指针:指向这条记录旧版本
-
更新时,不直接覆盖旧记录,而是生成一个新的版本。
-
读取时,判断事务id和当前事务id,如果版本不可见,就通过回滚指针找到旧版本。
-
提交时将旧版本放入回收链表中待清理。
-
通过undo日志进行回滚恢复。
-
间隙锁和next-key锁实现对间隙和幻读的控制。
MVCC实现了非阻塞的读写和版本控制,支持事务隔离。但也带来了额外的开销和复杂度。
4.MySQL的快照读和当前读机制
MySQL InnoDB中的快照读和当前读:
快照读(Snapshot read):
-
事务开始时创建快照,记录当前数据集状态。
-
事务读取时直接从快照读取数据,不用加锁。
-
实现非阻塞读,提高并发性。
当前读(Current read):
-
每次读取时直接从磁盘读取最新committed版本的数据。
-
需要加共享锁,可能造成阻塞。
-
可避免不可重复读的问题。
区别:
-
快照读通过一致的快照实现了非阻塞读。
-
当前读每次都读取最新数据,但有锁开销。
InnoDB默认是Repeatable Read隔离级别,使用快照读保证一致性且不阻塞读。
六、MySQL和Redis联合使用相关
1.设计一个框架让MySQL的表自动同步到Redis里
设计一个框架,实现MySQL表数据自动同步到Redis的步骤:
- 框架需要维护一个配置表,记录要同步的MySQL表及对应Redis键名。
- 实现一个抽象同步器,对MySQL的增删改操作进行拦截,将变更记录下来。
- 同步器启动独立线程,定时扫描变更记录,批量同步到Redis。
- 根据Redis的数据结构,选择合适的键值设计,如Hash、Set等。
- 使用Redis Pipeline进行同步操作,能够批量提交提高效率。
- 在同步完成后,及时清除变更记录,避免重复同步。
- 对敏感数据要进行脱敏处理后再同步。
- 使用信号量或者锁保证同步的原子性。
- 设计灵活的错误处理机制,如果同步失败则进行重试或报警。
- 支持可配置化,如同步频率、超时时间等参数。
这样通过抽象框架进行封装,可以实现 MySQL 到 Redis 的自动化高效同步。
还可以读MySQL的binlog
MySQL的binlog二进制日志文件可以被读取和解析,常见的读取和解析binlog的方式有:
-
使用mysqlbinlog工具,它可以打印出binlog中的SQL语句,用于查看binlog。
例如:
mysqlbinlog mysql-bin.000001
-
在MySQL客户端使用SHOW BINLOG EVENTS,可以查看binlog中的事件。
-
使用mysql库提供的mysql_binlog_dump()函数读取binlog内容。
-
使用Binlog API,在代码中注册事件监听器,可以解析binlog事件。
-
使用第三方工具,如go-mysql-replication,用于复制和解析binlog。
读取binlog的常见应用场景:
- 同步复制:从库解析主库binlog实现复制。
- 数据恢复:使用binlog恢复数据。
- 实时备份。
- 数据采集:采集binlog写入数据仓库。
2.redis的数据怎么同步到MySQL里
将Redis中的数据同步到MySQL数据库中,通常有以下几种实现方式:
-
使用Redis自带的Keyspace Notifications功能,监听Redis键空间事件,通过触发器同步到MySQL。
-
编写程序定期扫描Redis,同步新增或更新的键值到MySQL对应表中。
-
使用Redis流水线(pipelining)批量获取数据,然后同步到MySQL中。
-
通过Redis Pub/Sub实现消息队列,由消费者程序获取消息并写入MySQL。
-
使用第三方同步中间件,如Canal等,解析Redis的数据变更同步到MySQL。
-
利用ElasticSearch作为中间层,使用Logstash从Redis中获取数据导入ES,再同步到MySQL。
-
使用共享存储的方式,使Redis和MySQL访问同一份数据文件或备份文件。
根据业务需求和系统架构,选择合适的同步方案来保证Redis和MySQL数据的一致性。
3.怎么解决MySQL和Redis数据一致性的问题
要解决MySQL和Redis之间数据一致性问题,主要的方法包括:
-
单向同步:只要保证MySQL到Redis或者Redis到MySQL的单向同步即可。
-
强制顺序:对数据操作进行强制顺序化,确保同步的顺序性。
-
避免循环更新:避免同时对两个数据源进行更新从而形成循环,通过去重等手段避免。
-
事务一致性:使用分布式事务来确保跨数据库的事务一致性。
-
事件溯源:通过事件溯源的方式确保数据库始终基于同一系列事件进行更新。
-
数据校对:定期进行数据校对,纠正不一致情况。
-
冲突解决策略:设定数据不一致时的冲突解决方案,如时间戳判断。
-
唯一键验证:使用唯一键验证来避免插入不一致的数据。
-
流处理保证:使用流处理链路严格保证一致性。
根据系统架构,选择合适的方案来满足一致性需求。
七、MySQL整体
1.MySQL架构
MySQL的常见架构可以分为以下几层:
-
连接层:支持各种客户端协议,包括基于TCP/IP的MySQL协议,ssh协议,内存socket等。
-
服务层:负责查询缓存,SQL解析、预处理、权限验证等功能。
-
引擎层:存储引擎层,对表进行存取和管理,支持InnoDB、MyISAM等多种存储引擎。
-
存储层:主要是文件系统和磁盘管理,存储引擎通过接口与之交互。
-
复制层:主从复制相关的日志管理、故障切换等功能。
-
连接池模块:管理缓冲客户端连接,提高连接性能。
-
优化器模块:Sql语句执行的查询优化、执行计划选择等。
2.如何监控数据库,有没有什么工具
监控数据库的常用方法和工具包括:
-
基于日志的监控:开启MySQL的slow log、error log等日志,并设置合理的参数,通过分析日志来监控数据库。
-
基于SNMP的监控:使用SNMP服务,通过查询状态参数来监控数据库。
-
使用AOM等数据库遥测框架:通过收集各类性能指标数据库进行监控。
-
系统性能统计:使用top、vmstat、iostat等系统命令查看数据库服务器的状态。
-
数据库的information_schema表:查询其中的metrics表可以获取数据库运行时指标。
-
使用Prometheus exporter等工具暴露数据库指标。
-
Grafana、Zabbix、Nagios等开源监控工具,提供数据库监控插件。
-
阿里云、腾讯云等云厂商的数据库监控服务。
根据需求选择合适的监控方法,可以更好地管理和优化数据库。
3.Mysql主从复制方式
MySQL支持以下几种主从复制方式:
-
异步复制(Asynchronous Replication)
- 从库并不保证与主库完全同步,可能存在一定的延迟。
- 从库在本地执行SQL线程,并通过I/O线程拉取主库binlog日志。
- 系统简单,主库压力小, widely used.
-
半同步复制(Semisynchronous Replication)
- 主库确认至少一个从库接收到日志才确认提交。
- 增加了同步能力,但也增加了延迟。
-
全同步复制(Synchronous Replication)
- 要求主库提交必须等待多个或全部从库收到日志才能确认。
- 从库与主库完全同步,但主库压力大。
-
组复制(Group Replication)
-
MySQL 8.0的新复制方式,通过组内的协议实现多主多从。
-
可使每个节点成为读写节点。
-
-
延迟复制
延迟复制指的是从库可以配置在主库写入binlog日志一段时间后再应用日志中的修改。
实现方式是在从库配置delayed_replication_interval参数指定延迟时间。
使用场景:
- 数据恢复:主库删除或更新数据后,从库可以保留历史数据一段时间。
- 错误处理:主库执行错误操作,可以在从库待一段时间后再执行。
- 数据分析:在从库最新数据之外保留历史数据做报表。
- 灾备测试:模拟主库宕机情况测试灾备切换。
延迟复制实现了在从库保留历史数据的功能,提供了一定的容错空间。
需要考虑延迟时间,监控从库复制进度,以免延迟过长影响使用。
4.什么是数据库连接池?为什么需要数据库连接池呢?
数据库连接池是一种数据库资源复用技术,主要作用是提高数据库连接的使用效率。
具体来说,数据库连接池实现了以下功能:
-
缓存数据库连接对象,重用存在的连接,避免频繁创建销毁连接的资源开销。
-
管理连接对象数量,合理分配连接资源,避免无效连接占用资源。
-
管理空闲连接及其超时时间,释放超时空闲连接以节省资源。
-
提供连接使用数量监控,记录数据库连接的使用与性能情况。
-
提供线程安全的连接使用方式。
-
提供连接故障切换与重连机制,增强容错能力。
所以使用数据库连接池可以提高连接资源的利用率,节省连接创建和关闭的时间,降低系统开销,提高数据库访问性能和稳定性。
这是博主自己整理的MySQL面试题,有些是博主自己遇到过的面试题,如有错误,欢迎指正,如有不全的,欢迎提醒!!!