您的位置:首页 > 运维架构

测试分区维护对于字段索引的影响(包括本地/全局索引分区与普通分区)

2008-03-23 22:47 447 查看
最近公司数据库服务器某表的数据实现了分区表的形式,但是有关以后分区表的维护涉及到的许多问题还没有得到一个充分的理论或实践的依据,以后一旦在分区维护中出现了问题将会导致非常严重的问题。因此本周末花了一天半的时间来研究这些可能出现的问题。
首先是创建分区测试表(该测试在备份库中进行,涉及公司秘密原表名被隐藏):
--创建分区测试表
create table test_partition_table partition by range(starttime)(
partition test_part_01 values less than(date '2007-01-04') tablespace iptvbill,
partition test_part_02 values less than(date '2007-01-08') tablespace iptvbill,
partition test_part_03 values less than(date '2007-01-12') tablespace iptvbill,
partition test_part_04 values less than(date '2007-01-16') tablespace iptvbill,
partition test_part_05 values less than(date '2007-01-20') tablespace iptvbill,
partition test_part_06 values less than(date '2007-01-24') tablespace iptvbill,
partition test_part_07 values less than(date '2007-01-28') tablespace iptvbill,
partition test_part_08 values less than(date '2007-02-01') tablespace iptvbill
)
pctfree 5
pctused 40
initrans 1
maxtrans 255
storage(
initial 1m
next 1m
minextents 1
maxextents unlimited
pctincrease 0
) enable row movement as
select /*+rule*/* from [source_table] ib --partition(part_iptvtotal_15)
where ib.starttime < date '2007-02-01'
and ib.starttime >= date '2007-01-01'

--查看指定表名的所有的分区
select * from user_tab_partitions tp
where tp.table_name = 'TEST_PARTITION_TABLE'
order by tp.partition_position
--查看表信息
select * from user_tables t
where t.table_name = 'TEST_PARTITION_TABLE'
--查看索引信息
select * from user_indexes ind
where ind.table_name = 'TEST_PARTITION_TABLE'

以下本地索引都是指本地前缀索引,不涉及对本地非前缀索引的测试:
-----########### 第一部分: ################################
--目的:观察截断分区后对各索引状态的影响(本地分区索引和普通索引)
1.对starttime建立本地索引;
create index idx_test_starttime on test_partition_table(starttime) local tablespace INDX
2.对subscriberid建立普通索引;
create index idx_test_subid on test_partition_table(subscriberid) tablespace INDX
3.做表分析:
analyze table test_partition_table estimate statistics sample 10 percent for table;
analyze table test_partition_table COMPUTE statistics for all indexes for all indexed columns;
4.exp p05段数据备份;
5.截断p05分区:
alter table test_partition_table truncate partition TEST_PART_05
6.截断后, 本地分区仍然有效, 但是普通对字段subscriberid索引的status都变为unusable.
--执行下面语句正常
select * from test_partition_table pt where pt.starttime >= date '2007-01-20'
--执行下面语句报错:索引无效
select * from test_partition_table pt where pt.subscriberid >= 20930495

-----########### 第二部分: ################################
--目的:观察drop分区后对imp的影响和删除空分区对索引状态的影响
1.增加对ppvname的普通索引;
create index idx_test_ppvname on test_partition_table(ppvname) tablespace INDX
2.imp p05段数据;
imp dvboss_bak/passwd file=dmp.dmp buffer=40960000 indexes=n grants=n ignore=y fromuser=dvboss_bak touser=dvboss_bak
--到主机上执行如上语句失败,报错:
经由常规路径导出由EXPORT:V08.01.07创建的文件
已经完成ZHS16GBK字符集和ZHS16GBK NCHAR 字符集中的导入
. . 正在导入分区 "TEST_PARTITION_TABLE":"TEST_PART_05"
IMP-00058: ORACLE 错误1502出现
ORA-01502: 索引'DVBOSS_BAK.IDX_TEST_SUBID'或这类索引的分区处于不可用状态
IMP-00057: 警告: 转储文件可能不含有此表的所有分区数据
IMP-00017: 由于 ORACLE 错误1502,以下的语句失败
"ANALYZE TABLE "TEST_PARTITION_TABLE" ESTIMATE STATISTICS "
IMP-00003: ORACLE 错误1502出现
ORA-01502: 索引'DVBOSS_BAK.IDX_TEST_SUBID'或这类索引的分区处于不可用状态
成功终止导入,但出现警告。

3.重建subscriberid字段的索引;
alter index idx_test_subid rebuild ; --298.469
--查看状态
select ind.index_name, ind.status from user_indexes ind
where ind.index_name in('IDX_TEST_SUBID','IDX_TEST_PPVNAME'); --valid

select inp.index_name, inp.partition_name, inp.status
from user_ind_partitions inp
where inp.index_name = 'IDX_TEST_STARTTIME' --usuable

5.删除p05分区数据(此时p05分区数据为空)
alter table test_partition_table drop partition TEST_PART_05
--查看对应的本地分区索引也删除
select inp.index_name, inp.partition_name, inp.status
from user_ind_partitions inp
where inp.index_name = 'IDX_TEST_STARTTIME'
--执行下面语句正常
select * from test_partition_table pt where pt.starttime >= date '2007-01-20'
--执行下面语句正常
select * from test_partition_table pt where pt.subscriberid >= 20930495

-----########### 第三部分: ################################
--目的:观察drop分区后对索引状态的影响(普通索引和本地分区索引)
1.imp备份的p05分区数据
imp dvboss_bak/passwd file=dmp.dmp buffer=40960000 indexes=n grants=n fromuser=dvboss_bak ignore=y touser=dvboss_bak
--查看索引状态
select ind.index_name, ind.status from user_indexes ind
where ind.index_name in('IDX_TEST_SUBID','IDX_TEST_PPVNAME');

select inp.index_name, inp.partition_name, inp.status
from user_ind_partitions inp
where inp.index_name = 'IDX_TEST_STARTTIME'

2.备份然后drop p04分区数据
alter table test_partition_table drop partition TEST_PART_04
--对应的分区和本地索引的分区都已删除
3.查看各索引状态:
--下面索引已经无效
select ind.index_name, ind.status from user_indexes ind
where ind.index_name in('IDX_TEST_SUBID','IDX_TEST_PPVNAME'); --UNUSABLE
--下面本地索引仍然有效
select inp.index_name, inp.partition_name, inp.status
from user_ind_partitions inp
where inp.index_name = 'IDX_TEST_STARTTIME' --
4.重建索引
alter index idx_test_ppvname rebuild;
alter index idx_test_subid rebuild ;
--查看索引状态
select ind.index_name, ind.status from user_indexes ind
where ind.index_name in('IDX_TEST_SUBID','IDX_TEST_PPVNAME'); --valid

-----########### 第四部分: ################################
--目的:观察drop分区时采用update indexes选项后对各索引状态的影响
--此步骤不能执行

-----########### 第五部分: ################################
--目的:采用全局分区后删除一个分区对于全局索引状态的影响
1.删除本地分区索引
drop index idx_test_starttime
2.创建全局分区索引
create index idx_test_g_starttime on test_partition_table(starttime)
GLOBAL PARTITION BY RANGE(starttime)(
partition test_g_part_01 values less than(date '2007-01-04') tablespace INDX,
partition test_g_part_02 values less than(date '2007-01-08') tablespace INDX,
partition test_g_part_03 values less than(date '2007-01-12') tablespace INDX,
partition test_g_part_06 values less than(date '2007-01-24') tablespace INDX,
partition test_g_part_07 values less than(date '2007-01-28') tablespace INDX,
partition test_g_part_08 values less than(maxvalue) tablespace INDX
)
3.drop p01分区
alter table test_partition_table drop partition test_part_01
--查看对索引状态的影响
select ind.index_name, ind.status from user_indexes ind
where ind.index_name in('IDX_TEST_SUBID','IDX_TEST_PPVNAME'); --valid
select inp.index_name, inp.partition_name, inp.status
from user_ind_partitions inp
where inp.index_name = 'IDX_TEST_G_STARTTIME' --UNUSABLE
发现都已经变成UNUSABLE状态。

---#### 总结
对分区的维护DDL操作会使其他字段的索引的状态变成不可用状态(UNUSABLE);
对于全局索引也会使其变成不可用状态(UNUSABLE);
对于本地前缀索引,会删除对应本地索引分区,对于其他分区状态不发生改变。

关于分区表的如何实现及实现方式、例子等可参考如下文档:
http://download.oracle.com/docs/cd/B14117_01/server.101/b10739/partiti.htm#sthref2381
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: