MySQL相关问题思考与总结

  1. MySQL问题排查的常用手段有哪些?
  • 使用show processlist命令查看当前所有的数据查询和连接状态,详情请戳
  • 使用explain命令查询SQL语句执行计划,常用于优化复杂的SQL查询,详情请戳。
  • 开启慢查询日志set global slow_query_log=1(默认关闭),查看慢查询的SQL,详情请戳。
  1. 说一下乐观锁和悲观锁?
    基本概念
  • 乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下别人有没有去更新这个数据。通常使用比对版本号的方式实现。
  • 悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想要拿这个数据的时候都会被阻塞,直到锁被释放。

实现方式:

  • 乐观锁:数据库的乐观锁需要自己实现,在表中添加一个version字段,每次修改成功后该值+1,这样每次修改的时候先比对一下,自己拿到的version和数据库当前的version是否一致,如果不一致就放弃修改,这样就实现了乐观锁。

适用场景:

  • 悲观锁:比较适合写入操作比较频繁的场景,如果出现大量的读取操作,每次读取的时候都会进行加锁,这样会增加大量的锁的开销,降低了系统的吞吐量。
  • 乐观锁:比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可能性就会增大,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量的查询操作,降低了系统的吞吐量。
  1. 说一下MySQL的行锁和表锁?
    基本概念:
  • 行级锁:加锁的粒度为单行记录
  • 表级锁:加锁的粒度为整张表

特性对比:

  • 表级锁:开销小,加锁快。锁定粒度大,发生锁冲突的概率高,并发度最低。
  • 行级锁:开销大,加锁慢,会出现死锁。锁粒度小,发生锁冲突的概率小,并发度最高。

引擎实现:

  • MyISAM只支持表锁
  • InnoDB同时支持行锁和表锁,默认为行锁
  1. 说一下MySQL常用的引擎?
  • MyISAM :MySQL5.5版本之前的默认引擎。但是不提供事务支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作时需要锁定整张表,导致效率降低。不过和InnoDB不同的是,MyISAM引擎保存了表的行数,count(*)的执行效率高,无需全表扫描。所以如果表的读操作远远多于写操作,并且不需要事务支持,可以将MyISAM作为数据库引擎的首选。
  • InnoDB:MySQL5.5版本后成为默认引擎。提供了对数据库事务的支持(通过redo log实现),还提供了行级锁和外键的支持。它涉及的而目标就是处理大数据容量的数据库系统。MYSQL运行的时候,InnoDB会在内存中建立缓存池,用于缓冲数据和索引。但是该引擎不支持全文搜索,同时启动也比较慢,不会保存表的行数,count(*)会全表扫描。锁定粒度小,写操作不会锁定全表,所以在并发度较高的场景下使用会提升效率。
  1. 事务的四大特性ACID,事务隔离级别,Spring嵌套事务的实现。
    问题1:
  • 原子性:
  • 一致性:
  • 隔离性:
  • 持久性:

问题2:

  • 未提交读
  • 不可重复读:在同一个事务内,多次读取同一个数据结果却不一样。
  • 可重复读:默认隔离级别。
  • 串行化

问题3:

  • PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务,就加入到这个事务中。这是最常见的选择。
  • PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY:使用当前的事务,如果当前没有事务,就抛出异常。
  • PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
  1. 什么是幻读?如何解决幻读问题?
    含义:

指同一个事务内的多次查询返回的结果不一样。比如同一个事务A第一次查询的时候有n条记录,但是第二次同等条件下的查询却有n+1条记录。这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者修改了第一个事务结果集中的数据,同一个记录的数据内容被修改了,所以数据行的记录就变多或者变少了。

解决方案:

解决方案是加范围锁。

你可能感兴趣的:(MySQL相关问题思考与总结)