Mysql数据库核心知识有哪些

88次阅读
没有评论

共计 6247 个字符,预计需要花费 16 分钟才能阅读完成。

这篇文章主要为大家展示了“Mysql 数据库核心知识有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让丸趣 TV 小编带领大家一起研究并学习一下“Mysql 数据库核心知识有哪些”这篇文章吧。

一、Mysql 逻辑架构

Mysql 逻辑架构主要分三层:

第一层:负责连接处理,授权认证,安全等等

1、每个客户端连接都会在服务器进程中拥有一个线程,服务器维护了一个线程池,因此不需要为每一个新建的连接创建或者销毁线程;

2、当客户端连接到 Mysql 服务器时,服务器对其进行认证,通过用户名和密码认证,也可以通过 SSL 证书进行认证;

3、一旦客户端连接成功,服务器会继续验证客户端是否具有执行某个特定查询的权限。

第二层:负责编译并优化 SQL

1、这一层包括查询解析,分析,优化,缓存以及所有的的内置函数;

2、对于 SELECT 语句,在解析查询前,服务器会先检查查询缓存,如果能在其中找到对应的查询结果,则无需再进行查询解析、优化等过程,直接返回查询结果;

3、所有跨存储引擎的功能都在这一层实现: 存储过程,触发器,视图。

第三层:是存储引擎

1、存储引擎负责在 MySQL 中存储数据、提取数据;

2、存储引擎通过 API 与上层进行通信,这些 API 屏蔽了不同存储引擎之间的差异,使得这些差异对上层查询过程透明;

3、存储引擎不会去解析 SQL,不同存储引擎之间也不会相互通信,而只是简单地响应上层服务器的请求。

二、主从复制

主从复制原理,简言之,就三步曲:

1、主数据库有个 binlog 二进制文件,纪录了所有增删改 Sql 语句。(binlog 线程)

2、从数据库把主数据库的 binlog 文件的 sql 语句复制过来。(io 线程)

3、从数据库的 relay log 重做日志文件中再执行一次这些 sql 语句。(Sql 执行线程)

三、InnoDB 文件存储结构

从物理意义上讲,InnoDB 表由共享表空间文件 (ibdata1)、独占表空间文件(ibd)、表结构文件(.frm)、以及日志文件(redo 文件等) 组成。

四、表结构文件

在 MYSQL 中建立任何一张数据表,在其数据目录对应的数据库目录下都有对应表的.frm 文件,.frm 文件是用来保存每个数据表的元数据 (meta) 信息,包括表结构的定义等,.frm 文件跟数据库存储引擎无关,也就是任何存储引擎的数据表都必须有.frm 文件。

五、表空间结构

1、表空间(tablespace)

所有数据都放在表空间中。如果开启了 innodb_file_per_table 选项,则 InnoDB 会为每张表开辟一个表空间。但是需要注意的是表空间存放的只是数据、索引和插入缓冲 bitmap 页,其他数据比如 undo 信息,插入缓冲索引页,系统事务信息,二次写缓冲还是会放在原来的共享表空间内。

如果 rollback 后,共享表空间不会自动收缩,但是会判断空间是否需要(比如 undo 空间),如果不需要的话,会将这些空间标记为可用空间,供下次 undo 使用。

2、段(segment)

表空间由各个段组成,比如数据段,索引段,回滚段等。

3、区(extent)

区由连续的页组成,在任何情况下区的大小都是 1M。InnoDB 存储引擎一次从磁盘申请大概 4 - 5 个区(4-5M)。在默认情况下,页的大小为 16KB,即一个区中有大概 64 个连续的页。

4、页(page)

InnoDB 磁盘管理的最小单位。B 树节点 = 一个物理 Page(16K),数据按 16KB 切片为 Page 并编号,编号可映射到物理文件偏移(16K *
N),B+ 树叶子节点前后形成双向链表。Page 分为几种类型,数据页和索引页就是其中最为重要的两种类型。

六、缓冲池

InnoDB 存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理,但是由于 CPU 速度和磁盘速度之间的鸿沟,基于磁盘的数据库系统通常使用缓冲池记录来提高数据库的的整体性能。

在数据库中进行读取操作,首先将从磁盘中读到的页放在缓冲池中,下次再读相同的页中时,首先判断该页是否在缓冲池中。若在缓冲池中,称该页在缓冲池中被命中,直接读取该页。否则,读取磁盘上的页。

七、重做日志

默认情况在数据库数据文件夹下会有两个文件,ib_logfile0/ib_logfile1,
这就是重做日志文件,记录了对于 InnoDB 存储引擎的事务日志。

每个 Innodb 存储引擎至少有 1 个重做日志文件组,每个组至少包含 2 个重做日志文件(ib_logfile0,ib_logfile1)。

可以通过设置多个镜像日志组(mirrored log groups),将不同组放到不同磁盘,提高重做日志的高可用性。

日志组中的文件大小是一致的,以循环的方式运行。文件 1 写满时,切换到文件 2,文件 2 写满时,再次切换到文件 1. 日志组中的文件大小是一致的,以循环的方式运行。文件 1 写满时,切换到文件 2,文件 2 写满时,再次切换到文件 1(从头写入)。

为了保证数据的安全性,事务进行中时会不断的产生 redo log,在事务提交时进行一次 flush 操作,保存到磁盘中, redo
log 是按照顺序写入的,磁盘的顺序读写的速度远大于随机读写。当数据库或主机失效重启时,会根据 redo log 进行数据的恢复,如果 redo
log 中有事务提交,则进行事务提交修改数据。这样实现了事务的原子性、一致性和持久性。

对于写入重写日志文件的操作不是直接写,而是先写入一个重做日志缓冲 (redo lopg buffer) 中,然后按照一定的条件写入日志文件。

当对应事务的脏页写入到磁盘之后,redo log 的使命也就完成了,重做日志占用的空间就可以重用(被覆盖)。

通过 innodb_log_buffer_size 可以配置重写日志缓冲的的大小。

从日志缓冲写入磁盘有两个时间点:

1、主线程每秒都会将重做日志缓冲写入磁盘的重做日志文件,不论事务是否已经提交;

2、另外一个是由参数 innodb_flush_log_at_trx_commit 控制,表示在事务提交时,处理重做日志;

参数 innodb_flush_log_at_trx_commit 可设的值有 0、1、2。0 代表当提交事务时,并不将事务的重做日志写入磁盘上的日志文件,而是等待主线程每秒的刷新。而 1 和 2 不同的地方在于:1 是在 commit 时将重做日志缓冲同步写到磁盘;2 是重做日志异步写到磁盘,即不能完全保证 commit 时肯定会写入重做日志文件,只是有这个动作。

八、回滚日志

除了重做记录 redo log 外,当进行数据修改时还会记录 undo log,undo
log 用于数据的撤回操作,它记录了修改的反向操作,比如,插入对应删除,修改对应修改为原来的数据,通过 undo log 可以实现事务回滚,并且可以根据 undo
log 回溯到某个特定的版本的数据,实现 MVCC,也即非锁定读。

事务开始之前,将当前的版本生成 undo log,undo 也会产生 redo 来保证 undo log 的可靠性,事务提交之后,undo
log 并不能立马被删除,而是放入待清理的链表,由 purge 线程判断是否由其他事务在使用 undo 段中表的上一个事务之前的版本信息,决定是否可以清理 undo
log 的日志空间。

默认情况下 undo 文件是保持在共享表空间的,也即 ibdatafile 文件中,当数据库中发生一些大的事务性操作的时候,要生成大量的 undo 信息,全部保存在共享表空间中的。因此共享表空间可能会变的很大,默认情况下,也就是 undo
日志使用共享表空间的时候,被“撑大”的共享表空间是不会也不能自动收缩的。

九、ACID

ACID 是事务的四大特性。

1、原子性(Atomicity)

一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作,这就是事务的原子性。

2、一致性(Consistency)

数据库总是从一个一致性的状态转换到另一个一致性的状态。

3、隔离性(Isolation)

一个事务所做的修改在最终提交以前,对其他事务是不可见的。

4、持久性(Durability)

一旦事务提交,则其所做的修改不会永久保存到数据库

十、事务的隔离性问题

如果不考虑事务的隔离性,会出现以下问题:

1、脏读

一个事务在更新一条记录,未提交前,第二个事务读到了第一个事务更新后的记录,那么第二个事务就读到了脏数据,会产生对第一个未提交数据的依赖。一旦第一个事务回滚,那么第二个事务读到的数据,将是错误的脏数据。

2、幻读

一个事务按相同的查询条件查询之前检索过的数据,确发现检索出来的结果集条数变多或者减少(由其他事务插入、删除的),类似产生幻觉。

3、不可重复读(虚读)

一个事务在读取某些数据后的一段时间后,再次读取这个数据,发现其读取出来的数据内容已经发生了改变,就是不可重复读。

幻读和不可重复读的区别在于幻读是数据条数发生了变化(插入、删除),而不可冲突读在于数据发生了更新,前后读取的结果不一致。

十一、事务隔离级别

脏读、不可重读度、幻读,其实都是数据库的一致性问题,必须由一定的事务隔离机制来解决,InnoDB 下的事务隔离级别有以下四种:

1、读未提交(Read uncommitted)

一个事务可以读取到另一个事务未提交的修改。这会带来脏读、幻读、不可重复读问题。(基本没用)

2、读已提交(RC, Read Commit)

一个事务只能读取另一个事务已经提交的修改。其避免了脏读,但仍然存在不可重复读和幻读问题。

3、可重复读(RR, Repeatable Read)

同一个事务中多次读取相同的数据返回的结果是一样的。其避免了脏读和不可重复读问题,但幻读依然存在。

4、串行化(Serializable)

事务串行执行。避免了以上所有问题。MySQL 默认的级别是:Repeatable read 可重复读,级别越高,数据越安全,但性能越低。

十二、MVCC

MVCC(Mutil-Version Concurrency
Control),多版本并发控制,是为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值。这是一个可以用来增强并发性的强大的技术,因为这样的一来的话查询就不用等待另一个事务释放锁。

MVCC 的实现是通过保存数据在某个时间点的快照(redo
log)来实现的。这意味着一个事务无论运行多长时间,在同一个事务里能够看到数据一致的视图。根据事务开始的时间不同,同时也意味着在同一个时刻不同事务看到的相同表里的数据可能是不同的。

在每一行数据中额外保存两个隐藏的列:当前行创建时的版本号和删除时的版本号(可能为空)。这里的版本号并不是实际的时间值,而是系统版本号。每开始新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询每行记录的版本号进行比较。

每个事务又有自己的版本号,这样事务内执行 CRUD 操作时,就通过版本号的比较来达到数据版本控制的目的。

默认的隔离级别 (REPEATABLE READ) 下,增删查改变成了这样:

SELECT:读取创建版本小于或等于当前事务版本号,并且删除版本为空或大于当前事务版本号的记录。这样可以保证在读取之前记录是存在的。

INSERT:将当前事务的版本号保存至行的创建版本号

UPDATE:新插入一行,并以当前事务的版本号作为新行的创建版本号,同时将原记录行的删除版本号设置为当前事务版本号

DELETE:将当前事务的版本号保存至行的删除版本号

十三、InnoDB 索引结构

Mysql 索引用的 B + 树作为数据结构;Mysql 中 B +Tree 在经典 B +Tree 的基础上进行了优化,增加了顺序访问指针。在 B +Tree 的每个叶子节点增加一个指向相邻叶子节点的指针,就形成了带有顺序访问指针的 B +Tree。这样就提高了区间访问性能:如果要查询 key 为从 18 到 49 的所有数据记录,当找到 18 后,只需顺着节点和指针顺序遍历就可以一次性访问到所有数据节点,极大提到了区间查询效率(无需返回上层父节点重复遍历查找减少 IO 操作)。

MyISAM InnoDB 都使用 B +Tree 索引结构。但是底层索引存储不同,MyISAM
采用非聚簇索引,而 InnoDB 采用聚簇索引。

聚簇索引:索引 和 数据文件为同一个文件。

非聚簇索引:索引 和 数据文件分开的索引。

MyISAM 索引原理:采用非聚簇索引 -MyISAM
myi 索引文件和 myd 数据文件分离,索引文件仅保存数据记录的指针地址。叶子节点 data 域存储指向数据记录的指针地址。

MyISAM 索引按照 B +Tree 搜索,如果指定的 Key 存在,则取出其 data 域的值,然后以 data 域值 - 数据指针地址去读取相应数据记录。辅助索引和主索引在结构上没有任何区别,只是主索引要求 key 是唯一的,而辅助索引的 key 可以重复。

InnoDB 索引采用聚簇索引,InnoDB 数据 索引文件为一个 idb 文件,表数据文件本身就是主索引,相邻的索引临近存储。
叶节点 data 域保存了完整的数据记录(数据[除主键 id 外其他列 data]+ 主索引[索引 key: 表主键 id])。
叶子节点直接存储数据记录,以主键 id 为 key, 叶子节点中直接存储数据记录。(底层存储结构:** frm - 表定义、ibd:
innoDB 数据 索引文件)

由于 InnoDB 采用聚簇索引结构存储,索引 InnoDB 的数据文件需要按照主键聚集,因此 InnoDB 要求表必须有主键 (MyISAM 可以没有)。如果没有指定 mysql 会自动选择一个可以唯一表示数据记录的列作为主键,如果不存在这样的列,mysql 自动为 InnoDB 表生成一个隐含字段(6 个字节长整型) 作为主键。
InnoDB 的所有辅助索引都引用数据记录的主键作为 data 域。

十四、InnoDB 锁类型

1、加锁机制

乐观锁与悲观锁是两种并发控制的思想,可用于解决丢失更新问题。

2、乐观锁

每次去取数据,都很乐观,觉得不会出现并发问题。因此,访问、处理数据每次都不上锁。但是在更新的时候,再根据版本号或时间戳判断是否有冲突,有则处理,无则提交事务。

3、悲观锁

每次去取数据,很悲观,都觉得会被别人修改,会有并发问题。因此,访问、处理数据前就加排他锁。在整个数据处理过程中锁定数据,事务提交或回滚后才释放锁。

4、锁粒度

表锁:开销小,加锁快; 锁定力度大,发生锁冲突概率高,并发度最低; 不会出现死锁。

行锁:开销大,加锁慢; 会出现死锁; 锁定粒度小,发生锁冲突的概率低,并发度高。

页锁:开销和加锁速度介于表锁和行锁之间; 会出现死锁; 锁定粒度介于表锁和行锁之间,并发度一般。

5、兼容性

01、共享锁

又称读锁(S 锁)。一个事务获取了共享锁,其他事务可以获取共享锁,不能获取排他锁,其他事务可以进行读操作,不能进行写操作。SELECT … LOCK IN
SHARE MODE 显示加共享锁。

02、排他锁

又称写锁(X 锁)。如果事务 T 对数据 A 加上排他锁后,则其他事务不能再对 A 加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。SELECT …
FOR UPDATE 显示添加排他锁。

6、锁模式

记录锁:在行相应的索引记录上的锁,锁定一个行记录。

gap 锁:是在索引记录间歇上的锁, 锁定一个区间。

next-key 锁:是记录锁和在此索引记录之前的 gap 上的锁的结合,锁定行记录 + 区间。

意向锁:是为了支持多种粒度锁同时存在。

以上是“Mysql 数据库核心知识有哪些”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注丸趣 TV 行业资讯频道!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-26发表,共计6247字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)