MySQL由以下几个部分组成,了解MySQL必须牢牢记住其体系结构图。
连接池组件
管理服务和工具组件
SQL接口组件
查询分析器组件
优化器组件
缓冲组件
插件式存储引擎
物理文件
图中可以发现,MySQL数据库区别与其他数据库的最重要的一个特点就是其插件式的表存储引擎。
需要注意的是,存储引擎是基于表的,而不是数据库。存储引擎的好处是,每个存储引擎都有各自的特点,能够根据具体的应用建立不同存储引擎表。
常见引擎有:
InnoDB存储引擎
支持事务,行锁设计、支持外键,非读锁定,新版本添加了全文索引。从MySQL数据库5.5.8版本开始,InnoDB存储引擎是默认的存储引擎。
MyISAM存储引擎
不支持事务,表锁设计,支持全文索引。5.5.8版本之前是默认存储引擎。
Memory存储引擎
数据存放在内存中,重启或崩溃表中的数据都将消失。适合存储临时数据的临时表,默认使用哈希索引。
Archive存储引擎
只支持INSERT和SELECT操作,使用zlib算法将数据行进行压缩后存储,适合存储归档数据,如日志信息。
连接MySQL
连接MySQL操作是一个连接进程和MySQL数据库实例进行通信。从程序设计的角度来说,本质上就是进程通信。常用的进程通信方式有管道、命名管道、命名字、TCP/IP套接字、UNIX域套接字。MySQL数据库提供的连接方式从本质上看都是上述提及的进程通信方式。
TCP/IP
这种方式在TCP/IP连接上建立一个基于网络的连接请求,一般情况下客户端在一台服务器上,而MySQL实例在另一台服务器上。
在通过TCP/IP连接到MySQL实例时,数据库会先检查一张权限视图,用来判断发起请求的客户端IP是否允许连接到MySQL实例。
命名管道与共享内存
在windows平台上,如果两个需要进程通信的进程在同一台服务器上,那么可以使用命名管道。在MySQL4.1之后的版本中,MySQL还提供了共享内存的连接方式。
UNIX域套接字
在Linux和UNIX环境下,还可以使用UNIX域套接字。UNIX域套接字其实不是一个网络协议,所以只能在MySQL客户端和数据库实例在一台服务器上的情况下使用。用户可以在配置文件中指定套接字文件的路径,如--socket=/tmp/mysql.sock。当数据库实例启动后,用户可以通过下列命令来进行UNIX域套接字文件的查找:
SHOW VARIABLES LIKE 'socket'
知道了UNIX域套接字文件的路径后,就可以使用该方式进行连接了。
mysql -udavid -S /tmp/mysql.sock
文件
参数文件
MySQL实例启动时,数据库会先去读一个配置参数文件,用来寻找数据库的各种文件所在位置以及制定某些初始化参数,这些参数通常定义了某种内存结构有多大等。在默认情况下,MySQL实例会按照一定的顺序在指定的位置进行读取,用户只需要通过命令mysql--help|grep my.cnf来寻找即可。
MySQL数据库的参数可以分为两类:动态参数、静态参数。
静态参数在整个实例生命周期内不得更改,动态参数可以通过SET命令对动态的参数值进行修改。
日志文件
日志文件记录了影响MySQL数据库的各种类型活动。MySQL中常见的日志文件有:
错误日志
二进制日志
慢查询日志
查询日志
错误日志
错误日志文件对MySQL的启动、运行、关闭过程进行了记录。不仅记录了所有的错误信息,也记录一些警告信息或正确的信息。可通过命令 SHOW VARIABLES LIKE 'log_error'来定位该文件。
当数据库不能正常启动时,第一个必须查找的文件就应该是错误日志文件。
错误日志还会提供一些数据库优化信息,例如告诉用户需要增大InnoDB存储引擎的redo log。
慢查询日志
慢查询日志可以帮助用户定位可能存在问题的SQL语句,例如可以在MySQL启动时设一个阈值,将运行时间超过该值的所有SQL语句都记录到慢查询日志中。该阈值可通过参数long_query_time来设置,默认值10秒。
在默认情况下MySQL数据库并不启动慢查询日志,用户需要手工将这个参数设置为ON。
另一个和慢查询日志有关的参数是log_queries_not_using_indexes,如果运行的SQL语句没有使用索引,则MySQL数据库同样会将这条SQL语句记录到慢查询日志。log_throttle_queries_not_using_indexes,用来表示每分钟允许记录到slow log且未使用索引的SQL语句次数,防止日志增长过快。
当越来越多的SQL查询被记录到慢查询日志中时,要分析该文件就显得不那么简单直观了。这时MySQL数据库提供了mysqldumpslow命令帮助进行分析。
当数据库的容量较小时,可能因为数据库刚建立,此时非常大可能是数据库全部被缓存在缓冲池中,SQL语句运行的时间可能都是非常短的。
为了加强对SQL语句的捕获方式,MySQL增加了逻辑读取和物理读取的统计。这里物理读取指从磁盘进行IO读取的次数,逻辑读取包含所有的读取,不管磁盘还是缓冲池。
用户可以通过额外的参数long_query_io将超过指定逻辑IO次数的SQL语句记录到slow log中,默认为100。为了兼容原MySQL数据库的运行方式,还添加了slow_query_type来表示启动slow log的方式:
0不启动slow log
1按运行时间记录
2按逻辑IO次数记录
3按运行时间和逻辑IO次数记录
查询日志
查询日志记录了所有对MySQL数据库请求的信息,无论这些请求是否得到了正确的执行。默认文件名为:主机名.log。从5.1开始,可以将查询日志的记录放入general_log表中。
二进制日志
二进制日志记录了对MySQL数据库执行更改的所有操作,但是不包括SELECT和SHOW这类操作。即便UPDATE等修改操作未能产生实际作用,也会进行记录。
总的来说,二进制日志主要有以下几种作用。
恢复:某些数据的恢复需要二进制日志。
复制:其原理与恢复类似,通过复制和执行二进制日志使一台远程的MySQL数据库与一台MySQL数据库进行实时同步。
审计:用户可以通过二进制日志中的信息来进行审计,判断是否有对数据库进行注入的攻击。
通过配置参数log-bin [name] 可以启动二进制日志。如果不指定name,则默认文件名为主机名,所在路径为数据库所在目录。
参数max_binlog_size指定了单个二进制日志文件的最大值,如果超过该值,则产生新的二进制日志文件,后缀名+1,默认为1G。
二进制日志文件的文件格式为二进制,不能像错误日志文件、慢查询日志文件那样用cat、head、tail等命令查看。要查看二进制日志文件的内容,必须通过MySQL提供的工具mysqlbinlog。
套接字文件
在UNIX系统下本地连接MySQL可以采用UNIX域套接字方式,这种方式需要一个套接字(socket)文件。套接字文件可由参数socket控制。一般在/tmp目录下,名为mysql.sock。
pid文件
当MySQL实例启动时,会将自己的进程ID写入一个文件中——该文件即为pid文件。该文件可由参数pid_file控制,默认位于数据库目录下,文件名为主机名.pid
表结构定义文件
因为MySQL插件式存储引擎的体系结构的关系,MySQL数据的存储是根据表进行的,每个表会有与之对应的文件。但不论表采用何种存储引擎,MySQL都有一个以frm为后缀名的文件,这个文件记录了该表的表结构定义。
frm还用了存放视图的定义,如用户创建了一个v_a视图,那么对应会产生一个v_a.frm文件,用来记录视图的定义。
InnoDB存储引擎文件
每个表存储引擎也有自己独有的文件,包括重做日志文件、表空间文件。
表空间文件
InnoDB采用将存储的数据按表空间进行存放的设计。在默认配置下会有一个初始大小为10MB,名为ibdata1的文件。用户可以通过参数innodb_data_file_path对其进行设置。
用户可以通过多个文件组成一个表空间,同时制定文件的属性。若文件位于不同的磁盘上,磁盘的负载可能被平衡,因此可以提高数据库的整体性能。
设置innodb_data_file_path参数后,所有基于InnoDB存储引擎的表的数据都会记录到该共享表空间中。若设置了参数innodb_file_per_table,则用户可以将每个基于InnoDB存储引擎的表产生一个独立表空间。
重做日志文件
在默认情况下,在InnoDB存储引擎的数据目录下会有两个名为ib_logfile0和ib_logfile1的文件。MySQL官方手册称其为InnoDB的日志文件或者叫重做日志文件。它们记录了对于InnoDB存储引擎的事务日志。
当实例或介质失败时,重做日志文件就能派上用场。例如,数据库掉电导致实例失败,InnoDB存储引擎会使用重做日志恢复到掉电前的时刻,来保证数据的完整性。
每个InnoDB存储引擎至少有1个重做日志文件组,每个文件组下至少有2个重做日志文件,如默认的ib_logfile0和ib_logfile1。为了更高的可靠性,用户可以设置多个镜像日志组,将不同的文件组放在不同的磁盘上。
在日志组中,两个日志文件以循环写入的方式运行。InnoDB先写日志文件1,文件写满时,会切换至重做日志文件2,循环写入。
参数innodb_log_file_size指定每个重做日志文件的大小。
参数innodb_log_files_in_group指定了日志文件组中重做日志文件的数量,默认为2。
参数innodb_mirrored_log_groups指定了日志镜像文件组的数量,默认为1,没有镜像。
小结
当MySQL数据库发送任何错误时,首先就应该去查看错误日志。建议在任何时候都开启二进制日志的记录,用来进行point in time的恢复以及复制环境的搭建。
InnoDB包括表空间文件和重做日志文件,表空间文件用来管理InnoDB存储引擎的存储。重做日志用来记录InnoDB存储引擎的事务日志,保证InnoDB存储引擎可以提供可靠的事务。
参考