opatch被异常中断后的处理

今天在打一个patch的时候,已经是用opatch执行到了最后一个patch,一时手欠,没看清楚telnet的窗口,不小心按下了ctrl+C,于是,opatch被中断了。汗了,晚节不保啊!

再次执行opatch apply,报错:

用opatch lsinventory检查,发现这个patch还是已经安装上去了的:

ok,既然你已经在完成安装的列表中了,那我卸载可以不?

完蛋了,无论是重新apply还是rollback,都失败了。

在这个情况下,我们可以在$ORACLE_HOME找到一个隐含的文件夹,里面的rollback.sh和make.txt文件,来清楚已经安装的信息,从而让我们重新安装。因为在进行opatch的过程在,在$ORACLE_HOME下有个隐含目录.patch_storage,在这个目录下的对应的目录,

另一个rollback.sh脚本用于回滚失败的opatch执行过程,和一个make.txt脚本用于回滚编译ioracle的过程:

其实我们从回滚脚本可以具体的看到,第一个是将一些kfc.o,kfcb.o,kfcl.o的文件从libserver10.a中抽取出类备份且还原出来。也就是说,在执行opatch的过程是将kfc.o,kfcb.o,kfcl.o等文件写入到libserver10.a文件中的。第二步,重新编译ioracle。

因此,我们可以利用这2个脚本,和利用原来在opatch的时候,做的备份(注意,这里一定要用原来的备份,一定要做原来的kfc.o,kfcb.o,kfcl.o的文件,在后续的操作步骤中,请注意这点。),我们来进行还原操作。
操作步骤为:
情况1,如果你的没有再次执行opatch脚本,即在.patch_storage目录下的rollbak脚本没有被覆盖,你可以:

1.运行rollback脚本:
% sh $ORACLE_HOME/.patch_storage/1234567/rollback_1234567 .sh

注意,可以能会如下报错

这个可以不必忽略。

2.运行make脚本

注,make脚本仅在relink阶段出错的时候才需要使用。

3.重命名脚本的原目录
% mv $ORACLE_HOME/.patch_storage/1234567 $ORACLE_HOME/.patch_storage/1234567.orig

情况2,如果你已经再次执行opatch脚本,即在.patch_storage目录下的rollbak脚本被覆盖了,你需要:

1.从命名你的原路径:

2.重新生成rolback脚本,注意用no_inventory和on_relink参数

3.将生产的rollback脚本和make脚本移动至原路径,以便利用原来的备份。

4.执行rollback脚本和make脚本,注意执行的时候可能会出现和情况1一样的报错,可以忽略。

5.重命名原路径

我们是属于情况2,因此采用情况2的方法进行回滚:

我们用lsinventory来查看回滚情况:

发现确实已经清楚掉了6163771的安装信息!我们再次尝试安装opatch:

我们发现还是报错了!

难道是libserver10.a文件已经被破坏了?因为这个文件已经被破坏,所以在从这个文件读取备份文件信息的时候,会报错I/O error。也就是说,我是在opatch正在修改libserver10.a这个文件的时候,按下了ctrl+C,导致写文件到一半被中断,所以导致这个文件被破坏了!

用ar来测试一下:

唉,果真如此啊!在这情况下,我们也有两种方式来处理:
情况1:如果libserver10.a之前没有被其他patch修改过,我们可以用当前这个patch包中的文件进行编译和替换。

情况2,也是最坏的情况,libserver10.a文件已经之前被其他的patch所修改过,我们检查我也确实属于了这个情况: