oracle12c 日志分析,Oracle(12c)使用LogMiner分析Redo日志文件

Oracle 12c LogMiner 分析Redo日志详解
Oracle LogMiner工具允许通过SQL接口在线查询和分析Redo日志文件,用于数据审核、复杂数据分析、数据库错误定位及性能调整。它能追踪DML和DDL语句,提供事务级别的恢复信息。LogMiner操作涉及配置字典、指定日志文件、启动和结束分析。使用时需注意选择合适的字典选项,如在线目录、重做日志文件或平面文件,并确保正确指定Redo日志文件。

内容:

官方文档(https://docs.oracle.com/database/121/SUTIL/GUID-3417B738-374C-4EE3-B15C-3A66E01AE2B5.htm#SUTIL019)

Oracle LogMiner是Oracle数据库的一部分,它允许你通过SQL接口在线查询和归档Redo日志文件。Redo日志文件包含关于数据库活动历史的信息。

# LogMiner Benefits

对用户数据或数据库字典所做的所有更改都记录在Oracle redo日志文件中,以便可以执行数据库恢复操作。

由于LogMiner为Redo 日志文件提供了定义明确,易于使用且全面的关系接口,因此它既可以用作功能强大的数据审核工具,又可以用作复杂的数据分析工具。以下列表描述了LogMiner的一些关键功能:查明数据库何时发生了逻辑损坏(例如在应用程序级别发生的错误)。这些错误可能包括以下错误:由于WHERE子句中的值不正确而删除了错误的行,使用不正确的值更新了行,删除了错误的索引等等。例如,用户应用程序可能会错误地更新数据库,以使所有员工的工资增加100%,而不是增加10%,或者数据库管理员(DBA)可能会意外删除关键系统表。重要的是准确知道何时发生错误,以便知道何时启动基于时间或基于更改的恢复。这使我们可以将数据库还原到损坏之前的状态。更加详细的参阅Querying V$LOGMNR_CONTENTS Based on Column Values。

确定在事务级别执行细粒度恢复所需采取的操作。如果你完全理解并考虑了现有的依赖关系,则可以执行特定于表的撤消操作以将表返回到其原始状态。这是通过应用LogMiner提供的特定于表的重建SQL语句来实现的。更加详细的参阅Scenario 1: Using LogMiner to Track Changes Made by a Specific User。

通常,您必须将表还原到以前的状态,然后应用存档的重做日志文件将其前滚。

通过趋势分析进行性能调整和容量规划。您可以确定哪些表有最多的更新和插入。该信息提供了有关磁盘历史访问统计信息,可用于调整目的。有关示例,请参见"Scenario 2: Using LogMiner to Calculate Table Access Statistics

执行后审核。LogMiner可用于跟踪在数据库上执行的任何数据操作语言(DML)和数据定义语言(DDL)语句,和它们的执行顺序以及执行者。(但是,要使用LogMiner达到此目的,您需要了解事件发生的时间,以便可以指定适当的日志进行分析;否则,您可能必须挖掘大量的Redo日志文件,这可能需要长时间。考虑将LogMiner用作审核数据库使用情况的补充活动。有关数据库审核的信息,请参阅Oracle数据库管理员指南。

# Introduction to LogMiner

# LogMiner Configuration

你应该熟悉LogMiner配置中的四个基本对象:源数据库(source database),挖掘数据库(mining database),LogMiner词典(LogMiner dictionary)以及包含感兴趣数据的Redo日志文件(redo log files):源数据库是生成您希望LogMiner分析的所有重做日志文件的数据库。

挖掘数据库是LogMiner执行分析时使用的数据库。

LogMiner字典允许LogMiner在显示您请求的重做日志数据时提供表名和列名,而不是内部对象id。

LogMiner使用字典将内部对象标识符和数据类型转换为对象名称和外部数据格式。如果没有字典,LogMiner将返回内部对象id并以二进制数据的形式显示数据。

例如,考虑以下SQL语句:

INSERT INTO HR.JOBS(JOB_ID, JOB_TITLE, MIN_SALARY, MAX_SALARY) VALUES('IT_WT','Technical Writer', 4000, 11000);

没有字典,LogMiner会显示:

insert into "UNKNOWN"."OBJ# 45522"("COL 1","COL 2","COL 3","COL 4") values

(HEXTORAW('45465f4748'),HEXTORAW('546563686e6963616c20577269746572'),

HEXTORAW('c229'),HEXTORAW('c3020b'));

重做日志文件包含对数据库或数据库字典所做的更改。

# Directing LogMiner Operations and Retrieving Data of Interest

你可以直接使用LogMinerDBMS_LOGMNR and DBMS_LOGMNR_D PL/SQL程序包, 并使用 V$LOGMNR_CONTENTS视图, 如下:指定LogMiner字典.

使用DBMS_LOGMNR_D.BUILD程序生成或者当启动LogMiner(第三步)时指定数据字典,或者同时使用。具体取决于你想使用哪种数据字典。

指定要分析的Redo日志列表

使用DBMS_LOGMNR.ADD_LOGFILE程序添加或者当启动LogMiner(第三步)时自动创建要分析的日志文件列表

启动LogMiner.

使用 DBMS_LOGMNR.START_LOGMNR程序 .

获取想要的数据.

查询V$LOGMNR_CONTENTS视图.

结束LogMiner会话.

使用DBMS_LOGMNR.END_LOGMNR程序.

你必须拥有EXECUTE_CATALOG_ROLE角色和 LOGMINING的权限去查询V$LOGMNR_CONTENTS视图和使用LogMiner PL/SQL 程序包 .

注意:

在由Oracle RAC数据库生成的归档日志中挖掘指定时间或感兴趣的SCN范围时,必须确保已从该时间段或SCN范围内处于活动状态的所有重做线程指定了所有归档日志。如果您无法执行此操作,则所有V$LOGMNR_CONTENTS返回部分结果的查询都将仅返回部分结果(基于通过该DBMS_LOGMNR.ADD_LOGFILE过程指定给LogMiner的存档日志)。使用该CONTINUOUS_MINE选项在源数据库中挖掘归档日志时,此限制也有效。CONTINUOUS_MINE如果没有启用或禁用线程,则仅应在Oracle RAC数据库上使用。

您可以使用 DBMS_LOGMNR 和 DBMS_LOGMNR_D PL / SQL程序包,并使用 V$LOGMNR_CONTENTS 视图如下:

指定LogMiner字典。

使用 DBMS_LOGMNR_D.BUILD 在启动LogMiner时(在第3步中)或同时指定两者,这取决于您打算使用的字典类型。

指定重做日志文件列表以进行分析。

使用 DBMS_LOGMNR.ADD_LOGFILE 步骤,或指示LogMiner在启动LogMiner时自动创建要分析的日志文件列表(在步骤3中)。

启动LogMiner。

使用 DBMS_LOGMNR.START_LOGMNR 程序。

请求感兴趣的重做数据。

查询V$LOGMNR_CONTENTS视图。

结束LogMiner会话。

使用 DBMS_LOGMNR.END_LOGMNR 程序。

您必须具有查询视图和使用LogMiner PL / SQL包的EXECUTE_CATALOG_ROLE角色和LOGMINING特权V$LOGMNR_CONTENTS。

注意:

在由Oracle RAC数据库生成的归档日志中挖掘指定时间或感兴趣的SCN范围时,必须确保已从该时间段或SCN范围内处于活动状态的所有重做线程指定了所有归档日志。如果您无法执行此操作,则所有V$LOGMNR_CONTENTS返回部分结果的查询都将仅返回部分结果(基于通过该DBMS_LOGMNR.ADD_LOGFILE过程指定给LogMiner的存档日志)。使用该CONTINUOUS_MINE选项在源数据库中挖掘归档日志时,此限制也有效。CONTINUOUS_MINE如果没有启用或禁用线程,则仅应在Oracle RAC数据库上使用。

也可以看看:

有关使用LogMiner的示例,请参见 典型LogMiner会话中的步骤

# Using LogMiner in a CDB

LogMiner可以在多租户容器数据库(CDB)中使用,但是下面的小节讨论了在CDB中使用LogMiner与在非CDB中使用LogMiner时需要注意的一些区别:

# LogMiner V$ Views and DBA Views in a CDB

在CDB中,LogMiner用于显示有关在系统中运行的LogMiner会话的信息的视图包含一个名为CON_ID的附加列。此列标识与显示其信息的会话相关联的容器ID。当从可插拔数据库(PDB)查询视图时,只显示与数据库相关的信息。以下视图受此新行为影响:V$LOGMNR_DICTIONARY_LOAD

V$LOGMNR_LATCH

V$LOGMNR_PROCESS

V$LOGMNR_SESSION

V$LOGMNR_STATS

为了支持CDBs, 除了CON_ID之外V$LOGMNR_CONTENTS视图还有其他几个新列 The V$LOGMNR_CONTENTS View in a CDB".

以下DBA视图具有类似的CDB视图,其名称以CDB开头。DBA ViewCDB_ ViewDBA_LOGMNR_LOGCDB_LOGMNR_LOG

DBA_LOGMNR_PURGED_LOGCDB_LOGMNR_PURGED_LOG

DBA_LOGMNR_SESSIONCDB_LOGMNR_SESSION

DBA视图只显示与查询它们的容器中定义的会话相关的信息。

CDB视图包含一个附加的CON_ID列,它标识给定行所代表数据的容器。从根目录查询CDB视图时,可以使用它们查看所有容器的信息。

# The V$LOGMNR_CONTENTS View in a CDB

在CDB中,V$LOGMNR_CONTENTS视图及其相关函数被限制在根数据库中。为支持CDBs,在视图中新增了几列:CON_ID - 包含与执行查询的容器相关联的ID。因为V$LOGMNR_CONTENTS被限制在根数据库中,所以当在CDB上执行查询时,该列返回一个值1。

SRC_CON_NAME - PDB的名字。此信息仅在使用LogMiner字典进行挖掘时可用。

SRC_CON_ID - 生成重做记录的PDB的容器ID。此信息仅在使用LogMiner字典进行挖掘时可用。

SRC_CON_DBID - PDB标识符。此信息仅在使用当前LogMiner字典进行挖掘时可用。

SRC_CON_GUID - 包含与PDB关联的GUID。此信息仅在使用当前LogMiner字典进行挖掘时可用。

在信息没有意义的情况下,这些列可能并不总是返回值。当在非cdb中进行挖掘时,SRC_CON_xxx列为空。

# Enabling Supplemental Logging in a CDB

在CDB中,启用和禁用数据库范围的补充日志记录的语法与在非CDB数据库中相同:

ALTER DATABASE [ADD|DROP] SUPPLEMENTAL LOG DATA ...

注意:在CDB中,从CDB$ROOT启用的补充日志记录级别在整个CDB中启用。

如果至少在CDB$ROOT中启用了最低限度的补充日志记录,那么可以在PDB级别启用额外的补充日志记录级别。

在PDB级别上不能禁用CDB$ROOT在CDB级别启用的补充日志记录级别。

从CDB$ROOT中删除所有补充日志记录将禁用整个CDB的所有补充日志记录,而不考虑以前的PDB级别设置。

从CREATE TABLE和ALTER TABLE语句开始的附加日志操作可以在根数据库或PDB中执行,只影响它们所应用的表。

要管理多租户环境,您必须具有CDB_DBA角色。

获取更加详细信息请参考:Oracle Database Concepts for more information about CDBs

Oracle Database Reference for more information about views

Oracle Database Security Guide for more information about privileges and roles in CDBs and PDBs

# LogMiner Dictionary Files and Redo Log Files

在开始使用LogMiner之前,了解LogMiner如何使用LogMiner字典文件(或多个文件)和重做日志文件是很重要的。这将帮助您获得准确的结果并计划系统资源的使用。

# LogMiner Dictionary Options

当ogMiner返回重做数据时,它需要一个字典来将对象id转换成对象名。LogMiner提供了三个提供字典的选项:

# Using the Online Catalog

要指示LogMiner使用当前数据库中使用的字典,在启动LogMiner时指定源数据库数据字典,如下所示:

EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG);

除了使用源数据库数据字典分析联机重做日志文件外,如果您在生成归档重做日志文件的同一系统上,还可以使用源数据库数据字典分析归档重做日志文件。

源数据库数据字典包含关于数据库的最新信息,可能是开始分析的最快方法。因为更改重要表的DDL操作比较少见,所以源数据库数据字典通常包含分析所需的信息。

但是,请记住,源数据库数据字典只能重构在表的最新版本上执行的SQL语句。一旦表被更改,源数据库数据字典就不再反映表的前一个版本。这意味着LogMiner将无法重构在表的前一个版本上执行的任何SQL语句。相反,LogMiner在V$LOGMNR_CONTENTS视图的SQL_REDO列中生成不可执行的SQL(包括二进制值的十六进制到原始格式),类似于下面的示例:

insert into HR.EMPLOYEES(col

hextoraw('c306'));"

联机目录选项要求数据库是打开的。源数据库数据字典对于DBMS_LOGMNR.START_LOGMNR的DDL_DICT_TRACKING选项无效。

Oracle建议,当您可以访问创建重做日志文件的源数据库时,以及在预期不会更改相关表中的列定义时,使用此选项。这是最有效和最容易使用的选择。

# Extracting a LogMiner Dictionary to the Redo Log Files

要将LogMiner字典提取到重做日志文件中,必须打开数据库,并且必须启用ARCHIVELOG模式和归档。当字典被提取到重做日志流时,不能执行DDL语句。因此,提取到重做日志文件的字典保证是一致的(而提取到平面文件的字典则不是)。

要将字典信息提取到重做日志文件中,请执行PL/SQL DBMS_LOGMNR_D。使用STORE_IN_REDO_LOGS选项构建过程。不要指定文件名或位置。

EXECUTE DBMS_LOGMNR_D.BUILD(OPTIONS=> DBMS_LOGMNR_D.STORE_IN_REDO_LOGS);

See Also:Oracle Database Administrator's Guide for more information about ARCHIVELOG mode

将字典提取到重做日志文件的过程确实会消耗数据库资源,但是如果将提取限制在非高峰时间,那么这应该不是问题,而且它比提取到平面文件要快。根据字典的大小,它可能包含在多个重做日志文件中。如果相关的重做日志文件已经存档,那么您可以找出哪些重做日志文件包含提取的字典的开始和结束。为此,查询V$ARCHIVED_LOG视图,如下所示:

SELECT NAME FROM V$ARCHIVED_LOG WHERE DICTIONARY_BEGIN='YES';

SELECT NAME FROM V$ARCHIVED_LOG WHERE DICTIONARY_END='YES';

在准备开始LogMiner会话时,使用ADD_LOGFILE过程指定开始和结束重做日志文件的名称,以及它们之间可能的其他日志。

Oracle建议您定期备份重做日志文件,以便保存信息并在以后使用。理想情况下,这不会涉及任何额外的步骤,因为如果您的数据库得到了正确的管理,那么应该已经有了备份和恢复归档重做日志文件的过程。同样,由于所需的时间,最好在非高峰时间这样做。

Oracle建议,当您不希望访问创建重做日志文件的源数据库时,或者如果您预期将对相关表中的列定义进行更改时,请使用此选项。

# Extracting the LogMiner Dictionary to a Flat File

当LogMiner字典位于平面文件中时,使用的系统资源要比包含在重做日志文件中时少。Oracle建议您定期备份字典提取,以确保对旧的重做日志文件的正确分析。

要将数据库字典信息提取到平面文件中,使用DBMS_LOGMNR_D。使用STORE_IN_FLAT_FILE选项构建过程。

确保在构建字典时没有发生DDL操作。

以下步骤描述如何将字典提取到平面文件中。步骤1和步骤2是准备步骤。您只需要执行一次,然后就可以根据需要多次将字典解压缩到平面文件中。DBMS_LOGMNR_D构建过程需要访问一个可以放置字典文件的目录。因为PL/SQL过程通常不访问用户目录,所以必须指定DBMS_LOGMNR_D使用的目录。要指定一个目录,请在初始化参数文件中设置初始化参数UTL_FILE_DIR。例如,要将UTL_FILE_DIR设置为使用/oracle/database作为字典文件所在的目录,请在初始化参数文件中放置以下内容:

UTL_FILE_DIR = /oracle/database

请记住,要使初始化参数文件的更改生效,必须停止并重新启动数据库。

如果数据库已关闭,则使用SQL*Plus挂载并打开要分析其重做日志文件的数据库。例如,输入SQL STARTUP命令挂载并打开数据库:

STARTUP

执行PL/SQL过程DBMS_LOGMNR_D.BUILD来指定字典的文件名和文件的目录路径名。这个过程创建字典文件。例如,输入以下内容来在/oracle/database目录中创建dictionary.ora:

EXECUTE DBMS_LOGMNR_D.BUILD('dictionary.ora', -

'/oracle/database/', -

DBMS_LOGMNR_D.STORE_IN_FLAT_FILE);

您还可以只指定文件名和位置,而不需要指定STORE_IN_FLAT_FILE选项。结果是一样的。

这个选项是为了向后兼容以前的版本而保留的。此选项不保证事务一致性。Oracle建议您使用在线目录或从重做日志文件中提取字典。

如下图显示一个决策树,根据您的情况帮助您选择LogMiner字典。

# Redo Log File Options

要在重做日志文件中挖掘数据,LogMiner需要关于要挖掘哪些重做日志文件的信息。在这些重做日志文件中对数据库所做的更改将通过V$LOGMNR_CONTENTS视图传递给你。

您可以指示LogMiner自动地、动态地创建要分析的重做日志文件列表,或者您可以显式地指定要分析的重做日志文件列表,如下所示:Automatically

如果在源数据库上使用LogMiner,则可以指示LogMiner自动查找和创建用于分析的重做日志文件列表。使用DBMS_LOGMNR启动LogMiner时,请使用CONTINUOUS_MINE选项。START_LOGMNR过程,并指定时间或SCN范围。虽然本例指定了在线目录中的字典,但是任何LogMiner字典都可以使用。注意:CONTINUOUS_MINE选项要求挂载数据库并启用归档。

LogMiner将使用数据库控制文件查找并将满足指定时间或SCN范围的重做日志文件添加到LogMiner重做日志文件列表中。例如:

```sql

ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';

EXECUTE DBMS_LOGMNR.START_LOGMNR( -

STARTTIME => '01-Jan-2012 08:30:00', -

ENDTIME => '01-Jan-2012 08:45:00', -

OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + -

DBMS_LOGMNR.CONTINUOUS_MINE);

```

(为了避免在对DBMS_LOGMNR的PL/SQL调用中指定日期格式。START_LOGMNR过程,本例首先使用SQL ALTER会话集NLS_DATE_FORMAT语句。)

您还可以使用DBMS_LOGMNR指定一个重做日志文件,从而指示LogMiner自动构建要分析的重做日志文件列表。然后在启动LogMiner时指定CONTINUOUS_MINE选项。然而,前面描述的方法更典型。Manually

使用DBMS_LOGMNR。在启动LogMiner之前手动创建重做日志文件列表的ADD_LOGFILE过程。将第一个重做日志文件添加到列表后,随后添加的每个重做日志文件必须来自相同的数据库,并与相同的数据库重做日志SCN相关联。使用此方法时,LogMiner不需要连接到源数据库。

例如,要启动重做日志文件的新列表,请指定DBMS_LOGMNR的新选项。ADD_LOGFILE PL/SQL过程,表明这是一个新列表的开始。例如,输入以下命令来指定/oracle/logs/log1.f:

EXECUTE DBMS_LOGMNR.ADD_LOGFILE( -

LOGFILENAME => '/oracle/logs/log1.f', -

OPTIONS => DBMS_LOGMNR.NEW);

如果需要,可以通过指定PL/SQL DBMS_LOGMNR的ADDFILE选项来添加更多的重做日志文件。ADD_LOGFILE过程。例如,输入以下内容来添加/oracle/logs/log2.f:

EXECUTE DBMS_LOGMNR.ADD_LOGFILE( -

LOGFILENAME => '/oracle/logs/log2.f', -

OPTIONS => DBMS_LOGMNR.ADDFILE);

要确定在当前LogMiner会话中分析哪些重做日志文件,可以查询V$LOGMNR_LOGS视图,其中包含每个重做日志文件的一行。

# Starting LogMiner

调用DBMS_LOGMNR.START_LOGMNR来启动LogMiner。因为DBMS_LOGMNR提供了可用的选项。START_LOGMNR过程允许你控制输出到V$LOGMNR_CONTENTS视图,在查询V$LOGMNR_CONTENTS 视图之前执行必须调用DBMS_LOGMNR.START_LOGMNR。

当你启动LogMiner,你可以:指定LogMiner应该如何过滤它返回的数据(例如,通过开始和结束时间或SCN值)

指定格式化LogMiner返回的数据的选项

指定要使用的LogMiner字典

下面的列表是LogMiner设置的摘要,您可以使用DBMS_LOGMNR.START_LOGMNR的OPTIONS参数指定这些设置。

当执行DBMS_LOGMNR.START_LOGMNR过程, LogMiner会检测确保你指定的参数是有效的并且重做日志和数据字典是存在可获得的。 在您查询视图之前,V$LOGMNR_CONTENTS视图不会被填充, 详见How the V$LOGMNR_CONTENTS View Is Populated.

注意,在调用DBMS_LOGMNR.START_LOGMNR时,参数和选项不是持久的。每次调用DBMS_LOGMNR.START_LOGMNR时,必须指定所有需要的参数和选项(包括SCN和时间范围)。

# Querying V$LOGMNR_CONTENTS for Redo Data of Interest

通过查询V$LOGMNR_CONTENTS视图获取我们感兴趣的数据. (注意要有 SYSDBA or LOGMINING 权限来查询V$LOGMNR_CONTENTS.) 这个视图包括了数据库的历史变更信息,包括但不仅限于下列:对数据库的更改类型:插入、更新、删除或DDL(OPERATION column).

对其进行更改的SCN(SCN column).

提交更改的SCN (COMMIT_SCN column).

变更所属的事务 (XIDUSN, XIDSLT, and XIDSQN columns).

修改对象对应的表和schema (SEG_NAME and SEG_OWNER columns).

发出DDL或DML语句进行更改的用户的名称(USERNAME column).

如果更改是由于SQL DML语句造成的,则重构的SQL语句将显示与用于生成重做记录的SQL DML相同(但不一定相同)的SQL DML (SQL_REDO column).

如果密码是SQL_REDO列中语句的一部分,则对密码进行加密。与DDL语句对应的SQL_REDO列值总是与用于生成redo记录的SQL DDL相同。

如果更改是由于SQL DML更改造成的,则重构的SQL语句显示撤消更改所需的SQL DML语句 (SQL_UNDO column).

与DDL语句对应的SQL_UNDO列始终为空。对于某些数据类型和回滚操作,SQL_UNDO列可能也是NULL。

Note:

LogMiner支持透明数据加密(TDE),V$LOGMNR_CONTENTS显示对具有加密列的表执行的DML操作(包括正在更新的加密列),前提是LogMiner数据字典包含有关对象的元数据,并且Oracle wallet中有适当的主密钥。必须打开wallet,否则V$LOGMNR_CONTENTS无法解释相关的重做记录。如果数据库未打开(只读或读写),则不支持TDE。

Example of Querying V$LOGMNR_CONTENTS

假设你想要查找有一个叫Ron的用户对oe.orders所做的删除操作,你可以执行一个类似于下面的SQL语句:

SELECT OPERATION, SQL_REDO, SQL_UNDO

FROM V$LOGMNR_CONTENTS

WHERE SEG_OWNER = 'OE' AND SEG_NAME = 'ORDERS' AND

OPERATION = 'DELETE' AND USERNAME = 'RON';

下面是执行SQL查询出来的结果:

OPERATION SQL_REDO SQL_UNDO

DELETE delete from "OE"."ORDERS" insert into "OE"."ORDERS"

where "ORDER_ID" = '2413' ("ORDER_ID","ORDER_MODE",

and "ORDER_MODE" = 'direct' "CUSTOMER_ID","ORDER_STATUS",

and "CUSTOMER_ID" = '101' "ORDER_TOTAL","SALES_REP_ID",

and "ORDER_STATUS" = '5' "PROMOTION_ID")

and "ORDER_TOTAL" = '48552' values ('2413','direct','101',

and "SALES_REP_ID" = '161' '5','48552','161',NULL);

and "PROMOTION_ID" IS NULL

and ROWID = 'AAAHTCAABAAAZAPAAN';

DELETE delete from "OE"."ORDERS" insert into "OE"."ORDERS"

where "ORDER_ID" = '2430' ("ORDER_ID","ORDER_MODE",

and "ORDER_MODE" = 'direct' "CUSTOMER_ID","ORDER_STATUS",

and "CUSTOMER_ID" = '101' "ORDER_TOTAL","SALES_REP_ID",

and "ORDER_STATUS" = '8' "PROMOTION_ID")

and "ORDER_TOTAL" = '29669.9' values('2430','direct','101',

and "SALES_REP_ID" = '159' '8','29669.9','159',NULL);

and "PROMOTION_ID" IS NULL

and ROWID = 'AAAHTCAABAAAZAPAAe';

输出显示Ron从oe.orders表删除了两条数据. 他重构的SQL语句与Ron发出的实际语句是等价的,但不一定完全相同。. 造成这种差异的原因是原始的WHERE子句没有记录在重做日志文件中,所以LogMiner只能单独显示已删除(或更新或插入)的行。

T因此,即使一条DELETE语句可能负责删除这两行,V$LOGMNR_CONTENTS中的输出也不能反映这一事实。 实际执行的DELETE可能是 DELETE FROM OE.ORDERS WHERE CUSTOMER_ID ='101' 或者是DELETE FROM OE.ORDERS WHERE PROMOTION_ID = NULL.

# How the V$LOGMNR_CONTENTS View Is Populated

V$LOGMNR_CONTENTS与其他视图不同,不是反应表中数据关系,而是反应Redo日志的关系表示。

LogMiner仅在响应针对它的查询时填充视图。在查询V$LOGMNR_CONTENTS之前,必须成功启动LogMiner。

当对V$LOGMNR_CONTENTS视图执行select操作时,将按顺序读取重做日志文件。来自重做日志文件的翻译信息在V$LOGMNR_CONTENTS视图中以行形式返回。这将一直持续到满足在启动时指定的筛选条件或到达重做日志文件的结尾。

在某些情况下,V$LOGMNR_CONTENTS中的某些列可能不会被填充。例如:对于OPERATION列的值为DDL的行,不会填充TABLE_SPACE列。这是因为DDL可以在多个表空间上操作。例如,可以使用跨越多个表空间的多个分区创建一个表;因此,填充列并不准确。

LogMiner不为临时表生成SQL redo或SQL undo, SQL_REDO列会包含"/* No SQL_REDO for temporary tables /"字符串,SQL_UNDO 列会包含"/ No SQL_UNDO for temporary tables */"字符串.

LogMiner以SCN顺序返回所有行,除非您使用COMMITTED_DATA_ONLY选项指定只检索提交的事务。SCN顺序是媒体恢复中常用的顺序。

See Also:

Showing Only Committed Transactions for more information about the COMMITTED_DATA_ONLY option to DBMS_LOGMNR.START_LOGMNR

Note:

因为LogMiner只在响应查询时填充V$LOGMNR_CONTENTS视图,而不将请求的数据存储在数据库中,所以以下是正确的:每次查询V$LOGMNR_CONTENTS时,LogMiner都会分析您请求的数据的重做日志文件。

查询消耗的内存量不依赖于必须返回满足查询的行数。

返回请求的数据所需的时间取决于为找到该数据而必须挖掘的重做日志数据的数量和类型。

基于上面的注意事项,如果你需要保持查询结果以便日后分析,Oracle建议在实体表保存从V$LOGMNR_CONTENTS视图中查询到的结果,特别是当查询返回的数据量与LogMiner必须分析才能提供数据的重做数据量相比很小时。

# Querying V$LOGMNR_CONTENTS Based on Column Values

LogMiner允许您基于列值进行查询。

例如你可以查询所有对hr.employees做的salary增长超过一定值的update操作,这样的数据可以用来分析系统行为和执行审计任务。

使用两个挖掘函数从重做日志文件中提取数据:DBMS_LOGMNR。MINE_VALUE DBMS_LOGMNR.COLUMN_PRESENT。V$LOGMNR_CONTENTS视图中的REDO_VALUE和UNDO_VALUE列提供了对这些mine函数的支持。

下面是一个示例,演示如何使用MINE_VALUE函数来选择hr的所有更新。将工资栏增加到原来的两倍以上的员工:

SELECT SQL_REDO FROM V$LOGMNR_CONTENTS

WHERE

SEG_NAME = 'EMPLOYEES' AND

SEG_OWNER = 'HR' AND

OPERATION = 'UPDATE' AND

DBMS_LOGMNR.MINE_VALUE(REDO_VALUE, 'HR.EMPLOYEES.SALARY') >

2*DBMS_LOGMNR.MINE_VALUE(UNDO_VALUE, 'HR.EMPLOYEES.SALARY');

如下例所示,MINE_VALUE函数有两个参数:第一个参数指定是挖掘数据的redo (REDO_VALUE)部分还是undo (UNDO_VALUE)部分。数据的重做部分是插入、更新或删除操作后列中的数据;数据的撤消部分是插入、更新或删除操作之前列中的数据。将REDO_VALUE视为新值,将UNDO_VALUE视为旧值可能会有所帮助。

第二个参数是一个字符串,它指定要挖掘的列的完全限定名(在本例中是hr.employee .salary)。MINE_VALUE函数总是返回一个可以转换回原始数据类型的字符串。

# The Meaning of NULL Values Returned by the MINE_VALUE Function

描述MINE_VALUE函数返回的空值的含义。

如果MINE_VALUE函数返回一个空值,那么它可以表示:指定的列在数据的重做或撤消部分中不存在。

指定的列是存在的,并且有一个空值。

要区分这两种情况,可以使用DBMS_LOGMNR.COLUMN_PRESENT函数,如果该列出现在数据的重做或撤消部分,则该函数返回1。否则,它返回0。例如,假设您希望找出修改salary列中的值的增量和相应的事务标识符。你可以发出以下SQL查询:

SELECT

(XIDUSN || '.' || XIDSLT || '.' || XIDSQN) AS XID,

(DBMS_LOGMNR.MINE_VALUE(REDO_VALUE, 'HR.EMPLOYEES.SALARY') -

DBMS_LOGMNR.MINE_VALUE(UNDO_VALUE, 'HR.EMPLOYEES.SALARY')) AS INCR_SAL

FROM V$LOGMNR_CONTENTS

WHERE

OPERATION = 'UPDATE' AND

DBMS_LOGMNR.COLUMN_PRESENT(REDO_VALUE, 'HR.EMPLOYEES.SALARY') = 1 AND

DBMS_LOGMNR.COLUMN_PRESENT(UNDO_VALUE, 'HR.EMPLOYEES.SALARY') = 1;

# Usage Rules for the MINE_VALUE and COLUMN_PRESENT Functions

描述应用于MINE_VALUE和COLUMN_PRESENT函数的使用规则。

具体来说:它们只能在LogMiner会话中使用。

它们必须在V$LOGMNR_CONTENTS视图的select操作上下文中启动。

它们不支持LONG、LONG RAW、CLOB、BLOB、NCLOB、ADT或集合数据类型。

# Restrictions When Using the MINE_VALUE Function To Get an NCHAR Value

描述使用MINE_VALUE函数时的限制。

如果DBMS_LOGMNR.MINE_VALUE函数用于获取一个NCHAR值,该值包含在数据库字符集中没有找到的字符,然后这些字符作为数据库字符集的替换字符(例如,反问号)返回。

# Querying V$LOGMNR_CONTENTS Based on XMLType Columns and Tables

(XMLType也不常用 就不一一翻译)

LogMiner支持为XMLType列生成重做。在兼容性设置为11.0.0.0或更高的情况下生成重做时,支持将XMLType数据存储为CLOB。

作为对象关系和二进制XML存储的XMLType数据支持在11.2.0.3或更高的兼容性设置下重新生成。

LogMiner根据XMLType存储以不同的方式在V$LOGMNR_CONTENTS中显示SQL_REDO。在所有情况下,SQL_REDO列的内容和STATUS列都需要仔细检查,并且通常需要重新组装才能生成SQL或PL/SQL语句来重新执行更改。在某些情况下,可能无法使用SQL_REDO数据来构造这样的更改。以下小节中的示例基于存储为CLOB的XMLType,这通常是用于重建完整行更改的最简单方法。

Note:存储为CLOB的XMLType数据在Oracle数据库12c版本1(12.1)中被弃用。

Querying V$LOGMNR_CONTENTS For Changes to Tables With XMLType Columns

The example in this section is for a table named XML_CLOB_COL_TAB that has the following columns:f1 NUMBER

f2 VARCHAR2(100)

f3 XMLTYPE

f4 XMLTYPE

f5 VARCHAR2(10)

Assume that a LogMiner session has been started with the logs and with the COMMITED_DATA_ONLY option. The following query is executed against V$LOGMNR_CONTENTS for changes to the XML_CLOB_COL_TAB table.

SELECT OPERATION, STATUS, SQL_REDO FROM V$LOGMNR_CONTENTS

WHERE SEG_OWNER = 'SCOTT' AND TABLE_NAME = 'XML_CLOB_COL_TAB';

The query output looks similar to the following:

OPERATION STATUS SQL_REDO

INSERT 0 insert into "SCOTT"."XML_CLOB_COL_TAB"("F1","F2","F5") values

('5010','Aho40431','PETER')

XML DOC BEGIN 5 update "SCOTT"."XML_CLOB_COL_TAB" a set a."F3" = XMLType(:1)

where a."F1" = '5010' and a."F2" = 'Aho40431' and a."F5" = 'PETER'

XML DOC WRITE 5 XML Data

XML DOC WRITE 5 XML Data

XML DOC WRITE 5 XML Data

XML DOC END 5

In the SQL_REDO columns for the XML DOC WRITE operations there will be actual data for the XML document. It will not be the string 'XML Data'.

This output shows that the general model for an insert into a table with an XMLType column is the following:An initial insert with all of the scalar columns.

An XML DOC BEGINoperation with an update statement that sets the value for one XMLType column using a bind variable.

One or more XML DOC WRITE operations with the data for the XML document.

An XML DOC END operation to indicate that all of the data for that XML document has been seen.

If there is more than one XMLType column in the table, then steps 2 through 4 will be repeated for each XMLType column that is modified by the original DML.

If the XML document is not stored as an out-of-line column, then there will be no XML DOC BEGIN, XML DOC WRITE, or XML DOC END operations for that column. The document will be included in an update statement similar to the following:

OPERATION STATUS SQL_REDO

UPDATE 0 update "SCOTT"."XML_CLOB_COL_TAB" a

set a."F3" = XMLType('<?xml version="1.0"?>

Po_99

Dave Davids

')

where a."F1" = '5006' and a."F2" = 'Janosik' and a."F5" = 'MMM'

Querying V$LOGMNR_CONTENTS For Changes to XMLType Tables

DMLs to XMLType tables are slightly different from DMLs to XMLType columns. The XML document represents the value for the row in the XMLType table. Unlike the XMLType column case, an initial insert cannot be done which is then followed by an update containing the XML document. Rather, the whole document must be assembled before anything can be inserted into the table.

Another difference for XMLType tables is the presence of the OBJECT_ID column. An object identifier is used to uniquely identify every object in an object table. For XMLType tables, this value is generated by Oracle Database when the row is inserted into the table. The OBJECT_ID value cannot be directly inserted into the table using SQL. Therefore, LogMiner cannot generate SQL_REDO which is executable that includes this value.

The V$LOGMNR_CONTENTS view has a new OBJECT_ID column which is populated for changes to XMLType tables. This value is the object identifier from the original table. However, even if this same XML document is inserted into the same XMLType table, a new object identifier will be generated. The SQL_REDO for subsequent DMLs, such as updates and deletes, on the XMLType table will include the object identifier in the WHERE clause to uniquely identify the row from the original table.

# Restrictions When Using LogMiner With XMLType Data

Describes restrictions when using LogMiner with XMLType data.

Mining XMLType data should only be done when using the DBMS_LOGMNR.COMMITTED_DATA_ONLY option. Otherwise, incomplete changes could be displayed or changes which should be displayed as XML might be displayed as CLOB changes due to missing parts of the row change. This can lead to incomplete and invalid SQL_REDO for these SQL DML statements.

The SQL_UNDO column is not populated for changes to XMLType data.

# Example of a PL/SQL Procedure for Assembling XMLType Data

Example showing a procedure that can be used to mine and assemble XML redo for tables that contain out of line XML data.

This shows how to assemble the XML data using a temporary LOB. Once the XML document is assembled, it can be used in a meaningful way. This example queries the assembled document for the EmployeeName element and then stores the returned name, the XML document and the SQL_REDO for the original DML in the EMPLOYEE_XML_DOCS table.

Note:

This procedure is an example only and is simplified. It is only intended to illustrate that DMLs to tables with XMLType data can be mined and assembled using LogMiner.

Before calling this procedure, all of the relevant logs must be added to a LogMiner session and DBMS_LOGMNR.START_LOGMNR() must be called with the COMMITTED_DATA_ONLY option. The MINE_AND_ASSEMBLE() procedure can then be called with the schema and table name of the table that has XML data to be mined.

-- table to store assembled XML documents

create table employee_xml_docs (

employee_name varchar2(100),

sql_stmt varchar2(4000),

xml_doc SYS.XMLType);

-- procedure to assemble the XML documents

create or replace procedure mine_and_assemble(

schemaname in varchar2,

tablename in varchar2)

AS

loc_c CLOB;

row_op VARCHAR2(100);

row_status NUMBER;

stmt VARCHAR2(4000);

row_redo VARCHAR2(4000);

xml_data VARCHAR2(32767 CHAR);

data_len NUMBER;

xml_lob clob;

xml_doc XMLType;

BEGIN

-- Look for the rows in V$LOGMNR_CONTENTS that are for the appropriate schema

-- and table name but limit it to those that are valid sql or that need assembly

-- because they are XML documents.

For item in ( SELECT operation, status, sql_redo FROM v$logmnr_contents

where seg_owner = schemaname and table_name = tablename

and status IN (DBMS_LOGMNR.VALID_SQL, DBMS_LOGMNR.ASSEMBLY_REQUIRED_SQL))

LOOP

row_op := item.operation;

row_status := item.status;

row_redo := item.sql_redo;

CASE row_op

WHEN 'XML DOC BEGIN' THEN

BEGIN

-- save statement and begin assembling XML data

stmt := row_redo;

xml_data := '';

data_len := 0;

DBMS_LOB.CreateTemporary(xml_lob, TRUE);

END;

WHEN 'XML DOC WRITE' THEN

BEGIN

-- Continue to assemble XML data

xml_data := xml_data || row_redo;

data_len := data_len + length(row_redo);

DBMS_LOB.WriteAppend(xml_lob, length(row_redo), row_redo);

END;

WHEN 'XML DOC END' THEN

BEGIN

-- Now that assembly is complete, we can use the XML document

xml_doc := XMLType.createXML(xml_lob);

insert into employee_xml_docs values

(extractvalue(xml_doc, '/EMPLOYEE/NAME'), stmt, xml_doc);

commit;

-- reset

xml_data := '';

data_len := 0;

xml_lob := NULL;

END;

WHEN 'INSERT' THEN

BEGIN

stmt := row_redo;

END;

WHEN 'UPDATE' THEN

BEGIN

stmt := row_redo;

END;

WHEN 'INTERNAL' THEN

DBMS_OUTPUT.PUT_LINE('Skip rows marked INTERNAL');

ELSE

BEGIN

stmt := row_redo;

DBMS_OUTPUT.PUT_LINE('Other - ' || stmt);

IF row_status != DBMS_LOGMNR.VALID_SQL then

DBMS_OUTPUT.PUT_LINE('Skip rows marked non-executable');

ELSE

dbms_output.put_line('Status : ' || row_status);

END IF;

END;

END CASE;

End LOOP;

End;

/

show errors;

This procedure can then be called to mine the changes to the SCOTT.XML_DATA_TAB and apply the DMLs.

EXECUTE MINE_AND_ASSEMBLE ('SCOTT', 'XML_DATA_TAB');

As a result of this procedure, the EMPLOYEE_XML_DOCS table will have a row for each out-of-line XML column that was changed. The EMPLOYEE_NAME column will have the value extracted from the XML document and the SQL_STMT column and the X

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值