通常所说的MySQL服务器指的是mysqld程序,当运⾏mysqld后对外提供MySQL服务,这个专题的内容涵盖了以下关于MySQL服务器以及相关配置的内容,包括:
• 服务器⽀持的启动选项。可以在命令⾏和配置⽂件中指定这些选项。
• 服务器系统变量。反映了启动选项的当前状态和值,其中⼀些变量可以在服务器运⾏时修改。(系统变量可以被修改)
• 服务器状态变量。这些变量包含了有关运⾏时操作的计数器和统计信息。(状态变量不能被修改,只是代表了当前的状态,是一个指示器)
• 服务器如何管理客⼾端连接。
• 配置和使⽤时区⽀持。
• 服务器端帮助功能。
mysql有很多选项和系统变量可以在启动时进行配置,要查看服务器的默认选项和系统变量值,可以执行以下命令:
bash
mysqld --verbose --help
可以这样查看服务器再运行时系统变量的值,连接到MySQL并执行以下语句:
bash
SHOW VARIABLES;
可以这样查看服务器在运行时的一些统计和状态指示器:
bash
SHOW STATUS;
系统变量和状态信息也可以用mysqladmin命令来查看:
bash
mysqladmin variables
bash
mysqladmin extended-status
关于服务器的选项、系统变量、状态变量可以参考:
系统变量:
系统变量状态变量的作用域分为:Global(全局),Session(当前会话或者连接)或者二者都支持
解释一下这张表的选项,NAME是变量名,Cmd-Line是是否支持CMD,Option File是是否支持选项文件,System Var是这个是不是一个系统变量,Status Var是是否是一个状态变量,Var Scope是作用域,Dynamic是是否支持动态修改
系统变量和选项
当通过mysqld启动数据库服务器时,可以通过选项文件或者命令行中提供选项,但是在大多数情况下,为了确保服务器每次运行都使用相同的选项,最好的方法是在选项文件中指定相应的选项
mysqld从选项文件中的mysqld和server组(节点)中读取选项内容
mysqld接受的选项可以通过mysql --verbose --help查看,列表中的有些项目是可以在服务器启动时设置的系统变量,系统变量可以连接在MySQL后使用SHOW VARIABLES语句查看,但有些内容是只在--help中存在,SHOW VARIABLES时并没有显示,因为它们只是选项而不是系统变量
tips:选项值可以通过命令行和选项文件设置,部分系统变量可以通过SET语句动态设置值
latin1字符集不能保存中文
使用系统变量
如果数据库服务在公网部署,建议修改默认端口号
修改数据目录的时候,直接把Data目录整体复制到目标路径,在安装MySQL的过程中,会设置一些用户自定义的值,比如root用户的密码,这些值在MySQL启动的时候会从系统中读取
这是/etc/mysql下面的内容:
最终编写的是mysql.cnf
服务器自带的磁盘用来安装OS和其他的程序,比如MySQL
用来存储数据的设备(比如磁盘阵列)容量比较大
设置系统变量的语法与命令选项的语法相同,指定变量名称时,--和_可以互换使用
当使用选项设置一个数值的变量的时候,可以带有后缀K/M/G表示1024/1024^2/1024^3
从MySQL8.0.16开始,后缀也可以用T/P/E来表示1024^4/1024^5/1024^6
例:为服务器指定256KB的排序缓冲区大小和1GB的最大数据包大小
cpp
mysqld --sort-buffer-size=256K --max-allowed-packet=1G
也可以在选项文件中指定:
sql
[mysqld]
sort_buffer_size=256k
max_allowed_packet=1g
系统变量有两个作用域:GLobal和Session,Global全局变量影响服务器的整体操作,Session会话变量影响各个客户端连接的操作,给定的系统变量可以同时具有全局值和会话值:
🍿 服务器启动时会将每个全局变量初始化并设置默认值,具体的值可以通过命令行或选项文件更改
🍿 服务器为每个客户端维护一组session变量,在客户端连接时使用相应全局变量的当前值进行初始化
大部分系统变量是动态的,在服务器运⾏时可以通过SET 语句动态更改,并且⽆需停⽌和重新启 动服务器。在服务器运⾏时,使⽤ SET 语句设置系统变量,需要指定作⽤域(也可以在前⾯加上 @@ 修饰符),然后指定系统变量的名称,名称必须使⽤下划线⽽不是破折号:
🎃设置全局系统变量最大连接数为1000
sql
SET GLOBAL max_connections = 1000;
SET @@GLOBAL.max_connections = 1000;
sql
RESET PERSIST IF EXISTS system_var_name;
🦕将全局系统变量持久化到mysqld-auto.cnf文件(同时设置运行值):
sql
SET PERSIST max_connections = 1000;
SET @@PERSIST.max_connections = 1000;
🦖将全局系统变量持久化到mysqld-auto.cnf ⽂件(不设置运⾏时值):
sql
SET PERSIST_ONLY max_connections = 1000;
SET @@PERSIST_ONLY.max_connections = 1000;
🐡删除持久化的系统变量可以使用语句:
sql
RESET PERSIST IF EXISTS system_var_name;
🐺 设置Session系统变量,时区为"+8:00":
sql
SET SESSION time_zone='+8:00';
SET @@SESSION.time_zone='+8:00';
SET @@time_zone='+8:00';
对于数值型的系统变量,用带有后缀的值指定时,只适用于选项方式,而不能用在SET方式,SET方式可以使用表达式为系统变量指定值,而在选项方式中不允许:
sql
# 选项形式
root@hcss-ecs-d24c:~# mysqld --max_allowed_packet=16M # 允许
root@hcss-ecs-d24c:~# mysqld --max_allowed_packet=16*1024*1024 # 不允许
# 运⾏时SET形式
mysql> SET GLOBAL max_allowed_packet=16M; # 不允许
mysql> SET GLOBAL max_allowed_packet=16*1024*1024; # 允许
tips:在设置全局变量时需要指定GLOBAL关键字的原因是为了防止出现:
🦅 如果要删除的SESSION变量与GLOBAL变量名相同,那么具有修改全局变量权限的客户端可能会意外的更改GLOBAL变量,而不仅仅是只修改SESSION变量
🐴 如果已经有一个SESSION变量而且与GLOBAL变量同名,那么本意是要修改GLOBAL变量,可能只是修改了SESSION变量的值
所以没有明确指定GLOBAL和SESSION时,对于当前客户端来说SESSION的优先级更高
要显示系统变量名称和值可以使用这些语句:
sql
mysql> SHOW VARIABLES;
🐗可以使用LIKE子句显示与指定内容匹配的变量,也可以使用通配符
sql
# 查看指定的系统变量
SHOW VARIABLES LIKE 'max_join_size';
# 查看指定系统变量SESSION作⽤域的值
SHOW SESSION VARIABLES LIKE 'max_join_size';
# 查看包含指定内容的系统变量
SHOW VARIABLES LIKE '%size%';
# 查看包含指定内容系统变量的GLOBAL作⽤域的值
SHOW GLOBAL VARIABLES LIKE '%size%';
🐺 一部分的系统变量是内置的,也有一些需要通过安装服务器插件或者组件才能用
🦄 ⽤于审计插件 audit_log 实现了名为 audit_log_policy 的系统变量
🦉错误⽇志过滤组件 log_filter_dragnet 实现了名为log_error_filter_rules 的系统变量
服务器常用配置:
只说里牛渴死下的环境:
tips:
编辑前先备份原始文件
如果要修改数据目录选项建议先停止MySQL服务,并把原data目录整体复制到新路径,配置完成后重启服务
在[mysqld]节点添加以下内容:
sql
# 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
查看状态变量
MySQL服务器维护着当前系统信息的状态变量
可以使用SHOW[GLOBAL | SESSION] STATUS [like status_name];语句查看这些变量和对应的值
GLOBAL显示所有链接的值,SESSION显示当前链接的值
MySQL数据目录
MySQL服务器的管理信息(用户自身的数据,比如用户名和密码、用户的授权、系统变量的默认值、用户创建的库和表都要维护起来)、业务数据(用户创建的库和表及表中的数据)、日志文件、磁盘缓冲文件默认存储在数据目录(MySQL工作时主要操作的目录,最重要的一个目录,没有之一)下,数据目录:
就上面的binlog是二进制日志
sql
-rw-r----- 1 mysql mysql 201 Sep 24 00:00 binlog.000030
-rw-r----- 1 mysql mysql 201 Sep 25 00:00 binlog.000031
-rw-r----- 1 mysql mysql 201 Sep 26 00:00 binlog.000032
-rw-r----- 1 mysql mysql 201 Sep 27 00:00 binlog.000033
-rw-r----- 1 mysql mysql 201 Sep 28 00:00 binlog.000034
-rw-r----- 1 mysql mysql 201 Sep 29 00:00 binlog.000035
-rw-r----- 1 mysql mysql 201 Sep 30 00:00 binlog.000036
-rw-r----- 1 mysql mysql 201 Oct 1 00:00 binlog.000037
-rw-r----- 1 mysql mysql 201 Oct 2 00:00 binlog.000038
-rw-r----- 1 mysql mysql 201 Oct 3 00:00 binlog.000039
-rw-r----- 1 mysql mysql 201 Oct 4 00:00 binlog.000040
-rw-r----- 1 mysql mysql 201 Oct 5 00:00 binlog.000041
-rw-r----- 1 mysql mysql 201 Oct 6 00:00 binlog.000042
-rw-r----- 1 mysql mysql 201 Oct 7 00:00 binlog.000043
-rw-r----- 1 mysql mysql 201 Oct 8 00:00 binlog.000044
-rw-r----- 1 mysql mysql 201 Oct 9 00:00 binlog.000045
-rw-r----- 1 mysql mysql 201 Oct 10 00:00 binlog.000046
-rw-r----- 1 mysql mysql 201 Oct 11 00:00 binlog.000047
-rw-r----- 1 mysql mysql 201 Oct 12 00:00 binlog.000048
-rw-r----- 1 mysql mysql 201 Oct 13 00:00 binlog.000049
-rw-r----- 1 mysql mysql 201 Oct 14 00:00 binlog.000050
-rw-r----- 1 mysql mysql 201 Oct 15 00:00 binlog.000051
-rw-r----- 1 mysql mysql 201 Oct 16 00:00 binlog.000052
-rw-r----- 1 mysql mysql 201 Oct 17 00:00 binlog.000053
-rw-r----- 1 mysql mysql 201 Oct 18 00:00 binlog.000054
-rw-r----- 1 mysql mysql 948 Oct 19 00:00 binlog.000055
-rw-r----- 1 mysql mysql 201 Oct 20 00:00 binlog.000056
-rw-r----- 1 mysql mysql 201 Oct 21 00:00 binlog.000057
-rw-r----- 1 mysql mysql 24256 Oct 22 00:00 binlog.000058
-rw-r----- 1 mysql mysql 2166924 Oct 23 00:00 binlog.000059
-rw-r----- 1 mysql mysql 157 Oct 23 00:00 binlog.000060
下面的.pem是自动生成的SSL和RSA证书和密钥文件:
sql
-rw------- 1 mysql mysql 1705 Aug 29 22:53 ca-key.pem
-rw-r--r-- 1 mysql mysql 1112 Aug 29 22:53 ca.pem
-rw-r--r-- 1 mysql mysql 1112 Aug 29 22:53 client-cert.pem
-rw------- 1 mysql mysql 1701 Aug 29 22:53 client-key.pem
sql
-rw------- 1 mysql mysql 1705 Aug 29 22:53 private_key.pem
-rw-r--r-- 1 mysql mysql 452 Aug 29 22:53 public_key.pem
-rw-r--r-- 1 root root 3785 Oct 22 23:18 query.sql
-rw-r--r-- 1 mysql mysql 1112 Aug 29 22:53 server-cert.pem
-rw------- 1 mysql mysql 1705 Aug 29 22:53 server-key.pem
这是双写缓冲区文件:
sql
-rw-r----- 1 mysql mysql 196608 Oct 23 00:00 '#ib_16384_0.dblwr'
-rw-r----- 1 mysql mysql 8585216 Oct 22 17:09 '#ib_16384_1.dblwr'
这是缓存了内存池中的数据:
sql
-rw-r----- 1 mysql mysql 3475 Sep 17 16:42 ib_buffer_pool
系统表空间,临时表空间:
sql
-rw-r----- 1 mysql mysql 12582912 Oct 23 00:00 ibdata1 //系统表空间
-rw-r----- 1 mysql mysql 12582912 Sep 17 16:43 ibtmp1 //临时表空间
这是保存重做日志的文件:
sql
drwxr-x--- 2 mysql mysql 4096 Oct 22 23:09 '#innodb_redo'/
这是保存系统级别的管理信息:
sql
-rw-r----- 1 mysql mysql 26214400 Oct 22 23:19 mysql.ibd
这是保存动态设置的系统变量:
sql
-rw-r----- 1 mysql mysql 175 Oct 23 17:05 mysqld-auto.cnf
这是撤销表空间,保存撤销日志的文件:
sql
-rw-r----- 1 mysql mysql 16777216 Oct 22 23:20 undo_001
-rw-r----- 1 mysql mysql 16777216 Oct 22 23:20 undo_002
用户创建数据库也会生成子目录
1.数据目录下的每个子目录都是一个数据库目录,对应服务器管理的一个数据库,包括MySQL安装成功后创建的标准数据库:
🦋 mysql目录对于mysql系统库包含mysql服务器运行时所需的信息,该数据库包含数据字典表和系统表
🐌 performance_schema⽬录对应于Performance Schema,提供了在运⾏时⽤于检查服务器内部执⾏的信息
🐞 sys⽬录对应于sys系统库,提供⼀组对象来帮助解释性能模式相关信息
🐜其他⼦⽬录对应于⽤⼾或应⽤程序创建的数据库,也就是说我们每创建⼀个数据库,就会在数据⽬录⽣成⼀个同名的⽬录来保存对应的数据
2.服务器写入的日志文件
3.InnoDB表空间和日志文件
4.默认或自动生成的SSL和RSA整数和密钥文件
5.服务器进程ID文件(服务器运行时)
6.mysqld-auto.cnf文件用来存储持久化全局系统变量设置
通过选项重新配置服务器,可以将上述某些项目重新定位到指定目录
使用--datadir选项允许更改数据目录本身的位置
日志
MySQL Server有以下的日志,可以记录服务器正在发生的活动:
默认情况下,除Windows上的错误⽇志外,不启⽤任何⽇志,Linux下默认开启错误⽇志和⼆进制 ⽇志
在服务器运⾏期间可以控制⼀般查询和慢查询⽇志的禁⽤与开启,也可以更改⽇志⽂件名
⼀般查询⽇志和慢查询⽇志记录可以写⼊⽇志表、⽇志⽂件或两者同时写⼊
默认情况下,所有启⽤的⽇志将写⼊数据⽬录,可以通过刷新⽇志强制服务器关闭并重新打开⽇志 ⽂件
通过 FLUSH LOGS 语句刷新⽇志来强制服务器关闭并重新打开⽇志⽂件,也可以使⽤ mysqladmin的flush-logs 或refresh 参数,或mysqldump的--flush-logs 或- -master-data 选项
中继⽇志仅⽤于主从复制过程中的从服务器。(来源于集群中的主服务)
一般查询日志和慢查询日志的输出形式
🐯如果启用一般查询日志和慢查询日志,日志的输出方式可以指定为日志文件或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 系统变量
🐶 一般查询日志记录了所有的查询语句,慢查询日志是一般查询日志的子集
没有配置日志路径时,使用默认的路径
这是一些例子:
将一般查询日志写入日志表和日志文件:
sql
[mysqld]
#⽇志写⼊表和⽂件
log_output=TABLE,FILE
#开启⼀般查询⽇志
general_log=1
这是仅将一般查询日志和慢查询日志写入表:
sql
[mysqld]
log_output=TABLE #⽇志写⼊表
general_log=1 #开启⼀般查询⽇志
slow_query_log=1 #开启慢查询⽇志
这是仅将慢查询日志写入日志文件:
sql
[mysqld]
log_output=FILE #⽇志⽂件
slow_query_log=1 #开启慢查询⽇志
这是将一般查询日志和慢查询日志写入日志文件,并指定自定义的日志路径:
sql
[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的值,可以更改日志的输出形式,通过语句控制
sql
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语句的条件查询过滤日志内容,从而选择满足特定条件的日志记录,,,可以通过客户端程序连接到服务器并查询表中的日志信息,无需登录服务器主机访问文件系统,,,日志记录具有标准格式,可看日志表的结构:
sql
SHOW CREATE TABLE mysql.general_log; # ⼀般查询⽇志
SHOW CREATE TABLE mysql.slow_log; # 慢查询⽇志
一般查询日志
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语句的顺序将语句写⼊查询⽇志,这个顺序可能与语句执行的顺序不同
sql
SHOW CREATE TABLE mysql.general_log;
表结构:
sql
CREATE TABLE `general_log` (
# 发⽣时间
`event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE
CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`thread_id` bigint unsigned NOT NULL,
`server_id` int unsigned NOT NULL,
`command_type` varchar(64) NOT NULL,
`argument` mediumblob NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8mb3 COMMENT='General log'
分别是:发生的时间 ,用户主机,执行当前SQL语句的系统线程ID,选项文件中配置的server-id,日志类型,具体的SQL
要确保是开开的才能有内容捏
之前的配置文件已经改过哩
查看表中的日志内容:
我们可以通过正常的SQL语句查询日志
我们可以通过CAST()函数把编码之后的内容转换为可读的字符类型
CAST(要转换的内容 AS 目标数据类型)
sql
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;
可以查看磁盘上的一般查询日志文件
慢查询日志
慢查询⽇志由执⾏时间超过系统变量 long_query_time 指定的秒数(默认是10s)的SQL语句组成,并且检查的⾏数⼤于系统变量 min_examined_row_limit指定值。(查询语句返回的结果集中锁包含的行数,比如10)
一个SQL语句执行经历的阶段:
1.执行线程获取到锁
2.执行SQL并返回结果
3.释放锁
被记录的慢查询需要进⾏优化, 可以使⽤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 BY...DESC
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语句结束时间
bash
SHOW CREATE TABLE mysql.slow_log;
sql
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'
分别是:开始的时间、用户和所在的主机、查询的总耗时、争抢MySQL级别的锁的时间、返回结果集中数据行的数量、服务器扫描表中的数据行的数量、数据库名、关于插入的记录、选项文件中配置的server id、具体执行的SQL 、执行线程id
建议使用日志文件的格式记录慢查询日志
慢查询日志大概长这样:
一般是以#开头
错误日志
错误日志输出的位置可以是控制台或指定文件,控制台表示stderr标准错误输出
在Windows系统中,mysqld使用--log-error和--console选项来确定默认的错误日志目标是控制台还是文件,规则是这样的:
如果制定了--console选项,默认在控制台输出错误日志,如果--console和--log-error同时指定,则--console优先级更高,并且--log-error将失效
如果没有指定,--log-error或者没有指定具体的文件名,默认在数据目录中生成名为host_name.err的日志文件
可以通过指定绝对路径来更改默认的日志位置:
sql
[mysqld]
log-error=D:/log/MySQL/Error/error_log.err # ⾃定义错误⽇志的路径
Unix和Linux系统的默认错误日志路径:
里牛渴死!这才是我该学的
在Linux和Unix系统中,mysqld使用--log-error选项来指定默认错误日志目标,可以指定控制台或者文件,如果是文件,规则:
如果错误日志输出目标是控制台,则服务器将log_error系统变量设置为stderr,否则,将以文件形式输入错误日志,并以log_error的值为文件名
如果显示写出--log-error但没有指定具体文件,则默认路径是数据目录中host_name.err的文件
可以通过指定绝对路径,来更改默认的日志位置:
sql
[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 (其他)
🙊可选错误事件字段:OS_errno :操作系统错误号
OS_errmsg :操作系统错误消息
label :与值对应的 prio 描述
user :客⼾端⽤⼾
host :客⼾端主机
thread :产⽣错误事件的线程的ID
query_id :查询ID
可以这样通过SQL查看已经定义的错误类型:
介素参考:
MySQL :: MySQL 8.0 Reference Manual :: 29.12.20.11 Error Summary Tableshttps://dev.mysql.com/doc/refman/8.0/en/performance-schema-error-summary-tables.html MySQL :: MySQL 8.0 Error Reference :: 4 Global Error Message Referencehttps://dev.mysql.com/doc/mysql-errors/8.0/en/global-error-reference.html
举个例子:
sql
2023-07-27T14:15:59.267828+08:00 1 [System] [MY-011012] [Server] Starting
upgrade of data directory.
2023-07-27T14:15:59.267942+08:00 1 [System] [MY-013576] [InnoDB] InnoDB
initialization has started.
2021-07-27T14:16:11.478109+08:00 1 [System] [MY-013577] [InnoDB] InnoDB
initialization has ended.
2023-07-27T14:16:11.719225+08:00 2 [Warning] [MY-010772] [Server] db.opt file
not found for binlog database. Using default Character set.
2023-07-27T14:16:11.731900+08:00 2 [ERROR] [MY-013140] [Server] Invalid utf8
character string: 'C9F3C5'
2023-07-27T14:16:11.733024+08:00 2 [ERROR] [MY-013140] [Server] Invalid utf8
character string: 'C9F3C5'
2023-07-27T14:16:12.687947+08:00 2 [Warning] [MY-010772] [Server] db.opt file
not found for tmpdir database. Using default Character set.
2023-07-27T14:16:12.992579+08:00 0 [ERROR] [MY-010022] [Server] Failed to
Populate DD tables.
2023-07-27T14:16:12.994141+08:00 0 [ERROR] [MY-010119] [Server] Aborting
2023-09-20T08:23:49.135468Z 1 [Note] A temporary password is generated for
root@localhost: S3Gw_#UBNoqf
分别是:
时间、优先级、错误码、子系统、日志详情
刷新错误日志文件和重命名
如果使用FLUSH ERROR LOGS(当重新打开时找不到日志文件就会重新生成一个新的)、FLUSH LOGS语句或mysqladmin flush-logs命令刷新错误日志,服务器会将正在写入的任何错误日志文件关闭并重新打开
如果要手动重命名错误日志文件,可以在重命名操作之后执行刷新操作,服务器会以原文件名生成一个新的错误日志文件,例如日志文件名为host_name.err,可以按照以下的步骤操作:
先找小孤独加入乐队!
开玩笑的,还是理工科:
sql
mv host_name.err host_name.err-old # 重命名⽇志⽂件
mysqladmin flush-logs # 刷新操作
mv host_name.err-old backup-directory # 把重命名的⽇志⽂件移动到备份⽬录
二进制日志
如果读写操作全在一台机器上
当数据量增大的时候,单台服务器可能会存在性能瓶颈 :比如访问量过大、机器配置、IO操用、网络带宽。。。
所以说不能只有一个服务器啊
得有从服务器(除了主服务器之外的其他服务器橙汁为从节点,主要处理的是查询操作)
主服务器主要用于写入操作
当数据写入到主节点之后,怎么把新写入的数据同步到其他的结点上呢?
主服务器所有的修改操作都生成二进制日志,转到从服务器上就是中继日志(中继日志是主节点二进制日志的一个复本,从节点执行中继日志的所有修改记录)
启用二进制日志对服务器性能有些影响
先来简单介绍一哈二进制日志
⼆进制⽇志包含数据库更改的"事件",不会记录 SELECT 和 SHOW ,例如:记录表的创建操作或 表数据的更改,⼆进制⽇志还包含每个语句更新数据时花费的时间信息,启动⼆进制⽇志,对服务 器性能稍微有些影响
除了基于⾏的⽇志模式,它还包含可能进⾏更改数据的语句事件,例如 DELETE 操作没有匹配到 查找到的⾏
⼆进制⽇志的作⽤:
主从节点数据复制:从节点服务器读取主节点服务器上的⼆进制⽇志⽂件,并根据⼆进制⽇志中记录的事件在从节点上执⾏相同的操作,保证主从节点服务器上数据⼀致,实现数据复制功能。
数据恢复:从某个时间点恢复备份数据后,将重新执⾏备份时间点之后记录在⼆进制⽇志中的事件。这些事件使数据库从备份点更新到当前最新状态。⼆进制⽇志的语句中如果涉及⽤⼾的密码,则由服务器进⾏加密,不会以纯⽂本形式出现。
⼆进制⽇志的语句中如果涉及⽤⼾的密码,则由服务器进⾏加密,不会以纯⽂本形式出现
二进制日志相关的系统变量:
可以查看二进制日志相关的状态变量:
sql
mysql> show status like '%bin%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Binlog_cache_disk_use | 0 |
| Binlog_cache_use | 0 |
| Binlog_stmt_cache_disk_use | 0 |
| Binlog_stmt_cache_use | 0 |
| Com_binlog | 0 |
| Com_show_binlog_events | 0 |
| Com_show_binlogs | 0 |
+----------------------------+-------+
7 rows in set (0.00 sec)
默认情况下启⽤⼆进制⽇志, log_bin 系统变量为ON ;
禁⽤⼆进制⽇志,可以指定--skip-log-bin 或--disable-log-bin 选项。如果同时指定了--log-bin 则后指定的选项优先;(不用指定值)
选项--log-bin[=base_name] ⽤于指定⼆进制⽇志⽂件的基本名称,如果不指定 --logbin选项,默认基本名称为 binlog ,建议为⼆进制⽇志指定⼀个基本名
⼆进制⽇志⽂件名是由基本名+数字扩展名组成的,服务器每次创建⼀个新的⽇志⽂件时,数字扩 展名都会增加,从⽽保证有序的⽂件系列,发⽣以下事件时,服务器都会在创建⼀个新的⽇志⽂件:
1.服务器已启动或重新启动
2.服务器刷新日志
3.当前日志文件的大小达到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;
MySQL5.7中,启用二进制日志必须指定服务器ID,对应server_id 选项,否则服务器将⽆法启动。在MySQL8.0中, server_id 系统变量默认设置为1,在集群环境中,每台MySQL服务器必须有唯⼀的server_id ;
二进制日志记录事件支持三种格式类型:基于行的日志记录,基于语句的日志记录和混合日志记录
在二进制日志记录在语句或事务完成之后,释放锁或在提交完成之前进行,这样做是为了确保按照提交顺序记录日志
由于服务器崩溃或其他原因,导致对⼆进制⽇志⽂件⽆法进⾏写⼊、刷新或者同步到磁盘。那么主 从节点上的⽇志就会出现不⼀致,当遇到这种问题时,可以通过系统变量 binloglog_error_action控制处理⽅式:
默认值 ABORT_SERVER ,服务器停⽌⼆进制⽇志记录并关闭,排查完问题并重启后,服务器按意外停⽌执⾏恢复操作;
IGNORE_ERROR 表⽰,服务器继续进⾏当前的事务并记录错误,然后停⽌⽇志记录,排查问题后,需要确认启⽤ log_bin ,然后再次启动服务器,对⽇志要求不⾼的场景可以设置此 值,不推荐在集群环境使⽤;
可以使用RESET MASTER语句删除所有的二进制文件,或者使用PURGE binary LOGS删除一部分二进制文件 :
sql
# 重置⼆进⾏⽇志⽂件和索引⽂件为初始状态
mysql> RESET MASTER;
# 删除指定⽇志⽂件之前的所有⽇志⽂件并更新索引
mysql> PURGE BINARY LOGS TO 'mysql-bin.010';
# 删除指定时间之前的所有⽇志⽂件并更新索引
mysql> PURGE BINARY LOGS BEFORE '2024-10-24 22:46:26'
程序员节怎么你勒
tips:二进制日志文件通常表示包含单独编号的日志文件,二进制日志表示所有二进制日志文件和索引文件
查看二进制日志
我们可以使用客户端工具mysqlbinlog查看:
sql
mysqlbinlog binlog.000001 > binlog.000001
一般后面要新命名一个文件(因为作用是将输出重定向到一个不同的文件中)
也可以通过SQL语句查看:
sql
SHOW BINLOG EVENTS IN 'binlog.000031' FROM <起始位置> LIMIT <事件数量>;
SHOW BINLOG EVENTS IN 'binlog.000031' FROM 100 LIMIT 10;
这是表示从位置100开始并限制结果为十个事件:
分别解释一下这个代表着什么吧,二进制日志文件名,当前这条日志在文件中的起始偏移量,查询日志,服务器ld(标明是哪台主机),当前日志在文件中的结束偏移量,具体执行的操作
二进制日志格式
记录二进制日志使用的格式有以下几种:
🙈基于语句的⽇志格式,最初MySQL是基于SQL语句复制实现主从节点同步,通过指定选项 -- binlog-format=STATEMENT 使⽤此格式
🙉 基于⾏的⽇志格式(默认)中,主节点将事件写⼊⼆进制⽇志,表⽰各个表的⾏受到的影响,可以通 过指定选项--binlog-format=ROW 使⽤此格式
🙊混合⽇志记录格式,默认情况下使⽤基于语句的⽇志记录,如果MySQL认为基于语句的格式不能保 证主从复制过程中的数据安全时,会⾃动切换到基于⾏的⽇志格式,⽐如主节点在语句中⽤了 UUID() 函数,那么⽇志⽂件中记录的是UUID⽣成的真实值⽽不是直接使⽤原始的SQL语句,使⽤混合⽇志格式中以指定选项 --binlog-format=MIXED
当使用MySQL内的一些函数时,必须以行的格式记录日志
UUID()
当主节点执行了UUID函数的时候,会记录生成的具体的值
TIPS:设置⼆进制⽇志格式
sql
--binlog-format=[STATEMENT|ROW|MIXED]
基于语句和基于行的区别:
sql
# 基于语句,记录执⾏的SQL语句
update student set age = 18 where id between 10 and 20;
# 基于⾏,记录每⼀⾏的更改
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;
再见了uu们我们以后就不是一个阶级的了
因为我有贝斯了