zoukankan      html  css  js  c++  java
  • MySQL体系结构之物理文件

    一、MySQL日志文件

    mysql日志文件及功能:

    日志文件

    功能

    错误日志

    记录启动、停止、运行过程中mysqld时出现的问题

    通用日志

    记录建立客户端连接和执行的语句

    二进制日志

    记录更改数据的所有语句,还用于复制

    慢查询日志

    记录执行时间超过long_query_time秒的所有查询

    默认情况下,mysql所有日志均存储于mysql数据目录下。通过刷新日志,可以时mysqld强制关闭和打开日志文件(或者在某些情况下切换到下一个日志)。

    刷新日志方法:

    1)flush logs

    2)mysqladmin flush-logs

    3)mysqladmin refresh

    1、错误日志

    1)作用:记录mysqld启动、停止以及mysql数据库在运行过程中发生的各种严重错误信息。当数据库发生任何故障导致无法重启时,可以参考错误日志进行故障诊断。

    2)位置:可以使用--log-error[=file_name]参数选项来指定mysqld保存错误日志文件的位置。如果没有给定file_name文件位置,mysqld使用的错误日志名为host_name.err并默认保存在datadir指定的目录下。

    2、通用日志

    1)作用:查询日志记录客户端的所有语句(所有连接和语句都记录到通用日志),而binlog不记录select语句。

    2)位置:查询日志和慢查询日志都可以保存在文件或表中,并使用参数--log-output[=value]来进行控制,value的值可以是table,file,none的一个或多个的组合,中间用逗号进行分割,分别表示日志保存在表,文件,不保存在表或文件中,这里的表指的是mysql库总的general_log(慢查询日志是slow_log)表。其中none的优先级最高,比如--log-output=table,file表示日志同时输出到表和文件中,--log-output=table,none表示日志不保存在表中。如果不显示使用此参数,则表示日志输出到文件中。一般日志输出到表中要占用更多的系统资源。

    如果要启用查询日志,可以通过参数--general_log[={0|1}]和--general_log_file=file_name来进行控制。前者控制是否启用查询日志(--general_log设置为1或者不带值都可以启用查询日志,设置为0表示关闭查询日志,不指定此参数表示不启动查询日志),后者控制日志文件的路径。也可以使用--log[=file_name]或-l [file_name]选项启动它,如果没有给出file_name,那么默认值就是host_name.log。运行时可以通过set global general_log on打开通用日志。

    如果没有指定--general_log_file=file_name值,且没有显示设置--log_output参数,那么日志默认写入datadir目录下的,默认文件名为host_name.log。这两个参数都是global类型,可以在启动时或系统运行时动态修改。如果想在session级别控制日志是否被记录,则通过在session中设置参数sql_log_off为on或off来进行控制。

    查询通用日志位置:

    mysql> show variables like 'gene%';

    +------------------+--------------------------------------+

    | Variable_name    | Value                                |

    +------------------+--------------------------------------+

    | general_log      | OFF                                  |

    | general_log_file | /usr/local/mysql/data/chavinking.log |

    +------------------+--------------------------------------+

    2 rows in set (0.00 sec)

    3)日志内容的读取:查询日志为文本文档格式,一般直接读取就可。

    4)一般情况下不建议开启查询日志功能,否则可能造成短时间内磁盘占用率猛增。

    3、慢查询日志

    1)概述:当参数slow_query_log=1时,慢查询日志记录了所有执行时间超过参数long_query_time设置值并且扫描记录数不小于min_examined_row_limit的所有sql语句的日志(获得表锁定的时间不能算作执行时间)。当没有给出慢查询日志名时,默认为主机名,后缀为-slow.log,当给出了文件名,但不是绝对路径,慢查询日志会记录到mysql的数据目录下。执行完语句并且释放锁后,即可记入慢查询日志,记录顺序可以与执行顺序不同。慢查询日志可以查找执行时间长的语句,用于优化,它是MySQL数据中常用的性能优化工具。Long_query_time默认为10秒,最小为0,精度可以到微秒。

    一般两类语句不记录到慢查询日志中:管理语句和不使用索引进行查询的语句。如果要监控这两类SQL语句,可以分别通过参数--log-slow-admin-statements和log_queries_not_using_indexes进行控制。

    2)文件位置和格式:慢查询日志默认是关闭的,在mysql5.1.29前,当用--log-slow-queries[=file_name]选项启动mysqld时,慢查询日志开始被记录。和前几种日志一样,如果没有指定file_name的值,日志将写入datadir路径,默认文件名为host_name-slow.log。在mysql5.1.29后,--log-slow-queries参数废弃,采用两个新的参数进行替换:--slow_query_log[={0|1}]显示指定慢查询日志状态,如果不指定值或指定值为1都会打开慢查询;使用slow_query_log_file[=file_name]来指定慢查询日志路径,另外还可以指定--log-output参数指定日志的输出格式,默认输出到文件。需要注意的是如果选择输出到表,则表中的记录的慢查询时间只能精确到秒,而日志文件中可以精确到微秒。

    3)日志文件的读取:慢查询日志文件是存文本方式存储,可以直接读取。也可以通过mysqldumpslow工具(../bin/mysqldumpslow faspdev-slow.log)对慢查询日志进行汇总处理。慢查询日志通常用来定位mysql服务中sql问题,默认建议打开慢查询日志,并定期查看分析。

    4)慢查询日志在mysql性能优化中的作用详解:

    4.1)慢查询日志格式:

    mysql慢查询标准:

    query_time:查询耗时

    rows_examined:检查多少条记录

    rows_sent:返回多少行记录

    mysql使用以上几点大致衡量sql成本。

    其他信息包括如下:

    time:执行sql开始时间

    lock time:等待table lock的时间,注意innodb行锁等待不会反应在这里。

    user@host:执行查询的用户和客户端ip

    以下是一个慢查询例子:

    # Time: 170122 13:53:17

    # User@Host: root[root] @ localhost []  Id:     1

    # Query_time: 9.839503  Lock_time: 0.000159 Rows_sent: 0  Rows_examined: 524288

    SET timestamp=1485064397;

    insert into column_charset  select * from column_charset;

    一般执行时间最长的sql是需要优化的,如果检查了大量数据而只返回少量数据,则意味着质量不佳。需要注意的是慢查询日志里的慢查询不一定就是不良sql,还可能受其他查询影响,或者受到系统资源限制导致的。

    4.2)如何识别需要关注的sql:

    确认已经开启了慢查询日志,并且设置了合理的阈值。以下命令可以查看是否启用慢查询日志以及慢查询日志路径:

    mysql> show variables like '%slow_query_log%';

    +---------------------+------------------------------------------- ------------------------+

    | Variable_name       | Value                                      |

    +---------------------+--------------------------------------------------------------------+

    | slow_query_log      | OFF                                        |

    | slow_query_log_file | /usr/local/mysql5631/data/faspdev-slow.log |

    +---------------------+-------------------------------------------------------------------+

    以下命令可以查看全局变量long_query_time参数的值,所有超过该值得sql都将记录到慢查询日志中:

    mysql> show variables like 'long_query_time';

    +-----------------+-----------+

    | Variable_name   | Value     |

    +-----------------+-----------+

    | long_query_time | 1.000000 |

    +-----------------+-----------+

    1 row in set (0.00 sec)

    在mysql参数文件中开启慢查询日志设置如下:

    [mysqld]

    slow_query_log=1

    slow_query_log_file=/usr/local/mysql/data/log/slowquery.log

    long_query_time=0.5

    mysql 5.0慢查询参数是不一样的,且需要重启后才可以生效,相关参数为log_slow_queries和slow_launch_time。

    参数log-queries-not-using-indexes用于指定如果没有使用到索引或虽然使用了索引但仍然遍历了所有记录,就将其记录下来,默认此参数是关闭的。

    4.3)使用工具分析慢查询日志

    如果慢查询日志内容比较多,对于分析是比较麻烦的,一般有以下两种办法可以参考:

    u 调整阈值

    u 使用命令、脚本、工具进行分析,如mysqldumpslow、pt-query-digest等。

    A. 使用操作系统命令进行分析:

    可以使用shell命令进行统计分析,如grep、awk、wc,但是这些工具不容易实现高级功能。

    awk '/^#Time:/{print $3,$4,c;c=0}/^#User/{c++}' mysql-slow.log > /mnt/slowquery.log

    B. 使用mysqldumpslow工具进行分析:

    mysqldumpslow工具是官方自带的,此工具可以获得日志中的查询摘要。以下是mysqldumpslow工具使用帮助:

    $mysqldumpslow --help

    Usage: mysqldumpslow [ OPTS... ] [ LOGS... ]

    Parse and summarize the MySQL slow query log. Options are

      --verbose    verbose

      --debug      debug

      --help       write this text to standard output

      -v           verbose

      -d           debug

      -s ORDER     what to sort by (t, at, l, al, r, ar etc), 'at' is default

      -r           reverse the sort order (largest last instead of first)

      -t NUM       just show the top n queries

      -a           don't abstract all numbers to N and strings to 'S'

      -n NUM       abstract numbers with at least n digits within names

      -g PATTERN   grep: only consider stmts that include this string

      -h HOSTNAME  hostname of db server for *-slow.log filename (can be wildcard),

                   default is '*', i.e. match all

      -i NAME      name of server instance (if using mysql.server startup script)

      -l           don't subtract lock time from total time

    查询时间最长的10个sql:

    mysqldumpslow -t 10 mysql-slow.log

    查询访问次数最多的10个sql命令:

    mysqldumpslow -s c -t 10 mysql-slow.log

    查询访问记录最多的10条sql命令:

    mysqldumpslow -s r -t 10 mysql-slow.log

    4.4)以下是mysql运行状态下设置慢查询日志的例子

    mysql> show variables like 'long_query_time';

    +-----------------+-----------+

    | Variable_name   | Value     |

    +-----------------+-----------+

    | long_query_time | 10.000000 |

    +-----------------+-----------+

    1 row in set (0.00 sec)

    mysql> set long_query_time=2;

    Query OK, 0 rows affected (0.00 sec)

    mysql> show variables like '%slow_query_log%';

    +---------------------+--------------------------------------------+

    | Variable_name       | Value                                      |

    +---------------------+--------------------------------------------+

    | slow_query_log      | OFF                                        |

    | slow_query_log_file | /usr/local/mysql5631/data/faspdev-slow.log |

    +---------------------+--------------------------------------------+

    2 rows in set (0.00 sec)

    mysql> set global slow_query_log=1;

    Query OK, 0 rows affected (0.00 sec)

    4、binlog日志文件

    1)作用:Binlog记录了数据库所有的ddl语句和dml语句,但不包括select语句内容,语句以事件的形式保存,描述了数据的变更顺序,binlog还包括了每个更新语句的执行时间信息,binlog主要作用是用于恢复数据,因此binlog对于灾难恢复和备份恢复来说至关重要。相当于oracle数据库中的archivelog文件。

    binlog还用于实现mysql主从复制。

    二进制日志文件记录了数据库的变更过程,对于数据库的安全性和完整性起着至关重要的作用。

    2)位置和格式:当用--log-bin[=file_name]选项启动时,mysqld开始将数据库变更情况写入日志文件。如果没有给出file_name值,默认名为主机名-bin。如果给出了文件名,但不包含路径,则文件默认被写入datadir参数指定路径。

    mysqld将在每个binlog日志名后添加一个数字扩展名,每次要启动服务器或刷新日志时,该数字将会增加,如果当前日志大小达到了max-binlog-size参数设置的值,那么mysqld会自动创建新的二进制日志。

    mysqld还将创建一个binlog索引文件,其中包含了所有binlog文件的文件名,默认该索引文件与binlog文件名相同,扩展名为.index。当mysqld运行时,不可以手工编辑该索引文件,这样可能导致mysqld异常。当rm删除binlog后,你也许不得不手工编辑索引文件。

    3)binlog日志格式

    mysql有两种记录命令方式,一种是语句级(binlog_format=statement),一种是行级(binlog_format=row),建议命令格式设置为混合模式(binlog_format=mixed),这在大部分模式下试用,它在一般情况下试用语句级记录,但是在一些特殊情况下试用行级记录,这增加了复制的健壮性。

    Mysq5.5中,二进制日志格式分为3种:statement,row和mixed,可以在启动数据库时通过参数--binlog_format进行设置,这3种格式区别如下:

    3.1)statement:

    Mysql5.1之前的版本都采用这种方式,binlog日志中记录的都是语句(基于语句级的日志里包含了原始执行的sql语句,还有其他信息,如执行语句的线程id,语句执行的时间戳,执行所消耗时长),每一条对数据库造成修改的语句都会记录在日志中,通过mysqlbinlog工具,可以清晰的看到每条语句的文本。主从复制时,从库的日志解析为原文本在从库中执行。优点是日志量小,清晰易懂,对io压力小,缺点是某些情况下slave的日志复制会出差。

    3.2)row:

    Mysql5.1.11之后出现的。它将每一行变更记录到日志中,而不是记录sql语句(记录行的更改信息而不是语句)。优点是记录每一行数据变化的细节,不会出现slave模式下某些情况无法复制的情况。缺点是日志量大,对io影响较大。通过mysqlbinlog默认看到的都是经过base-64编码的信息,mysqlbinlog加参数-verbose(或-v)将会生成带注释的语句,如果连续两次使用这个参数(如-v -v),则生成字段类型、长度、是否为null等属性信息。

    一般而言,row模式更为健壮,而statement级别如果应用了mysql的一些额外特性,比如存储过程、触发器,则可能导致复制异常,所以,如果使用语句级记录,那么需要保持mysql数据库应用的简单性,即只用核心功能即可。

    3.3)mixed:

    这是目前mysql的默认binlog日志格式,即混合了statement和row两种日志。默认情况下采用statement,但是在一些特殊情况下采用row方式记录日志。此种模式利用statement和row的优点,而尽量避开他们的缺点。

    注意:可以在global和session级别对binlog日志的格式进行修改。

    4)日志文件的读取

    由于binlog以二进制方式存储,不能直接读取,因此需要使用mysqlbinlog工具进行日志分析,语法:mysqlbinlog log-file。

    例:

    4.1)以binlog方式启动数据库:

    [root@faspdev bin]# ./mysqld_safe --user=mysql --log-bin=binlog-test

    4.2)执行dml语句:

    mysql> delete from t1;

    Query OK, 2 rows affected (0.02 sec)

    4.3)mysqlbinlog查看binlog内容:

    [root@faspdev data]# ../bin/mysqlbinlog binlog-test.000001

    /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;

    /*!40019 SET @@session.max_insert_delayed_threads=0*/;

    /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;

    DELIMITER /*!*/;

    # at 4

    #161111 17:45:52 server id 1  end_log_pos 120 CRC32 0x5bfb8e4f Start: binlog v 4, server v 5.6.31-log created 161111 17:45:52 at startup

    # Warning: this binlog is either in use or was not closed properly.

    ROLLBACK/*!*/;

    BINLOG '

    UJMlWA8BAAAAdAAAAHgAAAABAAQANS42LjMxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAABQkyVYEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAU+O

    +1s=

    '/*!*/;

    # at 120

    #161111 17:47:29 server id 1  end_log_pos 199 CRC32 0x3f0abe26 Query thread_id=1 exec_time=0 error_code=0

    SET TIMESTAMP=1478857649/*!*/;

    SET @@session.pseudo_thread_id=1/*!*/;

    SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;

    SET @@session.sql_mode=1075838976/*!*/;

    SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;

    /*!C utf8 *//*!*/;

    SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;

    SET @@session.lc_time_names=0/*!*/;

    SET @@session.collation_database=DEFAULT/*!*/;

    BEGIN

    /*!*/;

    # at 199

    #161111 17:47:29 server id 1  end_log_pos 287 CRC32 0x78e57a7e Query thread_id=1 exec_time=0 error_code=0

    use `test`/*!*/;

    SET TIMESTAMP=1478857649/*!*/;

    delete from t1

    /*!*/;

    # at 287

    #161111 17:47:29 server id 1  end_log_pos 318 CRC32 0x0b2d7e98 Xid = 9

    COMMIT/*!*/;

    DELIMITER ;

    # End of log file

    ROLLBACK /* added by mysqlbinlog */;

    /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

    /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

    如果日志格式是row,mysqlbinlog解析的文件是无法读懂的字符,可以加-v或-v -v进行查看。

    5)默认情况下,并不是每次写入时都将binlog与磁盘同步,因此操作系统或机器发生故障,那么binlog中最后的语句有可能会丢失。要防止这种情况发生,可以设置sync_binlog全局变量为n(1为最安全的值,同时也是最慢的),使binlog每n此写入就与磁盘做同步。

    6)日志文件的删除

    查看binlog方法:

    mysql> show binary logs;

    6.1)方法1:reset master删除所有的binlog日志文件,删除后的日志文件从1开始编号。

    mysql> reset master;

    Query OK, 0 rows affected (0.00 sec)

    6.2)方法2:使用purge binary logs命令删除部分binlog文件:

    mysql> purge binary logs to 'mysql-bin.000001';

    Query OK, 0 rows affected (0.03 sec)

    6.3)方法3:purge master logs to ‘mysql-bin.******’命令,该命令删除‘******’编号之前的所有日志文件。

    6.4)方法4:purge master logs before ‘yyyy-mm-dd hh24:mi:ss’命令,该命令删除‘yyyy-mm-dd hh24:mi:ss’日期之前的所有日志。

    6.5)设置参数--expire_logs_days=#,此参数含义是设置日志过期天数, 过了指定天数后的日志将会被自动删除,这样有利于减少DBA管理日志的工作量。

    7)mysqlbinlog解析:

    u # at 199

    u #161111 17:47:29 server id 1  end_log_pos 287

    u # Query thread_id=1 exec_time=0 error_code=0

    8)binlog管理相关参数

    8.1)--binlog-do-db=db_name:该参数告诉主服务器,如果当前的数据库是db_name,应该将其记录到binlog中,其他没有被指定的数据库将被忽略,可多次使用,对多个数据库进行定义。

    8.2)--binlog-ignore-db=db_name:改参数告诉主服务器,如果当前数据库为db_name,则不记录binlog,其他没有指定的数据库变化将记录binlog中,可多次使用,对多个数据库进行定义。

    8.3)--innodb-sage-binlog:该参数经常和--sync-binlog=N(没写N次日志同步磁盘)一起配合使用,使得事务在日志中的记录更加安全。

    8.4)Set sql_log_bin=0:具有super权限的客户端可以通过此语句禁止将自己的语句记录二进制文件,这个选项在某些环境下是有用的,比如主主切换,或者mysql版本升级,但是使用一定倍加小心,免得造成slave环境下的数据不一致。

    5、日志文件维护

    很多生产环境,日志文件可以占用大量的磁盘空间,因此,需要对日志文件进行定期清理操作,mysql服务器当然也不例外。

    l 对于错误日志文件,一般不会太大,因此生产上注意一下就可以了。

    l 通用日志一般生产不开启,因此也不存在清理一说。

    l 慢查询日志在慢查询很多的情况下可能变得很大,可以手工清理或编写脚本管理。

    l binlog日志文件可以设置合适的过期策略,如expire-logs-days=10,表示设置binlog过期时间为10天。expires-logs-days设置会在运行flush logs命令后触发删除过期日志,注意,不能使用rm删除binlog日志文件,这可能导致你执行日志清理命令失败。mysql 5.6可以设置保留binlog日志文件大小,避免磁盘对填满。

    二、innodb数据文件和日志文件

    1、以下简单介绍mysql数据目录下的文件:

    1)db.opt

    数据库结构定义和设置

    2)*.frm

    数据表的结构定义

    3)*.MYD

    Myisam引擎表数据

    4)*.MYI

    Myisam引擎索引数据

    5)ibdata*

    Innodb表空间数据文件

    如果将innodb_file_per_table设置为1,那么innodb数据表可以各自存储为一个文件,这种模式成为独立表空间。如果将innodb_file_per_table设置为0,那么innodb数据则可以统一存储在一个共享表空间里。

    6)ib_logfile*

    Innodb重做日志文件

    7)*.idb

    Innodb数据和索引。

    8)*.trg

    触发器

    2、innodb数据文件和日志文件

    如果没有再参数文件中指定innodb相关参数,那么mysql将会在data目录下创建一个大小为10m的ibdata1文件和大小5m的两个ib_logfile*文件。这种设置对于生产而言太小,一般建议设置logfile为256m,数据文件初始大小1g~5g,并且设置自动增长。

    参数配置样例:

    Innodb_data_file_path=ibdata1:1000m:autiextend

    Innodb_log_file_size=256m

    Innodb_data_file_path的值可以设置为1个或多个列表。如果要命名一个以上的数据文件,请用“;”分隔它们。其语法格式为:Innodb_data_file_path=datafile01:size[;datafile02:size;...]。

    例如:Innodb_data_file_path=datafile01:2000m;datafile02:2000m;datafile03:2000m:autoextend

    其中autoextend及其后属相只能用于Innodb_data_file_path列表中最后一个数据文件,针对于最后一个数据文件,如果innodb共享表空间耗尽后,就会扩展最后一个数据文件,默认扩展大小为8m。

    1)innodb独立表空间和共享表空间

    共享表空间使用简单,方便维护,但是也存在缺点,使用贡献表空间明显的缺点是不能快速回收删除大表的空间,io操作可能会消耗更多的资源等待。而独立表空间是大部分DBA推荐使用的方式,它恰好在这一点弥补了共享表空间不足。Innodb下使用独立表空间,每个表都有它自己的表空间。

    开启独立表空间方式:

    在my.cnf文件中添加如下参数,重启mysql实例即可生效:

    [mysqld]

    innodb_file_per_table

    重启实例后,innodb将会把新创建的表存储到数据目录下的文件tb1_name.ibd中,这类似域myisam存储引擎所做的事,但是myisam把表分成数据文件tb1_name.MYD和索引文件tb1_name.MYI。对于innodb,数据和索引会放在一起,都存放到.ibd文件中,不过tb1_name.frm文件照旧会被创建。

    在my.cnf文件中删除了innodb_file_per_table行,重启实例后,innodb新创建的表会存储在共享表空间里,就是说innodb_file_per_table这个参数仅影响表的创建位置。innodb使用独立表空间,也仍然有一部分数据在共享表空间里。

    相对于myisam引擎管理的表,我们不能随意移动.ibd文件,这是因为表定义是被存储在innodb共享表空间里的,而innodb必须保持事务id和事务日志顺序号的一致性。

    2)innodb增加数据文件

    手动增加一个innodb数据文件时需要重启实例。为innodb存储引擎管理表添加数据文件需要修改my.cnf参数文件,把innodb_data_file_path参数指定添加的数据文件及其初始大小和相关参数。注意当你添加一个数据文件到innodb_data_file_path时,需要确定它不存在,当你重启实例时,innodb会自动创建这个数据文件。添加innodb数据文件需要首先计算当前innodb_data_file_path中最后一个数据文件大小,然后估计一个近似值给它,再添加新的数据文件。Innodb数据文件只有最后一个可以设置为自动扩展。

    3)改变innodb重做日志大小

    不要试图通过直接更改配置文件来设置innodb事务日志大小,这会导致不能启动数据库。如果想要改变innodb事务日志的数量和大小,必须正常关闭mysql实例,然后复制旧日志文件到一个安全的地方做备份,然后从日志文件目录删除所有的旧日志文件,之后更改my.cnf参数文件改变日志文件配置,并再次启动mysql实例。Mysqld在启动时会发现没有重做日志文件,然后告诉你它正在创建一个新的日志文件。

    更改innodb事务日志步骤:

    l 干净关闭mysql实例

    l 使用mv命令转移innodb重做日志文件。

    l 修改my.cnf配置文件,更改innodb_log_file_size

    l 启动mysql实例

    注意,旧版本mysql服务器重做日志总大小不能超过4g,在mysql5.6以后,限制扩展到521g。

    4)innodb的undo区域

    Undo区域也称为undo空间或undo表空间,是innodb设计的一块特殊存储区域,它保存了被活动事务更改的数据的副本(镜像),如果一个事务需要查看原来的数据(满足一致性读),那么可以从undo区域中获得未被更改的数据。默认情况下,undo区域也是在innodb共享表空间内。Mysql5.6以后提供了选项,可以把undo表空间独立到表空间,这样就可以进行热点块的io优化,提升性能。

    如果undo表空间暴涨,出现这种情况可能是因为负载比较大,或者存在长时间未提交的事务(长事务)。

    对于写操作比较频繁的应用,innodb清理线程的速度可能会跟不上,从而导致undo表空间越来越大,可以通过设置innodb_max_purge_lag参数来避免undo空间过度增大。Innodb事务系统维持一个事务列表,该列表记录被update或delete操作表示为删除的索引记录。这个列表的长度为purge_lag。当purge_lag超过了nnodb_max_purge_lag时,每个dml语句都被延迟一定时间。

    Undo空间里保存了数据的前镜像,这是满足一致性读的根本原因,同时也是灾难恢复的重要角色(即回滚)。

    3、临时文件

    Mysql临时文件作用类似但不等同于oracle临时表空间。Mysql使用环境变量TMPDIR的值作为保存临时文件的目录。如果未设置,则默认使用系统的默认值,一般为/tmp,/var/tmp,/usr/tmp。可以使用--tmpdir参数在启动时指定mysql临时目录,或者在my.cnf文件中指定tmpdir参数进行分配。

    如果mysql服务器正在作为复制服务器使用,那么不能将mysql临时路径指向基于内存的文件系统目录或者主机重启会清空的目录,否则可能造成复制失败。Mysql隐含创建所有的临时文件。进行排序操作时,mysql会使用一个或多个临时文件。一定要保证临时目录空间够用。一些普通的数据库操作都有可能创建临时文件用于维护数据库内的数据结构,alter table会在原表所在目录下创建临时表。

    4、mysql套接字文件

    服务器用来与本地客户端进行通信的linux套接字文件(也称为socket文件)默认位置是/tmp/mysql.sock。Scoket文件不建议放置在/tmp目录下,可以将其单独指定存储位置,我们可以通过my.cnf配置文件指定mysql socket文件存储路径,下面是my.cnf中定义socket储存路径:

    [mysqld]

    Socket=/opt/mysql/mysql.socket

    [client]

    Socket=/opt/mysql/mysql.socket

    Mysql服务器一定要保留root的除了socket外的其他登录方式,比如通过127.0.0.1的root登录账号,以防止socket文件被删除导致无法登录mysql数据库的窘境。

    三、MySQL灾难恢复过程

    1、预写日志和undo表空间

    mysql靠预写日志(innodb事务日志)来保证数据持久性,也就是说数据文件不会先被写入,而是先写日志文件。innodb脏数据存在于innodb_buffer_pool里,它会按照一定的机制批量写入磁盘,这样可以提高吞吐率。

    mysql宕机后的实例恢复过程:首先mysql找到事务日志中的某个点,从该点开始重做redo中的事务,在应用了所有redo日志后,根据undo区域确定哪些事务需要回滚,然后回滚哪些没有提交的事务,简单理解,mysql灾难恢复过程就是根据redo重做日志,然后根据undo回退事务。

    innodb事务日志很大程度上决定了数据的安全性,日志的持久性决定了灾难恢复后丢失多少数据!mysql可以通过参数控制commit时写入事务日志的频率,通常有以下3种情况:

    1)innodb_flush_log_at_trx_commit=1

    每次commit时都写入磁盘,这样理论上发生故障时我们只丢失一个事务。

    2)innodb_flush_log_at_trx_commit=2

    每次commit,只写日志缓存到操作系统缓冲,但不刷新磁盘,innodb每秒刷新磁盘一次,所以故障丢失的是最近1秒的数据。生产环境建议这样设置。

    3)innodb_flush_log_at_trx_commit=0

    每秒把日志缓冲的内容写入到日志文件,并且刷新到磁盘,但commit时什么也不做。

    2、双写缓冲

    数据文件的写操作,可能会将块写坏,mysql设计了一个数据存储区域双写缓冲,innodb使用双写缓冲来确保数据的安全,避免块损坏。双写缓冲是innodb表空间的一个特殊区域,主要用于写入页的备份,并且是顺序写入的。当innodb刷新数据时,首先写入双写缓冲,然后写入数据文件。这样既可确保所有写操作的原子性和持久性。

    崩溃重启后,innodb会检查每个块的校验和,判断块是否损坏,如果写入双写缓冲的是坏块,那么显然没有写入实际数据文件,那么用数据文件的块恢复双写缓冲;如果写入了双写缓冲,但是数据文件中的是坏块,那么使用双写缓冲中的块恢复实际数据文件中的块。这样的机制提供了双层的安全保障,但是缺点是增加了io。

    对于读取操作,innodb通过页校验和来保证数据的存取,每页在内存中都先算好一个校验值,放在文件头部,写入的时候先写校验值,读的时候也会校验一下校验值。

    四、mysql参数文件及参数修改方法

    MySQL数据库初始化参数由参数文件来设置,如果没有设置参数文件,mysql就按照系统中参数的默认值来启动。在windows和linux上,参数文件可以被放在多个位置,数据库启动时按照不同的顺序来搜索,如果多个位置都有参数文件,则搜索顺序靠后的参数文件中的参数将覆盖前的参数。

    表:linux下mysql参数文件读取顺序:

    参数文件名

    目的

    /etc/my.cnf

    全局选项

    $MYSQL_HOME/my.cnf

    服务器相关选项

    Default-extra-file

    用--Default-extra-file=path选项指定的文件,如果该文件存在的话

    ~/.my.cnf

    用户相关选项

    Mysql安装上述顺序寻找参数文件,如果多个文件同时存在,那么文件中指定的后读取的选项要优先于先读取的选项,所以数据目录或安装目录下的配置文件都有可能生效,所以理论上在数据目录或安装目录下放置一个my.cnf文件即可。Mysql启动时可以指定--datadir用于指定数据路径,但是此选项对于查询参数文件无效,因为在读取--datadir之前mysql服务器就已经读取了配置文件了。多次指定一个选项,后出现的将覆盖先出现的值,因此命令行中通过set修改的选项优先级最高。

    通过如下命令可以列出mysqld读取参数文件的优先顺序:该命令不能在生产环境随意运行

    $mysqld --verbose --help |grep my.cnf

    /etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf

    Mysql参数可以在3个级别进行更改:

    1)session级别:set

    2)全局级别:set global

    3)永久级别:my.cnf

    附:一份生产可用的mysql配置文件(my.cnf)示例(测试库mysql 5.6.24):

    [client]

    #客户端选项设置

    port = 3306

    socket = /opt/mysql-5.6.24/data/mysql.socket

    #设置客户端和连接字符集

    default_character_set = utf8

    [mysqld]

    #服务器端选项设置

    # innodb设置

    default_storage_engine = InnoDB

    innodb_strict_mode = 1

    innodb_buffer_pool_size = 256M      #mysql数据库服务器,该值可设为物理内存的50%-80%之间

    innodb_stats_on_metadata = 0

    innodb_file_format = Barracuda

    innodb_data_file_path=ibdata1:10m:autoextend

    innodb_flush_method = O_DIRECT

    innodb_log_files_in_group = 2

    innodb_log_file_size = 16M

    innodb_log_buffer_size = 8M

    innodb_file_per_table = 1

    innodb_max_dirty_pages_pct = 60

    innodb_io_capacity = 200

    innodb_flush_log_at_trx_commit = 2

    # 基本设置

    basedir = /opt/mysql-5.6.24

    datadir = /opt/mysql-5.6.24/data

    port = 3306

    server_id = 19900315

    tmpdir = /opt/mysql-5.6.24/tmp

    socket = /opt/mysql-5.6.24/tmp/mysql.socket

    Pid-file = /opt/mysql-5.6.24/data/mysql.pid

    skip-name-resolve = 1

    skip-external-locking = 1

    max_connect_errors = 500

    max_connections = 1000

    relay-log = mysql-relay-bin

    log-slave-updates = 1

    skip_slave_start = 1

    read_only = 0

    key_buffer_size = 8M

    tmp_table_size = 8M

    max_heap_table_size = 8M

    query_cache_type = 0

    query_cache_size = 0

    thread_cache_size = 1024

    open_files_limit = 65535

    table_open_cache = 1024

    max_allowed_packet = 16M

    gtid-mode = ON

    enforce-gtid-consistency = 1

    lower_case_table_names=1

    log-bin-trust-function-creators

    plugin-load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"

    replicate-ignore-table = mysql.ibbackup_binlog_marker

    slave-skip-errors = ddl_exist_errors

    relay-log-info-repository = TABLE

    relay_log_recovery = 1

    master_info_repository = TABLE

    # 服务器字符集设置

    character_set_server = utf8

    # error log设置

    log_error = /opt/mysql-5.6.24/data/mysql.err

    # slow log设置

    slow_query_log = 1

    slow_query_log_file = /opt/mysql-5.6.24/data/mysql-slow.log

    long_query_time = 0.5

    # binlog设置

    binlog_format = mixed

    log-bin = /opt/mysql-5.6.24/logs/mysql-bin

    sync_binlog = 2

    max_binlog_size = 16M

    expire_logs_days = 10

    #others设置

    join_buffer_size = 128M

    sort_buffer_size = 2M

    read_rnd_buffer_size = 2M

    sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

  • 相关阅读:
    C语言知识
    Java课程设计——个人
    Java大作业
    DAO模式代码阅读及应用
    有理数设计
    泛型 -Java
    集合框架之ArrayList -Java
    图总结
    树、二叉树、查找算法总结
    编辑器、编译器、文件、IDE等常见概念辨析
  • 原文地址:https://www.cnblogs.com/wcwen1990/p/6932536.html
Copyright © 2011-2022 走看看