oracle分区表的lob字段必须显式指定tablespace,否则默认落入users或用户默认表空间;lob子句需紧接列定义后、partition by前,且每个lob列须单独配置store as (tablespace xxx),并强制disable storage in row以实现分区级存储隔离。

Oracle分区表的LOB字段不能自动随主表分区走表空间,必须显式为每个LOB段指定存储位置,否则默认落到USERS或用户默认表空间——哪怕主表分区已按需分布,LOB仍可能集中堵在一块磁盘上,I/O瓶颈和备份压力立刻显现。
建表时必须在LOB子句中声明TABLESPACE
主表分区的TABLESPACE设置和LOB段的表空间是两套独立配置,互不影响。漏掉LOB子句里的TABLESPACE,哪怕所有主分区都指定了专用表空间,LOB数据仍会悄悄写进默认表空间。
-
LOB子句必须紧接在列定义后、PARTITION BY之前,且要覆盖全部LOB列 - 不支持用变量或模板生成,每个
LOB字段都要单独写一遍STORE AS (TABLESPACE xxx) - 若含多个LOB列(如
doc_pdf BLOB,doc_txt CLOB),需分别指定,不能合并简写
错误示例:lob(doc_pdf) store as (chunk 8k) → 缺少TABLESPACE,LOB段落USERS
正确写法:lob(doc_pdf) store as (tablespace tbs_lob_2024 chunk 8k disable storage in row)
分区表+LOB时,DISABLE STORAGE IN ROW几乎必选
启用STORAGE IN ROW(默认)会让小LOB(≤4000字节)直接存进数据块,看似省事,但会导致:主表分区数据块膨胀、无法按分区精准归档、冷热数据无法分离、备份粒度失控。
- 只要LOB字段存在且有实际大内容,应强制
DISABLE STORAGE IN ROW - 配合
CHUNK大小设置(建议匹配表空间BLOCKSIZE,如32K表空间配CHUNK 32K) -
DISABLE STORAGE IN ROW后,每个分区的LOB段会独立生成一个LOBSEGMENT,才能真正实现按分区隔离存储
MOVE PARTITION无法在线迁移LOB段,补救要分两步走
建表后发现LOB段全在默认表空间,想用ALTER TABLE ... MOVE PARTITION ... ONLINE一步到位?不行。Oracle明确限制:含LOB列的分区不支持在线迁移,会报ORA-14647。
- 第一步:先对主表分区执行
MOVE PARTITION ... ONLINE UPDATE INDEXES ONLINE - 第二步:再单独迁移对应LOB段:
ALTER TABLE t_name MODIFY LOB (col_name) (STORE AS (TABLESPACE new_ts)) - 注意:第二步操作会锁表(非在线),且要求目标表空间块大小与原LOB段兼容(如原LOB在8K表空间,不能直接挪到32K表空间)
验证LOB段是否真按分区落位,别只查USER_TAB_PARTITIONS
USER_TAB_PARTITIONS.TABLESPACE_NAME只显示主表分区的表空间,完全不反映LOB段位置。真正要看的是DBA_LOBS和DBA_SEGMENTS:
- 查LOB段归属:
SELECT table_name, column_name, tablespace_name FROM dba_lobs WHERE owner = 'SCHEMA_NAME' AND table_name = 'T_NAME' - 查每个LOB段具体物理位置:
SELECT segment_name, partition_name, tablespace_name FROM dba_segments WHERE segment_type = 'LOBSEGMENT' AND owner = 'SCHEMA_NAME' - 如果
DBA_LOBS.TABLESPACE_NAME为空,说明建表时根本没配TABLESPACE,LOB段正在默认表空间里“裸奔”
最易被忽略的是:即使主表做了范围分区、每个PARTITION都写了TABLESPACE,只要LOB子句里没跟TABLESPACE,所有分区的LOB段仍共用一个默认位置——这不是配置遗漏,是设计上就割裂的两件事。











