exp导出工具的几个常用参数想必大家都很熟悉;有时为了加速导出作业我们会加上direct=y,进一步的可能就会设置RECORDLENGTH参数了,Oracle官方对这个参数的定义是:length of IO record;这个解释过于简单了,偶有余暇来探究一下RECORDLENGTH的工作原理:
[maclean@rh2 test]$ exp help=y Export: Release 10.2.0.4.0 - Production on Mon Nov 8 17:26:34 2010 Copyright (c) 1982, 2007, Oracle. All rights reserved. You can let Export prompt you for parameters by entering the EXP command followed by your username/password: Example: EXP SCOTT/TIGER Or, you can control how Export runs by entering the EXP command followed by various arguments. To specify parameters, you use keywords: Format: EXP KEYWORD=value or KEYWORD=(value1,value2,...,valueN) Example: EXP SCOTT/TIGER GRANTS=Y TABLES=(EMP,DEPT,MGR) or TABLES=(T1:P1,T1:P2), if T1 is partitioned table USERID must be the first parameter on the command line. Keyword Description (Default) Keyword Description (Default) -------------------------------------------------------------------------- USERID username/password FULL export entire file (N) BUFFER size of data buffer OWNER list of owner usernames FILE output files (EXPDAT.DMP) TABLES list of table names COMPRESS import into one extent (Y) RECORDLENGTH length of IO record GRANTS export grants (Y) INCTYPE incremental export type INDEXES export indexes (Y) RECORD track incr. export (Y) DIRECT direct path (N) TRIGGERS export triggers (Y) LOG log file of screen output STATISTICS analyze objects (ESTIMATE) ROWS export data rows (Y) PARFILE parameter filename CONSISTENT cross-table consistency(N) CONSTRAINTS export constraints (Y) OBJECT_CONSISTENT transaction set to read only during object export (N) FEEDBACK display progress every x rows (0) FILESIZE maximum size of each dump file FLASHBACK_SCN SCN used to set session snapshot back to FLASHBACK_TIME time used to get the SCN closest to the specified time QUERY select clause used to export a subset of a table RESUMABLE suspend when a space related error is encountered(N) RESUMABLE_NAME text string used to identify resumable statement RESUMABLE_TIMEOUT wait time for RESUMABLE TTS_FULL_CHECK perform full or partial dependency check for TTS VOLSIZE number of bytes to write to each tape volume TABLESPACES list of tablespaces to export TRANSPORT_TABLESPACE export transportable tablespace metadata (N) TEMPLATE template name which invokes iAS mode export Export terminated successfully without warnings. /* 针对使用direct=y直接路径,未使用recordlength的作业进行strace系统调用追踪 */ [maclean@rh2 test]$ strace -o exp1.trace exp maclean/maclean file=tv.dmp tables=tv direct=y Export: Release 10.2.0.4.0 - Production on Mon Nov 8 17:27:23 2010 Copyright (c) 1982, 2007, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options Export done in US7ASCII character set and UTF8 NCHAR character set server uses ZHS16GBK character set (possible charset conversion) About to export specified tables via Direct Path ... . . exporting table TV 6602624 rows exported Export terminated successfully without warnings. [maclean@rh2 test]$ ps -ef|grep exp maclean 12265 12198 55 17:27 pts/2 00:00:02 strace -o exp1.trace exp maclean/maclean file=tv.dmp tables=tv direct=y maclean 12266 12265 24 17:27 pts/2 00:00:01 exp file=tv.dmp tables=tv direct=y maclean 12269 12233 0 17:27 pts/3 00:00:00 grep exp [maclean@rh2 test]$ pmap -x 12266 12266: exp file=tv.dmp tables=tv direct=y Address Kbytes RSS Dirty Mode Mapping 0000000000400000 608 280 0 r-x-- exp 0000000000698000 16 16 8 rwx-- exp 000000000069c000 40 40 40 rwx-- [ anon ] 000000000f330000 876 656 656 rwx-- [ anon ] 00000039f1800000 112 100 0 r-x-- ld-2.5.so 00000039f1a1b000 4 4 4 r-x-- ld-2.5.so 00000039f1a1c000 4 4 4 rwx-- ld-2.5.so 00000039f1c00000 1336 452 0 r-x-- libc-2.5.so 00000039f1d4e000 2044 0 0 ----- libc-2.5.so 00000039f1f4d000 16 16 8 r-x-- libc-2.5.so 00000039f1f51000 4 4 4 rwx-- libc-2.5.so 00000039f1f52000 20 20 20 rwx-- [ anon ] 00000039f2000000 520 20 0 r-x-- libm-2.5.so 00000039f2082000 2044 0 0 ----- libm-2.5.so 00000039f2281000 4 4 4 r-x-- libm-2.5.so 00000039f2282000 4 4 4 rwx-- libm-2.5.so 00000039f2400000 8 8 0 r-x-- libdl-2.5.so 00000039f2402000 2048 0 0 ----- libdl-2.5.so 00000039f2602000 4 4 4 r-x-- libdl-2.5.so 00000039f2603000 4 4 4 rwx-- libdl-2.5.so 00000039f2800000 88 60 0 r-x-- libpthread-2.5.so 00000039f2816000 2044 0 0 ----- libpthread-2.5.so 00000039f2a15000 4 4 4 r-x-- libpthread-2.5.so 00000039f2a16000 4 4 4 rwx-- libpthread-2.5.so 00000039f2a17000 16 4 4 rwx-- [ anon ] 00000039f5c00000 84 24 0 r-x-- libnsl-2.5.so 00000039f5c15000 2044 0 0 ----- libnsl-2.5.so 00000039f5e14000 4 4 4 r-x-- libnsl-2.5.so 00000039f5e15000 4 4 4 rwx-- libnsl-2.5.so 00000039f5e16000 8 0 0 rwx-- [ anon ] 00002b6ebde28000 8 8 8 rwx-- [ anon ] 00002b6ebde2a000 18632 5024 4 r-x-- libclntsh.so.10.1 00002b6ebf05c000 2044 0 0 ----- libclntsh.so.10.1 00002b6ebf25b000 656 656 640 rwx-- libclntsh.so.10.1 00002b6ebf2ff000 112 32 32 rwx-- [ anon ] 00002b6ebf31b000 3004 1280 416 r-x-- libnnz10.so 00002b6ebf60a000 1020 0 0 ----- libnnz10.so 00002b6ebf709000 708 256 256 rwx-- libnnz10.so 00002b6ebf7ba000 4 4 4 rwx-- [ anon ] 00002b6ebf7d8000 432 164 164 rwx-- [ anon ] 00002b6ebf844000 400 8 0 r-x-- timezlrg.dat 00002b6ebf8c5000 40 28 0 r-x-- libnss_files-2.5.so 00002b6ebf8cf000 2044 0 0 ----- libnss_files-2.5.so 00002b6ebface000 4 4 4 r-x-- libnss_files-2.5.so 00002b6ebfacf000 4 4 4 rwx-- libnss_files-2.5.so 00002b6ebfad0000 4 4 4 rwx-- [ anon ] 00007ffff2cb3000 84 64 64 rwx-- [ stack ] ffffffffff600000 8192 0 0 ----- [ anon ] ---------------- ------ ------ ------ total kB 51408 9276 2380 [maclean@rh2 test]$ cd /proc/12266/fd [maclean@rh2 fd]$ ls -l 总计 0 lrwx------ 1 maclean oinstall 64 11-08 17:27 0 -> /dev/pts/2 lrwx------ 1 maclean oinstall 64 11-08 17:27 1 -> /dev/pts/2 lrwx------ 1 maclean oinstall 64 11-08 17:27 2 -> /dev/pts/2 lr-x------ 1 maclean oinstall 64 11-08 17:27 3 -> /s01/10gdb/rdbms/mesg/expus.msb lr-x------ 1 maclean oinstall 64 11-08 17:27 4 -> /s01/10gdb/oracore/mesg/lrmus.msb lr-x------ 1 maclean oinstall 64 11-08 17:27 5 -> /s01/10gdb/rdbms/mesg/ocius.msb lrwx------ 1 maclean oinstall 64 11-08 17:27 6 -> socket:[56016] l-wx------ 1 maclean oinstall 64 11-08 17:27 7 -> /home/maclean/test/tv.dmp l-wx------ 1 maclean oinstall 64 11-08 17:27 8 -> pipe:[56017] lr-x------ 1 maclean oinstall 64 11-08 17:27 9 -> pipe:[56018] /* 同时分析该exp进程的地址空间及打开文件描述符,可以看到这里的fd=>7指向了导出文件tv.dmp */ 节选trace部分内容: read(9, "\7\333\0\0\6\0\0\0\0\0\10\0 \0\0009:57\5\0VALID\1\0N\1\0N"..., 2064) = 2064 read(9, "2008-03-12:00:39:58\5\0VALID\1\0N\1\0N"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0LID\1\0N\1\0N\1\0N\3\0SYS\v\0I_S"..., 2064) = 2064 read(9, "\376\377\3\0\302\5$\3\0\302\5$\5\0INDEX\7\0xl\3\f\1(<\7\0xl"..., 1958) = 1958 read(9, "\0\327\0\0\6\0\0\0\0\00059\5\0VALID\1\0N\1\0N\1\0N\5\0OU"..., 2064) = 215 write(7, "9:57\5\0VALID\1\0N\1\0N\1\0N\3\0SYS\t\0ATEMP"..., 4096) = 4096 write(7, "\0N\1\0N\3\0SYS\v\0I_SUMDEP$_2\376\377\3\0\302\5\17\3\0"..., 4096) = 4096 write(8, "\0r\0\0\6\0\0\0\0\0\3[\235@\177\202\277n+\0\0\0 \0\0\0\0\0\0\200a\314"..., 114) = 114 read(9, "\7\333\0\0\6\0\0\0\0\0\10\0 \0\0ALID\1\0N\1\0N\1\0N\5\0OU"..., 2064) = 2064 read(9, "\0N\1\0N\1\0N\3\0SYS\t\0MON_MODS$\376\377\3\0\302\5T\3"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\1)\1\7\0xl\3\f\1)\1\23\0002008-03-"..., 2064) = 2064 read(9, "ABLE\7\0xl\3\f\1)\26\7\0xl\3\f\1)\26\23\0002008-03-"..., 1958) = 1958 read(9, "\0\327\0\0\6\0\0\0\0\0\302\0061\3\0\302\0061\5\0INDEX\7\0xl\3\f\1"..., 2064) = 215 write(7, "ALID\1\0N\1\0N\1\0N\5\0OUTLN\17\0OL$NODE_OL"..., 4096) = 4096 write(7, ")\1\7\0xl\3\f\1)\1\23\0002008-03-12:00:40:00"..., 4096) = 4096 write(8, "\0r\0\0\6\0\0\0\0\0\3[\236@\177\202\277n+\0\0\0 \0\0\0\0\0\0\200a\314"..., 114) = 114 /* 文件描述符为9的是一个管道文件,不难猜测其数据来源于TV表所在数据文件; fd为8的因该是system call的输出管道,可以不用关心 */ [maclean@rh2 test]$ strace -o exp2.trace exp maclean/maclean file=tv.dmp tables=tv direct=y recordlength=32768 Export: Release 10.2.0.4.0 - Production on Mon Nov 8 18:31:07 2010 Copyright (c) 1982, 2007, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options Export done in US7ASCII character set and UTF8 NCHAR character set server uses ZHS16GBK character set (possible charset conversion) About to export specified tables via Direct Path ... . . exporting table TV 6602624 rows exported Export terminated successfully without warnings. 节选的recordlength为32k时的system call trace: read(9, "\7\333\0\0\6\0\0\0\0\0\10\0\200\0\0ONYM\7\0xl\3\f\2\t9\7\0xl"..., 2064) = 2064 read(9, "\5\0VALID\1\0N\1\0N\1\0N\7\0OLAPSYS\10\0CWM$U"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0002:01:09:00\5\0VALID\1\0N\1\0"..., 2064) = 2064 read(9, "\0N\7\0OLAPSYS\26\0CWM2$AWDIMCREATEACC"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\0\303\5T\2\5\0TABLE\7\0xl\3\f\2\n\4\7"..., 2064) = 2064 read(9, "\5T\25\4\0\303\5T\25\5\0INDEX\7\0xl\3\f\2\n\5\7\0xl\3\f\2"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\4\0\303\5T'\5\0INDEX\7\0xl\3\f\2\n\5"..., 2064) = 2064 read(9, "ID\1\0N\1\0N\1\0N\7\0OLAPSYS\23\0CWM2$HIERA"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0007:32\5\0VALID\1\0N\1\0N\1\0N\7\0"..., 2064) = 2064 read(9, "-10-20:20:07:33\5\0VALID\1\0N\1\0N\1\0N\7"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\0VALID\1\0N\1\0N\1\0N\7\0OLAPS"..., 2064) = 2064 read(9, "\0CWM2_OLAP_MEASURE\376\377\4\0\303\5U\"\376\377\7\0PA"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\0N\1\0N\1\0N\6\0PUBLIC\23\0CWM2"..., 2064) = 2064 read(9, "008-03-12:01:09:11\5\0VALID\1\0N\1\0N\1"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\0N\7\0OLAPSYS\35\0ALL$OLAP2"..., 2064) = 2064 read(9, "TTR_USES\376\377\4\0\303\5V\v\376\377\4\0VIEW\7\0xl\3\f\2\n"..., 1958) = 1958 read(9, "\3\v\0\0\6\0\0\0\0\0\2\n\23\7\0xn\n\24\25\10'\23\0002008-03-"..., 2064) = 779 write(7, "ONYM\7\0xl\3\f\2\t9\7\0xl\3\f\2\t9\23\0002008-03-"..., 4096) = 4096 write(7, "008-03-12:01:09:02\5\0VALID\1\0N\1\0N\1"..., 28672) = 28672 /* 以上可以看到exp进程首先了累计(accumulates)读取了32k左右的数据到缓存中,之后以2个write调用分别写出4096和28672 bytes 的数据,也就是在读取32k数据后全部写出再依次循环,不同于上面的累计读取8k然后写出8k */ /* 对比pmap报告可以发现内存使用也发生了变化 */ 00002b9f6e034000 708 256 256 rwx-- libnnz10.so 00002b9f6e0e5000 4 4 4 rwx-- [ anon ] 00002b9f6e103000 432 212 212 rwx-- [ anon ] 00002b9f6e16f000 400 8 0 r-x-- timezlrg.dat 00002b9f6e1f0000 40 28 0 r-x-- libnss_files-2.5.so /* 相对应的是exp进程的匿名块anon(00002b9f6e103000 432 212 212 rwx-- [ anon ])部分rss和Dirty, 由原来的164k增长到了212k,增长了48k */ [maclean@rh2 test]$ strace -o exp3.trace exp maclean/maclean file=tv.dmp tables=tv direct=y recordlength=65535 Export: Release 10.2.0.4.0 - Production on Mon Nov 8 17:53:25 2010 Copyright (c) 1982, 2007, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production With the Partitioning, OLAP, Data Mining and Real Application Testing options Export done in US7ASCII character set and UTF8 NCHAR character set server uses ZHS16GBK character set (possible charset conversion) About to export specified tables via Direct Path ... . . exporting table TV 6602624 rows exported Export terminated successfully without warnings. /* 以65535 recordlength导出的strace 记录 */ read(9, "\7\333\0\0\6\0\0\0\0\0\10\377\377\0\0MADMIN\21\0SYS_IOT_T"..., 2064) = 2011 read(9, "\7\333\0\0\6\0\0\0\0\00010-09-29:18:14:08\5\0VAL"..., 2064) = 2064 read(9, "4:09\5\0VALID\1\0N\1\0N\1\0N\3\0SYS\23\0AQ$AQ"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\4\0\303\6 b\5\0INDEX\7\0xn\t\36\17!0"..., 2064) = 2064 read(9, ":21\5\0VALID\1\0N\1\0N\1\0N\3\0SYS\4\0HR11\376\377"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0J$\4\0P101\4\0\303\6!>\4\0\303\6\"9\17\0"..., 2064) = 2064 read(9, "P101\4\0\303\6!O\4\0\303\6\">\17\0INDEX PARTITIO"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0I1CCOL$\4\0P101\4\0\303\6!a\4\0\303"..., 2064) = 2064 read(9, ":44\5\0VALID\1\0N\1\0N\1\0N\3\0SYS\16\0WRH$_P"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0N_HISTORY_PK\31\0WRH$_ACT"..., 2064) = 2064 read(9, "SQLSTAT_PK\31\0WRH$_SQLSTA_14284528"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\0002010-10-18:20:48:28\5\0"..., 2064) = 2064 read(9, ";\f\23\0002010-10-20:19:58:11\5\0VALID\1\0"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0RT$\376\377\4\0\303\6$W\376\377\5\0TABLE\7\0"..., 2064) = 2064 read(9, "38C00004$$\376\377\4\0\303\6%(\4\0\303\6%(\3\0LOB\7\0x"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\6%G\376\377\5\0TABLE\7\0xn\n\24\25\10\34\7"..., 2064) = 2064 read(9, "VALID\1\0N\1\0N\1\0N\3\0SYS\30\0GV_OLAPI_SE"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\1\0N\1\0N\3\0SYS\31\0OLAPI_MEM"..., 2064) = 2064 read(9, "n\n\24\25\t\n\7\0xn\n\24\25\t\n\23\0002010-10-20:20:0"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\4\0TYPE\7\0xn\n\24\25\t\v\7\0xn\n\24\25"..., 2064) = 2064 read(9, "\16\23\0002010-10-20:20:08:12\5\0VALID\1\0N"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\7\0xn\n\24\25\t\25\23\0002010-10-20:"..., 2064) = 2064 read(9, "ITIONSTRUCT\376\377\4\0\303\6(\4\376\377\4\0TYPE\7\0xn\n"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\4\0VIEW\7\0xn\n\24\25\t\27\7\0xn\n\24\25"..., 2064) = 2064 read(9, " PARTITION\7\0xn\v\7\0238\10\7\0xn\v\7\0238\10\23\00020"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0-11-07:18:55:08\5\0VALID"..., 2064) = 2064 read(9, "ITION\7\0xn\v\7\0238\n\7\0xn\v\7\0238\n\23\0002010-11"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\000010-11-07:22:52:09\5\0VA"..., 2064) = 2064 read(9, "-11-07:22:52:10\5\0VALID\1\0N\1\0N\1\0N\6"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0T_SOO_BUFFER_BUSY\376\377\4\0\303"..., 2064) = 2064 read(9, "\0xn\n\36\27\5\33\7\0xn\n\37\27\6\5\23\0002010-10-23:01"..., 1958) = 1958 read(9, "\7\333\0\0\6\0\0\0\0\0\6+ \17\0TABLE PARTITION\7\0"..., 2064) = 2064 read(9, "09\5\0VALID\1\0N\1\0N\1\0N\3\0SYS\27\0WRH$_DB"..., 1477) = 1477 write(7, "0-09-29:17:56:12\5\0VALID\1\0N\1\0N\1\0N"..., 4096) = 4096 write(7, "05465\376\377\4\0\303\6\37\\\4\0\303\6\37\\\5\0INDEX\7\0xn\t\35"..., 61440) = 61440 /* 这里exp首先累计(accumulates)读取了65536 bytes的数据到缓存中,然后以2次write写出这些记录到导出文件中 换而言之可以把recordlength看做direct patch时的buffer size */那么recordlength是如何影响exp的效率的呢?由以上演示可知在使用direct直接路径读取方式时,recordlength并不影响读取(read),不管我们设置如何的recordlength,exp进程所需做的read总工作量都是一样的。区别在于write的次数和单次写出的数据量,以不设置recordlength为例,其写出8192字节数据需要做2次的write,则当dump文件为600MB时需要写出153600次;而设置recordlength为65535时,其写出(4096+61440)=65536也仅需要做2次write call,当dump文件为600MB时仅需要写出19200次。可知当使用更大的recordlength时可以有效减少exp作业所需的CPU时间和实际IO次数,以极大地加速导出速度;表现到IO层的话,就是用户可以显示地使用iostat等工具看到在导出阶段的写出IO大幅上升。使用recordlength的直接代价是exp进程会消耗使用更多的内存(一般在100~200k左右),以现在的眼光看来这点内存无关紧要。 需要注意的是recordlength现在存在一个最大值(maximum)为65535,设置超过65536的recordlength,exp程序都会返回如:Note: RECORDLENGTH=65536 truncated to 65535的信息;早期版本(734 or 8i)中不存在这个限制,也说明了exp的开发人员逐渐意识到大于65535的 recordlength无益于加速导出。 metalink文档[ID 134966.1]指出了如何判断recordlength的默认值:
Problem Description ------------------- You want to export the entire database and move it to a different platform. The RECORDLENGTH parameter must be specified during the export since each platform has a different default. How do you determine the default RECORDLENGTH value for each platform? Solution Description -------------------- Look for the BUFSIZ-Parameter in the File /usr/include/stdio.h file to determine the default size of the output record length. If no value is specified for the BUFSIZ parameter then a default of 512 bytes will be used. Explanation ----------- If the RECORDLENGTH parameter is not explicitly set on EXP/IMP, ORACLE will use the value specified for BUFSIZ in the /usr/include/stdio.h file to determine the size of it's output record length. The BUFFER parameter applies ONLY to conventional path Export. It has no effect on a direct path Export. This BUFFER parameter specifies the size (in bytes) of the buffer used to fetch rows. It determines the maximum number of rows in an array, fetched by Export. For direct path Export, use the RECORDLENGTH parameter to specify the size of the buffer that Export uses for writing to the export file. The RECORDLENGTH parameter specifies the length (in bytes) of the file record. You can use this parameter to specify the size of the Export I/O buffer (highest value is 64 kb). Changing the RECORDLENGTH parameter affects only the size of data that accumulates before writing to disk. It does not affect the operating system file block size. If you do not define this parameter, it defaults to your platform-dependent value for BUFSIZ (1024 bytes in most cases).BUFSIZ本身是UNIX/LINUX系统中控制I/O buffersize的参数,有兴趣研究的话可以参考著名的apue书(W.Richard Stevens的<Advanced Programming in the UNIX Environment>,这本书可以做任何人的Unix C启蒙书:
The value of BUFSIZ is chosen on each system so as to make stream I/O efficient. So it is a good idea to use BUFSIZ as the size for the buffer when you call setvbuf. Actually, you can get an even better value to use for the buffer size by means of the fstat system call: it is found in the st_blksize field of the file attributes.Sometimes people also use BUFSIZ as the allocation size of buffers used for related purposes, such as strings used to receive a line of input with fgets (see section 12.8 Character Input). There is no particular reason to use BUFSIZ for this instead of any other integer, except that it might lead to doing I/O in chunks of an efficient size.'
本文转自maclean_007 51CTO博客,原文链接:http://blog.51cto.com/maclean/1277600