分类目录归档:数据库

Total insert collisions (ogg)

1、错误现象
Replicating from ECP.TAB_UUM_PACKAGE to RWGL.TAB_UUM_USER:
*** Total statistics since 2011-08-05 10:34:10 ***

Total inserts                               20.00
Total updates                                0.00
Total deletes                                0.00
Total discards                               0.00
Total operations                            20.00
Total insert collisions                     20.00

2、错误原因
RWGL.TAB_UUM_USER表上有insert触发器,导致失败。因为触发器使得插入操作为插入和触发器中的操作绑定为了一个整体,现在因为触发器失败,导致插入失败,而且还会丢失该条插入记录,需要查找出该条记录比较困难。

3、解决方案
采用自治事件结合异常捕获
自治事件使得触发器和插入操作相互分离,异常捕获记录触发器失败的原因,插入到日志表中,通过该表,可以查询查失败的记录,然后人工干预,触发器实例:

create or replace trigger ogg_t
  before insert on t_1
  for each row
declare
   tid NUMBER;
   err VARCHAR2(100);
   PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  SELECT t.id2 INTO tid FROM t_2 t WHERE NAME=:new.Name;
  INSERT INTO t_3 VALUES(tid,:new.name);
  COMMIT;
EXCEPTION
       WHEN TOO_MANY_ROWS THEN
         INSERT INTO t_error VALUES(:new.id,'TOO_MANY_ROWS');
         COMMIT;
        WHEN NO_DATA_FOUND THEN
           INSERT INTO t_error VALUES(:new.id,'NO_DATA_FOUND');
           COMMIT;
         WHEN OTHERS THEN
           err:=SUBSTR(SQLERRM(SQLCODE),1,100);
           INSERT INTO t_error VALUES(:new.id,err);
           COMMIT;
end ogg_t;

1)PRAGMA AUTONOMOUS_TRANSACTION;
自治事务,就是说触发器不管是成功,还是失败,数据库同步程序都能够同步成功数据到目标端

2)COMMIT;
因为采用了自治事件,所以begin end中的操作是独立与数据库中数据,需要单独提交

3)EXCEPTION
添加异常处理

4)INSERT INTO t_error VALUES(:new.id,’TOO_MANY_ROWS’);(类此语句,注意commit)
建立一张错误日志表(根据具体情况决定),如果触发器失败,把错误记录到该表中,以后出现问题查找很方便(要求:通过该表能够查询到那条语句的触发器执行失败。失败原因,失败时间,额外列(用于确定对应记录))

发表在 GoldenGate | 评论关闭

ORA-01012: not logged on

今天接到现场反馈,数据库出现ORA-01012: not logged on错误提示,这个问题上次也出现过一次,当时按照网上说的方法,直接重启数据库了,问题解决了,同时也导致因为数据库重启,现场破坏,而alert日志中无任何异常信息,所以不知从何处下手分析。这次我上数据库准备查看时,发现数据库已经正常,监控也显示正常,说明数据库已经恢复正常。从此我推理这个问题应该是外部因素导致,而不是数据库本身的bug,从而决定要找出该问题的原因来。有个重要的因素,该数据库是我几个月前因为undo损坏做过恢复的,查看相关参数,发现processes是默认值150,是不是该值导致的不敢肯定,因为一般process超了会报ORA-00020错误,而这次只有ORA-01012。但是心中还是没有底,总感觉这个的可能性最大,于是想通过试验来证实下自己的想法
1、数据库版本(10g结果相同)
SQL> select * from v$version where rownum=1;

BANNER
—————————————————————-
Oracle9i Enterprise Edition Release 9.2.0.4.0 – Production

2、创建pfile,修改processes,重启数据库,查看processes值
SQL> select name,value from v$parameter where name=’processes’;

NAME VALUE
——————– ——————–
processes 30

3、查看系统processes数量
SQL> select count(*) from v$process;

COUNT(*)
———-
13

4、添加数据库连接数(为了增加process数目)
[oracle@localhost ~]$ sqlplus chf/xifenfei

SQL*Plus: Release 9.2.0.4.0 – Production on Wed Jul 27 23:11:50 2011

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 – Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 – Production

SQL> !

5、重复3和4,发现当process数量为29时出现激动人心一幕
5.1)继续访问数据库
[oracle@localhost ~]$ sqlplus system/xifenfei

SQL*Plus: Release 9.2.0.4.0 – Production on Wed Jul 27 23:12:06 2011

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

ERROR:
ORA-00020: maximum number of processes (%s) exceeded

Enter user-name:

5.2)使用其他用户访问
[oracle@localhost ~]$ sqlplus /nolog

SQL*Plus: Release 9.2.0.4.0 – Production on Wed Jul 27 23:12:49 2011

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

SQL> conn / as sysdba
Connected to an idle instance.
SQL> select * from dual;
select * from dual
*
ERROR at line 1:
ORA-01012: not logged on

SQL> conn chf/xifenfei
ERROR:
ORA-00020: maximum number of processes (%s) exceeded

[oracle@localhost ~]$ sqlplus “/ as sysdba”

SQL*Plus: Release 9.2.0.4.0 – Production on Wed Jul 27 23:29:52 2011

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.

Connected.
SQL> select * from dual;
select * from dual
*
ERROR at line 1:
ORA-01012: not logged on
现象说明:
1)终于发现了ORA-01012错误,期待了很久。发现只有当sys登录系统,对数据库进行查询或者操作之时才会出现ORA-01012,其他用户只要一登录数据库就会提示ORA-00020错误。

2)当process达到数据库最大限时,sysdba登录系统是也显示不正常
2.1)当使用sqlplus “/ as sysdba”登录时,缺少:
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.4.0 – Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 – Production
2.2)当使用conn / as sysdba登录时,提示为:
Connected to an idle instance.

发表在 ORA-xxxxx | 标签为 | 2 条评论

ORA-01031: insufficient privileges

今天接到开发反馈,说数据库动态sql创建表语句无法执行,提示ORA-01031: insufficient privileges
1、数据库版本
SQL> select * from v$version where rownum=1;

BANNER
—————————————————————-
Oracle9i Enterprise Edition Release 9.2.0.4.0 – Production

2、创建用户并授权
SQL> create user test identified by xifenfei;

User created.

SQL> grant connect,resource to test;

Grant succeeded.

3、查看权限
SQL> SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE=’TEST’;

GRANTEE PRIVILEGE ADM
—————————— —————————————- —
TEST UNLIMITED TABLESPACE NO

SQL> SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTEE=’TEST’;

GRANTEE GRANTED_ROLE ADM DEF
—————————— —————————— — —
TEST CONNECT NO YES
TEST RESOURCE NO YES

SQL> CONN TEST/XIFENFEI
Connected.
SQL> SELECT * FROM SESSION_PRIVS;

PRIVILEGE
—————————————-
CREATE SESSION
ALTER SESSION
UNLIMITED TABLESPACE
CREATE TABLE
CREATE CLUSTER
CREATE SYNONYM
CREATE VIEW
CREATE SEQUENCE
CREATE DATABASE LINK
CREATE PROCEDURE
CREATE TRIGGER

PRIVILEGE
—————————————-
CREATE TYPE
CREATE OPERATOR
CREATE INDEXTYPE

14 rows selected.
注:目前create table权限是通过resource role授予test用户的

4、创建存储过程(Authid Current_User)
SQL> create or replace procedure create_table(t varchar2) Authid Current_User
2 is
3 P_SQL VARCHAR2(300);
4 BEGIN
5 P_SQL := ‘create table ‘||t||’ as select * from user_tables where 1=0′;
6 EXECUTE IMMEDIATE P_SQL;
END; 7
8 /

Procedure created.

5、执行存储过程
SQL> EXEC CREATE_table(‘a’);

PL/SQL procedure successfully completed.

6、重建存储过程(不包括Authid Current_User)
SQL> create or replace procedure create_table(t varchar2)
2 –Authid Current_User
3 is
4 P_SQL VARCHAR2(300);
5 BEGIN
6 P_SQL := ‘create table ‘||t||’ as select * from user_tables where 1=0′;
7 EXECUTE IMMEDIATE P_SQL;
8 END;
9 /

Procedure created.

SQL> EXEC CREATE_table(‘b’);
BEGIN CREATE_table(‘b’); END;

*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at “TEST.CREATE_TABLE”, line 7
ORA-06512: at line 1

7、授权(create table权限)
SQL> conn / as sysdba
Connected.
SQL> grant create table to test;

Grant succeeded.

SQL> conn test/xifenfei
Connected.
SQL> EXEC CREATE_table(‘c’);

PL/SQL procedure successfully completed.

8、查看结果
SQL> select * from tab;

TNAME TABTYPE CLUSTERID
—————————— ——- ———-
A TABLE
C TABLE

9、 查询资料
默认情况下,在调用存储过程用户的角色是不起作用的,即在执行存储过程时只有Public权限。所以如果被调用的存储过程中如果有execute immediate ‘create table..’语句,将会引发ORA-01031: insufficient privileges错误。
存储过程分为两种,即DR(Definer’s Rights ) Procedure和IR(Invoker’s Rights ) Procedure。为什么会有两种存储过程呢?其实考虑完下面的问题就清楚了。比如说用户hrch创建了删除表tar_table的存储过程drop_table(),当用户hrch调用时,即删除用户hrch下的表tar_table;如果是另一个用户scott调用呢?是删除用户scott下的tar_table表呢,还是删除用户hrch下的tar_table呢?另外,如果存储过程中包含建表语句,不管是用户hrch还是用户scott调用都会失败,因为Public没有建表权限,除非为Public grant建表权限。

10、动态sql中执行create table解决方案(10g也存在同样问题)
1)加上Authid Current_User
2)直接赋予create table to 该用户

11、匿名块的动态sql不在此限制中
SQL> conn / as sysdba
Connected.
SQL> SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE=’TEST’;

GRANTEE PRIVILEGE ADM
—————————— —————————————- —
TEST UNLIMITED TABLESPACE NO

SQL> CONN TEST/XIFENFEI
Connected.
SQL> DECLARE
2 P_SQL VARCHAR2(300);
3 BEGIN
4 P_SQL := ‘create table t_t as select * from user_tables where 1=0′;
5 EXECUTE IMMEDIATE P_SQL;
6 END;
7 /

PL/SQL procedure successfully completed.

发表在 ORA-xxxxx | 评论关闭