16.MySQL 服务器配置与管理
1.MySQL 服务器简介
通常所说的 MySQL 服务器指的是mysqld程序,当运⾏mysqld后对外提供MySQL 服务
1.1服务器配置和默认值
• mysqld 有很多选项和系统变量可以在启动时进⾏配置,要查看服务器的默认选项和系统变量值,
可以执⾏以下命令:
# 查看所有mysqld 选项和可配置的系统变量列表及默认值
root@guangchen-vm:/var/lib/mysql# mysqld --verbose --help
# 内容看起来像这样
abort-slave-event-count 0
allow-suspicious-udfs FALSE
archive ON
auto-increment-increment 1
auto-increment-offset 1
autocommit TRUE
automatic-sp-privileges TRUE
avoid-temporal-upgrade FALSE
back-log 80
basedir /usr/
... 省略
tmpdir /tmp
transaction-alloc-block-size 8192
transaction-isolation REPEATABLE-READ
transaction-prealloc-size 4096
transaction-read-only FALSE
transaction-write-set-extraction XXHASH64
updatable-views-with-limit YES
• 查看服务器在运⾏时系统变量的值,连接到MySQL并执⾏以下语句:

• 查看服务器在运⾏时的⼀些统计和状态指⽰器,连接到MySQL并执⾏以下语句:

• 系统变量和状态信息也可以使⽤ mysqladmin命令来查看
root@guangchen-vm:~# mysqladmin variables
root@guangchen-vm:~# mysqladmin extend-status
关于服务器的选项,系统变量,状态变量可以参考MySQL官网


注意:系统变量,状态变量的作用域分为:Global(全局),Session(当前会话或连接),或 两者都支持

1.2系统变量和选项
简介:
当通过mysqld启动数据库服务器时,可以通过选项⽂件或命令⾏中提供选项,但是,在⼤多数情
况下,为确保服务器每次运⾏时都使⽤相同的选项,最好的⽅法是在选项⽂件中指定相应的选项。
mysqld从选项⽂件中的 [mysqld] 和 [server] 组(节点)中读取选项内容
mysqld接受的选项可以通过 mysqld --verbose --help 查看,列表中的有些项⽬是可以在
服务器启动时设置的系统变量,系统变量可以在连接MySQL后使⽤ SHOW VARIABLES 语句查
看,但有些内容只在 --help 中存在,使⽤ SHOW VARIABLES 时并没有显⽰,这是因为它们只
是选项⽽不是系统变量。
注意:选项值可以通过命令⾏和选项⽂件设置,部分系统变量可以通过SET语句动态设置值
常用选项
类别 | 变量名 | 作用描述 | 常见设置示例 |
---|---|---|---|
连接相关 | max_connections | 控制同时连接的最大客户端数量 | SET GLOBAL max_connections = 500; |
连接相关 | max_user_connections | 限制单个用户的最大并发连接数(0 表示不限制) | SET GLOBAL max_user_connections = 100; |
连接相关 | wait_timeout | 非交互式连接的空闲超时时间(秒) | SET GLOBAL wait_timeout = 1800; |
连接相关 | interactive_timeout | 交互式连接的空闲超时时间(秒) | SET GLOBAL interactive_timeout = 1800; |
存储引擎相关 | default_storage_engine | 设置默认存储引擎(如 InnoDB、MyISAM) | SET GLOBAL default_storage_engine = 'InnoDB'; |
存储引擎相关 | innodb_buffer_pool_size | InnoDB 缓冲池大小(缓存数据和索引,影响性能) | SET GLOBAL innodb_buffer_pool_size = 1073741824; (1GB) |
查询相关 | query_cache_type | 控制查询缓存行为(OFF/ON/DEMAND,8.0 + 建议关闭) | SET GLOBAL query_cache_type = OFF; |
查询相关 | query_cache_size | 查询缓存占用的内存大小(字节,需为 1024 倍数) | SET GLOBAL query_cache_size = 16777216; (16MB) |
日志相关 | log_error | 指定错误日志文件路径 | SET GLOBAL log_error = '/var/log/mysql/error.log'; |
日志相关 | general_log | 控制是否开启通用查询日志(记录所有 SQL,默认 OFF) | SET GLOBAL general_log = ON; |
日志相关 | general_log_file | 通用查询日志文件路径(需开启 general_log) | SET GLOBAL general_log_file = '/var/log/mysql/query.log'; |
数据传输相关 | max_allowed_packet | 客户端请求的最大数据包大小(字节) | SET GLOBAL max_allowed_packet = 33554432; (32MB) |
数据传输相关 | net_buffer_length | 服务器接收数据的缓冲区大小(默认 16384 字节) | SET GLOBAL net_buffer_length = 16384; |
依旧(WPS + AI)
1.3使用系统变量
1. 以上我们介绍了通过选项⽂件和命令⾏设置相应系统变量的值,设置系统变量的语法与命令选项的语法相同,指定变量名称时,破折号和下划线可以互换使⽤。例如, --general_log=ON 和 -
-general-log=ON 是等价的。
2. 当使⽤选项设置⼀个数值的变量时,可以带有后缀 K 、 M 或 G (⼤⼩写不限)表⽰ 1024 、
1024^2 或 1024^3 ;从MySQL 8.0.14 开始,后缀也可以⽤ T 、 P 和 E 来表⽰ 1024^4 、
1024^5 或 1024^6 。
⽰例:为服务器指定 256 KB 的排序缓冲区⼤⼩和 1 GB 的最⼤数据包⼤⼩
# 在命令⾏的指定
mysqld --sort-buffer-size=256K --max-allowed-packet=1G# 在选项⽂件中指定
[mysqld]
sort_buffer_size=256k
max_allowed_packet=1g
3. 系统变量有两个作⽤域,分别是 Global (全局)和 Session (会话), Global 全局变量影响服
务器的整体操作, Session 会话变量影响各个客⼾端连接的操作。给定的系统变量可以同时具有
全局值和会话值,它们的关系如下:
◦ 服务器启动时,会将每个全局变量初始化并设置默认值,具体的值可以通过命令⾏或选项⽂件
更改。
◦ 服务器为每个客⼾端维护⼀组 Session 变量,在客⼾端连接时使⽤相应全局变量的当前值进
⾏初始化。
4. ⼤部分系统变量是动态的,在服务器运⾏时可以通过 SET 语句动态更改,并且⽆需停⽌和重新启动服务器。在服务器运⾏时,使⽤ SET 语句设置系统变量,需要指定作⽤域(也可以在前⾯加上
@@ 修饰符),然后指定系统变量的名称,名称必须使⽤下划线⽽不是破折号,如下所⽰:
a. 设置全局系统变量最⼤连接数为1000
mysql> SET GLOBAL max_connections = 1000;
mysql> SET @@GLOBAL.max_connections = 1000;
b. 将全局系统变量持久化到 mysqld-auto.cnf ⽂件(同时设置运⾏时值):
# PERSIST 表⽰持久化的同时设置全局变量的值mysql> SET PERSIST max_connections = 1000;
mysql> SET @@PERSIST.max_connections = 1000;
c. 将全局系统变量持久化到 mysqld-auto.cnf ⽂件(不设置运⾏时值):
# PERSIST 表⽰持久化的同时设置全局变量的值
mysql> SET PERSIST_ONLY max_connections = 1000;
mysql> SET @@PERSIST_ONLY.max_connections = 1000;
删除持久化的系统变量可以使⽤语句
RESET PERSIST IF EXISTS system_var_name;
d. 设置 Session 系统变量,时区为"+8:00":
mysql> SET SESSION time_zone='+8:00';
mysql> SET @@SESSION.time_zone='+8:00';
mysql> SET @@time_zone='+8:00';
5. 对于数值型的系统变量,⽤带有后缀的值指定时,只适⽤于选项⽅式,⽽不能⽤在 SET ⽅式中;SET ⽅式可以使⽤表达式为系统变量指定值,⽽在选项⽅式中不允许,如下所⽰:
# 选项形式
root@guangchen-vm:~# mysqld --max_allowed_packet=16M # 允许
root@guangchen-vm:~# mysqld --max_allowed_packet=16*1024*1024 # 不允许# 运⾏时SET形式
mysql> SET GLOBAL max_allowed_packet=16M; # 不允许
mysql> SET GLOBAL max_allowed_packet=16*1024*1024; # 允许
说明:在设置全局变量时需要指定GLOBAL关键字的原因是为了防⽌出现以下问题:
• 如果要删除的SESSION变量与GLOBAL变量名相同,那么具有修改全局变量权限的客⼾端可能会
意外地更改GLOBAL变量,⽽不仅仅是只修改SESSION变量。
• 如果已经有⼀个SESSION变量⽽且与GLOBAL变量同名,那么本意是要修改GLOBAL变量,可能
只是修改了SESSION变量的值
所以没有明确指定 GLOBAL 和 SESSION 时,对于当前客⼾端来说 SESSION 的优先级更⾼
6.要显⽰系统变量名称和值,请使⽤以下 SHOW VARIABLES 语句:
mysql> SHOW VARIABLES;
7.可以使⽤ LIKE ⼦句显⽰与指定内容匹配的变量,也可以使⽤通配符
# 查看指定的系统变量
SHOW VARIABLES LIKE 'max_join_size';
# 查看指定系统变量SESSION作⽤域的值
SHOW SESSION VARIABLES LIKE 'max_join_size';# 查看包含指定内容的系统变量
SHOW VARIABLES LIKE '%size%';
# 查看包含指定内容系统变量的GLOBAL作⽤域的值
SHOW GLOBAL VARIABLES LIKE '%size%';
8. ⼀部分系统变量是内置的,也有⼀些需要通过安装服务器插件或组件才可以使⽤

在 Unix 和 Linux 系统上读取的选项文件
*会逐级覆盖
1.4服务器常用配置
1.Linux系统下编程 /etc/mysql/my.cnf
注意:
* 编译前先备份原始文件
* 如果要修改数据目录选项建议先停止MySQL服务,并把原data目录整体复制到新路径,配置完成后重启服务
在 [mysqld] 节点下添加以下内容
如果数据库服务在公网部署,建议修改默认端口号
# MySQL 服务节点
[mysqld]# MySQL 服务启动后监听的端⼝号
port=3306# 数据⽬录的路径,这⾥演⽰的是windows下的配置,注意分隔符⽤/,如果是\则需要转义为\\.
# 把原data⽬录整体复制到新路径
datadir=D:/database/MySQL/data8.0# MySQL 服务器的字符集与排序规则
character-set-server=utf8mb4 //可识别中文...
collation-server=utf8mb4_general_ci # 新建表时使⽤的存储引擎,windows下已默认配置
default-storage-engine=INNODB
具体看WPS
2.Windows系统下打开D:/ProgramData/MySQL/MySQL Server 8.0/my.ini
2.5 查看状态变量
MySQL服务器维护着当前系统信息的状态变量(指示类型的变量,不能人为修改)
可以使⽤ SHOW [GLOBAL | SESSION] STATUS [like status_name]; 语句查看这些变量和对应的值。 (可以使用通配符)
GLOBAL显⽰所有连接的值,SESSION显⽰当前连接的值
mysql> SHOW GLOBAL STATUS;
+-----------------------------------+------------+
| Variable_name | Value |
+-----------------------------------+------------+
| Aborted_clients | 0 | #未正确关闭连接⽽中⽌的连接数
| Aborted_connects | 0 | #连接MySQL服务器失败的次数
| Bytes_received | 155372598 | #从所有客⼾端接收的字节数
| Bytes_sent | 1176560426 | #发送给所有客⼾端的字节数
...
| Connections | 30023 | #尝试连接到MySQL服务器的次数,不
论成功或失败
| Created_tmp_disk_tables | 0 | #创建内部磁盘临时表的数量
| Created_tmp_files | 3 | #创建了临时⽂件的数量
| Created_tmp_tables | 2 | #创建内部临时表的数量
...
| Threads_created | 217 | #为处理连接⽽创建的线程数
| Threads_running | 88 | #未休眠的线程数
| Uptime | 1389872 | #服务器已启动的秒数
+-----------------------------------+------------+
具体含义可看官网
2. MySQL数据目录


1. 数据⽬录下的每个⼦⽬录都是⼀个数据库⽬录,对应服务器管理的⼀个数据库,包括MySQL 安装成功后创建的标准数据库:
a. mysql⽬录对应于mysql系统库,包含mysql服务器运⾏时所需的信息,该数据库包含数据字典表和系统表;
b. performance_schema⽬录对应于Performance Schema,提供了在运⾏时⽤于检查服务器内部执⾏的信息;
c. sys⽬录对应于sys系统库,提供⼀组对象来帮助解释性能模式相关信息;
d. 其他⼦⽬录对应于⽤⼾或应⽤程序创建的数据库,也就是说我们每创建⼀个数据库,就会在数据⽬录⽣成⼀个同名的⽬录来保存对应的数据。
2. 服务器写⼊的⽇志⽂件
3. InnoDB 表空间和⽇志⽂件
4. 默认或⾃动⽣成的 SSL 和 RSA 证书和密钥⽂件
5. 服务器进程 ID ⽂件(当服务器运⾏时)
6. mysqld-auto.cnf ⽂件⽤来存储持久化全局系统变量设置
通过选项重新配置服务器,可以将上述某些项⽬重新定位到指定⽬录。
使⽤ --datadir 选项允许更改数据⽬录本⾝的位置
3.日志简介
MySQL Server 有以下⼏种⽇志,可以记录服务器正在发⽣的活动
默认情况下,除 Windows 上的错误⽇志外,不启⽤任何⽇志,Linux下默认开启错误⽇志和⼆进制
⽇志
• 在服务器运⾏期间可以控制⼀般查询和慢查询⽇志的禁⽤与开启,也可以更改⽇志⽂件名
• ⼀般查询⽇志和慢查询⽇志记录可以写⼊⽇志表、⽇志⽂件或两者同时写⼊
• 默认情况下,所有启⽤的⽇志将写⼊数据⽬录,可以通过刷新⽇志强制服务器关闭并重新打开⽇志⽂件
• 通过 FLUSH LOGS 语句刷新⽇志来强制服务器关闭并重新打开⽇志⽂件,也可以使⽤ mysqladmin 的 flush-logs 或 refresh 参数,或mysqldump 的 --flush-logs 或 --master-data 选项
• 中继⽇志仅⽤于主从复制过程中的从服务器。
3.1 ⼀般查询日志和慢查询日志的输出形式
如果启⽤⼀般查询⽇志和慢查询⽇志,⽇志的输出⽅式可以指定为⽇志⽂件或 mysql 系统库中
的 general_log 和 slow_log 表,也可以两者同时指定。
启动时的日志控制
• log_output 系统变量指定⽇志输出的形式,但并不会真正的启⽤⽇志。 log_output 可以有
三个值,分别是: TABLE (表)、 FILE (⽂件)(默认值)、 NONE (不输出),可以同时指定多个值,并⽤逗号隔开,未指定值时默认是 FILE ,如果列表中存在 NONE 则其他的不⽣效,也就是说 NONE 的优先级最⾼。
• 通过设置 general_log 系统变量的值来控制⼀般查询⽇志的 开启 1 与 禁⽤ 0 ,如果要为⽇
志指定⾃定义的路径或⽂件名可以使⽤ general_log_file 系统变量(绝对路径)
• 通过设置 slow_query_log 系统变量的值来控制慢查询⽇志的 开启 1 与 禁⽤ 0 ,如果要为
⽇志指定⾃定义的路径或⽂件名可以使⽤ slow_query_log_file 系统变量(绝对路径)

• ⽰例,以选项⽂件中的配置为例:
◦ 将⼀般查询⽇志写⼊⽇志表和⽇志⽂件
[mysqld]
#⽇志写⼊表和⽂件
log_output=TABLE,FILE
#开启⼀般查询⽇志
general_log=1
◦ 仅将⼀般查询⽇志和慢查询⽇志写⼊⽇志表
[mysqld]
log_output=TABLE #⽇志写⼊表
general_log=1 #开启⼀般查询⽇志
slow_query_log=1 #开启慢查询⽇志
◦ 仅将慢查询⽇志写⼊⽇志⽂件
[mysqld]
log_output=FILE #⽇志⽂件
slow_query_log=1 #开启慢查询⽇志
• 将⼀般查询⽇志和慢查询⽇志写⼊⽇志⽂件,并指定⾃定义的⽇志路径
[mysqld]
#⽇志⽂件
log_output=FILE
#开启⼀般查询⽇志
general_log=1
#指定⾃定义的⽂件名
general_log_file=/var/lib/mysql/general.log #开启慢查询⽇志
slow_query_log=1
#指定⾃定义的⽂件名
slow_query_log_file=/var/lib/mysql/slow_query.log
运行时的日志控制
• 在运⾏时修改 log_output 的值,以更改⽇志的输出形式,通过语句控制
• 语法:SET [GLOBAL|SESSION] variable_name=value
SET GLOBAL log_output=[FILE, TABLE, NONE]
•general_log[={0|1}] 和 slow_query_log[={0|1}] 可以表⽰启⽤和禁⽤⼀般查询⽇志和慢查询⽇志
• general_log_file 和 slow_query_log_file 表⽰通⽤查询⽇志和慢查询⽇志⽂件名称
• 只对当前会话禁⽤或启⽤⼀般查询⽇志记录,将 SESSION 作⽤域的 sql_log_off 变量设置
为 ON 或 OFF
使用日志表的优点
• 可以通过 SQL 语句的条件查询过滤⽇志内容(使用where 条件),从⽽选择满⾜特定条件的⽇志记录。⽐如,某个客⼾端的⽇志;
• 可以通过客⼾端程序连接到服务器并查询表中的⽇志信息(使用客户端用SQL语句查询,应用程序级别),⽆需登录服务器主机访问⽂件系统(需要有一个系统用户,并且有相应的权限,系统级别)
• ⽇志记录具有标准格式,可看⽇志表的结构,可以使⽤以下语句:
SHOW CREATE TABLE mysql.general_log; # ⼀般查询⽇志
SHOW CREATE TABLE mysql.slow_log; # 慢查询⽇志
3.2 一般查询日志
• General query log - ⼀般查询⽇志,记录客⼾端连接或断开连接的信息,也会记录从客⼾端接收的每个SQL语句。如果开启将会产⽣⼤量的内容,⾮常耗费服务器资源,所以默认为关闭(不开启),要启⽤⼀般查询⽇志可以使⽤:请使⽤ --general_log[={0|1}]
• 默认⽇志⽂件名为 host_name.log ,可以使⽤ general_log_file=file_name 修改;
• 记当客⼾端连接的⽇志⾏,使⽤ connection_type 来指⽰⽤于建⽴连接的协议。 TCP/IP 表
⽰不使⽤SSL建⽴的TCP/IP连接、 SSL/TLS 表⽰使⽤SSL建⽴的TCP/IP连接、 Socket 表⽰
Unix套接字⽂件连接、 Named Pipe 表⽰Windows命名管道连接、 Shared Memory 表⽰
Windows共享内存连接。
• Mysqld按照接收到SQL语句的顺序将语句写⼊查询⽇志,这个顺序可能与语句执⾏的顺序不同。
• 表结构如下:

⼀般查询日志示例
• 查询表中的⽇志内容
通过cast()函数把编码后的内容转换为可读的字符类型;cast(要转换的内容 AS 目标数据类型)
# 查看⽇志
SELECT DATE_FORMAT(event_time, '%Y-%m-%d %H:%i:%s') AS time, user_host, thread_id, server_id, command_type, CAST(argument AS CHAR) AS query
FROM mysql.general_log;
• 查看⽂件中的⽇志内容(需要开启一般日志)
root@guangchen-002:/var/lib/mysql# cat general.log
3.3 慢查询日志
•慢查询⽇志由执⾏时间超过系统变量 long_query_time 指定的秒数的 SQL 语句组成,并且检
查的⾏数⼤于系统变量 min_examined_row_limit 指定值(查询语句返回的结果集中所包含的行数,比如10)。被记录的慢查询需要进⾏优化,
可以使⽤ mysqldumpslow客⼾端程序对慢⽇志进⾏分析汇总。
• 获取初始锁的时间不计⼊执⾏时间,mysqld在执⾏完SQL语句并释放所有锁后才将符合条件的语
句写⼊慢速查询⽇志,因此⽇志顺序可能与执⾏顺序不同。

慢查询日志参数
• long_query_time 的默认值是10,最⼩值是0;
• 默认情况下,不记录管理语句,也不记录不使⽤索引的查询
• 默认为关闭(不开启),要启⽤慢查询⽇志可以使⽤:请使⽤ --slow_query_log[={0|1}] .
• 默认⽇志⽂件名为 host_name-slow.log ,可以使⽤ slow_query_log_file=file_name 修改;
• 使⽤ --log-short-format 选项,以简要格式记录慢查询⽇志
• 要记录管理语句,启⽤ log_slow_admin_statements 系统变量。管理语句包括 ALTER
TABLE 、 ANALYZE TABLE 、 CHECK TABLE 、 CREATE INDEX 、 DROP INDEX 、
OPTIMIZE TABLE 和 REPAIR TABLE 。
• 要记录不使⽤索引的查询,启⽤ log_queries_not_using_indexes 系统变量。当记录不使
⽤索引的查询时,⽇志会快速增⻓,通过设置系统变量(当开启了记录不使用索引的查询时,一定要记住配置一下每分钟记录的日志数)
log_throttle_queries_not_using_indexes 限制每分钟写⼊慢查询⽇志同类查询的数
量,默认值是0,表⽰⽆限制。
慢查询日志内容
FILE格式
• 如果启⽤慢查询⽇志并将 FILE 作为输出⽬标,每条语句前⾯都⽤⼀⾏来表⽰⽇志的字段,该⾏
以 # 字符开头并包含以下内容:
◦ Query_time: :SQL语句的执⾏时间,单位秒
◦ Lock_time: 获取锁的时间,单位秒
◦ Rows_sent: 发送到客⼾端的⾏数(返回的查询结果集的行数)
◦ Rows_examined: 服务器检查的⾏数(服务器扫描数据表中具体数据行的数量)
• 启⽤--log-slow-extra[={OFF|ON}]系统变量会将以下额外字段写⼊到FILE中,TABLE形式不受影 响
◦ Thread_id: 线程标识符
◦ Errno: 错误码,没有发⽣错误则为 0
◦ Killed: 如果语句被终⽌,⽤错误码表⽰原因,如果语句正常终⽌则为 0。
◦ Bytes_received: 接收到SQL语句的Bytes值。
◦ Bytes_sent: 返回给客⼾端的Byte值。
◦ Read_first: 索引中第⼀个条⽬被读取的次数,如果这个值很⾼,表明服务器正在执⾏⼤量完整索引扫描
◦ Read_last: 读取索引中最后⼀个键的请求数,使⽤ ORDER BY 时关注
◦ Read_key: 基于索引读取⼀⾏数据的请求数。如果这个值很⾼,表明表为当前查询建⽴了正确的索引
◦ Read_next: 按索引排序读取下⼀⾏的请求数,查询具有范围约束的索引列,或者进⾏索引
扫描,此值将递增。
◦ Read_prev: 按索引排序读取前⼀⾏的请求数。主要⽤于优化ORDER BYRDESC。
◦ Read_rnd: 基于固定位置读取⼀⾏的请求数。这个值很⾼表⽰,正在执⾏⼤量需要对结果进
⾏排序的查询,可能有很多查询进⾏了全表扫描整,或者没有正确使⽤索引的连接。
◦ Read_rnd_next: 读取数据⽂件中下⼀⾏的请求数。如果进⾏⼤量的表扫描,这个值会很
⾼。通常,表⽰表没有建⽴正确地索引,或者查询没有利⽤索引。
◦ Sort_merge_passes: 排序算法完成的归并次数,如果这个值很⼤,考虑增加sort_buffer_size 系统变量的值。
◦ Sort_range_count: 使⽤范围进⾏排序的次数。
◦ Sort_rows: 排序的⾏数。
◦ Sort_scan_count: 通过扫描表完成的排序数。
◦ Created_tmp_disk_tables: 服务器在执⾏语句时创建内部磁盘临时表的数量。
◦ Created_tmp_tables: 服务器在执⾏语句时创建的内部临时表的数量。
◦ Start: 执⾏SQL语句开始时间
◦ End: 执⾏SQL语句结束时间

TABLE格式
慢查询⽇志表的表结构如下:
mysql> SHOW CREATE TABLE mysql.slow_log;CREATE TABLE `slow_log` (`start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE
CURRENT_TIMESTAMP(6),`user_host` mediumtext NOT NULL,`query_time` time(6) NOT NULL,`lock_time` time(6) NOT NULL,`rows_sent` int NOT NULL,`rows_examined` int NOT NULL,`db` varchar(512) NOT NULL,`last_insert_id` int NOT NULL,`insert_id` int NOT NULL,`server_id` int unsigned NOT NULL,`sql_text` mediumblob NOT NULL,`thread_id` bigint unsigned NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8mb3 COMMENT='Slow log'
3.4 错误日志
错误⽇志⼀般会记录mysqld 启动和关闭的次数、诊断消息,以及服务器运⾏期间发⽣的错误和警
告;例如MySQL需要⾃动检查或修复⼀个表,就会在错误⽇志中写⼊⼀条记录。错误⽇志默认使⽤ UTF-8 ( utf8mb3 )编码格式,并使⽤英语⽣成记录
错误⽇志输出的位置,可以是控制台或指定⽂件,"控制台"表⽰ stderr 标准错误输出。
Windows 的默认错误日志路径
在Windows系统中,mysqld使⽤ --log-error(文件路径) 和 --console(控制台) 选项来确定默认的错误⽇志⽬标
是控制台还是⽂件,规则如下:
• 如果指定了 --console 选项,默认在控制台输出错误⽇志,如果 --console 和 --log
error 同时指定,则 --console 优先级更⾼,并且 --log-error 将失效。
• 如果没有指定 --log-error 或者没有指定具体的⽂件名,默认在数据⽬录中⽣成名为
host_name.err 的⽇志⽂件。
• 可以通过指定绝对路径,来更改默认的⽇志位置。
[mysqld]
log-error=D:/log/MySQL/Error/error_log.err # ⾃定义错误⽇志的路径
Unix 和Linux 系统的默认错误⽇志路径
在 Unix 和Linux 系统中,mysqld使⽤ --log-error 选项来指定默认错误⽇志⽬标,可以指定控制
台或是⽂件,如果是⽂件,规则如下:
• 如果错误⽇志输出⽬标是控制台,则服务器将 log_error 系统变量设置为 stderr . 否则,将
以⽂件形式输⼊错误⽇志,并以 log_error 的值为⽂件名。
• 如果显⽰写出 --log-error 但没有指定具体⽂件,则默认路径是数据⽬录中 host_name.err 的⽂件;
• 可以通过指定绝对路径,来更改默认的⽇志位置
[mysqld]
log-error=/var/log/mysql/error_log.err # ⾃定义错误⽇志的路径
错误日志中事件的字段
time :件时间戳,精度为微秒;
msg :事件消息字符串;
prio :事件优先级,包括 System event - 系统(0)、 Error event - 错误(1)、 Warning
event - 警告(2)或 Note/information event - 通知/提⽰事件(3),值越⼩优先级越⾼;
err_code :事件错误代码;
err_symbol :以字符串形式表⽰的事件错误符,例如 'ER_DUP_KEY' ;
SQL_state :事件 SQLSTATE 值,与 err_symbol 对应,例如 'ER_DUP_KEY' 对应的
SQLSTATE为23000
subsystem :事件发⽣的⼦系统。可能的值: InnoDB (InnoDB存储引擎)、 Repl (复制⼦系
统)、 Server (其他)。

当MySQL服务启动失败时,首先要查看一下错误日志
可选错误事件字段
OS_errno :操作系统错误号;
OS_errmsg :操作系统错误消息;
label :与值对应的 prio 描述 ;
user :客⼾端⽤⼾;
host :客⼾端主机;
thread :产⽣错误事件 的线程的 ID;
query_id :查询 ID。
可以通过以下SQL查看已定义的错误类型
mysql> SELECT *FROM performance_schema.events_errors_summary_global_by_errorWHERE SUM_ERROR_RAISED <> 0\G
刷新错误⽇志⽂件和重命名
• 如果使⽤ FLUSH ERROR LOGS(当重新打开时找不到日志文件就会重新生成一个新的) 、 FLUSH LOGS 语句或 mysqladmin flush-logs 命令刷
新错误⽇志,服务器会将正在写⼊的任何错误⽇志⽂件关闭并重新打开。
• 如果要⼿动重命名错误⽇志⽂件,可以在重命名操作之后执⾏刷新操作,服务器会以原⽂件名⽣成 ⼀个新的错误⽇志⽂件,例如⽇志⽂件名为 host_name.err ,可以按以下步骤操作:
mv host_name.err host_name.err-old # 重命名⽇志⽂件
mysqladmin flush-logs # 刷新操作
mv host_name.err-old backup-directory # 把重命名的⽇志⽂件移动到备份⽬录
3.5 二进制日志
简介:
• ⼆进制⽇志包含数据库更改的"事件",不会记录 SELECT 和 SHOW ,例如:记录表的创建操作或表数据的更改,⼆进制⽇志还包含每个语句更新数据时花费的时间信息,启动⼆进制⽇志,对服务器性能稍微有些影响(因为涉及到磁盘的IO)
• 除了基于⾏的⽇志模式,它还包含可能进⾏更改数据的语句事件,例如 DELETE 操作没有匹配到
查找到的⾏;
• ⼆进制⽇志的作⽤:
◦ 主从节点数据复制:从节点服务器读取主节点服务器上的⼆进制⽇志⽂件,并根据⼆进制⽇志
中记录的事件在从节点上执⾏相同的操作,保证主从节点服务器上数据⼀致,实现数据复制功
能。
◦ 数据恢复:从某个时间点恢复备份数据后,将重新执⾏备份时间点之后记录在⼆进制⽇志中的
事件。这些事件使数据库从备份点更新到当前最新状态。
• ⼆进制⽇志的语句中如果涉及⽤⼾的密码,则由服务器进⾏加密,不会以纯⽂本形式出现
选项和变量
• 查看⼆进制⽇志相关的系统变量
mysql> show variables like '%bin%';
• 查看⼆进制⽇志相关的状态变量
mysql> show status like '%bin%';
• 默认情况下启⽤⼆进制⽇志, log_bin 系统变量为 ON ;
• 禁⽤⼆进制⽇志,可以指定 --skip-log-bin 或 --disable-log-bin 选项。如果同时指定了 --log-bin 则后指定的选项优先;
• 选项 --log-bin[=base_name] ⽤于指定⼆进制⽇志⽂件的基本名称,如果不指定 --log bin 选项,默认基本名称为 binlog ,建议为⼆进制⽇志指定⼀个基本名;
• ⼆进制⽇志⽂件名是由基本名+数字扩展名组成的,服务器每次创建⼀个新的⽇志⽂件时,数字扩展名都会增加,从⽽保证有序的⽂件系列,发⽣以下事件时,服务器都会在创建⼀个新的⽇志⽂件:
◦ 服务器已启动或重新启动
◦ 服务器刷新⽇志
◦ 当前⽇志⽂件的⼤⼩达到 max_binlog_size (单个⽇志⽂件的最⼤字节数,最⼩值 4096 字
节,最⼤值和默认值 1GB).
⼆进制⽇志⽂件⼤⼩可能会超出 max_binlog_size 设定的值,因为⼆进制⽇志在记录事务
时,会完整的记录整个事务,不存在把⼀个事务拆分的情况,如果遇到⼀个⼤事务时,即使记录
整个事务会超过⽇志⼤⼩限制,也会保证事务的完整性
二进制日志以事物为单位记录日志
•mysqld还会创建⼀个包含⼆进制⽇志⽂件名的⽇志索引⽂件,默认情况下,这与⼆进制⽇志⽂件
具有相同的基本名称,扩展名为 .index . 可以使⽤选项 --log-bin-index[=file_name] 修改索引⽂件名;
• ⼆进制⽇志⽂件和索引⽂件的默认位置是数据⽬录。可以使⽤ --log-bin[=file_name] 选项
指定⾃定义路径, file_name 格式 = 绝对路径+基本名。 --log-bin 对应的系统变量是
log_bin_basename ;
• MySQL 5.7 中,启⽤⼆进制⽇志必须指定服务器 ID,对应 server_id 选项,否则服务器将⽆法
启动。在 MySQL 8.0 中, server_id 系统变量默认设置为 1,在集群环境中,每台MySQL服务
器必须有唯⼀的 server_id ;
• ⼆进制⽇志记录事件⽀持三种格式类型:基于⾏的⽇志记录、基于语句的⽇志记录和混合⽇志记
录,稍候具体介绍;
• ⼆进制⽇志记录在语句或事务完成之后,释放锁或在提交完成之前进⾏。这样做是为了确保按照提交顺序记录⽇志;
• 在⼀个未提交的事务中,对⽀持事务的表(如InnoDB表)的更改都会被缓存(UPDATE, DELETE或
INSERT),直到服务器收到 COMMIT 语句,mysqld在执⾏ COMMIT 之前将整个事务写⼊⼆进制⽇志;
• 如果事务回滚,则在整个事务中记录⼀个 ROLLBACK 语句,但是对⾮事务性表(如MyISAM表)的修改不能回滚,所以这些修改将被复制到从节点;
• 对⾮事务表的更新在执⾏后⽴即存储在⼆进制⽇志中;
• 当处理事务的线程启动时,它会分配⼀个⼤⼩为 binlog_cache_size 的缓冲区来缓存语句。如
果语句⼤⼩⼤缓冲区的值,线程则打开⼀个临时⽂件来存储事务,临时⽂件在线程结束时删除;
• Binlog_cache_use 状态变量显⽰使⽤该缓冲区(可能还有临时⽂件)存储事务的数量;
Binlog_cache_disk_use 状态变量显⽰有多少事务实际上使⽤了临时⽂件。结合这两个变量
可以把 binlog_cache_size 调优到⼀个⾜够⼤的值,从⽽避免使⽤临时⽂件;
• 系统变量 max_binlog_cache_size (默认值和最⼤值都是 4GB,最⼩值为 4096)⽤于限制
缓存区⼤⼩,如果事务语句⼤于这个值指定的字节数,事务将会失败并回滚;
• 如果使⽤基于⾏的⽇志记录⽅式, 为了保证⽇志的准确性, CREATE ... SELECT 或
INSERT ... SELECT 语句的并发插⼊将转换为普通插⼊;如果使⽤基于语句的⽇志记录⽅
式,则将原始语句写⼊⽇志。
• 由于服务器崩溃或其他原因,导致对⼆进制⽇志⽂件⽆法进⾏写⼊、刷新或者同步到磁盘。那么主从节点上的⽇志就会出现不⼀致,当遇到这种问题时,可以通过系统变量binloglog_error_action 控制处理⽅式:
◦ 默认值 ABORT_SERVER ,服务器停⽌⼆进制⽇志记录并关闭,排查完问题并重启后,服务器
按意外停⽌执⾏恢复操作;
◦ IGNORE_ERROR 表⽰,服务器继续进⾏当前的事务并记录错误,然后停⽌⽇志记录,排查问
题后,需要确认启⽤ log_bin ,然后再次启动服务器,对⽇志要求不⾼的场景可以设置此
值,不推荐在集群环境使⽤;
• 默认情况下, sync_binlog=1 ,表⽰每个事务在写⼊缓存后⽴即同步到磁盘,也可以设置为其
他值,⽐如 sync_binlog=N 表⽰N次事务提交到缓存之后再同步到磁盘,如果
sync_binlog=0 则MySQL不控制同步磁盘的频率,完全由操作系统控制。需要注意:如果当
sync_binlog 的值设置为 0 或 N 那么当服务器崩溃时,缓上存中的有些⽇志不能同步到磁
盘,可能造成⼀些更改丢失,所以 sync_binlog=1 是最安全的,但同时效率也是最低的。
• 可以使⽤ RESET MASTER 语句删除所有⼆进制⽇志⽂件,或者使⽤ PURGE binary LOGS 删
除⼀部分⼆进制⽇志⽂件,具体演⽰:
# 重置⼆进⾏⽇志⽂件和索引⽂件为初始状态
mysql> RESET MASTER; # 删除指定⽇志⽂件之前的所有⽇志⽂件并更新索引
mysql> PURGE BINARY LOGS TO 'mysql-bin.010';
# 删除指定时间之前的所有⽇志⽂件并更新索引
mysql> PURGE BINARY LOGS BEFORE '2019-04-02 22:46:26'
TIPS:
术语 "⼆进制⽇志⽂件" 通常表⽰包含单独编号的⽇志⽂件。术语 "⼆进制⽇志" 表⽰所有⼆进制⽇志⽂件和索引⽂件
查看二进制日志
使⽤客⼾端⼯具mysqlbinlog查看
mysqlbinlog binlog.000001 > binlog.000001-二进制日志名 -导出的目标文件名
• 通过SQL语句查看
mysql> show binlog events in 'binlog.000001' from N limit S;

⼆进制⽇志格式
记录⼆进制⽇志时使⽤的格式有以下⼏种:
• 基于语句的⽇志格式,最初MySQL 是基于 SQL 语句复制实现主从节点同步,通过指定选项 --
binlog-format=STATEMENT 使⽤此格式 。
• 基于⾏的⽇志格式(默认)中,主节点将事件写⼊⼆进制⽇志,表⽰各个表的⾏受到的影响,可以通过指定选项 --binlog-format=ROW 使⽤此格式 。
• 混合⽇志记录格式,默认情况下使⽤基于语句的⽇志记录,如果MySQL认为基于语句的格式不能保证主从复制过程中的数据安全时,会⾃动切换到基于⾏的⽇志格式,⽐如主节点在语句中⽤了
UUID() 函数,那么⽇志⽂件中记录的是UUID⽣成的真实值⽽不是直接使⽤原始的SQL语句,使
⽤混合⽇志格式中以指定选项 --binlog-format=MIXED 。
TIPS: 设置⼆进制⽇志格式
--binlog-format=[STATEMENT|ROW|MIXED]
• 基于语句与基于⾏的区别:
# 基于语句,记录执⾏的SQL语句
-执行了什么语句就原封不动的记录相应的SQL
update student set age = 18 where id between 10 and 20;# 基于⾏,记录每⼀⾏的更改
-当使用MySQL内部的一些函数时,必须以行的格式记录日志
-当主节点执行了UUID函数的时候,会记录生成的具体的值
update student set age = 18 where id = 10;
update student set age = 18 where id = 11;
update student set age = 18 where id = 12;
...
update student set age = 18 where id = 19;
update student set age = 18 where id = 20;
3.6 Redo Log 和 Undo Log
Redo Log :重做⽇志,⽤于恢复数据(对于已经提交的事务崩溃重启之后,依旧可以重新执行并写入磁盘)
Undo Log :撤消⽇志⽤于回滚操作;
3.7 服务器日志维护
MySQL 服务器可以创建多种不同的⽇志⽂件来帮助我们查看服务器的活动。但是必须定期清理这
些⽂件,以免⽇志占⽤过多的磁盘空间。在启⽤⽇志的情况下,通常希望备份和删除旧的⽇志⽂件,并把⽇志写到新⽂件。
• 默认⼆进制⽇志的过期时间为30天,过期后将⾃动删除,要指定⾃定义过期时间,可以使⽤系统变量 binlog_expire_logs_seconds=N 单位为秒,在下⼀次启动服务器和刷新⽇志时删除过期
⽇志⽂件;
• 强制使⽤新的⽇志⽂件可以⼿动刷新⽇志,当执⾏ FLUSH LOGS 语句或 mysqladmin flush
logs 、 mysqladmin refresh 、 mysqldump --flush-logs 、 mysqldump -- master-data 命令时,会发⽣⽇志刷新。此外当⼆进制⽇志⽂件⼤⼩达到 max_binlog_size 系统变量指定的值时,服务器会⾃动刷新⼆进制⽇志。
• FLUSH LOGS ⽀持可选的修饰符以启⽤个别⽇志的选择性刷新:
FLUSH BINARY LOGS # 刷新⼆进制⽇志
FLUSH ERROR LOGS # 刷新错误⽇志
FLUSH GENERAL LOGS # 刷新⼀般查询⽇志
FLUSH RELAY LOGS # 刷新中继⽇志
FLUSH SLOW LOGS # 刷新慢查询⽇志
• 刷新⼀般查询⽇志、慢查询⽇志或错误⽇志只是关闭并重新打开⽇志⽂件,如果要备份可以先重命名再执⾏刷新操作,⽐如⼀般查询⽇志、慢查询⽇志或错误⽇志⽂件名分别为: mysql.log 、
mysql-slow.log 和 err.log ,可以在命令⾏中使⽤如下⼀系列命令:
cd mysql-data-directory #进⼊⽇志⽬录
mv mysql.log mysql.log.old #重命名⼀般查询⽇志
mv mysql-slow.log mysql-slow.log.old #重命名慢查询⽇志
mv err.log err.log.old #重命名错误⽇志
mysqladmin flush-logs #刷新⽇志
要在运⾏时重命名⼀般查询⽇志或慢查询⽇志
◦ ⾸先连接到服务器并禁⽤⽇志:
SET GLOBAL general_log = 'OFF';
SET GLOBAL slow_query_log = 'OFF';
◦ 在禁⽤⽇志的情况下,重命名⽇志⽂件,例如⽤ mv 命令从命令⾏执⾏重命名操作
◦ 再次启⽤⽇志:
SET GLOBAL general_log = 'ON';
SET GLOBAL slow_query_log = 'ON';
◦ 这种⽅法适⽤于任何平台且不需要重启服务器
3.8 配置日志输出位置
# 服务器节点
[mysqld]
# ⼀般查询⽇志和慢查询⽇志记录⽅式为⽂件
log-output=FILE
# 开启⼀般查询⽇志
general-log=1
# ⼀般查询⽇志路径和⽂件名
general_log_file=/var/log/mysql/general.log
# 开启慢查询⽇志
slow-query-log=1
# 慢查询⽇志路径和⽂件名
slow_query_log_file=/var/log/mysql/slow-query.log
# 慢查询⽇志时间限制
long_query_time=10
# 错误⽇志路径和⽂件名
log-error=/var/log/mysql/error.err
# ⼆进制⽇志路径和基本名
log-bin=/var/log/mysql/binlog
# 服务器编号
server-id=1
4. mysql System Schema(mysql系统库)
Mysql Schema是⼀个系统库,表中存储了MySQL服务器运⾏时所需的信息。⼴义上,mysql
schema包含存储数据库对象元数据的数据字典和⽤于其他操作⽬的的系统表。数据字典表和系统表位于数据⽬录下⼀个名为 mysql.ibd 的表空间⽂件中,使⽤的是InnoDB存储引擎。
数据字典和系统表都是保存数据库对象属性的存储结构
4.1 数据字典
• MySQL 的数据字典,⽤来存储有关数据库对象⾃⾝的信息,不可以随意修改,否则可能造成服务器⽆法运⾏:以下列出⼏个常⻅的数据字典表:
◦ character_sets :有关可⽤字符集的信息 utf8mb4
◦ check_constraints :有关表上定义的 CHECK 约束的信息
◦ collations :每个字符集的排序规则信息
◦ column_type_elements :列类型的信息
◦ columns :有关表中列的信息
◦ indexes : 有关表索引的信息
◦ tables :有关数据库中表的信息
◦ tablespace_files :有关表空间使⽤的⽂件信息
◦ tablespaces :有关活动表空间的信息
◦ triggers :有关触发器的信息
• 数据字典表是受保护的,只能在调试版本中访问,在发⾏版中没有权限访问,如果在发⾏版本中查询表中的数据,出提⽰拒绝访问:
mysql> select * from mysql.character_sets; # 访问可⽤字符集的信息
ERROR 3554 (HY000): Access to data dictionary table 'mysql.catalogs' is
rejected.
• INFORMATION_SCHEMA 实现了某些数据字典的视图,可以通过视图查看某些数据字典的内容:
# 通过INFORMATION_SCHEMA中的视图访问可⽤字符集的信息
mysql> SELECT * FROM INFORMATION_SCHEMA.CHARACTER_SETS;
4.2 系统表
系统表按功能⼤致可以分为以下⼏类:权限授予系统表、对象信息系统表、⽇志系统表、服务器端帮助系统表、时区系统表、复制系统表、优化器系统表、杂项系统表。mysql系统库中的表如下所⽰:
mysql> use mysql
Database changed
mysql> show tables;
.....
权限授予系统表
包含有关⽤⼾帐⼾及帐⼾拥有的权限授权信息,主要的表有:
• user :⽤⼾帐⼾、全局权限和其他列。
• global_grants :为⽤⼾分配的动态全局权限;
• db :数据库级权限。
• tables_priv :表级权限。
• columns_priv : 列级权限。
• procs_priv : 存储过程和函数权限。
• proxies_priv : 代理⽤⼾权限。
• default_roles :列出了⽤⼾连接和认证后要激活的默认⻆⾊。
• role_edges : user 表的关联表,区分 user 表中某⼀⾏记录是帐⼾还是⻆⾊
• password_history :密码更改的信息
对象信息系统表
包含有关组件、可加载的服务器插件和函数的信息:
component :使⽤ INSTALL COMPONENT 安装的服务器组件,表中列出了在服务器启动期间安装的组件。
func : 使⽤ CREATE FUNCTION 安装的可加载函数,表中列出了在服务器启动期间加载的函数。
plugin :使⽤ INSTALL PLUGIN 安装的服务器插件,表中列出了在服务器启动期间安装的插
件。
日志系统表
服务器使⽤⽇志系统表进⾏⽇志记录:
• general_log :⼀般查询⽇志表。
• slow_log :慢查询⽇志表。
⽇志表使⽤ CSV 存储引擎
服务器端帮助系统表
包含服务器端帮助信息:
• help_category :有关帮助类别的信息。
• help_keyword :与帮助主题关联的关键字。
• help_relation :帮助关键字和主题之间的映射。
• help_topic :帮助主题内容
时区系统表
包含时区信息:
• time_zone :时区 ID 以及是否使⽤闰秒。
• time_zone_leap_second :发⽣闰秒时如何修正。
• time_zone_name : 时区 ID 和名称之间的映射。
• time_zone_transition , time_zone_transition_type : 时区说明及偏移量。
复制系统表
服务器使⽤以下系统表来⽀持复制
• gtid_executed :⽤于存储 GTID 的值。
• ndb_binlog_index :⽤于NDB Cluster 复制的⼆进制⽇志信息。只有在⽀持 NDB
CLUSTER 的服务器才会创建此表,我们的课程不讨论NDB 的相关内容
• slave_master_info , slave_relay_log_info , slave_worker_info : ⽤于存储从节点服务器上的复制信息。
以上⼏张表都使⽤ InnoDB 存储引擎。
优化器系统表
这些系统表供优化器使⽤:
• innodb_index_stats , innodb_table_stats : ⽤于 InnoDB 的持久优化器统计信息。
• server_cost , engine_cost :优化器成本模型使⽤的表,包含查询期间发⽣的操作成本估
算信息。 server_cost 包含服务器操作的优化器成本估算。 engine_cost 包含对特定存储
引擎操作的估计。
杂项系统表
audit_log_filter , audit_log_user : 如果安装了 MySQL Enterprise Audit,存储审计⽇志过滤器定义和⽤⼾帐⼾。
• firewall_group_allowlist , firewall_groups , firewall_memebership ,
firewall_users , firewall_whitelist :如果安装了 MySQL Enterprise Firewall,这
些存储表防⽕墙的使⽤信息。
• servers :由 FEDERATED 存储引擎使⽤。
• innodb_dynamic_metadata :由 InnoDB 存储引擎⽤来存储快速变化的表元数据,例如⾃
动递增计数器值和索引树损坏标志。
5.在一台机器上运行多个MySQL实例
• 有时候我们希望在⼀台机器上运⾏多个 MySQL 实例,⽐如在开发环境测试新的MySQL版本,同时⼜要保证原有的版本不受影响;MySQL 允许在⼀台机器上安装不同版本的发⾏版,⽐如同时运⾏5.7和8.0版本,只是要做⼀些相应的配置。



具体看WPS
6.面试题
介绍⼀下你知道的MySQL服务器配置⽂件的选项
这个问题主要考察选项的使⽤,回答这个问题可以先总体描述选项⽂件的使⽤场景,再介绍⼏个常⻅的选项即可
1. 选项⽂件主要作⽤是设置MySQL服务常⽤的系统变量初始值,以便服务器启动时⾃动读取;
2. 选项⽂件中可以⽤ [程序名] 的形式分别为不同的程序指定具体选项的值,也可以⽤
[client] 、 [server] 的形式分别指定客⼾端程序和服务器程序公共配置。
3. 常⻅的选项有,客⼾端和服务器使⽤的字符集,客⼾端默认的⽤⼾名和密码,服务器的排序规则,服务器的端⼝号,⾃定义数据⽬录的路径,⽇志⽂件的路径,服务器允许的最⼤连接数,还有⼀些关于存储引擎的选项也可以⽤于性能调优,⽐如关于INNODB的选项,等等