zoukankan      html  css  js  c++  java
  • MySQL的日志相关内容

    本篇文章介绍一下mysql的备份和日志,由于备份时需要用到日志,所以在讲备份前,如果日志内容篇幅过长,将会把日志和备份分开单独来讲,先简单介绍一下mysql的日志相关内容。

    MySQL日志

    日志是mysql数据库的重要组成部分。日志文件中记录着mysql数据库运行期间发生的变化;也就是说用来记录mysql数据库的客户端连接状况、SQL语句的执行情况和错误信息等。当数据库遭到意外的损坏时,可以通过日志查看文件出错的原因,并且可以通过日志文件进行数据恢复。

    mysql主要包含:错误日志、查询日志、慢查询日志、事务日志、二进制日志,中继日志;比较重要的日志有错误日志,慢查询日志,二进制日志。下面对这几种日志内容做简单介绍:

    错误日志

    错误日志是mysql的重要日志之一,它记录了mysql启动和停止时,以及服务器在运行过程中发生的任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时,可以首先查看错误日志。
    错误日志的定义在my.cnf中定义:

    [mysqld_safe]
    log-error=/var/log/mariadb/mariadb.log
    

    如果没有在my.cnf中定义错误日志,那么mysqld会使用host_name.err(主机名命名),并默认存放在DATADIR定义的目录下。

    慢查询日志

    慢查询日志记录了所有执行时间超过参数long_query_time(单位:秒)设置的值,long_query_time的默认时间为10秒,最小为0,精度可以到微妙。

    MariaDB [(none)]> show variables like 'long_query_time';
    +-----------------+-----------+
    | Variable_name   | Value     |
    +-----------------+-----------+
    | long_query_time | 10.000000 |
    +-----------------+-----------+
    1 row in set (0.00 sec)
    

    慢查询日志默认没有开启:查看慢查询是否启用:

    MariaDB [(none)]> show variables like 'slow%';
    +---------------------+---------------------------------+
    | Variable_name       | Value                           |
    +---------------------+---------------------------------+
    | slow_launch_time    | 2                               |
    | slow_query_log      | ON                              |
    | slow_query_log_file | /var/log/mariadb/mysql_slow.log |
    +---------------------+---------------------------------+
    3 rows in set (0.00 sec)
    

    启用慢查询
    slow_query_log是全局变量,支持命令设置启用或关闭,要注意的是,在终端使用指令设置不能永久生效:

    MariaDB [(none)]> set global slow_query_log=ON | OFF;
    

    要永久生效需要在配置文件中进行定义:

    [mysqld]
    slow_query_log=on
    

    重启服务后生效。查看开启状态:

    MariaDB [(none)]> show variables like 'slow_query_log';
    +----------------+-------+
    | Variable_name  | Value |
    +----------------+-------+
    | slow_query_log | ON    |
    +----------------+-------+
    1 row in set (0.00 sec)
    

    同时,开启慢查询后,会默认在将日志写入DATADIR目录下,命名为host_name_slow.log;当然,可以使用slow_query_log_file=/path/filename,的方式来定义慢查询日志存放路径。下面是自定义日志路径:

    [mysqld]
    slow_query_log=on
    slow_query_log_file=/var/log/mariadb/mysql_slow.log
    

    重启服务查看/var/log/mariadb/mysql_slow.log是否生成

    systemctl restart mariadb

    [root@localhost mysql]# ls /var/log/mariadb/
    mariadb.log  mariadb.log.rpmsave  mysql_slow.log
    

    设置long_query_time的阀值

    上面提到了只要查询时间超过long_query_log设置的值才会被记录到慢查询日志中,所以这个阀值要根据实际的应用环境来定。
    设置long_query_time阀值:

    MariaDB [(none)]> set long_query_time=1;
    Query OK, 0 rows affected (0.00 sec)
    
    MariaDB [(none)]> show variables like 'long_query_time';
    +-----------------+----------+
    | Variable_name   | Value    |
    +-----------------+----------+
    | long_query_time | 1.000000 |
    +-----------------+----------+
    1 row in set (0.00 sec)
    

    为了测试一下慢查询日志,在上将查询时间设置成了一秒

    MariaDB [db4]> select sleep(2), id from tb1 where id = 55;
    +----------+------+
    | sleep(2) | id   |
    +----------+------+
    |        0 |   55 |
    +----------+------+
    1 row in set (3.90 sec)   #查询时间3.9秒
    
    MariaDB [db4]> select id from tb1 where id = 55;
    +------+
    | id   |
    +------+
    |   55 |
    +------+
    1 row in set (0.00 sec)
    

    查看慢查询日志

    # User@Host: root[root] @ localhost []
    # Thread_id: 5  Schema: db4  QC_hit: No
    # Query_time: 3.898127  Lock_time: 1.889486  Rows_sent: 1  Rows_examined: 49
    SET timestamp=1528775278;
    select sleep(2), id from tb1 where id = 55;
    

    可以看到,查询时间超过1秒的查询被记录在日志中,最后的查询则没有被记录。

    官方提供的mysqldumpshow 慢查询分析工具可实现功能如下

    • 统计不同慢sql的
    • 出现次数(Count),
    • 执行最长时间(Time),
    • 累计总耗费时间(Time),
    • 等待锁的时间(Lock),
    • 发送给客户端的行总数(Rows),
    • 扫描的行总数(Rows),

    其他定义参数

    log_slow_filter:

    log_slow_filter是慢查询的一个过滤机制,在log_slow_filter所定义的操作如果执行时间超过慢查询定义的阀值,操作将会被记录到慢查询日志中

    log_queries_not_using_indexes
    log_queries_not_using_indexes是定义是否记录没有使用索引查询语句,默认为OFF

    MariaDB [db4]> show variables like 'log_queries_not_using_indexes';
    +-------------------------------+-------+
    | Variable_name                 | Value |
    +-------------------------------+-------+
    | log_queries_not_using_indexes | OFF   |
    +-------------------------------+-------+
    1 row in set (0.00 sec)
    

    启用该参数:

    MariaDB [db4]> set global log_queries_not_using_indexes=on;
    Query OK, 0 rows affected (0.00 sec)
    

    log_slow_rate_limit = 1

    log_slow_rate_limit 定义多少次查询才会记录到日志中

    查看慢查询状态

    MariaDB [db4]> show variables like '%slow%';
    +---------------------+--------------------------------------------------------------------------------------------------------------+
    | Variable_name       | Value                                                                                                        |
    +---------------------+--------------------------------------------------------------------------------------------------------------+
    | log_slow_filter     | admin,filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk |
    | log_slow_queries    | ON                                                                                                           |
    | log_slow_rate_limit | 1                                                                                                            |
    | log_slow_verbosity  |                                                                                                              |
    | slow_launch_time    | 2                                                                                                            |
    | slow_query_log      | ON                                                                                                           |
    | slow_query_log_file | /var/log/mariadb/mysql_slow.log                                                                              |
    +---------------------+--------------------------------------------------------------------------------------------------------------+
    7 rows in set (0.00 sec)
    

    二进制日志

    二进制日志(bin-log)记录了所有DDL(数据定义语句)和DML(数据操纵语句),对数据库结构,内容产生改变的操作都被记录到二进制日志中。

    日志的位置格式
    在配置文件中定义bin-log选项即可启用二进制日志,mysqld开始将数据变更情况写入日志文件,如果没有定义日志文件名,系统默认会用主机名后面跟‘-bin’,如果指定了文件名称没有指定日志存放路径,默认存放在DATADIR的目录下。

    [mysqld]
    log_bin=master-log
    

    查看bin-log是否启用

    MariaDB [(none)]> show variables like '%log_bin';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | log_bin       | ON    |
    | sql_log_bin   | ON    |
    +---------------+-------+
    2 rows in set (0.00 sec)
    

    log_bin与 sql_log_bin要同时启用,sql_log_bin默认开启,log_bin默认为OFF,需要定义存放位置与名称。

    bin-log日志记录格式

    binlog_format=STATEMENT|ROW|MIXED:二进制日志记录的格式,默认为STATEMENT

    Row :bin-log会记录成【每一行数据被修改的形式】,然后在Slave端再对相同的数据进行修改。

    优点:在Row Level模式下,Binnary Log可以不记录执行的Query语句的上下文相关信息,只要记录哪一行修改了,修改成什么样子。Row Level会详细的记录下每一行数据的修改细节,而且不会出现某个特定情况下的存储过程,或Function,以及Trigger的调用和触发无法被正确复制问题。

    缺点:所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容,比如一条update语句,修改多条记录,则binlog中每一条修改都会有记录,这样造成binlog日志量会很大,特别是当执行alter table之类的语句的时候,由于表结构修改,每条记录都发生改变,那么该表每一条记录都会记录到日志中。

    Statment :【每一条会修改的SQL语句】都会记录到Master的Binnary中。Slave端在复制的时候,SQL线程会解析成和原来Master端执行过相同的SQL语句,并再次执行。

    优点:首先,解决了Row Level下的缺点,不须要记录每一行的数据变化,减少了Binnary Log日志量,节约了IO成本,提高了性能。(相比row能节约多少性能与日志量,这个取决于应用的SQL情况,正常同一条记录修改或者插入row格式所产生的日志量还小于Statement产生的日志量,但是考虑到如果带条件的update操作,以及整表删除,alter表等操作,ROW格式会产生大量日志,因此在考虑是否使用ROW格式日志时应该跟据应用的实际情况,其所产生的日志量会增加多少,以及带来的IO性能问题。)

    缺点:由于它是记录的执行语句,为了让这些语句在Slave端也能正确执行。那么它还必须记录每条语句在执行时的一些相关信息,即上下文信息,以保证所有语句在Slave端被执行的时候能够得到和在Master端执行时相同的结果。

    Mixed :在Mixed模式下, 是以上两种level的混合使用。
    Mixed 混合了Statment 和 Row两种日志,默认情况下才用Statment 格式来记录,但是在一些特定的情况下使用row来记录更优更合理,mixed,可以让系统自行判定该基于哪种方式进行,这正是比较好的地方,但是在主从环境下,可能会产生主从之间的数据不一致。
    Mysql默认是使用Statement日志格式,推荐使用MIXED.

    查看默认bin-log记录格式

    MariaDB [(none)]> show variables like 'binlog_format';
    +---------------+-----------+
    | Variable_name | Value     |
    +---------------+-----------+
    | binlog_format | STATEMENT |
    +---------------+-----------+
    1 row in set (0.00 sec)
    

    二进制日志相关定义参数

    在配置文件中定义好log_bin=master-log之后,在数据库数据存放目录中会生成名为master-log.000001的文件,该文件就是二进制日志文件,而master-log.index文件是索引日志文件。

    一些相关参数定义

    • sql_log_bin= ON | OFF:是否记录二进制日志,默认ON

    • log_bin=/PATH/BIN_LOG_FILE:指定文件位置;默认OFF,表示不启用二进制日志功能,上述两项都开启才可

    • binlog_format=STATEMENT|ROW|MIXED:二进制日志记录的格式,默认STATEMENT
      以上参数上面内容已经提到过

    • max_binlog_size=1073741824;单个二进制日志文件的最大体积,到达最大值会自动滚动,默认为1G

    查看当前二进制日志文件的大小定义

    MariaDB [(none)]> show variables like 'max_binlog_size';
    +-----------------+------------+
    | Variable_name   | Value      |
    +-----------------+------------+
    | max_binlog_size | 1073741824 |  #1G
    +-----------------+------------+
    1 row in set (0.00 sec)
    
    • sync_binlog=1|0;设定是否启动二进制日志即时同步磁盘功能,默认0,由操
      作系统负责同步日志到磁盘

    sync_binlog 参数是比较重要的参数,在mysql的复制中,可以增加slave节点的复制可靠性。在主从复制中应该启用为 1

    MariaDB [(none)]> set global sync_binlog=1;
    Query OK, 0 rows affected (0.00 sec)
    
    MariaDB [(none)]> show variables like 'sync_binlog';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | sync_binlog   | 1     |
    +---------------+-------+
    1 row in set (0.00 sec)
    
    • expire_logs_days=N:二进制日志可以自动删除的天数。 默认为0,即不自动
      删除
    MariaDB [(none)]> show variables like 'expire_logs_days';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | expire_logs_days | 0     |
    +------------------+-------+
    1 row in set (0.00 sec)
    

    Mysql BInlog日志格式可以通过mysql的my.cnf指定。如以下:

    log_bin=master-bin          #binlog日志名 
    binlog_format = MIXED       # binlog日志格式
    expire_logs_days    = 7     #binlog过期清理时间
    max_binlog_size    100m     #binlog每个日志文件大小
    sync_binlog=1               #启用bin-log同步功能
    

    二进制日志读取-mysqlbinlog

    由于日志是以二进制方式存储的,不能直接读取,需要使用mysqlbinlog工具来查看。

    shell> mysqlbinlog log-file

    mysqlbinlog 指令常用选项:

    -d  dbname:  指定数据库名称
    -o  #:   忽略掉日志中的前#个命令
    -r : 将输出的文件格式日志输出到指定文件,重定向
    -s : 简单格式显示,忽略掉一些信息
    --set-charset=charname : 在输出文件时加上set name charname ,装载数据时有用
    --start-datetime= #  : 指定从开始时间显示内容
    --stop-datetime= #  : 指定内容到结束的时间点
    --start-position= #  :指定开始的pos值位置
    --stop-position= #  : 指定到结束的pos值位置
    

    测试创建一张空白查看二进制日志记录的内容

     MariaDB [db5]> create table tb1 (
        -> id int,
        -> name varchar(20)
        -> ) charset=utf8;
    Query OK, 0 rows affected (0.33 sec)
    

    查看bin-log

     [root@localhost mysql]# mysqlbinlog master-bin.000006
    
    # at 245
    #180612 16:26:22 server id 1  end_log_pos 370 	Query	thread_id=4	exec_time=0  #该行记录了当前最新的pos值,使用show master status查看:	error_code=0
    use `db5`/*!*/;
    SET TIMESTAMP=1528791982/*!*/;
    SET @@session.pseudo_thread_id=4/*!*/;
    SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    SET @@session.sql_mode=0/*!*/;
    SET @@session.auto_increment_increment=2, @@session.auto_increment_offset=1/*!*/;
    /*!C utf8 *//*!*/;
    SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;
    SET @@session.lc_time_names=0/*!*/;
    SET @@session.collation_database=DEFAULT/*!*/;
    create table tb1 (
    id int,
    name varchar(20)
    ) charset=utf8
    /*!*/;
    DELIMITER ;
    # End of log file
    ROLLBACK /* added by mysqlbinlog */;
    /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
    
     MariaDB [db5]> show master status;
    +-------------------+----------+--------------+------------------+
    | File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +-------------------+----------+--------------+------------------+
    | master-bin.000006 |      370 |              |                  |
    +-------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    

    也可以使用指定pos值的方式来查看

    [root@localhost mysql]# mysqlbinlog --start-position=245 --stop-position=370 master-bin.000006

    二进制日志的删除

    在繁忙的系统中,每天都会生成大量的日志文件,如果时间长不进行清理会对磁盘空间造成负担,定义备份好日志文件并清理日志是很有必要的工作。
    删除日志的方式

    • 方法1

    执行reset master; 指令

    该命令将删除所有bin-log日志,新的日志编号从000001开始。

    • 方法2

    执行purge master logs to 'master-bin.******' , 执行该命令将会删除指定该编号前的所有的bin-log日志文件。

    MariaDB [db5]> purge master logs to 'master-bin.000006';
    Query OK, 0 rows affected (0.81 sec)
    

    只保留了master-bin.000006以后的日志

    关于一些比较的重要的日志就说这么多,后面再介绍mysql的备份内容。

  • 相关阅读:
    [转]Maven类包冲突终极三大解决技巧
    python chardet 模块
    python pretty-errors模块
    认识执行时机
    python对象销毁顺序
    python字符串驻留
    python绘图练习
    小练习2
    小练习
    4G 内存处理 10G 大小的文件
  • 原文地址:https://www.cnblogs.com/anay/p/9174510.html
Copyright © 2011-2022 走看看