[20170221]数据文件与文件系统缓存.txt
--昨天探究磁盘之间拷贝文件时很慢,发现一个小工具nocache,发现这个可以用来探究数据文件与文件系统缓存的问题,自己测试看看.
1.环境以及构造测试数据:
--//首先说明我的测试数据库在安装在内存盘中,使用cachesats看数据库安装与否都是缓存的.
$ cachestats book/system01.dbf
book/system01.dbf pages in cache: 194562/194562 (100.0%) [filesize=778248.0K, pagesize=4K]
--//通过cp,再ln命令建立链接测试磁盘的情况.
$ cp -ar /mnt/ramdisk/book /u01/backup/2017021
$ cd /mnt/ramdisk
$ mv book book_ram
$ ln -s /u01/backup/2017021 book
$ ls -l
total 0
lrwxrwxrwx 1 oracle oinstall 19 2017-02-21 10:44:30 book -> /u01/backup/2017021
$ cachedel book/system01.dbf
$ cachestats book/system01.dbf
book/system01.dbf pages in cache: 0/194562 (0.0%) [filesize=778248.0K, pagesize=4K]
--//OK.
--//BTW: 我修改nocache的源代码,加入前面显示文件名的功能,很简单不再贴出.
--//启动数据库略
SYS@book> show parameter filesystem
NAME TYPE VALUE
-------------------- ------ ------
filesystemio_options string none
--//官方文档:(注中文部分我加的)
http://docs.oracle.com/cd/E11882_01/server.112/e41573/os.htm#PFGRF94410
9.1.1.2 FILESYSTEMIO_OPTIONS Initialization Parameter
You can use the FILESYSTEMIO_OPTIONS initialization parameter to enable or disable asynchronous I/O or direct I/O on
file system files. This parameter is platform-specific and has a default value that is best for a particular platform.
FILESYTEMIO_OPTIONS can be set to one of the following values:
ASYNCH: enable asynchronous I/O on file system files, which has no timing requirement for transmission.
在文件系统文件上启用异步I/O,在数据传送上没有计时要求。
DIRECTIO: enable direct I/O on file system files, which bypasses the buffer cache.
在文件系统文件上启用直接I/O,绕过buffer cache。
SETALL: enable both asynchronous and direct I/O on file system files.
在文件系统文件上启用异步和直接I/O。
NONE: disable both asynchronous and direct I/O on file system files.
在文件系统文件上禁用异步和直接I/O。
==========================
SCOTT@book> create table t as select rownum id from dual connect by level<=2;
Table created.
SCOTT@book> ALTER TABLE t MINIMIZE RECORDS_PER_BLOCK ;
Table altered.
--//这样可以实现每块2条记录.
SCOTT@book> insert into t select rownum+2 from dual connect by level <=64000-2;
63998 rows created.
SCOTT@book> commit ;
Commit complete.
insert into t select * from t;
insert into t select * from t;
insert into t select * from t;
commit ;
--//分析略.
SCOTT@book> select OWNER,SEGMENT_NAME,SEGMENT_TYPE,HEADER_FILE,HEADER_BLOCK,BYTES,BLOCKS from dba_segments where owner=user and segment_name='T';
OWNER SEGMENT_NAME SEGMENT_TYPE HEADER_FILE HEADER_BLOCK BYTES BLOCKS
------ -------------------- ------------------ ----------- ------------ ---------- ----------
SCOTT T TABLE 4 546 2154823680 263040
--//占用2154823680/1024/1024=2055M,263040块
2.测试:(FILESYTEMIO_OPTIONS=NONE)
--//FILESYTEMIO_OPTIONS=NONE
$ cachestats /mnt/ramdisk/book/users01.dbf
/mnt/ramdisk/book/users01.dbf pages in cache: 546436/547522 (99.8%) [filesize=2190088.0K, pagesize=4K]
SCOTT@book> set timing on
SCOTT@book> alter session set statistics_level=all;
Session altered.
select count(*) from t;
Plan hash value: 2966233522
----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | Reads |
----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 71094 (100)| | 1 |00:00:00.64 | 256K| 256K|
| 1 | SORT AGGREGATE | | 1 | 1 | | | 1 |00:00:00.64 | 256K| 256K|
| 2 | TABLE ACCESS FULL| T | 1 | 512K| 71094 (1)| 00:14:14 | 512K|00:00:00.61 | 256K| 256K|
----------------------------------------------------------------------------------------------------------------------
//实际上每次测试256K读.而且执行计划采用直接路径读,这样数据读取绕过了数据库缓存.
$ cat /tmp/nocache.txt
host cachedel /mnt/ramdisk/book/users01.dbf
select count(*) from t;
--//测试每次清除文件系统缓存的情况.
SCOTT@book> @ /tmp/nocache.txt
COUNT(*)
----------
512000
Elapsed: 00:00:03.72
--//执行多次,可以发现在没有缓存的情况下,执行需要3.7X秒.下面测试缓存的情况:
$ cachestats /mnt/ramdisk/book/users01.dbf
/mnt/ramdisk/book/users01.dbf pages in cache: 552970/554242 (99.8%) [filesize=2216968.0K, pagesize=4K]
--//取消执行cachedel的情况
$ cat /tmp/cache.txt
--host cachedel /mnt/ramdisk/book/users01.dbf
select count(*) from t;
SCOTT@book> @ /tmp/cache.txt
COUNT(*)
----------
512000
Elapsed: 00:00:00.61
--//执行多次,可以发现在文件系统缓存的情况下,执行需要0.61秒. 我的磁盘很快,从这里还是可以看出文件系统缓存对数据文件大量读
--//取的影响.
3.测试:(FILESYTEMIO_OPTIONS=DIRECTIO).
SCOTT@book> alter system set filesystemio_options=DIRECTIO scope=spfile;
System altered.
--//重启数据库略.
$ find /mnt/ramdisk/book/*.* -exec cachedel {} \;
$ find /mnt/ramdisk/book/*.* -exec cachestats {} \; */
/mnt/ramdisk/book/control01.ctl pages in cache: 0/2612 (0.0%) [filesize=10448.0K, pagesize=4K]
/mnt/ramdisk/book/control02.ctl pages in cache: 0/2612 (0.0%) [filesize=10448.0K, pagesize=4K]
/mnt/ramdisk/book/example01.dbf pages in cache: 0/88642 (0.0%) [filesize=354568.0K, pagesize=4K]
/mnt/ramdisk/book/redo01.log pages in cache: 0/12801 (0.0%) [filesize=51200.5K, pagesize=4K]
/mnt/ramdisk/book/redo02.log pages in cache: 0/12801 (0.0%) [filesize=51200.5K, pagesize=4K]
/mnt/ramdisk/book/redo03.log pages in cache: 0/12801 (0.0%) [filesize=51200.5K, pagesize=4K]
/mnt/ramdisk/book/redostb01.log pages in cache: 0/12801 (0.0%) [filesize=51200.5K, pagesize=4K]
/mnt/ramdisk/book/redostb02.log pages in cache: 0/12801 (0.0%) [filesize=51200.5K, pagesize=4K]
/mnt/ramdisk/book/redostb03.log pages in cache: 0/12801 (0.0%) [filesize=51200.5K, pagesize=4K]
/mnt/ramdisk/book/redostb04.log pages in cache: 0/12801 (0.0%) [filesize=51200.5K, pagesize=4K]
/mnt/ramdisk/book/sysaux01.dbf pages in cache: 0/240642 (0.0%) [filesize=962568.0K, pagesize=4K]
/mnt/ramdisk/book/system01.dbf pages in cache: 2/194562 (0.0%) [filesize=778248.0K, pagesize=4K]
/mnt/ramdisk/book/tea01.dbf pages in cache: 0/10242 (0.0%) [filesize=40968.0K, pagesize=4K]
/mnt/ramdisk/book/temp01.dbf pages in cache: 0/105986 (0.0%) [filesize=423944.0K, pagesize=4K]
/mnt/ramdisk/book/undotbs01.dbf pages in cache: 0/221442 (0.0%) [filesize=885768.0K, pagesize=4K]
/mnt/ramdisk/book/users01.dbf pages in cache: 8/554242 (0.0%) [filesize=2216968.0K, pagesize=4K]
--//首先清除文件系统缓存.
SCOTT@book> @ /tmp/nocache.txt
COUNT(*)
----------
512000
Elapsed: 00:00:04.17
--//执行多次,可以发现在没有缓存的情况下,执行需要4.1X秒.而且每次执行完成,使用cachestats看:
$ cachestats /mnt/ramdisk/book/users01.dbf
/mnt/ramdisk/book/users01.dbf pages in cache: 8/554242 (0.0%) [filesize=2216968.0K, pagesize=4K]
--//这也是DIRECTIO的含义: enable direct I/O on file system files, which bypasses the buffer cache.
SCOTT@book> @ /tmp/cache.txt
COUNT(*)
----------
512000
Elapsed: 00:00:04.08
--//在文件系统没有缓存的情况下,FILESYTEMIO_OPTIONS=DIRECTIO的情况下数据块的访问采用直接读取数据文件的方式.
--//如果FILESYTEMIO_OPTIONS=DIRECTIO情况数据文件缓存呢?
$ dd if=/mnt/ramdisk/book/users01.dbf of=/dev/zero bs=1024M ;
2+1 records in
2+1 records out
2270175232 bytes (2.3 GB) copied, 3.81141 seconds, 596 MB/s
$ cachestats /mnt/ramdisk/book/users01.dbf
/mnt/ramdisk/book/users01.dbf pages in cache: 554242/554242 (100.0%) [filesize=2216968.0K, pagesize=4K]
SCOTT@book> @ /tmp/cache.txt
COUNT(*)
----------
512000
Elapsed: 00:00:04.15
$ cachestats /mnt/ramdisk/book/users01.dbf
/mnt/ramdisk/book/users01.dbf pages in cache: 554242/554242 (100.0%) [filesize=2216968.0K, pagesize=4K]
--//执行多次,你可以发现并不会因为文件系统缓存而缩短执行时间.
--//换一种方式讲如果你采用这样方式FILESYTEMIO_OPTIONS=DIRECTIO,可以适当设置大一点sga*参数.
4.测试:(FILESYTEMIO_OPTIONS=ASYNCH).
--//ASYNCH: enable asynchronous I/O on file system files, which has no timing requirement for transmission.
SCOTT@book> alter system set filesystemio_options=ASYNCH scope=spfile;
System altered.
--//重启数据库略.
$ find /mnt/ramdisk/book/*.* -exec cachedel {} \;
$ find /mnt/ramdisk/book/*.* -exec cachestats {} \; */
$ find /mnt/ramdisk/book/users01.dbf -exec cachestats {} \;
/mnt/ramdisk/book/users01.dbf pages in cache: 8/554242 (0.0%) [filesize=2216968.0K, pagesize=4K]
alter session set statistics_level=all;
set timing on
SCOTT@book> @ /tmp/nocache.txt
COUNT(*)
----------
512000
Elapsed: 00:00:03.52
$ find /mnt/ramdisk/book/users01.dbf -exec cachestats {} \;
/mnt/ramdisk/book/users01.dbf pages in cache: 553150/554242 (99.8%) [filesize=2216968.0K, pagesize=4K]
--//可以发现执行后文件系统会缓存数据文件.
SCOTT@book> @ /tmp/cache.txt
COUNT(*)
----------
512000
Elapsed: 00:00:00.67
--//再次执行缓存的影响.
5.测试:(FILESYTEMIO_OPTIONS=SETALL).
--//SETALL: enable both asynchronous and direct I/O on file system files.
SCOTT@book> alter system set filesystemio_options=SETALL scope=spfile;
System altered.
--//重启数据库略.
$ find /mnt/ramdisk/book/*.* -exec cachedel {} \;
$ find /mnt/ramdisk/book/*.* -exec cachestats {} \; */
find /mnt/ramdisk/book/users01.dbf -exec cachestats {} \;
/mnt/ramdisk/book/users01.dbf pages in cache: 0/554242 (0.0%) [filesize=2216968.0K, pagesize=4K]
SCOTT@book> @ /tmp/nocache.txt
COUNT(*)
----------
512000
Elapsed: 00:00:03.73
SCOTT@book> @ /tmp/cache.txt
COUNT(*)
----------
512000
Elapsed: 00:00:03.73
$ find /mnt/ramdisk/book/users01.dbf -exec cachestats {} \;
/mnt/ramdisk/book/users01.dbf pages in cache: 0/554242 (0.0%) [filesize=2216968.0K, pagesize=4K]
--//可以发现执行后文件系统不会缓存数据文件.
--//如果FILESYTEMIO_OPTIONS=SETALL情况数据文件缓存呢?
$ dd if=/mnt/ramdisk/book/users01.dbf of=/dev/zero bs=1024M ;
2+1 records in
2+1 records out
2270175232 bytes (2.3 GB) copied, 3.96247 seconds, 573 MB/s
$ find /mnt/ramdisk/book/users01.dbf -exec cachestats {} \;
/mnt/ramdisk/book/users01.dbf pages in cache: 554242/554242 (100.0%) [filesize=2216968.0K, pagesize=4K]
SCOTT@book> @ /tmp/cache.txt
COUNT(*)
----------
512000
Elapsed: 00:00:03.76
--//执行多次,你可以发现并不会因为文件系统缓存而缩短执行时间.
--//换一种方式讲如果你采用这样方式FILESYTEMIO_OPTIONS=SETALL,可以适当设置大一点sga*参数.
6.画一个表格并总结:
----------------------------------------------------
FILESYTEMIO_OPTIONS nocache(秒) cache(秒)
----------------------------------------------------
NONE 3.62 0.61
DIRECTIO 4.17 4.08
ASYNCH 3.52 0.67
SETALL 3.73 3.73
----------------------------------------------------
--//说明: 这里的nocache与cache并不是指数据或者文件系统是否缓存,而是指执行前是否清除OS的文件系统缓存.
--//这表格看FILESYTEMIO_OPTIONS设置NONE,ASYNCH都不错,nocache的情况下相差很小.对于大量读盘操作都能从文件缓存中获得好的性
--//能.但是以消耗OS内存为代价.
--//DIRECTIO相对较差.
--//SETALL居中.但是DIRECTIO,SETALL都不会建立文件系统缓存,如果采用这种模式,可以适当设置大一点SGA参数.
--//通过这个测试,很容易联想到ASM,asm无法利用文件系统缓存,虽然采用异步IO,我感觉估计性能更接近FILESYTEMIO_OPTIONS=SETALL选
--//项.也不要把ASM吹上天,实际上小数据系统使用文件系统还是有优势的,另外注意的问题就是文件系统缓存,它可能掩盖IO存在的问题,
--//这点要特别注意.
--//推荐的设置FILESYTEMIO_OPTIONS=ASYNCH,实际上不设置问题也不大,从NONE与ASYNC在nocache的情况下差别很小.大约块5%.
--//如果你磁盘IO很快的情况可以设置,FILESYTEMIO_OPTIONS=SETALL,而且因为这时不使用文件系统缓存,可以适当设置大的sga.
FILESYTEMIO_OPTIONS can be set to one of the following values:
ASYNCH: enable asynchronous I/O on file system files, which has no timing requirement for transmission.
在文件系统文件上启用异步I/O,在数据传送上没有计时要求。
DIRECTIO: enable direct I/O on file system files, which bypasses the buffer cache.
在文件系统文件上启用直接I/O,绕过buffer cache。
SETALL: enable both asynchronous and direct I/O on file system files.
在文件系统文件上启用异步和直接I/O。
NONE: disable both asynchronous and direct I/O on file system files.
在文件系统文件上禁用异步和直接I/O。
--补充一点:我以前遇到FILESYTEMIO_OPTIONS=SETALL,如果恢复的rman的文件放在cifs恢复出问题.
--另外像我前面的使用内存ram盘做测试,也不能设置为DIRECTIO,SETALL(很久以前测试的,当时没记录)