alter table...move tablespace 不支持在线迁移大表,因其需全表排他锁、索引失效需重建、lob不自动迁移;oracle 11g+ 真正零停机方案是 dbms_redefinition,但须满足主键或rowid前提,并严控中间表结构一致性与finish时长事务冲突。

不能用 ALTER TABLE ... MOVE TABLESPACE 直接在线迁移大表——它会锁全表,DML 阻塞,业务不可接受。Oracle 11g+ 真正支持零停机迁移的只有 DBMS_REDEFINITION,但必须满足主键或伪主键(ROWID)前提,且过程有隐性陷阱。
为什么 MOVE TABLESPACE 不算“在线”
表面看命令执行快,但实际会触发以下连锁反应:
-
ALTER TABLE t MOVE TABLESPACE new_tbsp需要排他锁(TM-6),所有 INSERT/UPDATE/DELETE 会被挂起,直到 MOVE 完成 - 索引自动失效,必须立刻
REBUILD,这又是一轮锁和 I/O 尖峰 - LOB 字段不随 MOVE 自动迁移,漏掉
MOVE LOB(...) STORE AS会导致数据仍在旧表空间 - 高并发 OLTP 场景下,哪怕 30 秒锁表,也可能引发应用超时雪崩
DBMS_REDEFINITION 的两个启动条件
不是所有表都能直接走在线重定义。必须先验证可重定义性,且根据主键情况选择模式:
- 有主键(或唯一非空约束):用
DBMS_REDEFINITION.CONS_USE_PK,重定义后无隐藏列,索引可同步复制 - 无主键:只能基于
ROWID,但要求表不是索引组织表(IOT),且重定义后会多出隐藏列M_ROW$$,影响后续统计信息收集和某些工具识别 - 验证语句必须以
SYS或表拥有者身份执行:BEGIN DBMS_REDEFINITION.CAN_REDEF_TABLE('SCHEMA', 'TABLE_NAME', DBMS_REDEFINITION.CONS_USE_PK); END; - 失败常见原因:
ORA-12091: cannot online redefine table with materialized views(存在物化视图)、ORA-12092: cannot online redefine table with synchronous MVs
中间表创建和同步的关键细节
中间表不是随便建个空表就行,结构、约束、存储参数都要对齐,否则 START_REDEF_TABLE 会报错:
- 中间表必须建在目标表空间:
CREATE TABLE schema.interim_tab (...) TABLESPACE new_tbsp - 字段顺序、数据类型、NULL/NOT NULL 属性必须与原表严格一致;主键约束可省略,但列名不能改
- 如果原表有
DEFAULT值或虚拟列,中间表也要显式定义,否则COPY_TABLE_DEPENDENTS可能跳过依赖对象 - 启动重定义后,系统会自动在后台做初始数据拷贝 + 捕获 DML 变更(通过物化视图日志),这个阶段业务照常读写
- 真正风险点在
FINISH_REDEF_TABLE:它会短暂加锁交换表定义,通常毫秒级,但若此时有长事务未提交,会卡住交换,需提前 kill
容易被忽略的收尾动作
执行完 FINISH_REDEF_TABLE 并不等于结束。很多 DBA 忘了清理残留,导致空间没释放、监控误报、甚至下次重定义失败:
- 中间表不会自动删,必须手动
DROP TABLE schema.interim_tab,否则占着新表空间白耗资源 - 原表上的索引、约束、触发器不会自动迁移到新表结构上,要用
COPY_TABLE_DEPENDENTS显式复制,否则新表无索引 - 统计信息不会自动更新,重定义后立即执行
DBMS_STATS.GATHER_TABLE_STATS,否则执行计划可能劣化 - 检查
DBA_OBJECTS中表的STATUS是否为VALID,以及DBA_SEGMENTS中段是否真在新表空间:SELECT segment_name, tablespace_name FROM dba_segments WHERE segment_name = 'TABLE_NAME' AND owner = 'SCHEMA';
整个过程最脆弱的环节不在技术步骤,而在“中间表结构一致性”和“FINISH 时刻的长事务冲突”。建议在低峰期预演一次,抓取 V$SESSION_LONGOPS 和 V$TRANSACTION 实时监控,比背熟命令更重要。











