玩一玩MySQL服务器配置与管理的游戏(日志快乐版

通常所说的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

关于服务器的选项、系统变量、状态变量可以参考:

MySQL :: MySQL 8.0 Reference Manual :: 7.1.4 Server Option, System Variable, and Status Variable Referencehttps://dev.mysql.com/doc/refman/8.0/en/server-option-variable-reference.html

系统变量:

MySQL :: MySQL 8.0 Reference Manual :: 7.1.5 Server System Variable Referencehttps://dev.mysql.com/doc/refman/8.0/en/server-system-variable-reference.html

状态变量:https://dev.mysql.com/doc/refman/8.0/en/server-status-variable-reference.htmlhttps://dev.mysql.com/doc/refman/8.0/en/server-status-variable-reference.html

系统变量状态变量的作用域分为: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 的系统变量

可以动态设置的系统变量:MySQL :: MySQL 8.0 Reference Manual :: 7.1.9.2 Dynamic System Variableshttps://dev.mysql.com/doc/refman/8.0/en/dynamic-system-variables.html

服务器常用配置:

只说里牛渴死下的环境:

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显示当前链接的值

官方文档:https://dev.mysql.com/doc/refman/8.0/en/server-status-variables.htmlhttps://dev.mysql.com/doc/refman/8.0/en/server-status-variables.html

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 变量设置为ONOFF

使用日志表有一些优点,可以通过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们我们以后就不是一个阶级的了

因为我有贝斯了

相关推荐
中云DDoS CC防护蔡蔡41 分钟前
微信小程序被攻击怎么选择高防产品
服务器·网络安全·微信小程序·小程序·ddos
HPC_fac130520678162 小时前
以科学计算为切入点:剖析英伟达服务器过热难题
服务器·人工智能·深度学习·机器学习·计算机视觉·数据挖掘·gpu算力
yaoxin5211233 小时前
第二十七章 TCP 客户端 服务器通信 - 连接管理
服务器·网络·tcp/ip
向宇it6 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
i道i6 小时前
MySQL win安装 和 pymysql使用示例
数据库·mysql
sinat_384241097 小时前
使用 npm 安装 Electron 作为开发依赖
服务器
Oak Zhang8 小时前
sharding-jdbc自定义分片算法,表对应关系存储在mysql中,缓存到redis或者本地
redis·mysql·缓存
Kkooe8 小时前
GitLab|数据迁移
运维·服务器·git
久醉不在酒9 小时前
MySQL数据库运维及集群搭建
运维·数据库·mysql
WindFutrue9 小时前
使用Mybatis向Mysql中的插入Point类型的数据全方位解析
数据库·mysql·mybatis