MySQL文件结构

2020-09-28  本文已影响0人  爱健身的兔子

MySQL数据库各种类型文件,如下所示。

参数文件

当MySQL实例启动时,MySQL会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及指定某些初始化参数,这些参数通常定义了某种内存结构有多大等设置。可以在my.cnf来配置。使用show variables命令查看。

MySQL参数文件中的参数可以分为两类:动态(dynamic)参数和静态(static)参数。动态参数意味着你可以在MySQL实例运行中进行更改;静态参数说明在整个实例生命周期内都不得进行更改,就好像是只读(read only)的。可以通过SET命令对动态的参数值进行修改,SET的语法如下:

SET

| [global | session] system_var_name= expr

| [@@global. | @@session. | @@]system_var_name= expr

这里可以看到global和session关键字,它们表明该参数的修改是基于当前会话还是整个实例的生命周期。有些动态参数只能在会话中进行修改,如autocommit;有些参数修改完后,在整个实例生命周期中都会生效,如binlog_cache_size;而有些参数既可以在会话又可以在整个实例的生命周期内生效,如read_buffer_size。

日志文件

日志文件记录了影响MySQL数据库的各种类型活动。MySQL数据库中常见的日志文件有错误日志、二进制日志、慢查询日志、查询日志。

错误日志

错误日志文件对MySQL的启动、运行、关闭过程进行了记录。M通过show variables like 'log_error'来定位该文件,默认情况下错误文件的文件名为服务器的主机名

慢查询日志

前一小节提到可以通过错误日志得到一些关于数据库优化的信息帮助,而慢查询能为SQL语句的优化带来很好的帮助。可以设一个阈值,将运行时间超过该值的所有SQL语句都记录到慢查询日志文件中。该阈值可以通过参数long_query_time来设置,默认值为10,代表10秒。

默认情况下,MySQL数据库并不启动慢查询日志,你需要手工将这个参数slow_query_log设为ON,然后启动。MySQL数据库会记录运行时间超过该值的所有SQL语句。

另一个和慢查询日志有关的参数是log_queries_not_using_indexes,如果运行的SQL语句没有使用索引,则MySQL数据库同样会将这条SQL语句记录到慢查询日志文件。

MySQL 5.1开始可以将慢查询的日志记录放入一张表中,这使我们的查询更加直观。慢查询表在mysql架构下,名为slow_log。通过参数log_output指定了慢查询输出的格式,默认为FILE,你可以将它设为TABLE,然后就可以查询mysql架构下的slow_log表。

slow_log表使用的是CSV引擎,对大数据量下的查询效率可能不高。我们可以把slow_log表的引擎转换到MyISAM,用来进一步提高查询的效率。将slow_log表的存储引擎更改为MyISAM后,对数据库还是会造成额外的开销。不过好在很多关于慢查询的参数都是动态的,我们可以方便地在线进行设置或者修改。

查询日志

查询日志记录了所有对MySQL数据库请求的信息,不论这些请求是否得到了正确的执行。默认文件名为:主机名.log。

从MySQL 5.1开始,可以将查询日志的记录放入mysql架构下的general_log表,通过general_log参数开启查询日志。

二进制日志

二进制日志记录了对数据库执行更改的所有操作(不包括SELECT和SHOW这类操作),,二进制还包括了执行数据库更改操作的时间和执行时间等信息。二进制日志主要有以下两种作用:

通过配置参数log-bin可以启动二进制日志。默认二进制日志文件名为主机名,后缀名为二进制日志的序列号,所在路径为数据库所在目录(datadir)。

以下配置文件的参数影响着二进制日志记录的信息和行为:

参数max-binlog-size指定了单个二进制日志文件的最大值,如果超过该值,则产生新的二进制日志文件,后缀名+1,并记录到.index文件。

当使用事务的表存储引擎(如InnoDB存储引擎)时,所有未提交(uncommitted)的二进制日志会被记录到一个缓存中,等该事务提交时(committed)时直接将缓冲中的二进制日志写入二进制日志文件,而该缓冲的大小由binlog_cache_size决定,默认大小为32KB。此外,binlog_cache_size是基于会话(session)的,也就是说,当一个线程开始一个事务时,MySQL会自动分配一个大小为binlog_cache_size的缓存,当一个事务的记录大于设定的binlog_cache_size时,MySQL会把缓冲中的日志写入一个临时文件中。通过SHOW GLOBAL STATUS命令查看binlog_cache_use、binlog_cache_disk_use的状态,可以判断当前binlog_cache_size的设置是否合适。Binlog_cache_use记录了使用缓冲写二进制日志的次数,binlog_cache_disk_use记录了使用临时文件写二进制日志的次数。

默认情况下,二进制日志并不是在每次写的时候同步到磁盘(我们可以理解为缓冲写)。因此,当数据库所在操作系统发生宕机时,可能会有最后一部分数据没有写入二进制日志文件中。这会给恢复和复制带来问题。参数sync_binlog=[N]表示每写缓冲多少次就同步到磁盘。如果将N设为1,即sync_binlog=1表示采用同步写磁盘的方式来写二进制日志,这时写操作不使用操作系统的缓冲来写二进制日志。

但是,即使将sync_binlog设为1,还是会有一种情况会导致问题的发生。当使用InnoDB存储引擎时,在一个事务发出COMMIT动作之前,由于sync_binlog设为1,因此会将二进制日志立即写入磁盘。如果这时已经写入了二进制日志,但是提交还没有发生,并且此时发生了宕机,那么在MySQL数据库下次启动时,因为COMMIT操作并没有发生,所以这个事务会被回滚掉。但是二进制日志已经记录了该事务信息,不能被回滚。这个问题可以通过将参数innodb_support_xa设为1来解决,虽然innodb_support_xa与XA事务有关,但它同时也确保了二进制日志和InnoDB存储引擎数据文件的同步。

参数binlog-do-db和binlog-ignore-db(都在参数文件中指定)表示需要写入或者忽略写入哪些库的日志。默认为空,表示需要将所有库的日志同步到二进制日志。

binlog_format参数十分重要,这影响了记录二进制日志的格式。该参数可设的值有STATEMENT、ROW和MIXED。

(1)STATEMENT格式,二进制日志文件记录的是日志的逻辑SQL语句。

(2)在ROW格式下,二进制日志记录的不再是简单的SQL语句了,而是记录表的行更改情况。如果设置了binlog_format为ROW,你可以将InnoDB的事务隔离基本设为READ COMMITTED,以获得更好的并发性。

(3)MIXED格式下,mysql根据执行的写SQL选择ROW还是Statement;

binlog_format是动态参数,可以在数据库运行环境下进行更改。

套接字文件

Unix系统下本地连接MySQL可以采用Unix域套接字方式,这种方式需要一个套接字(socke)文件。套接字文件可由参数socket控制。一般在/tmp目录下,名为mysql.sock。

pid文件

当MySQL实例启动时,会将自己的进程ID写入一个文件中—该文件即为pid文件。该文件可由参数pid_file控制。默认路径位于数据库目录下,文件名为主机名.pid。

表结构定义文件

因为MySQL插件式存储引擎的体系结构的关系,MySQL对于数据的存储是按照表的,所以每个表都会有与之对应的文件。不论采用何种存储引擎,MySQL都有一个以frm为后缀名的文件,这个文件记录了该表的表结构定义。frm还用来存放视图的定义,如我们创建了一个v_a视图,那么对应地会产生一个v_a.frm文件。

InnoDB存储引擎文件

之前介绍的文件都是MySQL数据库本身的文件,和存储引擎无关。除了这些文件外,每个表存储引擎还有其自己独有的文件,包括重做日志文件、表空间文件。

表空间文件

InnoDB存储引擎在存储设计上模仿了Oracle,将存储的数据按表空间进行存放。默认配置下,会有一个初始化大小为10MB、名为ibdata1的文件。该文件就是默认的表空间文件(tablespace file)。你可以通过参数innodb_data_file_path对其进行设置。格式如下:

innodb_data_file_path=datafile_spec1[;datafile_spec2]...
你也可以用多个文件组成一个表空间,同时制定文件的属性,如:
[mysqld]
innodb_data_file_path = /db/ibdata1:2000M;/dr2/db/ibdata2:2000M:autoextend
这里将/db/ibdata1和/dr2/db/ibdata2两个文件用来组成表空间。表示文件idbdata1的大小为2000MB,文件ibdata2的大小为2000MB,但是如果用满了这2000MB后,该文件可以自动增长(autoextend)。
设置innodb_data_file_path参数后,之后对于所有基于InnoDB存储引擎的表的数据都会记录到该文件内。而通过设置参数innodb_file_per_table,我们可以将每个基于InnoDB存储引擎的表单独产生一个表空间,文件名为表名.ibd,这样不用将所有数据都存放于默认的表空间中。这些单独的表空间文件仅存储该表的数据、索引和插入缓冲等信息,其余信息还是存放在默认的表空间中。

InnoDB表存储引擎文件

3.6.2 重做日志文件
默认情况下会有两个文件,名称分别为ib_logfile0和ib_logfile1。它们记录了对于InnoDB存储引擎的事务日志。 重做日志文件的主要目的是,万一实例或者介质失败(media failure),重做日志文件主要用来恢复和保证数据的完整性。 每个InnoDB存储引擎至少有1个重做日志文件组(group),每个文件组下至少有2个重做日志文件,如默认ib_logfile0、ib_logfile1。日志组中每个重做日志文件的大小一致,并以循环方式使用。InnoDB存储引擎先写重做日志文件1,当达到文件的最后时,会切换至重做日志文件2,当重做日志文件2也被写满时,会再切换到重做日志文件1中。

日志文件组

参数innodb_log_file_sizeinnodb_log_files_in_groupinnodb_log_group_home_dir影响着重做日志文件的属性。参数innodb_log_file_size指定了重做日志文件的大小;innodb_log_files_in_group指定了日志文件组中重做日志文件的数量,默认为2;innodb_log_group_home_dir指定了日志文件组所在路径,默认在数据库路径下。

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


写 redo log 过程

主线程中每秒会将重做日志缓冲写入磁盘的重做日志文件中,不论事务是否已经提交。另一个触发这个过程是由参数innodb_ flush_log_at_trx_commit控制,表示在提交(commit)操作时,处理重做日志的方式。

《MySQL技术内幕:InnoDB存储引擎》连载 - 华章图书 - ITeye知识库频道

上一篇下一篇

猜你喜欢

热点阅读