专栏持续更新中:MySQL详解

一、业务概念

InnoDB支撑业务,而MyISAM不支撑业务

一个业务是由一条或许多条对数据库操作的SQL句子所组成的一个不可分割的单元,只要当业务中的一切操作都正常履行完了,整个事
务才会被提交给数据库
;假如有部分业务处理失利,那么业务就要回退到开端的状况,因而,业务要么悉数履行成功,要么悉数失利。

所以记住业务的几个基本概念,如下:

  1. 业务是一组SQL句子的履行,要么悉数成功,要么悉数失利,不能出现部分成功,部分失利的成果。确保业务履行的原子性
  2. 业务的一切SQL句子悉数履行成功,才干提交(commit) 业务,把成果写回磁盘
  3. 业务履行过程中,有SQL出现过错,那么业务必需要回滚(rollback) 到开端的状况

比如转账业务需要多条SQL句子共同完结,只要这些SQL都履行成功才算业务成功了

MySQL业务的ACID特性以及并发问题

begin敞开业务,假如这2句SQL都成功了,那么commit提交一个业务

假如其中恣意一条SQL由于停电,或许服务器犯错,导致SQL履行反常,那业务就没有提交,业务会回滚,数据将恢复到业务开端前的状况

这是存储引擎来确保的(redo log和undo log确保的)

MySQL业务的ACID特性以及并发问题

检查当时数据库支撑的存储引擎

show engines;

MySQL业务的ACID特性以及并发问题

数据库引擎能够经过命令暂时修正,或许经过配置文件永久修正

select @@autocommit;

MySQL业务的ACID特性以及并发问题

@autocommit为1表明业务主动提交,为0表明业务手动提交

做业务的时分,咱们一般会在代码上操控这个变量,一般来说,咱们的业务由多条SQL组成,所以咱们设置为手动提交。业务都成功,则提交这个业务;假如业务中间出现失利,就回滚1个业务

MySQL业务的ACID特性以及并发问题

二、ACID特性

每一个业务有必要满意下面的4个特性:

  • 原子性(Atomic):业务是一个不可分割的整体,业务有必要具有原子特性。当修正数据时,要么全履行,要么全不履行,即不答应部分业务完结
  • 一致性(Consistency):业务履行之前和履行之后,数据库数据有必要坚持一致性状况。数据库的一致性状况有必要由用户来负责,由并发操控机制完成。拿银行转账来说,只要让一个用户的余额减少,又让一个用户的余额添加才干构成一个完整的业务
  • 阻隔性(Isolation):当两个或许多个业务并发履行时,为了确保数据的安全性,将一个事物内部的操作与其它业务的操作阻隔起来,不被其它正在履行的业务所看到,使得并发履行的各个业务之间不能相互影响。阻隔等级:数据的安全性和业务的并发性。阻隔越严格,安全性越高,并发性越低(就是并发操控,确保数据安全)
  • 持久性(Durability):业务完结(业务commit成功)今后,DBMS确保它对数据库中的数据的修正是永久性的,即便数据库由于故障犯错,也应该能够恢复数据

InnoDB 引擎经过什么技能来确保业务的这四个特性的呢?

  • 持久性是经过 redo log (重做日志)来确保的
  • 原子性是经过 undo log(回滚日志) 来确保的
  • 阻隔性是经过 MVCC(多版本并发操控) 或锁机制来确保的
  • 一致性则是经过持久性+原子性+阻隔性来确保

DB写数据都是先在cache缓存上写的(由于速度快),然后操作系统经过磁盘I/O往磁盘上写,当业务成功提交后,commit就回来了。然后cache再慢慢往磁盘上写数据,这个过程中假如由于不可抗因素中断了,导致缓存上的数据向磁盘上写的时分没写完,那此刻数据就丢了。系统重启后MySQL数据库会根据redo log来重新履行这个业务并写入缓存,然后写入磁盘,来确保数据库的持久性。由于用户会写很多数据,所以commit不会等着这些数据从缓存悉数写到磁盘再回来,由于要经过磁盘I/O,业务上不可能让用户去等那么长时间

MySQL最重要的是日志,不是数据!

业务的ACD特性由redo log和undo log机制确保,业务的I特性由业务的锁机制来确保,锁粒度越大,业务阻隔性越好,安全性越高,并发性越低,效率越低

三、业务并发存在的问题

业务处理假如不经阻隔,并发履行业务时通常会产生以下问题:

  • 脏读(Dirty Read):一个业务读取了另一个业务未commit的数据(处理了一半的数据) 。例如当业务A和业务B并发履行时,当业务A更新后,业务B查询读取到A尚未提交的数据,此刻假如业务A rollback了,那业务B读到的数据就不是数据库所寄存的数- 据了,而是无效的脏数据(脏读有必要根绝,由于业务没有commit;而不可重复读和幻读不一定出问题,由于业务已经commit
  • 不可重复读(NonRepeatable Read):一个业务的操作导致另一个业务前后两次读取到不同的数据。例如当业务A和业务B并发履行时,当业务B查询读取数据后,业务A update操作更改业务B查询到的数据,此刻业务B再次去读该数据,发现前后两次读的数据不一样(业务B读取了业务A已commit的数据
  • 幻读(Phantom Read):一个业务的操作导致另一个业务前后两次查询的成果数据量不同。例如 当业务A和业务B并发履行时,当业务B查询读取数据后,业务A新增或许删去了一条满意业务B查询条件的记载,此刻业务B再去查询,发现查询到前一次不存在的记载,或许前一次查询的一些记载不见了(业务B读取了业务A新添加的数据或许读不到业务A删去的数据

在有些场景下,不可重复读和幻读一定程度上是能够答应的,不一定非要根绝(经过设置不同的阻隔等级处理),由应用场景需求决定

  • 脏读举例:张三的账户还剩100块,他一起发起两个业务,业务A转账50,业务B购买价格为80的水杯,业务A现对张三的余额减50,然后给另一个人余额加50。由于没有阻隔操控,业务B购买水杯前先读取余额,发现只要50,无法购买茶杯,所以茶杯购买失利。此刻业务A履行反常,将张三的余额回滚为业务履行前的状况,余额为100。当时场景中业务B读到了业务A还没有commit的数据50,产生了脏读,任何业务场景下都有必要根绝
  • 不可重复读举例:首先业务B查询余额,发现为100。业务A完结转账50,而且commit,业务B再次查询余额,发现变成了50,在某些业务场景下是能够答应的,不一定非要根绝
  • 幻读举例:业务B查询年纪为20的人,发现有5个。业务A插入或删去了年纪为20的记载,而且commit,业务B再次查询年纪为20的人,发现已经不是5个人了,幻读也是在某些业务场景下是能够答应的,不一定非要根绝

四、业务相关命令

检查MySQL是否主动提交业务

MySQL业务的ACID特性以及并发问题

1表明主动提交业务,0表明手动提交业务

一般咱们业务上假如要考虑到业务处理,咱们需要设置为手动提交方法,假如一个业务包含多个SQL,若是主动提交方法,一句SQL履行完就主动提交了,后边的SQL如果履行失利就无法正常rollback,无法确保业务的原子特性

MySQL业务的ACID特性以及并发问题

  • BEGIN:敞开一个业务
  • COMMIT:提交一个业务
  • ROLLBACK:回滚一个业务到初始的方位
  • SAVEPOINT point1:设置一个名字为point1的保存点
  • ROLLBACK TO point1:业务只回滚到保存点point1,而不是回滚到初始状况
  • SET TRANSACTION_ISOLATION=‘REPEATABLE-READ’:设置业务的阻隔等级
  • SELECT @@TRANSACTION_ISOLATION:查询业务的阻隔等级