Mysql支持多种存储引擎。这里记录最常用的InnoDB存储引擎
表空间:一个mysql实例可以对应多个表空间,用于存储记录、索引等数据。(在电脑上就是那个后缀为idb
文件)在Mysql8.0之前,记录文件使用.MYD 后缀,索引文件使用.MYI 后缀,表结构使用.frm 后缀。在Mysql8.0之后,表的记录、索引、表结构都存储在同一个 .ibd 文件中。
段:分为数据段、索引段、回滚段,InnoDB是索引组织表,数据段就是B+树的叶子节点,索引段即为B+树的非叶子节点。段用来管理多个区。
区:表空间的单元结构,每个区的大小为1M。默认情况下,InnoDB存储引擎页大小为16K,即一个区中一共有64个连续的页。
页:是InnoDB存储引擎磁盘管理的最小单元,每个页的大小默认为16KB。为了保证页的连续性,InnoDb存储引擎每次从磁盘申请4-5个区。
行:InnocentDB存储数据是按行进行存放的。
Trx_id:每次对某条记录进行改动时,都会把对应的事务id赋值给trx_id隐藏列。
Rollpointer:每次对某条引记录进行改动时,都会把旧的版本写入到undo日志中,然后这个隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息。
概念:是一组操作的集合,是不可分割的整体,事务会将所有操作一起向系统提交或撤销。这些操作要么同时成功,要么同时失败。
事务的原子性、一致性、持久性的实现原理都是基于
redo log
和undo log
这两个日志来实现的。
事务的隔离性是依托于锁和 MVCC
来实现的。
redo log(重做日志): 它保证了事务的持久性。
记录的是事务提交时数据页的物理修改,是用来实现事务的持久性。
该日志文件由两部分组成︰
如果我们没有重做日志,当将内存中的脏数据刷新到磁盘中时,出现错误。那么就会出现数据的丢失(因为事务已经提交了)
有了重做日志后,提交事务之后,我们会将数据页的变化保存到 redolog buffer。然后将日志刷新到磁盘中,用于在刷新脏数据页到磁盘,发生错误的时候,进行数据恢复使用。
undo log(回滚日志):用于实现事务的原子性。
用于记录数据被修改前的信息,作用包含两个:
undo log和redo log记录物理日志不一样,它是逻辑日志。
例子:
可以认为当delete一条记录的,Undo log中会记录一条对应的insert记录,(就是说,我事务中删除了一个记录,那么当我回滚的时候,需要将其恢复过来,就得使用一个insert语句将其插入)反之亦然,
当update一条记录时,它记录一条对应相反的update记录(update是记录两个操作,一个是删除更改的数据,插入原有的数据)。当执行rollback时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。
Undo log销毁:
undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC。
具体的是:
Undo log存储:
undo log采用段的方式进行管理和记录,存放在前面介绍的 rollback segment 回滚段中,内部包含1024个undo logsegment。
全称 Multi-Version Concurrency Control,
多版本并发控制
。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MCC提供了一个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView。
读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select ... lock in share mode(共享锁),select .. for update、update、insert、delete(排他锁)
都是一种当前读。(在使用锁的场景下,都是当前读)
简单的select(不加锁)就是快照读,快照读读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。
Read Committed
:每次select,都生成一个快照读。Repeatable Read
:开启事务后第一个select语句才是快照读的地方。Serializable
:快照读会退化为当前读。例子:(mysql默认隔离级别下,RR)
例子中,在RR隔离级别下,我们只有事务都提交之后,才能看到他们各自修改的数据。也就是说,在他们自己的事务中,是快照读。
在创建表的时候,InnoDB引擎会给我们表添加三个隐藏字段:
如何查看这个隐藏的字段?
在var/lib/mysql/数据库名称
目录下的找到对应表的ibd文件,使用ibd2sdi 表名.ibd
就可以查看到每个字段,包括隐藏的字段。
不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。
作用:
是快照读SQL执行时MVCC提取数据的依据(判断当前事务读取的是undo log版本链中的哪一条数据),他记录并维护系统当前活跃的事务id。
ReadView的四个核心字段:
不同的隔离级别,生成ReadView的时机不同:
这里我强烈推荐一位大佬的文章:看一遍就理解:MVCC原理详解,看里边的例子就很容易的理解MVCC的工作原理。
如果文章中有描述不准确或者错误的地方,还望指正。您可以留言或者私信我。
最后希望大家多多 关注+点赞+收藏^_^,你们的鼓励是我不断前进的动力!!!
感谢感谢~~~