目录
一、MySQL文件组成
1.1 数据库层面的文件
错误日志文件
慢查询日志
查询日志
二进制日志(binlog)
pid文件
表结构定义文件
1.2 存储引擎层面的文件
表空间文件
重做日志
撤销日志
二、MySQL 单机的二阶段提交
两阶段提交
从概念上说数据库是文件的集合,是依照某种数据模型组织起来并存放于二进制存储器中的数据集合。MySQL 数据库包含多种类型的文件,这些文件存储了数据库的结构、数据、日志和其他系统信息。
一、MySQL文件组成
MySQL 的文件分为数据库层面的文件和存储引擎层面的文件,他们有不同的功能和作用。
1.1 数据库层面的文件
错误日志文件
MySQL 错误日志文件是 MySQL 数据库系统用来记录服务器运行过程中遇到的所有错误、警告和其他重要事件的地方。它是数据库管理员和开发者在排查 MySQL 相关问题时的重要依据,有助于了解和诊断 MySQL 服务器的运行状况。其文件名为 error.log。
慢查询日志
MySQL 的慢查询日志(Slow Query Log)是一个用于记录在 MySQL 服务器上执行时间过长、消耗资源较多的 SQL 查询的特殊日志文件。慢查询日志可以帮助数据库管理员识别并优化那些可能导致数据库性能瓶颈的 SQL 语句,进而提高整个系统的响应速度和吞吐量。
慢查询日志的记录行为可以通过系统变量来配置:
- show_query_log:启用或禁用慢查询日志。
- long_query_time:设置慢查询的阈值,单位是秒。如果一个查询执行时间超过了这个值,那么该查询就会被记录到慢查询日志中。
- log_slow_admin_statements:决定是否记录管理语句(如:ANALYZE、OPTIMIZE)
- log_querys_not_using_indexes:是否记录没有使用到索引的查询
查询日志
MySQL 查询日志(General Query Log)是 MySQL 服务器用来记录所有执行的 SQL 语句及其执行结果的详细日志文件。它可以捕获所有客户端对数据库的连接、断开以及执行的查询语句,无论是成功的查询还是失败的查询,均会被记录下来。
二进制日志(binlog)
二进制日志(bin log)记录了对 MySQL 数据库执行更改的所有操作,但是不包括 select 和show 这类操作,因为这类操作本身并没有修改数据。
二进制日志的几个作用
- 恢复:某些数据的恢复需要二进制日志。如:在一个数据库全备文件恢复后,用户可以通过二进制进行恢复
- 复制:通过复制和执行二进制使一台远程的 MySQL 数据库与一台 MySQL 数据库进行同步(master slave)
- 审计:用户通过二进制日志的信息来进行审计,判断是否有对数据库进行攻击。
二进制日志文件在默认情况下并没有启动,需要手动指定参数来启动。但开启二进制文件会使性能下降1%(官方数据)。
MySQL 的 binlog(二进制日志)有不同的格式,包括Statement、Row和Mixed格式。不同的 binlog 格式在复制和数据恢复过程中可能会带来不同的问题:
- STATEMENT 格式和之前 MySQL 版本一样,二进制文件记录的是逻辑 sql。该格式下主从同步会有问题,如 sql 语句中使用 UUID、NOW 等函数会造成主从数据不一致的情况。
- ROW 格式下二进制日志中记录的不再是简单的 sql 语句,而是记录了表的行更改情况。
- MIXED 格式下,MySQL 默认采用 STATEMENT 格式进二进制日志文件的记录,但在一些情况下会使用 ROW 格式。如使用UUID()等函数。
binlog 的格式可以通过参数 binlog_format 查看。
pid文件
MySQL 的 pid 文件(Process ID file)是一个包含 MySQL 服务器进程ID(PID)的文本文件,它在 MySQL 服务器启动时创建,并在整个服务运行期间存在。这个文件对于 MySQL 的管理和监控至关重要,因为它提供了当前正在运行的 MySQL 服务进程的身份标识,该文件以.pid结尾。
pid 文件的主要用途:
- 进程监控:系统管理员或监控工具可以通过读取pid文件来检查MySQL服务器是否正在运行,以及其进程ID是多少,这对于系统监控和故障排查极为重要。
- 服务管理:在停止或重启MySQL服务时,操作系统服务管理工具(如init.d、systemd等)会根据pid文件来确定要停止或重启的进程。
- 故障恢复:在某些情况下,MySQL服务意外终止,pid文件可以帮助判断服务是否真的已经停止,以及是否需要清理遗留的资源。
- 安全考虑:确保只有一个MySQL服务器实例在运行,防止因多个实例运行而导致的资源冲突或数据混乱。
表结构定义文件
MySQL 的表结构定义文件主要用于存储数据库中表的逻辑结构信息,而不涉及具体的数据内容。在 MySQL 早期版本中,所有的表(无论其使用的存储引擎是什么)都会有一个对应的 .frm
文件,这个文件包含了创建表时定义的所有列信息、索引信息、表选项以及其他元数据。
1.2 存储引擎层面的文件
之前介绍的文件都是 MySQL 数据库本身的文件,和存储引擎无关,除了这些文件,每个存储引擎还有自己独有的文件。和 InnoDB 存储引擎密切相关的文件包括表空间文件、重做日志文件等。
表空间文件
InnoDB 采用将存储引擎的数据按表空间(tablespace)进行存放的设计。在默认配置下会有一个初始大小为10M,名为 ibdata1 的文件。该文件就是默认表空间文件。该文件的大小可以自动增长。
InnoDB 逻辑表空间由段、区、页组成。
表空间由各个段组成,常见的有数据段、索引段、回滚段。数据段即为 B+Tree 的叶子节点,索引段即为 B+Tree 的非索引节点。
区由连续的页组成,在任何情况下每个区的大小都为 1M。在默认情况下,InnoDB 存储引擎页的大小为 16KB,即一个区中一共有 64 个连续的页。
重做日志
在默认情况下,InnoDB 存储引擎的数据目录下会有两个名为 ib_logfile0 和 ib_logfile1 的文件。将其称为 Innodb 存储引擎的重做日志文件。他们记录了 InnoDB 存储引擎的事务日志。
每个 InnoDB 存储引擎至少有一个重做日志文件组,每个文件组下至少有两个重做日志文件,如默认的 ib_logfile0 和 ib_logfile1。可以设置多个镜像日志组。在日志组中每个重做日志的文件大小一致,并以循环写入的方式运行。InnoDB 存储引擎先写重做日志文件1,当达到文件最后时,会切换到重做日志文件2,当文件2满时,再切换到1。
撤销日志
MySQL 的 Undo Log(撤销日志)是 InnoDB 存储引擎用于实现事务回滚和 MVCC(多版本并发控制)的重要机制。在事务处理过程中,每当事务修改了数据,InnoDB 都会在 Undo Log中记录下原始数据的一个版本,以便在事务回滚时能够恢复到修改前的状态。
MVCC 通过 Undo Log 实现多版本并发控制,当用户读取一行记录时,若该记录已经被其他事务占用,当前事务可以通过 undo 读取之前的行版本信息,以此来实现非锁定读取。
二、MySQL 单机的二阶段提交
首先明确一下 binlog 和 redolog 的区别。
- binlog 是 MySQL 数据库的日志记录,所有引擎都会有,而 redolog 重做日志只记录 Innodb 存储引擎本身的事务日志。
- 记录的内容不同,无论用户将 binlog 的格式设置为 STATEMENT、ROW 或者 MIXED,其记录的都是关于一个事务的具体操作,即该日志是逻辑日志。而 Innodb 存储引擎的重做日志记录的是关于每个页更改的物理日志。
- 写入的时间也不同,binlog 文件仅在事务提交前进行提交,即只写磁盘一次,不论这时该事务多大。而在事务的进行过程中却不断有重做日志被写入到重做日志文件中。
两阶段提交
MySQL 中的 redolog 和 binlog 在事务处理过程中,采用两阶段提交(Two-Phase Commit, 2PC)来保证数据的持久性和一致性,尤其是在 InnoDB 存储引擎中。
阶段一:Prepare阶段
- 当事务开始提交时,InnoDB 首先将事务对数据所做的更改写入到 redo log(重做日志)中,并将 redo log 的状态标记为“prepare”。redo log 用于记录数据页的更改操作,能在数据库崩溃后用于恢复数据。
- 同时,MySQL Server 将事务相关的SQL语句记录到 binlog(二进制日志)中。binlog 用于主从复制和数据恢复,记录的是逻辑层面的SQL语句。
阶段二:Commit阶段
- 如果所有数据更改都已经成功写入 redo log 并标记为 prepare,并且 binlog 也已成功写入,则事务可以进入 commit 阶段。
- MySQL 会将 redo log 中的 prepare 状态更改为 commit 状态,这表示事务现在被视为已提交并且对所有后续的数据库恢复操作可见。
- 一旦 redo log 的状态被更新为 commit,事务在数据库中的更改就被视为永久性的,即使在提交后发生系统崩溃,也能在数据库重启时通过 redo log 恢复事务。
往期经典推荐
深度剖析MySQL锁:解开数据库并发控制的神秘面纱-CSDN博客
MySQL为什么会选错索引-CSDN博客
深入JVM内核揭示Java多态背后的神秘机制-CSDN博客
TiDB内核解密:揭秘其底层KV存储引擎如何玩转键值对_tidb 的key value是如何做到的-CSDN博客
决胜高并发战场:Redis并发访问控制与实战解析_redis semaphore实现并发控制-CSDN博客