码迷,mamicode.com
首页 > 数据库 > 详细

Mysql相关面试题目

时间:2020-03-18 11:29:22      阅读:71      评论:0      收藏:0      [点我收藏+]

标签:事务   ODB   内存   效率   ati   用户   执行   事务隔离   支持   

一、事务的四大特性:

  1)原子性(Atomicity):不可分割的操作单元,事务中所有操作,要么全部成功;要么撤回到执行事务之前的状态

  2)一致性(Consistency):

  3)隔离性(Isolation):事务操作之间彼此之间相互独立和透明互不影响。事务的独立运行,通常需要用锁来实现。一个事务处理的后果,如果影响了其他事务,那么其他事务就会撤回。事务的100%隔离,需要牺牲速度

  4)持久性(Durability):

  对于事务的ACID四大特性的理解,以从A账户转账50元到B账户为例进行说明

  1、根据定义,原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做。即要么转账成功,要么转账失败,是不存在中间的状态!

        如果无法保证原子性会怎么样?OK,就会出现数据不一致的情形,A账户减去50元,而B账户增加50元操作失败。系统将无故丢失50元。·

  2、隔离性是指多个事务并发执行的时候,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。如果无法保证隔离性会怎么样?

            OK,假设A账户有200元,B账户0元。A账户往B账户转账两次,金额为50元,分别在两个事务中执行。如果无法保证隔离性,会出现下面的情形技术图片

 

 

 

     如图所示,如果不保证隔离性,A扣款两次,而B只加款一次,凭空消失了50元,依然出现了数据不一致的情形!  

  3、持久性是指事务一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响

       如果无法保证持久性会怎么样?在Mysql中,为了解决CPU和磁盘速度不一致问题,Mysql是将磁盘上的数据加载到内存,对内存进行操作,然后再回写磁盘。好,假设此时宕机了,在内存中修改的数据全部丢失了,持久性就无法保证。

            设想一下,系统提示你转账成功。但是你发现金额没有发生任何改变,此时数据出现了不合法的数据状态,我们将这种状态认为是数据不一致的情形。     

       4、根据定义,一致性是指事务执行前后,数据处于一种合法的状态,这种状态是语义上的而不是语法上的。

    那什么是合法的数据状态呢?这个状态是满足预定的约束就叫做合法的状态,再通俗一点,这状态是由你自己来定义的。满足这个状态,数据就是一致  的,不满足这个状态,数据就是不一致的!

      如果无法保证一致性会怎么样?

   例一:A账户有200元,转账300元出去,此时A账户余额为-100元。你自然就发现了此时数据是不一致的,为什么呢?因为你定义了一个状态,余额这列必须大于0。

           例二:A账户200元,转账50元给B账户,A账户的钱扣了,但是B账户因为各种意外,余额并没有增加。你也知道此时数据是不一致的,为什么呢?因为你定义了一个状态,要求A+B的余额必须不变。

 

二、mysql 如何保证事务的四大特性?

  1)如何保证事务的原子性:利用innodb引擎的undo  log(回滚日志)

    回滚日志是实现事务的原子性的关键,它记录了如以下的信息:

    当delete操作时,记录了这条数据;当update操作时,记录了这条数据之前的旧值;当insert操作时记录了这条新数据的iD;

   当事务执行失败 或者调用了 rollback,导致事务需要回滚,就会根据这些信息将数据还原成之前的样子

  2)如何保证事务的持久性:利用innodb引擎的redo  log

  Mysql是先把磁盘上的数据加载到内存中,在内存中对数据进行修改,再刷回磁盘上。如果此时突然宕机,内存中的数据就会丢失。 怎么解决这个问题? 简单啊,事务提交前直接把数据写入磁盘就行啊。 这么做有什么问题?

  • 只修改一个页面里的一个字节,就要将整个页面刷入磁盘,太浪费资源了。毕竟一个页面16kb大小,你只改其中一点点东西,就要将16kb的内容刷入磁盘,听着也不合理。
  • 毕竟一个事务里的SQL可能牵涉到多个数据页的修改,而这些数据页可能不是相邻的,也就是属于随机IO。显然操作随机IO,速度会比较慢。

  于是,决定采用redo log解决上面的问题。当做数据修改的时候,不仅在内存中操作,还会在redo log中记录这次操作。当事务提交的时候,会将redo log日志进行刷盘(redo log一部分在内存中,一部分在磁盘上)。当数据库宕机重启的时候,会将redo log中的内容恢复到数据库中,再根据undo log和binlog内容决定回滚数据还是提交数据。采用redo log的好处? 其实好处就是将redo log进行刷盘比对数据页刷盘效率高,具体表现如下

  • redo log体积小,毕竟只记录了哪一页修改了啥,因此体积小,刷盘快。
  • redo log是一直往末尾进行追加,属于顺序IO。效率显然比随机IO来的快

  3)如何保证事务的隔离性:利用的是锁和MVCC机制

  4)如何保证事务的一致性:

   从数据库层面,数据库通过原子性、隔离性、持久性来保证一致性。也就是说ACID四大特性之中,C(一致性)是目的,A(原子性)、I(隔离性)、D(持久性)是手段,是为了保证一致性,数据库提供的手段。数据库必须要实现AID三大特性,才有可能实现一致性。例如,原子性无法保证,显然一致性也无法保证。

     如果你在事务里故意写出违反约束的代码,一致性还是无法保证的。例如,你在转账的例子中,你的代码里故意不给B账户加钱,那一致性还是无法保证。因此,还必须从应用层角度考虑。从应用层面,通过代码判断数据库数据是否有效,然后决定回滚还是提交数据!

三、mysql 的隔离级别?

  1)Read Uncommitted(读取未提交内容)

  在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

  2)Read Committed(读取提交内容)

  这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

  3)Repeatable Read(可重读)

  这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

  4)Serializable(可串行化)

  这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。

  技术图片

 

   参考:https://www.jianshu.com/p/75187e19faf2

四、mysql 的引擎?

Mysql相关面试题目

标签:事务   ODB   内存   效率   ati   用户   执行   事务隔离   支持   

原文地址:https://www.cnblogs.com/nlqt/p/12516026.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!