重庆思庄Oracle、Redhat认证学习论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 211|回复: 0
打印 上一主题 下一主题

[Oracle] ORA-604 ORA-16000 on Standby Opened Read Only

[复制链接]
跳转到指定楼层
楼主
发表于 2024-12-29 11:16:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
现象:
Tried to log into Standby database Opened Read Only as non-sysdba user via
SQLPLUS on the server:

It fails with the following errors:

SQL> conn <username>
Enter password:
ERROR:
ORA-00604: error occurred at recursive SQL level 1
ORA-16000: database open for read-only access
ORA-01017: invalid username/password; logon denied


更改:
These steps were taken on the PHYSICAL standby BEFORE the test was done.

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
SQL> ALTER DATABASE OPEN;
SQL> SELECT NAME, DATABASE_ROLE FROM V$DATABASE;

NAME DATABASE_ROLE
--------- ----------------
<NAME> PHYSICAL STANDBY

SQL> select log_mode,open_mode , database_role from v$database;

LOG_MODE OPEN_MODE DATABASE_ROLE
------------ ---------- ----------------
ARCHIVELOG READ ONLY PHYSICAL STANDBY


原因:
Cannot have failed_logon_attempts profiles set on an opened Read-only Standby Database. Oracle cannot write to the user$ table when the database is opened Read only.

To verify the issue, set events for the ora-604 and ora-16000:

Set the events on the standby.

  SQL> alter system set events '604 trace name errorstack level 10';
  SQL> alter system set events '16000 trace name errorstack level 10';
For 11g+, please set the events like:

  SQL> alter system set events '604 trace name errorstack level 10';
  SQL> alter system set events '16000 trace name errorstack level 3';




Reproduce the problem and upload the new trace files in the udump directory.

to unset the events:

  SQL> alter system set events '604 trace name errorstack off';
  SQL> alter system set events '16000 trace name errorstack off';


You will receive a Stack Trace like:

ksedmp ksddoa ksdpcg ksdpec ksfpec kgesev ksesec1 rpidrr rpidrv rpiexe ktsucu kqrcmt ktcrcm kziasfc kpolnb kpoauth opiodr ttcpip ...................

Current cursor: 0, pgadep: 0
Cursor Dump:
----------------------------------------
Cursor 1 (10386bc98): CURBOUND curiob: 103871080
curflg: 5 curpar: 0 curusr: 0 curses 5a97ec3e8
cursor name:
update user$ set name=:2,password=:3,datats#=:4,tempts#=:5,type#=:6,defrole=:7,resource$=:8,ptime=DECODE(to_char(:9, 'YYYY-MM-DD'), '0000-00-00', to_date(NULL), :9),exptime=DECODE(to_char(:10, 'YYYY-MM-DD'), '0000-00-00', to_date(NULL), :10),ltime=DECODE(to_char(:11, 'YYYY-MM-DD'), '0000-00-00', to_date(NULL), :11),astatus=:12, lcount=:13, defschclass=:14 where user#=:1
child pin: 0, child lock: 5ac621548, parent lock: 5ac6217f0
xscflg: 20100426, parent handle: 5bc588410, xscfl2: 5100400

-> Stack Trace functions:

kziasfc Set the FAILED_LOGIN_COUNT parameter of the user *
/
ktsucu insert, update, delete from user$ */


The ORA-16000 shows that the database is opened read-only. The ORA-1017 wants to update
the user$ table - FAILED_LOGIN_COUNT. This fails because the database isn't opened in read-write
mode, so that the internal tables (user$) can't be updated. This is the reason why the login never
is locked due to failed login.

In the above analysis it is established that the password profile does not work for a standby database in read only mode simply because of the fact no database writes can be done in read only, therefore the data dictionary (USER$) cannot be updated to log the failed login attempts

处理方法:
You will need to change the Profile on the Standby to not use Failed_logon_attempts by setting them to unlimited on the Primary(get passed through the archive redo logs to the Standby) or disable using profiles on the Standby. You can try auditing users via OS on the Standby instead.

处理步骤:

方法1:

1. On the Primary:

SQL> alter profile default limit failed_login_attempts unlimited ;

2. You can verify the change was made once the archivelogs have applied on the Standby by:


SQL> alter database open read only;
SQL> select RESOURCE_NAME,RESOURCE_TYPE,LIMIT from dba_profiles where profile='<userprofilename>';


方法2:

  1. Disable using profiles on the Standby database only, by auditing via the OS:

On the Standby:

    SQL> alter system set audit_trail='OS' scope=spfile;

     (or if using init file, set audit_trail='OS' in the init file)

     Restart the standby for the change to take effect.


方法3: Other cases that cause the ora-16000 on the Standby are:

1. Invalid Synonyms on the Primary

   If you see in the 16000 trace:

  ORA-16000: database open for read-only access
Current SQL statement for this session:
update syn$ set node=:2,owner=:3,name=:4 where obj#=:1

Solution:

On the Primary:

SQL> select object_name, object_type from dba_objects where status='INVALID' and object_type = 'SYNONYM';


Recompile the invalid synonyms



  2. Logon/Startup triggers

You normally will also receive the ORA-4088 with the ORA-16000 when it's a startup/logon trigger issue. You will just receive ORA-04088 when profiles are not involved and just startup/logon trigger issue.

<TRACE_FILE_NAME>.trc
==============================
Redo shipping client performing standby login
OCISessionBegin failed -1
.. Detailed OCI error val is 4088 and errmsg is 'ORA-04088: error during execution of trigger '<OWNER>.<TRIGGER_NAME>'
ORA-01403: no data found
ORA-06512: at line 6
'
*** 2009-03-31 08:33:58.688 62692 kcrr.c
Error 4088 received logging on to the standby
*** 2009-03-31 08:33:58.688 62692 kcrr.c
FAL[client, MRP0]: Error 4088 connecting to <DB_NAME> for fetching gap sequence
*** 2009-03-31 08:33:58.688
ksedmp: internal or fatal error
ORA-04088: error during execution of trigger '.'

Solution:

1) Disable the logon/startup trigger on the Primary or Standby, until you can fix it to not fire when the Standby database is open read only.

You can disable the startup trigger by setting the _system_trig_enabled=false parameter in the Standby's init.ora file.
Refer My Oracle Support Note 68636.1 and set the _system_trig_enabled = false
in Standby DB.

On the Primary:

  o Modify the Startup trigger to not fire when a database is opened read-only.

         i.e.  if v_database_role !='READ ONLY' then

  o Modify a Logon trigger to not fire for PUBLIC users.

         i.e. if v_username !='PUBLIC' then

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 支持支持 反对反对
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|重庆思庄Oracle、Redhat认证学习论坛 ( 渝ICP备12004239号-4 )

GMT+8, 2025-2-5 07:54 , Processed in 0.074861 second(s), 22 queries .

重庆思庄学习中心论坛-重庆思庄科技有限公司论坛

© 2001-2020

快速回复 返回顶部 返回列表