一个 MySQL instance 上可以有多个 database,每个 database 就是一个 schemaschema 中能够创建多张 table,每张 table 又可以对应到虚拟的 view

logical-storage-structure

MySQL 的 databaseschema 是一个概念。

以上描述的是逻辑层的结构,接下来说说物理文件的结构。

安装目录

MySQL 的安装目录下有多个文件夹:
mysql-basedir
它们的用途参考下表(取自 MySQL 官网):

Directory Contents of Directory
bin mysqld server, client and utility programs
docs MySQL manual in Info format
man Unix manual pages
include Include (header) files
lib Libraries
share Error messages, dictionary, and SQL for database installation
support-files Miscellaneous support files

数据目录

MySQL 默认会在安装目录下创建一个 data 目录,所有的数据文件都在里面,其结构如下图所示:

mysql-datadir

在 MySQL 中,一个数据库对应一个文件夹。当我们创建一个名为 employees 的数据库时,磁盘上就会自动生成一个相同名称的文件夹。如果在 employees 数据库中创建一张表, employees 文件夹下面就会出现一组文件。

凡是表都会有一个表结构定义文件,文件名和表名相同,以 .frm 作为扩展(这是个二进制文件,在所有平台上都是相同的)。下图列出了 employees 库中的 6 张表,因为它们都使用了 InnoDB 存储引擎,所以每张表还对应一个数据文件(*.ibd)。

mysql-table-files

数据目录下的其他文件,会在后面的文章中介绍。

配置文件

配置文件中定义着与 MySQL 实例运行相关的参数,这些参数其实就是键值对。
参数分为两类,动态参数和静态参数。
动态参数可以在实例运行过程中,通过 MySQL 命令行利用 SET GLOBAL 或者 SET SESSION 在线更改。GLOBAL 选项会让参数在修改后全局生效,即使当前会话退出也不会丢失。但数据库关闭或重启,配置还是会失效;SESSION 表示设置只对当前会话生效,退出即失效。
静态参数无法在实例运行过程中更改,只能在配置文件中定义,重启实例后才会生效。

某些动态参数的作用范围只在会话级别或者只在全局级别。
某些静态参数在整个实例生命周期内都没法进行调整。

相似的,我们也可以通过 SHOW GLOBAL VARIABLES LIKE 或者 SHOW SESSION VARIABLES LIKE 来查看各个参数的值。

在使用 CentOS 或者 RHEL 操作系统时,/etc/ 目录下默认就会有一份配置文件 my.cnf,但非常简易。
这里有一份比较完整的配置文件,从中可以发现,配置文件是有 section 这种概念的:

  • [client]:只由 MySQL 发行版中提供的客户端程序读取
  • [mysql]:只作用于客户端程序
  • [mysqld_safe]:只作用于 mysqld_safe 脚本
  • [mysqld]:只作用于 mysqld 命令
  • [mysqldump]:只作用于 mysqldump 命令

用户可以自定义配置文件的路径和文件名,但在启动 MySQL 时需要明确指定(《MySQL 的启动与连接》)。

日志文件

MySQL 有多种日志:

  • 错误日志
    错误日志记录了 MySQL 在启动、停止和运行中产生的错误信息。
    MySQL 在初始化时产生的临时登录密码,也是记录在错误日志中的。
    错误日志无法关闭,只能在配置文件中定义其路径和文件名。

  • 慢查询日志
    慢查询日志可以把执行时间超过 long_query_time 的所有 SQL 语句记录进来,帮助 DBA 优化有问题的 SQL 语句。

  • 常规日志
    记录 MySQL 运行中所有的操作,无论这些操作执行是否成功,另外还包括一些事件。
    对于繁忙的服务器,该日志会造成大量的磁盘 IO,影响数据库性能,建议不要开启。

  • 二进制日志
    用于记录对数据进行更改或者可能引起数据更改的 SQL 语句,不会包含那些没有修改任何数据的语句,例如 SELECT、SHOW 等操作。
    二进制日志非常重要,下文会详细讲解。

运行时文件

  • socket 文件
    套接字文件,Linux 操作系统下特有的文件,用于描述服务的 IP 地址和端口。

  • pid 文件
    记录着 mysqld 的进程 id。