绕过win中服务开启oracle数据库

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:绕过win中服务开启oracle数据库

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

在win系统中,如果oracle数据库的服务没有启动,使用sqlplus登录,会报ORA-12560错误,数据库无法启动

C:\Users\XIFENFEI>sqlplus / as sysdba
SQL*Plus: Release 11.2.0.1.0 Production on 星期一 12月 19 20:33:27 2011
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
ERROR:
ORA-12560: TNS: 协议适配器错误
请输入用户名:

绕过服务启动数据库具体操作步骤如下:

1.当前oracle数据库服务OracleServiceXFF处于关闭状态

2.右键OracleServiceXFF服务属性
从这里我们可以看到”可执行文件的路径”,然后我们直接在dos(管理员权限,或者说有权限运行oracle的用户下),运行该命令

3.在dos中运行命令
这里提示”Press CTRL-C to exit server:”在你不想oracle被abort之前,请不要执行CTRL-C或者直接关闭该窗口

4.开启oracle数据库

至此在win服务器中绕过服务,直接启动oracle操作完成,这个多半是在因为不能正常开启服务,通过这种方式来排错。在生产环境中,请勿模仿,如出现问题,后果自负(数据库被abort)

Memory Notification: Library Cache Object loaded into SGA

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:Memory Notification: Library Cache Object loaded into SGA

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

0.环境

--系统环境
[oracle@bas bdump]$ more /etc/redhat-release
Red Hat Enterprise Linux AS release 4 (Nahant Update 7)
--数据库版本
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bi
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

1.alert日志信息

Sun Dec 18 02:03:38 2011
Memory Notification: Library Cache Object loaded into SGA
Heap size 7607K exceeds notification threshold (2048K)
Details in trace file /opt/app/oracle/admin/BAS/udump/bas_ora_29900.trc

2.bas_ora_29900.trc文件信息

[oracle@bas bdump]$ more  /opt/app/oracle/admin/BAS/udump/bas_ora_29900.trc
/opt/app/oracle/admin/BAS/udump/bas_ora_29900.trc
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
ORACLE_HOME = /opt/app/oracle/product/10.2.0/db_1
System name:    Linux
Node name:      bas
Release:        2.6.9-78.ELsmp
Version:        #1 SMP Wed Jul 9 15:46:26 EDT 2008
Machine:        x86_64
Instance name: BAS
Redo thread mounted by this instance: 1
Oracle process number: 34
Unix process pid: 29900, image: oracle@bas (TNS V1-V3)
*** 2011-12-18 02:03:35.244
*** SERVICE NAME:(SYS$USERS) 2011-12-18 02:03:35.229
*** SESSION ID:(5465.1) 2011-12-18 02:03:35.229
Memory Notification: Library Cache Object loaded into SGA
Heap size 5249K exceeds notification threshold (2048K)
LIBRARY OBJECT HANDLE: handle=25d38a9d8 mutex=0x25d38ab08(0)

3.警告原因

These are warning messages that should not cause the program responsible for these errors to fail.  They appear as a result of new event messaging mechanism and memory manager in 10g Release 2.
The meaning is that the process is just spending a lot of time in finding free memory extents during an allocate as the memory may be heavily fragmented.  Fragmentation in memory is impossible to eliminate completely, however, continued messages of large allocations in memory indicate there are tuning opportunities on the application.
The messages do not imply that an ORA-4031 is about to happen.

从这里可以看出来,这个只是分配大的内存块(超过_kgl_large_heap_warning_threshold参数值)的一个警告信息,不会对系统的性能以及ORA-4031产生什么影响,如果不是很在意这个警告,可以忽略

4.解决方法

In 10g we have a new undocumented parameter that sets the KGL heap size warning threshold.   This parameter was not present in 10gR1.  Warnings are written if heap size exceeds this threshold.
Set  _kgl_large_heap_warning_threshold  to a reasonable high value or zero to prevent these warning messages. Value needs to be set in bytes.
If you want to set this to 8192 (8192 * 1024) and are using an spfile:
(logged in as "/ as sysdba")
SQL> alter system set "_kgl_large_heap_warning_threshold"=8388608 scope=spfile ;
SQL> shutdown immediate
SQL> startup
If using an "old-style" init parameter,
Edit the init parameter file and add
_kgl_large_heap_warning_threshold=8388608
NOTE:
1)The default threshold in 10.2.0.1 is 2M.   So these messages could show up frequently in some application environments.
2)In 10.2.0.2,  the threshold was increased to 50MB after regression tests, so this should be a reasonable and recommended value.

参考MOS:330239.1

Oracle 10g绕过密码登陆数据库

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:Oracle 10g绕过密码登陆数据库

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

0、数据库版本

SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production

1、Oracle 10g密码加密猜测
user$表中的password=hash(user||password)

SQL> create user xff identified by xifenfei;
User created.
SQL> create user xf identified by fxifenfei;
User created.
SQL> select name,password from user$ where name in('XF','XFF');
NAME                           PASSWORD
------------------------------ ------------------------------
XF                             1B60F4BFF1DAB500
XFF                            1B60F4BFF1DAB500

2、测试通过修改user$.password饶过oracle密码登陆

--创建两个可以登陆用户
SQL> grant connect to ab identified by xifenfei;
Grant succeeded.
SQL> grant connect to abc identified by xifenfei;
Grant succeeded.
--查看用户名和password内容
SQL> select user#,name,password from user$ where name in ('AB','ABC');
     USER# NAME                           PASSWORD
---------- ------------------------------ ------------------------------
        63 AB                             7AF07A2EFB054758
        64 ABC                            40C0E6EE497444B7
--修改ab用户的password内容和abc相同,即ab用户对应的密码应该为cxifenfei
SQL> update user$ set password='40C0E6EE497444B7' where user#=63;
1 row updated.
SQL> commit;
Commit complete.
SQL> select user#,name,password from user$ where name in ('AB','ABC');
     USER# NAME                           PASSWORD
---------- ------------------------------ ------------------------------
        63 AB                             40C0E6EE497444B7
        64 ABC                            40C0E6EE497444B7
--修改后登陆失败
SQL> conn ab/cxifenfei
ERROR:
ORA-01017: 用户名/口令无效; 登录被拒绝
Warning: You are no longer connected to ORACLE.
SQL> conn / as sysdba
Connected.
--ab的user$.password被重设为原先值
SQL> select user#,name,password from user$ where name in ('AB','ABC');
     USER# NAME                           PASSWORD
---------- ------------------------------ ------------------------------
        63 AB                             7AF07A2EFB054758
        64 ABC                            40C0E6EE497444B7
SQL>  update user$ set password='40C0E6EE497444B7' where user#=63;
1 row updated.
SQL> commit;
Commit complete.
SQL> select user#,name,password from user$ where name in ('AB','ABC');
     USER# NAME                           PASSWORD
---------- ------------------------------ ------------------------------
        63 AB                             40C0E6EE497444B7
        64 ABC                            40C0E6EE497444B7
--刷新databuffer和shared_pool
SQL> alter system flush buffer_cache ;
System altered.
SQL> alter system flush shared_buffer;
alter system flush shared_buffer
*
ERROR at line 1:
ORA-02000: missing SHARED_POOL/BUFFER_CACHE/GLOBAL CONTEXT keyword
SQL> alter system flush shared_pool;
System altered.
--修改ab的密码为cxifenfei成功
SQL> conn ab/cxifenfei
Connected.
SQL> show user;
USER is "AB"

3、绕过密码登陆数据库方法
1)建立一个和你需要登陆用户相似用户(一般是末尾多一个或者几个字符)
2)查询建立用户的user$.password,并修改你需要的用户的password
3)刷新data buffer和shared pool
4)使用你建立的用户多出在字符串+你建立用户的密码登陆你需要登陆用户

kkjcre1p: unable to spawn jobq slave process, error 1089

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:kkjcre1p: unable to spawn jobq slave process, error 1089

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

闲着无聊,看历史的alert文件,发现kkjcre1p: unable to spawn jobq slave process, error 1089警告

Thu Jul  8 21:23:39 2010
Starting background process CJQ0
CJQ0 started with pid=18, OS id=9019
Thu Jul  8 21:23:39 2010
Shutting down instance: further logons disabled
Thu Jul  8 21:23:42 2010
kkjcre1p: unable to spawn jobq slave process, error 1089
………………
Thu Jul  8 21:23:57 2010
kkjcre1p: unable to spawn jobq slave process, error 1089
Thu Jul  8 21:23:59 2010
Stopping background process QMNC
Thu Jul  8 21:23:59 2010
Stopping background process CJQ0
Thu Jul  8 21:24:01 2010
Stopping background process MMNL
Thu Jul  8 21:24:02 2010
Stopping background process MMON
Thu Jul  8 21:24:03 2010
Shutting down instance (immediate)
License high water mark = 1
Waiting for dispatcher 'D000' to shutdown
All dispatchers and shared servers shutdown
Thu Jul  8 21:24:05 2010
ALTER DATABASE CLOSE NORMAL
Thu Jul  8 21:24:05 2010
SMON: disabling tx recovery
SMON: disabling cache recovery
Thu Jul  8 21:24:05 2010
Shutting down archive processes
Archiving is disabled
Archive process shutdown avoided: 0 active
Thread 1 closed at log sequence 2
Successful close of redo thread 1
Thu Jul  8 21:24:05 2010
Completed: ALTER DATABASE CLOSE NORMAL
Thu Jul  8 21:24:05 2010
ALTER DATABASE DISMOUNT
Completed: ALTER DATABASE DISMOUNT
ARCH: Archival disabled due to shutdown: 1089
Shutting down archive processes
Archiving is disabled
Archive process shutdown avoided: 0 active
ARCH: Archival disabled due to shutdown: 1089
Shutting down archive processes
Archiving is disabled
Archive process shutdown avoided: 0 active

警告原因
If a job is about to be spawned when shutdown of database is in progress, you will see these errors in the alert log file and this is perfectly valid.

解决方法
1、这个警告可以安全的忽略
There is no harm at all because of this warning being logged to the alert.log The Error can be safely ignored as the job coordinator process tried to spawn a job slave when the Shutdown was in progress.

2、设置_JOB_QUEUE_INTERVAL更大值,减少出现该警告概率
One workaround that we can suggest is to set an underscore parameter
_JOB_QUEUE_INTERVAL=120 or greater value
The default value is 60 but when we change to 120 there are less chances of getting the above warnings in the alert log file.
Kkjcre1p: Unable To Spawn Jobq Slave Process, Error 1089 [ID 344275.1]

回收dba中alter system处理方法

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:回收dba中alter system处理方法

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

今天在pub上看到一个问题,一个朋友想回收dba的alter system权限,直接回收这个系统权限从dba的做法是不推荐使用,因为修改了系统默认的dba角色所具有的系统权限,可能会导致未知的后果。好的做法是创建新的角色,使其有dba中除alter system之外的所有权限。
1、数据库版本

SQL> select * from v$version;
BANNER
-------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for 32-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

2、创建角色并授权

SQL> create role xifenfei;
角色已创建。
SQL> declare
  2  cursor cur is select privilege from role_sys_privs where role='DBA'
  3  AND PRIVILEGE NOT IN ('ALTER SYSTEM','ADMINISTER RESOURCE MANAGER');
  4  BEGIN
  5    FOR C in cur loop
  6    EXECUTE IMMEDIATE  'grant '||c.privilege||' to xifenfei';
  7    END loop;
  8  END;
  9  /
PL/SQL 过程已成功完成。
SQL> SELECT PRIVILEGE FROM ROLE_SYS_PRIVS
  2  WHERE ROLE ='DBA' AND PRIVILEGE NOT IN(
  3  SELECT PRIVILEGE FROM ROLE_SYS_PRIVS
  4  WHERE ROLE ='XIFENFEI'
  5  );
PRIVILEGE
----------------------------------------
ALTER SYSTEM
ADMINISTER RESOURCE MANAGER

说明:授予创建角色出ALTER SYSTEM和ADMINISTER RESOURCE MANAGER系统权限之外的所有权限

3、创建用户并授权角色

SQL> create user chf_xff identified by xifenfei;
用户已创建。
SQL> grant xifenfei to chf_xff;
授权成功。

4、单独授予ADMINISTER RESOURCE MANAGER权限

SQL> exec dbms_resource_manager_privs.grant_system_privilege(
   2 grantee_name => 'CHF_XFF',admin_option => false);
PL/SQL 过程已成功完成。
SQL> CONN chf_xff/xifenfei
已连接。
SQL> SELECT * FROM SESSION_PRIVS WHERE
  2  PRIVILEGE ='ADMINISTER RESOURCE MANAGER';
PRIVILEGE
----------------------------------------
ADMINISTER RESOURCE MANAGER

说明:
1)通过授权xifenfei角色和ADMINISTER RESOURCE MANAGER权限,完成回收dba中的alter system权限要求。
2)如果只有个别用户有这样的需求,那么可以直接生成批量授权语句实现,而不用建立类此xifenfei这样的角色。

5、为何单独授予ADMINISTER RESOURCE MANAGER权限

SQL> CONN / AS SYSDBA
已连接。
SQL> GRANT ADMINISTER RESOURCE MANAGER TO CHF_XFF;
GRANT ADMINISTER RESOURCE MANAGER TO CHF_XFF
      *
第 1 行出现错误:
ORA-00990: 权限缺失或无效

说明:ADMINISTER RESOURCE MANAGER这个系统权限在10g及其以后版本中,就不能直接使用GRANT/REVOKE直接授权/回收权限,而必面使用dbms_resource_manager_privs.grant_system_privilege和revoke_system_privilege过程进行处理。

删除Oracle数据文件/临时文件

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:删除Oracle数据文件/临时文件

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

有些时候,想删除一个数据文件(临时文件),在10g之前的版本,要删除一个数据文件,必须删除该数据文件所属的表空间(特殊处理方法除外)。不太懂数据库的朋友直接os级别删除数据文件,导致数据库不能正常启动;稍微等点数据库的朋友,会先offline数据文件,然后os级别删除,但是这条数据文件的记录还保留在数据字典中,不爽(特殊处理办法见:清除离线数据文件记录)。在10g及其以后版本中,oracle提供了alter tablespace talbespace_name drop datafile/tempfile path/file_id进行删除某个数据文件

一、删除数据文件

[oracle@ECP-UC-DB1 ~]$ sqlplus / as sysdba
SQL*Plus: Release 10.2.0.4.0 - Production on Thu Dec 8 11:22:38 2011
Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> col tablespace_name for a20
SQL> col file_name for a50
SQL> set line 120
SQL> select file_id,file_name,tablespace_name
   2 from dba_data_files order by tablespace_name;
   FILE_ID FILE_NAME                                          TABLESPACE_NAME
---------- -------------------------------------------------- --------------------
         9 /opt/oracle/oradata/test/odu01.dbf                 ODU
        10 /opt/oracle/oradata/test/odu03.dbf                 ODU
         8 /opt/oracle/oradata/test/odu02.dbf                 ODU
         3 /opt/oracle/oradata/test/sysaux01.dbf              SYSAUX
         1 /opt/oracle/oradata/test/system01.dbf              SYSTEM
         2 /opt/oracle/oradata/test/undotbs01.dbf             UNDOTBS1
         5 /opt/oracle/oradata/test/user32g.dbf               USERS
         7 /opt/oracle/oradata/test/user02.dbf                USERS
         4 /opt/oracle/oradata/test/users01.dbf               USERS
         6 /opt/oracle/oradata/test/xifenfei01.dbf            XFF
        11 /opt/oracle/oradata/test/xifenfei03.dbf            XFF
11 rows selected.
SQL> !ls -l /opt/oracle/oradata/test/*.dbf
-rw-r----- 1 oracle oinstall   104865792 Dec  8 00:05 /opt/oracle/oradata/test/odu01.dbf
-rw-r----- 1 oracle oinstall 11282685952 Dec  8 00:05 /opt/oracle/oradata/test/odu02.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 00:05 /opt/oracle/oradata/test/odu03.dbf
-rw-r----- 1 oracle oinstall   387981312 Dec  8 12:36 /opt/oracle/oradata/test/sysaux01.dbf
-rw-r----- 1 oracle oinstall   534781952 Dec  8 12:45 /opt/oracle/oradata/test/system01.dbf
-rw-r----- 1 oracle oinstall   104865792 Dec  7 22:01 /opt/oracle/oradata/test/temp01.dbf
-rw-r----- 1 oracle oinstall  1289756672 Dec  8 12:45 /opt/oracle/oradata/test/undotbs01.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 00:05 /opt/oracle/oradata/test/user02.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 00:05 /opt/oracle/oradata/test/user32g.dbf
-rw-r----- 1 oracle oinstall     5251072 Dec  8 00:05 /opt/oracle/oradata/test/users01.dbf
-rw-r----- 1 oracle oinstall    20979712 Dec  8 00:05 /opt/oracle/oradata/test/xifenfei01.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 00:05 /opt/oracle/oradata/test/xifenfei03.dbf
SQL> alter tablespace xff drop datafile 11;
alter tablespace xff drop datafile 11
*
ERROR at line 1:
ORA-03262: the file is non-empty
SQL> col segment_name for a20
SQL> select owner,SEGMENT_NAME,FILE_ID,BLOCKS from dba_extents
  2  where file_id=11;
OWNER                          SEGMENT_NAME            FILE_ID     BLOCKS
------------------------------ -------------------- ---------- ----------
CHF                            XFF_TEST                     11          8
CHF                            XFF_TEST                     11        128
CHF                            XFF_TEST                     11        128
CHF                            T_XFF                        11        128
CHF                            T_XFF                        11        128
SQL> alter table chf.xff_test move tablespace users;
Table altered.
SQL> alter table chf.t_xff move tablespace users;
Table altered.
SQL> select owner,SEGMENT_NAME,FILE_ID,BLOCKS from dba_extents
  2  where file_id=11;
no rows selected
SQL> alter tablespace xff drop datafile 11;
Tablespace altered.
SQL> select file_id,file_name,tablespace_name
  2  from dba_data_files order by tablespace_name;
   FILE_ID FILE_NAME                                          TABLESPACE_NAME
---------- -------------------------------------------------- --------------------
         9 /opt/oracle/oradata/test/odu01.dbf                 ODU
        10 /opt/oracle/oradata/test/odu03.dbf                 ODU
         8 /opt/oracle/oradata/test/odu02.dbf                 ODU
         3 /opt/oracle/oradata/test/sysaux01.dbf              SYSAUX
         1 /opt/oracle/oradata/test/system01.dbf              SYSTEM
         2 /opt/oracle/oradata/test/undotbs01.dbf             UNDOTBS1
         4 /opt/oracle/oradata/test/users01.dbf               USERS
         7 /opt/oracle/oradata/test/user02.dbf                USERS
         5 /opt/oracle/oradata/test/user32g.dbf               USERS
         6 /opt/oracle/oradata/test/xifenfei01.dbf            XFF
10 rows selected.
SQL> !ls -l /opt/oracle/oradata/test/*.dbf
-rw-r----- 1 oracle oinstall   104865792 Dec  8 00:05 /opt/oracle/oradata/test/odu01.dbf
-rw-r----- 1 oracle oinstall 11282685952 Dec  8 00:05 /opt/oracle/oradata/test/odu02.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 00:05 /opt/oracle/oradata/test/odu03.dbf
-rw-r----- 1 oracle oinstall   387981312 Dec  8 12:36 /opt/oracle/oradata/test/sysaux01.dbf
-rw-r----- 1 oracle oinstall   534781952 Dec  8 12:45 /opt/oracle/oradata/test/system01.dbf
-rw-r----- 1 oracle oinstall   104865792 Dec  7 22:01 /opt/oracle/oradata/test/temp01.dbf
-rw-r----- 1 oracle oinstall  1289756672 Dec  8 12:45 /opt/oracle/oradata/test/undotbs01.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 12:52 /opt/oracle/oradata/test/user02.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 12:52 /opt/oracle/oradata/test/user32g.dbf
-rw-r----- 1 oracle oinstall     5251072 Dec  8 12:52 /opt/oracle/oradata/test/users01.dbf
-rw-r----- 1 oracle oinstall    20979712 Dec  8 12:52 /opt/oracle/oradata/test/xifenfei01.dbf

二、删除临时表空间文件

SQL> alter  tablespace temp add tempfile '/opt/oracle/oradata/test/xff_temp02.dbf' size 10m;
Tablespace altered.
SQL> select file_id,file_name,tablespace_name from dba_temp_files;
   FILE_ID FILE_NAME                                          TABLESPACE_NAME
---------- -------------------------------------------------- --------------------
         2 /opt/oracle/oradata/test/xff_temp02.dbf            TEMP
         1 /opt/oracle/oradata/test/temp01.dbf                TEMP
SQL> !ls -l /opt/oracle/oradata/test/*.dbf
-rw-r----- 1 oracle oinstall   104865792 Dec  8 00:05 /opt/oracle/oradata/test/odu01.dbf
-rw-r----- 1 oracle oinstall 11282685952 Dec  8 00:05 /opt/oracle/oradata/test/odu02.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 00:05 /opt/oracle/oradata/test/odu03.dbf
-rw-r----- 1 oracle oinstall   387981312 Dec  8 13:00 /opt/oracle/oradata/test/sysaux01.dbf
-rw-r----- 1 oracle oinstall   534781952 Dec  8 12:58 /opt/oracle/oradata/test/system01.dbf
-rw-r----- 1 oracle oinstall   104865792 Dec  7 22:01 /opt/oracle/oradata/test/temp01.dbf
-rw-r----- 1 oracle oinstall  1289756672 Dec  8 12:57 /opt/oracle/oradata/test/undotbs01.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 12:57 /opt/oracle/oradata/test/user02.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 12:57 /opt/oracle/oradata/test/user32g.dbf
-rw-r----- 1 oracle oinstall     5251072 Dec  8 12:57 /opt/oracle/oradata/test/users01.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 13:00 /opt/oracle/oradata/test/xff_temp02.dbf
-rw-r----- 1 oracle oinstall    20979712 Dec  8 12:57 /opt/oracle/oradata/test/xifenfei01.dbf
SQL> alter tablespace temp drop tempfile 2;
Tablespace altered.
SQL> !ls -l /opt/oracle/oradata/test/*.dbf
-rw-r----- 1 oracle oinstall   104865792 Dec  8 00:05 /opt/oracle/oradata/test/odu01.dbf
-rw-r----- 1 oracle oinstall 11282685952 Dec  8 00:05 /opt/oracle/oradata/test/odu02.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 00:05 /opt/oracle/oradata/test/odu03.dbf
-rw-r----- 1 oracle oinstall   387981312 Dec  8 13:00 /opt/oracle/oradata/test/sysaux01.dbf
-rw-r----- 1 oracle oinstall   534781952 Dec  8 12:58 /opt/oracle/oradata/test/system01.dbf
-rw-r----- 1 oracle oinstall   104865792 Dec  7 22:01 /opt/oracle/oradata/test/temp01.dbf
-rw-r----- 1 oracle oinstall  1289756672 Dec  8 12:57 /opt/oracle/oradata/test/undotbs01.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 12:57 /opt/oracle/oradata/test/user02.dbf
-rw-r----- 1 oracle oinstall    10493952 Dec  8 12:57 /opt/oracle/oradata/test/user32g.dbf
-rw-r----- 1 oracle oinstall     5251072 Dec  8 12:57 /opt/oracle/oradata/test/users01.dbf
-rw-r----- 1 oracle oinstall    20979712 Dec  8 12:57 /opt/oracle/oradata/test/xifenfei01.dbf

三、注意事项
1、Oracle Database 10g Release 2及其以上版本
2、删除数据文件从数据库和系统
3、数据文件必须为空
4、数据文件不是对应表空间的最后一个
5、不能删除只读表空间中数据文件
6、不能删除system中数据文件
7、不能删除本地管理的offline表空间数据文件

V$PWFILE_USERS和密码文件关系(续)

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:V$PWFILE_USERS和密码文件关系(续)

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

1、验证密码文件已经修改

SQL> create user xff01 identified by xifenfei;
User created.
SQL> grant sysdba to xff01;
Grant succeeded.
SQL> !md5sum $ORACLE_HOME/dbs/orapwora11g
04cedb56b62d94fd7e14124619722348  /opt/oracle/product/11.2.0/db_1/dbs/orapwora11g
SQL> !strings /opt/oracle/product/11.2.0/db_1/dbs/orapwora11g
]\[Z
ORACLE Remote Password file
INTERNAL
A1174901D667F113
18698BFD1A045BCC
XFF01
D32693095588EF4F
SQL> revoke sysdba from xff01;
Revoke succeeded.
SQL> !strings /opt/oracle/product/11.2.0/db_1/dbs/orapwora11g
]\[Z
ORACLE Remote Password file
INTERNAL
A1174901D667F113
18698BFD1A045BCC
XFF01
D32693095588EF4F
SQL> !md5sum $ORACLE_HOME/dbs/orapwora11g
1f6d120acb913a1877cfb0ab57702744  /opt/oracle/product/11.2.0/db_1/dbs/orapwora11g

2、查看基表

SQL> col owner for a20
SQL> col object_name for a30
SQL> SELECT owner,object_name,object_type FROM DBA_objects WHERE object_NAME ='V$PWFILE_USERS';
OWNER                OBJECT_NAME                    OBJECT_TYPE
-------------------- ------------------------------ -------------------
PUBLIC               V$PWFILE_USERS                 SYNONYM
SQL> SELECT table_owner,TABLE_name FROM Dba_Synonyms a WHERE a.synonym_name='V$PWFILE_USERS';
TABLE_OWNER                    TABLE_NAME
------------------------------ ------------------------------
SYS                            V_$PWFILE_USERS
SQL> SELECT owner,object_name,object_type FROM dba_objects WHERE object_name='V_$PWFILE_USERS';
OWNER                OBJECT_NAME                    OBJECT_TYPE
-------------------- ------------------------------ -------------------
SYS                  V_$PWFILE_USERS                VIEW
SQL> set long 1000
SQL> set line 200
SQL> SELECT dbms_metadata.get_ddl('VIEW','V_$PWFILE_USERS','SYS') FROM DUAL;
DBMS_METADATA.GET_DDL('VIEW','V_$PWFILE_USERS','SYS')
--------------------------------------------------------------------------------
  CREATE OR REPLACE FORCE VIEW "SYS"."V_$PWFILE_USERS" ("USERNAME", "SYSDBA", "SYSOPER", "SYSASM") AS
  select "USERNAME","SYSDBA","SYSOPER","SYSASM" from v$pwfile_users
SQL> select * from v$fixed_table where name ='V$PWFILE_USERS';
NAME                            OBJECT_ID TYPE   TABLE_NUM
------------------------------ ---------- ----- ----------
V$PWFILE_USERS                 4294951116 VIEW       65537
SQL> select VIEW_DEFINITION from v$fixed_view_definition where view_name='V$PWFILE_USERS';
VIEW_DEFINITION
--------------------------------------------------------------------------------------------------------
select  USERNAME , SYSDBA , SYSOPER, SYSASM from GV$PWFILE_USERS where inst_id = USERENV('Instance')
SQL> select VIEW_DEFINITION from v$fixed_view_definition where view_name='GV$PWFILE_USERS';
VIEW_DEFINITION
------------------------------------------------------------------------------------------------------------
select inst_id,username,decode(sysdba,1,'TRUE','FALSE'),  decode(sysoper,1,'TRUE','FALSE'),
 decode(sysasm,1,'TRUE','FALSE')  from x$kzsrt where valid=1  and username != 'INTERNAL'
SQL> set line 100
SQL> desc x$kzsrt
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 ADDR                                                           RAW(8)
 INDX                                                           NUMBER
 INST_ID                                                        NUMBER
 USERNAME                                                       VARCHAR2(30)
 SYSDBA                                                         NUMBER
 SYSOPER                                                        NUMBER
 SYSASM                                                         NUMBER
 VALID                                                          NUMBER
SQL> col username for a10
SQL> select * from x$kzsrt;
ADDR                   INDX    INST_ID USERNAME       SYSDBA    SYSOPER     SYSASM      VALID
---------------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
00002B9563678690          0          1 INTERNAL            1          1          0          1
00002B9563678690          1          1 SYS                 1          1          0          1
00002B9563678690          2          1 XFF01               0          0          0          0

从这里可以看出V$PWFILE_USERS视图的基表是x$kzsrt,这里和我们查看的密码文件一样,这些记录都存在,而是在密码文件中有不被strings显示的字符表示了账号是否启用,x$kzsrt.valid用1和0标示
上篇:V$PWFILE_USERS和密码文件关系

Oracle分布式事务故障处理

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:Oracle分布式事务故障处理

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

分布式事务,简单来说,是指一个事务在本地和远程执行,本地需要等待确认远程的事务结束后,进行下一步本地的操作。如通过dblink update远程数据库的一行记录,如果在执行过程中网络异常,或者其他事件导致本地数据库无法得知远程数据库的执行情况,此时就会发生in doublt的报错。此时需要dba介入,且需要分多种情况进行处理。分布式事务在commit提交时候,会经历3个阶段:
1.PREPARE PHASE
1.1 决定哪个数据库为commit point site。(注,参数文件中commit_point_strength值高的那个数据库为commit point site)
1.2 全局协调者(Global Coordinator)要求所有的点(除commit point site外)做好commit或者rollback的准备。此时,对分布式事务的表加锁。
1.3 所有分布式事务的节点将它的scn告知全局协调者。
1.4 全局协调者取各个点的最大的scn作为分布式事务的scn。(eygle在这篇文章中也测试过)
至此,所有的点都完成了准备工作,我们开始进入COMMIT PHASE阶段,此时除commit point site点外所有点的事务均为in doubt状态,直到COMMIT PHASE阶段结束。
如果数据库在此阶段出现问题,我们查询(假设远程数据库为commit point site,且本地数据库为Global Coordinator):
本地:

select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_ID          STATE
---------------------- ----------------
2.12.64845              collecting

远程:

select local_tran_id,state from dba_2pc_pending;
no rows selected

即表示本地数据库要求其他点做好commit或者rollback准备,现在正在“收集”其他点的数据库的返回信息,但是远程数据库未知状态(in doubt)。我们需要将本地的Global Coordinator的状态清除掉:

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');

或者我们在查询的时候发现是如下的状态:
本地:

select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_ID          STATE
---------------------- ----------------
2.12.64845             prepared

远程:

select local_tran_id,state from dba_2pc_pending;
no rows selected

即表示本地Global Coordinator已经做好准备,已经将分布式锁放到各个事务的表上,但是远程数据库的状态再次未知(in doubt),我们需要手工的将本地的transaction rollback掉,并且清除分布式事务信息:
本地:

rollback force 'local_tran_id';
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');

2.COMMIT PHASE
2.1 Global Coordinator将最大scn传到commit point site,要求其commit。
2.2 commit point尝试commit或者rollback。分布式事务锁释放。
2.3 commit point通知Global Coordinator已经commit。
2.4 Global Coordinator通知分布式事务的所有点进行commit。
如果数据库在此阶段出现问题,我们查询
本地:

select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_ID          STATE
---------------------- ----------------
2.12.64845             prepared

远程:

select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_ID          STATE
---------------------- ----------------
1.92.66874             commited

即远程数据库可能已经commit,但是本地Global Coordinator未知远程数据库的状态,还是处于prepare的状态。我们需要在如下处理:
本地:

commit force 'local_tran_id';
execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');

远程:

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');

或者我们在查询的时候发现是如下的状态:
本地:

select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_ID          STATE
---------------------- ----------------
2.12.64845            commited

远程:

select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_ID          STATE
---------------------- ----------------
1.92.66874             commited

即远程数据库和本地数据库均已经完成commit,但是分布式事务的信息尚未清除,我们需要在本地和远程运行:
本地:

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');

远程:

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');

3.FORGET PHASE
3.1 参与的点通知commit point site他们已经完成commit,commit point site就能忘记(forget)这个事务。
3.2 commit point site在远程数据库上清除分布式事务信息。
3.3 commit point site通知Global Coordinator可以清除本地的分布式事务信息。
3.4 Global Coordinator清除分布式事务信息。
此时如果出现问题,我们查询:
本地:

select local_tran_id,state from dba_2pc_pending;
LOCAL_TRAN_ID          STATE
---------------------- ----------------
2.12.64845            commited

远程:

select local_tran_id,state from dba_2pc_pending;
no rows selected

即远程commit point site已经完成commit,通知Global Coordinator清除本地的分布式事务信息,但是Global Coordinator没有收到该信息。我们需要这样处理:
本地:

execute DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('local_tran_id');

综上,分布式事务的依次状态为:

phase       local_state    remote_state       action
----------- ---------- ------------------  --------------------------------------------
prepare     collecting       /              本地DBMS_TRANSACTION.PURGE_LOST_DB_ENTRY
            prepared         /              本地rollback force后PURGE_LOST_DB_ENTRY
commit      prepared        commited        本地commit force后本地和远程均PURGE
            commited        commited        本地和远程均PURGE_LOST_DB_ENTRY
forget      commited         /              本地PURGE_LOST_DB_ENTRY

另,当我们遇到使用rollback/commit force的时候,无法正常的清除分布式事务的信息,会报错ORA-02058: no prepared transaction found with ID X.XX.XXXXX时,我们需要通过手工方式来清除该信息。
(注,以下方式修改数据字典,存在风险,使用前请备份好你的数据库)
情况1,在dba_2pc表中还有事务记录,但是实际已经不存在该事务了:

select local_tran_id, state from dba_2pc_pending;
LOCAL_TRAN_ID          STATE
---------------------- ----------------
1.92.66874             prepared

(注:’1.92.66874′的结构为rbs#, slot#, wrap#,此事务在rollback segment #1)
我们再用如下语句找出使用rollback segment #1且状态是active的transaction:

SELECT KTUXEUSN, KTUXESLT, KTUXESQN, /* Transaction ID */
       KTUXESTA Status,
       KTUXECFL Flags
FROM x$ktuxe
WHERE ktuxesta!='INACTIVE'
      AND ktuxeusn= 1; <== 这是rollback segment#,即rbs#
no rows selected

因此我们在rollback force的时候会报错:
ORA-02058: no prepared transaction found with ID 1.92.66874
我们需要如下处理:

set transaction use rollback segment SYSTEM;
delete from sys.pending_trans$
  where local_tran_id = '1.92.66874';
delete from sys.pending_sessions$ where local_tran_id = '1.92.66874';
delete from sys.pending_sub_sessions$ where local_tran_id = '1.92.66874';
commit;

情况2,这种情况比较少见,在dba_2pc表中无法查到分布式事务信息,但是实际上却是存在该分布式事务的:
我们在alertlog中可以看到:
ORA-1591: lock held by in-doubt distributed transaction 1.92.66874
我们查询dba_2pc的表,发现没有分布式事务信息:

select local_tran_id, state from dba_2pc_pending
where local_tran_id='1.92.66874';
no rows selected

但是去查实际的rollback segment信息,却发现有prepared状态的分布式事务存在:

SELECT KTUXEUSN, KTUXESLT, KTUXESQN, /* Transaction ID */
       KTUXESTA Status,
       KTUXECFL Flags
FROM x$ktuxe
WHERE ktuxesta!='INACTIVE'
      AND ktuxeusn= 1;
  KTUXEUSN   KTUXESLT   KTUXESQN STATUS           FLAGS
---------- ---------- ---------- ---------------- ------------------------
         1         92      66874 PREPARED         SCO|COL|REV|DEAD

我们无法做commit force或者rollback force:

rollback force '1.92.66874';
ORA-02058: no prepared transaction found with ID 1.92.66874

我们用如下的方式手工清理:

alter system disable distributed recovery;
insert into pending_trans$ (
    LOCAL_TRAN_ID,
    GLOBAL_TRAN_FMT,
    GLOBAL_ORACLE_ID,
    STATE,
    STATUS,
    SESSION_VECTOR,
    RECO_VECTOR,
    TYPE#,
    FAIL_TIME,
    RECO_TIME)
values( '1.92.66874', /* <== 此处为你的local tran id */
    306206,                  /*                                         */
    'XXXXXXX.12345.1.2.3',   /*  这些值不必更改,   */
    'prepared','P',          /*  是静态参数,可以直接   */
    hextoraw( '00000001' ),  /*  在这个sql中使用                             */
    hextoraw( '00000000' ),  /*                                         */
    0, sysdate, sysdate );
insert into pending_sessions$
values( '1.92.66874',/* <==此处为你的local tran id  */
    1, hextoraw('05004F003A1500000104'),
    'C', 0, 30258592, '',
    146
  );
commit;
commit force '1.92.66874';

此时如果commit force还是出现报错,需要继续执行:

delete from pending_trans$ where local_tran_id='1.92.66874';
delete from pending_sessions$ where local_tran_id='1.92.66874';
commit;
alter system enable distributed recovery;

此时如果没有报错,则执行以下语句:

alter system enable distributed recovery;
and purge the dummy entry from the dictionary, using
connect / as sysdba
alter session set "_smu_debug_mode" = 4;
--注:如果使用auto的undo管理方式,需要执行此步骤,此步骤能避免在后续执行
--purge_lost_db_entry出现ORA-01453 的报错,详细信息可见Bug 2191458
commit;
exec dbms_transaction.purge_lost_db_entry('1.92.66874');

原文:http://www.dbifan.com/200812/how-to-deal-with-distributed-transaction.html

V$PWFILE_USERS和密码文件关系

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:V$PWFILE_USERS和密码文件关系

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

一、V$PWFILE_USERS定义

V$PWFILE_USERS lists all users in the password file, and indicates whether the user has been granted the SYSDBA, SYSOPER, and SYSASM privileges.
Column	    Datatype	Description
USERNAM    VARCHAR2(30)	Name of the user that is contained in the password file
SYSDBA	   VARCHAR2(5)	Indicates whether the user can connect with SYSDBA privileges (TRUE) or not (FALSE)
SYSOPER	   VARCHAR2(5)	Indicates whether the user can connect with SYSOPER privileges (TRUE) or not (FALSE)
SYSASM	   VARCHAR2(5)	Indicates whether the user can connect with SYSASM privileges (TRUE) or not (FALSE)

二、v$pwfile_users与密码文件关系

[oracle@node1 ~]$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.3.0 Production on Sun Dec 4 19:08:06 2011
Copyright (c) 1982, 2011, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Oracle Label Security, OLAP, Data Mining,
Oracle Database Vault and Real Application Testing options
--查看密码文件用户权限
SQL> select * from v$pwfile_users;
USERNAME                       SYSDB SYSOP SYSAS
------------------------------ ----- ----- -----
SYS                            TRUE  TRUE  FALSE
SQL> show parameter instance_name;
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------
instance_name                        string      ora11g
--查看系统级别查看密码文件内容
SQL> !strings $ORACLE_HOME/dbs/orapwora11g
]\[Z
ORACLE Remote Password file
INTERNAL
A1174901D667F113
18698BFD1A045BCC
--创建新sysdba用户,查看视图和密码文件变化
SQL> create user xff01 identified by xifenfei;
User created.
SQL> grant sysdba to xff01;
Grant succeeded.
SQL>  select * from v$pwfile_users;
USERNAME                       SYSDB SYSOP SYSAS
------------------------------ ----- ----- -----
SYS                            TRUE  TRUE  FALSE
XFF01                          TRUE  FALSE FALSE
SQL>  !strings $ORACLE_HOME/dbs/orapwora11g
]\[Z
ORACLE Remote Password file
INTERNAL
A1174901D667F113
18698BFD1A045BCC
XFF01
D32693095588EF4F
--删除密码文件
SQL> ! mv $ORACLE_HOME/dbs/orapwora11g $ORACLE_HOME/dbs/orapwora11g_bak
SQL> !ls $ORACLE_HOME/dbs/orapwora11g
ls: /opt/oracle/product/11.2.0/db_1/dbs/orapwora11g: 没有那个文件或目录
--查看视图
SQL>  select * from v$pwfile_users;
no rows selected
SQL>  ! mv $ORACLE_HOME/dbs/orapwora11g_bak $ORACLE_HOME/dbs/orapwora11g
SQL> !ls $ORACLE_HOME/dbs/orapwora11g
/opt/oracle/product/11.2.0/db_1/dbs/orapwora11g
SQL> select * from v$pwfile_users;
USERNAME                       SYSDB SYSOP SYSAS
------------------------------ ----- ----- -----
SYS                            TRUE  TRUE  FALSE
XFF01                          TRUE  FALSE FALSE
--改变sysdba用户权限,视图内容变化
SQL> grant sysoper to xff01;
Grant succeeded.
SQL>  select * from v$pwfile_users;
USERNAME                       SYSDB SYSOP SYSAS
------------------------------ ----- ----- -----
SYS                            TRUE  TRUE  FALSE
XFF01                          TRUE  TRUE  FALSE
--密码文件内容无变化
SQL> !strings $ORACLE_HOME/dbs/orapwora11g
]\[Z
ORACLE Remote Password file
INTERNAL
A1174901D667F113
18698BFD1A045BCC
XFF01
D32693095588EF4F
SQL> revoke sysdba from xff01;
Revoke succeeded.
SQL> select * from v$pwfile_users;
USERNAME                       SYSDB SYSOP SYSAS
------------------------------ ----- ----- -----
SYS                            TRUE  TRUE  FALSE
XFF01                          FALSE TRUE  FALSE
SQL> revoke sysoper  from xff01;
Revoke succeeded.
SQL> select * from v$pwfile_users;
USERNAME                       SYSDB SYSOP SYSAS
------------------------------ ----- ----- -----
SYS                            TRUE  TRUE  FALSE
XFF01                          FALSE FALSE FALSE
SQL> revoke sysoper  from xff01;
Revoke succeeded.
--回收sysdba,sysoper权限后,视图记录消失
SQL> select * from v$pwfile_users;
USERNAME                       SYSDB SYSOP SYSAS
------------------------------ ----- ----- -----
SYS                            TRUE  TRUE  FALSE
--密码文件内容无变化
SQL>  !strings $ORACLE_HOME/dbs/orapwora11g
]\[Z
ORACLE Remote Password file
INTERNAL
A1174901D667F113
18698BFD1A045BCC
XFF01
D32693095588EF4F
--删除其中sysdba用户
SQL> drop user xff01;
User dropped.
--密码文件内容还是无变化
SQL>  !strings $ORACLE_HOME/dbs/orapwora11g
]\[Z
ORACLE Remote Password file
INTERNAL
A1174901D667F113
18698BFD1A045BCC
XFF01
D32693095588EF4F
--重启数据库密码文件依然无变化
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> !strings $ORACLE_HOME/dbs/orapwora11g
]\[Z
ORACLE Remote Password file
INTERNAL
A1174901D667F113
18698BFD1A045BCC
XFF01
D32693095588EF4F

1、如果密码文件不存在或者名称错误,查询v$pwfile_users将得到空记录
2、添加sysdba等权限用户,会记录到密码文件和v$pwfile_users中
3、到回收sysdba等权限用户,密码文件记录依然存在,但是v$pwfile_users中无对应记录

三、远程登录测试

--密码文件记录存在,视图不记录不存在,登录失败
[oracle@node1 ~]$ sqlplus xff01/xifenfei@ora11g as sysdba
SQL*Plus: Release 10.2.0.5.0 - Production on Sun Dec 4 19:42:26 2011
Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.
ERROR:
ORA-01031: insufficient privileges
Enter user-name
--密码文件视图记录均存在,登录成功
[oracle@node1 ~]$ sqlplus sys/xifenfei@ora11g as sysdba
SQL*Plus: Release 10.2.0.5.0 - Production on Sun Dec 4 19:42:10 2011
Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.
Connected to an idle instance.

是否能远程登录,依照v$pwfile_users为准

四、创建密码文件

win:
orapwd file=%ORACLE_HOME%\database\PWD%ORACLE_SID%.ora entries=3 password=manager force=y
linux:
orapwd file=$ORACLE_HOME/dbs/orapw$ORACLE_SID entries=3 password=manager force=y

下篇:V$PWFILE_USERS和密码文件关系(续)

pl/sql的定义者与调用者

联系:手机/微信(+86 17813235971) QQ(107644445)

标题:pl/sql的定义者与调用者

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

一、执行的schema不同,操作的对象也不同

C:\Users\XIFENFEI>sqlplus / as sysdba
SQL*Plus: Release 11.2.0.1.0 Production on 星期日 11月 20 20:39:06 20
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Productio
With the Partitioning, Oracle Label Security, OLAP, Data Mining,
Oracle Database Vault and Real Application Testing options
SQL> create user xffa identified by xifenfei;
用户已创建。
SQL> grant connect,resource to xffa;
授权成功。
SQL> create user xffb identified by xifenfei;
用户已创建。
SQL> grant connect,resource to xffb;
授权成功。
SQL> conn xffa/xifenfei
已连接。
xffa>create table tmp(str varchar2(50));
表已创建。
xffa>insert into tmp values
  2  ('my name is xffa');
已创建 1 行。
xffa>commit;
提交完成。
xffa>create or replace procedure definer_proc as
  2      begin
  3        for x in (select sys_context('userenv', 'current_user') current_user,
  4                         sys_context('userenv', 'session_user') session_user,
  5                         sys_context('userenv', 'current_schema') current_sch
ema,
  6                         str
  7                    from tmp) loop
  8        dbms_output.put_line('Current User:   ' || x.current_user);
  9        dbms_output.put_line('Session User:   ' || x.session_user);
 10        dbms_output.put_line('Current Schema: ' || x.current_schema);
 11        dbms_output.put_line('Tables Value:    ' || x.str);
 12      end loop;
 13    end;
 14    /
过程已创建。
xffa>create or replace procedure invoker_proc AUTHID CURRENT_USER as
  2      begin
  3        for x in (select sys_context('userenv', 'current_user') current_user,
  4                         sys_context('userenv', 'session_user') session_user,
  5                         sys_context('userenv', 'current_schema') current_sch
ema,
  6                         str
  7                    from tmp) loop
  8        dbms_output.put_line('Current User:   ' || x.current_user);
  9        dbms_output.put_line('Session User:   ' || x.session_user);
 10        dbms_output.put_line('Current Schema: ' || x.current_schema);
 11        dbms_output.put_line('Tables Value:    ' || x.str);
 12      end loop;
 13    end;
 14    /
过程已创建。
xffa>grant execute on definer_proc to xffb;
授权成功。
xffa>grant execute on invoker_proc to xffb;
授权成功。
xffa>set serveroutput on
xffa>exec definer_proc;
Current User:   XFFA
Session User:   XFFA
Current Schema: XFFA
Tables Value:    my name is xffa
PL/SQL 过程已成功完成。
xffa>exec invoker_proc;
Current User:   XFFA
Session User:   XFFA
Current Schema: XFFA
Tables Value:    my name is xffa
PL/SQL 过程已成功完成。
xffa>conn xffb/xifenfei
已连接。
xffb>exec xffa.definer_proc;
PL/SQL 过程已成功完成。
xffb>set serveroutput on
xffb>exec xffa.definer_proc;
Current User:   XFFA
Session User:   XFFB
Current Schema: XFFA
Tables Value:    my name is xffa
PL/SQL 过程已成功完成。
--除了session是当前用户的,其他都是这个过程所属用户
xffb>exec xffa.invoker_proc;
BEGIN xffa.invoker_proc; END;
*
第 1 行出现错误:
ORA-00942: 表或视图不存在
ORA-06512: 在 "XFFA.INVOKER_PROC", line 3
ORA-06512: 在 line 1
--根据这个提示,很容易知道是tmp表不存在,也就是说明这个没有调用xffa.tmp表
xffb>create table tmp(str varchar2(50));
表已创建。
xffb>insert into tmp values
  2  ('my name is xffb');
已创建 1 行。
xffb>commit;
提交完成。
xffb>exec xffa.invoker_proc;
Current User:   XFFB
Session User:   XFFB
Current Schema: XFFB
Tables Value:    my name is xffb
PL/SQL 过程已成功完成。
--这个可以看出当时调用者的时候,执行的完全是当前用户下面的对象

在定义者(definer)权限下,执行的用户操作的schema为定义者,所操作的对象是定义者在编译时指定的对象。
在调用者(invoker)权限下,执行的用户操作的schema为当前用户,所操作的对象是当前模式下的对象。

二、执行的权限不同

xffb>create or replace procedure createtbl_definer as
  2      begin
  3        execute immediate 'create table xff_definer (id number)';
  4      end;
  5      /
过程已创建。
xffb>create or replace procedure createtbl_invoker AUTHID CURRENT_USER  as
  2      begin
  3        execute immediate 'create table xff_invoker (id number)';
  4      end;
  5      /
xffb>grant execute on createtbl_definer to xffa;
授权成功。
xffb>grant execute on createtbl_invoker to xffa;
授权成功。
xffb>exec createtbl_definer;
BEGIN createtbl_definer; END;
*
第 1 行出现错误:
ORA-01031: 权限不足
ORA-06512: 在 "XFFB.CREATETBL_DEFINER", line 3
ORA-06512: 在 line 1
--提示权限不足,很明显是缺少创建表的权限
xffb>exec createtbl_invoker;
PL/SQL 过程已成功完成。
xffb>desc xff_invoker;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
--调用者创建成功
xffb>conn xffa/xifenfei
已连接。
xffa>exec xffb.createtbl_definer;
BEGIN xffb.createtbl_definer; END;
*
第 1 行出现错误:
ORA-01031: 权限不足
ORA-06512: 在 "XFFB.CREATETBL_DEFINER", line 3
ORA-06512: 在 line 1
--定义者同样提示没有权限创建表,通过1中的试验,我们知道
--定义者执行的这个过程定义者的对象,也就是说,是因为xffb无权创建表导致该提示
xffa>exec xffb.createtbl_invoker;
PL/SQL 过程已成功完成。
xffa>desc xff_invoker;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
xffa>conn / as sysdba
已连接。
SQL>select owner,table_name from dba_tables where table_name=upper('xff_invoker');
OWNER                          TABLE_NAME
------------------------------ ------------------------------
XFFB                           XFF_INVOKER
XFFA                           XFF_INVOKER
--xffa用户执行成功,并且在自己的schema下面创建了表,证明了1的正确
SQL>GRANT CREATE TABLE TO XFFB;
授权成功。
SQL>conn xffb/xifenfei
已连接。
xffb>exec createtbl_definer;
PL/SQL 过程已成功完成。
xffb>desc xff_definer;
 名称                                      是否为空? 类型
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER
--说明直接授权是的定义者操作成功,但是角色(resource)不能使其操作成功
xffb>conn xffa/xifenfei
已连接。
xffa>exec xffb.createtbl_definer;
BEGIN xffb.createtbl_definer; END;
*
第 1 行出现错误:
ORA-00955: 名称已由现有对象使用
ORA-06512: 在 "XFFB.CREATETBL_DEFINER", line 3
ORA-06512: 在 line 1
--因为定义者执行的是过程创建者的对象,因为XFFB.CREATETBL_DEFINER已经创建成功

在定义者(definer)权限下,当前用户的权限为角色无效情况下所拥有的权限。
在调用者(invoker)权限下,当前用户的权限为当前所拥有的权限(含角色)。

三、执行的效率不同
在定义者(definer)权限下,过程被静态编译静态执行(相对而言),所执行sql语句在共享区池中是可被共享使用的
在调用者(invoker)权限下,过程静态编译,但动态执行,虽然执行的语句相同,但不同用户执行,其sql语句在共享池中并不能共享。

参考:http://www.itpub.net/thread-935634-1-1.html