客户现场DG主备切换演练,在切换成功后,尝试登陆数据库,发现以下错误:
ORA-01033: ORACLE initialization or shutdown in progress
切换的流程是这样的,主备切换后,ip也做改变,原备库的ip修改成远主库的scan ip,这样应用就可以在不做改动的情况下,直接连数据库。但是奇怪的是在切换后却无法正常连接,尝试使用连接串登陆数据库,会报出ORA-01033错误。
针对ORA-01033错误,做了以下检查:
1.sqlplus登陆主库(原备库),指定service name和sid
sqlplus system/oracle@192.168.211.107:1521/rac/rac
再查看open_mode,发现是read write,说明数据库是open状态
select open_mode from v$database;
2.sqlplus再次登陆主库(原备库),只指定service name
出现ORA-01033错误
3.查看数据库alert日志,备库成功切换成主库,没有发现异常错误。
4.查看lsnrctl status,发现在rac服务下有多个实例,其中rac1和rac2是生产库的实例
从以上的检查中,可以发现备库(原主库)的实例注册到了主库(原备库)的监听中,应用在连接数据库的时候,连接上的是备库(原主库),而备库在主备切换后变成mount状态,所以才会出现ORA-01033错误。
为什么备库(原主库)的实例会注册到主库(原备库)的监听中?之前在自己环境模拟DG主备切换并修改IP时也遇到过同样的问题,解决方法就是修改remote_listener参数。
关于remote_listener的作用,以下是官方解释:
REMOTE_LISTENER specifies a network name that resolves to an address or address list of Oracle Net remote listeners (that is, listeners that are not running on the same machine as this instance). The address or address list is specified in the TNSNAMES.ORA file or other address repository as configured for your system.
简单来说就是REMOTE_LISTENER是用来指定远程的监听地址。
分析到这里,问题就很明显了,看了下备库(原主库)的remote参数:
SQL> show parameter remote_listener
NAME TYPE VALUE
-------------------------- ----------- --------------------
remote_listener string racdb-scan:1521
racdb-scan:1521正是主库(原备库)的监听地址,所以实例才会注册到主库的监听中。解决方法也很简单,修改remote_listener:
alter system set remote_listener='' sid='*' scope=both;
其实这个问题和Oracle的TNS Listener远程注册投毒类似,如果修复了这个漏洞,理论是可以避免这个错误的。
下面来模拟这个错误:
1.主备切换后,关掉备库的scan监听和scan。
2.修改主库的ip为scanip地址。
3.主库查看listener status,可以看到备库的实例rac1和rac2注册到了主库的监听中。
4.尝试sqlplus登陆主库,报出ORA-01033错误
5.修改备库的remote_listener,alter system set remote_listener='' sid='*' scope=both;,再次查看主库监听,发现没有了备库的实例。
6.尝试sqlplus登陆主库,登陆成功。