ITPub博客

首页 > 数据库 > > 5.4 mysql 服务器日志

5.4 mysql 服务器日志

作者:飘絮絮絮丶 时间:2020-05-14 13:32:14 0 删除 编辑

参考官方文档:

dev.mysql.com/doc/refma



MySQL服务器有几个日志可以帮助你找出正在发生的活动。




默认情况下,除Windows上的错误日志之外,不会启用任何日志。 (DDL日志始终在需要时创建,并且没有用户可配置选项)以下特定于日志的部分提供有关启用日志记录的服务器选项的信息。



默认情况下,服务器在数据目录中写入所有启用的日志。 您可以通过刷新日志来强制服务器关闭并重新打开日志文件(或者在某些情况下切换到新的日志文件)。 发出FLUSH LOGS语句时发生日志刷新; 使用flush-logs或刷新参数执行mysqladmin; 或使用--flush-logs或--master-data选项执行mysqldump。 另外,二进制日志在其大小达到max_binlog_size系统变量的值时被刷新。





您可以在运行时控制常规查询和慢速查询日志。 您可以启用或禁用日志记录,或更改日志文件名称。你可以告诉服务器写一般查询日志和慢查询日志到日志表,日志文件,或者both。





中继日志仅用于从属复制服务器,用于保存主服务器上的数据更改也必须在从属服务器上进行。







5.4.1 选择常规查询和慢速查询日志输出目标





如果启用了这些日志,则MySQL服务器可以灵活地控制输出到普通查询日志和慢速查询日志的目标。 日志条目的可能目标是日志文件或mysql数据库中的general_log和slow_log表。 可以选择任一个或两个目的地。



在服务器启动时进行日志控制:

--log-output选项指定日志输出的目的地。 该选项本身不会启用日志。 它的语法是--log-output [= value,...]:



  • 如果给出了--log-output值,该值应该是一个或多个TABLE(记录到表),FILE(记录到文件)或NONE(不记录到表)的逗号分隔列表 。 None,如果存在,优先于任何其他说明符。
  • 如果省略--log-output,则默认日志记录的目标为FILE。






general_log系统变量控制记录到所选日志目标的常规查询日志。 如果在服务器启动时指定,general_log采用1或0的可选参数来启用或禁用日志。 要指定除文件记录默认值以外的文件名,请设置general_log_file变量。 同样,slow_query_log变量控制记录到所选目标的慢查询日志,并设置slow_query_log_file指定文件记录的文件名。 如果启用了任一日志,则服务器将打开相应的日志文件并向其写入启动消息。 但是,除非选择FILE日志目标,否则不会进一步将查询记录到文件。





例如:

  • 要将常规查询日志条目写入日志表和日志文件,请使用--log-output=TABLE,FILE 来选择两个日志目标和--general_log以启用常规查询日志。
  • 要将通用和慢速查询日志条目仅写入日志表,请使用--log-output = TABLE选择表作为日志目标,并使用--general_log和--slow_query_log来启用这两个日志。
  • 要仅将慢速查询日志条目写入日志文件,请使用--log-output = FILE选择文件作为日志目标,并使用--slow_query_log启用慢速查询日志。 (在这种情况下,因为缺省日志目标是FILE,所以可以省略--log-output选项。)








在运行时的日志控制。与日志表和文件关联的系统变量支持运行时控制日志记录:

  • 全局log_output系统变量指示当前日志记录目标。 它可以在运行时修改以更改目标。
  • 全局general_log和slow_query_log变量指示常规查询日志和慢查询日志是启用(ON)还是禁用(OFF)。 您可以在运行时设置这些变量来控制是否启用日志。
  • 全局general_log_file和slow_query_log_file变量指示常规查询日志和慢速查询日志文件的名称。 您可以在服务器启动时或运行时设置这些变量以更改日志文件的名称。
  • 要禁用或启用当前连接的通用查询日志记录,请将会话sql_log_off变量设置为ON或OFF。




set global log_output='FILE,TABLE'



使用表进行日志输出具有以下好处:

  • 日志条目具有标准格式。 要显示日志表的当前结构,请使用以下语句:


SHOW CREATE TABLE mysql.general_log;

SHOW CREATE TABLE mysql.slow_log;

  • 日志内容可通过SQL语句访问。 这使得能够使用仅选择满足特定标准的日志条目的查询。 例如,要选择与特定客户端关联的日志内容(这可以用于识别来自该客户端的有问题的查询),使用日志表比日志文件更容易。
  • 可以通过任何可连接到服务器并发出查询的客户端(如果客户端具有适当的日志表权限)远程访问日志。 没有必要登录到服务器主机并直接访问文件系统。






日志表实现具有以下特征:

  • 一般来说,日志表的主要目的是为用户提供一个接口,以观察服务器的运行时执行情况,而不是干扰其运行时执行。
  • CREATE TABLE,ALTER TABLE和DROP TABLE是日志表上的有效操作。 对于ALTER TABLE和DROP TABLE,日志表不能被使用并且必须被禁用,如后面所述。
  • 默认情况下,日志表使用以逗号分隔值格式的CSV存储引擎写入数据 。 对于有权访问包含日志表数据的.CSV文件的用户,这些文件很容易导入其他程序,例如可处理CSV输入的电子表格。




日志表可以更改为使用MyISAM存储引擎。 您不能使用ALTER TABLE来更改正在使用的日志表。 日志必须先禁用。CSV或MyISAM以外的任何引擎对日志表都不合法。



  • 要禁用日志记录以便可以alter(或drop)日志表,可以使用以下策略。 该示例使用通用查询日志; 慢查询日志的过程类似,但使用slow_log表和slow_query_log系统变量。


SET @old_log_state = @@global.general_log;

SET GLOBAL general_log = 'OFF';

ALTER TABLE mysql.general_log ENGINE = MyISAM;

SET GLOBAL general_log = @old_log_state;

  • Truncate table 是日志表上的有效操作。 它可以用来过期日志条目。
  • RENAME TABLE 是log 表上的一个有效操作。您可以使用以下策略以原子方式重命名日志表(例如,执行日志循环):


USE mysql;

DROP TABLE IF EXISTS general_log2;

CREATE TABLE general_log2 LIKE general_log;

RENAME TABLE general_log TO general_log_backup, general_log2 TO general_log;



  • 在日志表上 CHECK TABLE 是有效操作
  • 在日志表上不能使用LOCK TABLES
  • 日志表上不能进行DML。这些操作只被服务器自身所允许。
  • LUSH TABLES WITH READ LOCK和read_only系统变量的状态对日志表没有影响。 服务器始终可以写入日志表。
  • 写入日志表的条目不写入二进制日志,因此不会复制到从属服务器。
  • 要刷新日志表或日志文件,分别使用FLUSH TABLES或FLUSH LOGS。
  • 不允许对日志表进行分区。
  • mysqldump转储包含重新创建这些表的语句,以便在重新加载转储文件后不会丢失它们。 日志表内容不会被转储。








5.4.2 错误日志

本节讨论如何配置MySQL服务器以将诊断消息记录到错误日志中。



错误日志包含mysqld启动和关闭时间的记录。 它还包含诊断消息,如服务器启动和关闭期间以及服务器运行期间发生的错误,警告。 例如,如果mysqld注意到需要自动检查或修复表,它会向错误日志写入消息。



在某些操作系统上,如果mysqld异常退出,错误日志将包含堆栈跟踪。 跟踪可用于确定mysqld退出的位置。





如果用来启动mysqld,mysqld_safe可能会将消息写入错误日志。 例如,当mysqld_safe发现异常mysqld退出时,它会重新启动mysqld并将mysqld restarted消息写入错误日志。



以下各节讨论配置错误日志记录的方面。 在讨论中,“console”意味着标准错误输出stderr。 这是您的终端或控制台窗口,除非标准错误输出已被重定向到不同的目的地。





服务器在Windows和Unix系统上决定哪里写错误消息的选项有些不同。 务必使用适合您的平台的信息配置错误日志记录。





5.4.2.1 在Windows 上的错误日志





在Windows上,mysqld使用--log-error,--pid-file和--console选项来确定mysqld是否将错误日志写入控制台或文件,并且如果是文件,则使用文件名:

  • --console 被给出,mysqld 将错误日志写入控制台。(如果两者都给出,并且关于--log-error的下列项不适用 ,--console优先于--log-error。在MySQL 5.7之前,这是相反的:--log-error优先于 --console。)
  • 如果没有给出--log-error,或者没有命名文件,mysqld会将错误日志写入数据目录中名为host_name.err的文件。除非指定了--pid-file选项 ,在这种情况下,文件名是数据目录中的后缀为.err的PID文件基本名称。
  • 如果给--log-error命名文件,mysqld将错误日志写入该文件(如果名称没有后缀,则添加一个.err后缀),除非给出绝对路径名来指定 一个不同的位置,否则写入数据目录下。




另外,服务器默认将事件和错误消息写入应用程序日志中的Windows事件日志:



  • 标记为 Error, Warning和 Note 的条目将写入事件日志,但不会写入单个存储引擎的信息语句等消息。
  • 事件日志条目具有MySQL的源。
  • 写入事件日志的信息使用log_syslog系统变量进行控制,该变量在Windows上默认启用。




5.4.2.2 在Unix和类Unix系统上记录错误



在Unix和类Unix系统上,mysqld使用--log-error选项来确定mysqld是否将错误日志写入控制台或文件,以及如果是文件,则使用文件名:

  • 如果未给出--log-error,则mysqld将错误日志写入控制台。
  • 如果在未命名文件的情况下给出--log-error,则mysqld将错误日志写入数据目录中名为host_name.err的文件。
  • 如果给--log-error命名文件,mysqld将错误日志写入该文件(如果名称没有后缀,则添加一个.err后缀),除非给出绝对路径名来指定 一个不同的位置。
  • 如果在[mysqld],[server]或[mysqld_safe]部分的选项文件中给出了--log-error,mysqld_safe将查找并使用该选项,并将其传递给mysqld。






注意:

Yum或APT软件包安装通常会在服务器配置文件中使用类似log-error=/var /log/mysqld.log的选项在/var/log下配置错误日志文件位置。 从选项中删除文件名将导致使用数据目录中的host_name.err文件。





如果服务器将错误日志写入控制台,它会将log_error系统变量设置为stderr。 否则,服务器将错误日志写入文件并将log_error设置为文件名。





5.4.2.3 错误日志到系统日志



可以让mysqld将错误日志写入系统日志。 这是Windows上的Event日志,以及Unix和类Unix系统上的syslog。 为此,请使用这些系统变量:



  • log_syslog:启用此变量将错误日志发送到系统日志。 (在Windows上,默认情况下启用log_syslog。)

如果启用log_syslog,则还可以使用以下系统变量进行更好的控制。



  • log_syslog_facility:syslog消息的默认设施是daemon。 设置这个变量来指定一个不同的设施。


  • log_syslog_include_pid :


是否在每行syslog输出中包含服务器进程ID。



  • log_syslog_tag:


这个变量定义了一个标签添加到系统日志消息中的服务器标识符(mysqld)。 如果已定义,则标记将通过前导连字符附加到标识符上。



注意:

记录到系统日志可能需要额外的系统配置。 查阅您的平台的系统日志文档。



在Unix和类Unix系统上,使用mysqld_safe也可以控制输出到syslog,它可以捕获服务器错误输出并将其传递给syslog。





注意:

不建议使用mysqld_safe进行syslog错误日志记录; 您应该使用服务器系统变量。



mysqld_safe有三个错误日志记录选项,--syslog,--skip-syslog和--log-error。 不带日志记录选项的默认值或使用--skip-syslog的默认日志文件。 要明确指定使用错误日志文件,请为mysqld_safe 指定--log-error = file_name,然后mysqld会将消息写入日志文件。 要使用syslog,请指定--syslog选项。 对于syslog输出,可以使用--syslog-tag = tag_val指定标签; 这将附加到带有前导连字符的mysqld服务器标识符。







5.4.2.4 错误日志过滤



log_error_verbosity系统变量控制服务器的详细程度,以便将错误,警告和note消息写入错误日志。 允许值为1(仅限错误),2(错误和警告),3(错误,警告和note ),默认值为3.如果该值大于2,则服务器为新的连接尝试记录中止的连接和访问被拒绝的错误 。





5.4.2.5 错误日志格式

包含在错误日志消息中的ID是负责写入消息的mysqld内的线程的ID。 这表明服务器的哪个部分生成了消息,并且与一般查询日志和慢查询日志消息(包括连接线程ID)一致。





log_timestamps系统变量控制写入错误日志(以及一般查询日志和慢速查询日志文件)的消息中的时间戳的时区。 允许的值是UTC(默认值)和SYSTEM(本地系统时区)。





5.4.2.6 错误日志文件刷新和重命名



如果使用FLUSH ERROR LOGS,FLUSH LOGS或mysqladmin flush-logs刷新日志,服务器将关闭并重新打开它正在写入的任何错误日志文件。 要重命名错误日志文件,请在刷新之前手动执行。 刷新日志然后用原始文件名打开一个新文件。 例如,假定一个日志文件名为host_name.err,要重命名该文件并创建一个新文件,请使用以下命令:



mv host_name.er host_name.err-old

mysqladmin flush-logs

mv host_name.err-old backup-directory





在Windows 上,使用rename 而不是mv



如果错误文件的位置不能被服务器写入,则日志刷新操作无法创建新的日志文件。 例如,在Linux上,服务器可能会将错误日志写为/var/log/mysqld.log,其中/var/log由root拥有,不可由mysqld写入。



如果服务器未写入指定的错误日志文件,则在刷新日志时不会发生错误日志文件重命名。





5.4.3 一般查询日志



一般查询日志是mysqld正在做什么的一般记录。 服务器在客户端连接或断开连接时将信息写入此日志,并记录从客户端接收到的每条SQL语句。 当您怀疑客户端发生错误并想确切知道客户端发送到mysqld的内容,通用查询日志可能非常有用。





显示客户端何时连接的每一行还包括using connection_type来指示用于建立连接的协议。 connection_type是TCP/IP(不使用SSL建立TCP/IP连接),SSL/TLS(使用SSL建立的TCP/IP连接),Socket(Unix套接字文件连接),Named Pipe(Windows命名管道连接)或Shared Memory (Windows共享内存连接)。



mysqld按照接收它们的顺序将语句写入查询日志,这可能与它们的执行顺序不同。 这个日志顺序与二进制日志的日志顺序相反,在释放任何锁之前,执行它们之后写入语句。 另外,查询日志可能只包含查询数据的语句,而这些语句从不写入二进制日志。





在复制主服务器上使用基于语句的二进制日志记录时,从服务器接收到的语句将写入每个从服务器的查询日志中。 如果客户端使用mysqlbinlog实用程序读取事件并将它们传递给服务器,则会将语句写入主服务器的查询日志。



但是,使用基于行的二进制日志记录时,update 发送将作为行更改而不是SQL语句,因此当binlog_format为ROW时,这些语句从不写入查询日志。 当此变量设置为MIXED时,给定的update也可能不会写入查询日志,具体取决于所使用的语句。





默认情况下,一般查询日志被禁用。 要明确指定初始通用查询日志状态,请使用--general_log[={0|1}]。 如果没有参数或参数为1,--general_log将启用日志。 参数为0时,此选项禁用日志。 要指定日志文件名称,请使用--general_log_file = file_name。 要指定日志目标,请使用--log-output



如果您不为普通查询日志文件指定名称,则默认名称为host_name.log。 服务器在数据目录中创建文件,除非给出绝对路径名来指定不同的目录。





要禁用或启用常规查询日志或在运行时更改日志文件名称,请使用全局general_log和general_log_file系统变量。 将general_log设置为0(或OFF)以禁用日志或设置为1(或ON)以启用它。 设置general_log_file以指定日志文件的名称。 如果日志文件已经打开,它将被关闭并打开新文件。



当启用通用查询日志时,服务器将输出到由--log-output选项或log_output系统变量指定的任何目标。 如果启用日志,服务器将打开日志文件并向其写入启动时消息。 但是,除非选择FILE日志目标,否则不会进一步将查询记录到文件。 如果目标为NONE,则即使启用一般日志,服务器也不会写入查询。 如果日志目标值不包含FILE,则设置日志文件名称对日志记录没有影响。



--感觉有点像审计的味道



服务器重新启动并且日志刷新不会导致生成新的常规查询日志文件(尽管刷新关闭并重新打开它)。 要重命名该文件并创建一个新文件,请使用以下命令:



shell> mv host_name.log host_name-old.log

shell> mysqladmin flush-logs

shell> mv host_name-old.log backup-directory



在Windows 上,使用 rename 而不是mv



您也可以通过禁用日志来在运行时重命名一般查询日志文件:

SET GLOBAL general_log = 'OFF';



在禁用日志的情况下,从外部重命名日志文件; 例如,从命令行。 然后再次启用日志:



SET GLOBAL general_log = 'ON';



此方法适用于任何平台,不需要重新启动服务器。



会话级别的sql_log_off变量可以设置为ON或OFF,以禁用或启用当前连接的通用查询记录。





写入通用查询日志的语句中的密码由服务器重写,不应以纯文本形式出现。 通过使用--log-raw选项启动服务器,可以为通用查询日志禁用密码重写。 此选项对于诊断目的可能很有用,可以查看服务器收到的语句的确切文本,但出于安全原因不建议用于生产用途。





隐式的密码重写是无法解析的语句(例如,由于语法错误)不会写入常规查询日志,因为它们被认为是无密码的。 需要记录所有语句(包括具有错误的语句)的用例应该使用--log-raw选项,同时记住这也会绕过密码重写。



密码重写仅在需要纯文本密码时才会发生。 对于需要密码哈希值的语法,不会发生重写。 如果为这种语法错误地提供明文密码,则密码将按给定的方式记录,而不会重写。 例如,下面的语句会按照所示进行记录,因为需要密码哈希值:



CREATE USER 'user1'@'localhost' IDENTIFIED BY PASSWORD 'not-so-secret';



--密码本身存储的时候回进行hash加密



log_timestamps系统变量控制写入一般查询日志文件(以及慢查询日志文件和错误日志)的消息中的时间戳的时区。 它不会影响写入日志表的常规查询日志和慢速查询日志消息的时区,但可以使用CONVERT_TZ()或通过设置会话将从这些表中检索的行从本地系统时区转换为任何所需的时区 time_zone系统变量。





5.4.4 二进制日志



二进制日志包含描述数据库更改的“事件”,例如表创建操作或对表数据的更改。 它还包含可能可能进行更改的语句的事件(例如,不匹配行的DELETE),除非使用基于行的日志记录。 二进制日志还包含每条语句花费多长时间更新数据的信息。 二进制日志有两个重要目的:



  • 对于复制,主复制服务器上的二进制日志提供了要发送给从服务器的数据更改记录。 主服务器将其二进制日志中包含的事件发送给其从服务器,从服务器执行这些事件以对主服务器进行相同的数据更改。




  • 某些数据恢复操作需要使用二进制日志。 备份恢复后,重新执行备份后记录的二进制日志中的事件。 这些事件从备份的角度使数据库保持最新状态。




--感觉类似oracle 的redo





二进制日志不用于SELECT或SHOW等不修改数据的语句。 要记录所有语句(例如,确定问题查询),请使用一般查询日志





运行启用二进制日志记录的服务器会使性能稍微降低。 但是,二进制日志的优势使您能够配置复制和恢复操作,这通常会超过此次要的性能下降。



二进制日志通常对意外终止具有弹性,因为只有完整的事务被记录或回读。



写入二进制日志的语句中的密码被服务器重写,不会以纯文本形式出现。





以下讨论描述了影响二进制日志记录操作的一些服务器选项和变量。







要启用二进制日志,请使用--log-bin[=base_name]选项启动服务器。 如果未给出base_name值,则默认名称是pid-file选项(默认为主机名称)的值,后跟-bin。 如果给出了基本名称,除非基本名称以前导绝对路径名给出以指定不同的目录 否则服务器将该文件写入数据目录中。 建议您明确指定一个基本名称,而不是使用主机名称的缺省值;





如果您在日志名称中提供扩展名(例如,--log-bin = base_name.extension),则会以静默方式删除并忽略扩展名。





mysqld将数字扩展名附加到二进制日志基本名称以生成二进制日志文件名称。 每次服务器创建一个新的日志文件时,该编号都会增加,从而创建一系列有序的文件。 每次启动或刷新日志时,服务器都会在系列中创建一个新文件。 当前日志的大小达到max_binlog_size后,服务器还会自动创建一个新的二进制日志文件。 如果您正在使用大型事务,则二进制日志文件可能会大于max_binlog_size,因为事务是一次写入文件的,而不会在文件之间进行分割。



为了跟踪哪些二进制日志文件已被使用,mysqld还会创建一个二进制日志索引文件,其中包含所有使用的二进制日志文件的名称。 默认情况下,它具有与二进制日志文件相同的基本名称,扩展名为“.index”。 您可以使用--log-bin-index [= file_name]选项更改二进制日志索引文件的名称。 在mysqld运行时,您不应手动编辑此文件; 这样做会混淆mysqld。



术语“二进制日志文件”通常表示包含数据库事件的单独编号的文件。 术语“二进制日志”共同表示编号的二进制日志文件加上索引文件的集合。



具有SUPER特权的客户端可以使用SET sql_log_bin = 0语句来禁用其自己语句的二进制日志记录。



默认情况下,服务器记录事件的长度以及事件本身,并使用它来验证事件写入是否正确。 您还可以通过设置binlog_checksum系统变量,使服务器为事件写入校验和。



从二进制日志回读时,主服务器默认使用事件长度,但可以通过启用master_verify_checksum系统变量来使用校验和(如果可用)。 从I / O线程还会验证从主设备接收的事件。 通过启用slave_sql_verify_checksum系统变量从中继日志读取时,可以使从属SQL线程使用校验和(如果可用)。





记录在二进制日志中的事件格式取决于二进制日志记录格式。 支持三种格式类型,基于行的日志记录,基于语句的日志记录和混合基日志记录。 使用的二进制日志记录格式取决于MySQL版本。



服务器使用与--replicate-do-db和--replicate-ignore-db选项相同的方式评估--binlog-do-db和--binlog-ignore-db选项。



默认情况下,复制从属服务器不会将从复制主服务器接收到的任何数据修改写入其自己的二进制日志。 要记录这些修改,除了使用--log-bin选项外,还需要使用--log-slave-updates选项来启动从服务器





您可以使用RESET MASTER语句或其中的一部分使用PURGE BINARY LOGS删除所有二进制日志文件。





如果您正在使用复制,则不应删除主服务器上的旧二进制日志文件,除非您确定没有从服务器仍需要使用它们。 例如,如果你的slave从未停止运行超过三天,那么每天你可以在主服务器上执行mysqladmin flush-logs,然后删除超过三天的任何日志。 您可以手动删除文件,但最好使用PURGE BINARY LOGS,它也可以安全地为您更新二进制日志索引文件(并且可以使用日期参数)。





您可以使用mysqlbinlog实用程序显示二进制日志文件的内容。 当您想要重新处理日志中的语句以进行恢复操作时,这非常有用。 例如,您可以从二进制日志更新MySQL服务器,如下所示:



shell> mysqlbinlog log_file | mysql -h server_name



mysqlbinlog也可用于显示复制从属中继日志文件的内容,因为它们使用与二进制日志文件相同的格式进行编写。



二进制日志记录在语句或事务完成后,但在任何锁定被释放或任何提交完成之前立即完成。 这可确保日志按提交顺序进行记录。





在未提交的事务中,更改事务表(例如InnoDB表)的所有更新(UPDATE,DELETE或INSERT)都会被缓存,直到服务器收到COMMIT语句。 此时,mysqld在执行COMMIT之前将整个事务写入二进制日志。





对非事务表的修改无法回滚。 如果回退的事务包括对非事务表的修改,则最后使用ROLLBACK语句记录整个事务,以确保对这些表的修改得到复制。





当处理事务的线程开始时,它将缓冲区语句分配binlog_cache_size大小的缓存。 如果一个语句大于这个,该线程将打开一个临时文件来存储该事务。 当线程结束时,临时文件被删除。





Binlog_cache_use状态变量显示使用此缓冲区(可能还有临时文件)存储语句的事务数。 Binlog_cache_disk_use状态变量显示实际上有多少事务需要使用临时文件。 这两个变量可用于将binlog_cache_size调整为足够大的值,以避免使用临时文件。





max_binlog_cache_size系统变量(默认4GB,也是最大值)可用于限制用于缓存多语句事务的总大小。 如果一个事务大于这么多字节,它会失败并回滚。 最小值是4096。



--不支持日志量超过4G的大事务(未测试)



如果您正在使用二进制日志和基于行的日志记录,则并发插入将转换为CREATE ... SELECT或INSERT ... SELECT语句的正常插入。 这样做是为了确保您可以通过在备份操作期间应用日志来重新创建表的精确副本。 如果您使用基于语句的日志记录,则原始语句将写入日志。





二进制日志格式有一些已知的限制,可能会影响从备份恢复。



请注意,由于复制的增强,二进制日志格式在MySQL 5.7与以前版本的MySQL中有所不同。



写入二进制日志文件和二进制日志索引文件的处理方式与写入MyISAM表的方式相同。



默认情况下,二进制日志在每次写入时同步到磁盘(sync_binlog=1)。 如果sync_binlog未启用,并且操作系统或计算机(不仅是MySQL服务器)崩溃,则二进制日志的最后一条语句可能会丢失。 为防止出现这种情况,请在每N个commit组后,启用sync_binlog系统变量以将二进制日志同步到磁盘。 sync_binlog的最安全值是1(默认值),但这也是最慢的。



例如,如果您正在使用InnoDB表并且MySQL服务器处理COMMIT语句,它会将许多准备好的事务顺序写入二进制日志,同步二进制日志,然后将此事务提交到InnoDB。如果服务器在这两个操作之间发生崩溃,那么事务会在重新启动时由InnoDB回退,但仍然存在于二进制日志中。假设--innodb_support_xa设置为1(默认值),则解决此问题。尽管此选项与InnoDB中对XA事务的支持有关,但它还可以确保二进制日志和InnoDB数据文件同步。为了提供更高级别的安全性,MySQL服务器还应配置为在提交事务之前将二进制日志和InnoDB日志同步到磁盘。 InnoDB日志默认是同步的,sync_binlog = 1可用于同步二进制日志。此选项的作用是,在崩溃后重新启动时,在执行事务回滚之后,MySQL服务器将扫描最新的二进制日志文件以收集事务xid值并计算二进制日志文件中的最后一个有效位置。 MySQL服务器然后告诉InnoDB完成任何已成功写入二进制日志的事务,并将二进制日志截断到最后一个有效位置。这可以确保二进制日志反映InnoDB表的确切数据,因此从服务器与主服务器保持同步,因为它没有收到已回退的语句。



--有点前滚redo的意思。oracle 实例恢复显示前滚,再回滚,mysql 是先执行事务回滚,再前滚。



注意:

innodb_support_xa已弃用,将在未来版本中删除。对于XA事务中的两阶段提交,InnoDB支持从MySQL 5.7.10开始始终启用。



如果MySQL服务器在崩溃恢复时发现二进制日志比本应该发生的短,它至少缺少一个成功提交的InnoDB事务。 如果sync_binlog = 1,并且磁盘/文件系统在请求(某些时不会)时执行实际同步,则不应发生这种情况,因此服务器会打印一条错误消息。二进制日志file_name比预期的大小短。 在这种情况下,此二进制日志不正确,应从主数据的新快照重新启动复制。



在解析二进制日志时,以下系统变量的会话值将写入二进制日志并由复制从属服务器执行:







5.4.4.1 二进制日志格式



服务器使用多种记录格式在二进制日志中记录信息。 确切的格式取决于正在使用的MySQL版本。 有三种日志格式:

  • MySQL中的复制功能最初是基于从主机到从机的SQL语句的传播。 这被称为基于语句的日志记录。 您可以通过使用--binlog-format = STATEMENT启动服务器来使用此格式。
  • 在基于行的日志记录中,主服务器将事件写入二进制日志,以指示单个表行如何受到影响。 因此,表总是使用主键来确保行可以被有效识别,这一点很重要。 您可以通过以--binlog-format = ROW启动它来使服务器使用基于行的日志记录。
  • 第三个选项也是可用的:混合记录。 对于混合日志记录,默认情况下使用基于语句的日志记录,但在某些情况下,日志记录模式会自动切换为基于行的,如下所述。 您可以通过使用--binlog-format = MIXED选项启动mysqld来显式使用混合日志记录。






日志格式也可以由正在使用的存储引擎设置或限制。 这有助于消除在使用不同存储引擎的主服务器和从服务器之间复制某些语句时的问题。





使用基于语句的复制时,复制非确定性语句可能存在问题。 在决定给定语句是否对基于语句的复制是安全的时,MySQL决定它是否可以保证可以使用基于语句的日志记录来复制语句。 如果MySQL无法做出这种保证,它会将该语句标记为可能不可靠并发出警告, Statement may not be safe to log in statement format.。



您可以通过使用MySQL的基于行的复制来避免这些问题。





5.4.4.2 设置二进制 日志格式



您可以通过使用--binlog-format=type启动MySQL服务器来显式选择二进制日志记录格式。 支持的类型值有:



  • STATEMENT导致日志记录基于语句。
  • ROW导致日志记录为基于行。
  • MIXED会导致日志记录使用混合格式。




记录格式也可以在运行时切换。 设置binlog_format系统变量的全局值以指定更改后连接的客户端的格式:



mysql> SET GLOBAL binlog_format = 'STATEMENT';

mysql> SET GLOBAL binlog_format = 'ROW';

mysql> SET GLOBAL binlog_format = 'MIXED';





单个客户端可以通过设置binlog_format的会话值来控制自己的语句的日志记录格式:

mysql> SET SESSION binlog_format = 'STATEMENT';

mysql> SET SESSION binlog_format = 'ROW';

mysql> SET SESSION binlog_format = 'MIXED';







注意:

每个MySQL服务器都可以设置自己的唯一的二进制日志记录格式(true是否将binlog_format设置为全局或会话范围)。 这意味着更改复制主服务器上的日志记录格式不会导致从服务器更改其日志记录格式以匹配。 (使用STATEMENT模式时,不会复制binlog_format系统变量;使用MIXED或ROW日志记录模式时,它将被复制,但被slave忽略)。在复制正在进行时更改主服务器上的二进制记录格式,可能会导致复制失败,并出现错误,如

Error executing row event: 'Cannot execute statement: impossible to write to binary log since statement is in row format and BINLOG_FORMAT = STATEMENT.'





要变更 全局或者会话的 binlog_format 值,你必须有SUPER权限



客户端可能希望按每个会话设置二进制日志记录的原因有几个:

  • 会对数据库进行很多小改动的会话可能需要使用基于行的日志记录。
  • 执行与WHERE子句中的许多行匹配的更新的会话可能需要使用基于语句的日志记录,因为记录几条语句比多行记录更有效。
  • 某些语句需要在主服务器上执行很长时间,但会导致只修改几行。 因此使用基于行的日志记录复制它们可能是有益的。




在运行时无法切换复制格式时有例外:



  • 从存储的函数或触发器中


  • 如果NDB存储引擎已启用


  • 如果会话当前处于基于行的复制模式并且已打开临时表




试图在任何这些情况下切换格式都会导致错误。



如果您使用的是InnoDB表,且事务隔离级别为READ COMMITTED或READ UNCOMMITTED,则只能使用基于行的日志记录。 可以将日志记录格式更改为STATEMENT,但在运行时会这样做会非常迅速地导致错误,因为InnoDB不能再执行插入操作。





如果存在任何临时表,则不建议在运行时切换复制格式,因为只有在使用基于语句的复制时记录临时表,而使用基于行的复制时则不记录它们。 通过混合复制,通常会记录临时表; 用户定义函数(UDF)和UUID()函数发生异常。





将二进制日志格式设置为ROW时,会使用基于行的格式将大多数更改写入二进制日志。 但是,有些更改仍然使用基于语句的格式。 例如包括所有DDL(数据定义语言)语句,如CREATE TABLE,ALTER TABLE或DROP TABLE。



--binlog-row-event-max-size选项可用于具有基于行复制功能的服务器。 行的大小以字节为单位存储在二进制日志中,不超过此选项的值。 该值必须是256的倍数。默认值是8192。







警告:

当使用基于语句的日志记录进行复制时,如果语句的设计方式使得数据修改不确定,则主服务器和从服务器上的数据可能会有所不同; 也就是说,它按查询优化器的意愿处理。 一般来说,即使不是主从复制环境,这也不是一个好的做法。





5.4.4.3 Mixed 二进制日志格式



以MIXED日志格式运行时,服务器在以下情况下自动从基于语句的行转换为基于行的日志记录:



  • 当函数包含UUID()。
  • 当一个或多个带有AUTO_INCREMENT列的表被更新并且触发器或存储函数被调用时。 像所有其他不安全的语句一样,如果binlog_format = STATEMENT,则会生成警告。
  • 当视图的主体需要基于行的复制时,创建视图的语句也会使用它。 例如,创建视图的语句使用UUID()函数时会发生这种情况。
  • 当UDF被调用时
  • 如果语句按行记录,并且执行该语句的会话具有任何临时表,则按行记录将用于所有后续语句(除访问临时表的那些语句外),直到删除该会话使用的所有临时表为止。




无论是否实际记录临时表,情况都是如此。


使用基于行的格式不能记录临时表; 因此,一旦使用基于行的日志记录,则使用该表的所有后续语句都是不安全的。 服务器会近似的将会话期间执行的所有语句视为不安全,直到会话不再保存任何临时表。



  • 当使用FOUND_ROWS()或ROW_COUNT()时。 (BUG#12092,BUG#30244)
  • 使用USER(),CURRENT_USER()或CURRENT_USER时。 (Bug#28086)
  • 当一个语句引用一个或多个系统变量时。 (Bug#31168)




例外:以下系统变量与会话作用域(仅)一起使用时,不会导致记录格式切换:



  • 当涉及的其中一个表是mysql数据库中的日志表时。
  • 当使用LOAD_FILE()函数时。 ( Bug #39701)








注意:

如果您尝试使用基于语句的日志记录(应该使用基于行的日志记录来生 )来执行语句,那么会生成成警告。 该警告显示在客户端(在SHOW WARNINGS的输出中)和mysqld错误日志中。 每次执行此类语句时,都会向SHOW WARNINGS表中添加警告。 但是,只有为每个客户端会话生成警告的第一条语句才会写入错误日志以防止日志泛滥。





除上述决定外,单个引擎还可以确定更新表中信息时使用的日志记录格式。 单个引擎的记录功能可以定义如下:

  • 如果引擎支持基于行的日志记录,则该引擎被称为行日志记录功能。
  • 如果一个引擎支持基于语句的日志记录,那么这个引擎就被说成是语句记录功能。




给定的存储引擎可以支持一种或两种日志格式。 下表列出了每个引擎支持的格式。

Storage EngineRow Logging SupportedStatement Logging SupportedARCHIVEYesYesBLACKHOLEYesYesCSVYesYesEXAMPLEYesNoFEDERATEDYesYesHEAPYesYesInnoDBYesYes when the transaction isolation level is REPEATABLE READ orSERIALIZABLE; No otherwise.MyISAMYesYesMERGEYesYesNDBYesNo




是否要记录一个语句,并根据语句类型(安全,不安全或二进制注入)确定要使用的记录模式,二进制记录格式(STATEMENT,ROW或MIXED)以及日志记录的功能 存储引擎(语句能力,行能力,两者兼容或不兼容)。 (二进制注入是指记录必须使用ROW格式记录的更改。)



语句可以记录,也可以不记录警告; 失败的语句不记录,但会在日志中生成错误。 这在下面的决策表中显示。 Type,binlog_format,SLC和RLC列概述了条件,而Error / Warning和Logged as列代表相应的操作。 SLC代表“语句记录功能”,RLC代表“行记录功能”。



详细参考:

dev.mysql.com/doc/refma





当通过确定产生警告时,产生标准的MySQL警告(并且可以使用SHOW WARNINGS)。 这些信息也被写入到mysqld错误日志中。 每个客户端连接的每个错误实例仅记录一个错误,以防止日志泛滥。 日志消息包含尝试的SQL语句。





如果从属服务器的log_error_verbosity设置为显示警告,则slave将消息打印到错误日志中,以提供有关其状态的信息,例如二进制日志和中继日志坐标,它在开始作业时,在切换到另一个中继日志时, 在断开连接后重新连接时,对基于语句的日志记录不安全的语句等等。





5.4.4.4 mysql 数据表上更改的日志格式



mysql数据库中授予表的内容可以直接修改(例如,使用INSERT或DELETE)或间接修改(例如使用GRANT或CREATE USER)。 影响mysql数据库表的语句使用以下规则写入到二进制日志中:

  • 根据binlog_format系统变量的设置,将直接更改mysql数据库表中数据的数据操作语句记录。 这与INSERT,UPDATE,DELETE,REPLACE,DO,LOAD DATA INFILE,SELECT和TRUNCATE TABLE等语句有关。
  • 不管binlog_format的值如何,间接更改mysql数据库的语句都会记录为语句。 这涉及GRANT,REVOKE,SET PASSWORD,RENAME USER,CREATE(除CREATE TABLE ... SELECT之外的所有表单),ALTER(所有表单)和DROP(所有表单)等语句。




CREATE TABLE ... SELECT是数据定义和数据操作的组合。 CREATE TABLE部分使用语句格式进行记录,SELECT部分根据binlog_format的值进行记录







5.4.5 慢查询日志





慢速查询日志包含执行时间超过long_query_time秒的SQL语句,并且至少需要检查min_examined_row_limit行。 long_query_time的最小值和默认值分别为0和10。 该值可以指定为微秒的精度。 对于记录到文件,写入时间包括微秒部分。 对于记录到表中,只写入整数次; 微秒部分被忽略。



默认情况下,不会记录管理语句,也不会使用索引进行查找。 如后面所述,可以使用log_slow_admin_statements和log_queries_not_using_indexes更改此行为。





获取初始锁的时间不计为执行时间。 mysqld在执行完所有锁之后并且在所有锁释放之后将语句写入慢查询日志,因此日志顺序可能与执行顺序不同。



默认情况下,慢查询日志被禁用。 要明确指定最初的慢查询日志状态,请使用--slow_query_log[={0|1}]。 如果没有参数或参数为1,--slow_query_log将启用日志。 参数为0时,此选项禁用日志。 要指定日志文件名称,请使用--slow_query_log_file = file_name。



如果您没有为慢速查询日志文件指定名称,则默认名称是host_name-slow.log。 服务器在数据目录中创建文件,除非给出绝对路径名来指定不同的目录。



要禁用或启用慢速查询日志或在运行时更改日志文件名称,请使用全局的slow_query_log和slow_query_log_file系统变量。 将slow_query_log设置为0(或OFF)以禁用日志,或设置为1(或ON)以启用它。 设置slow_query_log_file以指定日志文件的名称。 如果日志文件已经打开,它将被关闭并打开新文件。



当启用慢查询日志时,服务器将输出写入由--log-output选项或log_output系统变量指定的任何目标。 如果启用日志,服务器将打开日志文件并向其写入启动消息。 但是,除非选择FILE日志目标,否则不会进一步将查询记录到文件。 如果目标为NONE,即使启用了慢速查询日志,服务器也不写任何查询。 如果日志目标值不包含FILE,则设置日志文件名称对日志记录没有影响。



如果使用--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,这意味着没有限制。 对于不使用索引的查询的日志记录,正值会以每分钟为限制。 第一个这样的查询将打开一个60秒的窗口,在该窗口中,服务器将查询记录到给定的限制,然后压制其他查询。 如果在窗口结束时存在被抑制的查询,则服务器记录一个摘要,该摘要指示有多少人以及在这些人中花费的总时间。 当服务器记录下一个不使用索引的查询时,下一个60秒的窗口开始。



服务器按以下顺序使用控制参数来确定是否将查询写入慢速查询日志:



  1. 查询必须不是管理语句,或者必须启用log_slow_admin_statements。
  2. 该查询必须至少需要long_query_time秒,否则必须启用log_queries_not_using_indexes,并且查询不使用索引进行行查找。
  3. 查询必须检查至少min_examined_row_limit行。
  4. 不能根据log_throttle_queries_not_using_indexes设置来禁止查询。




log_timestamps系统变量控制写入慢查询日志文件(以及常规查询日志文件和错误日志)的消息中的时间戳的时区。 它不会影响写入日志表的常规查询日志和慢速查询日志消息的时区,但可以使用CONVERT_TZ()或通过设置会话将从这些表中检索的行从本地系统时区转换为任何所需的时区 time_zone系统变量。



所有的日志行包含一个时间戳



服务器不会将由查询缓存处理的查询写入慢速查询日志,也不会因索引的存在而受益,因为该表有零行或一行。



默认情况下,复制从服务器不会将复制查询写入慢速查询日志。 要改变这个,使用log_slow_slave_statements系统变量。



写入慢查询日志的语句中的密码被服务器重写,不会以纯文本形式出现。



慢速查询日志可用于查找需要很长时间才能执行的查询,因此可用于优化。 但是,检查一个很长的慢查询日志可能成为一项艰巨的任务。 为了简化操作,可以使用mysqldumpslow命令处理缓慢的查询日志文件,以总结出现在日志中的查询。





5.4.6 DDL log



DDL日志或元数据日志记录由数据定义语句(例如DROP TABLE和ALTER TABLE)生成的元数据操作。 MySQL使用此日志来恢复元数据操作中发生的崩溃。 当执行语句DROP TABLE t1,t2时,我们需要确保t1和t2都被drop,并且每个表的drop都完成。 这种类型的SQL语句的另一个例子是ALTER TABLE t3 DROP PARTITION p2,其中我们必须确定该分区完全被删除,并且其定义已从表t3的分区列表中删除。





元数据操作的记录(例如刚刚描述的那些)被写入到ddl_log.log文件中的MySQL数据目录中。 这是一个二进制文件; 它的不是人类可读的,你不应该试图以任何方式修改它的内容。



直到实际需要记录元数据语句时才会创建ddl_log.log,并且在成功启动mysqld后删除它。 因此,这个文件可能不会出现在以完全正常的方式运行的MySQL服务器上。





目前,ddl_log.log最多可容纳1048573个条目,大小相当于4 GB。 超过此限制后,必须重新命名或删除文件,才能执行任何其他DDL语句。 这是我们正在努力解决的已知问题(bug#83708)。



没有用户可配置的服务器选项或与此文件相关的变量。





5.4.7 服务器log 维护



MySQL服务器可以创建多个不同的日志文件,以帮助您查看正在发生的活动。 但是,您必须定期清理这些文件,以确保日志不占用太多的磁盘空间。



在启用日志记录的情况下使用MySQL时,您可能需要不时备份和删除旧的日志文件,并告诉MySQL开始记录到新文件。



在Linux(Red Hat)安装上,您可以使用mysql-log-rotate脚本来实现此目的。 如果您从RPM分发版安装了MySQL,则应该自动安装此脚本。 如果您使用二进制日志进行复制,请小心使用此脚本。 除非您确定其内容已被所有slave处理,否则不应删除二进制日志。





在其他系统上,您必须自己安装一个简短的脚本,您可以从cron(或其等效的脚本)开始处理日志文件。





对于二进制日志,您可以将expire_logs_days系统变量设置为在给定天数后自动过期二进制日志文件。 如果您正在使用复制,则应该设置变量不低于您的slave可能落后于master的最大天数。 要按需删除二进制日志,请使用PURGE BINARY LOGS语句







您可以强制MySQL通过刷新日志来开始使用新的日志文件。 发出FLUSH LOGS语句或执行mysqladmin flush-logs,mysqladmin refresh,mysqldump --flush-logs或mysqldump --master-data命令时会发生日志刷新。 另外,二进制日志在其大小达到max_binlog_size系统变量的值时被刷新。



FLUSH LOGS支持可选的修饰符,以便选择性地清除单个日志(例如FLUSH BINARY LOGS)。



log-flushing 操作执行以下操作:

  • 如果启用了常规查询日志记录或缓慢查询日志记录到日志文件,则服务器关闭并重新打开常规查询日志文件或慢速查询日志文件。
  • 如果启用二进制日志记录,则服务器关闭当前的二进制日志文件并使用下一个序列号打开一个新的日志文件。
  • 如果使用--log-error选项启动服务器以将错误日志写入文件,服务器将关闭并重新打开日志文件。






刷新日志时,服务器将创建一个新的二进制日志文件。 但是,它只是关闭并重新打开常规和慢查询日志文件。 要在Unix上创建新文件,请在刷新前重命名当前日志文件。 在刷新时间,服务器以原始名称打开新的日志文件。 例如,如果普通和慢查询日志文件被命名为mysql.log和mysql-slow.log,则可以使用如下一系列命令:





shell> cd mysql-data-directory

shell> mv mysql.log mysql.old

shell> mv mysql-slow.log mysql-slow.old

shell> mysqladmin flush-logs





在Windows 上,使用rename 而不是mv

此时,您可以对mysql.old和mysql-slow.old进行备份,然后将其从磁盘中删除。



如果有错误日志文件,可以使用类似的策略来备份错误日志文件。



您可以通过禁用日志来在运行时重命名常规查询日志或慢速查询日志:

SET GLOBAL general_log = 'OFF';

SET GLOBAL slow_query_log = 'OFF';



在禁用日志的情况下,从外部重命名日志文件; 例如,从命令行。 然后再次启用日志:



SET GLOBAL general_log = 'ON';

SET GLOBAL slow_query_log = 'ON';



此方法适用于任何平台,不需要重新启动服务器。



注意:

为使服务器在外部重命名文件后重新创建给定的日志文件,文件位置必须可由服务器写入。 这可能并非总是如此。 例如,在Linux上,服务器可能会将错误日志写为/var/log/mysqld.log,其中/ var / log由root拥有,不可由mysqld写入。 在这种情况下,日志刷新操作将无法创建新的日志文件。



要处理这种情况,必须在重命名原始日志文件后手动创建具有正确所有者的新日志文件。 例如,以root身份执行这些命令:





shell> mv /var/log/mysqld.log /var/log/mysqld.log.old

shell> install -omysql -gmysql -m064 /dev/null /var/log/mysqld.log

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3155869/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-09-09

  • 博文量
    2646
  • 访问量
    42316