<div>I traced MySQL:</div><div><br></div><div><div>[pid 13478] open("./test/big_tb.ibd", O_RDONLY) = 37</div><div>[pid 13478] pread(37, "W\346\203@\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\v\37c\225\263\0\10\0\0\0\0\0\0"..., 16384, 0) = 16384</div><div>[pid 13478] close(37)                   = 0</div><div>[pid 13478] open("./test/big_tb.ibd", O_RDWR) = 37</div><div>[pid 13478] fcntl(37, F_SETFL, O_RDONLY|O_DIRECT) = 0</div><div>[pid 13478] fcntl(37, F_SETLK, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}) = 0</div><div>[pid 13478] pread(37, "\350\301\270\271\0\0\0\3\377\377\377\377\377\377\377\377\0\0\0\v\37c\225\263E\277\0\0\0\0\0\0"..., 16384, 49152) = 16384</div><div>[pid 13478] pread(37, "e\251|m\0\0\0\1\0\0\0\0\0\0\0\0\0\0\0\0\0\31\245\243\0\5\0\0\0\0\0\0"..., 16384, 16384) = 16384<span id="_editor_bookmark_start_0" style="display: none; line-height: 0px;">‍</span></div></div><div><div><br></div><div>As we can see, MySQL will open data file twice when open table. And the first open file without O_DIRECT flag will generate page cache. I traced kernel:</div><div><br></div><div><div>Tracing "sys_pread64"... Ctrl-C to end.</div><div>  3)               |  sys_pread64() {</div><div>  3)   0.362 us    |    fget_light();</div><div>  3)               |    vfs_read() {</div><div>  3)               |      rw_verify_area() {</div><div>  3)               |        security_file_permission() {</div><div>  3)   0.251 us    |          cap_file_permission();</div><div>  3)   0.817 us    |        }</div><div>  3)   1.377 us    |      }</div><div>  3)               |      do_sync_read() {</div><div>  3)               |        xfs_file_aio_read() {</div><div>  3)   0.259 us    |          generic_segment_checks();</div><div>  3)               |          xfs_rw_ilock() {</div><div>  3)               |            xfs_ilock() {</div><div>  3)               |              down_read() {</div><div>  3)   0.233 us    |                _cond_resched();</div><div>  3)   0.713 us    |              }</div><div>  3)   1.433 us    |            }</div><div>  3)   2.097 us    |          }</div><div>  3)               |          generic_file_aio_read() {</div><div>  3)   0.229 us    |            generic_segment_checks();</div><div>  3)   0.227 us    |            _cond_resched();</div><div>  3)   0.261 us    |            find_get_page();</div><div>  3)               |            page_cache_sync_readahead() {</div><div>  3)               |              ondemand_readahead() {</div></div><div><span id="_editor_bookmark_start_1" style="display: none; line-height: 0px;">‍</span>...</div><div><br></div><div>I run MySQL 5.5.24 on CentOS6.5, with kernel 2.6.32-431.</div><div>Later I will use the newer kernel to test it.<span id="_editor_bookmark_start_2" style="display: none; line-height: 0px;">‍</span></div><div><br></div><div>Thanks,</div><div>Ye</div><div><br></div><div style="font-size: 12px;font-family: Arial Narrow;padding:2px 0 2px 0;">------------------ 原始邮件 ------------------</div><div style="font-size: 12px;background:#efefef;padding:8px;"><div><b>发件人:</b> "Dave Chinner";<david@fromorbit.com>;</div><div><b>发送时间:</b> 2015年4月9日(星期四) 凌晨5:14</div><div><b>收件人:</b> "YeYin"<eyniy@qq.com>; <wbr></div><div><b>抄送:</b> "xfs"<xfs@oss.sgi.com>; <wbr></div><div><b>主题:</b> Re:  回复: XFS direct IO problem</div></div><div><br></div>On Wed, Apr 08, 2015 at 03:05:57PM +0800, YeYin wrote:<br>> Dave,<br>> Thank you for your explanation. I got the reason, and I write some code to  simulate the MySQL.It will reproduce the progress:‍<br>> <br>> <br>> open file without direct flag<br>> read file   //cause kernel readahead 4 pages, and inode->i_mapping->nrpages > 0<br>> close file<br>> <br>> <br>> open file with direct flag<br>> lseek 4*4096 // skip 4 readahead pages<br>> read  file //cause xfs_flushinval_pages to do nothing<br>> ...<br>> <br><br>Yes, you can cause it that way, but any application mixing buffered<br>IO and direct IO like that is broken.  I'll point you at the open(2)<br>man page, in the section about O_DIRECT:<br><br>      "Applications should avoid mixing O_DIRECT and normal I/O to<br>     the same file, and especially to overlapping byte regions in<br>  the  same file.   Even  when  the filesystem correctly<br>       handles the coherency issues in this situation, overall I/O<br>   throughput is likely to be slower than using either mode<br>      alone.  Likewise, applications should avoid mixing mmap(2)<br>       of files with direct I/O to the same files."<br><br>IOWs, your test program is behaving as documented for a program<br>that mixes buffered and direct IO....<br><br>AFAIK, MySQL does not do  mixed buffer/direct IO like this and so<br>this is extremely unlikely to be the source of the problem.  I need<br>to understand how MySQL is generating cached pages on it's database<br>files when it is supposed to be using direct IO, and the reproducer<br>program needs to do what MySQL does to generate cached pages.<br><br>Can you please find the location of the cached pages (as I<br>sugggested via tracing in my last email) in the MySQL files that are<br>causing the problem?<br><br>> I'd like to ask XFS how to resovle this problem?<br><br>Applications that need to mix buffered and direct IO can invalidate<br>the cached pages by using POSIX_FADV_DONTNEED before doing direct<br>IO.<br><br>FWIW, You must be looking at quite old kernel code if<br>xfs_flushinval_pages() exists in your kernel. Does MySQL on a<br>current upstream kernel have the same problem?<br><br>Cheers,<br><br>Dave.<br>-- <br>Dave Chinner<br>david@fromorbit.com<br></div>