JAVA基础面试题总结(六)——Mysql部分(下)

Mysql缓存

Mysql查询缓存的优缺点

优点:

1、由于查询缓存是基于内存的,直接从内存中返回相应的查询结果,因此减少了大量的磁盘 I/O 和 CPU 计算,导致效率非常高。

缺点:

1、缓存查询需要Hash计算,高并发的时候比较耗时
2、查询缓存的失效问题。如果表的变更比较频繁,则会造成查询缓存的失效率非常高。表的变更不仅仅指表中的数据发生变化,还包括表结构或者索引的任何变化。
3、查询语句不同,但查询结果相同的查询都会被缓存,自愿消耗过大。

简单总结一下查询缓存的适用场景

1、表数据修改不频繁、数据较静态,比如博客系统。

2、查询(Select)重复度高。

3、查询结果集小于 1 MB

Mysql事务

Mysql事务的隔离级别

从SQL 标准定义了四个隔离级别的介绍可以看出,标准的 SQL 隔离级别定义里,REPEATABLE-READ(可重复读)是不可以防止幻读的。
但是!InnoDB 实现的 REPEATABLE-READ 隔离级别其实是可以解决幻读问题发生的,主要有下面两种情况:

快照读:由 MVCC 机制来保证不出现幻读。
当前读:使用 Next-Key Lock 进行加锁来保证不出现幻读,Next-Key Lock 是行锁(Record Lock)和间隙锁(Gap Lock)的结合,行锁只能锁住已经存在的行,为了避免插入新行,需要依赖间隙锁。

因为隔离级别越低,事务请求的锁越少,所以大部分数据库系统的隔离级别都是 READ-COMMITTED ,但是你要知道的是 InnoDB 存储引擎默认使用 REPEATABLE-READ 并不会有任何性能损失。

Mysql锁

什么是意向锁?

之前是事务要加表锁 的时候需要逐行检查当前表中是否有行锁,以避免锁冲突,但效率太低。
引入了意向锁后,别的事务加表锁的时候就不需要进行逐行检查是否加行锁了。直接根据加行锁时给表也加的
意向锁的类型和兼容性来决定,是否可以加表锁。即我们加行锁的同时 ,就会给表加上意向锁。

为什么RC隔离级别仅仅支持行级锁?

RC仅仅支持行级锁,不支持表级锁,因为它允许发生不可重复读和幻读,如果加上表级锁,那么就是可重复读的!

多版本并发控制 (Multi-Version Concurrency Control)

其中mvcc的意思是多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,它的底层实现主要是分为了三个部分,第一个是隐藏字段,第二个是undo log日志,第三个是readView读视图。

InnoDB对MVCC 的实现是怎样的?

MVCC地实现依赖于:隐藏字段、Read View(读视图)、undo log(版本链)

在内部实现中,InnoDB 通过数据行的 DB_TRX_ID(最近修改的事务的ID) 和 Read View(读视图) 来判断数据的可见性,如不可见,则通过数据行的 DB_ROLL_PTR (回滚指针)找到 undo log (版本链)中的历史版本进行读取数据。每个事务读到的数据版本可能是不一样的,在同一个事务中,用户只能看到该事务创建 Read View 之前已经提交的修改和该事务本身做的修改。

undo-log的主要的两个作用?

undo log 主要有两个作用:

  • 当事务回滚时用于将数据恢复到修改前的样子。

  • 另一个作用是 MVCC ,当读取记录时,若该记录被其他事务占用或当前版本对该事务不可见,则可以通过 undo log 读取之前的版本数据,以此实现快照读。

什么是一致性非锁定读和锁定读?

一致性非锁定读就是读取数据的历史版本,也叫作快照读。

锁定读就是读取的是数据的最新版本,这种读也被称为 当前读(current read)。锁定读会对读取到的记录加锁。

快照读和当前读的区别?

快照读是读取历史数据,即基于事务开始时数据库中的状态创建的数据,因此其他并发事务对数据行的修改不会影响当前事务的读取操作,也叫作一致性非锁定读。就是单纯的 SELECT 语句。

当前读:读取的是数据的最新版本,会对读取到的记录加锁,这种读也叫作锁定读。包括对记录的增删改以及加锁方式的select语句。

RC 和 RR 隔离级别下 MVCC 的差异

在 RC 隔离级别下的 每次select 查询前都生成一个Read View。
在 RR 隔离级别下只在事务开始后 第一次select 数据前生成一个Read View。

造成不可重复读和幻读的原因

不同的隔离级别下,生成ReadView的时机不同。
在RC(读已提交)的隔离级别中,在事务的每一次执行快照读的时候生成ReadView,会看到别的事务的提交内容,这就造成了RC的不可重复读。
在RR(可重复读)的隔离级别中,仅在事务第一次执行快照读的时候生成ReadView,因此是可以重复读的,但也造成了幻读现象。

InnoDB如何实现解决幻读的?

可重复读是不可以解决幻读的,但是InnoDB默认的隔离级别是EPEATABLE-READ 可重复读,是可以解决幻读的。

主要是通过 MVCC和 Next-key Lock 来解决幻读问题:

1、执行普通 select时这种快照读的情况下,此时会以 MVCC机制来防止幻读

在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成读视图 Read View ,并使用至事务提交。所以在生成 Read View 之后其它事务所做的更新、插入记录版本对当前事务并不可见,实现了可重复读和防止快照读下的 “幻读”

2、执行 select…for update/lock in share mode、insert、update、delete 等当前读

InnoDB 使用 Next-key Lock来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。只要我不让你插入,就不会发生幻读。

Mysql性能优化

能用 MySQL 直接存储文件(比如图片)吗?

可以是可以,直接存储文件对应的二进制数据即可。不过,还是建议不要在数据库中存储文件,会严重影响数据库性能,消耗过多存储空间。

数据库只存储文件地址信息,文件由文件存储服务负责存储。

什么是执行计划?

执行计划 是指一条 SQL 语句在经过 MySQL 查询优化器 的优化会后,具体的执行方式。

执行计划通常用于 SQL 性能分析、优化等场景。通过 EXPLAIN 的结果,可以获取到执行计划的相关信息。

可以了解到如数据表的查询顺序、数据查询操作的操作类型、哪些索引可以被命中、哪些索引实际会命中、每个数据表有多少行记录被查询等信息。

MySQL 如何存储 IP 地址?

可以将 IP 地址转换成整形数据存储,性能更好,占用空间也更小。

MySQL 提供了两个方法来处理 ip 地址

  • INET_ATON():把 ip 转为无符号整型 (4-8 位)
  • INET_NTOA() :把整型的 ip 转为地址

插入数据前,先用 INET_ATON() 把 ip 地址转为整型,显示数据时,使用 INET_NTOA() 把整型的 ip 地址转为地址显示即可。

自增值保存在哪里?

MyISAM 引擎的自增值保存在数据文件中。

InnoDB 引擎的自增值,其实是保存在了内存里,并没有持久化,如果删除记录后再重启,则会找到自增值的最大值,然后把这个最大值加1作为自增值。到了 MySQL 8.0 版本后,自增值的变更记录被放在了 redo log 中,提供了自增值持久化的能力。这个时候如果发生重启,表的自增值可以根据 redo log 恢复到启前的自增值。

自增值不连续的 4 个场景

1、自增初始值和自增步长设置不为 1

2、唯一键冲突:因为自增值修改的这个操作,是在真正执行插入数据的操作之前,当唯一键冲突的时候,数据插入失败,但是自增值已经加1。

3、事务回滚,事务回滚后,自增值并不会发生回滚。

为什么不把自增值改回去呢?

主要是为了提高性能,如果在回滚事务的时候把自增值也改回去,在多个事务的情况下,就会出现主键冲突。

4、批量插入(如 insert…select 语句),因为每次申请自增id的时候,申请的个数都是上一次的两倍

在这里插入图片描述

为什么不要用字符串存储日期?

  1. 字符串占用的空间更大!
  2. 字符串存储的日期效率比较低(逐个字符进行比对),无法用日期相关的 API 进行计算和比较

Datetime 和 Timestamp 之间的抉择

时区信息
DateTime 类型是没有时区信息的(时区无关),Timestamp 和时区有关。

占用空间
在 MySQL 5.6.4 之前,DateTime 和 Timestamp 的存储空间是固定的,分别为 8 字节和 4 字节。但是从 MySQL 5.6.4 开始,它们的存储空间会根据毫秒精度的不同而变化,DateTime 的范围是 5~8 字节,Timestamp 的范围是 4~7 字节

表示范围
Timestamp 表示的时间范围更小,只能到 2038 年:
DateTime:1000-01-01 00:00:00.000000 ~ 9999-12-31 23:59:59.499999
Timestamp:1970-01-01 00:00:01.000000 ~ 2038-01-19 03:14:07.499999

性能
由于 TIMESTAMP 需要根据时区进行转换,所以从毫秒数转换到 TIMESTAMP 时,不仅要调用一个简单的函数,还要调用操作系统底层的系统函数。这个系统函数为了保证操作系统时区的一致性,需要进行加锁操作,这就降低了效率。

使用时间戳的优缺点:

1、日期排序以及对比等操作的效率会更高,跨系统也很方便。

2、可读性较差。
在这里插入图片描述

Mysql索引

索引的概念

索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。
常见的索引结构有: B 树, B+树 和 Hash、红黑树。

在 MySQL 中,无论是 Innodb 还是 MyIsam,都使用了 B+树作为索引结构。

索引的优缺点

使用索引可以大大加快数据的检索速度,但是创建索引和维护索引需要耗费许多时间,并且索引需要使用物理文件存储,也会耗费一定空间。

B 树& B+树两者有何异同呢?

1、因为B+树的非叶结点只存放索引,而B树的所有结点既存放索引又存放数据,因此在数据量一定的情况下,B+树的高度较小,IO次数比较少。

2、B+树的查找都是到达叶子结点才算查找结束,因此B+树的检索效率比较稳定。

3、B 树的叶子节点都是独立的,B+树的叶子节点有一条指针指向与它相邻的叶子节点,因此更适用于范围查询以及排序。

综上,B+树与 B 树相比,具备更少的 IO 次数、更稳定的查询效率和更适于范围查询这些优势。

InnoDB为什么使用B+树?

B+树与 B 树相比,具备更少的 IO 次数、更稳定的查询效率和更适于范围查询这些优势。

聚簇索引与非聚簇索引

聚簇索引(Clustered Index)即索引结构和数据一起存放的索引,叶子结点保存了行数据。InnoDB 中的主键索引就属于聚簇索引。
优点:查询速度比较快,因为查到了索引就查到了数据
缺点:更新的代价比较大,索引列的数据被修改时,那么对应的索引也将会被修改,而且聚簇索引的叶子节点还存放着数据,修改代价肯定是较大的。

**非聚簇索引(Non-Clustered Index)即索引结构和数据分开存放的索引,叶子结点保存的是对应的主键。**二级索引(辅助索引)就属于非聚簇索引。MySQL 的 MyISAM 引擎,不管主键还是非主键,使用的都是非聚簇索引。

优点:更新的代价比较小。
缺点:可能会造成二次回表查询。

例如下面的语句的执行流程:

在这里插入图片描述

非聚簇索引一定回表查询吗(覆盖索引)?

非聚簇索引不一定回表查询:查询的字段正好是索引的字段,那么直接根据该索引,就可以查到数据了,因此无需回表查询。这种索引也叫作覆盖索引。

覆盖索引

如果一个索引包含(或者说覆盖)所有需要查询的字段的值,我们就称之为 覆盖索引(Covering Index) 。
覆盖索引即需要查询的字段正好是索引的字段,那么直接根据该索引,就可以查到数据了,而无需回表查询。

最左前缀匹配原则

最左前缀匹配原则指的是我们在使用联合索引时,查询会根据联合索引中的从左到右的字段顺序,从左到右依次到查询条件中去匹配。

最左匹配原则顾名思义:最左优先,以最左边的为起点任何连续的索引都能匹配上同时遇到范围查询(>、<、between、like)就会停止匹配

索引下推

索引下推是Mysql5.6后增加的新特性,就是在非聚集索引遍历的过程中,对索引中包含的字段先做判断,过滤掉不符合条件的记录,这样将过滤的工作从server层下推到引擎层利用来实现,从而减少了回表的条数和在server层的一个过滤流程!

比如:当未开启索引下推的时候,我们根据复合索引的第一个字段查询出来的数据会立即返回给server层,然后在server层进行全表扫表进行过滤。当我们开启了索引下推的时候,会直接根据第一个字段在b+树查询出来的记录的基础上,根据第二个字段,直接基于索引进行过滤,然后在回表。

Mysql索引失效的场景有哪些?

1、创建了联合索引,但查询条件未准守最左匹配原则

例子:

-- 联合索引 sname,s_code,address*

1select create_time from student where sname = "变成派大星" *-- 会走索引吗?*   //会

2select create_time from student where s_code = 1  *-- 会走索引吗?*    //不会

3select create_time from student where address = "上海" *-- 会走索引吗?*    //不会

4select create_time from student where address = "上海" and s_code = 1 *-- 会走索引吗?* //不会

5select create_time from student where address = "上海" and sname = "变成派大星" *-- 会走索引吗?*  //会

6select create_time from student where sname = "变成派大星" and address = "上海" *-- 会走索引吗?*     //会,只不过只使用左列的索引,即只使用sname

7select create_time from student where sname = "变成派大星" and s_code = 1 and address = "上海" *-- 会走索引吗?*    //会

最左匹配原则顾名思义:最左优先,以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配

例如:s_code = 2 如果建立(sname, s_code)顺序的索引,是匹配不到(sname, s_code)索引的;

顺序无所谓,因为优化器会自动调整顺序。

总结:

  • 如果 我 where 后面的条件是c = 1 and d = 1为什么不能走索引呢 如果没有 b 的话 你查询的值相当于*11 我们都知道*是所有的意思也就是我能匹配到所有的数据
  • 如果 我 where 后面是b = 1 and d =1 为什么会走索引呢?你等于查询的数据是 1*1我可以通过前面 1 进行索引匹配 所以就可以走索引
  • 最左缀匹配原则的最重要的就是 第一个字段

因此当不符合最左匹配原则的时候,就会索引失效。

2、SELECT * 不会直接导致索引失效(如果不走索引大概率是因为 where 查询范围过大导致的),但它可能会带来一些其他的性能问题比如造成网络传输和数据处理的浪费、无法使用索引覆盖;

3、在索引列上进行计算、函数、类型转换等操作也会导致索引失效,因为索引保存的是索引字段的原始值,并不是计算后的值。

4、以 % 开头的 LIKE 查询比如 LIKE '%abc',因为这个范围非常大 所以没有使用索引的必要了

5、查询条件中使用 OR,且 OR 的前后条件中有一个列没有索引,涉及的索引都不会被使用到。

6、首先使用 In 不是一定会造成全表扫描的 IN 肯定会走索引,但是当 IN 的取值范围较大时会导致索引失效,走全表扫描

7、隐式转换造成索引失效,当操作符左右两边的数据类型不一致时,会发生隐式转换

当 where 查询操作符左边为数值类型时发生了隐式转换,那么对效率影响不大,但还是不推荐这么做。

当 where 查询操作符左边为字符类型时发生了隐式转换,那么会导致索引失效,造成全表扫描效率极低。

正确使用索引的一些建议

1、选择合适的字段创建索引

不为 NULL 的字段:因为对于数据为 NULL 的字段,数据库较难优化。如果字段频繁被查询,但又避免不了为 NULL,建议使用 0,1,true,false 这样语义较为清晰的短值或短字符作为替代。

被频繁查询的字段:我们创建索引的字段应该是查询操作非常频繁的字段。

被作为条件查询的字段:被作为 WHERE 条件查询的字段,应该被考虑建立索引。

频繁需要排序的字段:索引已经排序,这样查询可以利用索引的排序,加快排序查询时间。

被经常频繁用于连接的字段:经常用于连接的字段可能是一些外键列,对于外键列并不一定要建立外键,只是说该列涉及到表与表的关系。对于频繁被连接查询的字段,可以考虑建立索引,提高多表连接查询的效率。

2、被频繁更新的字段应该慎重建立索引

3、限制每张表上的索引数量

索引并不是越多越好,建议单张表索引不超过 5 个

4、尽可能的考虑建立联合索引而不是单列索引

因为索引是需要占用磁盘空间的,使用联合索引将会节省很大的磁盘空间。

5、注意避免冗余索引

冗余索引指的是索引的功能相同,能够命中索引(a, b)就肯定能命中索引(a) ,那么索引(a)就是冗余索引。

6、字符串类型的字段使用前缀索引代替普通索引

7、删除长期未使用的索引

Mysql日志

Mysql中比较重要的日志包括:二进制日志 binlog(归档日志)和 redo log(重做日志)和 undo log(回滚日志)

在这里插入图片描述

redo log 重做日志

重做日志,记录的是事务提交时数据页的物理修改,是用来实现事务的持久性。
该日志文件由两部分组成:重做日志缓冲(redo log buffer)以及重做日志文件(redo log file),前者是在内存中,后者在磁盘中。当事务提交发生错误时, 进行之后会把所有修改信息都存到该日志文件中, 用于在刷新脏页到磁盘,数据恢复使用。

Mysql一开始进行查询数据的时候,会从硬盘把数据加载出来,会放入到缓冲池 Buffer Pool 中。
后续的查询都是先从缓冲池 Buffer Pool 中找,没有命中再去硬盘加载,减少硬盘 IO 开销,提升性能。
更新表数据的时候,也是如此,发现 Buffer Pool 里存在要更新的数据,就直接在 Buffer Pool 里更新。
同时会把“在某个数据页上做了什么修改这样的更新信息,即重做日志”记录到**重做日志缓存(redo log buffer)里,接着刷盘到重做日志文件(redo log)**里。

在这里插入图片描述

刷盘时机

(刷盘:即重做日志redo log从重做日志缓存刷新到重做日志缓存文件中)

1、事务提交:当事务提交时,重做日志缓存redo log buffer 里的 redo log 会被刷新到磁盘。
2、log buffer 空间不足时:重做日志缓存的重做日志已经占满了重做日志缓存总容量的大约一半左右,就需要把这些日志刷新到磁盘上。
3、事务日志缓冲区满:InnoDB 使用一个事务日志缓冲区(transaction log buffer)来暂时存储事务的重做日志条目。当缓冲区满时,会触发日志的刷新,将日志写入磁盘
4、Checkpoint(检查点):InnoDB 定期会执行检查点操作,将内存中的脏数据(已修改但尚未写入磁盘的数据)刷新到磁盘,并且会将相应的重做日志一同刷新,以确保数据的一致性。
5、后台刷新线程:InnoDB 启动了一个后台线程,负责周期性(每隔 1 秒)地将脏页(已修改但尚未写入磁盘的数据页)刷新到磁盘,并将相关的重做日志一同刷新。

6、正常关闭服务器:MySQL 关闭的时候,重做日志redo log 都会刷入到磁盘里去。

另外,InnoDB 存储引擎有一个后台线程,每隔1 秒,就会把 redo log buffer 中的内容写到文件系统缓存(page cache),然后调用 fsync 刷盘。

在这里插入图片描述

也就是说,一个没有提交事务的 redo log 记录,也可能会刷盘。

为什么说一个没有提交事务的 redo log 记录,也可能会刷盘?

1、因为在事务执行过程 redo log 记录是会写入redo log buffer 中,这些 redo log 记录会被后台线程写入到文件系统缓存page cache中,然后刷新到磁盘中。

2、当 redo log buffer 占用的空间即将达到 innodb_log_buffer_size 一半的时候,后台线程会主动刷盘。

只要每次把修改后的数据页直接刷盘不就好了,还有 redo log 什么事?

即:

为什么要使用重做日志(redo log)?

因为数据页大小是16KB,刷盘比较耗时,我们有可能只是修改了其中的几字节数据,没有必要把完整的数据进行刷盘。而且,因为一个数据页对应的位置可能在硬盘文件的随机位置,数据页刷盘是随机写,所以性能很差。而日志文件一行数据占比的空间比较小,而且都是追加的形式,这是一种顺序的磁盘IO,所以性能比较高。

binlog(归档日志)

redo log 它是物理日志,记录内容是“在某个数据页上做了什么修改”,属于 InnoDB 存储引擎。

而 binlog 是逻辑日志,记录内容是语句的原始逻辑,类似于“给 ID=2 这一行的 c 字段加 1”,属于MySQL Server 层。

不管用什么存储引擎,只要发生了表数据更新,都会产生 binlog 日志。

binlog会记录所有涉及更新数据的逻辑操作,并且是顺序写。

记录格式
binlog 日志有三种格式,可以通过binlog_format参数指定。

statement:记录的内容是SQL语句原文。

row:记录的内容不再是简单的SQL语句了,还包含操作的具体数据。但是这种格式,需要更大的容量来记录,比较占用空间,恢复与同步时会更消耗IO资源,影响执行速度。

mixed:是一种折中的方案,MySQL会判断这条SQL语句是否可能引起数据不一致,如果是,就用row格式,否则就用statement格式。

写入机制:
binlog的写入时机也非常简单,事务执行过程中,先把日志写到binlog cache,事务提交的时候,再把binlog cache写到binlog文件中。

因为一个事务的binlog不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为binlog cache。

在这里插入图片描述

上图的 write,是指把日志写入到文件系统的 page cache,并没有把数据持久化到磁盘,所以速度比较快。

上图的 fsync,才是将数据持久化到磁盘的操作。

redo log重做日志和bin log 归档日志的区别?

1、重做日志 是 InnoDB 引擎特有的; 归档日志是 MySQL 的 Server 层实现的,所有引擎都可以使用,MySQL数据库中的任何存储引擎对于数据库的更改都会产生binlog。

2、重做日志是物理日志,记录的是 “ 在某个数据页上做了什么修改 ” ;归档日志是逻辑日志,记录的是这个语句的原始逻辑,比如 “ 给 ID=2 这一行的 c 字段加 1 ”。

binlog 记录的都是事务操作内容,binlog 有三种模式:Statement(基于 SQL 语句的复制)、Row(基于行的复制) 以及 Mixed(混合模式)。具体这三种模式的区别请看主从同步和主备同步专栏。

3、 重做日志是循环写的(类似一个循环队列),因为它的空间固定会用完; 归档日志是可以追加写入的。 “ 追加写 ” 是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

4、重做日志在事务执行过程中可以刷盘写入,而归档日志是在 事务最终提交时才能刷盘写入。

5、虽然它们都属于持久化的保证,但是侧重点不同,redo log(重做日志)让InnoDB存储引擎拥有了崩溃恢复能力,保证了事务的持久性,binlog(归档日志)保证了MySQL集群架构的数据一致性。 redolog相当于是数据修改后,崩溃了,修改的丢失了,所以进行恢复,而binlog可以恢复到特定的位置的数据。

两阶段提交

redo log(重做日志)让InnoDB存储引擎拥有了崩溃恢复能力,即具有持久性。
binlog(归档日志)保证了MySQL集群架构的数据一致性。
虽然它们都属于持久化的保证,但是侧重点不同。
在执行更新语句过程,会记录redo log与binlog两块日志,以基本的事务为单位,redo log在事务执行过程中可以不断写入,而binlog只有在提交事务时才写入,所以redo log与binlog的写入时机不一样。

原理:

重做日志在事务执行过程中可以刷盘写入,而归档日志是在 事务最终提交时才能刷盘写入,为了防止数据不一致的问题,InnoDB存储引擎使用两阶段提交方案。
原理很简单,将重做日志的写入拆成了两个步骤prepare和commit,prepare阶段是在事务执行进行的,而commit是在事务提交时进行的。

当发生异常重启的时候,就会进行判断:

1、判断 redo log 是否完整,如果判断是完整的,就立即提交。

2、如果 redo log 只是预提交但不是 commit 状态,这个时候就会去判断 binlog 是否完整,如果完整就提交 redo log重做日志,然后通过重做日志来恢复数据,不完整就回滚事务。

在这里插入图片描述

undo log 回滚日志

我们知道如果想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚,

**在 MySQL 中,恢复机制是通过 回滚日志(undo log) 实现的,它主要记录的是逻辑日志,所有事务进行的修改都会先记录到这个回滚日志中,然后再执行相关的操作。如果执行过程中遇到异常的话,我们直接利用 回滚日志 中的信息将数据回滚到修改之前的样子即可!**并且,回滚日志会先于数据持久化到磁盘上。这样就保证了即使遇到数据库突然宕机等情况,当用户再次启动数据库的时候,数据库还能够通过查询回滚日志来回滚将之前未完成的事务。

总结

MySQL InnoDB 引擎使用 redo log(重做日志) 保证事务的持久性,使用 undo log(回滚日志) 来保证事务的原子性。

MySQL数据库的数据备份、主备、主主、主从都离不开归档日志binlog,需要依靠binlog来同步数据,保证数据一致性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值