-
传统将非分区表转换为分区表的方式,不能实现高可用
非分区表转换为分区表的传统的方式,是建一个分区表,然后将原表数据导入进去,然后修改原表和分区表表名,线上应用就会处于不可用状态,这种方式对于24*7运行的应用来说是不可取的。 -
对表做在线重定义方式,实现应用高可用
ORACLE自带的DBMS_REDEFINITION包功能很强大,可以用于回收碎片空间、降低高水位线,对表做在线重定义
(添加或删除字段,改变字段类型,普通表重定义表为分区表,分区表重定义表为普通表等等)
另外,它有一个非常强大的功能-“高可用”,应用运行同时切换表,但是也并不是完全的高可用,
因为在完成重定义前的最后一下,会持会表级排他锁,但这个锁定时间是可控的。
「使用在线重定义的一些限制条件」:
(1).必须有足够的表空间来容纳表的两倍数据量。
(2).主键列不能被修改。
(3).原表必须有主键。
(4).必须在同一个用户下进行在线重定义。
(5).SYS和SYSTEM用户下的表无法进行在线重定义。
(6).在线重定义无法采用nologging。
(7).如果中间表有新增列,则不能有NOT NULL约束
3. 举例
CLEAR_RESULT是原表,CLEAR_RESULT_TEMP是中间表(分区表/模板表),执行
重定义后,会将中间表和原表的索引、权限、约束、触发器等直接互换;
–非分区表
CREATE TABLE TEST(
ID VARCHAR2(20) NOT NULL ,
NAME VARCHAR2(10),
RESEND_FLAG CHAR(1),
CREATE_TIME TIMESTAMP,
CONSTRAINT PK_TEST_ID PRIMARY KEY (ID)
)
CREATE INDEX TEST_CREATE_TIME_IDX ON TEST (CREATE_TIME);
–分区表
CREATE TABLE TEST_TEMP(
ID VARCHAR2(20) NOT NULL ,
NAME VARCHAR2(10),
RESEND_FLAG CHAR(1),
CREATE_TIME TIMESTAMP,
CONSTRAINT PK_TEST_ID PRIMARY KEY (ID)
)
PARTITION BY RANGE(CREATE_TIME)
(
PARTITION month1 VALUES less than (TO_DATE(‘2021-01-01’,‘yyyy-MM-dd’)),
PARTITION month2 VALUES less than (TO_DATE(‘2021-02-01’,‘yyyy-MM-dd’)),
PARTITION month3 VALUES less than (TO_DATE(‘2021-03-01’,‘yyyy-MM-dd’)),
PARTITION month4 VALUES less than (TO_DATE(‘2021-04-01’,‘yyyy-MM-dd’)),
PARTITION month5 VALUES less than (TO_DATE(‘2021-05-01’,‘yyyy-MM-dd’)),
);
–建局部前缀分区索引
CREATE INDEX TEST_TEMP_CREATE_TIME_IDX ON TEST_TEMP (CREATE_TIME)
LOCAL (PARTITION month1 , PARTITION month2 ,PARTITION month3 ,PARTITION month4 ,PARTITION month5);
–1).重定义表必须有主键值,检查是否可以执行在线重定义,若返回错误的话说明不能执行
BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE(‘TEST’, ‘TEST_TEMP’, 1);
END;
/
–2)、执行在线同步,开始重定义*
begin
DBMS_REDEFINITION.START_REDEF_TABLE(‘UCS’, ‘TEST’,‘TEST_TEMP’,NULL,2);
end;
/
–3)、结束在线同步,结束重定义 (上一步数据过去了,但是索引什么的还没过去)
begin
DBMS_REDEFINITION.FINISH_REDEF_TABLE(‘UCS’, ‘TEST’,‘TEST_TEMP’);
end;
/
–4)、查询表结构,看是否分区成功,需要给UCS_APP用户重新赋下增删改查权限。看下是否需要修改主键、索引名称,原表的主键和索引名称是
–直接复制的中间表。
DBMS_REDEFINITION的在线重定义功能将非分区表置为分区表
于 2023-10-27 16:09:43 首次发布