MySql学习(二)MySql物理结构

MySql的物理结构

  1. MySQL是通过文件系统对数据和索引进行存储的。
  2. MySQL从物理结构上可以分为日志文件和数据索引文件。
  3. MySQL在Linux中的数据索引文件和日志文件都在/var/lib/mysql目录下。
  4. 日志文件采用顺序IO方式存储、数据文件采用随机IO方式存储。

日志文件

日志文件分为

  1. 错误日志(errorlog)
  2. 二进制日志(bin log)
  3. 通用查询日志(general query log)
  4. 慢查询日志(slow query log)
  5. 重做日志(redo log)
  6. 回滚日志(undo log)
  7. 中继日志(replay log)

错误日志(errorlog)

默认是开启的,而且从5.5.7以后无法关闭错误日志,错误日志记录了运行过程中遇到的所有严重的错误
信息,以及 MySQL每次启动和关闭的详细信息。

二进制日志(bin log)

MySQL的二进制日志(binary log)是一个二进制文件,主要用于记录修改数据或有可能引起数据变更的MySQL语句。二进制日志(binary log)中记录了对MySQL数据库执行更改的所有操作,并且记录了语句发生时间、执行时长、操作数据等其它额外信息,但是它不记录SELECT、SHOW等那些不修改数据的SQL语句。二进制日志(binary log)主要用于数据库恢复和主从复制,以及审计(audit)操作。

二进制日志开启方法

查看系统变量log_bin,如果其值为OFF,表示没有开启二进制日志(binary log)

mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | OFF   |
+---------------+-------+
1 row in set (0.00 sec)

开启需要修改mysql.cnf,在[mysqld]下面增加log_bin=mysql_bin_log不添加路径只有文件名默认在datadir中。

通用查询日志(general query log)

记录建立的客户端连接和执行的所有语句。这种比较消耗资源,且没有什么价值,不建议开启。

通用查询日志开启方法

 log_output=[none|file|table|file,table]  #通用查询日志输出格式
 general_log=[on|off]                     #是否启用通用查询日志
 general_log_file[=filename]              #通用查询日志位置及名字

慢查询日志(slow query log)

MySQL 慢查询日志是排查问题 SQL 语句,以及检查当前 MySQL 性能的一个重要功能。记录的是超过预设置秒数的查询日志信息。

查看是否开启慢查询功能

mysql> show variables like 'slow_query%';
+---------------------+------------------------------------+
| Variable_name       | Value                              |
+---------------------+------------------------------------+
| slow_query_log      | OFF                                |
| slow_query_log_file | /var/lib/mysql/instance-1-slow.log |
+---------------------+------------------------------------+
2 rows in set (0.01 sec)
mysql> show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.00 sec)

slow_query_log 慢查询开启状态
slow_query_log_file 慢查询日志存放的位置(这个目录需要MySQL的运行帐号的可写权限,一般设置为MySQL的数据存放目录)
long_query_time 查询超过多少秒才记录

开启慢查询功能

修改mysql.cnf

[mysqld]
slow_query_log = ON #代表是否开启
slow_query_log_file = /var/lib/mysql/instance-1-slow.log #日志文件存放位置
long_query_time = 2 #超过多少秒才进行记录

重做日志(redo log)

作用:

确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。

内容:

物理格式的日志,记录的是物理数据页面的修改的信息,其redo log是顺序写入redo log file的物理文件中去的。

什么时候产生:

事务开始之后就产生redo log,redo log的落盘并不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入redo log文件中。

什么时候释放:

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

对应的物理文件:

默认情况下,对应的物理文件位于数据库的data目录下的ib_logfile1&ib_logfile2

innodb_log_group_home_dir 指定日志文件组所在的路径,默认./ ,表示在数据库的数据目录下。

innodb_log_files_in_group 指定重做日志文件组中文件的数量,默认2

关于文件的大小和数量,由以下两个参数配置:

innodb_log_file_size 重做日志文件的大小。

innodb_mirrored_log_groups 指定了日志镜像文件组的数量,默认1

其他:

很重要一点,redo log是什么时候写盘的?前面说了是在事物开始之后逐步写盘的。

之所以说重做日志是在事务开始之后逐步写入重做日志文件,而不一定是事务提交才写入重做日志缓存,原因就是,重做日志有一个缓存区Innodb_log_buffer,Innodb_log_buffer的默认大小为8M(这里设置的16M),Innodb存储引擎先将重做日志写入innodb_log_buffer中。

然后会通过以下三种方式将innodb日志缓冲区的日志刷新到磁盘

Master Thread 每秒一次执行刷新Innodb_log_buffer到重做日志文件。

每个事务提交时会将重做日志刷新到重做日志文件。

当重做日志缓存可用空间 少于一半时,重做日志缓存被刷新到重做日志文件

由此可以看出,重做日志通过不止一种方式写入到磁盘,尤其是对于第一种方式,Innodb_log_buffer到重做日志文件是Master Thread线程的定时任务。

因此重做日志的写盘,并不一定是随着事务的提交才写入重做日志文件的,而是随着事务的开始,逐步开始的。

另外引用《MySQL技术内幕 Innodb 存储引擎》(page37)上的原话:

即使某个事务还没有提交,Innodb存储引擎仍然每秒会将重做日志缓存刷新到重做日志文件。

这一点是必须要知道的,因为这可以很好地解释再大的事务的提交(commit)的时间也是很短暂的。

回滚日志(undo log)

作用:

保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读

内容:

逻辑格式的日志,在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,这一点是不同于redo log的。

什么时候产生:

事务开始之前,将当前是的版本生成undo log,undo 也会产生 redo 来保证undo log的可靠性

什么时候释放:

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

对应的物理文件:

MySQL5.6之前,undo表空间位于共享表空间的回滚段中,共享表空间的默认的名称是ibdata,位于数据文件目录中。

MySQL5.6之后,undo表空间可以配置成独立的文件,但是提前需要在配置文件中配置,完成数据库初始化后生效且不可改变undo log文件的个数

如果初始化数据库之前没有进行相关配置,那么就无法配置成独立的表空间了。

关于MySQL5.7之后的独立undo 表空间配置参数如下:

innodb_undo_directory = /data/undospace/ –undo独立表空间的存放目录

innodb_undo_logs = 128 –回滚段为128KB

innodb_undo_tablespaces = 4 –指定有4个undo log文件

如果undo使用的共享表空间,这个共享表空间中又不仅仅是存储了undo的信息,共享表空间的默认为与MySQL的数据目录下面,其属性由参数innodb_data_file_path配置。

其他:

undo是在事务开始之前保存的被修改数据的一个版本,产生undo日志的时候,同样会伴随类似于保护事务持久化机制的redolog的产生。

默认情况下undo文件是保持在共享表空间的,也即ibdatafile文件中,当数据库中发生一些大的事务性操作的时候,要生成大量的undo信息,全部保存在共享表空间中的。

因此共享表空间可能会变的很大,默认情况下,也就是undo 日志使用共享表空间的时候,被“撑大”的共享表空间是不会也不能自动收缩的。

因此,mysql5.7之后的“独立undo 表空间”的配置就显得很有必要了。

数据文件

SHOW VARIABLES LIKE '%datadir%';

每种存储引擎的数据结构是不一样的

InnoDB数据文件

  1. .frm文件:主要存放与表相关的数据信息,主要包括表结构的定义信息.
  2. .ibd:使用独享表空间存储表数据和索引信息,一张表对应一个ibd文件。
  3. ibdata文件:使用共享表空间存储表数据和索引信息,所有表共同使用一个或者多个ibdata文件。

MyIsam数据文件

  1. .frm文件:主要存放与表相关的数据信息,主要包括表结构的定义信息
  2. .myd文件:主要用来存储表数据信息。
  3. .myi文件:主要用来存储表数据文件中任何索引的数据树。

注意

  1. 日志文件在磁盘中是顺序写入的。速度快,耗费时间短
  2. 数据文件在磁盘中是随机写入的。速度慢,耗费时间长

那为什么数据文件不采用顺序写入的方式呢,因为数据文件有大量的插入删除操作,顺序写入会产生大量的磁盘碎片。(这和磁盘的硬件结构有关,顺序写入只进行一次寻道,随机写入会经常寻道)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章