专业只做数据库实训和认证的品牌机构

微信公众号新浪微博
免费咨询电话:400-0909-964
当前位置: 网站首页 > 公开课 > Oracle 12c新特性系列专题讲座-In-Database Archiving(row archive)

Oracle 12c新特性系列专题讲座-In-Database Archiving(row archive)

文章来源: 更新时间:2019/5/28 14:43:22

在线老师点击咨询:

最新学讯:近期OCP认证正在报名中,因考试人员较多请尽快报名获取最近考试时间,报名费用请联系在线老师,甲骨文官方认证,报名从速!

我要咨询

   
    在企业的应用场景中,经常会遇到当我们不需要表中的某些行时,需要把它删除。但是有时候并不是想在物理上真正的删除这些数据,在传统的表设计中,我们一般会采用加一个额外的列来表示逻辑删除。比如is_del,当应用程序在处理时,在where条件中根据is_del的值来判断某些行是否应该被删除了。这种解决方案给维护带来了额外的开销,而且缺少灵活性。
    Oracle12c版本中增加了一个新特性叫作row archive,可以让数据库自动判断某些行数据是否为删除,这个新功能也叫作In-DatabaseArchiving(数据库内归档),这个解决方案减少了维护上的开销,而且实现起来非常简单灵活。
    简单的说数据库内归档(即行归档)就是在数据库自动创建的隐藏列上给予赋值,如果是0,说明是活跃的数据,可以被查询到,如果是非0的数据,则表示为归档的数据(即被删除的数据),查询时就不会被查询出来。行归档就像一个开关一样,数据要么是活跃的,要么是归档的,根据用户设置的归档策略数据库自动判断。 
    本文通过各种案例诠释Oracle 12c中关于ILM(数据生命周期管理)多个新特性中相对最简单的一个――数据库内归档(In-DatabaseArchiving)。
    ILM有些特性在12c版本中只有12.2版本才支持,但是行归档功能在12.1版本中就支持,而且支持多租户架构,可以在PDB中使用。


表启用行归档前后的结构变化:




/* 查看启用行归档前表的结构 */

SQL> col COLUMN_NAME for a20

SQL> col DATA_TYPE for a20

SQL> col HIDDEN_COLUMN for a10

SQL> selectCOLUMN_NAME,DATA_TYPE,HIDDEN_COLUMN FROM USER_TAB_COLS WHERE TABLE_NAME='EMP'

COLUMN_NAM DATA_TYPE            HIDDEN_COL

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

EMPNO     NUMBER               NO

ENAME     VARCHAR2             NO

JOB       VARCHAR2             NO

MGR       NUMBER               NO

HIREDATE  DATE                 NO

SAL       NUMBER               NO

COMM      NUMBER               NO

DEPTNO    NUMBER               NO

/* 启用行归档 */

SQL> alter table EMP row archival;

/* 查看启用行归档后表的结构 */

SQL> selectCOLUMN_NAME,DATA_TYPE,HIDDEN_COLUMN FROM USER_TAB_COLS WHERE TABLE_NAME='EMP'

COLUMN_NAME          DATA_TYPE            HIDDEN_COL

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

EMPNO                NUMBER               NO

ENAME                VARCHAR2             NO

JOB                  VARCHAR2             NO

MGR                  NUMBER               NO

HIREDATE             DATE                 NO

SAL                  NUMBER               NO

COMM                 NUMBER               NO

DEPTNO               NUMBER               NO

SYS_NC00009$         RAW                  YES

ORA_ARCHIVE_STATE    VARCHAR2             YES

       可以看出Oracle是使用隐藏列来实现这个功能的,在启用该特性以后,会自动在表上增加SYS_NC00009$和ORA_ARCHIVE_STATE字段,ORA_ARCHIVE_STATE是一个VARCHAR2(4000)的字段。其中SYS_NC00009$是为了以后创建函数索引的时候使用,ORA_ARCHIVE_STATE用来表示行数据的活跃状态。


启用行归档后数据查询操作

查看EMP表中的当前的数据分布:

SQL>SQL> select ename,to_char(hiredate,'yyyy-mm-dd hh24:mi:ss') from emp order byhiredate;

ENAME     TO_CHAR(HIREDATE,'Y

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

SMITH     1980-12-17 00:00:00

ALLEN     1981-02-20 00:00:00

WARD      1981-02-22 00:00:00

JONES     1981-04-02 00:00:00

BLAKE     1981-05-01 00:00:00

CLARK     1981-06-09 00:00:00

TURNER    1981-09-08 00:00:00

MARTIN    1981-09-28 00:00:00

KING      1981-11-17 00:00:00

JAMES     1981-12-03 00:00:00

FORD      1981-12-03 00:00:00

MILLER    1982-01-23 00:00:00

SCOTT     1987-04-19 00:00:00

ADAMS     1987-05-23 00:00:00

14 rows selected.

将雇佣日期在1981-05-01 00:00:00之前的记录设置为归档。可以通过使用UPDATE语句将ORA_ARCHIVE_STATE字段更新为任意非0的字符来实现。

SQL> update emp set ORA_ARCHIVE_STATE=1

      where hiredate < to_date('1981-05-0100:00:00','yyyy-mm-dd hh24:mi:ss');

4 rows updated.

查看修改状态后表的数据:

SQL> selectename,to_char(hiredate,'yyyy-mm-dd hh24:mi:ss') from emp order by hiredate;

ENAME     TO_CHAR(HIREDATE,'Y

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

BLAKE     1981-05-01 00:00:00

CLARK     1981-06-09 00:00:00

TURNER    1981-09-08 00:00:00

MARTIN    1981-09-28 00:00:00

KING      1981-11-17 00:00:00

JAMES     1981-12-03 00:00:00

FORD      1981-12-03 00:00:00

MILLER    1982-01-23 00:00:00

SCOTT     1987-04-19 00:00:00

ADAMS     1987-05-23 00:00:00

10 rows selected.      

/* 可以查看这些行的数据活跃状态标识 */

SQL> selectename,to_char(hiredate,'yyyy-mm-dd hh24:mi:ss'),ORA_ARCHIVE_STATE from emporder by hiredate;

ENAME     TO_CHAR(HIREDATE,'Y ORA_ARCHIV

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

BLAKE     1981-05-01 00:00:00 0

CLARK     1981-06-09 00:00:00 0

TURNER    1981-09-08 00:00:00 0

MARTIN    1981-09-28 00:00:00 0

KING      1981-11-17 00:00:00 0

JAMES     1981-12-03 00:00:00 0

FORD      1981-12-03 00:00:00 0

MILLER    1982-01-23 00:00:00 0

SCOTT     1987-04-19 00:00:00 0

ADAMS     1987-05-23 00:00:00 0

10 rows selected.

    通过隐藏的列的值,数据库自动判断哪些数据是活跃的,哪些是归档的,活跃的就显示,归档的就不显示,无需添加条件语句。

    可以在会话级别控制归档数据的显示情况:

/* 记录是归档的,也显示出来,注意归档的状态标识0为活跃的,非0值为归档的 */

SQL> ALTER SESSION SET ROW ARCHIVALVISIBILITY = ALL;

SQL> select ename,to_char(hiredate,'yyyy-mm-ddhh24:mi:ss'),ORA_ARCHIVE_STATE from emp order by hiredate;

ENAME     TO_CHAR(HIREDATE,'Y ORA_ARCHIV

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

SMITH     1980-12-17 00:00:00 1

ALLEN     1981-02-20 00:00:00 1

WARD      1981-02-22 00:00:00 1

JONES     1981-04-02 00:00:00 1

BLAKE     1981-05-01 00:00:00 0

CLARK     1981-06-09 00:00:00 0

TURNER    1981-09-08 00:00:00 0

MARTIN    1981-09-28 00:00:00 0

KING      1981-11-17 00:00:00 0

JAMES     1981-12-03 00:00:00 0

FORD      1981-12-03 00:00:00 0

MILLER    1982-01-23 00:00:00 0

SCOTT     1987-04-19 00:00:00 0

ADAMS     1987-05-23 00:00:00 0

14 rows selected.

/* 如果不显示归档的数据,则重新设置为默认值:*/

ALTER SESSION SET ROW ARCHIVAL VISIBILITY =ACTIVE;

Session altered.

SQL> select ename,to_char(hiredate,'yyyy-mm-ddhh24:mi:ss'),ORA_ARCHIVE_STATE from emp order by hiredate;

ENAME     TO_CHAR(HIREDATE,'Y ORA_ARCHIV

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

BLAKE     1981-05-01 00:00:00 0

CLARK     1981-06-09 00:00:00 0

TURNER    1981-09-08 00:00:00 0

MARTIN    1981-09-28 00:00:00 0

KING      1981-11-17 00:00:00 0

JAMES     1981-12-03 00:00:00 0

FORD      1981-12-03 00:00:00 0

MILLER    1982-01-23 00:00:00 0

SCOTT     1987-04-19 00:00:00 0

ADAMS     1987-05-23 00:00:00 0

10 rows selected.

 

数据更新操作

    如果会话处于ARCHIVAL VISIBILITY = ACTIVE,如果在UPDATE的时候ORA_ARCHIVE_STATE字段为非0值,则这些行不会被修改;如果需要被修改则要把参数设为ROW ARCHIVAL VISIBILITY = ALL

SQL> update emp set sal=sal+100 wherehiredate < to_date('1981-12-17 00:00:00','yyyy-mm-dd hh24:mi:ss');

0 rows updated.

如果要能够更新这些行,需要设置如下参数:

SQL> ALTER SESSION SET ROW ARCHIVALVISIBILITY = ALL;

Session altered.

SQL> update emp set sal=sal+100 wherehiredate < to_date('1981-12-17 00:00:00','yyyy-mm-dd hh24:mi:ss');

11 rows updated.

修改成功

总结:被标识为归档的数据,用select查询不出来,那么在进行update和delete操作的时候也一样无法操作。只有在会话级把ROW ARCHIVAL VISIBILITY 设置成all,才可以修改。

    那么数据库是如何处理归档的数据呢,虽然我们没有添加条件,但是数据库还是对隐藏字段进行了filter操作。即使是只显示活跃数据,也仍然需要扫描全表。这一点在真实应用中可以通过创建索引来避免全表扫描,也就是数据库内归档虽然没有显示归档的数据,但是归档的数据数据库还是会扫描的

SQL> select * from emp;

14 rows selected.

Execution Plan

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

Plan hash value: 3956160932

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

| Id | Operation         | Name |Rows  | Bytes | Cost (%CPU)| Time     |

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

|   0| SELECT STATEMENT  |      |   14 |   560 |     3  (0)| 00:00:01 |

|*  1|  TABLE ACCESS FULL| EMP  |    14|   560 |     3  (0)| 00:00:01 |

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

 

Predicate Information (identified byoperation id):

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

 

   1 -filter("EMP"."ORA_ARCHIVE_STATE"='0')

Note

-----

   -dynamic statistics used: dynamic sampling (level=2)

/* 如果使用索引扫描,看它的执行计划 */

SQL> select * from emp where empno=7788;

Execution Plan

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

Plan hash value: 2949544139

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

| Id | Operation                   |Name   | Rows  | Bytes | Cost (%CPU)| Time     |

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

|   0| SELECT STATEMENT            |        |    1 |    40 |     1  (0)| 00:00:01 |

|*  1|  TABLE ACCESS BY INDEX ROWID| EMP    |    1 |    40 |     1  (0)| 00:00:01 |

|*  2|   INDEX UNIQUE SCAN         | PK_EMP |     1 |      |     0   (0)| 00:00:01 |

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

Predicate Information (identified byoperation id):

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

   1 -filter("EMP"."ORA_ARCHIVE_STATE"='0')

   2 - access("EMPNO"=7788)

可以看出数据库用了两个条件语句。

    数据库内归档可以跟时间有效性管理一起配合使用。我们会在时间有效性的技术文章中给大家说明。

    结论:数据库内归档是一个Oracle利用隐藏字段实现的非常简单的功能,但是数据架构人员在规划的时候一定要考虑性能因素,不显示不代表不扫描。

    如果EMP表不想再使用归档方式管理行数据,可以禁用这个功能:

/* 查看禁用行归档 */

SQL> alter table EMP no row archival;

/* 查看禁用行归档后表的结构 */

SQL> selectCOLUMN_NAME,DATA_TYPE,HIDDEN_COLUMN FROM USER_TAB_COLS WHERE TABLE_NAME='EMP'

COLUMN_NAME          DATA_TYPE            HIDDEN_COL

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

EMPNO                NUMBER               NO

ENAME                VARCHAR2             NO

JOB                  VARCHAR2             NO

MGR                  NUMBER               NO

HIREDATE             DATE                 NO

SAL                  NUMBER               NO

COMM                 NUMBER               NO

DEPTNO               NUMBER               NO

 可以看出原来在表上增加SYS_NC00009$和ORA_ARCHIVE_STATE字段被自动删除了。

思考题:

Which two statements are true when row archival management is enabled?
A.The ORA_ARCHIVE_STATE column visibility is controlled by the ROW ARCHIVAL VISIBILITY session parameter.
B.The ORA_ARCHIVE_STATE column is updated manually or by a program that could reference activity tracking columns, to indicate that a row is no longer considered active.
C.The ROW ARCHIVAL VISIBILITY session parameter defaults to active rows only.
D.The ORA_ARCHIVE_STATE column is visible if referenced in t he select list of a query.
E.The ORA_ARCHIVE_STATE column is updated automatically by the Oracle Server based on activity tracking columns, to Indicate that a row is no longer considered active.
 
上一期思考题答案:
Which three tasks can be automatically performed by the Automatic Data Optimization feature of Information lifecycle Management (ILM)?
A. Tracking the most recent read time for a table segment in a user tablespace
B. Tracking the most recent write time for a table segment in a user tablespace
C. Tracking insert time by row for table rows
D. Tracking the most recent write time for a table block
E. Tracking the most recent read time for a table segment in t he SYSTEM tablespace
F. Tracking the most recent write time for a table segment in t he SYSAUX tablespace
Anser:ABD
(解析:启用热图后,内存活动跟踪模块将跟踪所有访问。不跟踪SYSTEM和SYSAUX表空间中的对象)


本篇文章作者介绍:Oracle金牌讲师

北京优技教育科技有限公司
培训机构创始人、Oracle技术首席讲师

自2000年就职于CUUG从事于Oracle的授课和维护工作,经过多年辗转于2006年再度回到CUUG担任Oracle技术讲师,多年的Oracle工作经验,坚持不懈的学习Oracle新的技术,通过举办Oracle技术沙龙(总共累积50多场),向广大Oracle爱好者传播最新、主流的Oracle技术,为推广Oracle认证做了很多工作,每年培训出众多的Oracle技术人才,为Oracle技术推广和Oracle认证普有着杰出的贡献和突出影响力。

“Oracle WDP项目为个人学习Oracle技术提供了良好的学习途径,对Oracle的普及起到了巨大的作用,很多人通过这个途径学到了Oracle的技术,找到了满意的工作,实现了人生的价值。”


本文地址:http://www.cuug.com.cn/gongkaike/21527542609.html 转载请注明!


在线预约 抢先报名 获取课程排期

Oracle培训机构

金牌讲师<>

冉乃纲-老师CUUG金牌讲师
冉老师 CUUG金牌讲师 Oracle及RedHat高级讲师、Unix/Linux 资深专家...[详细了解老师]

免费咨询上课流程 客服在线中

陈卫星-老师CUUG金牌讲师
陈老师 CUUG金牌讲师 精通Oracle管理、备份恢复、性能优化 11年Ora...[详细了解老师]

免费咨询上课流程 客服在线中

选学校如何选择适合自己的学校

CUUG -CHINA UNIX USER GROUP,是国际UNIX组织UNIFORUM的中国代表,是国内悠久的专业UNIX培训机构,被誉为中国UNIX 的摇篮。多年来,以提高教学质量为本,强调素质教育,积极引进、消化国外的新技术,有效的结合中国....[详情]

一站式服务(从入学到就业一帮到底)

入学

学习

就业

实操

食宿
地址:北京市海淀区北清路164号28-38号院
课程咨询:010-59426307 010-59426319 400-0909-964
企业服务:137 1818 8639(陈经理)
部分信息来源于网络,如有错误请联系指正!
版权所有@北京神脑资讯技术有限公司 (CUUG,中国UNIX用户协会) Copyright 2016 ALL Rights Reserved 京ICP备11008061号-1