83-Oracle 行迁移和行链接

上一期说到了块-区-段-表空间,当单行数据超出数据块大小或是一个数据块空间使用很低,下次插入的时候数据又超过空余空间的时候,Oracle会如何处理。此处引出,行迁移和行链接,Oracle数据库用来处理数据块空间不足的两种机制。迁移是UPDATE触发的被动搬移(原块留指针),链接是超长行固有的分段存储(天然跨块),它们保证了数据在更新或插入时即使超出当前块空间也能成功存储,提高了数据存储的灵活性和可靠性。同样影像就是增加了I/O开销(读取一行数据需要访问多个数据块),降低了查询性能,并可能造成存储碎片。

一、行迁移与行链接的功能特点与技术原理

1. 行迁移 (Row Migration)​
  • 触发条件​:UPDATE操作导致行长度增加,​当前块剩余空间不足​(即使其他块有空间)。
  • 存储原理​:
    • 整行迁移到新块,原块保留行指针​(nrid,指向新块地址)
    • ROWID保持不变(查询时仍通过原ROWID定位)
  • 性能影响​:单行读取需访问2个块​ → 逻辑I/O翻倍(如:consistent gets从2增至3)
2. 行链接 (Row Chaining)​
  • 触发条件​:行长度超过数据块大小​(如8KB块存储20KB数据)。
  • 存储原理​:行被拆分为多个片段(row pieces),用链表跨块存储(首块保存后续块地址)。
  • 性能影响​:读取单行需访问N个块​(N=行长度/块大小)→ I/O呈线性增长。
3. 核心区别

​特性​

行迁移

行链接

触发时机

UPDATE

INSERT或UPDATE

存储形式

整行迁移+指针

行分片+链表

ROWID变化

不变

不变

首次插入是否可能

 二、实操脚本

1. 行链接模拟与检测​
-- 1. 在默认表空间建表
CREATE TABLE row_mig_demo (
  id NUMBER PRIMARY KEY,
  data VARCHAR2(2000)
);
--Table ROW_MIG_DEMO created.
-- 2. 插入初始数据(小数据)
INSERT INTO row_mig_demo VALUES (1, RPAD('X',2000,'Y'));
COMMIT;
--1 row inserted.
-- 3. 更新数据触发行迁移
UPDATE row_mig_demo SET data = RPAD('Y',1800,'Y') WHERE id=1;
COMMIT;
--1 row updated.
-- 4. 检测行迁移--chaintable 需要单独utl的sql
ANALYZE TABLE row_mig_demo LIST CHAINED ROWS INTO chained_rows;
SELECT owner_name, table_name, head_rowid FROM chained_rows;  -- 返回迁移行
--Table ROW_MIG_DEMO analyzed.
OWNER_NAME    TABLE_NAME        HEAD_ROWID
_____________ _________________ _____________________
SYS           ROW_CHAIN_DEMO    AAATUsAAAAAAAEGAAA

-- 5. 观察I/O消耗(逻辑读从2→3)
SELECT /*+ INDEX(t) */ * FROM row_mig_demo t WHERE id=1;

   ID DATA  
_____ ___________________________________________________
    1 YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
2. 行迁移模拟与检测​ 
-- 1. 创建4KB块表空间
ALTER SYSTEM SET db_4k_cache_size=1m SCOPE=BOTH;
--
SYS@CDB$ROOT> alter session set container=CDB$ROOT;
Session altered.
SYS@CDB$ROOT> ALTER SYSTEM SET db_4k_cache_size=1m SCOPE=BOTH;
System altered.
--
CREATE TABLESPACE tbs_4k DATAFILE 'tbs4k.dbf' SIZE 10m BLOCKSIZE 4k;
--
SYS@CDB$ROOT> alter session set container=FREEPDB1;
Session altered.
SYS@CDB$ROOT> CREATE TABLESPACE tbs_4k DATAFILE 'tbs4k.dbf' SIZE 10m BLOCKSIZE 4k;
TABLESPACE TBS_4K created.
-- 2. 建表(设计超长行)
CREATE TABLE row_chain_demo (
  id NUMBER PRIMARY KEY,
  data1 CHAR(1000),
  data2 CHAR(1000),
  data3 CHAR(1000),
  data4 CHAR(1000)
) TABLESPACE tbs_4k;
--Table ROW_CHAIN_DEMO created.
-- 3. 插入数据(触发行链接)
INSERT INTO row_chain_demo VALUES (1, 'All', 'Batch', 'Char', 'Darl');
COMMIT;
--1 row inserted.
--23ai free如果无法检测链接需要现运行utl脚本,此脚本在 SYS 模式下创建 CHAINED_ROWS 表
 @?/rdbms/admin/utlchain.sql
 --Table CHAINED_ROWS created.
-- 4. 检测行链接
ANALYZE TABLE row_chain_demo LIST CHAINED ROWS INTO chained_rows;
--Table ROW_CHAIN_DEMO analyzed.
SELECT owner_name, table_name, head_rowid FROM chained_rows;  -- 应返回1行记录
--
OWNER_NAME    TABLE_NAME        HEAD_ROWID
_____________ _________________ _____________________
SYS           ROW_CHAIN_DEMO    AAATUsAAAAAAAEGAAA

-- 5. 观察I/O消耗(逻辑读=3)
SELECT /*+ INDEX(t) */ * FROM row_chain_demo t WHERE id=1;
SYS@CDB$ROOT> SELECT /*+ INDEX(t) */ * FROM row_chain_demo t WHERE id=1;

   ID DATA1                  
_____ __________
    1 All                   

三、优化策略​

​1. 行迁移修复​
-- 重组表(消除碎片)
ALTER TABLE row_mig_demo MOVE;
--Table ROW_MIG_DEMO altered.
-- 重建索引,名字取实际index
ALTER INDEX <pk_index_name> REBUILD;
2. 行链接修复​ 
-- 使用更大块尺寸表空间
ALTER SYSTEM SET db_32k_cache_size=20m SCOPE=BOTH;
--System altered.
CREATE TABLESPACE tbs_32k DATAFILE 'tbs32k.dbf' SIZE 20m BLOCKSIZE 32k;
ALTER TABLE row_chain_demo MOVE TABLESPACE tbs_32k;
--
SYS@CDB$ROOT> alter session set container=FREEPDB1;
Session altered.
SYS@CDB$ROOT> CREATE TABLESPACE tbs_32k DATAFILE 'tbs32k.dbf' SIZE 20m BLOCKSIZE 32k;
TABLESPACE TBS_32K created.
SYS@CDB$ROOT> ALTER TABLE row_chain_demo MOVE TABLESPACE tbs_32k;
Table ROW_CHAIN_DEMO altered.
3. 预防措施​ 

​问题​

​预防策略​

​行迁移​

设置合理PCTFREE(如15-25%)、定期重组表、避免频繁更新大字段

​行链接​

使用CLOB/BLOB替代VARCHAR2(4000)、增大块尺寸(32KB)、压缩表

​通用​

监控字典视图:DBA_TABLES.CHAIN_CNT、DBA_TABLES.AVG_ROW_LEN

四、官方手册上的记录,留个痕迹

行迁移定义​(Oracle 19c Concepts Guide):

"When a row is updated and can no longer fit in the remaining space of the data block, Oracle moves the entire row to a new block, leaving a forwarding address in the original block."

行链接定义​(Oracle 19c Concepts Guide):

"If a row is too large to fit into one block, Oracle stores the row in a chain of blocks. Row chaining occurs when a row is initially inserted."

检测方法​:ANALYZE TABLE ... LIST CHAINED ROWS

 实操体会:行迁移和行链接均通过破坏数据存储连续性导致I/O增加,区别在于触发机制和存储结构。通过MOVE TABLE和块尺寸优化可有效修复,合理设计表结构及参数可预防。

TIPS:生产环境操作建议在要在业务负载小的时候进行,块尺寸调整需评估内存与IO开销。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值