Oracle LOB字段迁移:避开那些“看似成功”的坑 在Oracle数据库的日常运维里,给大表搬家或者整理表空间是常事。但如果你处理的表里包含了LOB(大对象)字段,比如存放文档的CLOB或者图片的BLOB,那可得留神了。一个标准的ALTER TABLE ... MOVE命令下去,很可能事与愿违。
在Oracle数据库的日常运维里,给大表搬家或者整理表空间是常事。但如果你处理的表里包含了LOB(大对象)字段,比如存放文档的CLOB或者图片的BLOB,那可得留神了。一个标准的ALTER TABLE ... MOVE命令下去,很可能事与愿违。今天,我们就来把LOB迁移的关键步骤和那些容易踩的雷区,一次说清楚。
ALTER TABLE MOVE迁移直接对含有LOB字段的表执行alter table ... move,十有八九会失败。原因在于,LOB数据在物理上并不和表段(Table Segment)存储在一起。它拥有自己独立的段(lobsegment)和索引(lobindex),并且默认创建在和表相同的表空间里。所以,当你试图移动表时,Oracle会明确拒绝你,常见的报错比如ORA-10631: the shrink clause cannot be used for this object,或者更典型的ORA-22858: invalid alteration of datatype(尤其是如果你在命令里顺手加了modify之类的操作时)。
长期稳定更新的攒劲资源: >>>点此立即查看<<<

那么,正确的姿势是什么?答案是必须显式指定LOB列,并使用专门的MOVE LOB子句:
ALTER TABLE t1 MOVE LOB (clob_col) STORE AS (TABLESPACE ts_new);MOVE表本身(不含LOB数据),再单独MOVE LOB。MOVE LOB (c1, c2, b1) STORE AS (...)。这是新手甚至老手都容易翻车的地方。很多人照着示例写命令,却漏掉了STORE AS子句里的TABLESPACE关键字。结果就是,命令看似执行成功了,没有报错,但一查数据字典,LOB段依然稳稳地待在原来的表空间里。白忙一场!Oracle不会因为你前面移动了表,就自动把LOB段也放到目标表空间去。
所以,记住这个铁律:TABLESPACE必须写,不能省。正确写法如下:
ALTER TABLE doc_table MOVE LOB (content) STORE AS (TABLESPACE users_lob);
下面这些写法都是无效的,无法达成迁移表空间的目的:
STORE AS (PCTVERSION 10) —— 只设置了存储参数,没指定表空间,LOB原地不动。STORE AS lob_seg_name —— 这只是给LOB段起了个新名字,跟换表空间没关系。STORE AS —— 语法直接报错,根本执行不了。这个操作可不是“温和”的。它会持有DML级别的锁,意味着在迁移过程中,表上的INSERT、UPDATE、DELETE操作会被阻塞(SELECT查询通常不受影响)。更要命的是,操作一旦开始就无法中断,既不能ROLLBACK,也不能CANCEL。如果LOB列里存了几个TB的数据,那这个迁移过程跑上几个小时是家常便饭。
因此,动手之前务必做好以下准备:
DBA_LOBS视图查清楚LOB当前在哪,别搬错了地方。查询语句:SELECT tablespace_name FROM dba_lobs WHERE table_name='DOC_TABLE' AND column_name='CONTENT';有个好消息:你不需要手动去处理那个配套的LOB索引(LOBINDEX)。MOVE LOB命令在移动LOB段的同时,会自动重建LOB索引段,并将其放置到与新的LOB段相同的表空间中。索引的名字会保持不变(通常是像SYS_IL00001234567890$这样的系统生成名),你无需操心重命名或单独移动它。
迁移完成后,可以用下面的语句验证一下:
SELECT segment_name, segment_type, tablespace_name FROM dba_segments WHERE segment_name IN ( SELECT index_name FROM dba_indexes WHERE table_name = 'DOC_TABLE');
这里有个细节:如果你之前手工给LOB索引重命名过,MOVE之后它会继续使用你改过的名字。但只要你在命令中没有显式使用INDEX子句去干预,Oracle就会按默认逻辑重建它。
最后,也是最容易被忽略的一点:MOVE LOB操作完成后,旧的LOB段所占用的空间并不会立即释放。它会一直留在原表空间,直到发生归档日志切换并由空间回收机制处理,或者你手动执行ALTER TABLE ... DEALLOCATE UNUSED命令。所以,别奇怪为什么操作后表空间使用率看起来没怎么下降,记得去清理这些“幽灵”空间。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述