块(Block)管理

1.1、数据块结构

Oracle数据块是I/O的最小单位,其内部结构如下:

|---------------------|------------------------|
| 组成部分 | 说明 |
| Common Header | 块类型、格式、SCN等基本信息 |
| Table Directory | 该块中存储了哪些表的数据 |
| Row Directory | 每行数据在块内的位置指针 |
| Free Space | 未使用的空间,用于INSERT和UPDATE |
| Row Data | 实际的行数据存储区域 |
| Block Overhead | 块管理元数据,约占84~107字节 |

1.2、块大小选择

Oracle支持2KB、4KB、8KB(默认)、16KB、32KB五种块大小。选择原则:

  • **推荐:**OLTP场景(短事务、高并发):8KB(默认),平衡行锁和缓存效率
  • **大块优势:**DSS/数据仓库(大范围扫描):16KB或32KB,减少I/O次数
  • **通用建议:**混合负载:8KB通常是最佳折中
sql 复制代码
-- 查看当前块大小
SHOW PARAMETER db_block_size;

-- 非标准块大小表空间(需要配置对应的缓冲池)
CREATE TABLESPACE ts_16k
  DATAFILE '+DATA' SIZE 10G
  BLOCKSIZE 16K;

-- 必须先配置16K缓冲池
ALTER SYSTEM SET db_16k_cache_size = 2G SCOPE=BOTH;

实例:块大小优化

**S --- Situation(场景):**某OLTP系统数据库(块大小8KB)在处理大量小事务时出现Buffer Busy Waits等待事件,热块争用严重,AWR报告显示buffer busy waits占总等待时间的15%。

T --- Task **(任务):**分析热块争用原因,评估是否需要调整块大小或采用其他优化手段。

A --- Action(行动):

1、分析AWR报告,定位热块争用的具体段:

SELECT owner, object_name, statistic_name, value FROM v$segment_statistics WHERE statistic_name = 'buffer busy waits' ORDER BY value DESC FETCH FIRST 10 ROWS ONLY;

2、发现IDX_ORDER_STATUS索引是主要争用源;

3、评估方案:

方案A:调整块大小(需要重建数据库,不可行)

方案B:使用反向键索引(适合等值查询但不适合范围查询)

方案C:分区索引(将索引分散到多个段,最优方案)

4、选择方案C,创建LIST分区索引。

**R --- Result(结果):**使用分区索引后,buffer busy waits等待时间下降70%。索引段从1个分散到16个分区段,热块争用基本消除。TPS从12000提升至18000,系统吞吐量提升50%。(结论:大多数情况下,调整块大小不如优化索引结构有效。)

1.3、 PCTFREE 和 PCTUSED

PCTFREE和PCTUSED是控制块空间使用的关键参数:

  • PCTFREE **:**块中保留的空闲空间百分比,用于UPDATE操作。默认10%。
  • **PCTUSED:**块使用率低于此值后才重新加入Freelist(仅MSSM)。默认40%。
sql 复制代码
-- 创建表时设置PCTFREE/PCTUSED
CREATE TABLE orders (
  order_id    NUMBER,
  customer_id NUMBER,
  order_date  DATE,
  amount      NUMBER(12,2)
) PCTFREE 20 PCTUSED 40;

-- ASSM模式下查看实际块使用情况
ANALYZE TABLE orders COMPUTE STATISTICS;
SELECT table_name, num_rows, blocks, empty_blocks,
       avg_space, chain_cnt
FROM dba_tables
WHERE owner = 'APP_USER' AND table_name = 'ORDERS';

-- DBMS_SPACE包分析块使用详情
DECLARE
  unformatted_blocks NUMBER;
  unformatted_bytes  NUMBER;
  fs1_blocks NUMBER; fs1_bytes NUMBER;
  fs2_blocks NUMBER; fs2_bytes NUMBER;
  fs3_blocks NUMBER; fs3_bytes NUMBER;
  fs4_blocks NUMBER; fs4_bytes NUMBER;
  full_blocks NUMBER; full_bytes NUMBER;
BEGIN
  DBMS_SPACE.SPACE_USAGE(
    segment_owner => 'APP_USER',
    segment_name  => 'ORDERS',
    segment_type  => 'TABLE',
    unformatted_blocks => unformatted_blocks,
    unformatted_bytes  => unformatted_bytes,
    fs1_blocks => fs1_blocks, fs1_bytes => fs1_bytes,
    fs2_blocks => fs2_blocks, fs2_bytes => fs2_bytes,
    fs3_blocks => fs3_blocks, fs3_bytes => fs3_bytes,
    fs4_blocks => fs4_blocks, fs4_bytes => fs4_bytes,
    full_blocks => full_blocks, full_bytes => full_bytes
  );
  DBMS_OUTPUT.PUT_LINE('0-25% free: ' || fs1_blocks);
  DBMS_OUTPUT.PUT_LINE('25-50% free: ' || fs2_blocks);
  DBMS_OUTPUT.PUT_LINE('50-75% free: ' || fs3_blocks);
  DBMS_OUTPUT.PUT_LINE('75-100% free: ' || fs4_blocks);
  DBMS_OUTPUT.PUT_LINE('Full blocks: ' || full_blocks);
END;
相关推荐
SelectDB14 小时前
阶跃星辰基于 SelectDB 构建 PB 级 Agent 可观测平台
大数据·数据库·aigc
这个DBA有点耶16 小时前
GROUP BY优化全解:如何写出既不丢数据又飞快的分组查询
数据库·mysql·架构
掉头发的王富贵19 小时前
【StarRocks】极限十分钟入门StarRocks
数据库·sql·mysql
Nturmoils19 小时前
WHERE 条件别凭习惯写,常用查询先跑一遍
数据库
Databend2 天前
在 AWS 中国峰会逛了一天,我在 Databend 展台看到了 Agent 数据基础设施的新思路
数据库·人工智能·agent
ClouGence3 天前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因
数据库·后端·oracle
飞将3 天前
从零实现数据库(2)——HashIndex + IndexManager
数据库
Nturmoils4 天前
订单列表慢查询,先看 WHERE、ORDER BY 和 LIMIT
数据库
渣波4 天前
拒绝 SQL 焦虑!手把手带你用 NestJS + Prisma + DTO 写出“防弹”级后端代码
javascript·数据库·后端
倔强的石头_5 天前
KingbaseES 新版MySQL 兼容版体验:旧版迁移 + 功能实测
数据库