MySQL-基础3-MySQL文件与InnoDB存储引擎文件

目录

1. MySQL参数文件

2. 日志文件

2.1 错误日志

2.2 慢查询日志

2.3 查询日志

2.4 二进制日志

2.5 扩展:MySQL事务隔离级别

2.6 扩展:幻读

3. 套接字文件

4. pid文件

5. 表结构定义文件

6. InnoDB存储引擎文件

6.1 表空间文件

6.2 重做日志文件


 


 

1. MySQL参数文件

默认情况下,MySQL实例会按照一定顺序在指定的位置来读取,可以通过mysql --help|grep my.cnf来查找。

可以通过命令show variables来查看数据库配置的所有参数,也可以使用like来过滤参数名,从MySQL5.1开始,还可以通过information_schema架构下的global_variables视图来进行查找

MySQL数据库中参数可以分为2类:动态参数、静态参数。这里的动态参数指的是在MySQL实例运行时可以修改,而静态参数则在MySQL实例整个生命周期内不可以修改。(动态参数可以用set命令修改)

注意:对动态参数值修改,仅仅在这次MySQL实例生命周期内有效,但对应的参数文件中值并不会进行修改,通俗来讲,MySQL重启后,你修改的动态参数都没了,因此,要想永久生效还得去修改配置文件。

2. 日志文件

MySQL数据库中常见的日志文件有:错误日志、二进制日志、慢查询日志、查询日志。

2.1 错误日志

错误日志文件对MySQL的启动、运行、关闭过程进行记录。该文件不仅记录所有错误信息,同时也记录警告信息、正确信息等,可以通过show variables like log_error来查看文件位置

2.2 慢查询日志

慢查询日志slow log可以帮助开发者定位存在问题的SQL语句,从而进行SQL语句层面的优化。参数long_query_time来设置一个阈值,超过该阈值的SQL全部记录下来,该参数默认值为10,即代表10秒。默认情况下不启动慢查询日志,需要手动把log_slow_queries设置为on

注意事项:

①设置long_query_time参数后,只记录运行时间大于该参数的SQL语句,不记录正好等于该参数的SQL语句。

从MySQL5.1开始,该参数单位为微妙,而不是秒,如果参数值为10,则代表10微妙。

如果把log_queries_not_using_indexes设置为on,则如果运行的SQL语句没有使用索引,则同样被记录到慢查询日志文件中。

从MySQL5.6.5版本开始新增log_throttle_queries_not_using_indexes参数,用来表示每分钟允许记录到慢查询日志的、且未使用索引的SQL语句的数量,该参数默认值为0,表示没有限制。

鉴于数据库服务器运行越久,slow log文件会越来越大,为了方便分析,MySQL提供了mysqldumpslow命令来解析slow log文件

从MySQL5.1版本开始,会把慢查询日志放到mysql架构下slow_log表中,方便用户更加直观分析。

InnoDB引擎除了以SQL运行时间为标准来捕获,还以逻辑读取和物理读取为标准,其中的物理读取指的是从磁盘进行IO读取的次数,而逻辑读取则是所有的读取数,包括磁盘与内存缓冲池。

针对逻辑读取,通过long_query_io参数把超过该参数的逻辑IO次数的SQL语句记录到慢查询日志中,该参数默认值为100。

参数slow_query_type则是为了兼容MySQL数据库的运行方式来针对slow log的记录方式:

0表示不将SQL语句记录到slow log;

1表示仅仅根据运行时间将SQL语句记录到slow log;

2表示仅仅根据逻辑IO次数将SQL语句记录到slow log;

3表示根据运行时间、逻辑IO次数将SQL语句记录到slow log;

2.3 查询日志

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

从MySQL5.1版本开始,也会把查询日志放到mysql架构下general_log表中,方便用户更加直观查看。

2.4 二进制日志

二进制日志binary log则是记录了对MySQL数据库执行更改的所有操作,但不包括select和show这类操作,因为这类操作对数据本身并没有修改,至于其他操作,即便没有修改数据也会被记录到binary log中。

二进制文件一般用于下面几个用处:

①恢复:特定数据的恢复需要二进制日志文件;

②复制:原理与恢复类似,就是通过复制和恢复执行二进制日志,使一台远程MySQL数据库与一台MySQL数据库进行实时同步;

③审计:通过二进制日志判断是否有对数据库进行SQL注入的攻击;

通过log-bin[=name]来启动二进制日志,如果不指定name则默认二进制日志文件名就是主机名,后缀名则是二进制日志的序列号,文件存放路径则是数据库所在目录datadir,例如:

xxx.index则为二进制 的索引文件,用来存储过往产生的二进制日志序号,通常情况下,不建议手工修改这个文件;

xxx.000001文件则是二进制日志文件,后面的则是序号,序号依次往后排;

默认情况下不启动二进制日志文件,需要手动来开启,因为这个选项会影响数据库性能,只不过影响有限,官方说是开启后会使性能下降1%。

二进制日志文件的内容与行为还与下面参数有关:

①max_binlog_size:配置单个二进制日志文件的最大值,如果超过该参数值,则创建新的二进制日志文件,文件后缀名+1,并记录到.index文件中,MySQL5.0开始默认值为1G。

②binlog_cache_size:当MySQL使用具有事务功能的存储引擎时,所有未提交的二进制日志会记录到一个内存缓冲池中,等事务提交后再把日志从内存缓冲池写入磁盘上的二进制日志文件中,这个内存缓冲池大小则由该参数配置,默认32K。

注意:该参数是基于会话session的,即一个线程开始一个事务时,该事务就会被分配一个binlog_cache_size大小的内存,因此,该参数不能设置过大,否则会挤占内存。另外,当一个事务的记录大于binlog_cache_size时,MySQL只能把缓冲池中的日志写入磁盘上一个临时文件,因此,也不能太小,太小容易频繁读写磁盘。

可以通过show global status来查看binlog_cache_use和binlog_cache_disk_use的状态,来判断参数大小是否合适。

③sync_binlog:默认情况下,当数据库发生改变的时候,并不会立刻把日志写入到二进制日志,因此,当数据库宕机时,会有一部分数据没写入二进制日志,这就带来数据丢失问题,而参数sync_binlog=[N]则表示每隔写操作多少次后就同步写入磁盘上的二进制日志。该参谋默认值为0,但如果N=1,即代表数据库发生变动时立刻写入磁盘,毕竟N=1就代表写1次吗。

这里注意下写入时间,在使用InnoDB存储引擎时,事务在commit之前,由于sync_binlog=1,现在就会把修改写入到磁盘上的二进制日志中,如果此刻宕机,则会导致二进制日志内容与数据库真实内容不匹配的问题,此时需要innodb_support_xa=1来解决该问题。

④binlog-do-db:需要写入哪些数据库的日志,默认为空,表示所有数据库的日志都要写入二进制日志中。

⑤binlog-ignore-db:需要忽略哪些数据库的日志,默认为空,表示所有数据库的日志都要写入二进制日志中。

⑥log-slave-update:如果当前数据库是主从复制中的slave,那么其不会把从master获取并执行的二进制日志写入到自己数据库的二进制日志文件中,如果需要写入的话,则需要该参数,该参数用于主从复制的场景。

⑦binlog_format:设置二进制日志内容格式。MySQL5.1版本之前,二进制日志里面格式都是基于SQL语句级别的(通俗理解就是里面是SQL语句),但这种方式的缺点有2个:

缺点1:虽然这种方式整体看起来不错,感觉就是复制文件到另外数据库,然后恢复即可,但这里存在一个问题:如果主数据库里二进制日志里面调用了自定义的函数、触发器、存储过程的话,这就要求从数据库也必须有对应的函数、触发器、存储过程,否则会造成主从数据库数据的不一致。

缺点2:由于二进制日志格式的问题,InnoDB存储引擎默认事务隔离级别是repeatable_read,如果想使用read_committed级别则会出现更新语句丢失现象,进而造成主从数据库数据不一致。

而到了MySQL5.1开始引入了binlog_format参数,该参数取值如下:

①statement:与之前的MySQL版本一样,二进制日志文件记录的是日志的逻辑SQL语句。

②row:记录表的行更改情况,同时解决了statement格式下的复制问题,且binlog_format=row还允许InnoDB把事务隔离界别设为read committed来获取更好的并发性能。

③mixed:默认采用statement格式进行二进制日志文件记录,但在一些情况下则使用row格式,例如:使用了uuid/user/row_count等不确定函数、使用insert delay语句、使用用户自定义函数、使用临时表等场景。

注意:

①binlog_format的取值与具体存储引擎有关,有的引擎不支持row,有的引擎不支持statement;

②binlog_format是动态参数,允许运行环境下进行修改;

③row是针对每一行的修改进行记录,所以,当采用row格式时,二进制日志文件大小会急剧增加,对于网络传输、磁盘存储都会造成压力;

④二级制日志文件,只能通过mysqlbinlog工具来查看,因为文件是以二进制形式存储,MySQL只不过先按照statement/row方式来编写内容,然后再把内容以二进制方式写入到日志文件中,因此,需要mysqlbinlog工具来查看;

⑤当采用statement格式时,用mysqlbinlog即可;当采用row格式时,用mysqlbinlog -vv才行,然后你会发现,row里记录的信息量比statement多了很多很多;

2.5 扩展:MySQL事务隔离级别

①未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据

②提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)

③可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读

④串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞

2.6 扩展:幻读

如果一个事务先根据某些条件查询出一些记录,之后另一个事务又向表中插入了符合这些条件的记录,原先的事务再次按照该条件查询时,能把另一个事务插入的记录也读出来,这就是幻读;

3. 套接字文件

UNIX系统下连接本地MySQL则采用UNIX域套接字方式,该方式需要一个套接字文件,该文件一般叫做/tmp/mysql.sock,该文件可以通过参数socket来配置;

4. pid文件

当MySQL实例启动时,会把对应的进程ID写入一个叫做pid文件的中,该文件通过参数pid_file控制,默认在数据库目录下,名字叫做:主机名.pid;

5. 表结构定义文件

因为MySQL插件式存储引擎体系,其存储是以表为单位进行存储的,每个表都有对应的文件,虽然不同引擎的表有不同格式的文件,但都有一个.frm为后缀名的文件,该文件记录该表的表结构信息。该frm文件还用来存放视图定义,同时frm文件是一个文本文件,可以用文本工具/命令进行查看。

6. InnoDB存储引擎文件

既然这本书是来介绍InnoDB引擎的,那么就说一下该引擎对应的文件信息。

6.1 表空间文件

InnoDB采用将存储的数据按照表空间进行存储的设计。默认配置下有一个大小为10MB的ibdata1文件,该文件就是默认的表空间文件,可以通过参数innodb_data_file_path来人工配置,例如:

innodb_data_file_path=/db/ibdata1:2000M;/dr2/db/ibdata2:2000M:autoextend

这里说明下:

①可以通过多个文件共同组成一个表空间,每个文件之间以”;”(分号)作为分隔符;

②文件名后面可以跟文件属性,例如:2000MB,指的是表空间文件大小是2000MB,ibdata2如果用完2000MB则可以自动增长;

通过innodb_data_file_path参数,可以把所有使用InnoDB存储引擎的表的数据,都存储到这个共享表空间中,如果想每个表都有独立的表空间,则可以使用参数innodb_file_per_table=ON,这样每个基于InnoDB存储引擎的表都会产生一个独立的表空间,该独立表空间命名规则为:表名.ibd;

注意:独立表空间文件仅仅存储了该表的数据、索引、插入缓冲bitmap等信息,其他信息还是放到默认的共享表空间中;

6.2 重做日志文件

默认情况下,InnoDB存储引擎的数据目录下会有ib_logfile0、ib_logfile1的文件,这2个文件就是重做日志文件redo log file,里面记录了对于InnoDB存储引擎的事务日志;

当数据库实例或者介质失败时,重做日志文件就能派上用场,比如:掉电导致实例失败,那么就可以用重做日志恢复到掉电前的时刻来保证数据完整性。

(掉电是描述用电设备因断电、失电、或电的质量达不到要求而不能正常工作的术语)

每个InnoDB存储引擎至少有1个重做日志文件组,每个文件组内至少有2个重做日志文件,为了更高的可靠性,可以设置多个镜像日志组,把不同文件组放到不同的磁盘上;

在日志文件组中每个重做日志文件的大小是一样的,以循环写入的方式来运行,InnoDB会先写入ib_logfile0,当文件写满时,再写入ib_logfile1,当文件写满时,再去写入ib_logfile0,依次轮退;

对重做日志文件有影响的参数有下列几个:

①innodb_log_file_size:指定每个重做日志文件的大小,InnoDB1.2.x之前,所有重做日志总大小不得超过4GB,1.2.x版本之后扩大为总大小不得超过512GB;

②innodb_log_files_in_group:指定日志文件组中重做日志文件的数量,默认值为2;

③innodb_mirrored_log_groups:指定日志镜像文件组的数量,默认值为1,表示只有一个日志文件组,没有镜像;

④innodb_log_group_home_dir:指定日志文件组所在路径,默认为./,表示在MySQL数据库的数据目录下;

重做日志文件不能设置太大,也不能设置太小,太大则导致恢复时间很长,太小则容易让一个事务来多个文件之间来回切换,然后频繁发生async checkpoint问题;

重做日志与二进制日志区别有哪些?

①使用者不同:二进制日志记录所有与MySQL数据库有关的日志记录,也包括各种存储引擎的日志,是MySQL自己的日志;而重做日志仅仅记录InnoDB引擎有关的事务日志,是该引擎自己所独有的;

②内容不同:二进制日志记录的是关于一个事务的具体操作内容,即该日志就是逻辑机制;而重做日志文件记录的是关于每个数据页的更改的物理情况;(相当于二进制日志通用性比较高,里面是二进制的SQL语句,所有引擎都会识别SQL语句,而重做日志记录了InnoDB引擎内部数据页的变化,通用性低)

③写入时间不同:二进制日志仅在事务提交前进行提交,只写磁盘1次,而在事务进行的过程中,不断有重做日志条目被写入到重做日志文件中,读写N次;

④写入方式不同:二进制日志写入就是写入,没太多的特殊情况,而重做日志则不一样:不同操作对应着不同的重做日志格式,每次写入时先写入内存中的重做日志缓冲,然后再按照一定的条件,每次按照512个字节顺序写入日志文件,整个过程不需要double write;另外除了InnoDB引擎会在3种情况下将重做日志缓冲中的内容写入磁盘上的重做日志文件外,还受到参数innodb_flush_log_at_trx_commit影响,噶参数表示在提交commit操作时,该怎么处理重做日志,该参数取值如下:

①0:当提交事务时,不会将事务的重做日志写入到磁盘上的重做日志文件,而是等待主线程每秒的刷新;

②1:在执行commit时,将重做日志缓冲同步写入磁盘的文件上,有fsync调用;

③2:在执行commit时,将重做日志缓冲同步写入磁盘文件系统的缓存中,只保证写这个动作,不保证会把信息写入到重做日志文件中;

因此为了保证事务的ACID持久性,必须将innodb_flush_log_at_trx_commit设为1,来保证当事务提交commit时,对应日志必须写入到重做日志文件中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值