MySQL面试题合集

MySQL面经知识整理

文章目录

  • MySQL面经知识整理
    • 一、查询相关
      • 1.什么是MySQL的连接查询,左连接,右连接,内外连接
      • 2.SQL慢查询优化的方法
      • 3.大表查询如何优化
    • 二、索引相关
      • 1.在MySQL中,可以通过哪些命令来查看查询是否使用了索引
      • 2.MySQL的最左匹配原则
      • 3.MySQL什么情况下会索引失效
      • 4.索引的优缺点
      • 5.什么情况下需要建立索引
      • 6.什么情况下不需要建立索引
      • 7.索引有什么分类
      • 8.索引的设计原则
      • 9.索引的数据结构
      • 10.为什么B+树比B树更适合实现数据库索引
      • 11.什么是覆盖索引
      • 12.聚簇索引(Clustered Index)和非聚簇索引(Non-clustered Index)的区别
      • 13.索引为什么不是二叉树,为什么不是平衡二叉树
      • 14.什么是回表
    • 三、事务相关
      • 1.事务的四大特性
      • 2.什么是脏读、不可重复读、幻读
      • 3.事务的隔离级别
      • 4.MySQL的事务在高并发下会遇到什么问题,会用到哪些锁,有没有解决方案
    • 四、锁相关
      • 1.InnoDB有哪几种锁
      • 2.不同的事务隔离级别下分别用了哪些锁
      • 3.MySQL什么情况下会形成死锁,以及相应的解决方案
      • 4.什么是乐观锁,什么悲观锁
      • 5.乐观锁和悲观锁的实现
    • 五、存储引擎相关
      • 1.MySQL的常见存储引擎
      • 2.InnoDB内存结构包含的四大核心组件
      • 3.MVCC机制
      • 4.MySQL的快照读和当前读机制
    • 六、MySQL和Redis联合使用相关
      • 1.设计一个框架让MySQL的表自动同步到Redis里
      • 2.redis的数据怎么同步到MySQL里
      • 3.怎么解决MySQL和Redis数据一致性的问题
    • 七、MySQL整体
      • 1.MySQL架构
      • 2.如何监控数据库,有没有什么工具
      • 3.Mysql主从复制方式
      • 4.什么是数据库连接池?为什么需要数据库连接池呢?

一、查询相关

1.什么是MySQL的连接查询,左连接,右连接,内外连接

  1. 内连接(INNER JOIN):

    返回两张表中联结字段匹配的行。

  2. 左连接(LEFT JOIN):

    返回左表所有的行,即使右表中没有匹配的行。

  3. 右连接(RIGHT JOIN):

    返回右表所有的行,即使左表中没有匹配的行。

  4. 全外连接(FULL OUTER JOIN):

    返回两张表中的所有行,左右表没有匹配的行时,结果为NULL。

SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.idSELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.idSELECT * FROM table1 RIGHT JOIN table2 ON table1.id = table2.idSELECT * FROM table1 FULL OUTER JOIN table2 ON table1.id = table2.id

2.SQL慢查询优化的方法

  1. 查看慢查询日志,找到执行时间超长的SQL。
  2. 加索引,特别是加上经常用于查询条件、排序、分组、连接的字段索引。
  3. 调优SQL,简化复杂查询,避免全表扫描和不必要的排序、临时表。
  4. 修改查询方式,例如 EXISTS 代替 IN, UNION ALL 代替 UNION。
  5. 对大表数据进行拆分,减少单表数据量,可提高查询效率。
  6. 缓存频繁查询的数据,利用缓存降低数据库访问。
  7. 配置数据库参数,适当增加配置以提高效率。
  8. 升级数据库服务器硬件配置,使用SSD、增加CPU和内存。
  9. 对于大数据量的报表查询,建议使用数据仓库,并适当拆分数据。
  10. 避免在高峰期运行大查询,选择在低峰时段运行。

3.大表查询如何优化

对于MySQL中大表的查询优化,可以从以下几个方面进行:

  1. 加索引,特别是联合索引,减少扫描行数。
  2. 对查询进行优化,使用条件筛选,避免全表扫描,在索引列上进行计算。
  3. 优化关联查询,使被关联的表大小尽可能小。
  4. 对大表进行拆分,拆分为多个小表,避免单表数据过大。
  5. 采用分页查询,避免一次性取出过多数据。
  6. 缓存热点数据到Redis等缓存系统。
  7. 对于分析类的大查询,建议使用数据仓库进行查询。
  8. 配置MySQL参数,适当调高缓存大小,调低磁盘IO影响。
  9. 使用explain查看执行计划,根据结果进一步优化查询。
  10. 在业务层面进行优化,比如异步化查询,合理控制查询频率等。

综合运用以上手段可以大幅优化MySQL大表查询。

二、索引相关

1.在MySQL中,可以通过哪些命令来查看查询是否使用了索引

  1. EXPLAIN:使用EXPLAIN或者EXPLAIN EXTENDED前置于查询语句,可以分析查询执行计划,从中可以看到是否使用了索引。
  2. SHOW INDEXES:显示表的索引信息,可以查看表上索引的详细情况。
  3. SHOW STATUS:包含Index_searches值,表示执行索引查找的次数,可以和Questions值作对比。
  4. SHOW PROFILE:显示执行每个查询阶段的时间,可以看到索引查询的时间。
  5. 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中,索引可能会出现失效的情况,常见的原因包括:

  1. 索引列参与计算,计算结果无法使用索引。
  2. 查询使用索引列的别名,导致索引不可用。
  3. LIKE语句的通配符出现在查询条件的最前面。
  4. 字符串类型的索引列查询使用不等于非法值时。
  5. 查询条件是一个范围,但范围条件不是索引列的前缀。
  6. 复合索引的查询没有按照索引顺序使用索引列。
  7. 使用OR条件,使得索引无法评估。
  8. 数据类型转换导致索引不能使用,如字符串转数值。
  9. 返回结果来自多个表的联合查询。
  10. 使用了MySQL函数,索引失效。
  11. 某些MySQL优化策略选择了全表扫描。

4.索引的优缺点

优点:

  • 加速查询,直接找到目标记录,减少IO操作。
  • 通过索引进行排序,避免使用文件排序。
  • 使用索引条件过滤获取更少记录,减少读取记录数。
  • 加速表和表之间的连接,使用索引列进行关联。
  • 在存储引擎层面,索引可保持数据的有序性。

缺点:

  • 建立和维护索引需要额外存储空间。
  • 索引会增加写操作开销,需要更新索引。
  • 过多索引会造成查询优化器无法选择最优查询计划。
  • 一些情况索引会失效,需要注意索引使用场景。
  • 索引维护需要碎片整理,会产生额外开销。

5.什么情况下需要建立索引

  1. 主键列需要建立主键索引。
  2. 经常用于查询条件的字段,可以大幅提升查询效率。
  3. 经常用于连接的字段,这些列主要optimize join操作。
  4. 经常需要排序的字段,可以通过索引排序避免全表扫描。
  5. 查询中统计或分组字段,这些字段通常需要建立索引。
  6. 经常更新的字段通常不适合创建索引,会降低更新速度。
  7. Where条件里用到的字段需要建立索引。
  8. 查询中与其他表关联的字段,可以加速关联查询。
  9. 字符串类型的字段如果用到了前缀查找也可以建立索引。

6.什么情况下不需要建立索引

  1. 数据量很小的表。索引需要占用额外存储空间,在小表中查询本身很快,不需要索引。
  2. 主键列已建立索引,则其他列不需要建立索引,避免冗余。
  3. 频繁更新的字段不适合创建索引,维护索引的开销很高。
  4. Where条件里用不到的字段不需要创建索引。
  5. 很少使用的表可以不创建索引,提高写操作速度。
  6. 对于频繁增长且需要定期清理的日志表也不需要建索引。
  7. 文本、图像等大lob字段不适合建立索引。
  8. 频繁查询的表可以只建立部分索引而不是全部字段创建索引。
  9. 冗余和重复数据可以不建索引。

7.索引有什么分类

数据库索引可以分以下几类:

1、单列索引

只针对一列建立的索引,一张表可以有多个单列索引。

2、唯一索引

索引列的值必须唯一,但允许有空值。

3、复合索引

基于多列建立的索引,只有使用了第一个字段才能生效。

4、前缀索引

只索引字段的前几个字符,提高查询效率。

5、全文索引(只有在MyISAM引擎上才能使用)

针对文本的内容进行索引,用于全文搜索。

6、空间索引

MYSQL 5.7版本支持的空间数据索引。

7、哈希索引

将值进行哈希计算,然后索引哈希值,只支持精确等值查询。

8、主键索引

  • 主键列上的索引,确保主键的唯一性。
  • 一张表只能有一个主键。
  • 主键索引是一种特殊的唯一索引。
  • 查询时主键索引提供高效访问表数据的途径。
  • 主键索引都会默认创建,不需要手动建立。

8.索引的设计原则

设计数据库索引的常见原则:

  1. 对查询频繁的字段建立索引,这是设计索引的首要原则。
  2. 唯一性索引要注意选择合适的字段,不要对可能重复的数据建唯一索引。
  3. 对字符串类型数据要根据查询情况决定建立普通索引还是前缀索引。
  4. 限制索引的个数,避免冗余索引和重复索引。
  5. 对于大表要注意区分主键索引和非主键索引。
  6. 不要对更新频繁的字段建索引,会降低更新速度。
  7. 尽量使用连续整数作为主键索引代替UUID,可以减少数据文件碎片。
  8. 正确选择索引策略,在合适时机建立和删除索引,以便数据库优化。
  9. 参考数据库执行计划选择合适的索引。
  10. 根据系统实际查询情况不断测试和优化现有索引。

9.索引的数据结构

MySQL中的索引主要使用以下两种数据结构实现:

  1. B+树

    这是MySQL中最常见的索引结构,理由如下:

    • B+树的叶子节点存放数据指针,提高搜索效率。
    • B+树内部节点存储键值信息,树较平衡,查找性能好。
    • 相对红黑树来说,B+树磁盘IO次数更少。
    • 支持顺序扫描及区间查找。
  2. 哈希表

    InnoDB引擎支持哈希索引,原理是通过哈希函数计算索引键值的哈希值,然后映射到存储引擎页。

    • 只支持精确匹配查询,不支持范围查询。
    • 查找性能极高,通常只需要一次查找。
    • 只能用于等值比较查询。
    • 不支持排序等其它用途。

10.为什么B+树比B树更适合实现数据库索引

B+树比B树更适合实现数据库索引的原因有:

  1. B+树的叶子节点存放数据记录的指针,提高检索效率。B树的叶子节点需要遍历才能找到数据。
  2. B+树内部节点只存储键值信息,可以拥有更大的枝干,树更加平衡。B树内部节点存储数据记录,树相对更不平衡。
  3. B+树的叶子节点使用指针连接,方便区间查找和遍历。B树需要回溯内部节点。
  4. 由于不存数据记录,B+树的节点大小固定,便于缓存。B树节点大小不固定,缓存不友好。
  5. B+树的插入效率更稳定。B树可能需要拆分节点。
  6. B+树只需访问叶子节点就可完成查找,IO次数少。B树需要从根访问到叶子。

11.什么是覆盖索引

覆盖索引(Covering Index)指的是查询只通过访问索引就可以返回所需数据,而无需再次访问数据表,这可以大大提高查询效率。

是否覆盖索引的判断依据是:

  • 查询的字段都出现在索引中
  • 查询结果来自索引,而不是数据表

形成覆盖索引的原因:

  • 索引包含了所查询的所有字段值
  • 数据行存在于索引页中,索引是聚簇索引

覆盖索引的优点:

  • 避免访问表,减少IO次数
  • 利用索引的优化查找算法
  • 避免关联其他索引

12.聚簇索引(Clustered Index)和非聚簇索引(Non-clustered Index)的区别

  1. 数据存储位置不同
  • 聚簇索引的数据存储与索引放在一起。
  • 非聚簇索引的数据存储在表中,索引处于另外的结构中。
  1. 索引组织方式不同
  • 聚簇索引的叶子节点存放数据,按照索引排列数据。
  • 非聚簇索引的叶子节点存储指向数据的指针。
  1. 数据访问方式不同
  • 聚簇索引支持直接定位到具体数据。
  • 非聚簇索引需要先定位到索引,再访问数据页面。
  1. 主键区别
  • 主键若设为聚簇索引,数据存储与主键索引在一起。
  • 主键若为非聚簇,主键和数据分开存储。

13.索引为什么不是二叉树,为什么不是平衡二叉树

主要原因如下:

  1. 磁盘IO是影响索引效率的主要因素。多路平衡查找树能减少磁盘IO次数。

  2. 数据库索引需要支持范围查找和顺序扫描,而非简单的点查找。B树可以高效支持区间查找。

  3. 数据库中的数据经常需要插入更新,B树对动态数据的支持更好。

  4. B+树只在叶子节点存储数据,可以减少磁盘IO。

  5. 红黑树等平衡二叉树虽平衡,但磁盘IO次数较高。

  6. 数据库索引节点大小影响高速缓存效率。B树节点大小固定,有利于缓存。

  7. B+树叶子节点链表支持高效地顺序访问索引。

所以数据库系统选择B树或B+树作为索引结构,主要是为了减少IO消耗,提高多用户高并发环境下的查询效率。

14.什么是回表

回表(Index Join Backward Scan) 是数据库系统优化器的一种执行计划。

当查询使用了覆盖索引,需要取得额外的列数据时,会触发回表机制:

  1. 根据索引条件,定位主键或唯一索引记录

  2. 拿到主键或唯一索引值

  3. 用该值到数据表中进行KEY Lookup,查看完整记录

  4. 获取需要的额外列数据

回表的优点是直接定位到所需记录,避免全表扫描。

回表的劣势是需要额外的JOIN操作,如果大批数据会增加开销。

是否回表由优化器决定,可以通过explain查看执行计划。

在索引设计时,使用覆盖索引可以有效减少回表情况。

三、事务相关

1.事务的四大特性

事务的四大特性:

  1. 原子性(Atomicity):

    事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

  2. 一致性(Consistency):

    事务必须使数据库从一个一致性状态变换到另一个一致性状态。

  3. 隔离性(Isolation):

    一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的。

  4. 持久性(Durability):

    一旦事务完成,无论系统发生什么错误,其结果都不会受到影响,该事务的修改将会永久保存在数据库中。

综合起来,事务的这四大特性简称为ACID,指事务具备原子性、一致性、隔离性和持久性这四个特点。这能确保事务在高并发环境中数据的完整性和一致性。

2.什么是脏读、不可重复读、幻读

脏读(Dirty read): 一个事务读取了另一个未提交事务修改的数据。

不可重复读(Nonrepeatable read): 一个事务多次读取同一数据,但读取结果不一致。

幻读(Phantom read):一个事务按相同查询条件重新读取数据,发现其他事务插入了新数据。

原因:

  • 脏读是读取了未提交数据
  • 不可重复读是同一事务重复读取数据值被修改
  • 幻读是同一事务读取到了其他事务插入的数据

3.事务的隔离级别

  1. 读未提交(Read Uncommitted) 最低级别,允许脏读、不可重复读、幻读的发生。
  2. 读提交(Read Committed) 只允许读取已经提交的数据。可以避免脏读,但不可重复读和幻读可能会发生。
  3. 可重复读(Repeatable Read) 确保同一个事务中多次读取的数据都是一致的。可以避免脏读和不可重复读。
  4. 串行化(Serializable) 最高隔离级别,强制事务串行顺序执行,完全避免上述问题。

隔离级别越高,数据一致性就越好,但并发性越弱。 需要根据业务需求选择合适的隔离级别。 MySQL默认使用可重复读隔离级别,能避免常见的一致性问题。

  • 查看隔离级别

    select @@transaction_isolation;
    
  • 设置隔离级别

    set session transaction isolation level read uncommitted;
    

4.MySQL的事务在高并发下会遇到什么问题,会用到哪些锁,有没有解决方案

MySQL的事务在高并发下主要会遇到以下问题:

  1. 长事务会产生锁等待,阻塞其他事务,降低并发性。
  2. 读写锁冲突频繁,导致请求积压。
  3. 幻读问题,导致事务隔离性受损。

MySQL的事务会使用以下几种锁:

  1. 共享锁(S):允许同时读,阻止写。
  2. 排他锁(X):只允许单个线程访问。
  3. 意向锁:事先申请锁类型的意向。

解决方案:

  1. 缩短事务范围,减少锁持有时间。
  2. 避免长事务和表锁,最小化锁粒度。
  3. 写操作前获取意向锁,避免冲突。
  4. 尽量使用乐观锁,而非悲观锁。
  5. 将冲突操作分布到不同物理节点。
  6. 设置事务隔离级别避免幻读问题。

四、锁相关

1.InnoDB有哪几种锁

InnoDB 的几种锁的细节如下:

  1. 共享锁(S):
  • 允许多个事务同时对记录进行读取操作。

  • 其他事务只能再获得共享锁,不能获得排他锁。

  1. 排他锁(X):
  • 只允许当前事务访问资源,其他事务不能访问。

  • 保证事务隔离性,用于 update、delete 等修改操作。

  1. 意向共享锁(IS):
  • 事务在申请共享锁前需要获得的锁。

  • 提升并发性, notified锁可以先获取IS锁。

  1. 意向排他锁(IX):
  • 在获取排他锁前需要获得的意向锁。

  • 如果事务T1持有IX锁,其他事务只能获取IS锁,不能直接获取X锁,避免死锁。

  1. 自动增长锁:
  • 对AUTO_INCREMENT类型的字段进行修改时,会加自动增长锁。

  • 只允许一个事务进行自增操作,实现序列的唯一性。

  1. 插入意向锁:
  • 对即将插入的数据行加插入意向锁,表示插入意图。

  • 避免同一关键字的重复插入。

2.不同的事务隔离级别下分别用了哪些锁

在不同的事务隔离级别下,InnoDB使用的锁机制有所不同:

  1. 读未提交(read uncommitted):
  • 只会对修改的行加排他锁,不会加任何读锁。

  • 会出现脏读、不可重复读、幻读情况。

  1. 读提交(read committed):
  • 对读取的行加共享锁,对修改的行加排他锁。

  • 可以防止脏读,但幻读、不可重复读可能发生。

  1. 可重复读(repeatable read):
  • 对读取的行加共享锁,对修改的行加排他锁。

  • 再加上间隙锁,可以防止幻读。

  1. 序列化(serializable):
  • 对读取查询范围加共享锁,对修改的行加排他锁。

  • 加上间隙锁和Next-Key锁,完全串行化。

隔离级别越高,并发性越低,但数据一致性更好。需要根据业务需求折中考虑。

3.MySQL什么情况下会形成死锁,以及相应的解决方案

MySQL中可能出现死锁的典型情况:

  1. 两个事务以不同顺序请求锁资源,形成互相等待。

  2. 一个事务占用锁资源的同时,请求其他锁资源。

  3. 锁资源范围不明确,一个事务锁定范围过广。

  4. 锁粒度过细,事务在同一资源的不同数据行申请锁。

  5. 事务在锁资源时进行了DML操作。

解决死锁的方法:

  1. 尽量减少锁粒度,避免不必要的锁定资源范围。

  2. 避免事务中的锁竞争,按固定顺序或锁分段申请。

  3. 降低隔离级别,使用乐观锁等手段。

  4. 设置锁超时,防止无限等待。

  5. 死锁检测机制,事务回滚重试。

  6. 合理设计 schema,减少锁冲突。

  7. 根据业务分离操作集中在一个事务中,分段提交。

4.什么是乐观锁,什么悲观锁

悲观锁和乐观锁是两种不同的并发控制方法:

悲观锁:

  • 假设会发生并发冲突,屏蔽一切可能违反数据完整性的操作。

  • 主要方式是通过数据库的锁机制控制并发访问。

  • 线程在访问数据时需要先获得锁,操作完成后释放锁。

乐观锁:

  • 假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。

  • 主要方式是通过版本控制实现并发控制。

  • 不对数据加锁,但在更新时检查版本是否发生变化。

  • 更新失败时,重试更新操作。

相比之下,乐观锁适合高并发低冲突情况,不需要锁的开销,提高了吞吐量。

5.乐观锁和悲观锁的实现

悲观锁和乐观锁的实现方式:

悲观锁:

  • 使用 synchronized 或者 lock 进行锁定;

  • 读取数据时上锁,更新完成后释放锁;

  • 线程等待锁释放,可能造成线程阻塞。

乐观锁:

  • 在数据表中新增版本号version字段;

  • 更新时检查版本号是否变化,如果没变化则更新,否则重试。

  • 不需要锁定资源,通过 retrying 来确保一致性。

具体实现:

  • 悲观锁通过语言原生的lock来控制;

  • 乐观锁在应用级别实现,在数据字段中加入版本来控制。

  • 数据库的悲观锁通过锁机制实现。

  • MVCC则是一种优化的乐观锁理念。

五、存储引擎相关

1.MySQL的常见存储引擎

MySQL常见的存储引擎包括:

MyISAM:

  • 不支持事务和行级锁
  • 读写效率高,节省系统资源
  • 不支持外键
  • 只有表锁,并发写效率低

InnoDB:

  • 支持事务与外键
  • 行级锁设计,并发效率高
  • 内存占用高,表锁开销较大
  • 可靠性好,支持故障恢复

Memory:

  • 将所有数据放到内存中
  • 读写速度快,但数据无法持久化
  • 响应时间极短,非常适合临时表

Archive:

  • 只支持插入和查询操作
  • 数据高度压缩,磁盘空间占用极低
  • 不支持索引,无法进行修改、删除

各引擎有自己的优势场景,MyISAM适合干净快速读写,InnoDB带事务支持;Memory用于临时表,Archive用于归档存储。

2.InnoDB内存结构包含的四大核心组件

InnoDB存储引擎的内存结构主要包含以下4大组件:

  1. Buffer Pool

    缓冲池,用于缓存数据和索引,避免频繁访问磁盘。它占用了InnoDB内存的大部分。

  2. Log Buffer

    红日志缓冲区,用于临时缓冲日志数据,提高写性能。

  3. Lock System

    锁管理系统,存储锁信息,管理事务并发控制。

  4. Change Buffer

    变更缓冲区,用于暂时记录对二级索引的变更,提高写入速度。

这4个组件各司其职,共同提高InnoDB的并发性能:

  • Buffer Pool减少磁盘I/O
  • Log Buffer加速日志写入
  • Lock System实现并发控制
  • Change Buffer延迟二级索引更新

它们保证了InnoDB的事务支持与高性能。

3.MVCC机制

MySQL InnoDB存储引擎通过MVCC(多版本并发控制)来支持事务并实现隔离级别,其基本原理是:

  1. 每行记录包含两个隐藏字段:
  • 事务id:标记最后修改该记录的事务id
  • 回滚指针:指向这条记录旧版本
  1. 更新时,不直接覆盖旧记录,而是生成一个新的版本。

  2. 读取时,判断事务id和当前事务id,如果版本不可见,就通过回滚指针找到旧版本。

  3. 提交时将旧版本放入回收链表中待清理。

  4. 通过undo日志进行回滚恢复。

  5. 间隙锁和next-key锁实现对间隙和幻读的控制。

MVCC实现了非阻塞的读写和版本控制,支持事务隔离。但也带来了额外的开销和复杂度。

4.MySQL的快照读和当前读机制

MySQL InnoDB中的快照读和当前读:

快照读(Snapshot read):

  • 事务开始时创建快照,记录当前数据集状态。

  • 事务读取时直接从快照读取数据,不用加锁。

  • 实现非阻塞读,提高并发性。

当前读(Current read):

  • 每次读取时直接从磁盘读取最新committed版本的数据。

  • 需要加共享锁,可能造成阻塞。

  • 可避免不可重复读的问题。

区别:

  • 快照读通过一致的快照实现了非阻塞读。

  • 当前读每次都读取最新数据,但有锁开销。

InnoDB默认是Repeatable Read隔离级别,使用快照读保证一致性且不阻塞读。

六、MySQL和Redis联合使用相关

1.设计一个框架让MySQL的表自动同步到Redis里

设计一个框架,实现MySQL表数据自动同步到Redis的步骤:

  1. 框架需要维护一个配置表,记录要同步的MySQL表及对应Redis键名。
  2. 实现一个抽象同步器,对MySQL的增删改操作进行拦截,将变更记录下来。
  3. 同步器启动独立线程,定时扫描变更记录,批量同步到Redis。
  4. 根据Redis的数据结构,选择合适的键值设计,如Hash、Set等。
  5. 使用Redis Pipeline进行同步操作,能够批量提交提高效率。
  6. 在同步完成后,及时清除变更记录,避免重复同步。
  7. 对敏感数据要进行脱敏处理后再同步。
  8. 使用信号量或者锁保证同步的原子性。
  9. 设计灵活的错误处理机制,如果同步失败则进行重试或报警。
  10. 支持可配置化,如同步频率、超时时间等参数。

这样通过抽象框架进行封装,可以实现 MySQL 到 Redis 的自动化高效同步。

还可以读MySQL的binlog

MySQL的binlog二进制日志文件可以被读取和解析,常见的读取和解析binlog的方式有:

  1. 使用mysqlbinlog工具,它可以打印出binlog中的SQL语句,用于查看binlog。

    例如:

    mysqlbinlog mysql-bin.000001
    
  2. 在MySQL客户端使用SHOW BINLOG EVENTS,可以查看binlog中的事件。

  3. 使用mysql库提供的mysql_binlog_dump()函数读取binlog内容。

  4. 使用Binlog API,在代码中注册事件监听器,可以解析binlog事件。

  5. 使用第三方工具,如go-mysql-replication,用于复制和解析binlog。

读取binlog的常见应用场景:

  • 同步复制:从库解析主库binlog实现复制。
  • 数据恢复:使用binlog恢复数据。
  • 实时备份。
  • 数据采集:采集binlog写入数据仓库。

2.redis的数据怎么同步到MySQL里

将Redis中的数据同步到MySQL数据库中,通常有以下几种实现方式:

  1. 使用Redis自带的Keyspace Notifications功能,监听Redis键空间事件,通过触发器同步到MySQL。

  2. 编写程序定期扫描Redis,同步新增或更新的键值到MySQL对应表中。

  3. 使用Redis流水线(pipelining)批量获取数据,然后同步到MySQL中。

  4. 通过Redis Pub/Sub实现消息队列,由消费者程序获取消息并写入MySQL。

  5. 使用第三方同步中间件,如Canal等,解析Redis的数据变更同步到MySQL。

  6. 利用ElasticSearch作为中间层,使用Logstash从Redis中获取数据导入ES,再同步到MySQL。

  7. 使用共享存储的方式,使Redis和MySQL访问同一份数据文件或备份文件。

根据业务需求和系统架构,选择合适的同步方案来保证Redis和MySQL数据的一致性。

3.怎么解决MySQL和Redis数据一致性的问题

要解决MySQL和Redis之间数据一致性问题,主要的方法包括:

  1. 单向同步:只要保证MySQL到Redis或者Redis到MySQL的单向同步即可。

  2. 强制顺序:对数据操作进行强制顺序化,确保同步的顺序性。

  3. 避免循环更新:避免同时对两个数据源进行更新从而形成循环,通过去重等手段避免。

  4. 事务一致性:使用分布式事务来确保跨数据库的事务一致性。

  5. 事件溯源:通过事件溯源的方式确保数据库始终基于同一系列事件进行更新。

  6. 数据校对:定期进行数据校对,纠正不一致情况。

  7. 冲突解决策略:设定数据不一致时的冲突解决方案,如时间戳判断。

  8. 唯一键验证:使用唯一键验证来避免插入不一致的数据。

  9. 流处理保证:使用流处理链路严格保证一致性。

根据系统架构,选择合适的方案来满足一致性需求。

七、MySQL整体

1.MySQL架构

image-20231003212521215

MySQL的常见架构可以分为以下几层:

  1. 连接层:支持各种客户端协议,包括基于TCP/IP的MySQL协议,ssh协议,内存socket等。

  2. 服务层:负责查询缓存,SQL解析、预处理、权限验证等功能。

  3. 引擎层:存储引擎层,对表进行存取和管理,支持InnoDB、MyISAM等多种存储引擎。

  4. 存储层:主要是文件系统和磁盘管理,存储引擎通过接口与之交互。

  5. 复制层:主从复制相关的日志管理、故障切换等功能。

  6. 连接池模块:管理缓冲客户端连接,提高连接性能。

  7. 优化器模块:Sql语句执行的查询优化、执行计划选择等。

2.如何监控数据库,有没有什么工具

监控数据库的常用方法和工具包括:

  1. 基于日志的监控:开启MySQL的slow log、error log等日志,并设置合理的参数,通过分析日志来监控数据库。

  2. 基于SNMP的监控:使用SNMP服务,通过查询状态参数来监控数据库。

  3. 使用AOM等数据库遥测框架:通过收集各类性能指标数据库进行监控。

  4. 系统性能统计:使用top、vmstat、iostat等系统命令查看数据库服务器的状态。

  5. 数据库的information_schema表:查询其中的metrics表可以获取数据库运行时指标。

  6. 使用Prometheus exporter等工具暴露数据库指标。

  7. Grafana、Zabbix、Nagios等开源监控工具,提供数据库监控插件。

  8. 阿里云、腾讯云等云厂商的数据库监控服务。

根据需求选择合适的监控方法,可以更好地管理和优化数据库。

3.Mysql主从复制方式

MySQL支持以下几种主从复制方式:

  1. 异步复制(Asynchronous Replication)

    • 从库并不保证与主库完全同步,可能存在一定的延迟。
    • 从库在本地执行SQL线程,并通过I/O线程拉取主库binlog日志。
    • 系统简单,主库压力小, widely used.
  2. 半同步复制(Semisynchronous Replication)

    • 主库确认至少一个从库接收到日志才确认提交。
    • 增加了同步能力,但也增加了延迟。
  3. 全同步复制(Synchronous Replication)

    • 要求主库提交必须等待多个或全部从库收到日志才能确认。
    • 从库与主库完全同步,但主库压力大。
  4. 组复制(Group Replication)

    • MySQL 8.0的新复制方式,通过组内的协议实现多主多从。

    • 可使每个节点成为读写节点。

  5. 延迟复制

    延迟复制指的是从库可以配置在主库写入binlog日志一段时间后再应用日志中的修改。

    实现方式是在从库配置delayed_replication_interval参数指定延迟时间。

    使用场景:

    • 数据恢复:主库删除或更新数据后,从库可以保留历史数据一段时间。
    • 错误处理:主库执行错误操作,可以在从库待一段时间后再执行。
    • 数据分析:在从库最新数据之外保留历史数据做报表。
    • 灾备测试:模拟主库宕机情况测试灾备切换。

    延迟复制实现了在从库保留历史数据的功能,提供了一定的容错空间。

    需要考虑延迟时间,监控从库复制进度,以免延迟过长影响使用。

4.什么是数据库连接池?为什么需要数据库连接池呢?

数据库连接池是一种数据库资源复用技术,主要作用是提高数据库连接的使用效率。

具体来说,数据库连接池实现了以下功能:

  1. 缓存数据库连接对象,重用存在的连接,避免频繁创建销毁连接的资源开销。

  2. 管理连接对象数量,合理分配连接资源,避免无效连接占用资源。

  3. 管理空闲连接及其超时时间,释放超时空闲连接以节省资源。

  4. 提供连接使用数量监控,记录数据库连接的使用与性能情况。

  5. 提供线程安全的连接使用方式。

  6. 提供连接故障切换与重连机制,增强容错能力。

所以使用数据库连接池可以提高连接资源的利用率,节省连接创建和关闭的时间,降低系统开销,提高数据库访问性能和稳定性。


这是博主自己整理的MySQL面试题,有些是博主自己遇到过的面试题,如有错误,欢迎指正,如有不全的,欢迎提醒!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/96969.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跨域请求方案整理实践

项目场景: 调用接口进行手机验证提示,项目需要调用其它域名的接口,导致前端提示跨域问题 问题描述 前端调用其他域名接口时报错提示: index.html#/StatisticalAnalysisOfVacancy:1 Access to XMLHttpRequest at http://xxxxx/CustomerService/template/examineMes…

UniApp创建项目HelloWorld

浏览器预览效果镇楼 普通项目创建 点击创建完成后,就如下所示 确实和微信小程序开发差不多。只是稍微换了一个名字的概念了,这个就是开发嘛,不要过于纠结概念性东西。开发开发,开了就知道怎么发了? 或许是 反正write就…

基于虚拟阻抗的下垂控制——孤岛双机并联Simulink仿真

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

Python3操作文件系列(二):文件数据读写|二进制数据读写

Python3操作文件系列(一):判断文件|目录是否存在三种方式 Python3操作文件系列(二):文件数据读写|二进制数据读写 Python3数据文件读取与写入 一: 文件数据|二进制数据读写 import os"""Python3的open(file,mode"文件的操作模式")利用该函数可以对…

基于腾讯云的OTA远程升级

一、OTA OTA即over the air,是一种远程固件升级技术,它允许在设备已经部署在现场运行时通过网络远程更新其固件或软件。OTA技术有许多优点,比如我们手机系统有个地方做了优化,使用OTA技术我们就不用召回每部手机,直接通过云端就可…

Git 学习笔记 | 版本控制和版本控制工具

Git 学习笔记 | 版本控制和版本控制工具 Git 学习笔记 | 版本控制和版本控制工具什么是版本控制?版本管理工具的特性版本管理工具的发展简史主流的版本控制器本地版本控制集中版本控制分布式版本控制 Git与SVN的主要区别 Git 学习笔记 | 版本控制和版本控制工具 学…

HttpClient实现爬虫开发

网络爬虫是一种高效获取网络信息的方式,而HttpClient是一个强大而灵活的Java库,提供了方便的API和丰富的功能,使其成为开发高效且灵活的网络爬虫的理想选择。本文将分享如何利用HttpClient库进行网络爬虫开发,帮助您更好地理解并实…

【计算机网络】因特网中的电子邮件

文章目录 简单邮件传送协议SMTP邮件访问协议POP3IMAPHTTP 参考资料 电子邮件为异步通信媒介 因特网电子邮件系统 电子邮件系统的三个构件:用户代理、邮件服务器、邮件发送和读取协议 用户代理 User Agent 即UA 电子邮件客户端软件,用户与电子邮件系统的接…

林沛满-TCP之在途字节数

本文整理自:《Wireshark网络分析的艺术 第1版》 作者:林沛满 著 出版时间:2016-02 我一直谨记斯蒂芬霍金的金玉良言—每写一道数学公式就会失去一半读者。不过为了深度分析网络包,有时候是不得不计算的,好在小学一年级…

图形学中一些基本知识的总结与复习

前言 在过完games101课程后仍然觉得自己还有许多地方不懂与遗漏,以此来补充与复习一些其中的知识。 参考:Games101、《Unity Shader 入门精要》 GPU渲染流水线(GPU Rendering Pipeline) ----注:Games101课程中所展示渲染流程与书中有所不同&…

javaWeb网上购物系统的设计与实现

摘 要 随着计算机网络技术的飞速发展和人们生活节奏的不断加快,电子商务技术已经逐渐融入了人们的日常生活当中,网上商城作为电子商务最普遍的一种形式,已被大众逐渐接受。因此开发一个网上商城系统,适合当今形势,更加…

详解FreeRTOS:FreeRTOS任务恢复过程源码分析(进阶篇—4)

本篇博文讲解FreeRTOS中任务恢复过程的源代码,帮助各位更好理解恢复任务的原理和流程。 在详解FreeRTOS:FreeRTOS任务管理函数(基础篇—11)中,讲述了任务恢复函数有两个vTaskResume()和xTaskResumeFromISR(),一个是用在任务中的,一个是用在中断中的,但是基本的处理过程…

智慧空调插座:智控生活好伴侣,节能降耗好帮手

所谓“智能插座”,就是在普通插座上增加Wi-Fi模块,通过手机APP控制单个或整个插座的电源通断,并统计一段时间的用电量。 目前市面上所销售的智能插座,大多具备可连接Wi-Fi网路功能,如此一 来便不需要额外再购买定时控…

评价指标篇——IOU(交并比)

什么是IoU(Intersection over Union) IoU是一种测量在特定数据集中检测相应物体准确度的一个标准。 即是产生的候选框(candidate bound)与原标记框(ground truth bound)的交叠率 即它们的交集与并集的比值。最理想情况是完全重叠…

数据中台实战(11)-数据中台的数据安全解决方案

0 微盟删库跑路 除了快、准和省,数据中台须安全,避免“微盟删库跑路”。 2020年2月23日19点,国内最大精准营销服务商微盟出现大面积系统故障,旗下300万商户线上业务全停,商铺后台所有数据被清。始作俑者是一位运维&a…

秒验:可以自定义UI的一键登录服务

一键登录如今成为越来越多移动应用的首选,但千篇一律的登陆界面在引发用户担忧其安全性的同时,也容易让用户在不同APP切换时产生误解。因此,由国内知名移动应用开发服务商MobTech打造的一键登录工具——秒验,通过允许开发者自定义…

C#学习系列相关之多线程(一)----常用多线程方法总结

一、多线程的用途 在介绍多线程的方法之前首先应当知道什么是多线程, 在一个进程内部可以执行多个任务,而这每一个任务我们就可以看成是一个线程。是程序使用CPU的基本单位。进程是拥有资源的基本单位, 线程是CPU调度的基本单位。多线程的作用…

快速掌握批量合并视频

在日常的工作和生活中,我们经常需要对视频进行编辑和处理,而合并视频、添加文案和音频是其中常见的操作。如何快速而简便地完成这些任务呢?今天我们介绍一款强大的视频编辑软件——“固乔智剪软件”,它可以帮助我们轻松实现批量合…

C++深入学习part_1

Linux下编译C程序 安装g命令:sudo apt install g 编译命令:$ g *.cc 或者 *.cpp -o fileName; hellworld 编译程序可以看到: namespace命名空间 首先,命名空间的提出是为了防止变量重名冲突而设置的。 浅浅试一下&#xff1…

深度学习基础之参数量(3)

一般的CNN网络的参数量估计代码 class ResidualBlock(nn.Module):def __init__(self, in_planes, planes, norm_fngroup, stride1):super(ResidualBlock, self).__init__()print(in_planes, planes, norm_fn, stride)self.conv1 nn.Conv2d(in_planes, planes, kernel_size3, …