Failover Connections for Data Guard Error with ORA-1033 [ID 461874.1]

Failover Connections for Data Guard Error with ORA-1033 [ID 461874.1]


 

Modified 28-SEP-2010     Type PROBLEM     Status PUBLISHED

 

In this Document
  Symptoms
  Cause
  Solution


Applies to:

Oracle Net Services - Version: 9.2.0.1.0 to 10.2.0.1.0 - Release: 9.2 to 10.2
Information in this document applies to any platform.

Symptoms

Connections in data guard environment fail with ORA-01033: ORACLE initialization or shutdown in progress.

Oracle Net client trace shows after successful connection handshake

[27-SEP-2007 11:34:18:104] nsprecv: 00 00 39 4F 52 41 2D 30  |..9ORA-0|
[27-SEP-2007 11:34:18:104] nsprecv: 31 30 33 33 3A 20 4F 52  |1033:.OR|
[27-SEP-2007 11:34:18:104] nsprecv: 41 43 4C 45 20 69 6E 69  |ACLE.ini|
[27-SEP-2007 11:34:18:104] nsprecv: 74 69 61 6C 69 7A 61 74  |tializat|
[27-SEP-2007 11:34:18:104] nsprecv: 69 6F 6E 20 6F 72 20 73  |ion.or.s|
[27-SEP-2007 11:34:18:104] nsprecv: 68 75 74 64 6F 77 6E 20  |hutdown.|
[27-SEP-2007 11:34:18:104] nsprecv: 69 6E 20 70 72 6F 67 72  |in.progr|
[27-SEP-2007 11:34:18:104] nsprecv: 65 73 73 0A              |ess.    |

Net service name has LOAD_BALANCE set in description section

  (DESCRIPTION =
    (LOAD_BALANCE = yes)
    (ADDRESS = (PROTOCOL = TCP)(HOST = NodeA)(PORT = 1521))
    (ADDRESS = (PROTOCOL = TCP)(HOST = NodeB)(PORT = 1521))

Or has two description sections

  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(Host = NodeA)(Port = 1521))
      (CONNECT_DATA =
        (SERVICE_NAME = ORCL1)
      )
    )
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(Host = NodeB)(Port = 1521))
      (CONNECT_DATA =
        (SERVICE_NAME = ORCL2)

 

Cause

Error ORA-1033 is expected for connections when they attempt to connect to standby instance, because it is mounted and not open.

When LOAD_BALANCE is set, connections can load balance between the addresses in the net service name.

When there are two description sections in a net service name, Oracle Net will load balance between them.

Solution

Example is for service called failover

1. Setup the net service name, ensuring LOAD_BALANCE is not used and one has one description section.

 DGtest = 
  (DESCRIPTION = 
    (ADDRESS_LIST = 
      (ADDRESS = (PROTOCOL = TCP)(HOST = NodeA)(PORT = 1521)) 
      (ADDRESS = (PROTOCOL = TCP)(HOST = NodeB)(PORT = 1521)) 
    ) 
    (CONNECT_DATA = 
      (SERVICE_NAME = failover) 
      (SERVER = DEDICATED) 
        (FAILOVER_MODE = 
          (TYPE = session) 
          (METHOD = BASIC) 
          (RETRIES = 180) 
          (DELAY = 5) 
        ) 
      ) 
    ) 
  )

2. Create and start service

SQL> exec DBMS_SERVICE.CREATE_SERVICE (service_name => 'failover',network_name => 'failover',aq_ha_notifications => true,failover_method => 'BASIC', failover_type => 'SELECT',failover_retries => 180,failover_delay => 1);

PL/SQL procedure successfully completed.


SQL>exec dbms_service.start_service('failover');

PL/SQL procedure successfully completed.

3.Create a database trigger to ensure the service name is always the same, no matter which node's instance is the primary.

sqlplus / as sysdba

SQL> CREATE OR REPLACE TRIGGER manage_OCIservice
after startup on database
DECLARE
role VARCHAR(30);
BEGIN
SELECT DATABASE_ROLE INTO role FROM V$DATABASE;
IF role = 'PRIMARY' THEN
DBMS_SERVICE.START_SERVICE('failover');
ELSE
DBMS_SERVICE.STOP_SERVICE('failover');
END IF;
END;

PL/SQL procedure successfully completed.

4. Ensure the change is made on the standby with command.

SQL> Alter system archive log current ;

5. Listener service command lsnrctl services on primary will then show

Service "failover" has 1 instance(s).
  Instance "tom1", status READY, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:0 refused:0 state:ready
         LOCAL SERVER


This method ensures the service failover is only available on the primary node.The net service name DGtest works through the addresses in the address_list section, in order. If NodeA is the standby, then Node B will have the service failover and the connection will attempt to connect.

More information on Dataguard setup can be found in following articles:
Note 316740.1How to configure to let TAF work after Data Guard Switchover or Failover

http://www.oracle.com/technology/deploy/availability/htdocs/maa.htm
http://www.oracle.com/technology/deploy/availability/pdf/MAA_WP_10gR2_ClientFailoverBestPractices.pdf

 

 

 

------------------------------------------------------------------------------

QQ:492913789

Email:ahdba@qq.com

Blog: http://www.cndba.cn/dave 


网上资源: http://tianlesoftware.download.csdn.net

相关视频:http://blog.csdn.net/tianlesoftware/archive/2009/11/27/4886500.aspx

DBA1 群:62697716(); DBA2 群:62697977()

DBA3 群:62697850   DBA 超级群:63306533;    

聊天 群:40132017

--加群需要在备注说明Oracle表空间和数据文件的关系,否则拒绝申请

 

<think>好的,我现在需要解决用户提出的Oracle数据库中的ORA-00604和ORA-03180错误,特别是涉及Active DataGuard备用库序列值分配的问题。首先,我需要回忆这两个错误代码的含义。ORA-00604通常表示在递归SQL层发生了错误,可能由多种原因引起,比如权限问题、对象不存在或内部错误。而ORA-03180则指出在备用数据库上无法分配序列号,这可能是因为备用库处于只读状态,无法生成新的序列值。用户提到使用的是Active DataGuard,所以备用库应该是只读的,但可能应用了实时查询功能。接下来,我需要分析问题的根源。在DataGuard环境中,备用库通常是只读的,无法执行DML操作,包括序列的递增。当应用程序错误地尝试在备用库上获取序列值时,就会触发这些错误。这可能是因为连接配置错误,导致应用连接到了备用库而不是主库,或者在主备切换后未正确调整应用配置。 解决方案方面,首先需要确保应用程序始终连接到主库执行写操作,包括序列的获取。可以通过配置TNSNAMES.ora文件,将写操作定向到主库,读操作定向到备用库。另外,检查序列的配置,确认是否使用了ORDER或NOORDER选项。在RAC环境中,NOORDER可能更高效,但在Data Guard中可能需要调整。 此外,可能需要修改应用程序逻辑,在获取序列值时显式指定连接到主库。如果问题发生在主备切换后,应验证序列的当前值是否在切换后保持一致,必要时手动同步序列。如果使用12c及以上版本,可以考虑使用Identity列代替序列,简化管理。最后,需要预防措施,比如在应用层添加检查,确保只在主库执行写操作,并定期监控序列的使用情况。如果问题持续,可能需要查看详细的日志文件,如alert.log和跟踪文件,以获取更具体的错误信息,或者联系Oracle支持。生成相关问题的时候,需要考虑用户可能的后续疑问,比如如何配置TNSNAMES实现读写分离,如何检查序列的当前值,或者在主备切换后如何避免此类问题。还要涵盖更广泛的DataGuard配置问题和Oracle错误处理的一般方法。</think>### ORA-00604 和 ORA-03180 错误解决方案 #### 问题根源分析 在Oracle Active Data Guard环境中,备用库(Standby)默认处于只读模式。当应用程序尝试在备用库上执行序列(Sequence)的`NEXTVAL`操作时,会触发ORA-03180错误,并可能级联引发ORA-00604错误[^1][^2]。 #### 分步解决方案 1. **验证数据库角色** ```sql SELECT DATABASE_ROLE FROM V$DATABASE; ``` - 确保应用程序连接的是主库(PRIMARY)而非备用库(PHYSICAL STANDBY) 2. **配置连接隔离** - 在`TNSNAMES.ORA`中为读写操作单独配置主库连接别名: ``` PRIMARY_DB = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = primary_host)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = primary_service) ) ) ``` 3. **修改序列属性** - 对于需要跨节点同步的序列,添加`ORDER`属性: ```sql ALTER SEQUENCE your_sequence ORDER CACHE 20; ``` - 检查现有序列属性: ```sql SELECT SEQUENCE_NAME, ORDER_FLAG, CACHE_SIZE FROM DBA_SEQUENCES WHERE SEQUENCE_OWNER='YOUR_SCHEMA'; ``` 4. **应用层改造** ```java // 示例:Java应用中强制从主库获取序列值 @Transactional(readOnly = false) public Long getNextSequence() { return jdbcTemplate.queryForObject( "SELECT your_sequence.NEXTVAL FROM DUAL", Long.class); } ``` 5. **数据同步验证** - 在主库执行: ```sql SELECT your_sequence.CURRVAL FROM DUAL; ``` - 在备用库验证是否同步: ```sql SELECT your_sequence.CURRVAL FROM DUAL; ``` #### 高级配置方案 - **使用服务重定向**(12c+) ```sql ALTER DATABASE ADD SERVICE 'write_svc' AVAILABILITY_MAX = PERFORMANCE FAILOVER_TYPE = TRANSACTION REPLAY_INIT_TIME = 300 ROLE = PRIMARY; ``` - **启用序列代理**(18c+) ```sql ALTER SEQUENCE your_sequence PROXY FOR your_proxy_user@primary_db; ``` #### 预防措施 1. 在备用库创建触发器拦截序列操作: ```sql CREATE OR REPLACE TRIGGER block_sequence_dml BEFORE SELECT ON your_sequence DECLARE BEGIN IF SYS_CONTEXT('USERENV','DATABASE_ROLE') = 'PHYSICAL STANDBY' THEN RAISE_APPLICATION_ERROR(-20001, 'Sequence operations not allowed on standby'); END IF; END; ``` 2. 定期检查序列同步状态: ```sql SELECT DI.sequence_name, DI.current_value - SI.current_value AS diff FROM dba_sequences@primary_db DI JOIN dba_sequences SI ON DI.sequence_name = SI.sequence_name WHERE DI.sequence_owner = 'YOUR_SCHEMA'; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值