LOB在RAC中变慢的根本原因是默认ENABLE STORAGE IN ROW、小CHUNK及缺失LOGGING控制,导致频繁缓存融合争用与redo膨胀;应设DISABLE STORAGE IN ROW、CHUNK为DB_BLOCK_SIZE整数倍、PCTVERSION 10–20,并优选SecureFile以支持DEDUPLICATE、在线COMPRESS和细粒度LOGGING。
LOB字段为什么在RAC里容易变慢?
oracle rac中
(尤其是
/
)性能下降,根本原因不是rac本身,而是默认
+
小 + 缺少
控制,导致大量跨实例的缓存融合(cache fusion)争用和redo膨胀。真实场景中,一个
语句修改10kb的
字段,可能触发几十次
等待。
默认
大小是8KB,但实际分配按
对齐,小
仍存于行内,大
则分散到LOB segment,引发额外I/O和全局资源竞争
RAC节点间共享
结构,高并发
/
易出现
或
操作虽快,但在RAC中可能导致备库/闪回丢失数据,且
的
不作用于索引段,仍写redo
怎么设置LOB存储参数才适合RAC?
关键不是“调大”,而是让
行为可预测、减少跨节点同步开销。重点调整三个参数:
、
、
,并强制
。
设为
整数倍(如8192),避免跨块切分;若LOB普遍>4MB,可设为65536,减少chunk数量和index深度
建议设为10–20(非默认0),防止高并发更新时产生过多旧版本LOB数据块,避免
(snapshot too old)
必须显式指定
,否则即使LOB>4000字节,仍可能因内部优化存入行内,加剧buffer busy waits
创建示例:
SecureFile比BasicFile在RAC里强在哪?
BasicFile在RAC中本质是“伪共享”——每个节点维护自己的LOB缓存和锁管理逻辑,冲突多、诊断难;SecureFile则由RAC-aware的底层引擎统一调度,尤其在并发读写和压缩场景下差异明显。
SecureFile支持
,相同LOB内容只存一份,大幅降低RAC节点间重复传输量
在SecureFile中是在线、无锁的,BasicFile压缩需
,触发全表锁+跨节点重分布
SecureFile的
使用列级密钥,加密/解密不依赖实例本地wallet,避免RAC节点间密钥不一致导致
BasicFile的
开关粒度粗(整个segment),SecureFile可精确到
操作级别(如
是否记redo)
应用层怎么安全地并发读写LOB?
直接
查LOB再
,在RAC中极易死锁或超时;正确做法是绕过行级锁,用乐观控制+原子操作。
写入优先用
+
等批量接口,避免逐字节
引发长时间持有LOB locator
更新LOB时,用
配合应用层version字段,失败则重试,不依赖数据库锁
读取大LOB不要用
直取,改用
分片拉取,降低单次GC流量
禁止在PL/SQL循环里反复
小块数据——每次调用都触发一次LOB locator解析和远程块请求,换成
+批量
能降80%+ GC等待
真正棘手的从来不是LOB有多大,而是应用没意识到:RAC里每个
调用背后,都可能是一次跨节点的块传输和全局队列争用。
lobblobclobenable storage in rowchunkloggingupdateclobgc current block 2-wayCHUNKDB_BLOCK_SIZELOBLOBLOBINDEXINSERTUPDATEenq: TX - row lock contentionenq: UL - contentionNOLOGGINGLOBNOLOGGINGLOBCHUNKPCTVERSIONRETENTIONDISABLE STORAGE IN ROWCHUNKDB_BLOCK_SIZEPCTVERSIONORA-22924DISABLE STORAGE IN ROWCREATE TABLE doc_store (
id NUMBER,
content CLOB
) LOB(content) STORE AS SECUREFILE doc_lob (
CHUNK 8192
PCTVERSION 15
DISABLE STORAGE IN ROW
RETENTION MIN
LOGGING
);DEDUPLICATECOMPRESS MEDIUM/HIGHALTER TABLE ... MOVEENCRYPTORA-28365LOGGINGLOBDBMS_LOB.WRITEAPPENDSELECT ... FOR UPDATEDBMS_LOB.WRITEDBMS_LOB.CREATETEMPORARYDBMS_LOB.CONVERTTOBLOBWRITEUPDATE ... SET lob_col = :new_lob WHERE id = :id AND version = :old_versionSELECT lob_col FROM ...DBMS_LOB.SUBSTR(lob_col, 32767, 1)DBMS_LOB.READDBMS_LOB.OPENREADDBMS_LOB