MYSQL术语部分讲解
一.InnoDB 引擎
1.redo log日志
当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log(持久化)里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做。
InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB,那么总共就可以记录 4GB 的操作。从头开始写,写到末尾就又回到开头循环写,如下面这个图所示。
write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。
write pos 和 checkpoint 之间是还空着的部分,可以用来记录新的操作。如果 write pos 追上 checkpoint,表示空间满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下。
有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash-safe。
而这整个过程就是MySQL 里经常说到的 WAL 技术。
2.WAL
WAL 的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘。
如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高。这就是WAL技术的出现原因。
3.事务
简单来说,事务就是要保证一组数据库操作,要么全部成功,要么全部失败。
4.索引
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
简单来讲索引类似与字典的目录一样。
5.undo log
字面理解为撤销日志。用于事务间的可见性操作。
在我理解看来,一个事务可以看到的数据是什么,为了满足事务的隔离性而引入,通过他我们可以在不同的隔离级别看到同一数据的不同数值。
如下图所示:
不同事务隔离级别中,同一事务可看到的视图可能不同,那么如果在可重复读隔离级别中只能看到read-view A,但是我们的数据此时视图已经为read-view C,那么我们当前可看到的视图即为当前视图与undo log回滚日志得到的。
6.trx_id
事务id,InnoDB 内部维护了一个 max_trx_id 全局变量,每次需要申请一个新的 trx_id 时,就获得 max_trx_id 的当前值,然后并将 max_trx_id 加 1。对于正在执行的事务,你可以从 information_schema.innodb_trx 表中看到事务的 trx_id。
7.row_id
如果创建的 InnoDB 表没有指定主键,那么 InnoDB 会给你创建一个不可见的,长度为 6 个字节的 row_id。InnoDB 维护了一个全局的 dict_sys.row_id 值,所有无主键的 InnoDB 表,每插入一行数据,都将当前的 dict_sys.row_id 值作为要插入数据的 row_id,然后把 dict_sys.row_id 的值加 1。如果row_id自增到达上限后,会重新开始计数,在我们的表上面表示的就是覆盖了之前的数据,所以我们需要在我们建立的表上显示加上主键,以免通过row_id覆盖数据,表现出数据丢失的严重后果。
二.Server层
1.binlog日志
binlog 是逻辑日志,记录的是一个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
2.Xid
redo log 和 binlog 相配合的时候,它们有一个共同的字段叫作 Xid。它在 MySQL 中是用来对应事务的。在一个事务中,两阶段提交中redo log 和 binlog通过Xid确认彼此。并且Xid是Server层维护的。
3.thread_id
thread_id 的逻辑很好理解:系统保存了一个全局变量 thread_id_counter,每新建一个连接,就将 thread_id_counter 赋值给这个新连接的线程变量。thread_id_counter 定义的大小是 4 个字节,因此达到 2的32次方-1 后,它就会重置为 0,然后继续增加。