March 6, 2013

[MySQL 5.6] innodb_flush_method新值O_DIRECT_NO_FSYNC 及bug#68555

Facebook的Mark大神最近一直在测试5.6的性能,并且发现了不少问题. 看来Facebook是要跳过5.5,直接上5.6了。同为互联网行业,Facebook的许多需求和我们是类似的,online ddl, 热点数据更新问题等。。。 当然,我最关注的还是5.6存在的bug。 related blog: http://mysqlha.blogspot.com/2013/03/mysql-56-cached-update-only-workload.html http://mysqlha.blogspot.com/2013/03/mysql-56-no-odirectnofsync-for-you.html related bug: http://bugs.mysql.com/bug.php?id=45892 提到两个问题,一个是从5.6.7开始innodb_flush_method有一个新值:O_DIRECT_NO_FSYNC。他的含义也很简单。当文件被设置为O_DIRECT时,如果将其设置为O_DIRECT_NO_FSYNC时,就无需在写文件后,再做一次flush(实际上是随后的调用逻辑性能太差了,而不仅仅是fsync很慢的缘故)。 从函数fil_flush可以很清晰的看到,fil_buffering_disabled为true时,很快就释放全局锁fil_system->mutex,返回。根据mark的测试,其性能提升也非常理想: update-only & IO-bound workload updates/second for update 1 row by PK via sysbench     8      16      32      64     128     256   concurrent clients 18234   24359   10379    9795    9843   10283   O_DIRECT 17996   26853   30265   28923   29293   29477   O_DIRECT_NO_FSYNC   可惜的是,这种设置只对部分文件系统是安全的,一些文件系统,例如XFS,即使设置了O_DIRECT,还需要将Metadata信息fsync到磁盘。另外当free list为空时(脏页太快,Page cleaner跟不上),用户线程可能去从LRU获取一个空闲block,这会导致如下backtrace。 os_thread_sleep,fil_flush,fil_flush_file_spaces,buf_flush_sync_datafiles, buf_flush_single_page_from_LRU,buf_LRU_get_free_block, buf_page_init_for_read,buf_read_page_low,.. 这种场景发生在IO-BOUND负载下,即使在扫描lru也没有发现非脏block可以转移到free list后,会去尝试从lru尾部刷一个脏block(buf_flush_single_page_from_LRU),然后将其放到free list上,这其中如果包含了sync操作,显然会大大的影响用户线程的性能。 […]