首页 » ORACLE [C]系列, ORACLE 9i-23c » Oracle 12.2.0.2/Oracle 18.1 新特性: Sequence SCALE EXTEND ?

Oracle 12.2.0.2/Oracle 18.1 新特性: Sequence SCALE EXTEND ?

从Oracle 12.2版本发布以后原只以为DBBP就已是关于和以前版本PSU相关最大的改变,但是并不是, 关注我WEIBO(@weejar)的朋友知道我在6月初发布过2条关于Oracle可能将改变ORACLE的版本和补丁称呼。其中一个改季度更新为RU (Release Update)和原PSU 更名 RUR (Release Update Revision),但不适用于12.1及以前版本,这点已见证,Oracle已经于201707发布了12.2的一个RU;另一个改变可能是ORACLE12C的是18.1(12.2.0.2),在MOS 742060.1中已证实。 叫什么不重要,这里我要分享的这个新特性是12.2 已经悄悄引入但undocument的,也可能会在下个RU公布,因为RU是可以引入小的特性的(RUR不会)。

在之前的版本或现在,对于表上的主键列或唯一约束的列的填充时会使用sequence, 利用sequnece的特性防止ID编号的重复, 但是在现实中如果高并发多会话insert表只是单纯的调 用sequnect nextval时,会发现主键列或唯一列上的索引争用非常严重,造成了数据库加载时的瓶颈。 数据库中TOP event可能是enq: tx- index contention, buffer busy wait,如果是在两个节点上的insert还有可能会显示”gc”类的 热块争用事件。原因很简单就是因为索引是一种按KEY顺序存放的物理结构,在insert时所有会话问是在频繁的更新索引最后一个块(或几个块),才产生的因sequence顺序值填充index产生的索引块热块。相关的statistics是索引右侧的分裂leaf node 90-10 splits.

常用的优化手段都是围绕打散索引值,如hash partition index , reverse index. 如果使用hash也只是把1个段上的争用分摊给hash 的数量,但不能完全避免, 但是也知道对于索引如范围扫描等将不可用。对于reverse 是可以避免该类争用,但是又增加了索引维护里的I/O 次数,增加了存储的IOPS。 当然如果有一种方法可以让每个session有自己的sequence区间,这样就可以解决 该问题, 当然如果前期有考虑到该问题, 在优化时就建议应用使用如instance number+ sid + sequence的组合手动拼接数值就可以了。Oracle的强大就是与庞大的用户群合作互赢,把用户的最佳实践和需求引入ORACLE, 这个特性因为没有某些原因在12.2中都没有公开,但是SQL语法已经可用,暂时称做Sequence SCALE EXTEND 。注意公开前不建议在用户应用中使用

anbob@pdbanbob:anbob> @desc dba_sequences;
           Name                            Null?    Type
           ------------------------------- -------- ----------------------------
    1      SEQUENCE_OWNER                  NOT NULL VARCHAR2(128)
    2      SEQUENCE_NAME                   NOT NULL VARCHAR2(128)
    3      MIN_VALUE                                NUMBER
    4      MAX_VALUE                                NUMBER
    5      INCREMENT_BY                    NOT NULL NUMBER
    6      CYCLE_FLAG                               VARCHAR2(1)
    7      ORDER_FLAG                               VARCHAR2(1)
    8      CACHE_SIZE                      NOT NULL NUMBER
    9      LAST_NUMBER                     NOT NULL NUMBER
   10      SCALE_FLAG                               VARCHAR2(1)
   11      EXTEND_FLAG                              VARCHAR2(1)
   12      SESSION_FLAG                             VARCHAR2(1)
   13      KEEP_VALUE                               VARCHAR2(1)
   

anbob@pdbanbob:anbob> create sequence seq_scale maxvalue 100000 scale;
Sequence created.

anbob@pdbanbob:anbob> select seq_scale.nextval from dual;
select seq_scale.nextval from dual
       *
ERROR at line 1:
ORA-64603: NEXTVAL cannot be instantiated for SEQ_SCALE. Widen the sequence by
1 digits or alter sequence with SCALE EXTEND.

anbob@pdbanbob:anbob> alter sequence seq_scale SCALE EXTEND;
Sequence altered.

anbob@pdbanbob:anbob> set numw 30
anbob@pdbanbob:anbob>  select seq_scale.nextval from dual;
                       NEXTVAL
------------------------------
                  101147000001

1 row selected.

anbob@pdbanbob:anbob> /
                       NEXTVAL
------------------------------
                  101147000002
1 row selected.

anbob@pdbanbob:anbob> /
                       NEXTVAL
------------------------------
                  101147000003
1 row selected.


anbob@pdbanbob:anbob> col SEQUENCE_OWNER for a10
anbob@pdbanbob:anbob> col SEQUENCE_NAME for a15
anbob@pdbanbob:anbob> @seq seq_scale

SEQUENCE_O SEQUENCE_NAME    MIN_VALUE  MAX_VALUE INCREMENT_BY C O CACHE_SIZE LAST_NUMBER S E S K
---------- --------------- ---------- ---------- ------------ - - ---------- ----------- - - - -
ANBOB      SEQ_SCALE                1     100000            1 N N         20          21 Y Y N N

1 row selected.

Note:
注意到在12.2的dba_sequences里就增加了这个特性的标识列,在启用了该特性后sequnece为2大部分组成,第1部分为系统扩展区间区,第2部分和以前一样是sequece值,长度为sequence的最大长前,前补0。 对于第1部分的扩展区间因为文档未公开还不确认其数的资源来源,但可以猜。

anbob@pdbanbob:anbob> select INSTANCE_NUMBER from v$instance;
INSTANCE_NUMBER
---------------
              1

anbob@pdbanbob:anbob> select sid from v$mystat where rownum<2; SID ------------------------------ 147 1 row selected. sys@pdbanbob:anbob> @pd sequence
Show all parameters and session values from x$ksppi/x$ksppcv...

       NUM N_HEX NAME                        VALUE        DESCRIPTION
---------- ----- --------------------------- ------------ ------------------------------------------------------
      2608   A30 _pdb_use_sequence_cache     TRUE         Use sequence cache in PDB mode
      2919   B67 _kqdsn_instance_digits      2            number of instance digits in scalable sequence
      2920   B68 _kqdsn_cpu_digits           3            number of cpu digits in scalable sequence

Note:
第1部分是1位是1,目前不知道其意义
第2部分是2位的实例号,如实例1是01,实例2是02
第3部分是3位的session id,如果SID为4位以上时可以测是否是后3位还是前3位?
第4部分是sequnece最大数位前用0补齐。
并且控制第2和3部分长度的参数应该是“_kqdsn_instance_digits”和“_kqdsn_cpu_digits”。
以上只是猜测

如果启用了SCALE而未启用EXTEND,NO EXTEND区别是会把第一部分系统扩展区的长度算在最大长度内。

anbob@pdbanbob:anbob> create sequence seq_scale_noext maxvalue 1000000 scale;
Sequence created.

anbob@pdbanbob:anbob> select seq_scale_noext.nextval from dual;
   NEXTVAL
----------
   1011471
1 row selected.

anbob@pdbanbob:anbob> select seq_scale_noext.nextval from dual;
   NEXTVAL
----------
   1011472
...
...
anbob@pdbanbob:anbob> select seq_scale_noext.nextval from dual;
   NEXTVAL
----------
   1011479

anbob@pdbanbob:anbob> select seq_scale_noext.nextval from dual;
select seq_scale_noext.nextval from dual
*
ERROR at line 1:
ORA-64603: NEXTVAL cannot be instantiated for SEQ_SCALE_NOEXT. Widen the sequence by 1 digits or alter sequence with SCALE EXTEND.

anbob@pdbanbob:anbob> create sequence seq_scale_noext1 maxvalue 10000000 scale;
Sequence created.

anbob@pdbanbob:anbob> select seq_scale_noext1.nextval from dual;
   NEXTVAL
----------
  10114701

1 row selected.

Summary:
scale extend sequence这个功能非常的适用,可以有效的避免使用sequnece大并发insert时并生的索引块上的争用,包含了实例号和sid的组合及sequence的组合,只是出于某些原因并未把方法和使用公开到12.2的document中,相信在后续的版本中会公开,在公开前不建议使用在应用中。可以手动实现如

drop sequence seq_scale_nosca ;
create sequence seq_scale_nosca maxvalue 10000000;

SQL> select  to_number(sys_context('userenv','INSTANCE')||userenv('SID')||lpad(seq_scale_nosca.nextval,7,0)) from dual;
TO_NUMBER(SYS_CONTEXT('USERENV','INSTANCE')||USERENV('SID')||LPAD(SEQ_SCALE_NOSCA.NEXTVAL,7,0))
-----------------------------------------------------------------------------------------------
                                                                                     1330000001
SQL> r
TO_NUMBER(SYS_CONTEXT('USERENV','INSTANCE')||USERENV('SID')||LPAD(SEQ_SCALE_NOSCA.NEXTVAL,7,0))
-----------------------------------------------------------------------------------------------
                                                                                     1330000002
SQL> r
TO_NUMBER(SYS_CONTEXT('USERENV','INSTANCE')||USERENV('SID')||LPAD(SEQ_SCALE_NOSCA.NEXTVAL,7,0))
-----------------------------------------------------------------------------------------------
                                                                                     1330000003

打赏

,

对不起,这篇文章暂时关闭评论。