zoukankan      html  css  js  c++  java
  • [20201126]11g VPD的问题.txt

    [20201126]11g VPD的问题.txt

    --//链接https://hourim.wordpress.com/2020/09/30/ddl-optimization-and-vpd/提到的问题在测试环境测试看看。
    --//你可以查看中文版本更加详细的介绍10g,11g与12c增加列的一些操作方式上的变化:
    --//https://www.oracle.com/technetwork/cn/articles/database/ddl-optimizaton-in-odb12c-2331068-zhs.html
    --//我仅仅测试11g环境。

    1.环境:
    SCOTT@book> @ ver1
    PORT_STRING                    VERSION        BANNER
    ------------------------------ -------------- --------------------------------------------------------------------------------
    x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

    2.建立测试:
    SCOTT@book> create table t1 as select rownum n1, lpad('x',5) v1 from dual connect by level <=5;
    Table created.
    --//分析表略。

    SCOTT@book>  alter table t1 add c1 number default 42 not null;
    Table altered.

    SCOTT@book> alter session set statistics_level = all;
    Session altered.

    SCOTT@book> select count(1) from t1 where c1=42;
      COUNT(1)
    ----------
             5

    SCOTT@book> @ dpc '' ''
    PLAN_TABLE_OUTPUT
    -------------------------------------
    SQL_ID  a4v8hg2qxzp1g, child number 0
    -------------------------------------
    select count(1) from t1 where c1=42
    Plan hash value: 3724264953
    ---------------------------------------------------------------------------------------------------------------------
    | Id  | Operation          | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
    ---------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |      1 |        |       |     3 (100)|          |      1 |00:00:00.01 |       3 |
    |   1 |  SORT AGGREGATE    |      |      1 |      1 |    13 |            |          |      1 |00:00:00.01 |       3 |
    |*  2 |   TABLE ACCESS FULL| T1   |      1 |      5 |    65 |     3   (0)| 00:00:01 |      5 |00:00:00.01 |       3 |
    ---------------------------------------------------------------------------------------------------------------------
    Query Block Name / Object Alias (identified by operation id):
    -------------------------------------------------------------
       1 - SEL$1
       2 - SEL$1 / T1@SEL$1
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - filter(NVL("C1",42)=42)

    --//注意filter条件。是NVL("C1",42)=42。因为这个字段并不保存在数据段中。

    3.建立VPD policy:
    SCOTT@book> select sys_context('USERENV','LANG') from dual;
    SYS_CONTEXT('USERENV','LANG')
    -----------------------------
    US

    create or replace function
        f_t1_policy(piv_schema in varchar2
                   ,piv_object in varchar2)
    return varchar2
    is
      lv_return_value varchar2(4000);
    begin
      if sys_context('USERENV','LANG') = 'US'
      then
        lv_return_value := '1=1';
      else
        lv_return_value := '1=0';
      end if;
       return lv_return_value;
    end f_t1_policy;
    /
    --//也就是测试返回 lv_return_value := '1=1';

    -- assign this policy to t1 table
    begin
     dbms_rls.add_policy
       (object_schema    => user,
        object_name      => 'T1',
           policy_name      => 'F_T1_POLICY',
           function_schema    => user,
           policy_function  => 'F_T1_POLICY',
           statement_types  => 'SELECT'
        );
    end;
    /

    SCOTT@book> alter table t1 add c2 number default 43 not null;
    Table altered.

    SCOTT@book> select count(1) from t1 where c2=43;
      COUNT(1)
    ----------
             5
    --//嗯,我的测试是ok的。

    SCOTT@book> @ dpc '' ''
    PLAN_TABLE_OUTPUT
    -------------------------------------
    SQL_ID  6vk08skyq9v43, child number 0
    -------------------------------------
    select count(1) from t1 where c2=43
    Plan hash value: 3724264953
    ---------------------------------------------------------------------------------------------------------------------
    | Id  | Operation          | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |
    ---------------------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |      1 |        |       |     3 (100)|          |      1 |00:00:00.01 |       2 |
    |   1 |  SORT AGGREGATE    |      |      1 |      1 |    12 |            |          |      1 |00:00:00.01 |       2 |
    |*  2 |   TABLE ACCESS FULL| T1   |      1 |      1 |    12 |     3   (0)| 00:00:01 |      5 |00:00:00.01 |       2 |
    ---------------------------------------------------------------------------------------------------------------------
    Query Block Name / Object Alias (identified by operation id):
    -------------------------------------------------------------
       1 - SEL$F5BB74E1
       2 - SEL$F5BB74E1 / T1@SEL$2
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - filter("C2"=43)
    --//注意过滤条件"C2"=43。这样就奇怪了,明明过滤条件是C2=43,按照前面的测试如果数据不在段中,应该count(1)是0才对啊。

    4.继续探究:
    SCOTT@book> select rowid,t1.* from t1 where rownum=1;
    ROWID                      N1 V1            C1         C2
    ------------------ ---------- ----- ---------- ----------
    AAAXJRAAEAAAAILAAA          1     x         42         43

    SCOTT@book> @ rowid AAAXJRAAEAAAAILAAA
        OBJECT       FILE      BLOCK        ROW ROWID_DBA            DBA                  TEXT
    ---------- ---------- ---------- ---------- -------------------- -------------------- ----------------------------------------
         94801          4        523          0  0x100020B           4,523                alter system dump datafile 4 block 523 ;


    --//通过bbed观察,注意执行一次刷新数据缓存,不然看到的可能不真实。
    SCOTT@book> alter system flush buffer_cache;
    System altered.

    BBED> x  /rncnn dba  4,523 *kdbr[1]
    rowdata[48]                                 @8096
    -----------
    flag@8096: 0x2c (KDRHFL, KDRHFF, KDRHFH)
    lock@8097: 0x02
    cols@8098:    4

    col    0[2] @8099: 2
    col    1[5] @8102:     x
    col    2[0] @8108: *NULL*
    col    3[2] @8109: 43
    --//噢,注意看第4个字段通过类似的方式加入表中,而rls的存在改变的操作模式直接插入到数据段中。

    SCOTT@book> column BINARYDEFVAL format a20
    SCOTT@book> select * from sys.ecol$;
       TABOBJ#     COLNUM BINARYDEFVAL
    ---------- ---------- --------------------
         94801          3 C12B

    --//启用rls后,在数据字段sys.ecol$,仅仅出现字段3.
    --//注42的oracle数字编码就是C12B。

    SCOTT@book> select dump(42,16),dump(43,16) from dual ;
    DUMP(42,16)        DUMP(43,16)
    ------------------ ------------------
    Typ=2 Len=2: c1,2b Typ=2 Len=2: c1,2c

    --//也就是这样操作模式可能会导致表产生大量的redo,甚至影响前台的操作,在工作中要引起注意。
    --//作者的测试在19c上视乎遇到了bug,不过对方还提到sys用户的一些情况我也测试看看。

    SYS@book> show user
    USER is "SYS"

    SYS@book> alter table scott.t1 add c3 number default 44 not null;
    Table altered.

    SYS@book> select count(1) from scott.t1 where c3=44;
      COUNT(1)
    ----------
             5
    --//OK,正确。

    SYS@book> @ dpc '' ''
    PLAN_TABLE_OUTPUT
    -------------------------------------
    SQL_ID  92qghqsahftp5, child number 0
    -------------------------------------
    select count(1) from scott.t1 where c3=44
    Plan hash value: 3724264953
    ----------------------------------------------------------------------------
    | Id  | Operation          | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time   |
    ----------------------------------------------------------------------------
    |   0 | SELECT STATEMENT   |      |        |       |     3 (100)|          |
    |   1 |  SORT AGGREGATE    |      |      1 |    12 |            |          |
    |*  2 |   TABLE ACCESS FULL| T1   |      1 |    12 |     3   (0)| 00:00:01 |
    ----------------------------------------------------------------------------
    Query Block Name / Object Alias (identified by operation id):
    -------------------------------------------------------------
       1 - SEL$1
       2 - SEL$1 / T1@SEL$1
    Predicate Information (identified by operation id):
    ---------------------------------------------------
       2 - filter(NVL("C3",44)=44)

    --//注意看过滤条件。现在是filter(NVL("C3",44)=44)。

    SCOTT@book> select * from sys.ecol$;
       TABOBJ#     COLNUM BINARYDEFVAL
    ---------- ---------- --------------------
         94801          3 C12B
         94801          5 C12D
    --//也就是以sys用户操作缺省值记录在sys.ecol$中,绕过了这个问题。

    SCOTT@book> @ desc_proc sys dbms_rls DROP_POLICY
    INPUT OWNER PACKAGE_NAME OBJECT_NAME
    sample : @desc_proc sys dbms_stats gather_%_stats
    OWNER      PACKAGE_NAME         OBJECT_NAME SEQUENCE ARGUMENT_NAME DATA_TYPE IN_OUT    DEFAULTED
    ---------- -------------------- ----------- -------- ------------- --------- --------- ----------
    SYS        DBMS_RLS             DROP_POLICY        3 POLICY_NAME   VARCHAR2  IN        N
                                                       1 OBJECT_SCHEMA VARCHAR2  IN        Y
                                                       2 OBJECT_NAME   VARCHAR2  IN        N

    SCOTT@book> exec    dbms_rls.drop_policy (object_schema=> user,object_name=> 'T1',  policy_name=> 'F_T1_POLICY');
    PL/SQL procedure successfully completed.
                                                                            
    SCOTT@book> alter table t1 add c4 number default 45 not null;
    Table altered.

    SCOTT@book> select * from sys.ecol$;
       TABOBJ#     COLNUM BINARYDEFVAL
    ---------- ---------- --------------------
         94801          6 C12E
         94801          3 C12B
         94801          5 C12D
    --//这样就不会出现前面遇到的情况。

  • 相关阅读:
    MAC下MAMP安装php扩展教程记录
    公司通知正式上班邀请函 3分钟生成微信通知h5邀请函
    H5是什么?H5是否等于HTML5???
    浏览器渲染机制
    小程序后台布局,B站的经典写法
    原创:子组件传递数据给父组件
    父组件传递数据给自定义子组件过程
    原创: 自定义tabs切换组件并使用(微信小程序中
    原创: SpringBoot中filter的使用详解及原理
    若依官方文档 集成jwt实现登录授权访问,返回SysUser对象更多信息给前端
  • 原文地址:https://www.cnblogs.com/lfree/p/14040765.html
Copyright © 2011-2022 走看看