简介
迁移或复制数据是很常见的任务。无论是通过网络将数据复制到新的文件系统中,还是在同一卷组中复制逻辑卷或将它复制到另一个卷组,抑或只是创建文件系统的备份。转移或复制数据的原因可能是为了提高性能,或者因为当前环境中没有足够的空间容纳不断增长的数据。可以使用不同的工具(比如 migratepv、cplv、tar、cpio、cp 或 rsync)执行上面提到的数据转移任务。对于 jfs,可以使用 splitcopy(或对 jfs2 使用 snapshot)获得文件系统的拷贝。对于哪种方法最适合某项数据转移任务,并没有绝对的规定。在本文中,我会演示在文件系统和逻辑卷级上转移或复制数据的不同方法,主要关注以下 AIX 实用程序:cplv、tar 和 cp。
使用 tar 和 cp 将数据复制到新的文件系统
在对应用程序文件系统应用更新时,要先执行备份,很可能是将数据备份到磁带。但是如果空间允许,也可以复制应用程序所在的文件系统。这样做的优点是可以快速进行恢复。另外,通过交换挂载点,可以快速地对比更新后的文件与原来的文件。假设文件系统 /opt/pluto 包含要升级的应用程序:
# df -g…/dev/fslv00 1.00 0.03 97% 22 1% /opt/pluto |
我们来看一下使用 cp、tar 和 cplv 将应用程序文件复制到另一个文件系统的三种方法。
首先,需要创建备份(复制的)文件系统。这会使用到 crfs 命令,要确保文件系统的类型相同,而且系统的大小不小于原文件系统。当前 /pluto 文件系统的大小是 1G,是 jfs2 类型的。新的文件系统名为 /opt/pluto_bak。可以使用以下命令创建这个文件系统:
# crfs -v jfs2 -g rootvg -m /opt/pluto_bak -A yes -p rw -a agblksize=4096 -a size=1GFile system created successfully.524068 kilobytes total disk space.New File System size is 1048576 |
在这个示例中,输入参数的含义如下:
-v jfs2 | 指定 jfs2 文件系统类型 |
-g rootvg | 创建文件系统 rootvg |
-m /opt/pluto_bak | 指定实际的挂载点 |
-A yes | 指定在重新引导时自动地挂载这个文件系统 |
-p rw | 指定读写权限 |
-a agblksize=4096 | 以字节为单位指定块大小 |
-a size=1G | 指定要创建的文件系统的大小(在这个示例中是 1GB) |
接下来要挂载文件系统 /opt/pluto_bak:
现在使用的是 cp 命令,为了确保复制权限/修改时间和符号链接,可以使用 Rph 标志。
下面的 cp 命令将所有文件和符号链接(如果有的话)从 /opt/pluto 复制到 /opt/pluto_bak:
# cd /opt/pluto# pwd/opt/pluto# cp -Rph * /opt/pluto_bak |
一定要检查复制是否正确地完成了,方法是在原来的和复制的文件系统上列出文件数量并运行 du。对于 /opt/pluto:
# pwd/opt/pluto# du -ms .988.46 .# ls |wc 17 17 146 |
对于 /opt/pluto_bak:
# cd ../pluto_bak# ls |wc 17 17 146# du -ms .988.46 . |
前面的输出说明原来的和复制的文件系统是匹配的,所以一切正常(复制成功地完成了)。
现在,再次执行相同的操作,但是这一次使用 tar 实用程序。
在处理大量小文件时,使用 tar 通常更快。如果文件大于 2GB,一定要使用 GNU tar 实用程序。
# cd /opt/pluto# pwd/opt/pluto# tar cpf - . | (cd /opt/pluto_bak; tar xpf - ) |
在前面的输出中,tar 从当前目录创建存档,包括修改时间/权限;tar 把存档发送到标准输出。然后,输出管道连接到一个子 shell,再进入 /opt/pluto_bak,最后把数据从标准输出提取到 /opt/pluto_bak 文件系统中。
与前面一样,一定要检查原来的和复制的文件系统的总大小和文件数量是否匹配。
如果希望看到存档和提取文件的过程,就添加详细输出 (v) 选项:
# cd /opt/pluto# tar cvpf - . | (cd /opt/pluto_bak; tar xvpf - )a .a ./lost+founda ./myfile.dat 0 blocks.a ./pop 1 blocks.a ./test100M.bin 195313 blocks.x .x ./lost+foundx ./myfile.dat, 0 bytes, 0 media blocks.x ./pop, 139 bytes, 1 media blocks.x ./test100M.bin, 100000000 bytes, 195313 media blocks.a ./myfile1 195313 blocks.x ./myfile1, 100000000 bytes, 195313 media blocks.a ./mprep 195313 blocks.x ./mprep, 100000000 bytes, 195313 media blocks.a ./chklp 195313 blocks.x ./chklp, 100000000 bytes, 195313 media blocks.a ./poplt 195313 blocks.x ./poplt, 100000000 bytes, 195313 media blocks.…..….. |
使用 tar 将数据复制到远程文件系统
还可以使用 tar 通过网络复制数据,尽管使用 scp 也可以。对于文件系统复制,我一般喜欢使用 tar。要想通过网络使用 tar,则应该使用 ssh 作为传输方法。也可以使用 rsh,但是我不建议这么做,因为它有安全缺陷。
如果希望将数据从本地主机上的 /opt/pluto 复制到远程主机 nordkapp 上的文件系统 /opt/pluto,则可以使用以下命令:
# cd /opt/pluto# tar -cpf - . | ssh nordkapp (cd /opt/pluto; tar -xpf -) |
通过这个示例可以看出,对于本地复制/恢复与远程复制/恢复,tar 命令并没有很大的差异。前面的示例假设已经交换了 ssh 密钥,所以可以执行无密码连接/登录。
在卷组中复制逻辑卷
在处理小的文件系统时,使用 cplv 比使用 cp 或 tar 慢得多。要考虑的另一要点是,cplv 需要复制整个逻辑卷,而 tar 和 cp 只需复制文件。经验规则是:如果文件系统大于 10 GB,则使用 cplv。
在下面的示例中,我们要将 /opt/pluto 所在的逻辑卷(名为 fslv00)复制到文件系统逻辑卷 fslv01。cplv 命令会覆盖 fslv01 的当前内容,这正是我们想要的效果。注意,在这个示例中,已经创建了文件系统 /opt/pluto_bak;该文件系统中目前没有任何数据。可以通过 df 命令的输出看出这一点:
# df -g…../dev/fslv00 1.00 0.03 97% 22 1% /opt/pluto/dev/fslv01 1.00 1.00 1% 4 1% /opt/pluto_bak |
首先要做的是卸载这两个文件系统。与 tar 和 cp 不同,不能在文件系统处于联机状态下时执行 cplv 命令:
# umount /opt/pluto# umount /opt/pluto_bak |
如果文件系统报告它因为忙无法卸载,则应确保关闭应用程序。然后,使用 fuser 判断哪些进程导致文件系统无法卸载:
例如:
如果决定终止此文件系统上的所有进程,那么可以使用以下命令:
接下来要使用 cplv 命令。在这个示例中,我们将复制逻辑卷 fslv00,这会覆盖现有的目标逻辑卷 fslv01。命令的基本格式是:
cplv -e < dest lv> -f <source lv> |
其中:
-e | 将逻辑卷的内容复制到现有的逻辑卷 |
dest lv | 指定目标逻辑卷(在这个示例中是 fslv01) |
source lv | 指定源逻辑卷(在这个示例中是 fslv00) |
因为要覆盖另一个逻辑卷,所以应该确保目标逻辑卷的逻辑卷类型被设置为 copy 而不是 jfs2(在逻辑卷属性中)。如果不这样设置,命令会失败,并会发出警告消息,指出需要修改这个属性。对目标逻辑卷执行以下 lslv 命令以检查 TYPE:
# lslv fslv01 |grep TYPETYPE: jfs2 WRITE VERIFY: off |
在前面的输出中看到,目标逻辑卷的类型设置为 jfs2。现在需要将它设置为 copy 并运行 lslv 命令,以确认该设置:
# chlv -t copy fslv01# lslv fslv01 |grep TYPETYPE: copy WRITE VERIFY: off |
在将类型设置为 copy 之后,就可以复制逻辑卷了:
# cplv -e fslv01 -f fslv00cplv: Logical volume fslv00 successfully copied to fslv01 . |
从这个输出中看到,复制成功了。完成 cplv 命令之后,逻辑卷类型将恢复为 jfs2。我们来核实一下:
# lslv fslv01 |grep TYPETYPE: jfs2 WRITE VERIFY: off |
一切正常。现在,我们要来挂载文件系统:
# mount /opt/pluto# mount /opt/pluto_bak# df -g…./dev/fslv00 1.00 0.03 97% 22 1% /opt/pluto/dev/fslv01 1.00 0.03 97% 22 1% /opt/pluto_bak |
现在已经使用 cplv 命令将文件系统 /opt/pluto 复制到了 /opt/pluto_bak 中。与前面一样,一定要在复制的文件系统上对比这两个文件的大小和文件数量。
如果在应用程序升级期间出现错误,应用程序变得不可用,那么您别无选择,只能执行恢复操作。但是,我们已经复制了文件系统,只需将损坏的应用程序文件系统交换为好的应用程序即可。交换文件系统比从磁带恢复快,而且还可以保留升级失败的文件系统供进一步诊断。
在以下示例中,假设我们想从 /opt/pluto_bak 交换(即改变挂载点)到 /opt/pluto。首先,必须把 /opt/pluto 的挂载点更改为 /opt/pluto_err。这样,在将 /opt/pluto_bak 改为 /opt/pluto 时就不会出现名称冲突。使用 chfs 命令改变文件系统的挂载点。一定要先卸载文件系统。基本格式是:
chfs -m <new mount point> <original mount point> |
将 /opt/pluto 的挂载点更改为 /opt/pluto_err,然后将 /opt/pluto_bak 的挂载点更改为 /opt/pluto:
# chfs -m /opt/pluto_err /opt/pluto |
既然已经将 /opt/pluto 的挂载点更改为 /opt/pluto_err,现在即可将 /opt/pluto_bak 更改为 /opt/pluto:
# chfs -m /opt/pluto /opt/pluto_bak |
接下来,我们要挂载文件系统:
# mount /opt/pluto_err# mount /opt/pluto |
应用程序现在可以使用了。发生故障的应用程序目前保存在 /opt/pluto_err 中,这个文件系统也已挂载,因为两个应用程序文件系统目前都已挂载,所以需要进行进一步检查,比如进行对比。
将逻辑卷复制到另一个卷组
可以使用 tar、cp 或 cplv 将文件系统数据复制到另一个卷组。在本文中,我将使用 cplv。操作过程与前面相似。唯一的区别是,目标文件系统并不在同一卷组中,而是在另一个卷组中创建它。在将数据复制到另一个卷组时,必须修改 /etc/filesystems 中的逻辑卷设备(可能还有日志设备)属性,让 AIX 在请求挂载文件系统时知道在哪里寻找它。
我们来看看如何将逻辑卷复制到另一个卷组。步骤如下:
- 卸载 /opt/pluto 文件系统。
- 复制保存在 /opt/pluto 的逻辑卷 fslv00。使用复制命令将它解析为新的逻辑卷 pluto_lv。
- 如果目标卷组是新的卷组,则创建一个新的 jfs2log 并将其格式化。否则,使用卷组中现有的 jfs2log。
- 编辑 /etc/filesystems,让 /opt/pluto 的设备和日志设备都指向此卷组中的正确设备。
- 挂载刚复制的逻辑卷 pluto_lv 上的 /opt/pluto 文件系统。
- 检查刚挂载的文件系统。
- 卸载文件系统,然后执行 fsck 命令并重新挂载它。
对于 /opt/pluto 文件系统,假设希望把逻辑卷 fslv00 从 rootvg 复制到另一个卷组 apps_vg。另外,应该将这个逻辑卷改名为 pluto_lv。
对于这个示例,cplv 命令的基本格式如下:
cplv -v <dest vg> -y <new lv name> source _lv |
其中:
-v <dest vg> | 是目标卷组(在这个示例中是 apps_vg) |
-y <new lv name> | 是目标逻辑卷名称(在这个示例中是 pluto_lv) |
第一个任务是卸载希望复制的文件系统,然后才能访问逻辑卷。
使用 lsvg 命令确认文件系统已关闭:
# lsvg -l rootvg…fslv00 jfs2 64 64 1 closed/syncd /opt/pluto |
现在执行复制操作:
# cplv -v apps_vg -y pluto_lv fslv00cplv: Logical volume fslv00 successfully copied to pluto_lv . |
完成复制操作之后,现在即可用 lsvg 命令检查一下:
# lsvg -l apps_vgapps_vg:LV NAME TYPE LPs PPs PVs LV STATE MOUNT POINTpluto_lv jfs2 128 128 1 closed/syncd N/A |
从前面的输出可以看出,逻辑卷 fslv00 已经复制到卷组 apps_vg 并改名为 pluto_lv。但还要注意的是,其中没有 JFS (journaled file system) jfs2log 条目。如果将逻辑卷复制到空的卷组,就会出现这种情况。
使用 mklv 命令创建 jfs2log。mklv 命令的基本格式是:
mklv -t <type> -y <new lv_name> vg_name <number of LPs> |
其中:
-t <type> | 指定逻辑卷类型。在这里是 jfs2log |
-y <new lv name> | 指定目标逻辑卷名称。在本示例中是 jfs2log_lv |
vg_name | 表示 jfs2log 所在的卷组。在本示例中是 apps_vg |
Number of LPs | 逻辑分区的数量;在这里只需要一个分区 |
因此,使用以下命令创建 jfs2log,它位于卷组 apps_vg 中,名为 jfs2log_lv:
# mklv -t jfs2log -y jfslog_lv apps_vg 1jfslog_lv |
确认已经创建了这个逻辑卷:
# lsvg -l apps_vgapps_vg:LV NAME TYPE LPs PPs PVs LV STATE MOUNT POINTpluto_lv jfs2 128 128 1 closed/syncd N/Ajfslog_lv jfs2log 1 1 1 closed/syncd N/A |
下一个任务是初始化和格式化逻辑卷 jfs2log_lv,以便可以将它用作 jfs2log。这会使用到 logform 命令。在提示要销毁的内容时,选择 Yes。实际上不会销毁任何数据,而是对刚创建的逻辑卷进行格式化。
# logform /dev/jfslog_lvlogform: destroy /dev/rjfslog_lv (y)?y# |
现在差不多可以挂载 /opt/pluto 了;但是,必须先让 AIX 知道与它相关联的新设备和 jfs2log。看一下 /etc/filesystems 文件中 /opt/pluto 的文件系统条目:
# grep -w -p "/opt/pluto" /etc/filesystems/opt/pluto: dev = /dev/fslv00 vfs = jfs2 log = /dev/hd8 mount = true options = rw account = false |
可以看出需要修改以下属性:
这些属性反映这个逻辑卷驻留在 rootvg 中时的日志和设备。因为这个逻辑卷现在位于卷组 apps_vg 中,所以需要修改 log 和 dev 值。为了反映日志和逻辑卷现在所在的位置,将:
改为
将:
改为
现在编辑 /etc/filesystems,按前面的示例修改这些属性。完成之后,确认属性修改已经完成。
# grep -w -p "/opt/pluto" /etc/filesystems/opt/pluto: dev = /dev/pluto_lv vfs = jfs2 log = /dev/jfslog_lv mount = true options = rw account = false |
现在,只需挂载目前位于 apps_vg 卷组中的 /opt/pluto 即可。逻辑卷的复制已经完成了。
# mount /opt/pluto# lsvg -l apps_vgapps_vg:LV NAME TYPE LPs PPs PVs LV STATE MOUNT POINTpluto_lv jfs2 128 128 1 open/syncd /opt/plutojfslog_lv jfs2log 1 1 1 open/syncd N/A |
原来的逻辑卷仍然在 rootvg 中,没有相关联的挂载点。检查 /opt/pluto 以后,便可删除它。在检查过程中,最好对刚复制的文件系统运行 fsck(但是一定要先卸载它)。
# umount /opt/pluto# fsck -y /dev/pluto_lvThe current volume is: /dev/pluto_lvPrimary superblock is valid.J2_LOGREDO:log redo processing for /dev/pluto_lvPrimary superblock is valid.*** Phase 1 - Initial inode scan*** Phase 2 - Process remaining directories*** Phase 3 - Process remaining files*** Phase 4 - Check and repair inode allocation map*** Phase 5 - Check and repair block allocation mapFile system is clean# mount /opt/pluto |
接下来,如果所有检查都没有发现问题,则从 rootvg 删除原来的逻辑卷。一定要在重新引导(或执行 exportvg)之前删除原来的逻辑卷,因为 ODM 仍然包含原来的逻辑卷和文件系统属性:
# lsvg -l rootvg…..fslv00 jfs2 64 64 1 closed/syncd N/A# rmlv fslv00Warning, all data contained on logical volume fslv00 will be destroyed.rmlv: Do you wish to continue? y(es) n(o)? yrmlv: Logical volume fslv00 is removed. |
结束语
在文件系统之间转移或复制数据是系统管理员经常执行的一项任务,无论是在同一卷组中复制还是通过网络复制。在本文中,我演示了执行这些任务的不同方法。可以用许多方法复制数据,我只通过示例重点介绍了其中的几种。
关于作者
![]()
![]()
David Tansley 是一位自由作家。他有 15 年 UNIX 系统管理经验,最近 8 年使用 AIX。他喜欢打羽毛球和观赏一级方程式赛车,但是最喜欢与妻子一起开着 GSA 摩托车旅行。
http://www.ibm.com/developerworks/cn/aix/library/au-cp_mv/index.html