<p>FREELISTS 在 Oracle 19c RAC 中必须禁用,因其仅适用于 MSSM,而 19c 默认启用 ASSM;在 ASSM 下该参数完全无效,且在 RAC 中会引发 gc buffer busy acquire 和 enq: TX - row lock contention,加剧段头与位图块争用。</p>

Oracle 19c 高并发写入下,别再碰 FREELISTS —— 它在 RAC 和 ASSM 环境中不仅无效,还会加剧争用。
为什么 FREELISTS 在 19c RAC 中必须禁用
Oracle 19c 默认启用 ASSM(Automatic Segment Space Management),而 FREELISTS 是手工段空间管理(MSSM)的产物。RAC 环境中,FREELISTS 要求每个实例维护本地空闲列表并跨节点同步,极易引发 gc buffer busy acquire 和 enq: TX - row lock contention。实测显示:启用了 FREELISTS 的哈希分区表在双节点各 500 并发插入时,平均单条耗时飙升 4 倍以上。
- FREELISTS 参数对 ASSM 表段完全无效 ——
ALTER TABLE t STORAGE(FREELISTS 4)不会改变任何行为 - RAC 中多个实例同时修改同一 freelist group 的位图块,会触发高频全局缓存块传输(GCS)
- 即使单实例,FREELISTS 也会导致热块集中在 segment header,与序列热点叠加后形成“双重瓶颈”
ASSM 下真正起作用的是 PCTFREE 和 INITRANS
在 ASSM 段中,空间分配由位图块(bitmap block)动态管理,PCTFREE 和 INITRANS 才是影响高并发插入的关键参数:
-
PCTFREE决定数据块预留空间比例;设太低(如 0)会导致频繁块分裂,设太高(如 40)则浪费空间、降低块密度。推荐值:10(默认)适用于多数 OLTP 场景;若字段更新少、插入密集,可降至5 -
INITRANS控制块头初始事务槽数量;默认2在高并发下很快耗尽,引发TX - row lock contention。建议设为16或32(最大支持值取决于块大小) - 修改需重建段:
ALTER TABLE t MOVE PCTFREE 5 INITRANS 16,之后记得重建索引
如何验证当前段是否真在用 ASSM
别只看文档,默认不等于生效。必须查实际段属性:
- 确认表空间是否 ASSM:
SELECT extent_management, allocation_type FROM dba_tablespaces WHERE tablespace_name = 'YOUR_TS'→ 结果应为LOCAL+UNIFORM或AUTO - 确认表段是否 ASSM:
SELECT segment_space_management FROM dba_segments WHERE segment_name = 'YOUR_TABLE'→ 必须返回AUTO - 查 FREELISTS 是否被忽略:
SELECT table_name, freelists, freelist_groups FROM dba_tables WHERE table_name = 'YOUR_TABLE'→ 即使显示非零,也代表历史定义,不生效
比调参数更关键的是避免 ASSM 失效场景
某些操作会让 Oracle 退回到 MSSM 行为,等同于手动打开 FREELISTS 风险:
- 显式指定
STORAGE(FREELISTS N)或MINEXTENTS等 MSSM 参数 → 触发警告但可能静默降级 - 使用
ALTER TABLE ... ALLOCATE EXTENT手动扩展 → 可能绕过位图管理逻辑 - 从 11g 以前版本升级未执行
DBMS_SPACE_ADMIN.SEGMENT_MGMT_TEST校验 → 存量段可能仍为 MSSM
最稳妥做法:新建表时明确用 SEGMENT CREATION IMMEDIATE + 不带任何 FREELISTS 相关子句,并在创建后立即查 dba_segments.segment_space_management 确认为 AUTO。


















