alter table move 会重建表而非仅修改元数据,触发全表扫描与重插入,重置hwm和物理存储,但索引、约束、统计信息不自动更新,lob段需显式指定,分区表须按分区操作,且需重建索引并注意锁与事务影响。
alter table move 会重建表,不是单纯修改元数据
直接执行 alter table table_name move tablespace new_tbs 并不会“搬走”现有数据文件,而是触发一次全表扫描 + 重新插入:oracle 在新表空间中分配新段、逐行读取旧数据、按新存储参数写入。这意味着原表的物理位置、区(extent)分布、甚至高水位线(hwm)都会重置——但索引、约束、统计信息不会自动迁移或更新。
常见错误现象:ORA-01502: index 'OWNER.INDEX_NAME' or partition of such index is in unusable state。这是因为 MOVE 后所有普通索引(非分区索引)全部失效,查询仍可走全表扫描,但一旦涉及索引字段就会报错或跳过索引。
- 必须在 MOVE 后立即重建索引:
ALTER INDEX idx_name REBUILD TABLESPACE new_tbs - 唯一/主键约束依赖的索引也会失效,需显式
REBUILD,不能只靠ENABLE CONSTRAINT - 如果表有 LOB 字段,
MOVE默认不移动 LOB 段,必须额外指定LOB (col_name) STORE AS (TABLESPACE new_tbs)
MOVE 时指定 STORAGE 参数才能真正控制新段行为
不带任何存储子句的 MOVE 会沿用当前用户的默认存储设置(DEFAULT TABLESPACE 的初始参数),而非目标表空间的属性。比如目标表空间是 ASSM(自动段空间管理),但没显式指定 SEGMENT SPACE MANAGEMENT AUTO,MOVE 后段仍可能按 MSSM 方式分配。
推荐写法:
ALTER TABLE t1 MOVE TABLESPACE users STORAGE (INITIAL 64K NEXT 64K PCTINCREASE 0) LOB (content) STORE AS (TABLESPACE users DISABLE STORAGE IN ROW);
-
STORAGE子句决定新段的初始大小和扩展行为,与表空间本身的EXTENT MANAGEMENT无关 -
DISABLE STORAGE IN ROW对大 LOB 很关键:避免小 LOB 被挤进数据块,导致后续 UPDATE 触发行迁移 - 若目标表空间是本地管理(LMT),
MINEXTENTS/MAXEXTENTS会被忽略,不用写
分区表不能直接 ALTER TABLE MOVE,要用分区级语法
对分区表执行 ALTER TABLE ... MOVE 会报错:ORA-14511: cannot perform operation on a partitioned object。必须针对具体分区操作。
正确做法是移动单个分区或子分区:
ALTER TABLE sales MOVE PARTITION sales_q1_2024 TABLESPACE ts_new; ALTER TABLE sales MOVE SUBPARTITION sales_q1_2024_sp1 TABLESPACE ts_new;
- 分区 MOVE 后,该分区上的本地索引自动失效,需单独
ALTER INDEX ... REBUILD PARTITION - 全局索引默认保持 VALID,但如果你加了
UPDATE GLOBAL INDEXES子句,就能在线重建,避免锁表 - 如果表启用了行移动(
ENABLE ROW MOVEMENT),MOVE 分区不影响其他分区的 ROWID,但普通 MOVE 表本身仍会改 ROWID
MOVE 前必须确认表上无未提交事务,且评估锁影响
ALTER TABLE ... MOVE 是 DDL 操作,需要对表加 EXCLUSIVE 锁。整个过程会阻塞所有 DML(INSERT/UPDATE/DELETE),SELECT 可继续,但可能因 HWM 重置看到“空洞”(实际是已提交但未清理的块)。
- 执行前检查:
SELECT * FROM v$locked_object WHERE object_id = (SELECT object_id FROM dba_objects WHERE object_name = 'T1'); - 大表 MOVE 可能持续数分钟甚至小时,建议在低峰期做,并提前通知应用方停写
- 如果不能停业务,考虑用
DBMS_REDEFINITION在线重定义——它不锁表,但要求额外空间、更复杂,且不支持某些对象类型(如 IOT)
最易被忽略的是 LOB 段和索引的分离处理:很多人只记得 MOVE 表,忘了 LOB 还在老表空间,也忘了索引已失效,结果上线后查不到数据或性能骤降。











