您的位置:首页 > 数据库 > MySQL

mysql innodb学习(三)

2012-12-11 23:12 1786 查看

上一篇讲到了innodb的日志文件的设置和日志缓存的作用,这一篇接着说一下innodb如何将日志缓存中的信息刷新到日志文件。

  • innodb_flush_method

    这个参数主要设置的是innodb使用什么方式将缓存数据写到磁盘中的日志文件,这个选项的设置同时影响到日志文件和数据文件,选项设置主要包含以下几个:

1.fdatasync

这个选项是innodb在非windows系统上的默认选项,单从选项的名字上来看,innodb使用了fdatasync()函数,但是实际情况是innodb使用了fsync()来刷新日志文件和数据文件,这两个函数的区别在于fsync()函数不仅刷新了文件的数据,还刷新了文件的元数据信息(创建时间,最后访问时间,文件大小等等),而fdatasync()函数只刷新了文件的数据。因此光从这个方面来比较的话,fsync()函数应该需要更昂贵的代价,因为需要两次IO,而fdatasync函数只需要一次IO,但是实际的情况是innodb的开发者发现了fdatasync()函数在某些情况会发生崩溃,因此为了安全起见,innodb使用了fsync()函数来实现刷新数据。

fsync的另外一个缺点是操作系统的内核也缓存了数据,这就导致存了两份缓存,一个是innodb自己保存的缓存数据,还有一个就是内核保存的缓存数据。如果设置了参数innodb_file_per_table,那么就会导致innodb单独的使用fsync函数来刷新不同的表文件,不能在刷新多个表文件的时候将多个IO合并成一个IO,这就导致了innodb会调用更多的fsync来刷新数据。

2.O_DIRECT

innodb在不同的系统上了使用了不同的实现方式,在solaris系统上了,innodb使用了directio()函数来实现,而在其他的系统上大都是使用O_DIRECT标志来实现。这个设置本质上也使用了fsync函数实现,但是区别是这个选项通知操作系统部使用缓存来保存数据,而是直接将文件写到磁盘上,从而避免了fdatasync选项导致的双重缓存问题。

3.ALL_O_DIRECT

这个选项只有在Percona Server(http://www.percona.com/software/percona-server)和MariaDB(http://mariadb.org/)中有效,它可以让服务器采用标准mysql访问数据文件的方式来访问日志文件。

4.O_DSYNC

这个选项设置了在调用open函数时的O_SYNC参数,使得所有的写操作都使用同步写的方式,即写操作只有在将文件写到了磁盘中才返回,这个选项不影响数据文件的写。这个选项和O_DIRECT的区别在于这个选项不会禁用操作系统的缓存,因此也就无法避免双重缓存,不能直接将文件写到磁盘中,而只能先写到操作系统的缓存,然后再写到磁盘中。 这个选项的设置看起来和fsync差不多(都使用同步写,都不能避免双重缓存),但是这两个选项的实现却很不相同,当设置了O_DSYNC选项,操作系统会传递一个“use synchronous I/O”标记到硬件层,告诉磁盘设备不使用缓存,而fsync则告诉操作系统将修改过的缓存刷新到磁盘设备,紧跟着一个指令,让磁盘设备刷新它的缓存。 跟fdatasync一样(O_SYNC同步文件的数据和元数据信息,O_DSYNC只同步了文件的数据信息),这个选项的名字也有点迷惑,innodb其实使用了O_SYNC标志,而不是O_DSYNC,同样的,innodb的开发者也发现了O_DSYNC存在不稳定的BUG。

5.async_unbuffered

这个选项是windows系统的默认选项,它使得innodb对大部分的写操作使用不缓存的I/O,除非是在innodb_flush_log_at_trx_commit的值为2的时候才使用缓存的I/O。这个选项使用了操作系统的native异步I/O来操作读和写。

6.unbuffered

这个选项基本上和async_unbuffer一致,唯一的区别在于它不使用操作系统的native异步I/O实现,而是使用unbuffered I/O。(只适用于windows系统)

7.normal

只适用于windows系统,这个选项设置了innodb既不使用async_unbuffered I/O,也不使用unbuffered I/O.

8.nosync and littlesync

只用于开发使用,不适用于实际使用。

这里只介绍了这个配置参数的几个常用的选项,更具体的还要深入研究操作系统内核的一些内容。

(adsbygoogle = window.adsbygoogle || []).push({});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mysql innodb