我正在尝试递归复制超过 25G 的可安装目录的巨大目录,并希望保留所有者和组 ID、权限模式等。
所以我运行了以下命令:
bash-3.2$ date; cp -rpP /source/path/Oracle /target/path/Oracle;date;
Tue Jun 4 09:44:54 EDT 2013
...
Run Code Online (Sandbox Code Playgroud)
一些观察:
今天(2013 年 6 月 5 日星期三 12:09:25 EDT)我注意到它仍然没有完成并且似乎卡在某个地方。我开始分析这个过程,它似乎在睡觉:
bash-3.2$ truss -p 09431;
read(10, 0xFFBEF288, 32768) (sleeping...)
Run Code Online (Sandbox Code Playgroud)最后一个条目还表明它睡着了。
bash-3.2$ pflags 09431
9431: cp -rpP /source/path/Oracle /target/path/Oracle
data model = _ILP32 flags = RLC|ASYNC|MSACCT|MSFORK
flttrace = 0xfffffbff
sigtrace = 0xfffffeff 0xffffffff
HUP|INT|QUIT|ILL|TRAP|ABRT|EMT|FPE|BUS|SEGV|SYS|PIPE|ALRM|TERM|USR1|USR2|CLD|PWR|WINCH|URG|POLL|STOP|TSTP|CONT|TTIN|TTOU|VTALRM|PROF|XCPU|XFSZ|WAITING|LWP|FREEZE|THAW|CANCEL|LOST|XRES|JVM1|JVM2|RTMIN|RTMIN+1|RTMIN+2|RTMIN+3|RTMAX-3|RTMAX-2|RTMAX-1|RTMAX
entryset = 0x00000401 0x04000000 0x00000000 0x00000028
0x80000000 0x00000000 0x00000000 0x00000000
exitset = 0xfffffffe 0xffffffff 0xffffffff 0xffffffd7
0x7fffffff 0xffffffff 0xffffffff 0xffffffff
/1: flags = ASLEEP read(0xa,0xffbef288,0x8000)
Run Code Online (Sandbox Code Playgroud)终于试过了 pfiles
bash-3.2$ pfiles -F 09431
9431: cp -rpP /source/path/Oracle /target/path/Oracle
Current rlimit: 256 file descriptors
0: S_IFCHR mode:0620 dev:363,0 ino:12582922 uid:502012187 gid:7 rdev:24,3
O_RDWR|O_NOCTTY|O_LARGEFILE
/devices/pseudo/pts@0:3
1: S_IFCHR mode:0620 dev:363,0 ino:12582922 uid:502012187 gid:7 rdev:24,3
O_RDWR|O_NOCTTY|O_LARGEFILE
/devices/pseudo/pts@0:3
2: S_IFCHR mode:0620 dev:363,0 ino:12582922 uid:502012187 gid:7 rdev:24,3
O_RDWR|O_NOCTTY|O_LARGEFILE
/devices/pseudo/pts@0:3
3: S_IFDIR mode:0750 dev:377,1 ino:1135681 uid:502012187 gid:502012187 size:4096
O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
/source/path/Oracle
4: S_IFDIR mode:0750 dev:377,1 ino:1135682 uid:502012187 gid:502012187 size:4096
O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
/source/path/Oracle/Middleware
5: S_IFDIR mode:0750 dev:377,1 ino:14640507 uid:502012187 gid:502012187 size:4096
O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
/source/path/Oracle/Middleware/user_projects
6: S_IFDIR mode:0750 dev:377,1 ino:14640508 uid:502012187 gid:502012187 size:4096
O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
/source/path/Oracle/Middleware/user_projects/epmsystem2
7: S_IFDIR mode:0750 dev:377,1 ino:6480147 uid:502012187 gid:502012187 size:4096
O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
/source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer
8: S_IFDIR mode:0750 dev:377,1 ino:6480149 uid:502012187 gid:502012187 size:4096
O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
/source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1
9: S_IFDIR mode:0750 dev:377,1 ino:6480151 uid:502012187 gid:502012187 size:4096
O_RDONLY|O_NDELAY|O_LARGEFILE FD_CLOEXEC
/source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1/bin
10: S_IFIFO mode:0660 dev:377,1 ino:9088704 uid:502012187 gid:502012187 size:0
O_RDONLY|O_LARGEFILE
/source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1/bin/ESSBASE1_1
11: S_IFREG mode:0660 dev:326,22000 ino:128325 uid:502012187 gid:502012187 size:0
O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE
/target/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1/bin/ESSBASE1_1
Run Code Online (Sandbox Code Playgroud)更新: 请注意,上述cp
进程已被终止。所以下面的观察试图重现这个问题。
被阻止的文件:
bash-3.2$ ls -l ESSBASE1_1
prw-rw---- 1 kent kent 0 Nov 22 2011 ESSBASE1_1
Run Code Online (Sandbox Code Playgroud)当我尝试单独 cp 这个文件时:
bash-3.2$ cp ESSBASE1_1 ESSBASE1_1kent # PID = 08745
...
Run Code Online (Sandbox Code Playgroud)
它也挂了。
看着pflags
,好像睡着了。
bash-3.2$ pflags 08745
8745: cp ESSBASE1_1 ESSBASE1_1kent
data model = _ILP32 flags = MSACCT|MSFORK
/1: flags = ASLEEP read(0x3,0xffbf6bc8,0x8000)
Run Code Online (Sandbox Code Playgroud)使用此文件搜索所有其他进程
bash-3.2$ fuser -f /source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1/bin/ESSBASE1_1
/source/path/Oracle/Middleware/user_projects/epmsystem2/EssbaseServer/essbaseserver1/bin/ESSBASE1_1: 8745o 25057o
Run Code Online (Sandbox Code Playgroud)
请注意,“o”表示进程正在使用该文件作为打开的文件。
在进程中查找:
bash-3.2$ pstree | grep 8745
| | | |--- 09695 kent grep 8745
| | \--- 08745 kent cp ESSBASE1_1 ESSBASE1_1kent
bash-3.2$ pstree | grep 25057
| | | \--- 09700 kent grep 25057
| | |-+- 25057 kent 86:43 /some/path/Oracle/Middlewa
Run Code Online (Sandbox Code Playgroud)
PID 为 25057 的进程是一个服务器进程。
打开的文件位于挂载点上。这是一个NAS磁盘。
bash-3.2$ cat /etc/mnttab | grep apps
server1.com:/vol/server1_nec_nosnap0/dev_apps /source/path/ nfs rw,xattr,dev=5e40001 1362894854
Run Code Online (Sandbox Code Playgroud)cp
中止并抛出错误,而不是无限期地被阻止。PID=25057
似乎正在将该文件用作打开文件。但是为什么这会阻止cp
命令?如果您查看pfiles
文件描述符 10 的输出,您会注意到该文件是一个 FIFO;p
您ls
列表中的类型也证明了这一点。FIFO 的本质是读取将阻塞,除非另一个进程正在写入数据,这就是您cp
在尝试读取其内容时卡住的原因。
为了解决这个问题,您可以使用rsync
复制目录树来代替。
rsync -a /source/path/Oracle /target/path
Run Code Online (Sandbox Code Playgroud)
rsync
足够聪明,可以制作重复的 FIFO 而不是从原始 FIFO 中读取。请注意,您没有指定Oracle
目的地,因为rsync
将在那里创建目录。