IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> Mysql之文件 -> 正文阅读

[大数据]Mysql之文件

Mysql中的重要文件可以分为两大类:Mysql数据库本身的文件和存储引擎的文件(这里只介绍InnoDB相关的文件)。

Mysql数据库自身的文件

参数文件

告诉Mysql实例启动时在哪里可以找到数据库文件,并且制定某些初始化参数,这些参数定义了某种内存结构的大小等设置。Mysql启动时可以没有参数文件,这时所有的参数值取决于编译Mysql时指定的默认值和源代码中指定参数的默认值。但是如果Mysql实例在默认的数据库目录下找不到mysql架构,则启动会失败。
什么是参数呢?
简单的说,可以把数据库参数看成一个键值对。例如,一个对于InnoDB存储引擎非常重要的参数innodb_bufer_pool_size。如果想将此参数设置为1G,即innodb_bufer_pool_size=1G。这里的“键”是innodb_bufer_pool_size,“值”是1G,这就是键值对。
参数类型分类

  • 动态参数:意味着可以在Mysql实例运行中进行更改。
  • 静态参数:说明在整个实例生命周期都不得进行更改,就好像是只读的一样。

注意,此文件是Mysql数据库本身的文件,和存储引擎无关。

日志文件

日志文件记录了影响Mysql数据库的各种类型活动。常见的有以下几种:

错误日志文件(error log)

错误日志文件对Mysql的启动、运行、关闭过程进行了记录。在默认情况下错误文件的文件名为服务器的主机名。当出现Mysql数据库不能正常启动时,第一个必须查找的文件应该是错误日志文件。

慢日志文件(slow query log)

慢日志就是记录查询时间耗时较长sql的日志。可以在Mysql启动时设一个阈值,将运行时间超过(等于这个值的不会被记录)该值的所有sql语句都记录到慢查询日志文件中。该参数为long_query_time默认是10,代表10秒。注意,sql的执行时间是实时的,而不是cpu的执行时间,因此同一条sql会受到系统负载的影响。

这里需要注意两点。首先,设置long_query_time这个阈值后,Mysql数据库会记录运行时间超过该值的所有SQL语句,但是运行时间正好等于该值的情况不会被记录下来。其次,从mysql5.1开始,long_query_time开始以微妙记录SQL语句运行的时间,之前仅用秒为单位记录。这样可以更精确的记录SQL运行的时间。

另一个和慢查询日志有关的参数是log_queries_not_using_indexes,如果打开了此参数,当运行的SQL语句没有使用索引时,则同样会将这条sql记录到慢查询日志文件。

在Mysql5.6.5开始,新增了一个参数log_throttle_queries_not_using_indexes,用来表示每分钟允许记录到slow log的且未使用索引的sql语句次数。该值默认为0,表示没有限制。在生产中,若没有使用索引,此类SQL语句会频繁地被记录到slow log,从而导致slow log文件大小不断增加,故一般生产中需要配置此参数。

DBA可以通过慢日志来找出有问题的SQL语句,对其进行优化。然而随着Mysql数据库服务器运行时间的增加,慢日志文件会越来越大,此时要分析该文件就显得不是那么容易了。而这时Mysql数据库提供的mysqldumpslow命令,可以很好地解决这个问题。例如:

//查询a-slow.log文件所有内容
mysqldumpslow a-slow.log
//查询执行时间最长的10条sql语句
mysqldumpslow -s al -n 10 a-slow.log

Mysql5.1开始可以将慢查询的日志记录放入一张表中,这使得用户的查询更加方便和直观。通过参数log_output指定了慢查询输出的格式,默认为FILE,可将将它设置为TABLE,且此参数是动态的,并且是全局的。慢查询表再mysql架构下,名为slow_log。slow_log使用的是CSV引擎,对大数据量下的查询效率可能不高。用户可以把slow_log表的引擎转换为MyISAM,并且在start_time列上添加索引以进一步提高查询的效率。

需要注意的是,将slow_log表的存储引擎改为MyISAM之后,是会对数据库造成额外的开销。好在有关慢查询的参数都是动态的,我们可以随时调整。

我们知道Mysql的slow log通过运行时间来对SQL语句进行捕获,这是一个非常有用的优化技巧。但是有个情况需要注意,当数据库刚建立时,所有的数据可能都被缓存在缓冲池中,SQL语句运行的时间可能都是非常短的。所以InnoSQL(MySQL一个分支版本)版本加强了对SQL语句的捕获。在原版MySQL的基础上增加了对逻辑读取物理读取的统计。物理读取是指从磁盘进行IO读取的次数,逻辑读取包含所有的读取,不管是磁盘还是缓冲池。

需要说明的一点,Mysql默认情况下不启动慢日志查询

查询日志文件(log)

查询日志记录了所有对Mysql数据库请求的信息,无论这些请求是否得到了正确的执行。默认文件名:主机名.log。

同样地,从Mysql5.1开始,可以将查询日志的记录放入mysql架构下的general_log表中,该表使用和slow_log表基本一样,不再赘述。

二进制日志文件(binlog)

二进制日志记录了对Mysql数据库执行更改的所有操作,但是不包括select和show这类操作。然而,若操作本身并没有导致数据库发生变化,那么该操作可能也会写入二进制日志。二进制日志文件的文件格式为二进制,所以不能直接阅读,需要通过Mysql提供的工具mysqlbinlog来查看。对于STATEMENT格式的二进制文件,在使用mysqlbinlog后,看到的就是执行的逻辑SQL语句。但如果使用的是ROW格式的记录方式,会发现mysqlbinlog结果变得“不可读”了,看不到执行的sql语句,反而是一大串用户不可读的字符。其实只要加上参数-v或-vv就能清楚地看到执行的具体信息了。

如果用户想记录和查看select和show操作,那只能使用查询日志,而不是二进制日志。二进制日志还包括了执行数据库更改操作的时间等信息。总的来说,二进制日志有以下几种作用

  • 恢复:某些数据的恢复需要二进制日志。例如,在一个数据库全备文件恢复后,用户可以通过二进制日志进行point-in-time的恢复。
  • 复制:其原理和恢复类似,通过复制和执行二进制日志使一台远程的Mysql数据库与一台Mysql数据库(一般指master)进行实时同步。
  • 审计:用户可以通过二进制日志中的信息来进行审计,判断是否有对数据库进行注入的攻击。

除了二进制日志文件,二进制索引文件bin_log.index也是我们需要注意的,它用来存储过往产生的二进制日志序号。

二进制日志文件默认情况下并没有启动,需要手动指定参数(log_bin)启动。当然启动二进制日志文件确会影响性能,但是性能的损失十分有限,官方测试开始二进制日志性能会下降1%。但考虑到可以使用复制point-in-time的恢复,这些性能的损失绝对是可以接受的,所以建议生产环境要开启二进制日志。但是影响二进制日志记录的信息和行为的参数有很多:

  • log_bin
    通过配置参数log_bin[=name]可以启动二进制日志。如果不指定name,则默认二进制日志文件名为主机名,后缀名为二进制日志的序列号,所在路径为数据库所在目录(datadir)。
  • max_binlog_size
    指定了单个二进制日志文件的最大值,如果超过该值,则产生新的文件默认为1073741824,代表1G。
  • binlog_cache_size
    当使用事务型存储引擎时,所有未提交的二进制日志会被记录到一个缓存中去,等该事务提交时直接将缓冲中的二进制日志写入二进制日志文件,而该缓冲的大小有binlog_cache_size决定,默认大小为32K。此外,binlog_cache_size是基于会话的,也就是说,当一个线程开启一个事务时,Mysql会自动为此线程分配一个大小为binlog_cache_size的缓存,因此该值设置需要相当小心,不能设置的太大。当一个事务的记录大于设定的binlog_cache_size时,Mysql会把缓冲中的日志写入一个临时文件中,因此该值又不能设置的太小。
  • sync_binlog
    在默认情况下,二进制日志并不是在每次写的时候同步到磁盘(我们可以理解为缓冲写)。因此,当数据库所在操作系统宕机时,可能会有最后一部分数据没有写入二进制日志文件中,这会给恢复和复制带来问题。参数sync_binlog=[N]表示每写缓冲多少次就同步磁盘。如果N为1,表示采用同步写磁盘的方式来写二进制日志,这时写操作不使用操作系统的缓冲来写二进制日志。sync_binlog默认为0,如果使用InnoDB进行复制,并且想得到最大的高可用性,建议设置为1。不过该值为1时,确实会对数据库的IO系统带来一定影响。
    但是,即便将sync_binlog设为1,还是会有一种情况导致问题的发生。当使用InnoDB时,在一个事务发出commit之前,由于sync_binlog为1,因此会将二进制日志立即写入磁盘。如果已经写入了二进制日志,但是提交还没有发乎,此时发生了宕机,那么在Mysql数据库下次启动时,由于commit操作并没发生,这个事务会被回滚掉。但是二进制日志已经记录了该事务信息,不能被回滚。这个问题可以通过将参数innodb_support_xa设为1来解决,它能确保二进制日志和InnoDB存储引擎数据文件的同步。
  • binlog-do-db
  • binlog-ignore-db
  • log-slave-update
  • binlog-format:这个参数十分重要,指定了记录二进制日志的格式。在Mysql5.1版本之前没有这个参数,二进制文件的格式是基于SQL语句的。此时,对于复制是有一定要求的,如在主服务器运行rand、uuid等函数,又或是使用触发器等操作,这些都可能会导致主从服务器上表中数据不一致。另一个影响是,会发现InnoDB存储引擎的默认隔离级别是READ REPEATABLE。这其实也是因为二进制文件格式的关系,如果使用READ COMMINTED的事务隔离级别,会出现类似丢失更新的现象,从而出现出现主从数据库的数据不一致。
    该参数的取值有STATEMENT、ROW和MIXED:
    • STATEMENT:格式和Mysql5.1版本一样,二进制日志文件记录的是日志的逻辑sql语句。这是Mysql默认的设置
    • ROW:记录的不再是简单的sql语句了,而是记录表的行更改情况。这就解决了Statement格式下复制的问题。从Mysql5.1版本开始,如果设置了binlog-format为row,可以将InnoDB的事务隔离级别设为READ COMMINTED,以获得更好的并发性。通常情况下,我们将参数binlog-format设置为ROW,这可以为数据库的恢复和复制带来更好的可靠性。但是不可忽略的是,这会带来二进制大小大小的增加。例如对一张表所有数据执行Update操作,STATEMENT模式下只是一条sql语句,但是在ROW模式下可能就需要更大的容量了。而由于复制是采用传输二进制日志方式实现的,因此复制的网络开销也有所增加。
    • MIXED:在此格式下,Mysql默认采用STATEMENT格式进行二进制日志文件的记录,但有些情况会使用ROW格式。

注意,以上所有日志文件是Mysql数据库本身的文件,和存储引擎无关。

PID文件

当Mysql实例启动时,会将自己的进程ID写入一个文件中----该文件即为pid文件。
注意,此文件是Mysql数据库本身的文件,和存储引擎无关。

表结构定义文件

因为Mysql插件式存储引擎的体系结构的关系,Mysql数据的存储是根据表进行的,每个表都会有与之对应的文件。无论采用何种存储引擎,Mysql都有一个以.frm为后缀的文件,这个文件记录了表的表结构定义。
注意,此文件是Mysql数据库本身的文件,和存储引擎无关。

InnoDB存储引擎相关的文件

我们知道以上所说的文件都是Mysql数据库本身的文件,和存储引擎无关。下面所要将的就是和InnoDB存储引擎有关的重要文件:重做日志文件表空间文件

表空间文件

InnoDB采用将存储的数据按表空间进行存放的设计。默认为一个10MB的名为ibdata1的文件。该文件就是默认的表空间文件,可以通过参数innodb_data_file_path设置多个文件组成一个表空间(也称为共享表空间),例如:innodb_data_file_path=/db/ibdata1:2000M;/db/ibdata2:2000M,并且ibdata1和ibdata2文件可以分布在不同的磁盘上,这样可以提高数据库的整体性能。如果ibdata1和ibdata2的2000M用完了,该文件可以自动的增长。

我们还可以通过设置参数innodb_file_pre_table=ON为每个基于InnoDB存储引擎的表产生一个独立表空间。独立表空间的命名规则为:表名.ibd。通过这样的方式,用户不用将所有数据都存放于默认的表空间中。

需要注意的是,这些单独表空间文件仅存储该表的数据、索引和插入缓冲BITMAP等信息,其他类型数据,如undo信息、插入缓冲索引页、系统事务信息、二次写缓冲等还是存放在默认的表空间文件(也就是共享表空间文件)中。

重做日志文件

默认情况下,在InnoDB存储引擎的数据目录下会有两个名为ib_logfile0和ib_logfile1的文件。在Mysql官方手册中将其称为InnoDB存储引擎的日志文件,不过更准确的定义应该是重做日志文件(redo log file)。重做日志文件对于InnoDB存储引擎至关重要,它们记录了对于InnoDB的事务日志。

当实例或介质失败时,重做日志文件就能派上用场了。例如,数据库由于所在主机掉电导致实例失败,InnoDB存储引擎会使用重做日志恢复到掉电前的时刻,一次来保证数据的完整性。

每个InnoDB存储引擎至少有1个重做日志文件组,每个文件组至少有2个重做日志文件,默认为ib_logfile0和ib_logfile1。在日志组中每个重做日志文件的大小一致,并以循环写入的方式运行。Innodb先写重做日志文件1,当达到文件的最后时,会切换到重做日志文件2,再当重做日志2也被写满时,会再切换到重做日志文件1中。

参数innodb_log_file_size指定每个重做日志文件的大小。在1.2.x版本之前,重做日志文件总的大小不得大于等于4GB,而1.2.x版本将这个限制扩大为了512G。重做日志文件的大小对InnoDB的性能有着非常大的影响,设置得太大,在恢复时可能需要很长的时间;设置得太小,可能导致一个事务的日志需要多次切换重做日志文件。此外重做日志文件太小会导致频繁地发生async checkpoint,导致性能的抖动。这是因为重做日志有一个capacity变量,该值代表乐最后的检查点不能超过这个阈值,如果超过则必须将缓冲池(innodb buffer pool)中脏页列表中的部分脏数据页写回磁盘,这时会导致用户线程的阻塞。

为了得到更高的可靠性,用户可以设置多个的景象日志组,将不同的文件组放在不同的磁盘上,以此提高重做日志的高可用性。参数innodb_mirrored_log_groups指定了日志镜像文件组的数量,默认为1,表示只有一个日志文件组,没有镜像。若磁盘本身已经做了高可用的方案,如磁盘阵列,那么可以不开启重做日志镜像功能。

重做日志写入磁盘的过程

我们知道,写入重做日志文件的操作不是直接写,而是先写入一个重做日志缓冲(redo log buffer)中,然后按照一定的条件顺序的写入日志文件

从重做日志缓冲往磁盘写入时,是按512字节,也就是一个扇区的大小进行写入。因为扇区是写入的最小单位,因此可以保证写入必定是成功的。这样一来就不会出现部分写入的情况,因此在重做日志的写入过程中不需要doublewrites

另外,有个参数innodb_flush_log_at_trx_commit需要注意,它的有效值为0、1、2

  • 0:表示当提交事务时,不将事务的重做日志写入磁盘的日志文件,而是等待主线程每秒的刷新。
  • 1:表示在执行commit时将重做日志缓冲同步写到磁盘,即伴有fsync的调用。
  • 2:表示将重做日志异步写到磁盘,即写到文件系统的缓存中,因此不能完全保证在执行commit时肯定写入重做日志文件,只是有这个动作发生。

因此为了保证事务的持久性,必须将innodb_flush_log_at_trx_commit设置为1,也就是每当事务提交时,就必须确保事务都已经写入重做日志文件。那么当数据库因为意外发生宕机时,可以通过重做日志文件恢复,并保证可以恢复已经提交的事务。而将此参数设置为0或2,都有可能发生恢复时部分事务的丢失。不同之处在于,设置为2,时,当Mysql数据库发生宕机而操作系统没有宕机及服务器时,由于此时未写入磁盘的事务日志保存在文件系统缓存中,当恢复时同样能保证数据不丢失。

触发重做日志写入磁盘的条件:

  • 主线程每秒钟会将重做日志缓冲写入磁盘的重做日志文件,不论事务是否已经提交都会进行此操作
  • 另一个触发写磁盘的过程是参数innodb_flush_log_at_trx_commit控制,表示在事务提交时,处理重做日志的方式。

重做日志文件和二进制文件的区别

虽然两者同样是记录事务日志,但是两者还是有些却别:

  • 二进制日志文件记录所有与Mysql数据库数据更改有关的日志记录,包括各个存储引擎的日志。而Innodb存储引擎的重做日志只记录有关该存储引擎的事务日志。
  • 记录的内容不同,二进制日志记录的都是有关一个事务的具体操作内容,即该日志是逻辑日志,其记录的是对应的SQL语句。而InnoDB的重做日志是物理格式日志,其记录的是对于每个页的修改。
  • 写入时间不同,二进制日志仅在事务提交前进行提交,即只写磁盘一次,不论这时的事务多大。而在事务进行的过程中,却不断有重做日志条目(redo entry)被写入到重做日志文件中,这表现为日志并不是随事务提交的顺序进行写入的。
    在这里插入图片描述
    总而言之,二进制日志仅在事务提交时记录,并且对于每一个事务,仅包含对应事务的一个日志。而对于InnoDB存储引擎的重做日志,由于其记录的是物理操作日志,因此每个事务对应多个日志条目,并且事务的重做日志写入是并发的,并非在事务提交时写入,故其在文件中的记录的顺序并非是事务开始的顺序。
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-17 22:14:33  更:2022-03-17 22:15:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:16:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码