精細審計

精細審計

精細審計FGA(Fined-Grained Aiditing)能實現比標準審計粒度更細化的審計功能,如當用戶對滿足指定條件的數據行或列進行了操作才進行審計。

FGA的實現通過dbms_fga包進行。審計結果放在fga_log$中,可通過系統視圖dba_fga_audit_trail進行查詢。

SQL> begin

 2  dbms_fga.add_policy

 3  (object_schema=>'scott',

 4  object_name=>'emp',

 5 policy_name=>'fga_rows_audit',

 6 audit_condition=>'deptno=10',

 7  enable=>true,

 8 statement_types=>'select,update');

 9  end;

 10  /

 

PL/SQL procedure successfully completed.

【設置FGA審計策略,當scott用戶emp表上部門號爲10的數據行被查詢或修改時即記錄審計信息】

 

[oracle@desktop241 ~]$ sqlplus / as sysdba

SQL> select * from dba_audit_policies;

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

SCOTT                    EMP

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

FGA_ROWS_AUDIT

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

deptno=10

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

 

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

                                             YES YES NO  YES

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

NO DB+EXTENDED  ANY_COLUMNS

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

SQL> grant select any table to john;

 

Grant succeeded.

 

SQL> grant update any table to john;

 

Grant succeeded.

 

SQL> select timestamp,db_user,os_user,object_schema,object_name,sql_textfrom dba_fga_audit_trail;

 

no rows selected【查詢FGA審計結果】

 

[oracle@desktop241 ~]$ sqlplus john/john123

SQL> select * from scott.emp wheredeptno=10;

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7782 CLARK      MANAGER         7839 09-JUN-81          2450

      10

 

     7839 KING       PRESIDENT    17-NOV-81          5000

      10

 

     7934 MILLER     CLERK        7782 23-JAN-82          1300

      10

 

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text fromdba_fga_audit_trail;

 

TIMESTAMP   DB_USER

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

OS_USER

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

OBJECT_SCHEMA

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

OBJECT_NAME

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

SQL_TEXT

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

18-OCT-12   JOHN

oracle

SCOTT

 

TIMESTAMP   DB_USER

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

OS_USER

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

OBJECT_SCHEMA

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

OBJECT_NAME

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

SQL_TEXT

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

EMP

select * from scott.emp where deptno=10

【再查FGA審計結果】

SQL> select * from scott.emp wheredeptno=20;

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7369 SMITH      CLERK        7902 17-DEC-80           800

      20

 

     7566 JONES      MANAGER         7839 02-APR-81          2975

      20

 

     7788 SCOTT      ANALYST          7566 19-APR-87          3000

      20

 

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7876 ADAMS      CLERK       7788 23-MAY-87         1100

      20

 

     7902 FORD       ANALYST          7566 03-DEC-81          3000

      20

 

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text from dba_fga_audit_trail;

 

TIMESTAMP   DB_USER

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

OS_USER

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

OBJECT_SCHEMA

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

OBJECT_NAME

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

SQL_TEXT

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

18-OCT-12   JOHN

oracle

SCOTT

 

TIMESTAMP   DB_USER

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

OS_USER

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

OBJECT_SCHEMA

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

OBJECT_NAME

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

SQL_TEXT

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

EMP

select * from scott.emp where deptno=10

 

 

SQL>update scott.emp set sal=sal*1.1 where deptno=10;

 

3 rows updated.

 

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text fromdba_fga_audit_trail;

update scott.emp set sal=sal*1.1 wheredeptno=10

 

SQL> execdbms_fga.drop_policy('scott','emp','fga_rows_audit');

 

PL/SQL procedure successfully completed.

 

SQL> truncate table fga_log$;

 

Table truncated.

SQL> begin

 2  dbms_fga.add_policy

 3  (object_schema=>'scott',

 4  object_name=>'emp',

 5 policy_name=>'fga_columns_audit',

 6  audit_column=>'sal',

 7  enable=>true,

 8  statement_types=>'select');

 9  end;

 10  /

 

PL/SQL procedure successfully completed.

【再設FGA審計策略,當scott用戶emp表上sal列被查詢時即記錄審計信息】

測試:

SQL> select sal from scott.emp wheredeptno=10;

 

      SAL

----------

     2695

     5500

     1430

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text from dba_fga_audit_trail;

EMP

select sal from scott.emp where deptno=10

 

SQL> select ename from scott.emp wheredeptno=10;

 

ENAME

----------

CLARK

KING

MILLER

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text fromdba_fga_audit_trail;

select sal from scott.emp where deptno=10

 

SQL> select ename from scott.emp wheredeptno=10 and sal>3000;

 

ENAME

----------

KING

 

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text fromdba_fga_audit_trail;

 

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

EMP

select ename from scott.emp where deptno=10and sal>3000

 

SQL> execdbms_fga.drop_policy('scott','emp','fga_columns_audit');

 

PL/SQL procedure successfully completed.

 

SQL> truncate table fga_log$;

 

Table truncated.

 

SQL> get fga.add

 1  begin

 2  dbms_fga.add_policy

 3  (object_schema=>'scott',

 4  object_name=>'emp',

 5  policy_name=>'fga_audit',

 6 audit_condition=>'deptno=10',

 7  audit_column=>'sal',

 8  enable=>true,

 9  statement_types=>'select');

 10*end;

 11  /

 

PL/SQL procedure successfully completed.

【再設FGA審計策略,當scott用戶emp表上deptno爲10的數據庫行的sal列被查詢時即記錄審計信息。即當audit_condition與audit_column指定的條件都滿足時將進行FGA審計記錄】

測試:

SQL> select empno from scott.emp;

 

    EMPNO

----------

     7369

     7499

     7521

     7566

     7654

     7698

     7782

     7788

     7839

     7844

     7876

 

    EMPNO

----------

     7900

     7902

     7934

 

14 rows selected.

 

SQL> show user;

USER is "JOHN"

SQL> select timestamp,db_user,os_user,object_schema,object_name,sql_textfrom dba_fga_audit_trail;

 

no rows selected

SQL> select empno,sal from scott.emp;

 

    EMPNO        SAL

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

     7369    800

     7499  1600

     7521  1250

     7566  2975

      7654  1250

     7698  2850

     7782  2695

     7788  3000

     7839  5500

     7844  1500

     7876  1100

 

    EMPNO        SAL

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

     7900    950

     7902  3000

     7934  1430

 

14 rows selected.

 

SQL> select timestamp,db_user,os_user,object_schema,object_name,sql_textfrom dba_fga_audit_trail;

 

no rows selected

 

SQL_TEXT

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

EMP

select empno,sal from scott.emp

SQL> select empno,sal from scott.emp;

 

    EMPNO        SAL

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

     7369    800

     7499  1600

     7521  1250

     7566  2975

     7654  1250

     7698  2850

     7782  2450

     7788  3000

     7839  5000

     7844  1500

     7876  1100

 

    EMPNO        SAL

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

     7900    950

     7902  3000

     7934  1300

 

14 rows selected.

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text fromdba_fga_audit_trail;

 

SQL> show user;

USER is "SCOTT"

 

SQL_TEXT

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

EMP

select empno,sal from scott.emp

 

SQL> execdbms_fga.drop_policy('scott','emp','fga_audit');

 

PL/SQL procedure successfully completed.

 

SQL> truncate table fga_log$;

 

Table truncated.【查自己的表記錄,sys用戶查不記錄】

強制審計

【記錄以sysdba身份登錄數據庫的動作,默認生效,不依賴於參數設置,在數據庫關閉時也同樣生效】

SQL> show parameter audit_file_dest;

 

NAME                         TYPE   VALUE

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

audit_file_dest              string   /u01/app/oracle/admin/ora10/ad

                                   ump

[oracle@desktop241 ~]$ sqlplus / as sysdba

[oracle@desktop241 ~]$ ps -ef | grepV$SPID;

oracle  30705 30589  0 22:56 pts/4    00:00:00 grep V

 

 

[oracle@desktop241 adump]$ vimora10_ora_30582_1.aud

Thu Oct 18 22:53:41 2012

LENGTH : '158'

ACTION :[7] 'CONNECT'

DATABASE USER:[1] '/'

PRIVILEGE :[6] 'SYSDBA'

CLIENT USER:[6] 'oracle'

CLIENT TERMINAL:[5] 'pts/1'

STATUS:[1] '0'

DBID:[9] '775040288'

 

VPD虛擬專用數據庫(virtual private database)

虛擬專用數據庫(VPD)提供了角色視圖無法提供的行級訪問控制,如實現每個銷售用戶登錄後只能訪問銷售表中自己的銷售中自己的銷售記錄。具體實現過程爲:

1.   先設置應用程序上下文A(應用程序上下文是一個數據庫對象,在整個session週期內保存session的各項屬性如登錄用戶名,類似於環境變量)用來保存用戶登錄時的登錄名;

2.   再在用戶登錄時由觸發器C執行預設定好的程序單元B 獲取用戶名並保存在應用程序上下文A中;

3.   預設定好的審計規則E在監控到銷售用戶執行銷售記錄的查詢語句時,由預設定好的程序單元D在用戶執行的查詢語句後隱式添加指定條件,如當銷售用戶執行select * from sales時系統自動轉換爲select * from sales where seller=’s001’;

建立測試環境

SQL> create table scott.sales(product_id varchar(4),price number,qtys number,seller varchar(4));

 

Table created.

 

SQL> insert into scott.sales values('0001',1000,1,'s001');

 

1 row created.

 

SQL> insert into scott.sales values('0002',2000,2,'s002');

 

1 row created.

 

SQL> create user s001 identified bys001;

 

User created.

 

SQL> create user s002 identified bys002;

 

User created.

 

SQL> create user mgr identified by mgr;

 

User created.

 

SQL> grant connect,resource,select anytable to s001;

 

Grant succeeded.

 

SQL> grant connect,resource,select anytable to s002;

 

Grant succeeded.

 

SQL> grant connect,resource,select anytable to mgr;

 

Grant succeeded.

[oracle@desktop241 ~]$ sqlplus s001/s001

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001        1000       1 s001

0002        2000       2 s002

 

SQL> connect s002/s002

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001        1000       1 s001

0002        2000       2 s002

 

SQL> connect mgr/mgr

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001        1000       1 s001

0002        2000       2 s002

【測試3個用戶均能查到sales銷售表中所有數據,VPD需要實現Mgr用戶能查所有數據,而s001和s002只能查到自己的銷售數據】

A.   B建立應用程序上下文A(保存登錄用戶名)和存儲過程B(獲取登錄用戶名)

SQL> connect / as sysdba

Connected.

SQL> create or replacecontext vpd_context using scott.vpd_get_username;

【建立應用程序上下文vpd_context,其中所保存的屬性由存儲過程scott.vpd_get_username(即存儲過程B)賦予】

Context created.

 

SQL> create or replaceprocedure scott.vpd_get_username is begin

  2 dbms_session.set_context('vpd_context','seller',user);

  3  end;

  4  /

【建立存儲過程,爲vpd_context建立屬性名seller,用來保存屬性值user】

Procedure created.

SQL> grant execute on scott.vpd_get_username to public;

【將存儲過程的執行權限賦給所有用戶】

Grant succeeded.

C.建立觸發器C(自動獲取登錄用戶名)

SQL>create or replace trigger get_username_on_logon

  2 after logon on database

  3 begin

  4 scott.vpd_get_username;

  5  end;

  6  /

【建立觸發器,用於用戶登錄後自動執行存儲過程vpd_get_username獲取用戶名存入應用程序上下文vpd_context中】

Trigger created.

 

SQL> connect s001/s001

Connected.

SQL> selectsys_context('vpd_context','seller')from dual;

 

SYS_CONTEXT('VPD_CONTEXT','SELLER')

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

S001

 

SQL> connect s002/s002

Connected.

SQL> selectsys_context('vpd_context','seller')from dual;

 

SYS_CONTEXT('VPD_CONTEXT','SELLER')

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

S002

 

SQL> connect mgr/mgr

Connected.

SQL> selectsys_context('vpd_context','seller')from dual;

 

SYS_CONTEXT('VPD_CONTEXT','SELLER')

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

MGR

【測試應用程序上下文vpd_context是否生效,其屬性seller中是否包含用戶名屬性值】

D.建立函數D(在用戶執行的語句後隱式添加指定條件)

SQL> create or replace function scott.vpd_add_condition

  2  (p_schema_name varchar2,p_tab_name varchar2)

  3  return varchar2 is

  4  v_namevarchar2(100):=upper(sys_context('vpd_context','seller'));

  5  v_condition varchar2(2000);

  6  begin

  7  if v_name like 's%' thenv_condition:='seller='||''''||v_name||'''';

  8                      else v_condition:=null;

 9  end if;

 10 return v_condition;

 11  end;

 12  /

 

Function created.

【建立函數D,在用戶執行的查詢語句後隱式添加指定條件。如當銷售用戶執行語句select * fromsales時系統自動轉換爲select *from sales where seller=’s001’;而當非銷售用戶mgr執行語句時,則不添加指定條件(Null),其中p_schema_name和p_tab_name兩變量值爲FGAC規則函數必須的兩個傳入參數,分別用來表示對哪個schema下的哪個table 添加FGAC規則】

FGAC即FINE_CRAINED ACCESS CONTROL,即對數據行進行過濾的VPD,即提供行級安全性的VPD,即基於行的VPD。

E.建立審計規則E(監控銷售表上執行的查詢語句)

 

SQL>begin dbms_rls.add_policy

  2 (object_schema=>'scott',

  3 object_name=>'sales',

  4 policy_name=>'fgac_vpd',

  5 function_schema=>'scott',

  6 policy_function=>'vpd_add_condition',

  7 statement_types=>'select',

  8 enable=>true);

  9  end;

 10  /

 

PL/SQL procedure successfully completed.

【建立審計規則E,監控到sales銷售表上執行查詢語句時,就調用vpd_add_condition函數進行處理】

測試結果:

 

SQL> conn S001/S001

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001         100       1 S001

 

SQL> conn scott/tiger

Connected.

SQL> select * from scott.sales;

 

no rows selected

 

SQL> conn S002/S002

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0002         200       2 S002

 

SQL> conn mgr/mgr

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001         100       1 S001

0002         200       2 S002

 

SQL> conn system/song

Connected.

SQL> select * from scott.sales;

 

no rows selected

 

SQL> conn sys/song  as sysdba

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001         100       1 S001

0002         200       2 S002

 

 

 

基於列的VPD

僅有具有權限的用戶才能訪問敏感列,敏感列,否則列數據被屏蔽

 

SQL> create or replace functionscott.vpd_col_condition

 2  (p_owner varchar2,p_objvarchar2)

 3  return varchar2 is

 4  v_condition varchar2(2000);

 5  begin

 6  if (p_owner=user)thenv_condition:=null;

 7                  elsev_condition:='1=2';

 8  end if;

 9  return v_condition;

 10  end;

 11  /

【建立規則函數,判斷執行查詢語句的用戶是不是表的屬主,是則不做限制,不是則添加條件1=2】

Function created.

 

SQL> begin dbms_rls.add_policy

 2  (object_schema=>'scott',

 3  object_name=>'emp',

 4  policy_name=>'fgac_col_vpd',

 5  function_schema=>'scott',

 6 policy_function=>'vpd_col_condition',

 7  statement_types=>'select',

 8  sec_relevant_cols=>'sal',

 9  sec_relevant_cols_opt=>dbms_rls.all_rows);

 10  end;

 11  /

 

PL/SQL procedure successfully completed.

【建立審計規則,監控到emp表上執行查詢語句時,就調用vpd_col_condition函數判斷執行查詢語句的用戶是不是表的屬主,是則不做限制,不是則對所有記錄(由參數sec_relevant_cols_opt=>dbms_rls.all_rows指定)的sal列(sec_relevant_cols=>’sal’指定)單獨添加條件1=2(即隱藏該列數據)】

SQL> conn scott/tiger

Connected.

SQL> select * from scott.emp;

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7369 SMITH      CLERK        7902 17-DEC-80           800

      20

 

     7499 ALLEN      SALESMAN        7698 20-FEB-81          1600    300

      30

 

     7521 WARD       SALESMAN       7698 22-FEB-81          1250    500

SQL> conn mgr/mgr

Connected.

SQL> select * from scott.emp;

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7369 SMITH      CLERK        7902 17-DEC-80

      20

 

     7499 ALLEN      SALESMAN        7698 20-FEB-81                  300

      30

 

     7521 WARD       SALESMAN       7698 22-FEB-81                  500

      30

SQL> conn / as sysdba

Connected.

SQL> select * from scott.emp;

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7369 SMITH      CLERK        7902 17-DEC-80           800

      20

 

     7499 ALLEN      SALESMAN        7698 20-FEB-81          1600    3

 

TDE透明數據加密(transparent database encryption)

使用VPD可對敏感信息進行保護,但無法阻止用戶直接從數據文件dump出重要信息,實際工程中常在應用程序代碼中調用特定加密函數對數據加密,但要求熟悉應用程序。

Oracle的TDE在數據寫入磁盤前調用錢包wallet文件中的密鑰自動加密數據(支持3DES168,AES128,AES192,AES256等加密算法),查詢時則調用錢包wallet文件中的密鑰自動解密,簡化了成本和複雜性,但其只將數據在存儲級別進行了加密,不能阻止用戶通過查詢語句查詢敏感數據,故應將VPD,TDE等方法結合起來保護數據。

Sys用戶的表不能被加密

SQL> host mkdir/u01/app/oracle/admin/ora10/wallet

【指定錢包默認存儲路徑】

SQL> alter system set encryption keyidentified by song;

【創建錢包文件並設置錢包訪問口令】

System altered.

 

SQL> host ls -l$ORACLE_BASE/admin/ora10/wallet/

總計 4【查看生成的錢包文件】

-rw------- 1 oracle oinstall 1309 10-1916:19 ewallet.p12

SQL> create table scott.tde(idnumber,name char(10) encrypt using 'AES128' no salt);

【利用錢包使用AES128算法對新建表 指定列進行加密,加密時不使用隨機字符串增強密碼強度( salt,使得相同明文加密後密文不同,)以使能在加密列上建立索引】

Table created.

測試:

SQL> insert into scott.tde values (0001,'aaa');

 

1 row created.

 

SQL> insert into scott.tde values(0002,'bbb');

 

1 row created.

 

SQL> insert into scott.tde values(0002,'ccc');

 

1 row created.

 

SQL> select * from scott.tde;

 

      IDNAME

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

       1 aaa

       2 bbb

       2 ccc

SQL> alter system set encryption walletclose;

 

System altered.

 

SQL> select * from scott.tde;

select * from scott.tde

                    *

ERROR at line 1:

ORA-28365: wallet is not open

 

 

SQL> select id from scott.tde;

 

      ID

----------

       1

       2

       2

 

SQL> alter system set encryption walletopen authenticated by song;

 

System altered.

 

SQL> select * from scott.tde;

 

      IDNAME

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

       1 aaa

       2 bbb

       2 ccc

 

SQL> alter table scott.tde modify namechar(10) decrypt;

【取消列加密】

Table altered.

 

SQL> alter system set encryption walletclose;

 

System altered.

 

SQL> select * from scott.tde;

 

      IDNAME

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

       1 aaa

       2 bbb

       2 ccc

加密備份數據

SQL> alter system set encryption walletopen authenticated by song;

 

System altered.

RMAN> connect target sys/song

 

connected to target database: ORA10(DBID=775040288)

using target database control file insteadof recovery catalog

 

RMAN> configure encryption for databaseon;

 

new RMAN configuration parameters:

CONFIGURE ENCRYPTION FOR DATABASE ON;

new RMAN configuration parameters aresuccessfully stored

 

RMAN> backup tablespace users;

 

Starting backup at 19-OCT-12

allocated channel: ORA_DISK_1

channel ORA_DISK_1: sid=143 devtype=DISK

channel ORA_DISK_1: starting full datafilebackupset

channel ORA_DISK_1: specifying datafile(s)in backupset

input datafile fno=00004name=/u01/app/oracle/oradata/ora10/users01.dbf

channel ORA_DISK_1: starting piece 1 at19-OCT-12

channel ORA_DISK_1: finished piece 1 at19-OCT-12

piece handle=/backup/backup_0pno5hvm_1_1 tag=TAG20121019T164022comment=NONE

channel ORA_DISK_1: backup set complete,elapsed time: 00:00:03

Finished backup at 19-OCT-12

 

Starting Control File and SPFILE Autobackupat 19-OCT-12

piecehandle=/u01/app/oracle/flash_recovery_area/ORA10/autobackup/2012_10_19/o1_mf_s_797100026_8824hysg_.bkpcomment=NONE

Finished Control File and SPFILE Autobackupat 19-OCT-12

【打開錢包,配置RMAN爲透明加密模式,則備份數據時利用錢包進行加密,恢復時也需打開錢包才能進行,適合備份和恢復都在本地進行的備份模式

RMAN> set encryption identified by song1only;

 

executing command: SET encryption

 

RMAN> backup tablespace users;

 

Starting backup at 19-OCT-12

using channel ORA_DISK_1

channel ORA_DISK_1: starting full datafilebackupset

channel ORA_DISK_1: specifying datafile(s)in backupset

input datafile fno=00004name=/u01/app/oracle/oradata/ora10/users01.dbf

channel ORA_DISK_1: starting piece 1 at19-OCT-12

channel ORA_DISK_1: finished piece 1 at19-OCT-12

piece handle=/backup/backup_0rno5i71_1_1tag=TAG20121019T164417 comment=NONE

channel ORA_DISK_1: backup set complete,elapsed time: 00:00:02

Finished backup at 19-OCT-12

 

Starting Control File and SPFILE Autobackupat 19-OCT-12

piecehandle=/u01/app/oracle/flash_recovery_area/ORA10/autobackup/2012_10_19/o1_mf_s_797100259_8824q3st_.bkpcomment=NONE

Finished Control File and SPFILE Autobackupat 19-OCT-12

【不使用錢包,配置RMAN爲密碼加密模式,則恢復時必須提供備份時所指定的密碼(set decryption)才能進行,適合備份在本地,恢復在異地的備份模式】

RMAN> set decryption identified bysong1;

 

executing command: SET decryption

 

RMAN> set encryption identified bysong2;

 

executing command: SET encryption

 

RMAN> backup tablespace users;

 

Starting backup at 19-OCT-12

using channel ORA_DISK_1

channel ORA_DISK_1: starting full datafilebackupset

channel ORA_DISK_1: specifying datafile(s)in backupset

input datafile fno=00004name=/u01/app/oracle/oradata/ora10/users01.dbf

channel ORA_DISK_1: starting piece 1 at19-OCT-12

channel ORA_DISK_1: finished piece 1 at19-OCT-12

piece handle=/backup/backup_0tno5iii_1_1tag=TAG20121019T165026 comment=NONE

channel ORA_DISK_1: backup set complete,elapsed time: 00:00:01

Finished backup at 19-OCT-12

 

Starting Control File and SPFILE Autobackupat 19-OCT-12

piecehandle=/u01/app/oracle/flash_recovery_area/ORA10/autobackup/2012_10_19/o1_mf_s_797100627_88252n6k_.bkpcomment=NONE

Finished Control File and SPFILE Autobackupat 19-OCT-12

 

RMAN> set decryption identified bysong2;

 

executing command: SET decryption

【使用錢包和密碼,配置RMAN爲混合加密模式,則恢復時打開錢包,或者提供備份時所指定的密碼均可進行,適合恢復即可能在本地,也可能在異地進行的備份模式】

LOCK   &  LATCH

Lock

獨佔鎖(X鎖)與共享鎖(S鎖)

SQL> update t1 set id=2 where id=1;

 

1 row updated.

SQL> update t1 set id=3 where id=1;

Waiting….

【爲保證數據的一致性,會話1在修改記錄時在記錄上加了獨佔鎖(exclusive,簡稱x鎖),又稱排他鎖,以防止事務在提交或回退前記錄被其他事務同時修改。

一旦用戶對某個資源添加了x鎖,則其他用戶都不能再對該資源添加任何類型的鎖,直到該用戶釋放了資源上的x鎖爲止】

 

SQL> update t1 set id=2 where id=1;

 

1 row updated.

SQL> drop table t1;

drop table t1

          *

ERROR at line 1:

ORA-00054: resource busy and acquire withNOWAIT specified

 

【爲保證數據的一致性,會話1在修改記錄時同時還在表頭上加了共享鎖(shared ,簡稱s鎖),以便其他刪表事務執行前不用檢查表中每條記錄是否加了獨佔鎖(那就不能刪表),而只要檢查表頭是否存在共享鎖就可以了

若刪表事務(要對全表加獨佔鎖)進行前,還有另一會話還進行了刪除記錄操作(且未提交或回退,即事務未結束),那麼另一會話在被刪記錄上加獨佔鎖,同時在表上再加一個共享鎖,則刪表事務要等到表頭上所有共享鎖全部取消後(即所有獨佔事務全部完成後),才能進行(才能對整表施加獨佔鎖)。

一旦用戶對某個資源添加了S鎖,則其他用戶都不能在該資源上添加X,只能添加S鎖,直到該用戶釋放了資源上的s 鎖爲止】

DML事務鎖

根據被保護的對象種類的不同,鎖還可以分成多種類型,如因DDL引起的鎖,DML事務引起的鎖,分佈式事務中涉及的鎖等,DML事務鎖應主要關注。

DML事務鎖能保證當某用戶正在更新表中某行數據時,其他用戶不能同時更新相同的數據行,而且也不能刪除或修改被更新的表,包括行鎖TX表鎖TM

 

前列修改記錄時,在行記錄上所施加的就是行(獨佔)鎖,對於ORACLE來說,行鎖只可能是獨佔鎖;而同時在表頭上所施加的就是表(共享)鎖,對於ORACLE來說,表鎖可能是共享鎖(如刪表中記錄時在表頭上所施加的共享鎖),也可能是獨佔鎖(如刪表操作時需要在表頭上所施加的獨佔鎖)。

 

TM表鎖的種類

TM表鎖即可能是獨佔鎖,也可能是共享鎖,可細分爲如下幾類:

編號                  表鎖                    含義

0/1                     無    

2                           RS                row share

3                         RX                  row exclusive

4                         S                    share

5                         SRX                    share+row  exclusive

6                            x                      exclusive

 

A.   select * from table_name不會產生鎖;

B.   lock table table_name in rowshare mode 會在表上加RS鎖,使用完畢後rollback即解鎖。

【當執行相應語句時,系統自動在所要操作的表上申請表級RS鎖(意向鎖,表示某事務有意向進行鎖表),當表上加RS鎖後,不許其他事務對該表添加x排他鎖(如drop table),但允許其他事務對該表再加除x鎖之外的其他鎖,如其他事務再對該表加RS鎖(再執行lock table in row share mode),或其他事務再對該表加RX鎖(再執行插刪改DML操作),或其他事務再對該表加S鎖(再執行建索引操作)等】

 

SQL> create table t4 (id number);

 

Table created.

 

SQL> insert into t4 values (1);

 

1 row created.

 

SQL> insert into t4 values(10);

 

1 row created.

 

SQL> commit;

 

Commit complete.

 

SQL> lock table t4 in row share mode;

 

Table(s) Locked.

 

SQL> select sid from v$mystat;

 

       SID

----------

       157

SQL> select * from v$lock where sid=157;

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

    CTIME BLOCK

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

3FB4A54C 3FB4A564 157 TM      55335     0          2       0

      116      0

 

SQL> drop table t4;

drop table t4

          *

ERROR at line 1:

ORA-00054: resource busy and acquire withNOWAIT specified

C/D/E/F.insert/update/ delete DML語句及select * from table_name for  update句會在表上加RX(其中select for update用於在讀數據過程中禁止其他事務對所讀數據進行DML操作),操作完成後commit或roback解鎖。

當執行相應語句時,系統自動在所要操作的表上申請表級RX鎖(意向鎖,表示某事務有意向要進行鎖表),當表級鎖獲得後,系統再自動申請TX行鎖(實體鎖,表示該事務的具體鎖動作),並將相應數據行加x鎖,當表上加RX鎖後,不許其他事務對該表再加X排他鎖(如drop table),不允許其他事務對該表再加S鎖(如建索引);但允許其他事務對該表再加RS鎖(如執行lock table inrow share mode)或RX鎖(如插刪改記錄,注意,其他事務在同一表上再加RX表鎖沒問題,但再加行鎖時,不能再加在表內已加X鎖的數據行上,而只許加在表內其他數據行上。

對錶施加RX鎖也可以通過手工執行Lock table table_name in rowexclusive mode進行顯示加鎖,執行後即對錶施加了RX鎖(但未對數據行申請加TX行鎖),直到rollback釋放。

RS與RX區別:

1.   產生條件不同。

2.   RX鎖後,其他事務讀不到更改後的結果。而RS對其他事務而言讀是沒有問題的,故稱RS,雖都是指在表的層面上防止其他事務鎖表,但RX是 forexclusive reading or writing,而RS是for exclusive write access.這也是RS的S(share)表現的地方。

SQL> insert into t4 values (8);

 

1 row created.

 

SQL> commit;

 

Commit complete.

 

SQL> update t4 set id=9 where id<=3;

 

4 rows updated.

 

SQL> select * from v$mystat;

 

       SID STATISTIC#     VALUE

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

       145       0          1

       145       1          1

 

SQL> select * from v$lock where sid=145;

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

     CTIME  BLOCK

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

3FB4A54C 3FB4A564 145 TM      55336     0           3       0

       131       0

 

3FB85DF8 3FB85E1C 145TX     458775   597           6       0

 

SQL> rollback;

 

SQL> select * from v$lock where sid=145;

 

ADDR    KADDR      SID TY       ID1   ID2       LMODE    REQUEST

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

     CTIME  BLOCK

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

3FB4A54C 3FB4A564 145 TM      55336     0           3       0

       172       0

 

3FB85DF8 3FB85E1C 145 TX     458775   597           6       0

       172       0

SQL> select xidusn,xidslot,xidsqn,status from v$transaction;

 

    XIDUSN    XIDSLOT   XIDSQN STATUS

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

 7      23         597 ACTIVE

 

SQL> select sid,type,id1,id2,lmode,request,block from v$lockwhere sid=145;

 

       SID TY        ID1     ID2 LMODE        REQUEST     BLOCK

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

       145 TM     55336       0      3        0       0

       145 TX     458775    597      6        0       0

 

SQL> select object_name from dba_objects where object_id='55336';

 

OBJECT_NAME

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

T4

 

SQL> select trunc(458775/power(2,16)) from dual;

 

TRUNC(458775/POWER(2,16))

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

            7

 

SQL> select bitand (458775,to_number('ffff','xxxx'))+0 from dual;

 

BITAND(458775,TO_NUMBER('FFFF','XXXX'))+0

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

                         23

 

SQL> show parameter transactions

 

NAME                          TYPE   VALUE

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

transactions                  integer 187

transactions_per_rollback_segment   integer 5

SQL> show parameter dml_locks;

 

NAME                          TYPE   VALUE

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

dml_locks                     integer 748

 

【TX數量和事務個數相同,並受transactions參數(默認187)限制,TM鎖數量和被更新的表的個數相同,並受dml_locks參數(默認748)限制,即默認情況下可同時啓動187個事務,更新748個表,平均允許每個事務同時更新4個表】

SQL> select resource_name,initial_allocation,current_utilization,max_utilizationfrom v$resource_limit where resource_name in ('transactions','dml_locks');

 

RESOURCE_NAME                 INITIAL_ALLOCATION   CURRENT_UTILIZATION

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

MAX_UTILIZATION

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

dml_locks                     748                     0

     44

 

transactions                   187                     0

      9

【查看當前TX/TM鎖的使用情況,包括能夠分配的最大個數,當前分配的個數,及曾經分配的最大個數】

SQL> update t4 set id=10 where id<10;

 

9 rows updated.

 

SQL> update t4 set id=10 where id<=10;

 

SQL> select sid,type,id1,id2,lmode,request,block from v$lockwhere sid in (145,158) order by sid desc;

 

       SID TY        ID1     ID2 LMODE        REQUEST     BLOCK

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

       158 TM     55336       0      3        0       0

       158 TX     196619    637      0        6       0

       145 TX     196619    637      6        0       1

       145 TM     55336       0      3        0       0

 

Create index on table語句會在表上加S鎖,操作完成後即解鎖。

創建索引時,需要讀表中所有數據,且在讀數據過程中數據不能由其他事務進行更新,此時需要對錶加S鎖,S鎖用於保證在操作期間整個表上不能再由其他事務加RX鎖(進行插刪改操作)及X鎖(不能刪表),因爲若在創建索引時,允許有未提交的其他插刪改事務發生,而新的數據是不會被索引的,則將造成數據和索引間的不一致。因爲S和RX鎖是互斥的,所以當某事務在表上有未提交插刪改事務時(以加RX鎖),另一事務不能創建索引(無法再加S鎖)。或者反之,當創建索引動作還沒結束時(S鎖未釋放),其他事務即不可以在表上開始插刪改事務(無法獲得RX鎖)。

當表上加S鎖後,不許其他事務對該表再加X排他鎖(如drop table),不允許其他事務對該表再加RX鎖(如插刪改記錄);但允許其他事務對該表再加RS鎖(如執行LOCK table inrow  share mode).

對錶施加S鎖也可以通過手工執行lock table table_name in share mode 進行顯式加鎖,執行後即對錶施加了S 鎖,其他事務對該表即不能進行數據插刪改及刪表操作,直到rollback釋放。

 

SQL> update t4 set id=10 where id=10;

 

0 rows updated.

 

SQL> select * from v$lock where sid=158;

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

     CTIME BLOCK

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

3FB4A608 3FB4A620 158 TM      55336     0           3       0

      21      0

 

 

SQL> create index i4 on t4 (id);

create index i4 on t4 (id)

                   *

ERROR at line 1:

ORA-00054: resource busy and acquire with NOWAIT specified

 

SQL> select * from v$lock where sid=158;

 

no rows selected

 

SQL> create index i4 on t4 (id);

create index i4 on t4 (id)

                   *

ERROR at line 1:

ORA-00054: resource busy and acquire with NOWAIT specified

SQL> lock table t4 in share mode;

 

SQL> select * from v$lock where sid in (158,145);

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

     CTIME BLOCK

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

3FB4A54C 3FB4A564 145 TM      55336     0           3       0

      2185      0

 

3FB86364 3FB86388 145 TX     196619   637           6       0

      2185      0

 

SQL> select * from v$lock where sid in (145,158,148);

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

     CTIME BLOCK

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

3FB4A54C 3FB4A564 145 TM      55336     0           5       0

       179      1

 

3FB4A6C4 3FB4A6DC     148TM      55336     0           0       3

      60      0

 

3FB4A780 3FB4A798 158 TM      55336     0           0       3

      33      0

 

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

     CTIME BLOCK

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

3FB86364 3FB86388 145 TX     458790   575           6       0

       179      0

 

如果對一個數據庫對象加SRX鎖,表示對它加S鎖,再加RX鎖,即SRX=S+RX.例如事務對某個表加SRX鎖,則表示該事務需要讀表中所有數據,且在讀數據過程中數據不能由其他事務進行更新(所以要對該表加S鎖),同時本事務會更新個別行(所以要對該表加RX鎖),注意,表上加S鎖後再由本事務加RX鎖是允許的,而表上加S鎖後再由其他事務加RX鎖是不允許的。

對錶施加SRX鎖也可以通過手工執行lock table table_name in share row exclusive mode 進行顯式加鎖,執行後即對錶施加了SRX鎖,其他事務對該表即不能進行數據插刪改及刪表操作,直到rollback釋放。

 

 

執行Alter table,drop table ,drop index,truncatetable操作時,需要對錶加X鎖,X鎖是限制級別最高的鎖。對錶加X鎖後,不能進行其他任何鎖操作。

對錶施加X鎖也可以通過手工執行lock table table_name in exclusive mode 進行顯式加鎖,執行後即對錶施加了x鎖,其他事務對該表即不能進行任何其他加鎖操作,直到rollback釋放。

死鎖deadlock

精細審計

精細審計FGA(Fined-Grained Aiditing)能實現比標準審計粒度更細化的審計功能,如當用戶對滿足指定條件的數據行或列進行了操作才進行審計。

FGA的實現通過dbms_fga包進行。審計結果放在fga_log$中,可通過系統視圖dba_fga_audit_trail進行查詢。

SQL> begin

 2  dbms_fga.add_policy

 3  (object_schema=>'scott',

 4  object_name=>'emp',

 5 policy_name=>'fga_rows_audit',

 6 audit_condition=>'deptno=10',

 7  enable=>true,

 8 statement_types=>'select,update');

 9  end;

 10  /

 

PL/SQL procedure successfully completed.

【設置FGA審計策略,當scott用戶emp表上部門號爲10的數據行被查詢或修改時即記錄審計信息】

 

[oracle@desktop241 ~]$ sqlplus / as sysdba

SQL> select * from dba_audit_policies;

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

SCOTT                    EMP

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

FGA_ROWS_AUDIT

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

deptno=10

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

 

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

                                             YES YES NO  YES

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

NO DB+EXTENDED  ANY_COLUMNS

 

OBJECT_SCHEMA                 OBJECT_NAME

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

POLICY_NAME

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

POLICY_TEXT

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

POLICY_COLUMN                 PF_SCHEMA

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

PF_PACKAGE                  PF_FUNCTION                ENA SEL INS UPD

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

DEL AUDIT_TRAIL  POLICY_COLU

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

SQL> grant select any table to john;

 

Grant succeeded.

 

SQL> grant update any table to john;

 

Grant succeeded.

 

SQL> select timestamp,db_user,os_user,object_schema,object_name,sql_textfrom dba_fga_audit_trail;

 

no rows selected【查詢FGA審計結果】

 

[oracle@desktop241 ~]$ sqlplus john/john123

SQL> select * from scott.emp wheredeptno=10;

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7782 CLARK      MANAGER         7839 09-JUN-81          2450

      10

 

     7839 KING       PRESIDENT    17-NOV-81          5000

      10

 

     7934 MILLER     CLERK        7782 23-JAN-82          1300

      10

 

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text fromdba_fga_audit_trail;

 

TIMESTAMP   DB_USER

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

OS_USER

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

OBJECT_SCHEMA

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

OBJECT_NAME

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

SQL_TEXT

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

18-OCT-12   JOHN

oracle

SCOTT

 

TIMESTAMP   DB_USER

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

OS_USER

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

OBJECT_SCHEMA

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

OBJECT_NAME

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

SQL_TEXT

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

EMP

select * from scott.emp where deptno=10

【再查FGA審計結果】

SQL> select * from scott.emp wheredeptno=20;

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7369 SMITH      CLERK        7902 17-DEC-80           800

      20

 

     7566 JONES      MANAGER         7839 02-APR-81          2975

      20

 

     7788 SCOTT      ANALYST          7566 19-APR-87          3000

      20

 

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7876 ADAMS      CLERK       7788 23-MAY-87         1100

      20

 

     7902 FORD       ANALYST          7566 03-DEC-81          3000

      20

 

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text from dba_fga_audit_trail;

 

TIMESTAMP   DB_USER

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

OS_USER

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

OBJECT_SCHEMA

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

OBJECT_NAME

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

SQL_TEXT

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

18-OCT-12   JOHN

oracle

SCOTT

 

TIMESTAMP   DB_USER

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

OS_USER

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

OBJECT_SCHEMA

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

OBJECT_NAME

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

SQL_TEXT

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

EMP

select * from scott.emp where deptno=10

 

 

SQL>update scott.emp set sal=sal*1.1 where deptno=10;

 

3 rows updated.

 

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text fromdba_fga_audit_trail;

update scott.emp set sal=sal*1.1 wheredeptno=10

 

SQL> execdbms_fga.drop_policy('scott','emp','fga_rows_audit');

 

PL/SQL procedure successfully completed.

 

SQL> truncate table fga_log$;

 

Table truncated.

SQL> begin

 2  dbms_fga.add_policy

 3  (object_schema=>'scott',

 4  object_name=>'emp',

 5 policy_name=>'fga_columns_audit',

 6  audit_column=>'sal',

 7  enable=>true,

 8  statement_types=>'select');

 9  end;

 10  /

 

PL/SQL procedure successfully completed.

【再設FGA審計策略,當scott用戶emp表上sal列被查詢時即記錄審計信息】

測試:

SQL> select sal from scott.emp wheredeptno=10;

 

      SAL

----------

     2695

     5500

     1430

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text from dba_fga_audit_trail;

EMP

select sal from scott.emp where deptno=10

 

SQL> select ename from scott.emp wheredeptno=10;

 

ENAME

----------

CLARK

KING

MILLER

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text fromdba_fga_audit_trail;

select sal from scott.emp where deptno=10

 

SQL> select ename from scott.emp wheredeptno=10 and sal>3000;

 

ENAME

----------

KING

 

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text fromdba_fga_audit_trail;

 

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

EMP

select ename from scott.emp where deptno=10and sal>3000

 

SQL> execdbms_fga.drop_policy('scott','emp','fga_columns_audit');

 

PL/SQL procedure successfully completed.

 

SQL> truncate table fga_log$;

 

Table truncated.

 

SQL> get fga.add

 1  begin

 2  dbms_fga.add_policy

 3  (object_schema=>'scott',

 4  object_name=>'emp',

 5  policy_name=>'fga_audit',

 6 audit_condition=>'deptno=10',

 7  audit_column=>'sal',

 8  enable=>true,

 9  statement_types=>'select');

 10*end;

 11  /

 

PL/SQL procedure successfully completed.

【再設FGA審計策略,當scott用戶emp表上deptno爲10的數據庫行的sal列被查詢時即記錄審計信息。即當audit_condition與audit_column指定的條件都滿足時將進行FGA審計記錄】

測試:

SQL> select empno from scott.emp;

 

    EMPNO

----------

     7369

     7499

     7521

     7566

     7654

     7698

     7782

     7788

     7839

     7844

     7876

 

    EMPNO

----------

     7900

     7902

     7934

 

14 rows selected.

 

SQL> show user;

USER is "JOHN"

SQL> select timestamp,db_user,os_user,object_schema,object_name,sql_textfrom dba_fga_audit_trail;

 

no rows selected

SQL> select empno,sal from scott.emp;

 

    EMPNO        SAL

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

     7369    800

     7499  1600

     7521  1250

     7566  2975

      7654  1250

     7698  2850

     7782  2695

     7788  3000

     7839  5500

     7844  1500

     7876  1100

 

    EMPNO        SAL

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

     7900    950

     7902  3000

     7934  1430

 

14 rows selected.

 

SQL> select timestamp,db_user,os_user,object_schema,object_name,sql_textfrom dba_fga_audit_trail;

 

no rows selected

 

SQL_TEXT

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

EMP

select empno,sal from scott.emp

SQL> select empno,sal from scott.emp;

 

    EMPNO        SAL

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

     7369    800

     7499  1600

     7521  1250

     7566  2975

     7654  1250

     7698  2850

     7782  2450

     7788  3000

     7839  5000

     7844  1500

     7876  1100

 

    EMPNO        SAL

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

     7900    950

     7902  3000

     7934  1300

 

14 rows selected.

SQL> selecttimestamp,db_user,os_user,object_schema,object_name,sql_text fromdba_fga_audit_trail;

 

SQL> show user;

USER is "SCOTT"

 

SQL_TEXT

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

EMP

select empno,sal from scott.emp

 

SQL> execdbms_fga.drop_policy('scott','emp','fga_audit');

 

PL/SQL procedure successfully completed.

 

SQL> truncate table fga_log$;

 

Table truncated.【查自己的表記錄,sys用戶查不記錄】

強制審計

【記錄以sysdba身份登錄數據庫的動作,默認生效,不依賴於參數設置,在數據庫關閉時也同樣生效】

SQL> show parameter audit_file_dest;

 

NAME                         TYPE   VALUE

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

audit_file_dest              string   /u01/app/oracle/admin/ora10/ad

                                   ump

[oracle@desktop241 ~]$ sqlplus / as sysdba

[oracle@desktop241 ~]$ ps -ef | grepV$SPID;

oracle  30705 30589  0 22:56 pts/4    00:00:00 grep V

 

 

[oracle@desktop241 adump]$ vimora10_ora_30582_1.aud

Thu Oct 18 22:53:41 2012

LENGTH : '158'

ACTION :[7] 'CONNECT'

DATABASE USER:[1] '/'

PRIVILEGE :[6] 'SYSDBA'

CLIENT USER:[6] 'oracle'

CLIENT TERMINAL:[5] 'pts/1'

STATUS:[1] '0'

DBID:[9] '775040288'

 

VPD虛擬專用數據庫(virtual private database)

虛擬專用數據庫(VPD)提供了角色視圖無法提供的行級訪問控制,如實現每個銷售用戶登錄後只能訪問銷售表中自己的銷售中自己的銷售記錄。具體實現過程爲:

1.   先設置應用程序上下文A(應用程序上下文是一個數據庫對象,在整個session週期內保存session的各項屬性如登錄用戶名,類似於環境變量)用來保存用戶登錄時的登錄名;

2.   再在用戶登錄時由觸發器C執行預設定好的程序單元B 獲取用戶名並保存在應用程序上下文A中;

3.   預設定好的審計規則E在監控到銷售用戶執行銷售記錄的查詢語句時,由預設定好的程序單元D在用戶執行的查詢語句後隱式添加指定條件,如當銷售用戶執行select * from sales時系統自動轉換爲select * from sales where seller=’s001’;

建立測試環境

SQL> create table scott.sales(product_id varchar(4),price number,qtys number,seller varchar(4));

 

Table created.

 

SQL> insert into scott.sales values('0001',1000,1,'s001');

 

1 row created.

 

SQL> insert into scott.sales values('0002',2000,2,'s002');

 

1 row created.

 

SQL> create user s001 identified bys001;

 

User created.

 

SQL> create user s002 identified bys002;

 

User created.

 

SQL> create user mgr identified by mgr;

 

User created.

 

SQL> grant connect,resource,select anytable to s001;

 

Grant succeeded.

 

SQL> grant connect,resource,select anytable to s002;

 

Grant succeeded.

 

SQL> grant connect,resource,select anytable to mgr;

 

Grant succeeded.

[oracle@desktop241 ~]$ sqlplus s001/s001

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001        1000       1 s001

0002        2000       2 s002

 

SQL> connect s002/s002

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001        1000       1 s001

0002        2000       2 s002

 

SQL> connect mgr/mgr

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001        1000       1 s001

0002        2000       2 s002

【測試3個用戶均能查到sales銷售表中所有數據,VPD需要實現Mgr用戶能查所有數據,而s001和s002只能查到自己的銷售數據】

A.   B建立應用程序上下文A(保存登錄用戶名)和存儲過程B(獲取登錄用戶名)

SQL> connect / as sysdba

Connected.

SQL> create or replacecontext vpd_context using scott.vpd_get_username;

【建立應用程序上下文vpd_context,其中所保存的屬性由存儲過程scott.vpd_get_username(即存儲過程B)賦予】

Context created.

 

SQL> create or replaceprocedure scott.vpd_get_username is begin

  2 dbms_session.set_context('vpd_context','seller',user);

  3  end;

  4  /

【建立存儲過程,爲vpd_context建立屬性名seller,用來保存屬性值user】

Procedure created.

SQL> grant execute on scott.vpd_get_username to public;

【將存儲過程的執行權限賦給所有用戶】

Grant succeeded.

C.建立觸發器C(自動獲取登錄用戶名)

SQL>create or replace trigger get_username_on_logon

  2 after logon on database

  3 begin

  4 scott.vpd_get_username;

  5  end;

  6  /

【建立觸發器,用於用戶登錄後自動執行存儲過程vpd_get_username獲取用戶名存入應用程序上下文vpd_context中】

Trigger created.

 

SQL> connect s001/s001

Connected.

SQL> selectsys_context('vpd_context','seller')from dual;

 

SYS_CONTEXT('VPD_CONTEXT','SELLER')

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

S001

 

SQL> connect s002/s002

Connected.

SQL> selectsys_context('vpd_context','seller')from dual;

 

SYS_CONTEXT('VPD_CONTEXT','SELLER')

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

S002

 

SQL> connect mgr/mgr

Connected.

SQL> selectsys_context('vpd_context','seller')from dual;

 

SYS_CONTEXT('VPD_CONTEXT','SELLER')

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

MGR

【測試應用程序上下文vpd_context是否生效,其屬性seller中是否包含用戶名屬性值】

D.建立函數D(在用戶執行的語句後隱式添加指定條件)

SQL> create or replace function scott.vpd_add_condition

  2  (p_schema_name varchar2,p_tab_name varchar2)

  3  return varchar2 is

  4  v_namevarchar2(100):=upper(sys_context('vpd_context','seller'));

  5  v_condition varchar2(2000);

  6  begin

  7  if v_name like 's%' thenv_condition:='seller='||''''||v_name||'''';

  8                      else v_condition:=null;

 9  end if;

 10 return v_condition;

 11  end;

 12  /

 

Function created.

【建立函數D,在用戶執行的查詢語句後隱式添加指定條件。如當銷售用戶執行語句select * fromsales時系統自動轉換爲select *from sales where seller=’s001’;而當非銷售用戶mgr執行語句時,則不添加指定條件(Null),其中p_schema_name和p_tab_name兩變量值爲FGAC規則函數必須的兩個傳入參數,分別用來表示對哪個schema下的哪個table 添加FGAC規則】

FGAC即FINE_CRAINED ACCESS CONTROL,即對數據行進行過濾的VPD,即提供行級安全性的VPD,即基於行的VPD。

E.建立審計規則E(監控銷售表上執行的查詢語句)

 

SQL>begin dbms_rls.add_policy

  2 (object_schema=>'scott',

  3 object_name=>'sales',

  4 policy_name=>'fgac_vpd',

  5 function_schema=>'scott',

  6 policy_function=>'vpd_add_condition',

  7 statement_types=>'select',

  8 enable=>true);

  9  end;

 10  /

 

PL/SQL procedure successfully completed.

【建立審計規則E,監控到sales銷售表上執行查詢語句時,就調用vpd_add_condition函數進行處理】

測試結果:

 

SQL> conn S001/S001

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001         100       1 S001

 

SQL> conn scott/tiger

Connected.

SQL> select * from scott.sales;

 

no rows selected

 

SQL> conn S002/S002

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0002         200       2 S002

 

SQL> conn mgr/mgr

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001         100       1 S001

0002         200       2 S002

 

SQL> conn system/song

Connected.

SQL> select * from scott.sales;

 

no rows selected

 

SQL> conn sys/song  as sysdba

Connected.

SQL> select * from scott.sales;

 

PROD      PRICE      QTYS SELL

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

0001         100       1 S001

0002         200       2 S002

 

 

 

基於列的VPD

僅有具有權限的用戶才能訪問敏感列,敏感列,否則列數據被屏蔽

 

SQL> create or replace functionscott.vpd_col_condition

 2  (p_owner varchar2,p_objvarchar2)

 3  return varchar2 is

 4  v_condition varchar2(2000);

 5  begin

 6  if (p_owner=user)thenv_condition:=null;

 7                  elsev_condition:='1=2';

 8  end if;

 9  return v_condition;

 10  end;

 11  /

【建立規則函數,判斷執行查詢語句的用戶是不是表的屬主,是則不做限制,不是則添加條件1=2】

Function created.

 

SQL> begin dbms_rls.add_policy

 2  (object_schema=>'scott',

 3  object_name=>'emp',

 4  policy_name=>'fgac_col_vpd',

 5  function_schema=>'scott',

 6 policy_function=>'vpd_col_condition',

 7  statement_types=>'select',

 8  sec_relevant_cols=>'sal',

 9  sec_relevant_cols_opt=>dbms_rls.all_rows);

 10  end;

 11  /

 

PL/SQL procedure successfully completed.

【建立審計規則,監控到emp表上執行查詢語句時,就調用vpd_col_condition函數判斷執行查詢語句的用戶是不是表的屬主,是則不做限制,不是則對所有記錄(由參數sec_relevant_cols_opt=>dbms_rls.all_rows指定)的sal列(sec_relevant_cols=>’sal’指定)單獨添加條件1=2(即隱藏該列數據)】

SQL> conn scott/tiger

Connected.

SQL> select * from scott.emp;

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7369 SMITH      CLERK        7902 17-DEC-80           800

      20

 

     7499 ALLEN      SALESMAN        7698 20-FEB-81          1600    300

      30

 

     7521 WARD       SALESMAN       7698 22-FEB-81          1250    500

SQL> conn mgr/mgr

Connected.

SQL> select * from scott.emp;

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7369 SMITH      CLERK        7902 17-DEC-80

      20

 

     7499 ALLEN      SALESMAN        7698 20-FEB-81                  300

      30

 

     7521 WARD       SALESMAN       7698 22-FEB-81                  500

      30

SQL> conn / as sysdba

Connected.

SQL> select * from scott.emp;

 

    EMPNO ENAME      JOB          MGR HIREDATE          SAL  COMM

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

   DEPTNO

----------

     7369 SMITH      CLERK        7902 17-DEC-80           800

      20

 

     7499 ALLEN      SALESMAN        7698 20-FEB-81          1600    3

 

TDE透明數據加密(transparent database encryption)

使用VPD可對敏感信息進行保護,但無法阻止用戶直接從數據文件dump出重要信息,實際工程中常在應用程序代碼中調用特定加密函數對數據加密,但要求熟悉應用程序。

Oracle的TDE在數據寫入磁盤前調用錢包wallet文件中的密鑰自動加密數據(支持3DES168,AES128,AES192,AES256等加密算法),查詢時則調用錢包wallet文件中的密鑰自動解密,簡化了成本和複雜性,但其只將數據在存儲級別進行了加密,不能阻止用戶通過查詢語句查詢敏感數據,故應將VPD,TDE等方法結合起來保護數據。

Sys用戶的表不能被加密

SQL> host mkdir/u01/app/oracle/admin/ora10/wallet

【指定錢包默認存儲路徑】

SQL> alter system set encryption keyidentified by song;

【創建錢包文件並設置錢包訪問口令】

System altered.

 

SQL> host ls -l$ORACLE_BASE/admin/ora10/wallet/

總計 4【查看生成的錢包文件】

-rw------- 1 oracle oinstall 1309 10-1916:19 ewallet.p12

SQL> create table scott.tde(idnumber,name char(10) encrypt using 'AES128' no salt);

【利用錢包使用AES128算法對新建表 指定列進行加密,加密時不使用隨機字符串增強密碼強度( salt,使得相同明文加密後密文不同,)以使能在加密列上建立索引】

Table created.

測試:

SQL> insert into scott.tde values (0001,'aaa');

 

1 row created.

 

SQL> insert into scott.tde values(0002,'bbb');

 

1 row created.

 

SQL> insert into scott.tde values(0002,'ccc');

 

1 row created.

 

SQL> select * from scott.tde;

 

      IDNAME

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

       1 aaa

       2 bbb

       2 ccc

SQL> alter system set encryption walletclose;

 

System altered.

 

SQL> select * from scott.tde;

select * from scott.tde

                    *

ERROR at line 1:

ORA-28365: wallet is not open

 

 

SQL> select id from scott.tde;

 

      ID

----------

       1

       2

       2

 

SQL> alter system set encryption walletopen authenticated by song;

 

System altered.

 

SQL> select * from scott.tde;

 

      IDNAME

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

       1 aaa

       2 bbb

       2 ccc

 

SQL> alter table scott.tde modify namechar(10) decrypt;

【取消列加密】

Table altered.

 

SQL> alter system set encryption walletclose;

 

System altered.

 

SQL> select * from scott.tde;

 

      IDNAME

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

       1 aaa

       2 bbb

       2 ccc

加密備份數據

SQL> alter system set encryption walletopen authenticated by song;

 

System altered.

RMAN> connect target sys/song

 

connected to target database: ORA10(DBID=775040288)

using target database control file insteadof recovery catalog

 

RMAN> configure encryption for databaseon;

 

new RMAN configuration parameters:

CONFIGURE ENCRYPTION FOR DATABASE ON;

new RMAN configuration parameters aresuccessfully stored

 

RMAN> backup tablespace users;

 

Starting backup at 19-OCT-12

allocated channel: ORA_DISK_1

channel ORA_DISK_1: sid=143 devtype=DISK

channel ORA_DISK_1: starting full datafilebackupset

channel ORA_DISK_1: specifying datafile(s)in backupset

input datafile fno=00004name=/u01/app/oracle/oradata/ora10/users01.dbf

channel ORA_DISK_1: starting piece 1 at19-OCT-12

channel ORA_DISK_1: finished piece 1 at19-OCT-12

piece handle=/backup/backup_0pno5hvm_1_1 tag=TAG20121019T164022comment=NONE

channel ORA_DISK_1: backup set complete,elapsed time: 00:00:03

Finished backup at 19-OCT-12

 

Starting Control File and SPFILE Autobackupat 19-OCT-12

piecehandle=/u01/app/oracle/flash_recovery_area/ORA10/autobackup/2012_10_19/o1_mf_s_797100026_8824hysg_.bkpcomment=NONE

Finished Control File and SPFILE Autobackupat 19-OCT-12

【打開錢包,配置RMAN爲透明加密模式,則備份數據時利用錢包進行加密,恢復時也需打開錢包才能進行,適合備份和恢復都在本地進行的備份模式

RMAN> set encryption identified by song1only;

 

executing command: SET encryption

 

RMAN> backup tablespace users;

 

Starting backup at 19-OCT-12

using channel ORA_DISK_1

channel ORA_DISK_1: starting full datafilebackupset

channel ORA_DISK_1: specifying datafile(s)in backupset

input datafile fno=00004name=/u01/app/oracle/oradata/ora10/users01.dbf

channel ORA_DISK_1: starting piece 1 at19-OCT-12

channel ORA_DISK_1: finished piece 1 at19-OCT-12

piece handle=/backup/backup_0rno5i71_1_1tag=TAG20121019T164417 comment=NONE

channel ORA_DISK_1: backup set complete,elapsed time: 00:00:02

Finished backup at 19-OCT-12

 

Starting Control File and SPFILE Autobackupat 19-OCT-12

piecehandle=/u01/app/oracle/flash_recovery_area/ORA10/autobackup/2012_10_19/o1_mf_s_797100259_8824q3st_.bkpcomment=NONE

Finished Control File and SPFILE Autobackupat 19-OCT-12

【不使用錢包,配置RMAN爲密碼加密模式,則恢復時必須提供備份時所指定的密碼(set decryption)才能進行,適合備份在本地,恢復在異地的備份模式】

RMAN> set decryption identified bysong1;

 

executing command: SET decryption

 

RMAN> set encryption identified bysong2;

 

executing command: SET encryption

 

RMAN> backup tablespace users;

 

Starting backup at 19-OCT-12

using channel ORA_DISK_1

channel ORA_DISK_1: starting full datafilebackupset

channel ORA_DISK_1: specifying datafile(s)in backupset

input datafile fno=00004name=/u01/app/oracle/oradata/ora10/users01.dbf

channel ORA_DISK_1: starting piece 1 at19-OCT-12

channel ORA_DISK_1: finished piece 1 at19-OCT-12

piece handle=/backup/backup_0tno5iii_1_1tag=TAG20121019T165026 comment=NONE

channel ORA_DISK_1: backup set complete,elapsed time: 00:00:01

Finished backup at 19-OCT-12

 

Starting Control File and SPFILE Autobackupat 19-OCT-12

piecehandle=/u01/app/oracle/flash_recovery_area/ORA10/autobackup/2012_10_19/o1_mf_s_797100627_88252n6k_.bkpcomment=NONE

Finished Control File and SPFILE Autobackupat 19-OCT-12

 

RMAN> set decryption identified bysong2;

 

executing command: SET decryption

【使用錢包和密碼,配置RMAN爲混合加密模式,則恢復時打開錢包,或者提供備份時所指定的密碼均可進行,適合恢復即可能在本地,也可能在異地進行的備份模式】

LOCK   &  LATCH

Lock

獨佔鎖(X鎖)與共享鎖(S鎖)

SQL> update t1 set id=2 where id=1;

 

1 row updated.

SQL> update t1 set id=3 where id=1;

Waiting….

【爲保證數據的一致性,會話1在修改記錄時在記錄上加了獨佔鎖(exclusive,簡稱x鎖),又稱排他鎖,以防止事務在提交或回退前記錄被其他事務同時修改。

一旦用戶對某個資源添加了x鎖,則其他用戶都不能再對該資源添加任何類型的鎖,直到該用戶釋放了資源上的x鎖爲止】

 

SQL> update t1 set id=2 where id=1;

 

1 row updated.

SQL> drop table t1;

drop table t1

          *

ERROR at line 1:

ORA-00054: resource busy and acquire withNOWAIT specified

 

【爲保證數據的一致性,會話1在修改記錄時同時還在表頭上加了共享鎖(shared ,簡稱s鎖),以便其他刪表事務執行前不用檢查表中每條記錄是否加了獨佔鎖(那就不能刪表),而只要檢查表頭是否存在共享鎖就可以了

若刪表事務(要對全表加獨佔鎖)進行前,還有另一會話還進行了刪除記錄操作(且未提交或回退,即事務未結束),那麼另一會話在被刪記錄上加獨佔鎖,同時在表上再加一個共享鎖,則刪表事務要等到表頭上所有共享鎖全部取消後(即所有獨佔事務全部完成後),才能進行(才能對整表施加獨佔鎖)。

一旦用戶對某個資源添加了S鎖,則其他用戶都不能在該資源上添加X,只能添加S鎖,直到該用戶釋放了資源上的s 鎖爲止】

DML事務鎖

根據被保護的對象種類的不同,鎖還可以分成多種類型,如因DDL引起的鎖,DML事務引起的鎖,分佈式事務中涉及的鎖等,DML事務鎖應主要關注。

DML事務鎖能保證當某用戶正在更新表中某行數據時,其他用戶不能同時更新相同的數據行,而且也不能刪除或修改被更新的表,包括行鎖TX表鎖TM

 

前列修改記錄時,在行記錄上所施加的就是行(獨佔)鎖,對於ORACLE來說,行鎖只可能是獨佔鎖;而同時在表頭上所施加的就是表(共享)鎖,對於ORACLE來說,表鎖可能是共享鎖(如刪表中記錄時在表頭上所施加的共享鎖),也可能是獨佔鎖(如刪表操作時需要在表頭上所施加的獨佔鎖)。

 

TM表鎖的種類

TM表鎖即可能是獨佔鎖,也可能是共享鎖,可細分爲如下幾類:

編號                  表鎖                    含義

0/1                     無    

2                           RS                row share

3                         RX                  row exclusive

4                         S                    share

5                         SRX                    share+row  exclusive

6                            x                      exclusive

 

A.   select * from table_name不會產生鎖;

B.   lock table table_name in rowshare mode 會在表上加RS鎖,使用完畢後rollback即解鎖。

【當執行相應語句時,系統自動在所要操作的表上申請表級RS鎖(意向鎖,表示某事務有意向進行鎖表),當表上加RS鎖後,不許其他事務對該表添加x排他鎖(如drop table),但允許其他事務對該表再加除x鎖之外的其他鎖,如其他事務再對該表加RS鎖(再執行lock table in row share mode),或其他事務再對該表加RX鎖(再執行插刪改DML操作),或其他事務再對該表加S鎖(再執行建索引操作)等】

 

SQL> create table t4 (id number);

 

Table created.

 

SQL> insert into t4 values (1);

 

1 row created.

 

SQL> insert into t4 values(10);

 

1 row created.

 

SQL> commit;

 

Commit complete.

 

SQL> lock table t4 in row share mode;

 

Table(s) Locked.

 

SQL> select sid from v$mystat;

 

       SID

----------

       157

SQL> select * from v$lock where sid=157;

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

    CTIME BLOCK

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

3FB4A54C 3FB4A564 157 TM      55335     0          2       0

      116      0

 

SQL> drop table t4;

drop table t4

          *

ERROR at line 1:

ORA-00054: resource busy and acquire withNOWAIT specified

C/D/E/F.insert/update/ delete DML語句及select * from table_name for  update句會在表上加RX(其中select for update用於在讀數據過程中禁止其他事務對所讀數據進行DML操作),操作完成後commit或roback解鎖。

當執行相應語句時,系統自動在所要操作的表上申請表級RX鎖(意向鎖,表示某事務有意向要進行鎖表),當表級鎖獲得後,系統再自動申請TX行鎖(實體鎖,表示該事務的具體鎖動作),並將相應數據行加x鎖,當表上加RX鎖後,不許其他事務對該表再加X排他鎖(如drop table),不允許其他事務對該表再加S鎖(如建索引);但允許其他事務對該表再加RS鎖(如執行lock table inrow share mode)或RX鎖(如插刪改記錄,注意,其他事務在同一表上再加RX表鎖沒問題,但再加行鎖時,不能再加在表內已加X鎖的數據行上,而只許加在表內其他數據行上。

對錶施加RX鎖也可以通過手工執行Lock table table_name in rowexclusive mode進行顯示加鎖,執行後即對錶施加了RX鎖(但未對數據行申請加TX行鎖),直到rollback釋放。

RS與RX區別:

1.   產生條件不同。

2.   RX鎖後,其他事務讀不到更改後的結果。而RS對其他事務而言讀是沒有問題的,故稱RS,雖都是指在表的層面上防止其他事務鎖表,但RX是 forexclusive reading or writing,而RS是for exclusive write access.這也是RS的S(share)表現的地方。

SQL> insert into t4 values (8);

 

1 row created.

 

SQL> commit;

 

Commit complete.

 

SQL> update t4 set id=9 where id<=3;

 

4 rows updated.

 

SQL> select * from v$mystat;

 

       SID STATISTIC#     VALUE

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

       145       0          1

       145       1          1

 

SQL> select * from v$lock where sid=145;

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

     CTIME  BLOCK

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

3FB4A54C 3FB4A564 145 TM      55336     0           3       0

       131       0

 

3FB85DF8 3FB85E1C 145TX     458775   597           6       0

 

SQL> rollback;

 

SQL> select * from v$lock where sid=145;

 

ADDR    KADDR      SID TY       ID1   ID2       LMODE    REQUEST

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

     CTIME  BLOCK

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

3FB4A54C 3FB4A564 145 TM      55336     0           3       0

       172       0

 

3FB85DF8 3FB85E1C 145 TX     458775   597           6       0

       172       0

SQL> select xidusn,xidslot,xidsqn,status from v$transaction;

 

    XIDUSN    XIDSLOT   XIDSQN STATUS

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

 7      23         597 ACTIVE

 

SQL> select sid,type,id1,id2,lmode,request,block from v$lockwhere sid=145;

 

       SID TY        ID1     ID2 LMODE        REQUEST     BLOCK

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

       145 TM     55336       0      3        0       0

       145 TX     458775    597      6        0       0

 

SQL> select object_name from dba_objects where object_id='55336';

 

OBJECT_NAME

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

T4

 

SQL> select trunc(458775/power(2,16)) from dual;

 

TRUNC(458775/POWER(2,16))

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

            7

 

SQL> select bitand (458775,to_number('ffff','xxxx'))+0 from dual;

 

BITAND(458775,TO_NUMBER('FFFF','XXXX'))+0

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

                         23

 

SQL> show parameter transactions

 

NAME                          TYPE   VALUE

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

transactions                  integer 187

transactions_per_rollback_segment   integer 5

SQL> show parameter dml_locks;

 

NAME                          TYPE   VALUE

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

dml_locks                     integer 748

 

【TX數量和事務個數相同,並受transactions參數(默認187)限制,TM鎖數量和被更新的表的個數相同,並受dml_locks參數(默認748)限制,即默認情況下可同時啓動187個事務,更新748個表,平均允許每個事務同時更新4個表】

SQL> select resource_name,initial_allocation,current_utilization,max_utilizationfrom v$resource_limit where resource_name in ('transactions','dml_locks');

 

RESOURCE_NAME                 INITIAL_ALLOCATION   CURRENT_UTILIZATION

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

MAX_UTILIZATION

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

dml_locks                     748                     0

     44

 

transactions                   187                     0

      9

【查看當前TX/TM鎖的使用情況,包括能夠分配的最大個數,當前分配的個數,及曾經分配的最大個數】

SQL> update t4 set id=10 where id<10;

 

9 rows updated.

 

SQL> update t4 set id=10 where id<=10;

 

SQL> select sid,type,id1,id2,lmode,request,block from v$lockwhere sid in (145,158) order by sid desc;

 

       SID TY        ID1     ID2 LMODE        REQUEST     BLOCK

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

       158 TM     55336       0      3        0       0

       158 TX     196619    637      0        6       0

       145 TX     196619    637      6        0       1

       145 TM     55336       0      3        0       0

 

Create index on table語句會在表上加S鎖,操作完成後即解鎖。

創建索引時,需要讀表中所有數據,且在讀數據過程中數據不能由其他事務進行更新,此時需要對錶加S鎖,S鎖用於保證在操作期間整個表上不能再由其他事務加RX鎖(進行插刪改操作)及X鎖(不能刪表),因爲若在創建索引時,允許有未提交的其他插刪改事務發生,而新的數據是不會被索引的,則將造成數據和索引間的不一致。因爲S和RX鎖是互斥的,所以當某事務在表上有未提交插刪改事務時(以加RX鎖),另一事務不能創建索引(無法再加S鎖)。或者反之,當創建索引動作還沒結束時(S鎖未釋放),其他事務即不可以在表上開始插刪改事務(無法獲得RX鎖)。

當表上加S鎖後,不許其他事務對該表再加X排他鎖(如drop table),不允許其他事務對該表再加RX鎖(如插刪改記錄);但允許其他事務對該表再加RS鎖(如執行LOCK table inrow  share mode).

對錶施加S鎖也可以通過手工執行lock table table_name in share mode 進行顯式加鎖,執行後即對錶施加了S 鎖,其他事務對該表即不能進行數據插刪改及刪表操作,直到rollback釋放。

 

SQL> update t4 set id=10 where id=10;

 

0 rows updated.

 

SQL> select * from v$lock where sid=158;

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

     CTIME BLOCK

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

3FB4A608 3FB4A620 158 TM      55336     0           3       0

      21      0

 

 

SQL> create index i4 on t4 (id);

create index i4 on t4 (id)

                   *

ERROR at line 1:

ORA-00054: resource busy and acquire with NOWAIT specified

 

SQL> select * from v$lock where sid=158;

 

no rows selected

 

SQL> create index i4 on t4 (id);

create index i4 on t4 (id)

                   *

ERROR at line 1:

ORA-00054: resource busy and acquire with NOWAIT specified

SQL> lock table t4 in share mode;

 

SQL> select * from v$lock where sid in (158,145);

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

     CTIME BLOCK

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

3FB4A54C 3FB4A564 145 TM      55336     0           3       0

      2185      0

 

3FB86364 3FB86388 145 TX     196619   637           6       0

      2185      0

 

SQL> select * from v$lock where sid in (145,158,148);

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

     CTIME BLOCK

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

3FB4A54C 3FB4A564 145 TM      55336     0           5       0

       179      1

 

3FB4A6C4 3FB4A6DC     148TM      55336     0           0       3

      60      0

 

3FB4A780 3FB4A798 158 TM      55336     0           0       3

      33      0

 

 

ADDR    KADDR      SID TY        ID1   ID2       LMODE   REQUEST

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

     CTIME BLOCK

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

3FB86364 3FB86388 145 TX     458790   575           6       0

       179      0

 

如果對一個數據庫對象加SRX鎖,表示對它加S鎖,再加RX鎖,即SRX=S+RX.例如事務對某個表加SRX鎖,則表示該事務需要讀表中所有數據,且在讀數據過程中數據不能由其他事務進行更新(所以要對該表加S鎖),同時本事務會更新個別行(所以要對該表加RX鎖),注意,表上加S鎖後再由本事務加RX鎖是允許的,而表上加S鎖後再由其他事務加RX鎖是不允許的。

對錶施加SRX鎖也可以通過手工執行lock table table_name in share row exclusive mode 進行顯式加鎖,執行後即對錶施加了SRX鎖,其他事務對該表即不能進行數據插刪改及刪表操作,直到rollback釋放。

 

 

執行Alter table,drop table ,drop index,truncatetable操作時,需要對錶加X鎖,X鎖是限制級別最高的鎖。對錶加X鎖後,不能進行其他任何鎖操作。

對錶施加X鎖也可以通過手工執行lock table table_name in exclusive mode 進行顯式加鎖,執行後即對錶施加了x鎖,其他事務對該表即不能進行任何其他加鎖操作,直到rollback釋放。

死鎖deadlock

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章