V1.0
Revision |
Author/Modifier | Comments | |
No. |
Date |
||
1.0 | 2012.2 | 王涛 | 初稿 |
一、 目的
明确加分区操作的风险及标准流程,最大限度避免加分区操作带来的故障。
二、 适用范围
l 日常分区表维护。
l 主要考虑增加range,list分区(hash分区,不允许新加分区,在系统规划初始的时候充分考虑数据增长情况)。
l 不考虑子分区情况(目前无系统使用子分区)。
l 不适用分区分裂情况,本文后面详细叙述为何不使用分区分裂。
三、 风险评估
l 登录到错误的schema下,导致分区到错误的schema里,而应用无法访问。
l 忽略了TABLESPACE参数,导致分区建到了默认表空间,导致后续空间增长和维护困难。建议分区表的表空间和产品DBA确认沟通好。
l 对于未来增量较快的表选择了一个空间规划不足的表空间,导致后续空间增长和维护困难。
l 脚本末尾缺少分号,导致该分区没有被创建上,而执行DDL的过程又不会报错。
l 其他原因漏建了分区,导致应用访问错误。
l 同步库没有及时创建相应的分区,或者没有更新同步配置,导致同步及应用出问题。
l 加分区,可能导致SQL执行计划走错的风险。这个在国际站美国库上存在过。请务必选择在系统低峰期操作。
l 分区表的分区名需与应用DBA,产品DBA,应用团队沟通确认,是否有特殊命名规则依赖。
四、 操作流程
1. 准备工作
a) 在准备发布脚本时,检查分区类型,评估tablespace的剩余空间,选择合适的表空间,并在加分区的时候指定表空间名字。
b) 严禁使用Spilt 方式增加分区,理由如下:
i. 若spilt的分区有数据,会导致local index为unusable;一般分区都是大表,后果不堪设想。
ii. 若spilt的分区有数据,会占用大量的临时段。举例:
1. 假设A类型的数据有200M,它会在原来的分区扩展200M的临时段,然后再把这200M切换到新的分区里去。
iii. 不要存在侥幸心理,若存在各种历史原因,请先修改表结构定义后,再加分区!
c) 在确定加分区类型之前,先确认分区类型,然后选择相应的action进行操作:
使用下面的命令确认所有者,表名,分区类型,默认表空间,间隔:
Select OWNER, table_name, PARTITIONING_TYPE,DEF_TABLESPACE_NAME,INTERVAL From Dba_Part_Tables where owner=:1 and table_name=:2;
i. 如果是LIST分区:
若是list分区,先查看list分区的定义:
apollo@CRMG>Select high_value,tablespace_name From User_Tab_Partitions Where table_name=’ORD_ORDER’;
HIGH_VALUE TABLESPACE_NAME
—————————— —————————–
’save_temp’ APOLLO_IND
‘closed’ APOLLO_IND
default APOLLO_IND
说明:
如果HIGH_VALUE有default,那么该表是无法再加分区,会报错:
ORA-14323: cannot add partition when DEFAULT partition exists
如果确认没有default,那可以直接加分区了:
alter table table_name add partition partition_name values (‘分区条件’)
tablespace tablespace_name;
结论:list分区严禁给予default分区,否则无法添加其他值的分区。
ii. 如果是RANGE分区
Range分区我们主要用在时间上比较多,对range分区进行分类,有两种模式:
apollo@CRMG>Select a.table_name,a.Interval From User_Part_Tables a Where a.partitioning_type=’RANGE’;
TABLE_NAME INTERVAL
—————————— ——————————
WT2 NUMTOYMINTERVAL(1,’MONTH’)
WT
如果interval字段非空且是11G以后版本的数据库,那么该分区使用了自动加分区特性,不需要DBA进行任何操作,Oracle会自动加分区。
如果interval字段为空,则需要加分区,查看当前分区值:
Select partition_name,high_value From User_Tab_Partitions Where table_name=’TABLE_NAME’;
确认当前分区的high_value以后,即可增加分区。
d) 使用@dep脚本,检查分区表的对象依赖。确保在变更过程中,对象始终有效。
e) 若所加的上一个分区,有统计信息,先将统计信息导出,修改分区名字后,再导入。若分区内容有重大变化,请勿复制统计信息。
导出统计信息:
dbms_stats.export_table_stats(ownname => ‘user_name’,stattab => ’stattab’,tabname => ‘table_name’,partname => ‘partition_name’);
修改统计信息:
Update stattab Set c2=’partition_name’ and c1=’table_name’;
导入统计信息:
dbms_stats.import_table_stats(ownname => ‘user_name’,tabname => ‘table_name’,stattab => ’stattab’,partname => ‘partition_name’);
f) 若是核心表,加分区操作务必放在系统低峰时间进行,不得在高峰时段做此操作。有必要和应用负责人约定加分区时间,防止意外情况发生。其它非核心表,则可以在变更窗口内进行。
g) 加分区操作属于标准变更或重大变更(根据表的情况而定),在做之前必须在ITIL中提交相应的变更申请。
2. 执行过程
a) 开启DDL TRIGGER禁止远程编译。
b) 用应用账户登录数据库,SHOW USER检查是否连接到正确的schema。严禁使用sys、system等用户加分区。
c) 加分区脚本必须一条条粘贴,只有确认上一条命令执行成功后,方可执行下一条命令。
d) 查看过程若无报错,退出当前登录。若有报错,找出报错的地方,修改确认再执行,直至全部执行通过,最后退出当前登录。
e) 关闭DDL TRIGGER开启远程编译。
3. 验证方案
a) 检查数据库中是否有失效对象:@dbcheck
b) 检查所加分区是否添加成功:@size
c) 立即联系开发接口人进行应用测试,【加分区】变更是否成功以应用测试结果为准。
d) 检查分区的统计信息是否被导入成功。@tabstat
e) 同步库若建表,也需要执行 a) , b) 两个步骤。
五、 核心对象风险
选择在系统低峰执行,评估SQL执行计划走错的可能。
六、 回退方案
若分区表加错,需要根据分区类型,选择不同的回滚方案。主要步骤分为三步:
1. 确认所删分区是否有数据:
Select count(*) from table_name partition(partion_name);
2. 评估分区类型
a) List分区:确认无误后,可以删除。
b) Rang分区:确认无误后,可以删除。
c) 任何分区删除操作必须加上 update global Indexes,防止全局索引失效。
3. 索引维护
由于索引删除以后,global的索引的状态是unsable的。因此必须check索引状态:
Select status from user_indexes where table_name=’table_name’;
七、 历史故障及教训
略