在MySQL专题的上篇文章《MySQL基础入门:MySQL的体系架构》中,重点介绍了MySQL的体系结构及官方提供的存储引擎。本篇文章,我们一起揭开MySQL安装目录以及目录下文件的神秘面纱。
MySQL 的版本众多,目前最新版本为 MySQL 8,考虑到实际的情况,MySQL系列文章将以 CentOS 7下MySQL5.7.32 社区版本进行学习交流。
进入MySQL的安装目录,我们可以看到如下的目录结构:
在 MysQL 的安装目录下有一个非常重要的 bin 目录,这个目录下存放着许多可执行文件。与其他系统中的可执行文件与此的类似。这些可执行文件都是与服务器程序和客户端程序相关的。
bin目录下主要文件:
mysqld
mysqld 这个可执行文件就代表着 MySOL 服务器程序,运行这个可执行文件就可以直接启动一个服务器进程。但这个命令不常用。
mysqld_safe
mysqld safe是一个启动脚本,它会间接地调用 mysqld,而且还顺便启动了另外一个监控进程,这个监控进程在服务器进程挂了的时候,可以帮助重启它。另外,使用 mysqld_safe 启动服务器程序时,它会将服务器程序的出错信息和其他诊断信息重定向到某个文件中,产生出错日志,这样可以方便我们找出发生错误的原因。
mysql.server
mysql.server 也是一个启动脚本,它会间接地调用 mysqld_safe。在调用mysql.server 时指定start或stop参数就可以启动和停止MySQL服务器程序
mysql.server start
mysql.server stop
需要注意的是,这个mysql.server文件是一个链接文件,它的实际文件是
support-files/mysql.server,所以如果在bin目录找不到,到support-files下去找找,而且如果你愿意的话,自行用ln命令在bin目录下创建一个链接。
mysqld_multi
mysqld_multi 使用单一配置文件统一管理多个MySQL多个实例。多实例就是在一台机器上开启多个不同的服务端口(如:3306,3307),运行多个MySQL服务进程,通过不同的socket监听不同的服务端口来提供各自的服务。而mysql_multi 可执行文件可以对每一个服务器进程的启动或停止进行监控。
MySQL的几个存储引擎如InnoDB和MyISAM都是将数据存储到磁盘上,而我们的操作系统是通过文件系统来管理磁盘的,所以可以说这几个存储引擎都是将表和表数据存储在文件系统上的,而我们通过操作文件系统来读写数据。
数据目录用于存储MySQL服务器在运行过程中产生的数据文件,且在服务器程序启动时会从这个目录下加载相关文件。与安装目录不同,安装目录存储了许多控制服务器和客户端程序的命令。
查看数据目录地址:
mysql> show variables like 'datadir';
+---------------+-------------------+
| Variable_name | Value |
+---------------+-------------------+
| datadir | /www/server/data/ |
+---------------+-------------------+
1 row in set (0.00 sec)
当然,数据目录可以动过配置文件自行指定。在my.cnf配置文件的[mysqld]下指定数据目录:
[mysqld]
datadir = /www/server/data
#innodb存储引擎数据目录,默认值为datadir的配置值
innodb_data_home_dir = /www/server/data
MySQL数据目录都存放那些文件?
带着问题来学习,常常会理解的更为深刻。那么MySOL 在运行过程中都会产生哪些数据呢? 其中包含我们创建的数据库、表、视图和触发器等用户数据,除了这些用户数据,为了程序更好的运行,MySQL也会创建一些其他的额外数据,例如日志文件等。
当我们执行CREATE DATABASE 语句创建一个数据库时,对应的在文件系统会发生什么呢?
mysql> create database demo_db;
Query OK, 1 row affected (0.01 sec)
mysql>
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| dblog |
| demo_db |
| mysql |
| performance_schema |
| spmsdb |
| sys |
+--------------------+
7 rows in set (0.00 sec)
刷新数据目录,我们发现多出了一个名为 demo_db 的文件夹:
总结一下,每当我们新建一个数据库时,MySQL 会帮我们做这两件事儿:
那么,当我们创建一张表是,有会发生什么呢?每个数据表的信息分为两部分:
表结构包含表的名称,有多少个列,每个列的数据类型,约束条件和索引信息,以及使用的什么字符集、存储引擎等等。这些信息都包含在建表语句中。当然,不同的存储引擎,会有不同的专门的文件保存表结构信息。
接下来我们一起看看,InnoDB 和 MyIASM 这两种存储引擎是如何保存表结构信息的。使用demo_db,分别创建两张表demo_innodb(使用InnoDB存储引擎)和demo_myisam(使用MyISAM存储引擎)。
InnoDB的文件存放在一个表空间或者文件空间(英文名: table space 或者 file space)。这个表空间是一个抽象的概念,它可以对应文件系统上一个或多个真实文件(不同表空间对应的文件数量可能不同)。每一个表空间可以被划分为很多个页,我们的表数据就存放在某个表空间下的某些页里。
mysql> CREATE TABLE demo_innodb
-> (
-> id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
-> name VARCHAR(30) NOT NULL COMMENT '用户名称',
-> PRIMARY KEY (id)
-> )
-> ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息表';
Query OK, 0 rows affected (0.05 sec)
如下图,我们可以看到,在demo_db目录下,除了db.opt文件外,多出了两个文件,分别为:
demo_innodb.frm 保存表结构信息
demo_innodb.ibd 保存数据和索引文件
系统表空间(system tablespace)
当我们开启了innodb_file_per_table 配置项(默认就是开启的)之后,系统表空间内就只用于存储 Change Buffer相关的数据。而当我们将其关闭之后,系统表空间内就会存储表和索引相关的数据。
系统表空间可以具有一个或多个数据文件。默认情况下,在数据目录中创建一个名为ibdata1的系统表空间数据文件。
系统表空间数据文件的大小和数量由innodb_data_file_path决定:
mysql> show variables like '%innodb_data_file_path%';
+-----------------------+------------------------+
| Variable_name | Value |
+-----------------------+------------------------+
| innodb_data_file_path | ibdata1:10M:autoextend |
+-----------------------+------------------------+
1 row in set (0.00 sec)
这里指明了系统表空间的文件名为ibdata1 ,初始化大小为10M 。随着 MySQL 的运行,其数据量会慢慢的增长,数据文件必须要申请更多的空间来存储数据。而定义了autoextend。InnoDB存储引擎就会帮我们自动对数据文件进行扩容,每次扩容申请 8M 的空间。当然,这个 8M 也是可以配置的,通过配置项innodb_autoextend_increment 来配置。
mysql> show variables like '%innodb_autoextend_increment%';
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| innodb_autoextend_increment | 8 |
+-----------------------------+-------+
1 row in set (0.00 sec)
独立表空间(file-per-table tablespace)
在 MySQL5.6.6 以及之后的版本中,InnoB 并不会默认的把各个表的数据存储到系统表空间中,而是为每一个表建立一个独立表空间,也就是说我们创建了多少个表,就有多少个独立表空间。
使用独立表空间来存储表数据的话,MySQL会在该表所属数据库对应的目录下创建一个表示该独立表空间的文件,文件名和表名相同,.ibd为扩展名,即上面讲到的table_name.ibd。
当然我们也可以指定使用系统表空间还是独立表空间来存储数据,通过innodb_file_per_table控制。修改MySQL配置文件:
[server]
innodb_file_per_table=0
当 innodb_file_per table 的值为 0 时,代表使用系统表空间;当 innodb_file_per_table的值为1 时,代表使用独立表空间。不过 innodb_file_per_table 参数只对新建的表起作用,对于已经分配了表空间的表并不起作用。
随着 MySQL 的发展,除了上述两种老牌表空间之外,现在还新提出了一些不同类型的表空间,比如通用表空间(general tablespace) ,undo 表空间(undo tablespace)、临时表空间(temporary tablespace)等。
在 MyISAM 中的数据和索引是分开存放的。所以在文件系统中也是使用不同的文件来存储数据文件和索引文件。而且和 InnoDB 不同的是,MyISAM并没有所谓的表空间一说,表数据都存放到对应的数据库子目录下。
mysql> CREATE TABLE demo_myisam
-> (
-> id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',
-> name VARCHAR(30) NOT NULL COMMENT '用户名称',
-> PRIMARY KEY (id)
-> )
-> ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='用户信息表';
Query OK, 0 rows affected (0.01 sec)
再看demo_db目录,有多出了三个文件,分别为:
demo_myisam.frm 保存 表结构 信息(同InnoDB存储引擎,都以.frm为后缀)
demo_myisam.MYD 保存 数据 文件
demo_myisam.MYI 保存 索引 文件
本篇文章,我们一起系统的了解MySQL安装目录结构,以及数据库、表在文件系统中的存在形式,虽然偏理论性知识,但是对使用和学习MySQL非常重要。
你知道的越多,不知道的就越多。
程序员的修养就是对技术发自内心的欣赏和敬畏!倘若文中表述有误,还请谅解,并欢迎与我讨论,自主思考永远比被动接受更有效!