我正在尝试递归复制超过 25G 的巨大可安装目录,并希望保留所有者和组 ID、权限模式等。
所以我运行了以下命令:
bash-3.2$ date; cp -rpP /source/path/Oracle /target/path/Oracle;date;
Tue Jun 4 09:44:54 EDT 2013
...
一些观察结果:
今天(2013 年 6 月 5 日星期三 12:09:25 EDT)我注意到它仍然没有完成并且似乎卡在某个地方。我开始分析这个过程,它似乎在睡觉:
bash-3.2$ truss -p 09431; read(10, 0xFFBEF288, 32768) (sleeping...)
最后一个条目还显示它正在睡觉。
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)
终于尝试了
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
更新: 注意上面的cp
进程已经被杀死了。因此,以下观察试图重现该问题。
文件被阻止:
bash-3.2$ ls -l ESSBASE1_1 prw-rw---- 1 kent kent 0 Nov 22 2011 ESSBASE1_1
当我尝试单独 cp 这个文件时:
bash-3.2$ cp ESSBASE1_1 ESSBASE1_1kent # PID = 08745 ...
它也挂了。
看样子
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)
搜索使用该文件的所有其他进程
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
请注意,“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
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
- 谁能帮我理解是什么导致复制命令冻结?
- 我可以猜测该应用程序正在运行,并且可能会以某种方式阻止任何其他进程访问特定文件。
- 但在这种情况下,我希望
cp
中止并抛出错误,而不是无限期地被阻止。 - 根据更新,进程似乎
PID=25057
正在使用该文件作为打开的文件。但是为什么这会阻止cp
命令呢?
答案1
如果您查看pfiles
文件描述符 10 的输出,您会注意到该文件是 FIFO;p
您列表中的类型也证明了这一点ls
。 FIFO 的本质是读取会阻塞,除非另一个进程正在写入数据,这就是为什么cp
在尝试读取其内容时会卡住的原因。
为了解决这个问题,您可以使用rsync
复制目录树来代替。
rsync -a /source/path/Oracle /target/path
rsync
它足够聪明,能够创建一个重复的 FIFO,而不是从原始的 FIFO 中读取。请注意,您没有指定Oracle
目标,因为rsync
将在那里创建目录。