/images/hugo/avatar.png

7 MYSQL 索引

B+树索引

/images/mysql/MySQL45%E8%AE%B2/innodb_index.png

1. InnoDB 的索引模型

实现索引的方式有很多方式,N 叉树由于在读写上的性能优点,以及适配磁盘的访问模式,已经被广泛应用在数据库引擎中了。在 InnoDB 中,表都是根据主键顺序以索引的形式存放的,这种存储方式的表称为索引组织表。InnoDB 使用了 B+ 树索引模型,所以数据都是存储在 B+ 树中的。每一个索引在 InnoDB 里面对应一棵 B+ 树。

6 MySQL 幻读与间隙锁

幻读

1. 幻读

幻读指的是一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。对于幻读需要在注意:

  1. 可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的。而当前读的规则,就是要能读到所有已经提交的记录的最新值。因此,幻读只在当前读”下才会出现。
  2. 修改结果,被之后的 select 语句用“当前读”看到,不能称为幻读。幻读仅专指“新插入的行”

1.1 幻读有什么问题?

没有行锁到底会导致什么问题,我们来看下面这个示例:

5 MYSQL 事务

事务的隔离性和回滚日志

1.事务的隔离性

事务的隔离级别包括:

  1. 读未提交: read uncommitted,一个事务还没提交时,它做的变更就能被别的事务看到
  2. 读提交: read committed,一个事务提交之后,它做的变更才会被其他事务看到
  3. 可重复读: repeatable read,一个事务执行过程中看到的数据,总是跟这个事务在启动时看到的数据是一致的
  4. 串行化: 对于同一行记录,“写”会加“写锁”,“读”会加“读锁”。当出现读写锁冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行(锁是在事务提交之后才释放的)。

在实现上,数据库里面会创建一个视图,访问的时候以视图的逻辑结果为准。

4 MYSQL 锁

全局锁 - 表锁 - 行锁

1. 全局锁

全局锁:

  • 作用: 对整个数据库实例加锁
  • 加锁: Flush tables with read lock
  • 解锁: unlock tables,客户端断开时会自动释放锁
  • 场景: 全库逻辑备份,即把整库每个表都 select 出来存成文本
  • 加锁范围: 数据更新语句(数据的增删改)、数据定义语句(包括建表、修改表结构等)和更新类事务的提交语句都会被阻塞

做全库备份时,对于 Innodb,通过可重复度隔离级别我们就可以获取数据库的一致视图,但是对 于MyISAM 这些不支持事务的存储引擎,只能使用 Flush tables with read lock 让整个库处于只读状态。

3 Innodb 表空间回收

我的数据库占用空间太大,我把一个最大的表删掉了一半的数据,怎么表文件的大小还是没变?

1.innodb_file_per_table

一个 InnoDB 表包含两部分,即:表结构定义和数据。在 MySQL 8.0 版本以前,表结构是存在以.frm 为后缀的文件里。而 MySQL 8.0 版本,则已经允许把表结构定义放在系统数据表中了。

2 MySQL 如何保证数据不丢失

redo log,bin log 的写入流程

前面我们介绍了 WAL 机制,得到的结论是:只要 redo log 和 binlog 保证持久化到磁盘,就能确保 MySQL 异常重启后,数据可以恢复。今天,我们就再一起看看 MySQL 写入 binlog 和 redo log 的流程,看看 MySQL 是如何保证数据不丢失的。