mysql-innoDB的参数优化(一)

 

Innodb 维护了一个缓存数据和索引信息到内存的存储区叫做Buffer Pool(缓冲池),缓冲池并不仅仅缓存索引:它还会缓存行的数据,自适应哈希索引,插入缓冲(Insert buffer),锁,以及其他的内部数据结构。InnoDB还使用缓冲池来帮助延迟写入,这样就能合并多个写入操作,然后一起顺序的协会。它会将最近访问的数据缓存到缓冲区.基于LRU算法来实现。

 

1   innodb_buffer_pool_size

 

基本上,innodb_buffer_pool_size指定了MySQL应该分配给InnoDB缓冲池多少内存,InnoDB缓冲池用来存储缓存的数据,二级索引,脏数据(已经被更改但没有刷新到硬盘的数据)以及各种内部结构如自适应哈希索引。

根据经验,在一个独立的MySQL服务器应该分配给MySQL整个机器总内存的80%。设置的过大,会导致system的swap空间被占用,导致操作系统变慢,从而减低sql查询的效率

 

理想情况下,在给服务器的其他进程留下足够的内存空间的情况下,Buffer Pool Size应该设置的尽可能大。当Buffer Pool .Size设置的足够大时,整个数据库就相当于存储在内存当中,当读取一次数据到Buffer Pool Size以后,后续的读操作就不用再访问磁盘。

 

查看方法:

show global variables like 'innodb_buffer_pool_size';

 

修改方法:

修改my.cnf

 

innodb_buffer_pool_size = 2G

 

 

下面这俩值只有在mysql5.7.5 以后才有:

 

 

innodb_buffer_pool_chunk_size   Inno  DB Buffer Pool的执行单元 chunk size的大小.

buffer pool会根据这个参数值的整数倍增加或减小

 

innodb_buffer_pool_instances 设置InnoDB Buffer Pool实例的个数,每一个实例都有自己独立的list管理Buffer Pool;

image.png

 

 

 

三者的关系大概如上图。

 

2 innodb_additional_mem_pool_size

 

这个参数用来设置 InnoDB 存储的数据目录信息和其它内部数据结构的内存池大小。应用程序里的表越多,你需要在这里分配越多的内存。对于一个相对稳定的应用,这个参数的大小也是相对稳定的,也没有必要预留非常大的值。如果 InnoDB 用光了这个池内的内存, InnoDB 开始从操作系统分配内存,并且往 MySQL 错误日志写警告信息。默认值是 1MB ,当发现错误日志中已经有相关的警告信息时,就应该适当的增加该参数的大小

 

innodb_log_file_size

 

这个参数用来设置innodb的日志大小。要修改日志的文件大小,需要完全关闭mysql。

 

1 小日志文件使写入速度更慢,崩溃恢复速度更快。

 

由于事务日志相当于一个写缓冲,而小日志文件会很快的被写满,这时候就需要频繁地刷新到硬盘,速度就慢了。如果产生大量的写操作,MySQL可能就不能足够快地刷新数据,那么写性能将会降低。

 

2 大日志文件使写入更快,崩溃恢复速度更慢。

 

大的日志文件,另一方面,在刷新操作发生之前给你足够的空间来使用。反过来允许InnoDB填充更多的页面。

对于崩溃恢复 – 大的重做日志意味着在服务器启动前更多的数据需要读取,更多的更改需要重做,这就是为什么崩溃恢复慢了

 

 

4 innodb_log_files_in_group

 

日志组中日志文件个数 默认值是2    [ib_logfile0,ib_logfile1]

 

官方文档建议

Log sequence number和 Last checkpoint 之间的距离最好不要超过innodb_log_files_in_group*innodb_log_file_size的0.75, innodb_log_files_in_group的default值为2. 一般太小的logfile size的表现情况就是checkpoint比较频繁,导致刷新dirty page到磁盘的次数增加,在刷新时会使整个系统变得很慢.所以这种情况要尽量避免.

 

 

---

LOG

---

Log sequence number 2574010

Log flushed up to   2574010

Pages flushed up to 2574010

Last checkpoint at  2574001

0 pending log flushes, 0 pending chkp writes

100 log i/o's done, 0.00 log i/o's/second

 

5  innodb_flush_logs_at_trx_commit

 

这个参数老厉害了。innodb必须掌握的一个参数。

了解这个参数之前,必须先知道,当innodb变更任何数据时,会写一条变更记录到内存日志缓冲区。

在缓冲满的时候,事务提交的时候,或者每一秒钟,InnoDB 都会刷写缓冲区的内容到磁盘日志文件---- 无论三个套件哪个先达到。innodb_log_buffer_size 可以控制日志缓冲区的大小。

Innodb怎么样刷新日志缓冲呢?当Innodb把日志缓冲刷新到磁盘日志文件时,先会使用一些个Mutex锁住缓冲区,刷新到所需要的位置,然后移动剩下的条目到缓冲区的前面。当Mutex释放时,可能有超过一个事务已经准备刷新其日志记录。

 

日志缓冲必须被刷新到持久化存储,以确保提交的事务完全被持久化了。如果和持久相比更在性能,那么这个innodb_flush_logs_at_trx_commit变量来控制日志缓冲刷新的频繁程度。 可能设置的参数有三个:

0 把日志缓冲写到日志文件,并且每秒钟刷新一次,但是事务提交时不做任何事(没有io操作)。

1 (默认值)将日志缓冲写到日志文件,并且每次事务提交都刷新到持久化存储。这是默认的并且是最安全的设置,该设置能保证不会丢失任何已经提交的事务,除非磁盘或者操作系统是“伪”刷新。

 

2 每次提交时把日志缓冲写到日志文件,但是并不刷新。InnoDB 每秒钟做一次刷新。

0与2最重要的不同是(也是为什么2是最合适的设置),如果MySQL进程挂了,2不会丢失任何事务。如果整个服务器挂了或者断电了,则还是可能户丢失一些事务。因为可能有一秒的数据存在于操作系统的缓存里。

 

 

把日志缓冲写到日志文件:只是简单的把数据从INNODB的内存缓冲转移到了操作系统的缓存,也是在内存里,并没有把真的数据写到了持久化存储。

 

把日志刷新到持久化存储 意味着Innodb 请求操作系统把数据输出缓存,并且确认写到磁盘了,这是一个阻塞I/O的调用,知道数据被完全协会才会完成,因为数据到磁盘比较慢,当这个参数被设为1时,可能明显的降低Innodb每秒可以提交的事务数。

 

高性能事务处理需要的最佳配置是把innodb_flush_log_at_trx_commit 的设置为1,且把日志文件放到一个有电池保护的写花奴才能的RAID卷中,这样就兼顾了安全和速度。

 

6  innodb_flush_method

文件的写操作包括三步:open,write,flush

 

使用innodb_flush_method 选项可以配置Innodb如何跟文件系统相互作用。

 

fdatasync: 默认的方式。Innodb用fsync() 来刷新数据和日志文件。

Innodb通常用fsync()代替fdatasync(),fsync()缺点是导致更多的io,系统至少会在自己的缓存中缓冲一些数据。

fdatasync 只刷新文件的数据,而不包括元数据(最后的修改时间,等等)

 

O_DIRECT: 依然采用fsync()来刷新文件到磁盘,但是会通知操作系统不要缓存数据,也不要用预读,这个选项完全关闭了操作系统缓存,并且使所有的读和写都直接通过存储设备,避免了双重缓存。

 

O_DSYNC 这个选项使文件调用open() 函数时设置O_SYNC标记,只有数据写完磁盘后写操作才返回,这个选项不影响数据文件。0_SYNC 没有禁用操作系统层的缓存。同时同步数据和元数据。

 

 

详解:

mysql的innodb_flush_method这个参数控制着innodb数据文件及redo log的打开、刷写模式,对于这个参数,文档上是这样描述的:
有三个值:fdatasync(默认),O_DSYNC,O_DIRECT
默认是fdatasync,调用fsync()去刷数据文件与redo log的buffer
为O_DSYNC时,innodb会使用O_SYNC方式打开和刷写redo log,使用fsync()刷写数据文件
为O_DIRECT时,innodb使用O_DIRECT打开数据文件,使用fsync()刷写数据文件跟redo log

首先文件的写操作包括三步:open,write,flush
上面最常提到的fsync(int fd)函数,该函数作用是flush时将与fd文件描述符所指文件有关的buffer刷写到磁盘,并且flush完元数据信息(比如修改日期、创建日期等)才算flush成功。
使用O_DSYNC方式打开redo文件表示当write日志时,数据都write到磁盘,并且元数据也需要更新,才返回成功。
O_DIRECT则表示我们的write操作是从MySQL innodb buffer里直接向磁盘上写。

这三种模式写数据方式具体如下:

fdatasync模式:写数据时,write这一步并不需要真正写到磁盘才算完成(可能写入到操作系统buffer中就会返回完成),真正完成是flush操作,buffer交给操作系统去flush,并且文件的元数据信息也都需要更新到磁盘。
O_DSYNC模式:写日志操作是在write这步完成,而数据文件的写入是在flush这步通过fsync完成
O_DIRECT模式:数据文件的写入操作是直接从mysql innodb buffer到磁盘的,并不用通过操作系统的缓冲,而真正的完成也是在flush这步,日志还是要经过OS缓冲

详解链接:https://blog.csdn.net/smooth00/article/details/72725941

 

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注