MySQL是怎样运行的
文章平均质量分 85
读《MySQL 是怎样运行的:从根儿上理解 MySQL》有感
会编程的林俊杰
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
归档日志-binlog
MySQL 引入了 binlog 组提交(group commit)机制,当有多个事务提交的时候,会将多个 binlog 刷盘操作合并成一个,从而减少磁盘 I/O 的次数,如果说 10 个事务依次排队刷盘的时间成本是 10,那么将这 10 个事务一次性一起刷盘的时间成本则近似于 1。上面的每个阶段都有一个队列,每个阶段有锁进行保护,因此保证了事务写入的顺序,第一个进入队列的事务会成为 leader,leader领导所在队列的所有事务,全权负责整队的操作,完成后通知队内其他事务操作结束。原创 2025-07-28 20:38:16 · 1152 阅读 · 0 评论 -
回滚日志-undo log
undo log也被称为回滚日志,与redo log(物理日志,记录数据页的修改)不同的是,undo log是一种逻辑日志,用于数据修改的回滚,以此保证事务的原子性。这样,在事务回滚时,我们就可以从undo log中反向读取相应的内容,并进行回滚;另外我们也可以根据undo log中的内容读取到一条被修改后数据的原值。该日志中记录的是数据修改的相反记录,比如:当删除一条记录,日志中会记录一条对应的新增记录。redo log 和 undo log 区别在哪?原创 2025-07-28 20:35:59 · 319 阅读 · 0 评论 -
重做日志-redo log
首先,提出一个问题:redo log是否对其文件大小有限制?若有限制,当超过其限制时,数据库会做出怎样对应的操作?解一:redo log文件的大小InnoDB的redo log是固定大小的,比如可以配置为一组4个文件,每个文件的大小是 1GB,那么这个日志总共就可以记录4GB的操作。并且写redo log是环状写日志的形式,如下图。write pos是当前记录的位置,一边写一边后移。check point是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。原创 2025-07-27 17:09:05 · 654 阅读 · 0 评论 -
MySQL中的锁有哪些
导读:在解决读写冲突产生的问题时,不同的数据库厂商使用的方式也不尽相同,但是大致可分为以下两种方案:方案一:读操作利用多版本并发控制(MVCC),写操作进行加锁。对于读操作,一个查询语句会产生一个 Read View(读视图),在不同的隔离级别下,根据 Read View 找到该事务可以访问的历史版本数据;对于写操作,通过对最新版本的数据进行加锁,只有获取到锁的事务才可以对数据进行修改,避免了脏写问题。原创 2025-07-18 21:05:40 · 804 阅读 · 0 评论 -
搞清MVCC
MVCC,全称 Multi-Version Concurrency Control ,即多版本并发控制,是一种即使不加锁也能够解决并发操作中的读写冲突的并发控制手段,即做到了非阻塞读。其中,不加锁可以大大降低程序开销。补充:读写冲突会造成脏读、幻读、不可重复读。当前读:当前读获取到的记录是最新记录;读取记录时,要对记录进行加锁操作,保证记录不被其他事务所修改。可以看作是悲观锁的一种实现。快照读:快照读可以看作是MVCC的一种实现,主要是为了通过不加锁的方式解决读写冲突。原创 2025-07-17 21:28:19 · 1167 阅读 · 0 评论 -
并发事务~
READ UNCOMMITTED隔离级别下,可能发生脏读、不可重复读和幻读问题。READ COMMITTED隔离级别下,可能发生不可重复读和幻读问题,但是不可以发生脏读问题。REPEATABLE READ隔离级别下,可能发生幻读问题,但是不可以发生脏读和不可重复读的问题。SERIALIZABLE隔离级别下,各种问题都不可以发生。原创 2025-07-17 21:25:16 · 919 阅读 · 0 评论 -
事务~~~
从图中大家也可以看出了,只有当事务处于提交的或者中止的状态时,一个事务的生命周期才算是结束了。对于已经提交的事务来说,该事务对数据库所做的修改将永久生效,对于处于中止状态的事务,该事务对数据库所做的所有修改都会被回滚到没执行该事务之前的状态。C 一致性:事务前后的状态要保持一致,可以理解为数据的一致性。只有保证了原子性、隔离性、持久性才能保证事务的一致性。A 原子性:对数据的一组操作,要么执行成功,要么不执行。I 隔离性:多个事务之间是隔离的,互不影响。原创 2025-07-16 23:19:38 · 215 阅读 · 0 评论 -
Buffer Pool
对于该种场景,InnnDB 设计者们又添加了 innodb_old_blocks_time 这个系统变量,也就是说,从磁盘上被加载到 LRU 链表的 old 区域的某个页来说,如果第一次和最后一次访问该页面的时间间隔小于1s(很明显在一次全表扫描的过程中,多次访问一个页面中的时间不会超过1s),那么该页是不会被加入到young区域的。这样链表尾部的数据就是最近最少使用的数据了,当 Buffer Pool容量不足,或者后台线程主动刷新数据页时,就会优先刷新链表尾部的数据页。原创 2025-07-16 23:17:34 · 1051 阅读 · 0 评论 -
Explain关键字
- 内层 SELECT 是 DERIVED。SELECT 1 FROM orders WHERE user_id = u.id -- 依赖外层 u.id。查询执行计划的标识符,用于表示查询中每个 SELECT 子句的执行顺序和层级关系。-- 内层 SELECT 是 SUBQUERY。优化:为 ORDER BY/GROUP BY 字段添加联合索引。优化:为 ORDER BY 字段添加索引。原创 2025-07-09 23:03:39 · 969 阅读 · 0 评论 -
子查询~~
在一个查询语句里的某个位置也可以有另一个查询语句,这个出现在某个查询语句的某个位置中的查询就被称为子查询。原创 2025-07-09 22:57:04 · 315 阅读 · 0 评论 -
多表查询~
扫描表的过程就是通过磁盘 I/O 将表的数据加载到内存,然后从内存中比较匹配条件是否满足,因此使用嵌套循环连接算法时,可能需要多次磁盘 I/O 读取被驱动表,势必会造成性能上的损耗。而要想减轻这方面的代价,我们可以通过尽量减少访问被驱动表的次数。在 BNL 中,通过加入一块 join buffer 区域,用于存放若干条驱动表的结果集,然后将 join buffer 区域中的记录与被驱动表记录进行匹配,这样的话,就可以使一条被驱动表的记录一次同时与多条驱动表的记录进行匹配(反入为主)。原创 2025-07-07 22:27:52 · 743 阅读 · 0 评论 -
单表查询~
导读在熟悉了 MySQL 中数据的存储细节之后,接下来就该了解其数据查询的那些事儿了。作为用户,在查询数据时,我们只需通过一条 SQL 来声明要查询哪些数据,完全不需要注意 MySQL Server 具体是怎样完成查询的,也就是说我们不看重过程,只看重结果;而对于 MySQL Server,执行一条 SQL 的查询逻辑是较为复杂的,首先 Server 端需与 Client 建立连接,然后 Server 端开始语法解析、查询优化,待查询优化模块生成出一个最优执行计划后,再调用存储引擎执行操作并返回结果。原创 2025-07-07 22:22:59 · 1006 阅读 · 0 评论 -
MySQL的数据目录
根据前面的所学知识,我们知道了InnoDB存储引擎存储数据的数据结构、存储过程,而被组织好的数据则被存储在操作系统的磁盘上,当我们在对表数据进行增删改查时,其实就是InnoDB存储引擎与磁盘的交互。此外,操作系统中对磁盘的管理归属于文件系统,所以我们也可将数据增删改查的过程称为是InnoDB存储引擎与文件系统的交互。之前我们只是通过工具对数据库中的数据进行操作,并没有真正看到过数据库、表等存储文件,接下来我们就来了解一下在文件系统中,MySQL是以什么样的形式对数据进行的存储?保存了哪些数据?原创 2025-07-05 13:51:03 · 865 阅读 · 0 评论 -
最左匹配原则
导读:首先创建一张 test 表,并插入一些数据:`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',其中,test 表中有一个联合索引 idx_abc,其包含索引(a)、索引(ab)、索引(abc)。原创 2025-07-05 13:45:16 · 836 阅读 · 0 评论 -
InnoDB索引
一条条数据存储到页中后,各个数据页组成了一个双向链表,而每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表。此时,如果我想根据主键值查询一条记录,只能从第一个数据页开始一个页一个页地去查询,这种全表搜索方式的效率想想也不会很高,因此 MySQL 选择为每一个存储了用户数据的数据页建立目录,通过目录确定目标数据在哪个页,然后再在目标页中根据 Page Directory (页目录) + 二分法查询目标数据。原创 2025-07-01 23:13:19 · 1141 阅读 · 0 评论 -
InnoDB数据页
首先,在每一个数据页中存在两个虚拟记录,一个代表最小记录,一个代表最大记录,它们被存储在数据页的 Infimum + Supremum 部分。紧接着,当向表中插入一些数据时,这些记录会被存储在数据页中的 User Records 中,这里不仅存储了其真实内容,还有存储了一些额外的数据,比如头信息中的 next_record,通过这个标记加上两个虚拟记录,使得记录形成了一条按照主键值由小到大的顺序的单链表(非插入顺序。原创 2025-07-01 23:06:09 · 843 阅读 · 0 评论 -
InnoDB行格式
从图中可以看出来,对于 Compact 和 Redundant 行格式来说,如果某一列中的数据非常多的话,在本记录的真实数据处只会存储该列的 前768 个字节的数据和一个指向其他页的地址,然后把剩下的数据存放到其他页中,这个过程也叫做行溢出,存储超出 768 字节的那些页面也被称为溢出页。最后需要注意的是,不只是 VARCHAR(M) 类型的列,其他的 TEXT、BLOB 类型的列在存储数据非常多的时候也会发生行溢出。对于这些类型的列,数据是单独存储的,并且通过行中的指针来访问。原创 2025-06-29 19:42:55 · 801 阅读 · 0 评论 -
字符集和比较规则
1、字符集是什么?字符集是一个有限的字符集合,其定义了可以表示的字符的范围,这些字符可以是中文、字母、数字、标点符号、控制字符等。有啥用?通过建立字符串与二进制的映射关系,解决了计算机无法存储字符串的问题(计算机只能存储二进制数据上述提到的,将一个字符映射成一个二进制数据的过程也叫做编码,在这里亦称为"字符编码其中,一种字符集可以有不同的编码方案。比如,Unicode 编码方案包括 UTF-8、UTF-16 和 UTF-32 等。但是,MySQL。原创 2025-06-29 19:39:43 · 956 阅读 · 0 评论 -
MySQL的调控按钮
以本地MySQL服务 MySQL57 为例,通过服务 - MySQL57 - 属性,可看到该服务的可执行文件、配置文件的地址。为了让我们更好的了解服务器程序的运行情况,MySQL服务器程序中维护了好多关于程序运行状态的变量,它们被称为状态变量。因此命令行设置启动选项适合偶尔改动的选项,而对于无需频繁更改的选项配置在文件中将更加方便。),并且同一个启动选项既出现在命令行中,又出现在配置文件中,那么以命令行中的启动选项为准。程序每次启动时都是从配置文件中加载启动选项,而命令行设置启动项只在当次启动有效(原创 2025-06-29 19:37:24 · 894 阅读 · 0 评论 -
MySQL架构理解
MySQL是一个开源的、轻量级的存储数据工具,因其不错的性能广泛被人们使用。原创 2025-06-29 19:32:55 · 323 阅读 · 0 评论
分享