Oracle 高水位(HWM: High Water Mark) 说明
一. 准备知识:ORACLE的逻辑存储管理.
ORACLE在逻辑存储上分4个粒度: 表空间, 段, 区 和 块.
1.1 块: 是粒度最小的存储单位,现在标准的块大小是8K,ORACLE每一次I/O操作也是按块来操作的,也就是说当ORACLE从数据文件读数据时,是读取多少个块,而不是多少行. 每一个Block里可以包含多个row.
1.2 区: 由一系列相邻的块而组成,这也是ORACLE空间分配的基本单位,举个例子来说,当我们创建一个表Dave时,首先ORACLE会分配一区的空间给这个表,随着不断的INSERT数据到Dave,原来的这个区容不下插入的数据时,ORACLE是以区为单位进行扩展的,也就是说再分配多少个区给Dave,而不是多少个块.
1.3 段: 是由一系列的区所组成, 一般来说, 当创建一个对象时(表,索引),就会分配一个段给这个对象. 所以从某种意义上来说,段就是某种特定的数据.如CREATE TABLE Dave,这个段就是数据段,而CREATE INDEX ON Dave(NAME), ORACLE同样会分配一个段给这个索引,但这是一个索引段了.查询段的信息可以通过数据字典: SELECT * FROM USER_SEGMENTS来获得.
1.4 表空间: 包含段,区及块.表空间的数据物理上储存在其所在的数据文件中.一个数据库至少要有一个表空间.
表空间(tableSpace) 段(segment) 盘区(extent) 块(block) 关系
http://blog.csdn.net/tianlesoftware/archive/2009/12/08/4962476.aspx
当我们创建了一个表,即使我没有插入任何一行记录, ORACLE还是给它分配了8个块. 当然这个跟建表语句的INITIAL 参数及MINEXTENTS参数有关. 如:
STORAGE
(
INITIAL 64K
MINEXTENTS 1
MAXEXTENTS UNLIMITED
);
也就是说,在这个对象创建以后,ORACLE至少给它分配一个区,初始大小是64K,一个标准块的大小是8K,刚好是8个BLOCK.
Oracle Table 创建参数 说明
http://blog.csdn.net/tianlesoftware/archive/2009/12/07/4954417.aspx
二. 高水线(High Water Mark)
2.1 官网说明如下
http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/logical.htm#CNCPT89022
To manage space, Oracle Database tracks the state of blocks in the segment. The high water mark (HWM) is the point in a segment beyond which data blocks are unformatted and have never been used.
MSSM uses free lists to manage segment space. At table creation, no blocks in the segment are formatted.When a session first inserts rows into the table, the database searches the free list for usable blocks. If the database finds no usable blocks, then it preformats a group of blocks, places them on the free list, and begins inserting data into the blocks. In MSSM, a full table scan reads all blocks below the HWM.
ASSM does not use free lists and so must manage space differently. When a session first inserts data into a table, the database formats a single bitmap block instead of preformatting a group of blocks as in MSSM. The bitmap tracks the state of blocks in the segment, taking the place of the free list. The database uses the bitmap to find free blocks and then formats each block before filling it with data. ASSM spread out inserts among blocks to avoid concurrency issues.
Oracle 自动段空间管理(ASSM:auto segment space management)
http://blog.csdn.net/tianlesoftware/archive/2009/12/07/4958989.aspx
Every data block in an ASSM segment is in one of the following states:
(1)Above the HWM
These blocks are unformatted and have never been used.
(2)Below the HWM
These blocks are in one of the following states:
(1)Allocated, but currently unformatted and unused
(2)Formatted and contain data
(3)Formatted and empty because the data was deleted
Figure 12-23 depicts an ASSM segment as a horizontal series of blocks. At table creation, the HWM is at the beginning of the segment on the left. Because no data has been inserted yet, all blocks in the segment are unformatted and never used.
Figure 12-23 HWM at Table Creation
Figure 12-26 Advancing HWM and Low HWM
http://blog.csdn.net/tianlesoftware/archive/2011/05/12/6414765.aspx
2.3.1 执行表重建指令 alter table table_name move;
在线转移表空间ALTER TABLE ... MOVE TABLESPACE ..
当你创建了一个对象如表以后,不管你有没有插入数据,它都会占用一些块,ORACLE也会给它分配必要的空间.同样,用ALTER TABLE MOVE释放自由空间后,还是保留了一些空间给这个表.
2.3.2 执行alter table table_name shrink space;
此命令为Oracle 10g新增功能,再执行该指令之前必须允许行移动 alter table table_name enable row movement;
复制要保留的数据到临时表t,drop原表,然后rename临时表t为原表
2.3.5. Alter table table_name deallocate unused
DEALLOCATE UNUSED为释放HWM上面的未使用空间,但是并不会释放HWM下面的自由空间,也不会移动HWM的位置.
(1)如果是INEXTENT, 可以使alter table tablename deallocate unused将HWM以上所有没使用的空间释放
(2) 如果MINEXTENT >HWM 则释放MINEXTENTS 以上的空间。如果要释放HWM以上的空间则使用KEEP 0。
SQL>alter table tablesname deallocate unused keep 0;
(3)truncate table drop storage(缺省值)命令可以将MINEXTENT 之上的空间完全释放(交还给操作系统),并且重置HWM。
(4)如果仅是要移动HWM,而不想让表长时间锁住,可以用truncate table reuse storage,仅将HWM重置。
(5)ALTER TABLE MOVE会将HWM移动,但在MOVE时需要双倍的表空间,而且如果表上有索引的话,需要重构索引
(6)DELETE表不会重置HWM,也不会释放自由的空间(也就是说DELETE空出来的空间只能给对象本身将来的INSERT/UPDATE使用,不能给其它的对象使用)
(1)可以使用alter table test_tab shrink space命令来联机移动hwm,
(2)如果要同时压缩表的索引,可以发布:alter table test_tab shrink space cascade
2.4.1 ORACLE用HWM来界定一个段中使用的块和未使用的块.
2.4.2. HWM在插入数据时,当现有空间不足而进行空间的扩展时会向上移,但删除数据时不会往下移.
ORACLE 不会释放空间以供其他对象使用,有一条简单的理由:由于空间是为新插入的行保留的,并且要适应现有行的增长。被占用的最高空间称为最高使用标记 (HWM),
2.4.4. ORACLE的全表扫描是读取高水位标记(HWM)以下的所有块.
所以问题就产生了.当用户发出一个全表扫描时,ORACLE 始终必须从段一直扫描到 HWM,即使它什么也没有发现。该任务延长了全表扫描的时间。
2.4.5. 当用直接路径插入行时,即使HWM以下有空闲的数据库块,键入在插入数据时使用了append关键字,则在插入时使用HWM以上的数据块,此时HWM会自动增大。
例如,通过直接加载插入(用 APPEND 提示插入)或通过 SQL*LOADER 直接路径 数据块直接置于 HWM 之上。它下面的空间就浪费掉了。
SQL> create table tt (id number);
SQL>SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
--------------- --------------- ----------
SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
--------------- ---------- ---------- ------------
PL/SQL procedure successfully completed.
SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
--------------- ---------- ---------- ------------
SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
--------------- --------------- ----------
此时表TT 占用的数据库已经是24个了。 但是user_tables 显示的信息还是为空。 因为没有做统计分析。
SQL> exec DBMS_STATS.GATHER_TABLE_STATS('SYS','TT');
PL/SQL procedure successfully completed.
SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
--------------- --------------- ----------
SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
--------------- ---------- ---------- ------------
此时user_tables 已经有了数据,显示的使用了20个数据块。 但是empty_blocks 还是为空。 这里要注意的地方。 这个字段只有使用analyze 收集统计信息之后才会有数据。
SQL> ANALYZE TABLE TT COMPUTE STATISTICS;
SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
--------------- ---------- ---------- ------------
-- 这里有显示空的数据库有3个。 注意:20+3=23. 比占用的24个数据块少一个。因为有一个数据库块被保留用作segment header。
SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
--------------- --------------- ----------
SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
--------------- --------------- ----------
SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
--------------- ---------- ---------- ------------
SQL> analyze table tt compute statistics;
SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
--------------- ---------- ---------- ------------
SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
--------------- --------------- ----------
SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
--------------- --------------- ----------
SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
--------------- ---------- ---------- ------------
SQL> exec dbms_stats.gather_table_stats('SYS','TT');
PL/SQL procedure successfully completed.
SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
--------------- ---------- ---------- ------------
SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
--------------- --------------- ----------
--段的信息已经改变,但是empty_blocks 段没有改变,该段只有使用analyze 才能改变。
SQL> analyze table tt compute statistics;
SQL> SELECT table_name,num_rows,blocks,empty_blocks FROM user_tables WHERE table_name='TT';
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
--------------- ---------- ---------- ------------
SQL> SELECT segment_name,segment_type,blocks FROM dba_segments WHERE segment_name='TT';
SEGMENT_NAME SEGMENT_TYPE BLOCKS
--------------- --------------- ----------
-- 总共8个数据块,7个为空,还有一个是segment header。
四. Alter table move 和Shrink 区别
http://blog.csdn.net/robinson1988/archive/2010/09/07/5868742.aspx
alter table move跟shrink space的区别
http://blog.csdn.net/wyzxg/archive/2010/05/28/5631721.aspx
Move从segment的底部开始,move这些rows到segment的头部。Shrink则是delete/insert相结合,这样会产生非常多的UNDO和REDO。
在10g之后,整理碎片消除行迁移的新增功能shrink space
SQL>alter table <table_name> shrink space [ <null> | compact | cascade ];
compact: 这个参数当系统的负载比较大时可以用,不降低HWM。如果系统负载较低时,直接用alter table table_name shrink space就一步到位了
cascade:这个参数是在shrink table的时候自动级联索引,相当于rebulid index。
alter table table_name enable row movement ;
alter table table_name shrink space compact;
alter table table_name shrink space;
alter table table_name shrink space cascade;
alter index index_name shrink space
1). 对cluster,cluster table,或具有Long,lob类型列的对象 不起作用。
2). 不支持具有function-based indexes 或 bitmap join indexes的表
3). 不支持mapping 表或index-organized表。
通过desc table_name 来检查表中是否有LOB 字段, 如果表没有LOB字段, 直接 alter table move; 然后 rebuild index
也可以单独move lob,但是表上的index 同样会失效. 所以在操作结束,需要对索引进行rebuild。
ON a.owner = b.index_owner AND a.index_name = b.index_name
WHERE a.owner = '&owner' AND a.table_name = '&table_name';
对于普通索引直接rebuild online nologging parallel,
Move 通过移动数据来来降低HWM,因此需要更多的磁盘空间。 Shrink 通过delete 和 insert, 会产生较多的undo 和redo。
总之,使用Move 效率会高点,但是会导致索引失效。Shrink 会产生undo 和redo,速度相对也慢一点。
Oracle 高水位(HWM: High Water Mark) 说明相关推荐
- oracle hwm的位置,Oracle 高水位(HWM)教程(2)
4. 用逻辑导入导出: Emp/Imp 5. Alter table table_name deallocate unused 注:这证明,DEALLOCATE UNUSED为释放HWM上面的未使用空 ...
- ORACLE 高水位(HWM)
在9I中: (1)如果MINEXTENT 可以使ALTER TABLE TABLENAME DEALLOCATE UNUSED将HWM以上所有没使用的空间释放 (2)如果MINEXTENT >H ...
- oracle的高水位和低水位实验,Oracle 高水位问题
Oracle 对数据段的管理有一个高水位(HWM, High Water Mark)的概念.高水位是数据段中使用过和未使用过的数据块的分界线.高水位以下的数据块是曾使用过的,以上的是从未被使用或初始化 ...
- Oracle 高水位问题
Oracle 对数据段的管理有一个高水位(HWM, High Water Mark)的概念.高水位是数据段中使用过和未使用过的数据块的分界线.高水位以下的数据块是曾使用过的,以上的是从未被使用或初始化 ...
- oracle hwm 查询,Oracle HWM( High Water Mark)
Oracle HWM( High Water Mark) 1.什么是HWM 注意:此部分内容请先了解oracle物理结构和逻辑结构 顾名思义,这是一条水位线,oracle的每一个对象都是一个segem ...
- oracle hwm调整语法,各个Oracle 版本下如何调整高水位(HWM)
各个Oracle 版本下如何调整高水位(HWM) 以下没有注明版本号的各版本都适用. 1.CTAS : create table xxx_new tablespace new_tablespace_n ...
- oracle delete block,Oracle delete和truncate对高水位(HWM)的影响详细解析
在讨论高水位之前需要明确一下oracle的逻辑存储的概念:Block.extent.segment.tablespace block:块的概念,他是oracle最小的一个存储单元,一般为8K,也是一次 ...
- mysql 回收高水位_Oracle 高水位(HWM)回收原理及操作方法
一. 高水位(HWM)及其产生原因 High Water Mark,HWM) 是Oracle(Segment)级别的概念.在仅有DML(比如delete,insert)操作时,高水位线只会增长,不会 ...
- 数据表 高水位 mysql_Oracle中的高水位(HWM)
Linux公社(www.linuxidc.com)是专业的Linux系统门户网站,实时发布最新Linux资讯,包括Linux.Ubuntu.Fedora.RedHat.红旗Linux.Linux教程. ...
最新文章
- 部署Wi-Fi 6之前要回答的5个问题—Vecloud
- JAVA随机存储_java-如何将随机整数存储到类的实例中
- 关系型数据库(RDBMS)实质
- 蜘蛛侠3.1(无错版)站群分享源码 带视频,关键字软件安装使用教程
- MyEclipse使用经验归纳
- Tomcat(介绍,JDK安装,Tomcat安装,配置Tomcat监听80端口)
- Yii2学习笔记(一):Yii的安装和使用(base版)
- vc2013控件第一个程序
- 微软服务器补丁每月几号发布,微软补丁日安全通告 |9 月份
- poi ppt 作者属性 修改_POI之PPT文本框生成及样式设置实例
- MarkDown简单使用教程
- (SSM,JQUERY-EASYUI,MYSQL)快递物流系统
- linux smb 添加用户,samba创建新用户
- 领扣LintCode问题答案-5. 第k大元素
- 实现闲鱼自动化脚本-方案对比分析
- String源码 spilt
- 3d智慧城市线上3d模型展示可视化平台
- 雷达模拟器-监控摄像机模拟软件 SPx Video Simulator
- 椭圆机真的不伤膝盖吗
- 【读书笔记】数学之美