本文出自: http://weipengfei.blog.51cto.com/1511707/985968 
innodb_flush_log_at_trx_commit 决定了事务日志何时write,flush
    innodb_flush_method确定了日志及数据文件如何write、flush。“show   variables”显示该变量为空,那说明被设置了默认值(fdatasync)

    下面我们先从Linux IO上理解一下文件是如何打开、写入、刷写到磁盘上的。
    一般的文件I/O操作的三个过程open、write、fdatasync,分别是打开文件、写文件、flush操作(将文件缓存刷到磁盘上)

    open 阶段:

    系统调用Open(),使用 O_WRONLY| O_APPEND|O_SYNC 打开文件:
    O_WRONLY表示我们以“写”的方式打开文件。
    O_APPDENT以追加的方式写文件。
    O_DSYNC 当向文件写入数据的时候,只有当数据写到了磁盘时,写入操作才会完成(write 才会返回成功),
与之相对应的是:
    O_SYNC: 这个比O_DSYNC 更严格,把数据写入到文件时,还要把数据的一些元信息写入到磁盘比如文件长度等。
    O_RSYNC 表示文件读取时,该文件的缓存必须已经flush到磁盘上。
    O_DIRECT打开文件,则读/写操作都会跳过OS cache,直接在device(disk)上读/写。(这样会降低文件的顺序读写的效率)
    write阶段: 依赖与open阶段。
    flush阶段:将数据刷写到磁盘上。
    Fdatasync() 来确保数据文件flush到了磁盘上。
    与之相对应的是:
    fsync() fdatasync()两者区别等同于 O_sync 和 O_Dsync
    sync()函数,将文件写入os cache 就认为写入成功(所以这个很不可靠,但性能确实提高啦)
      对于linux平台的 innodb_flush_method() 设置为 Fdatasync 默认,O_sync, O_Direct
    对于fdatasync:
    Innodb 使用fsync()函数来刷写数据和日志。fysnc()相比fdatasync()函数需要更多的IO(元数据信息),fdatasync()在某些情况下造成Innodb崩溃。
    使用fsync()的缺点是 os会缓存部分数据。因为Innodb 能够比os更能智能的管理自己的缓存区(Innodb buffer pool)。这样会造成双缓冲的浪费。(双缓冲部分的优点:有些文件系统会累计写入并执行他们,可能很有效率的排序,或者并行的写入到设备中。可以做预读取),具体情况可以具体测试一番。如果启用Innodb_file_per_table时导致每个文件都被单独使用fsync()函数,,当写入到多个表的时候不能合并到单个IO操作中。https://blog.51cto.com/user_index.php
对于O_DIRECT:
    数据文件使用该标记,这个选项不会影响日志文件,对linux、freeBSD、Solaris 支持。,这个时候os不会缓存数据,完全禁止了os缓存并且使所有的读写动作直接到存储设备(避免了双缓冲),使用fsync()把文件刷写到磁盘上(该设置不能禁止RAID卡上的提前读取功能,只是禁止os的提前读取功能),对于RAID卡的缓存还是建议打开的。对于Innodb_file_per_table影响不大(热身时间会加长,满足buffer pool)
    对于O_DSYNC:
这个对日志文件调用open()使用了O_SYNC标志,所有的写入是同步的,数据只有写入磁盘才算有效。它不会影响数据文件。
    它不会禁止os 的缓存.
具体关系:
 
             openlog     flush log     opendata file     flush datafile
Fdatasync                  fsync()                                    fsync()
O_DSYNC       O_SYNC                                          fsync()
O_DIRECT                   fsync()         O_DIRECT           fsync()