oracle数据库⾼⽔位线问题处理
⼀、什么是⾼⽔线(High Water Mark)?
Oracle 数据库在创建⼀张表时,会为这张表分配⼀个段空间(gment),为了⽅便理解,把段空间容纳数据的上限,称之为⾼⽔位线(HIGH WATER MARK) HWM ,HWM是⼀个标记,⽤来说明表⽰有多少未使⽤的块分配给这个段。
两个结论:
1.⽔位线以上表⽰已经分配但还未使⽤块(block),⽔位先以下爱表⽰已经分配且已经使⽤过的块(包含了正在使⽤的块和使⽤过的且被删除了数据的空块)
2.理论上来说,⼀张表的⽔位线只会增⼤不会减⼩(除⾮通过特殊的⽅法重置),即使将表中的数据全部删除,HWM还是为原值。
山地车十大名牌⼆、HWM数据库的操作有如下影响:
a) 全表扫描通常要读出直到HWM标记的所有的属于该表数据库块,即使该表中没有任何数据。
b) 即使HWM以下有空闲的数据库块,键⼊在插⼊数据时使⽤了append关键字,HWM也会不断增⼤,占⽤系统资源,表所占的实际空间会不断增⼤,导致系统出现问题
三、⾼⽔位线原因以及解决⽅法:
产⽣原因:
北京电视台官方网站1.操作表时使⽤删除了⼤量数据。
2.在插⼊时使⽤了/append nologging/语句,append关键字会从为表分配段中的随机位置插⼊,⽔位线会不断增⾼。
3.Sql load 时默认使⽤truncate ⾃带了reu storage参数,导致truncate以后⽔位线不会降低。
解决⽅法:
1.直接truncate table drop storage
2.建⽴⼀张维护表定期move并重建索引或者shrink space。
3.表数据落表时按照⽇期建⽴了备份表,保留⼀定天数数据
4.Rename表名,重建表,重建索引,将数据导⼊重建表,drop原表,然后rename重建表为原表
5.使⽤alter table 表名 shrink space(oracle10新增功能)
6.在线表重定义(功能强⼤,操作复杂,⼀般不使⽤,可以改变表的结构)
表重建的两个⽅法move与shrink的对⽐:
move是oracle8出现的命令,使⽤时会创建⼀块和原来表空间相同⼤⼩的另⼀块表空间,然后进⾏数据的复制,完成后使⽤后表替换原表,解决hwm的问题。
缺点:操作时锁表,索引会失效。
shrink是oracle10新增功能,使⽤时不会开辟新的表空间,操作分为两步,第⼀步整理数据,第⼆步降低⽔位线,进⾏第⼀步时,可以在线进⾏操作。可以再业务不繁忙的时候进⾏第⼆步操作。
缺点:相⽐move速度⽐较缓慢。
shrink的详细操作步骤:
电烤箱哪个牌子好详细收缩步骤
1. 全表收缩
不管分区表还是⾮分区表,收缩都可以表级别进⾏,具体语句如下:
ALTER TABLE owner.table_name ENABLE ROW MOVEMENT;(开启⾏移动会使游标失效,需谨慎)
ALTER TABLE owner.table_name SHRINK SPACE COMPACT CASCADE(第⼀步整理数据,并不会降低⾼⽔位线,可以在线进⾏操作);
ALTER TABLE owner.table_name SHRINK SPACE CASCADE(第⼆步分析重置⾼⽔位线,会短暂锁表需要在业务量⼩的时候进⾏操作);
2. 单个分区收缩
分区表的收缩还可以分区级别进⾏,具体语句如下:
ALTER TABLE owner.table_name ENABLE ROW MOVEMENT;
爱的渴望
ALTER TABLE owner.table_name MODIFY PARTITION partition_name SHRINK SPACE COMPACT CASCADE;
ALTER TABLE owner.table_name MODIFY PARTITION partition_name SHRINK SPACE CASCADE;
ALTER INDEX owner.index_name MODIFY PARTITION partition_name SHRINK SPACE COMPACT CASCADE;
ALTER INDEX owner.index_name MODIFY PARTITION partition_name SHRINK SPACE CASCADE;
四、在线表重定义步骤:
1、确认表是否可以做在线重定义:
BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE(
uname => 'OWNER',
tname => 'ORIGTABLENAME',
options_flag => s_u_pk);
END;
/
--如果有主键则是options_flag => s_u_pk,如果没有s_u_rowid
2、创建新的中间表TABLENAME_TMP准备重定义 (可以新增删除字段、可以修改表存储参数、可以修改为分区表等需要的操作)
注意因为在线重定义过程中要求列的属性要相同,因此不可使⽤dbms_redefinition完成列类型的调整
--普通表
CREATE TABLE OWNER.TABLENAME_TMP ( ) TABLESPACE XXX;
--分区表
CREATE TABLE OWNER.TABLENAME_TMP ( )
PARTITION BY RANGE (PARTITIONNAME)
(
PARTITION P1 VALUES LESS THAN ('xxx'),
...
PARTITION PMAX VALUES LESS THAN (MAXVALUE)
)
TABLESPACE XXX;
小学生读物3、开启并⾏提⾼在线重定义速度:
ALTER SESSION FORCE PARALLEL DML PARALLEL 2;
ALTER SESSION FORCE PARALLEL QUERY PARALLEL 2;
4、开始在线重定义:
BEGIN
dbms_redefinition.start_redef_table(
uname => 'OWNER',
orig_table => 'ORIGTABLENAME',
int_table => 'TABLENAME_TMP',
options_flag => s_u_pk);
END;
/
--如果有主键则是options_flag => s_u_pk,如果没有s_u_rowid
5、使⽤COPY_TABLE_DEPENDENTS把原始表的权限、约束、索引等在中间表上创建⼀份
DECLARE
num_errors PLS_INTEGER;
BEGIN
py_table_dependents(
uname => 'OWNER',
orig_table => 'ORIGTABLENAME',
int_table => 'TABLENAME_TMP',
copy_indexes => s_orig_params,
copy_triggers => true,
copy_constraints => true,
copy_privileges => true,
ignore_errors => fal,
num_errors => num_errors,
copy_statistics => true);
END;
/
6、假如在线重定义要很久,这期间应⽤往源表插⼊数据,中间表并不会有这条数据,使⽤sync_interim_table包同步在线重定义期间源表所有的DML的数据:
BEGIN
dbms_redefinition.sync_interim_table(
uname => 'OWNER',
orig_table => 'ORIGTABLENAME',
int_table => 'TABLENAME_TMP');
END;
/
7、完成在线重定义:
BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE(
河南三本分数线
uname => 'OWNER',
orig_table => 'ORIGTABLENAME',
int_table => 'TABLENAME_TMP');
END;
/
王乐夫
9、中间重定义报错时需要执⾏以下命令终⽌重定义:
*BEGIN
樱花几月份*DBMS_REDEFINITION.ABORT_REDEF_TABLE( *uname => 'OWNER',
*orig_table => 'ORIGTABLENAME',
*int_table => 'TABLENAME_TMP');
*END;
*/
10、确定数据索引等同步成功后,删除中间表:drop table OWNER.TABLENAME_TMP;