diff --git a/mysql/mysql文档/mysql_文件.md b/mysql/mysql文档/mysql_文件.md index 996dfeb..bc1bcb1 100644 --- a/mysql/mysql文档/mysql_文件.md +++ b/mysql/mysql文档/mysql_文件.md @@ -218,3 +218,111 @@ binlog为动态参数,可以在数据库运行时进行修改,并且可以 ```bash mysqlbinlog --start-position=203 ${binlog_path} ``` + +## pid文件 +mysql实例启动时,会将进程id写入到一个文件中,该文件被称为pid文件。 + +pid文件路径通过`pid_file`参数来进行控制,fedora中默认路径为`/run/mysqld/mysqld.pid`。 + +## 表结构定义文件 +mysql中数据的存储是根据表进行的,每个表都有与之对应的文件。无论表采用何种存储引擎,都会存在一个以`frm`为后缀的文件,该文件中保存了该表的表结构定义。 + +> mysql 8中,schema对应目录下不再包含frm文件。 + +## 表空间文件 +innodb采用将存储的数据按照表空间(tablespace)进行存放的设计。在默认配置下,将会有一个初始大小为10MB,名称为ibdata1的文件,该文件为默认的表空间文件。 + +### innodb_data_file_path +可以通过`innodb_data_file_path`参数对默认表空间文件进行设置,示例如下: +```sql +innodb_data_file_path=datafile_spec1[;datafile_spec2]... +``` +用户可以通过多个文件组成一个表空间,示例如下: +```sql +innodb_data_file_path=/db/ibdata1:2000M;/dr2/db/ibdata2:2000M;autoextend +``` +在上述配置中,表空间由`/db/ibdata1`和`/dr2/db/ibdata2`两个文件组成,如果两个文件位于不同的磁盘上,那么磁盘的负载将会被平均,数据库的整体性能将会被提高。 + +同时,在上述示例中,为两个文件都指定了后续属性,含义如下: +- ibdata1:文件大小为2000M +- ibdata2:文件大小为2000M,并且当文件大小被用完后,文件会自动增长 + +当`innodb_data_file_path`被设置后,所有基于innodb存储引擎的表,其数据都会记录到该共享表空间中。 + +### innodb_file_per_table +如果`innodb_file_per_table`被启用后(默认启用),则每个基于innodb存储引擎的表都可以有一个独立的表空间,独立表空间的命名规则为`表名+.ibd`。 + +通过innodb_file_per_table,用户不需要将所有的数据都放置在默认的表空间中。 + +> `innodb_file_per_table`所产生的独立表空间文件,其仅存储该表的数据、索引和插入缓冲BITMAP信息,其余信息仍然存放在默认的表空间中。 + +## redo log文件 +redo log是一个基于磁盘的数据结构,用于在crash recovery过程中纠正由`未完成事务写入的错误数据`。 + +> 在一般操作中,redo log对那些`会造成表数据发生改变的请求`进行encode操作,请求通常由sql statement或地级别api发起。 + +redo log通常代表磁盘上的redo log file。写入重做日志文件的数据通常基于受影响的记录进行编码。在数据被写入到redo log file中时,LSN值也会不断增加。 + +### 循环写入 +innodb会按顺序写入redo log文件,例如redo log file group中存在两个文件,innodb会先写文件1,文件1写满后会切换文件2,在文件2写满后,重新切换到文件1。 + +### redo log capacity +从mysql 8.0.30开始,`innodb_redo_log_capacity`参数用于控制redo log file占用磁盘空间的大小。该参数可以在实例启动时进行设置,也可以通过`set global`来进行设置。 + +`innodb_redo_log_capacity`默认值为`104857600`,即`100M`。 + +redo log文件默认位于`datadir`路径下的`#innodb_redo`目录下。innodb会尝试维护32个redo log file,每个redo log file文件大小都相同,为`1/32 * innodb_redo_log_capacity`。 + +redo log file将会使用`#ib_redoN`的命名方式,`N`是redo log file number。 + +innodb redo log file分为如下两种: +- ordinary:正在被使用的redo log file +- spare:等待被使用的redo log file + +> 相比于ordinary redo log file,spare redo log file的名称中还包含了`_tmp`后缀 + +每个oridnary redo log file都关联了一个制定的LSN范围,可以通过查询`performance_schema.innodb_redo_log_files`表里获取LSN范围。 + +示例如下: +```sql +select file_name, start_lsn, end_lsn from performance_schema.innodb_redo_log_files; +``` +查询结果示例如下: +| file\_name | start\_lsn | end\_lsn | +| :--- | :--- | :--- | +| ./#innodb\_redo/#ib\_redo6 | 19656704 | 22931456 | + +当执行checkpoint时,innodb会将checkpoint LSN存储在文件的header中,在recovery过程中,所有的redo log文件都将被检查,并且基于最大的LSN来执行恢复操作。 + +常用的redo log状态如下 +```bash + # resize operation status + Innodb_redo_log_resize_status + # 当前redo log capacity + Innodb_redo_log_capacity_resized + Innodb_redo_log_checkpoint_lsn + Innodb_redo_log_current_lsn + Innodb_redo_log_flushed_to_disk_lsn + Innodb_redo_log_logical_size + Innodb_redo_log_physical_size + Innodb_redo_log_read_only + Innodb_redo_log_uuid +``` +> 重做日志大小设置时,如果设置大小过大,那么在执行恢复操作时,可能需要花费很长时间;如果重做日志文件大小设置过小,可能会导致事务的日志需要多次切换重做日志文件。 +> +> 此外,重做日志太小会频繁发生async checkpoint,导致性能抖动。重做日志存在一个capacity,代表了最后的checkpoint不能够超过这个阈值,如果超过必须将缓冲区中的部分脏页刷新到磁盘中,此时可能会造成用户线程的阻塞。 + +### redo log和binlog的区别 +#### 记录内容 +binlog记录的是一个事务的具体操作内容,该日志为逻辑日志。 + +而innodb redo log记录的是关于某个页的修改,为物理日志。 + +#### 写入时机 +binlog仅当事务提交前才进行提交,即只会写磁盘一次。 + +redo log则是在事务运行过程中,不断有重做日志被写入到redo log file中。 + +### redo log写入时机 +- master thread会每秒将redo log从buffer中刷新到redo log ile中,不露内事务是否已经提交 +- innodb_flush_log_at_trx_commit控制redo log的刷新时机,默认情况下,在事务提交前会将数据从redo log buffer刷新到redo log file中 \ No newline at end of file