前言日志文件记录了影响MySQL数据库的各类活动。MySQL数据库中常见的日志文件包括错误日志、二进制日志、慢查询日志和查询日志。下面分别介绍。错误日志错误日志文件记录了MySQL的启动、运行和关闭过程。mysql>showvariablelike'log_error';+----------------+--------------------+|Variable_name|值|+----------------+--------------------+|log_error|/var/log/mysqld。log|+----------------+--------------------+1rowinset(0.03sec)可以看到错误日志的路径和文件名。默认情况下,错误文件的文件名是服务器的主机名,即:hostname.err。只是我这里设置了/var/log/mysqld.log。修改错误日志地址,可以在/etc/my.cnf中添加#RecommendedinstandardMySQLsetupsql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES[mysqld_safe]log-error=/var/log/mysqld。logpid-file=/var/run/mysqld/mysqld.pid当MySQL数据库无法正常启动时,首先要查找的文件就是错误日志文件,它记录了错误信息,可以帮助我们找到问题所在。慢查询日志慢查询日志用于记录响应时间超过阈值的SQL语句,因此我们可以设置一个阈值,将所有运行时间超过该值的SQL语句记录到慢查询日志文件中。阈值可以通过参数long_query_time设置,默认为10秒。启动慢查询日志MySQL数据库默认不启动慢查询日志,需要手动将此参数设置为ON,然后启动mysql>showvariableslike"%slow%";+--------------------------+------------------------------------------------+|Variable_name|Value|+-------------------------+------------------------------------------------+|log_slow_admin_statements|OFF||log_slow_slave_statements|OFF||slow_launch_time|2||slow_query_log|OFF||slow_query_log_file|/var/lib/mysql/iz2zeaf3cg1099kiidi06mz-slow.log|+----------------------------+------------------------------------------------+5rowsinset(0.00sec)mysql>setglobalslow_query_log='ON';QueryOK,0rowsaffected(0.00sec)mysql>showvariableslike"slow_query_log";+--------------------------+--------------------------------------------+|Variable_name|Value|+-------------------------+----------------------------------------------+|slow_query_log|ON||slow_query_log_file|/var/lib/mysql/iz2zeaf3cg1099kiidi06mz-slow.log|+-----------------------------+-----------------------------------------------+2rowsinset(0.00sec)但是使用setglobalslow_query_log='ON'开启慢查询日志,只对当前数据库有效。如果重启MySQL数据库就会失效,所以如果要永久生效,需要修改配置文件my.cnf(其他系统变量同理),如下:[mysqld]slow_query_log=1并重启MySQL以启用慢查询日志记录。至于日志文件的路径,就是上面slow_query_log_file对应的路径。设置阈值mysql>showvariablelike'long_query_time';+----------------+----------+|Variable_name|Value|+----------------+------------+|long_query_time|10.000000|+----------------+----------+1rowinset(0.00sec)阈值默认为10秒,我们可以修改阈值大小,例如(当然这对当前数据库仍然有效):mysql>setgloballong_query_time=0.05;QueryOK,0rowsaffected(0.00sec)设置long_query_time阈值后,MySQL数据库会记录所有运行时间超过该值的SQL语句,但对于运行时间正好等于long_query_time的情况,则不会记录记录。并将long_query_time设置为0来捕获所有的查询参数log_queries_not_using_indexes与慢查询日志相关的另一个参数是log_queries_not_using_indexes,如果运行的SQL语句没有使用索引,MySQL数据库也会将这条SQL语句记录到慢查询日志文件中。首先确认log_queries_not_using_indexes开启;mysql>showvariableslike'log_queries_not_using_indexes';+----------------------------+-------+|Variable_name|Value|+--------------------------------+------+|log_queries_not_using_indexes|ON|+----------------------------+--------+1rowinset(0.12sec)示例,无索引用于查询:mysql>explainselect*fromvote_record_memorywherevote_id=323;+----+------------+--------------------+-------+----------------+-----+--------+------+--------+------------+|id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra|+----+------------+--------------------+------+----------------+------+--------+------+--------+------------+|1|SIMPLE|vote_record_memory|ALL|NULL|NULL|NULL|NULL|149272|Usingwhere|+----+--------------+--------------------+------+----------------+-----+--------+------+--------+------------+1rowinset(1.56sec)可以可见最后进行了全表扫描;然后去log日志文件查看,这条SQL因为没有使用索引,已经被标记为慢SQL。#时间:18081711:42:59#用户@主机:root[root]@[117.136.86.151]ID:2625#QUERY_TIME:0.016542LOCK_TIME:0.000112ROWS_SENT:142ROWS_EXAMIND:149272SETTIMESTAMP=1534477779ID;RESTION__ERTISE放入表MySQL5.1可以将慢查询日志记录放入一个表中,在mysql数据库下,命名为slow_log|slow_log|CREATETABLE`slow_log`(`start_time`timestampNOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,`user_host`mediumtextNOTNULL,`query_time`timeNOTNULL,`lock_time`timeNOTNULL,`rows_sent`int(11)NOTNULL,`rows_examined`int(11)NOTNULL,`db`varchar(512)NOTNULL,`last_insert_id`int(11)NOTNULL,`insert_id`int(11)NOTNULL,`server_id`int(10)unsignedNOTNULL,`sql_text`mediumtextNOTNULL,`thread_id`bigint(21)unsignedNOTNULL)ENGINE=CSVDEFAULTCHARSET=utf8COMMENT='Slowlog'|参数log_output指定慢查询输出的格式,默认为file,你可以set设置为table,会变成mysql>showvariablelike上面slow_log中的"log_output";+---------------+--------+|变量名|值|+----------------+--------+|log_output|FILE|+----------------+-------+1行inset(0.19sec)但大多数情况下没有必要这样做,不仅对性能影响很大,MySQL5.1在记录慢查询到文件时已经支持微秒级别的信息,但是记录慢查询到表这会导致降级到秒级的时间粒度,秒级的慢查询日志意义不大。慢查询日志分析工具mysqldumpslow命令当越来越多的SQL查询记录在慢查询日志文件中时,这个时候直接看日志文件就不容易了,MySQL提供了mysqldumpslow命令解决:[root@iz2zeaf3cg1099kiidi06mzmykisql]#mysqldump9mclowiz2.logReadingmysqlslowquerylogfromiz2zeaf3cg1099kiidi06mz-slow.logCount:1Time=60.02s(60s)Lock=0.00s(0s)Rows=149272.0(149272),root[root]@[117.136.86.151]select*fromvote_record_memoryCount:1Time=14.8s)5s锁=0.00s(0s)Rows=0.0(0),root[root]@[117.136.86.151]CALLadd_vote_memory(N)Count:1Time=1.72s(1s)Lock=0.00s(0s)Rows=0.0(0),root[root]@[117.136.86.151]INSERTintovote_recordSELECT*fromvote_record_memoryCount:1Time=0.02s(0s)Lock=0.00s(0s)Rows=142.0(142),root[root]@[117.136.86.151]select*fromvote_record_memorywherevote_id=N关于mysqldumpslow命令的更多信息,请参考:https://github.com/luisedware/Archives/issues/7pt-query-digest工具pt-query-digest是分析MySQL查询日志最强大的工具。这个工具很强大。它可以分析binlog、Generallog、slowlog也可以通过showprocesslist或者tcpdump抓取的MySQL协议数据进行分析,比mysqldumpslow更具体、更完善。下面是使用pt-query-digest://直接分析慢查询文件的例子pt-query-digestslow.log>slow_report.log这个工具可以打印出查询的分析报告,并将分析结果输出到一份文件。分析过程是先对查询语句的条件进行参数化,然后对参数化后的查询进行参数化。分组统计,统计每个查询的执行时间、频率、比例等,并根据分析结果发现问题并进行优化。更多pt-query-digest的安装和使用请参考:www.ywnds.com/?p=8179Querylog查看日志记录了所有对MySQL数据库的请求,不管这些请求是否被正确执行.默认是hostname.logmysql>showvariablelike"general_log%";+----------------+-----------------------------------------+|Variable_name|Value|+-------------------+--------------------------------------------+|general_log|OFF||general_log_file|/var/lib/mysql/iz2zeaf3cg1099kiidi06mz.log|+----------------+-------------------------------------------+2rowsinset(0.24sec)默认不启用查询日志,必须首先启用。mysql>setglobalgeneral_log='ON';QueryOK,0rowsaffected(0.05sec)mysql>showvariableslike"general_log%";+----------------+------------------------------------------+|Variable_name|Value|+----------------+-------------------------------------------+|general_log|ON||general_log_file|/var/lib/mysql/iz2zeaf3cg1099kiidi06mz.log|+--------------------+-------------------------------------------+2rowsinset(0.11sec)二进制日志binary日志记录了对数据库执行更改的所有操作,但不包括select和show等操作,因为此类操作不会修改数据本身。如果还想记录select和show操作,只能使用querylogs。而不是二进制日志。另外,二进制文件中还包含了数据库更改操作是什么时候执行的,什么时候执行的等信息。二进制日志主要有以下功能:恢复:一些数据恢复需要二进制日志。例如,当一个数据库全量备份文件被恢复时,我们可以通过二进制日志进行时间点恢复复制(replication)。):通过二进制日志的复制和执行,远程MySQL数据库(通常是slave或standby)和MySQL数据库(通常是master或primary)可以进行实时同步审计(audit):用户可以通过二进制日志中的信息审计判断数据库是否存在注入攻击。打开二进制日志。可以通过配置参数log-bin[=name]来启动二进制日志。如果不指定名称,默认二进制日志文件名为主机名,后缀为二进制日志的序号[mysqld]log-binmysql>showvariableslike'datadir';+------------+----------------+|Variable_name|Value|+----------------+----------------+|datadir|/var/lib/mysql/|+----------------+----------------+1rowinset(0.00sec)mysqld-bin.000001是二进制日志文件,mysqld-bin.index是二进制索引文件。MySQL为了管理所有的binlog文件,额外创建了一个索引文件,它按顺序记录了MySQL使用的所有binlog文件。如果要自定义索引文件的名称,可以设置log_bin_index=file参数。-rw-rw----1mysqlmysql120Aug2116:42mysqld-bin.000001-rw-rw----1mysqlmysql20Aug2116:42mysqld-bin.index查看二进制日志文件对于二进制日志文件,不同于错误日志文件,慢查询日志文件可以用cat、head、tail等命令查看,需要用到mysql提供的工具mysqlbinlog。如:[root@iz2zeaf3cg1099kiidi06mzmysql]#mysqlbinlogmysqld-bin.000001/*!50530SET@@SESSION.PSEUDO_SLAVE_MODE=1*/;/*!40019SET@@session.max_insert_delayed_threads=0*/;/*!50003SET@OLD_PE=COMPLETION_TYCOMPLETION_TYPE,COMPLETION_TYPE=0*/;DELIMITER/*!*/;#at4#18082116:42:53serverid1end_log_pos120CRC320x3e55be40Start:binlogv4,serverv5.6.39-logcreated18082116:42:53atstartup#Warning:thisbinlogiseitherinuseorwasnotclosedproperly.ROLLBACK/*!*/;BINLOG'jdB7Ww8BAAAAdAAAAHgAAAABAAQANS42LjM5LWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACN0HtbEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAUC+VT4='/*!*/;DELIMITER;#EndoflogfileROLLBACK/*addedbymysqlbinlog*/;/*!50003SETCOMPLETION_TYPE=@OLD_COMPLETION_TYPE*??/;/*!50530SET@@SESSION.PSEUDO_SLAVE_MODE=0*/;二进制日志文件配置参数下面简单介绍一下二进制日志文件的几个重要配置参数。max_binlog_size可以通过max_binlog_size参数限制单个binlog文件的大小(默认1G)。binlog_cache_size当使用事务表存储引擎(如InnoDB存储引擎)时,所有未提交(uncommitted)的二进制日志都会记录在一个缓冲区中,当事务提交时,缓存中的二进制日志会直接写入二进制在日志文件中,缓冲区的大小由binlog_cache_size决定,默认大小为32K。另外,binlog_cache_size是基于会话(session)的。当每个线程开始一个事务时,MySQL会自动分配一个大小为binlog_cache_size的缓存mysql>showvariableslike'binlog_cache_size';+--------------------+-------+|Variable_name|Value|+------------------+--------+|binlog_cache_size|32768|+-------------------+--------+1rowinset(0.00sec)sync_binlog默认情况下,二进制日志不会每次写入都同步到磁盘。参数sync_binlog=[N]表示每个writebuffer被同步到磁盘的次数。如果N设置为1,即sync_binlog=1表示二进制日志同步写入磁盘。此时写操作就不需要使用上面提到的操作系统的缓冲区来写二进制日志了。binlog_formatbinlog_format参数很重要,它影响了二进制日志的记录格式,分为三种格式:1.statement:记录日志的逻辑SQL语句2.row:记录表的行变化3.mixed:在这种格式下,mysql默认使用statement格式记录二进制日志文件,但在某些情况下使用ROW格式,有以下几种情况:表的存储引擎是NDB,在此时,对表的DML操作将以ROW格式记录。使用了UUID()、USER()、CURRENT_USER()、FOUND_ROW()、ROW_COUNT()等不确定函数。使用INSERTDELAY语句。使用用户定义函数(UDF)。使用临时表。
