• 移动指定datafile数据到新表空间 释放磁盘空间


    --生成环境,数据文件时常存在高水位,导致不能直接收缩数据文件的大小,释放磁盘空间

    create or replace package PKG_TOOL is

    -- Author : LILEI
    -- Created : 2019/5/17 8:57:03
    -- Purpose : SOME TOOLS

    --移动指定datafile数据到新表空间
    procedure move_ddl(v_fileid in number,
    v_newtbs in varchar2,
    v_parallel in pls_integer default 1);

    --执行move ddl语句
    procedure exec_ddl;

    --输出sql的信息(执行计划,表信息,索引信息)
    procedure test_plan (txt in varchar2);

    end PKG_TOOL;
    /
    create or replace package body PKG_TOOL is

    /*
    ------初始化
    grant select on dba_extents to system;
    grant select on dba_lobs to system;
    grant select on dba_lob_partitions to system;
    grant select on dba_part_indexes to system;
    grant select on dba_indexes to system;
    grant select on dba_ind_columns to system;
    Grant ALTER ANY INDEX to system;
    grant alter any table to system;
    grant create any index to system;
    grant drop any index to system;


    create table tools_ddl
    (
    owner varchar2(50),
    segment_name varchar2(50),
    segment_type varchar2(50),
    operation_type varchar2(20),
    sql_text varchar2(200),
    is_over number(1),
    execute_result varchar2(200)
    )tablespace users;


    grant select on dba_part_tables to system;
    grant select on dba_tab_partitions to system;
    grant select on dba_ind_partitions to system;
    grant select on dba_tab_partitions to system;
    grant select on dba_segments to system;
    grant select on dba_tables to system;
    grant select on dba_tab_cols to system;
    grant select on dba_part_tables to system;
    grant select on dba_part_key_columns to system;
    grant select on dba_tab_partitions to system;
    grant select on dba_ind_partitions to system;
    */

    procedure move_ddl(v_fileid in number,
    v_newtbs in varchar2,
    v_parallel in pls_integer default 1) is
    v_sql varchar2(200);
    v_column_name varchar2(50);
    v_table_name varchar2(50);
    v_partition_name varchar2(50);
    v_locality varchar2(50);
    v_UNIQUENESS varchar2(20);
    v_operation_type varchar2(20);
    v_count pls_integer;
    v_index_type varchar2(50);
    begin
    for cur in (select owner,segment_name,partition_name,segment_type from dba_extents where file_id=v_fileid
    group by owner,segment_name,partition_name,segment_type

    /*也可以直接换视图查询,从一个表空间移动到另外一个表空间,查询方式换一下就行了

    select owner,segment_name,partition_name,segment_type from dba_segments where tablespace_name=v_fileid
    group by owner,segment_name,partition_name,segment_type

    */

    )loop

    v_sql:='';
    v_operation_type:='ALTER';
    if cur.segment_type='TABLE' then
    v_sql:= 'alter table '||cur.owner||'.'||cur.segment_name ||
    ' move tablespace '||v_newtbs||' parallel '||v_parallel;
    elsif cur.segment_type='TABLE PARTITION' then
    v_sql:= 'alter table '||cur.owner||'.'||cur.segment_name ||' move partition '||
    cur.partition_name||' tablespace '||v_newtbs||' parallel '||v_parallel;
    elsif cur.segment_type='TABLE SUBPARTITION' then
    v_sql:='alter table '||cur.owner||'.'||cur.segment_name ||' move subpartition '||
    cur.partition_name ||' tablespace '||v_newtbs||' parallel '||v_parallel;
    elsif cur.segment_type='LOBSEGMENT' then
    select column_name,table_name into v_column_name,v_table_name from dba_lobs where segment_name=cur.segment_name;
    v_sql:='alter table '||cur.owner||'.'||v_table_name ||' move lob ( '|| v_column_name ||
    ')store as(tablespace '||v_newtbs||') parallel '||v_parallel;
    elsif cur.segment_type='LOB PARTITION' then
    select column_name,table_name,partition_name into v_column_name,v_table_name,v_partition_name
    from dba_lob_partitions where lob_name=cur.segment_name and lob_partition_name=cur.partition_name;
    v_sql:= 'alter table '||cur.owner||'.'||v_table_name||' move partition '||v_partition_name||
    ' lob( '|| v_column_name ||')store as(tablespace '||v_newtbs||') parallel '||v_parallel;
    elsif cur.segment_type='INDEX' then
    v_sql:='alter index '||cur.owner||'.'||cur.segment_name ||' rebuild tablespace '||v_newtbs
    ||' parallel '||v_parallel;
    elsif cur.segment_type='INDEX PARTITION' then
    select index_type into v_index_type from dba_indexes where index_name=cur.segment_name and OWNER=cur.owner;
    if v_index_type='LOB' then
    continue;
    end if;
    select locality into v_locality from dba_part_indexes where index_name =cur.segment_name;
    if v_locality='GLOBAL' then
    select count(*) into v_count from tools_ddl where owner=cur.owner and segment_name=cur.segment_name;
    if v_count>1 then
    continue;
    end if;
    select b.column_name,a.UNIQUENESS,a.TABLE_name into v_column_name,v_UNIQUENESS,v_table_name from dba_indexes a,dba_ind_columns b
    where a.INDEX_NAME=b.INDEX_NAME and a.OWNER=b.INDEX_OWNER and a.INDEX_NAME=cur.segment_name;

    if v_UNIQUENESS='UNIQUE' then
    v_sql:= 'create UNIQUE index '||cur.owner||'.'||cur.segment_name ||' on '||cur.owner||'.'||v_table_name||
    '('||v_column_name||')'||'GLOBAL PARTITION BY HASH ('||v_column_name||') PARTITIONS 128 TABLESPACE '
    ||v_newtbs||' parallel '||v_parallel;
    else
    v_sql:= 'create index '||cur.owner||'.'||cur.segment_name ||' on '||cur.owner||'.'||v_table_name||
    '('||v_column_name||')'||'GLOBAL PARTITION BY HASH ('||v_column_name||') PARTITIONS 128 TABLESPACE '
    ||v_newtbs||' parallel '||v_parallel;
    end if;
    v_operation_type:='CREATE';
    insert into tools_ddl(owner,segment_name,segment_type,operation_type,sql_text,is_over,execute_result)values
    (cur.owner,cur.segment_name,cur.segment_type,v_operation_type,v_sql,0,null);
    v_operation_type:='DROP';
    v_sql:='drop index '||cur.owner||'.'||cur.segment_name;
    else
    v_sql:='alter index '||cur.owner||'.'||cur.segment_name ||' rebuild PARTITION '
    ||cur.partition_name ||' tablespace '||v_newtbs||' parallel '||v_parallel;
    end if;
    elsif cur.segment_type='INDEX SUBPARTITION' then
    v_sql:='alter index '||cur.owner||'.'||cur.segment_name ||' rebuild SUBPARTITION '||
    cur.partition_name ||' tablespace '||v_newtbs||' parallel '||v_parallel;
    end if;
    if v_sql is not null then
    insert into tools_ddl(owner,segment_name,segment_type,operation_type,sql_text,is_over,execute_result)values
    (cur.owner,cur.segment_name,cur.segment_type,v_operation_type,v_sql,0,null);
    end if;
    end loop;
    commit;
    end move_ddl;

    procedure exec_ddl is
    v_error varchar2(500);
    begin
    for cur in(select sql_text,rowid from tools_ddl where is_over=0
    order by segment_type desc,operation_type desc) loop
    begin
    execute immediate cur.sql_text;
    exception
    when others then
    v_error:=substr(sqlerrm,1,400);
    update tools_ddl set is_over=2,execute_result=v_error
    where rowid=cur.rowid;
    continue;
    end;
    update tools_ddl set is_over=1 where rowid=cur.rowid;
    end loop;
    commit;
    end exec_ddl;

    end PKG_TOOL;
    /

    --别忘记重建失效的索引

  • 相关阅读:
    手机市场价格尚待规范
    Hotmail的2G邮箱被收回,只剩250M了
    网格50题(zz)
    Wallop介绍
    Hotmail邮箱居然还有2G
    IE 7.0抛弃Win2000用户?(zz)
    祝各位Blogger新春快乐!
    Gmail Invitation
    A CS Research Topic Generator(zz)
    今天"做大岁"
  • 原文地址:https://www.cnblogs.com/muzisanshi/p/11842698.html
Copyright © 2020-2023  润新知