mysql高频问题记录

1、谈谈mysql的事务隔离级别

事务并发处理可能会带来一些问题,比如:更新丢失、脏读、不可重复读、幻读等。

  • 更新丢失
    多个事务更新同一行记录,产生更新丢失现象。分为两种情况:
    回滚覆盖:一个事务rollback,把其他事务已提交的数据给覆盖了;
    提交覆盖:一个事务commit,把其他事务已提交的数据给覆盖了;
  • 脏读:一个事务读取到了另一个事务修改但未提交的数据;
  • 不可重复读:一个事务中多次读取同一行记录不一致,后面读取的跟前面读取的不一致。
  • 幻读:一个事务中多次按相同条件查询,结果不一致。后续查询的结果和前面查询结果不同,多了或少了几行记录。

为了解决上述事务并发的问题,数据库引入了隔离级别,设置不同隔离级别,可以解决不同问题。

  • 读未提交: Read Uncommitted,解决了回滚覆盖类型的更新丢失,但可能发生脏读现象,也就是可能读取到其他会话中未提交事务修改的数据。
  • 已提交读: Read Committed,只能读取到其他会话中已经提交的数据,解决了脏读,但可能发生不可重复读现象,也就是可能在一个事务中两次查询结果不一致。
  • 可重复读: Repeatable Read,解决了不可重复读,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据记录。不过理论上会出现幻读,简单的说幻读指的的当用户读取某一范围的数据行时,另一个事务又在该范围插入了新行,当用户在读取该范围的数据时会发现有新的幻影行。
  • 可串行化:Serializable,所有的增删改查串行执行。它通过强制事务排序,解决相互冲突,从而解决幻度的问题。这个级别可能导致大量的超时现象的和锁竞争,效率低下。
2、 mysql中分布式ID生成策略有哪些
  • UUID:UUID是通用唯一识别码。

UUID在生成时使用到了以太网卡地址、纳秒级时间、芯片ID码和随机数等信息,目的是让分布式系统中的所有元素都能有唯一的识别信息。使用UUID做主键,可以在本地生成,没有网络消耗,所以生成性能高。但是UUID比较长,没有规律性,耗费存储空间。

  • COMB(UUID变种):解决UUID无序的问题,性能优于UUID
  • SNOWFLAKE:SnowFlake是Twitter开源的分布式ID生成算法,结果是一个long型的ID,能够按照时间有序生成数据库ID表:创建一张表,这张表的ID设置为自动递增,其他地方需要全局唯一ID的时候,就先向这个这张表中模拟插入一条记录,此时ID就会自动递增,然后我们获取刚生成的ID后再进行A1和A2表的插入。
  • Redis生成ID:当使用数据库来生成ID性能不够要求的时候,我们可以尝试使用Redis来生成ID。这主要依赖于Redis是单线程的,所以也可以用生成全局唯一的ID。
3、讲一下MySQL的存储引擎,InnoDB和MyISAM的区别

存储引擎负责MySQL中数据的存储和提取,是与文件打交道的子系统,它是根据MySQL提供的文件访问层抽象接口定制的一种文件访问机制,这种机制就叫作存储引擎。
使用show engines命令,就可以查看当前数据库支持的引擎信息。
在5.5版本之前默认采用MyISAM存储引擎,从5.5开始采用InnoDB存储引擎。

  • InnoDB:支持事务,具有提交,回滚和崩溃恢复能力,事务安全
  • MyISAM:不支持事务和外键,访问速度快

InnoDB和MyISAM是使用MySQL时最常用的两种引擎类型,我们重点来看下两者区别
事务和外键
InnoDB支持事务和外键,具有安全性和完整性,适合大量insert或update操作
MyISAM不支持事务和外键,它提供高速存储和检索,适合大量的select查询操作

  • 锁机制
    InnoDB支持行级锁,锁定指定记彔。基于索引来加锁实现。
    MyISAM支持表级锁,锁定整张表。

  • 索引结构
    InnoDB使用聚集索引(聚簇索引),索引和记彔在一起存储,既缓存索引,也缓存记彔。
    MyISAM使用非聚集索引(非聚簇索引),索引和记彔分开。

  • 并发处理能力
    MyISAM使用表锁,会导致写操作并发率低,读之间并不阻塞,读写阻塞。
    InnoDB读写阻塞可以与隔离级别有关,可以采用多版本并发控制(MVCC)来支持 高并发

  • 存储文件
    InnoDB表对应两个文件,一个.frm表结构文件,一个.ibd数据文件。InnoDB表最大支持64TB;
    MyISAM表对应三个文件,一个.frm表结构文件,一个MYD表数据文件,一个.MYI索引文件。
    从MySQL5.0开始默认限制是256TB。

  • 两种引擎该如何选择?
    是否需要事务?是,InnoDB
    是否存在并发修改?是,InnoDB
    是否追求快速查询,且数据修改少?是,MyISAM
    在绝大多数情况下,推荐使用InnoDB

4、mysql日志系统
  • undo log,事务开始前产生,把要修改的记录放到undo日志里,当事务回滚或数据库崩溃时,可以利用事务对应的undo日志,撤销未提交事务对数据库产生的影响。
  • redo log和binlog
  1. redo log以数据恢复为目的,在数据库发生意外时重现操作。并不是每次事务提交都会立刻持久化到磁盘,而是先记录到redo文件,如果mysql重启,会从redo log恢复。
    如果一不小心执行了drop table ***;或者把库删了,redo log就无能为力了,先别急着跑路,考虑下binlog恢复。
  • binlog日志最重要的两个场景:主从复制和数据恢复。
    • 主从复制:主库开启binlog,默认是关闭的,从库从binlog恢复数据达到主从数据已执行。
    • 数据恢复:通过mysqlbinlog工具恢复数据。
  1. binlog记录的是对数据库的各种修改操作(create/update),用来表示修改操作的数据结构是各种event。
  2. 两者区别
    • redolog是Innodb引擎自带功能,binlog是mysql-server自带功能,并且是以二进制文件记录
    • rodolog记录的是物理日志,记录的更新内容,binlog记录的更新过程;
    • redolog是循环写,日志空间大小是固定的;binlog是追加写入
    • redolog服务器异常宕机后事务数据自动恢复;binlog作为主从复制和数据恢复使用

分布式事务

分布式系统的核心就是处理各种异常情况,这也是分布式系统复杂的地方,所以我们在做分布式系统的时候,最先考虑的就是这种情况。这些异常可能有 机器宕机、网络异常、消息丢失、消息乱序、数据错误、不可靠的TCP、存储数据丢失、其他异常等等。

单个数据库的性能产生瓶颈的时候,我们可能会对数据库进行分区,再想保证集群的ACID几乎是很难达到,CAP定理提出web服务无法同时满足一致性、可用性和分区容错性。
分布式系统中,可用性的重要程序比一致性要高,BASE理论是对CAP定理进行进一步扩充,BASE理论是对CAP中的一致性和可用性进行一个权衡的结果。理论的核心思想就是:我们无法做到强一致,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性(Eventual consistency)。

分布式事务解决方案

1、两阶段提交(2PC):牺牲可用性换取强一致性,不适合高并发高性能场景。
第一阶段是表决阶段,所有参与者都将本事务能否成功的信息反馈发给协调者;第二阶段是执行阶段,协调者根据所有参与者的反馈,通知所有参与者,步调一致地在所有分支上提交或者回滚。
2、补偿事务(TCC):一致性较差,需要程序员写一些补偿代码,一些业务场景下,TCC不好定义和处理。
3、本地事务表(异步确保):基本思路是将本地操作和发送消息放在一个事务中,保证本地操作和消息发送要么两者都成功或者都失败,
避免了分布式事务,实现了最终一致性,但是会把消息表耦合到业务系统,如果没有分装好的解决方案,还有一些杂活要处理。
4、mq事务消息:实现了最终一致性,不需要依赖本地数据库事务。主流mq不支持,rocketmq事务消息部分未开源。
mq事务消息需要考虑的问题:
支付宝向余额宝转账,支付宝扣款后未提交时先发送消息到中间件,中间件不会立即发送,而是等待扣款事务提交成功后收到消息确认发送指令才会发送。
业务与消息解耦:添加一个消息确认系统,定时去支付宝系统查询这个消息的状态,收到确认发送指令后才发送。
消息重复投递即重复消费
事件表+消息队列实现事务最终一致性
解决方法很简单,在余额宝这边增加消息应用状态表(message_apply),通俗来说就是个账本,用于记录消息的消费情况,每次来一个消息,在真正执行之前,先去消息应用状态表中查询一遍,如果找到说明是重复消息,丢弃即可,如果没找到才执行,同时插入到消息应用状态表(同一事务)。

参考:mysql常见面试题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值