InnoDB -- InnoDB-文件
[toc]
文件
参数文件
这个可以直接视作配置文件,mysql通过这些参数来确定各类型文件的位置,以及设置一些内存分配和策略
1 | <!--通过这个命令可以看到具体的配置加载顺序--> |
什么是参数
键值对
参数类型
分为动态和静态,就是有些参数可以在数据库启动后修改仍然生效,有的必须预先设置才会生效
动态修改的时候分为global和session,字面意思
日志文件
错误日志
记录了启动、运行和关闭过程中的异常,遇到问题时查看这个日志可以进行问题定位
慢查询日志
1 | <!--查看是否开启慢查询--> |
- 所谓慢查询是运行时间超过某个阈值的sql,默认是10s
- 另一个是如果一个sql运行没有使用索引,也会被写入慢查询,通过
log_queries_not_using_indexes进行配置,还有一个参数可以对这个类型的sql每分钟能写入慢查询日志的数量进行限制 - 通过mysqldumpslow 接慢查询日志文件,统计出执行时间最长的10条sql
- 还可以将慢查询记录放到表中,可以更方便直观抖进行分析,这个表叫slow_log,这个表使用的是CSV引擎,大数据量的查询效率不高,可以改为MyISAM,但是会消耗更多的性能
查询日志
会记录所有的请求信息,包括一些权限验证失败的请求
二进制日志
binary log也就是平时说的binlog,这个会记录所有对数据进行了修改的操作,select和show这类的查询操作不会进行记录,但如果是一个更新语句,即使这个语句没有真正的造成数据的改动也同样会被记录
- 主要作用:
- 恢复,这块举例说了在数据库全备份文件恢复后,进行point-in-time的恢复(这个和redis的混合备份比较像了)
- 复制,从库可以复制和执行binlog来进行数据同步(==所以要进行读写分离,是否只有一台机器负责写入,那么如果只有一台机器复制写的话,这个瓶颈如何处理==)
- 审计:==判断是否有注入攻击,这个不明白==
- 默认是不会启动的,官方说启动这个日志会使得性能下降1%,但从收益来看是完全可以接受的
- max_binlog_size:配置文件大小,默认1G,超过后会创建新的文件
- binlog_catch_size:使用事务时,会将未提交的事务binlog日志写入到缓存中,这个参数控制单个事务分配的缓存空间大小,如果事务的binlog大于了该配置会将binlog写入到一个临时文件中,所以可以看到如果配置过大浪费空间,配置过小性能降低
1
2
3
4
5
6
7
8
9<!--查看binlog配置大小-->
show variables like 'binlog_cache_size'
输出:binlog_cache_size 1048576
<!--查看使用情况-->
show global status like 'binlog_cache%'
结果:磁盘使用次数很少,配置没问题
Binlog_cache_disk_use 34
Binlog_cache_use 404051762 - sync_binlog:binlog写磁盘流程有事务缓存操作的,这个配置默认为0即不开启同步,带来的问题就是缓存中的数据会丢失;开启同步后的问题是事务还没有被提交就被写入日志了,这时候发生了宕机,启动的时候由于事务没有提交会被回滚,但是二进制文件中记录了该事务的信息不能回滚,可以通过设置
innodb_support_xa为1来解决,同时这个配置会确保binlog和InnoDB存储引擎数据文件的同步 - binlog-do-db:决定哪些binlog需要写入,binlog-ignore-db:哪些binlog不需要写入,这俩默认都为空即使说所有binlog都写入
- log-slave-update:如果是slave库,那就不需要将master复制过来执行的binlog再进行记录了
- binlog_format:影响日志文件的格式,在5.1之前没有这个参数,binlog的格式都是基于SQL语句(statement)级别;导致的问题是主从同步时rand、uuid等函数或者触发器可能会导致数据不一致;且默认的隔离级别repeatable read也是由于这个格式关系,如果使用read committed会出现类似丢失更新的现象,5.1之后格式可配置
- statement:SQL语句
- row:记录表的行更改情况,解决了statement的问题,这个时候可以将隔离级别设置为read committed来获得更好的并发性;坏处是日志文件的体积会有增加,网络传输的消耗增加;原因是假如用一个SQL修改10w行数据,statement只需要记录SQL即可(200b),但是row需要将这10w行修改都记录下来(13M)差距非常非常大
- mixed:就是上述两个混用,默认使用statement,再statement可能会出现问题的情况下会使用row,这里不一一列举
套接字文件
==Unix系统通过套接字进行数据库连接的时候会创建一个.sock文件==
pid文件
MySQL服务启动的时候会把服务的PID写入这个文件
表结构定义文件
由于MySQL是插件式存储引擎的体系结构关系,真正表中的数据存储是交给存储引擎来进行决策的,但是表结构定义的记录都是以frm为后缀的文件进行存储的
InnoDB存储引擎文件
上面介绍的文件都是MySQL自己规范中的文件,下面介绍InnoDB存储引擎自己特有的文件
表空间文件

InnoDB表数据分为三部分,表结构定义文件是由MySQL进行管理的,表中的数据可以存储在共享表空间中也可以单独进行存储(也可以指定几个表的数据存储在一起),一般都会分开进行存储,需要做数据清理的时候比较快捷
重做日志文件
redo log,这个之前已经介绍过基础的运行原理了,为了保证数据的可靠性,每个InnoDB至少有一个重做日志组,每个组下至少有两个重做日志文件,用户还可以设置多个镜像日志文件组放到不同的磁盘上来提高可靠性
1 | innodb_log_file_size //每个重做日志文件的大小 |
- 每个组内,默认是两个日志文件,进行循环写入,一个满了写到第二个文件,第二个满了再次写到第一个文件(单个文件最大限制为512G)
- 关于重做日志的大小,不能设置太大,那样数据恢复的时间会很长,也不能太小,可能导致一个事务的日志需要多次切换日志文件,且会导致频繁进行async CheckPoint导致性能抖动
- redo log和binlog的区别
- binlog会记录所有与MySQL有关的日志文件(修改相关),它是MySQL的日志机制之一,而redo log是InnoDB的只存储引擎本身的事务文件
- 内容上binlog记录的是逻辑操作(statement、row和mixed都是)记录的是事务的具体操作(开发者写的SQL语句,人能看懂),而redo log记录的是数据页的更改的物理情况(人看不懂)
- 写入时间不同,binlog只在事务提交前进行提交(事务执行中使用了缓存,binlog相当于只记录执行成功的SQL语句),redo log是在事务进行中就不断的进行记录了(事务过程中页的数据不断的被修改)
- 重做日志的流程是从缓存中写入到磁盘,这个过程每次写入512字节,也就是一个扇区的大小,由于扇区已经是写入的最小单位所以不会出现写到一半失败而导致数据损坏的问题,不需要doublewirte
- 重做日志缓存刷新到磁盘的情况,第一是master进程每秒执行一次,第二是事务提交的时候,通过
innodb_flush_log_at_trx_commit进行配置,取值有0、1、2- 0表示不在事务提交时进行刷新,完全进行这个工作交给master
- 1表示将缓冲同步刷新到磁盘,这个时候持久性可以得到保障(不能再去考虑缓冲刷新的过程中宕机,这种原子粒度的丢失无法避免)
- 2表示异步的进行刷新,也就是通知操作系统去做,这个时候如果服务器宕机,那这些数据就丢失了,如果只是MySQL挂了,那文件系统缓存还在可以正常恢复
- redo log采用的是WAL(Write-ahead logging,预写式日志),所有修改先写入日志,再更新到Buffer Pool,保证了数据不会因MySQL宕机而丢失,从而满足了持久性要求
