截断单个分区后,其主键的索引变得不可用,并且对该分区的所有插入/更新都失败

Ken*_*war 5 index oracle-11g partitioning alter-table truncate

我有一个分区表:SAMPLE_PARTITIONED_TBL基于PERIOD_ID数字字段(数据集:201001...201212.. 等等)有 60 个分区(没有子分区)。该表有几个本地索引,但由于某种原因,问题出在 PK 索引上。我在另一个模式中有相同的 DDL,它在那里工作正常。不确定 tio 寻找什么来解决这个问题。

我正在使用 Informatica(ETL 工具)将数据加载到该表中。在加载之前,我们会截断分区表:

SQL> ALTER TABLE owner_name.SAMPLE_PARTITIONED_TBL 
   2 TRUNCATE PARTITION SMPL_201001 DROP STORAGE;
Run Code Online (Sandbox Code Playgroud)

当加载开始时,我收到以下错误:

Message: Database errors occurred: 
ORA-01502: index 'owner_name.SAMPLE_PARTITIONED_TBL_PK' or 
partition of such index is in unusable state
Run Code Online (Sandbox Code Playgroud)

查看索引的状态...

SQL> select STATUS from all_indexes
  2  where INDEX_NAME like 'SAMPLE_PARTITIONED_TBL_PK';

STATUS
--------
UNUSABLE
Run Code Online (Sandbox Code Playgroud)

现在在执行SQL> ALTER INDEX owner_name.SAMPLE_PARTITIONED_TBL_PK REBUILD;本地分区索引返回STATUS=VALID状态后,加载可以继续没有问题。


更新:

根据下面@Mat 的观察,我正在检查 PK 索引是否在本地分区:

SQL> select * from all_indexes where table_name = 'SAMPLE_PARTITIONED_TBL';
Run Code Online (Sandbox Code Playgroud)

我看到SAMPLE_PARTITIONED_TBL_PK了列表中的其他索引。

SQL> select * from  all_part_indexes where table_name = 'SAMPLE_PARTITIONED_TBL';
Run Code Online (Sandbox Code Playgroud)

在这里,我看到所有带有LOCALITY='LOCAL';的索引 除了SAMPLE_PARTITIONED_TBL_PK在结果集中丢失,因此证实了 Mat 的观察。:)

谢谢。

Mat*_*Mat 6

这是预期的,分区上的大多数 DDL 操作将使受 DDL 影响的索引无效。在ALTER TABLE文档状态上的所有相关操作。

专为truncate partition

对于每个被截断的分区或子分区,Oracle 数据库也会截断对应的本地索引分区和子分区。如果这些索引分区或子分区被标记为 UNUSABLE,那么数据库会截断它们并将 UNUSABLE 标记重置为 VALID。

所以本地索引被截断和标记valid。除非您特别要求维护全局索引,否则它们将失效。(请参阅进一步的内容。)
在您的情况下,您的主键似乎不是基于本地索引 – 实际上似乎没有分区,因为您无法alter index ... rebuild对分区索引执行操作,您需要重建每个划分。所以失效是可以预料的。

为此,您可以在语句中添加一个UPDATE INDEXES/UPDATE GLOBAL INDEXES子句,让ALTER TABLEOracle 在ALTER- 请参阅自动更新索引期间为您自动维护索引。但是有一些限制,请仔细阅读自动更新索引时注意事项部分。

但这并不总是可取的。有时在加载后重建索引更有效。在这种情况下,您的加载过程通常可以使用该SKIP_UNUSABLE_INDEXES参数(可以在会话级别设置)。(此参数TRUE在 11gR2 中默认。)