Oracle案例09——ORA-12154: TNS:could not resolve the connect identifier specified
DG处理的问题还是蛮多的,但这次遇到一个比较奇葩的事情,表面配置、网络都没啥问题,但主备的同步始终有问题,经过多次调整参数、重新部署问题依旧,最终还是求助mos问题得以解决,现将处理过程记录如下:
一、问题现象
偶尔发现一个主备数据库同步有问题,检查备库发现除了无法完成同步,其他无错误信息,检查主库发现错误信息如下:
set line 200; set pagesize 2000; select dest_id,status,error from v$archive_dest;
ORA-12154: TNS:could not resolve the connect identifier specified
alert日志内容如下:
Error 12154 received logging on to the standby
trace内容如下:
*** 2018-07-02 09:37:36.230 OCIServerAttach failed -1 .. Detailed OCI error val is 12154 and errmsg is 'ORA-12154: TNS:could not resolve the connect identifier specified ' OCIServerAttach failed -1 .. Detailed OCI error val is 12154 and errmsg is 'ORA-12154: TNS:could not resolve the connect identifier specified ' OCIServerAttach failed -1 .. Detailed OCI error val is 12154 and errmsg is 'ORA-12154: TNS:could not resolve the connect identifier specified ' OCIServerAttach failed -1 .. Detailed OCI error val is 12154 and errmsg is 'ORA-12154: TNS:could not resolve the connect identifier specified ' *** 2018-07-02 09:37:36.246 4329 krsh.c Error 12154 received logging on to the standby
二、问题原因
一般遇到ora-12154的错误,首先我们想到的肯定是监听配置和tnsnames.ora配置是否一致,然后看dg的服务名配置是否一致,然后还会检查本地监听(local_listener )是否配置正确,通过上述检查发现都没问题,然后又通过服务名用户名密码连接也没问题。那为什么还是会报服务名无法解析导致归档无法完成的错误呢?
最奇葩的是有些归档是可以传输过去,有些归档是无法传输。这里实在没招了,只能求助mos,在mos上找到了解决方案。()
Cause After adding a new standby database, a corresponding new TNS alias entry was added to the tnsnames.ora on the primary node, but neither the instance nor the archiver processes were restarted. The ARC processes read the tnsnames.ora only once during process initialization, any updates to the tnsnames.ora after startup will not be known to the ARC process and hence the error ORA-12154: TNS:could not resolve the connect identifier specified is reported when the ARC processes try to resolve the (new) value for the 'service' attribute.
大致意思是说新的tns别名在主库被添加,实例和归档进程都没有被重启,导致归档进程读取的tnsnames.ora还是初始化启动的时候的内容,所以无法识别新的tnsnames.ora配置的服务器名。
三、解决方案
mos提供了3中解决方案,重启主数据库实例、指定归档服务串、重启归档进程,我这里采用的是第三种,重启归档进程
1. Shutdown and restart the primary database instance. This will cause a (short) outage of the primary database and may not be feasible for this reason. 2. Use a connect descriptor for the 'service' parameter. Instead of using a TNS alias for the service parameter (which requires a lookup of the tnsnames.ora file) one can use the connect descriptor itself. Assume the following (new) entry in the tnsnames.ora on the primary node: REMOTE_DEST_NEW = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = standbynode)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = STDBY) ) ) The corresponding 'alter system' command would then be: alter system set log_archive_dest_2 = 'service="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=standbynode)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=STDBY)))"' ; Please note that there's a length limit for the log_archive_dest_<n> parameter, so this will only work if the length of the connect string plus the length of other attributes specified does not exceed this limit. 3. Kill the ARC processes of the primary instance. With RDBMS releases <= 9.2 it was possible to stop and restart the archiver processes by issuing 'archive log stop' followed by 'archive log start'. However these commands are no longer valid with 10g and above, so to cause a respawn of the archiver processes they must be killed, they will be restarted immediately by the instance. This solution requires due care to avoid accidentally killing other vital background processes. The following script (ksh,bash) may assist in identifying the correct ARC processes that need to be killed: ps -ef|egrep "ora_arc.*_${ORACLE_SID}"|grep -v grep |while read user pid junk do echo "kill -9 $pid" done
通过kill 掉主库的归档进程,然后完成alter system switch logfile ;发现数据库数据同步正常。
四、问题总结
查询从库日志应用情况: select sequence#,archived,applied from v$archived_log order by sequence#; 改变归档路径: alter system set LOG_ARCHIVE_DEST_STATE_3=defer scope=both; alter system set LOG_ARCHIVE_DEST_3='SERVICE=dbs ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=dbs' scope=both; alter system set log_archive_dest_1='location=/oracle/oradata/db/arch VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=db' scope=both;