一、什么是OV存储
当修改表中的数据时候(大部分是update)原先能够完全存储在一个数据块内的行, 在经过更新操作后变大,以至于无法再原地容纳,超过了表设置的最大"PCTFREE"时候,就会产生溢出,此时就会在单独的空间去存储数据,此时的空间就是OV存储。
PCTFREE:块的预留置空间比例。比如设置的15%,存储数据最大占比就是75%,剩余的15%用于数据更新操作。
二、查看表的OV存储
SELECT * FROM sys_ov_stores a, sys_tables b ,sys_gstores c ,sys_stores d
WHERE b.table_id = c.obj_id AND c.GSTO_NO = d.GSTO_NO AND d.OV_STO_NO = a.OV_STO_NO
AND d.OV_STO_NO <> 0 AND a.table_name = '你的表名'
三、OV存储原理
1、创建测试表ROW_MIGRATION,并设置表的预留置空间比例(PCTFREE)为最小的1%。
CREATE TABLE ROW_MIGRATION(id integer PRIMARY KEY ,c_lob VARCHAR2,NAME VARCHAR2,sex int);
set block_pctfree = 1;
2、向表中插入300000数据
DECLARE
n_num integer;
BEGIN
n_num := 300000;
WHILE (n_num >1) LOOP
INSERT INTO ROW_MIGRATION values(n_num,'什么是检查点? 一般所说的检查点是一种将内存中的已修改数据块与磁盘上的数据文件进行同步的数据库事件(Event),是Oracle在数据库一致性关闭、实例恢复和Oracle基本操作不可缺少的机制。,4,199999','ces',1);
n_num := n_num -1;
END LOOP;
END
3、查看存储
SELECT STORE_NO,GSTO_NO,ROW_NUM,DEL_NUM,LSN,DELAY_DROP,OV_STO_NO FROM sys_stores WHERE gsto_no IN (SELECT a.gsto_no FROM sys_gstores a,sys_tables b WHERE a.obj_id = b.table_id AND b.table_name ='ROW_MIGRATION')
此时通过观察存储可以发现并没有产生OV溢出,OV_STO_NO存储号全是为空的代表没有产生溢出。
4、批量更新表中的数据,最好是更新后的数据大于预留空间,这样才能观察出OV溢出存储。
DECLARE
n_num integer;
BEGIN
n_num :=50000;
WHILE (n_num>1) LOOP
UPDATE ROW_MIGRATION SET c_lob ='这里弄大于表预留空间的字符串' WHERE id = n_num;
n_num :=n_num -1;
END LOOP;
end
5、再次观察表的OV存储
此时OV_STO_NO不为空,证明产生了存储溢出,次数OV_STO_NO存储的是sys_ov_stores中的OV存储编号(OV_STO_NO)。
6、总结
当要更新表数据的大小超过了表的预留空间大小,此时就会产生存储溢出,而溢出的数据存在sys_ov_stores表中,原来存储数据的块空间此时存储的是溢出的存储空间地址信息。特殊情况当更新字段为大对象字段时就算更新的数据大于了表的预留空间也不会产生存储溢出,原因是当大对象字段超过512个字节由行内转换成行外存储。
三、OV存储的回收和重复利用
当产生了存储溢出时,删除表后怎么回收溢出的存储和重复利用呢?
OV存储回收:虽然OV存储在DROP等操作后会被回收至自由链,但由于按块管理的原因,这些存储块不能立即作为正常存储分配使用,导致OV存储占用持续增加。
OV存储复用:OV存储的复用是存在的,但存在一定的延迟,回收的存储块不会立即被重新分配使用。
扩展策略:OV存储的扩展按8M进行,初始使用一个8M块,后续扩展也是按8M块进行,未使用的部分挂入自由链以备复用。。