当前位置: 首页 > news >正文

Oracle 在线重定义

Oracle 在线重定义(Online Redefinition) 是一种功能,通过DBMS_REDEFINITION 包提供,允许DBA在不需要停止或显著影响数据库正常操作的情况下,对数据库表进行结构化修改。

可以实现的功能

  • 将表移动到其它表空间

  • 增加、修改或者删除表的字段

  • 将非分区表转换为分区表

  • 修改表的分区结构

  • 高水位线回收

  • 将普通表转换为索引组织表

测试数据

五千万条数据,数据文件test_tbs01.dbf,表空间test_tbs

将表移动到其它表空间

#创建新表空间
CREATE TABLESPACE new_tbs DATAFILE '/datafile/new_tbs01.dbf' SIZE 10G AUTOEXTEND ON NEXT 1G MAXSIZE UNLIMITED;#给用户授权
ALTER USER TEST_USER QUOTA UNLIMITED ON NEW_TBS;#检查选择的表是否可以执行在线重定义
BEGINDBMS_REDEFINITION.CAN_REDEF_TABLE('TEST_USER', 'TEST_TABLE');
END;
/#创建中间表(结构与原表一致,但指定新表空间)
CREATE TABLE test_user.test_table_int (id NUMBER PRIMARY KEY,name VARCHAR2(100) NOT NULL,created_date DATE,value NUMBER(10),comments VARCHAR2(500)
) TABLESPACE new_tbs;# 开始在线重定义(使用主键方式)
BEGINDBMS_REDEFINITION.START_REDEF_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT',options_flag => DBMS_REDEFINITION.CONS_USE_PK  -- 使用主键);
END;
/# 复制依赖对象(自动复制索引、约束)
DECLAREnum_errors PLS_INTEGER;
BEGINDBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT',copy_indexes => DBMS_REDEFINITION.CONS_ORIG_PARAMS,copy_triggers => TRUE,copy_constraints => TRUE,copy_privileges => TRUE,ignore_errors => TRUE,num_errors => num_errors);
END;
/# 同步数据
BEGINDBMS_REDEFINITION.SYNC_INTERIM_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT');
END;
/# 完成重定义(短暂锁表)# DBMS_REDEFINITION.FINISH_REDEF_TABLE 会执行flush shard pool 需要规避
alter session set events '10995 trace name context forever, level 2';BEGINDBMS_REDEFINITION.FINISH_REDEF_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT');
END;
/

增加、修改或者删除表的字段

操作:添加字段new_column VARCHAR2(50),删除字段comments。

#检查选择的表是否可以执行在线重定义
BEGINDBMS_REDEFINITION.CAN_REDEF_TABLE('TEST_USER', 'TEST_TABLE');
END;
/

# 创建中间表(添加新字段,删除旧字段)
CREATE TABLE test_user.test_table_int (id NUMBER PRIMARY KEY,name VARCHAR2(100) NOT NULL,created_date DATE,value NUMBER(10),new_column VARCHAR2(50)
) TABLESPACE test_tbs;

# 开始在线重定义(使用主键方式)
BEGINDBMS_REDEFINITION.START_REDEF_TABLE(uname        => 'TEST_USER', orig_table   => 'TEST_TABLE',int_table    => 'TEST_TABLE_INT',col_mapping  => 'id id, name name, created_date created_date, value value', options_flag => DBMS_REDEFINITION.CONS_USE_PK);
END;
/

# 复制依赖对象(自动复制索引、约束)
DECLAREnum_errors PLS_INTEGER;
BEGINDBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT',copy_indexes => DBMS_REDEFINITION.CONS_ORIG_PARAMS,copy_triggers => TRUE,copy_constraints => TRUE,copy_privileges => TRUE,ignore_errors => TRUE,num_errors => num_errors);
END;
/
# 同步数据
BEGINDBMS_REDEFINITION.SYNC_INTERIM_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT');
END;
/

# 完成重定义
BEGINDBMS_REDEFINITION.FINISH_REDEF_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT');
END;
/

将非分区表转换为分区表

#检查选择的表是否可以执行在线重定义
BEGINDBMS_REDEFINITION.CAN_REDEF_TABLE('TEST_USER', 'TEST_TABLE');
END;
/

#创建中间表
CREATE TABLE test_user.test_table_int (id            NUMBER,name          VARCHAR2(100) NOT NULL,created_date  DATE NOT NULL, value         NUMBER(10),new_column    VARCHAR2(50),CONSTRAINT pk_test_table_int PRIMARY KEY (id, created_date) 
)
PARTITION BY RANGE (created_date) (PARTITION p1 VALUES LESS THAN (TO_DATE('2023-01-01', 'YYYY-MM-DD')),PARTITION p2 VALUES LESS THAN (TO_DATE('2024-01-01', 'YYYY-MM-DD')),PARTITION p3 VALUES LESS THAN (MAXVALUE)
) TABLESPACE test_tbs;

# 开始在线重定义(使用主键方式)
BEGINDBMS_REDEFINITION.START_REDEF_TABLE(uname        => 'TEST_USER',orig_table   => 'TEST_TABLE',int_table    => 'TEST_TABLE_INT',col_mapping  => 'id id, name name, created_date created_date, value value, new_column new_column',  options_flag => DBMS_REDEFINITION.CONS_USE_PK);
END;
/

-- 复制依赖对象(自动复制索引、约束)
DECLAREnum_errors PLS_INTEGER;
BEGINDBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT',copy_indexes => DBMS_REDEFINITION.CONS_ORIG_PARAMS,copy_triggers => TRUE,copy_constraints => TRUE,copy_privileges => TRUE,ignore_errors => TRUE,num_errors => num_errors);
END;
/

# 同步数据
BEGINDBMS_REDEFINITION.SYNC_INTERIM_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT');
END;
/

# 完成重定义# DBMS_REDEFINITION.FINISH_REDEF_TABLE 会执行flush shard pool 需要规避
alter session set events '10995 trace name context forever, level 2';BEGINDBMS_REDEFINITION.FINISH_REDEF_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT');
END;
/

#创建新表空间
CREATE TABLESPACE new_tbs DATAFILE '/datafile/new_tbs01.dbf' SIZE 10G AUTOEXTEND ON NEXT 1G MAXSIZE UNLIMITED;#给用户授权
ALTER USER TEST_USER QUOTA UNLIMITED ON NEW_TBS;#检查选择的表是否可以执行在线重定义
BEGINDBMS_REDEFINITION.CAN_REDEF_TABLE('TEST_USER', 'TEST_TABLE');
END;
/#创建中间表(结构与原表一致,但指定新表空间)
CREATE TABLE test_user.test_table_int (id NUMBER PRIMARY KEY,name VARCHAR2(100) NOT NULL,created_date DATE,value NUMBER(10),comments VARCHAR2(500)
) TABLESPACE new_tbs;# 开始在线重定义(使用主键方式)
BEGINDBMS_REDEFINITION.START_REDEF_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT',options_flag => DBMS_REDEFINITION.CONS_USE_PK  -- 使用主键);
END;
/-- 复制依赖对象(自动复制索引、约束)
DECLAREnum_errors PLS_INTEGER;
BEGINDBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT',copy_indexes => DBMS_REDEFINITION.CONS_ORIG_PARAMS,copy_triggers => TRUE,copy_constraints => TRUE,copy_privileges => TRUE,ignore_errors => TRUE,num_errors => num_errors);
END;
/# 同步数据
BEGINDBMS_REDEFINITION.SYNC_INTERIM_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT');
END;
/# 完成重定义(短暂锁表)# DBMS_REDEFINITION.FINISH_REDEF_TABLE 会执行flush shard pool 需要规避
alter session set events '10995 trace name context forever, level 2';BEGINDBMS_REDEFINITION.FINISH_REDEF_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT');
END;
/

修改表的分区结构

当前表为范围分区:

# 创建哈希分区中间表CREATE TABLE test_user.test_table_int (id            NUMBER,name          VARCHAR2(100) NOT NULL,created_date  DATE,value         NUMBER(10),new_column    VARCHAR2(50),CONSTRAINT pk_test_table_int PRIMARY KEY (id)
)
PARTITION BY HASH (id)
PARTITIONS 4
TABLESPACE test_tbs;

# 启动在线重定义
BEGINDBMS_REDEFINITION.START_REDEF_TABLE(uname        => 'TEST_USER',orig_table   => 'TEST_TABLE',int_table    => 'TEST_TABLE_INT',col_mapping  => 'id id, name name, created_date created_date, value value, new_column new_column',options_flag => DBMS_REDEFINITION.CONS_USE_PK);
END;
/

# 复制依赖对象(自动复制索引、触发器等)
DECLAREnum_errors PLS_INTEGER;
BEGINDBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(uname          => 'TEST_USER',orig_table     => 'TEST_TABLE',int_table      => 'TEST_TABLE_INT',copy_indexes   => DBMS_REDEFINITION.CONS_ORIG_PARAMS,copy_triggers  => TRUE,ignore_errors  => TRUE,num_errors     => num_errors);DBMS_OUTPUT.PUT_LINE('依赖对象错误: ' || num_errors);
END;
/

# 同步数据
BEGINDBMS_REDEFINITION.SYNC_INTERIM_TABLE(uname        => 'TEST_USER',orig_table   => 'TEST_TABLE',int_table    => 'TEST_TABLE_INT');
END;
/

# 完成重定义(短暂锁表)
BEGINDBMS_REDEFINITION.FINISH_REDEF_TABLE(uname        => 'TEST_USER',orig_table   => 'TEST_TABLE',int_table    => 'TEST_TABLE_INT');
END;
/

高水位线回收(碎片整理)

# 记录当前高水位线
SELECT blocks, empty_blocks 
FROM dba_tables 
WHERE owner = 'TEST_USER' AND table_name = 'TEST_TABLE';

#检查选择的表是否可以执行在线重定义
BEGINDBMS_REDEFINITION.CAN_REDEF_TABLE('TEST_USER', 'TEST_TABLE');
END;
/

#创建中间表
CREATE TABLE test_user.test_table_int (id NUMBER PRIMARY KEY,name VARCHAR2(100) NOT NULL,created_date DATE,value NUMBER(10),new_column VARCHAR2(50)
) TABLESPACE test_tbs;

# 开始在线重定义(使用主键方式)
BEGINDBMS_REDEFINITION.START_REDEF_TABLE(uname        => 'TEST_USER',orig_table   => 'TEST_TABLE',int_table    => 'TEST_TABLE_INT',col_mapping  => 'id id, name name, created_date created_date, value value, new_column new_column',  options_flag => DBMS_REDEFINITION.CONS_USE_PK);
END;
/

-- 复制依赖对象(自动复制索引、约束)
DECLAREnum_errors PLS_INTEGER;
BEGINDBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT',copy_indexes => DBMS_REDEFINITION.CONS_ORIG_PARAMS,copy_triggers => TRUE,copy_constraints => TRUE,copy_privileges => TRUE,ignore_errors => TRUE,num_errors => num_errors);
END;
/

# 同步数据
BEGINDBMS_REDEFINITION.SYNC_INTERIM_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT');
END;
/

# 完成重定义# DBMS_REDEFINITION.FINISH_REDEF_TABLE 会执行flush shard pool 需要规避
alter session set events '10995 trace name context forever, level 2';BEGINDBMS_REDEFINITION.FINISH_REDEF_TABLE(uname => 'TEST_USER',orig_table => 'TEST_TABLE',int_table => 'TEST_TABLE_INT');
END;
/

检查高水位是否回收

SELECT blocks, empty_blocks 
FROM dba_tables 
WHERE owner = 'TEST_USER' AND table_name = 'TEST_TABLE';

转换为索引组织表(IOT)

总体步骤都与前面相同

http://www.dtcms.com/a/313738.html

相关文章:

  • git操作命令和golang编译脚本
  • 力扣301:删除无效的括号
  • Scikit-learn - 机器学习库初步了解
  • Javascript面试题及详细答案150道之(046-060)
  • (论文速读)RMT:Retentive+ViT的视觉新骨干
  • 【优选算法】分治--归并排序
  • 力扣1124:表现良好的最长时间段
  • 进程生命周期管理:从创建到终止的完整逻辑
  • [激光原理与应用-136]:光学器件 - 光经过不同的材料,为什么会有折射?
  • 基于springboot的学习辅导系统设计与实现
  • ESP32开发问题汇总
  • 【解决办法】报错Found dtype Long but expected Float
  • SaProt 模型部署与运行教程
  • 【量化交易】日内交易有效特征因子
  • 智慧社区(六)——社区居民人脸识别功能实现详解:从腾讯 API 集成到模拟验证
  • Mysql深入学习:索引篇一
  • Linux操作系统的相关操作介绍
  • Android 之 MVP架构
  • python---可变对象、不可变对象
  • SpringBoot学习总结
  • 在不可更改系统上构建数据响应机制的可选策略
  • 彻底屏蔽夸克浏览器更新
  • ORA-12514:TNS: 监听程序当前无法识别连接描述符中请求的服务
  • 【Spring】Bean的生命周期,部分源码解释
  • 【高等数学】第七章 微分方程——第九节 欧拉方程
  • Java基础:代码块/内部类/Lambda函数/常用API/GUI编程
  • LeetCode - 合并两个有序链表 / 删除链表的倒数第 N 个结点
  • 三角洲行动ACE反作弊VT-d报错?CPU虚拟化如何开启!
  • MySQL架构全面理解
  • 克罗均线策略思路