字典禁忌:UPDATE GLOBAL_NAME为空之后的恢复

编辑手记:最近一个朋友遭遇到了这个问题,当GLOBAL_NAME被更新为空值之后,数据库无法启动,我们重温一下老熊的这个测试,记住结论,无论如何不要Update字典表

如果你在数据库的告警日志中发现类似如下的提示,那么多半你的PROPS$发生了更改:

Database Characterset is ZHS16GBK Updating 7.0.0.0.0 NLS parameters in sys.props$ -- adding 10.2.0.5.0 NLS parameters.

在以前的一篇文章中( 数据库链:Database Link与GLOBAL_NAMES参数的关系 ),我提到千万不能将 Oracle 数据库的 global_name 更新为空。这不,事儿来了。我的一个同事,提到了一个解决办法,不过那个办法实际上是一种不完全恢复的办法,如果没有备份,就行不通。如果没有备份,可以使用BBED来修改块来解决这个问题,不过使用 bbed 仍然比较麻烦。

下面是我一时心血来潮进行的一次测试。测试环境,10.2.0.4 for Linux AS 5.5。注意,不要在生产库上模仿。注意:这个方法可能仅适用于10.2.0.4版本。

首先 UPDATE GLOBAL_NAME 为空,COMMIT 后以 abort 方式关闭数据库,以 abort 方式只是为了增加点难度。之后再启动数据库。

启动失败,不出意料出现 ORA-600[18062] 错误:

下面来解决这个问题。

第1步,重启数据库到 MOUNT 状态:

第2步,在另一个窗口中,使用 gdb

第3步,OPEN 数据库:

约等一会儿,在 alert 日志里面可以看到:

在 gdb 的输出可以看到:

第4步,在 gdb 那里中止 OPEN:

sqlplus 会提示:

这一次,Instance 并没有 terminated。只是 Serverprocess 被 KILL 了。

第5步,还原 GLOBAL_NAME:

虽然可以执行 UPDATE,但是不能 COMMIT。再试试能不能做 DDL:

成功了。

在另会一个会话中查看 GLOBAL_NAME:

GLOBAL_NAME 回来了。

这里通过 DDL 的隐式提交特性来 UPDATE GLOBAL_NAME。其实还有更简单的办法:OCI 主动断开连接时的自动提交。如果 UPDATE 之后,直接退出 sqlplus,UPDATEGLOBAL_NAME 的事务实际也提交了。看起来 ORACLE 这时只是不能执行显式的 COMMIT 语句。

第6步,重启数据库:

看起来只能以 abort 方式关闭数据库:

成功了,数据库起来了。没有数据丢失,没有使用备份。不需要基于时间点的恢复,不需要 BBED,不需要 Resetlog。

原文发布于微信公众号 - 数据和云(OraNews)

原文发表时间:2016-07-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

扫码关注云+社区