[Oracle]高水位标记HWM(二)

举报
寒六先生 发表于 2021/02/07 10:50:43 2021/02/07
【摘要】 所谓高水位标记,是指一个已经分配的段中,已经使用的空间与未使用的空间的分界线。在表的使用过程中,随着数据的不断增多(insert),HWM不断向数据段未使用部分方向移动,而在删除数据(delete)的过程中,HWM并不会向反方向移动,即使删除全部数据,HWM依然不会改变。

(八)shrink与move测试

(8.1)测试目的:

    测试shrink与move的区别,主要是第(七)点列出的区别

(8.2)测试步骤

(1)创建测试表,插入数据,分析表,查看统计信息

--创建表
SQL> create table test02
  2  (
  3    id number,
  4    name varchar(15)
  5  );
 
Table created
 
--插入1000万条数据
SQL> declare
  2    i number :=1;
  3  begin
  4    loop
  5      if i > 10000000
  6      then
  7        exit;
  8      end if;
  9      insert into test02 values(i,'euvcg');
 10      i:=i+1;
 11    end loop;
 12    commit;
 13  end;
 14  /
 
PL/SQL procedure successfully completed
 
Executed in 185.125 seconds
 
--创建索引
SQL> create index test02_idx on test02 (id,name);
 
Index created
 
Executed in 17.172 seconds
 
--分析表
SQL> exec dbms_stats.gather_table_stats('LIJIAMAN','TEST02');
 
PL/SQL procedure successfully completed
 
Executed in 3.921 seconds
 
SQL> analyze table test02 compute statistics;
 
Table analyzed
 
Executed in 39.11 seconds

--查看分析结果
SQL> select
  2    dt.table_name,
  3    dt.blocks,
  4    dt.empty_blocks
  5  from
  6    dba_tables dt
  7  where
  8    dt.table_name = 'TEST02';
 
TABLE_NAME                         BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ------------
TEST02                              23357          195
 
Executed in 0.078 seconds
SQL> select
  2    ds.segment_name,
  3    ds.segment_type,
  4    ds.header_file,
  5    ds.header_block,
  6    ds.bytes,
  7    ds.blocks,
  8    ds.extents
  9  from
 10    dba_segments ds
 11  where
 12    ds.segment_name = 'TEST02';
 
SEGMENT_NAME  SEGMENT_TYPE       HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS    EXTENTS
------------- ------------------ ----------- ------------ ---------- ---------- ----------
TEST02        TABLE                        6          130  192937984      23552         94
 
Executed in 0.078 seconds
可以看到。test02一共占用了94个extents,23552个数据块。其中23357个数据块有数据,195个数据块空闲。

接下来,我们先查看表的信息,这里截取了部分结果。在这里,我们需要了解ROWID的作用,rowid是数据在oracle储存中的具体位置,1-6位为object id,7-9位为file_id,10-15位代表block id,16-18位为row number。在下面结果中,前5条数据在AAAACD块中,后6条数据在AAAACE块中。我们取出一个block,查看其数据:

SQL> select * from test02 where rowid like 'AAASNnAAGAAAACM%';
 
        ID NAME
---------- ---------------
      2912 euvcg
      2913 euvcg
      2914 euvcg
      2915 euvcg
      ...  ...
      3394 euvcg
      3395 euvcg
 
484 rows selected

(2)删除test02的一半数据,数据块并没有释放,执行shrink操作

--删除500万条数据
SQL> declare
  2    i number :=1;
  3  begin
  4    loop
  5      if i > 10000000
  6      then
  7        exit;
  8      end if;
  9      delete test02 where id = i;
 10      i:=i+2;
 11    end loop;
 12    commit;
 13  end;
 14  /
--经过查看,数据块未释放

--激活行移动
SQL> alter table test02 enable row movement;
 
Table altered
 
Executed in 0.078 seconds
 
--执行shrink操作 
SQL> alter table test02 shrink space cascade;
 
Table altered
 
Executed in 234.593 seconds

需要注意的是,在执行shrink的过程中,在表上是有锁存在的,在表上存在3级锁(SX)

SQL> select * from v$lock where type in ('TM','TX');
 
SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK
--- ---- ---------- ---------- ---------- ---------- ---------- ----------
 30 TM        74597          0          3          0        178          0
 30 TX       327684       1294          6          0          0          0
 30 TX       327699        994          6          0        178          0

(3)分析数据,查看表信息

SQL> analyze table test02 compute statistics;
Table analyzed

SQL> select
  2    dt.table_name,
  3    dt.blocks,
  4    dt.empty_blocks
  5  from
  6    dba_tables dt
  7  where
  8    dt.table_name = 'TEST02';
 
TABLE_NAME BLOCKS     EMPTY_BLOCKS
---------- ---------- ------------
TEST02          11648          152
SQL> select
  2    ds.segment_name,
  3    ds.segment_type,
  4    ds.header_file,
  5    ds.header_block,
  6    ds.bytes,
  7    ds.blocks,
  8    ds.extents
  9  from
 10    dba_segments ds
 11  where
 12    ds.segment_name = 'TEST02';
 
SEGMENT_NAME  SEGMENT_TYPE       HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS    EXTENTS
------------- ------------------ ----------- ------------ ---------- ---------- ----------
TEST02        TABLE                        6          130   96665600      11800         83
在执行shrink之后,我们的数据块使用量由原来的23552减少为11800。


(4)再次查看上面数据块中的数据,可以看出在执行了shrink之后,该数据块中的数据发生了变化。对于该块,原来的数据保持不变,但是在已经删除数据的空间中,有其它块的数据插入了进来。

SQL> select * from test02 where rowid like 'AAASNnAAGAAAACM%';
 
        ID NAME
---------- ---------------
      2912 euvcg
      4050 euvcg
      2914 euvcg
      4052 euvcg
      2916 euvcg
      4054 euvcg
      3388 euvcg
      3390 euvcg
      3392 euvcg
      3394 euvcg
 
399 rows selected

(8.3)结论

1.shrink是对行数据进行移动。对表进行shrink后,部分行数据的rowid发生了变化,而table所位于的block区域的位置却没有发生变化;

2.shrink产生TM(SX)锁及TX锁。


(8.4)对shrink有了一定的了解,我们再来看一下move

--创建表
create table test03
(
  id number,
  name varchar(15)
);

--插入数据
SQL> declare
  2    i number :=1;
  3  begin
  4    loop
  5      if i > 10000
  6      then
  7        exit;
  8      end if;
  9      insert into test03 values(i,'euvcg');
 10      i:=i+1;
 11    end loop;
 12    commit;
 13  end;
 14  /
 
PL/SQL procedure successfully completed
 
--统计信息
SQL> analyze table test03 compute statistics;
 
Table analyzed
 
--查看统计信息
SQL> select
  2    dt.table_name,
  3    dt.blocks,
  4    dt.empty_blocks
  5  from
  6    dba_tables dt
  7  where
  8    dt.table_name = 'TEST03';
 
TABLE_NAME                         BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ------------
TEST03                                 28            4
SQL> select
  2    ds.segment_name,
  3    ds.segment_type,
  4    ds.header_file,
  5    ds.header_block,
  6    ds.bytes,
  7    ds.blocks,
  8    ds.extents
  9  from
 10    dba_segments ds
 11  where
 12    ds.segment_name = 'TEST03';
 
SEGMENT_NAME SEGMENT_TYPE       HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS    EXTENTS
------------ ------------------ ----------- ------------ ---------- ---------- ----------
TEST03       TABLE                        6          146     262144         32          4

取其中一个数据块,查看存储的信息

SQL> select rowid,id,name from test03 where rowid like 'AAASNxAAGAAAACY%';
 
ROWID                      ID NAME
------------------ ---------- ---------------
AAASNxAAGAAAACYAAA       3880 euvcg
AAASNxAAGAAAACYAAC       3882 euvcg
AAASNxAAGAAAACYAAE       3884 euvcg
AAASNxAAGAAAACYAAG       3886 euvcg
AAASNxAAGAAAACYAAI       3888 euvcg
AAASNxAAGAAAACYAAK       3890 euvcg
AAASNxAAGAAAACYAAM       3892 euvcg
AAASNxAAGAAAACYAAO       3894 euvcg
AAASNxAAGAAAACYAAQ       3896 euvcg
…                           …    …

执行move操作

SQL> alter table test03 move;
 
Table altered
 
SQL> analyze table test03 compute statistics;
 
Table analyzed

SQL> select
  2    dt.table_name,
  3    dt.blocks,
  4    dt.empty_blocks
  5  from
  6    dba_tables dt
  7  where
  8    dt.table_name = 'TEST03';
 
TABLE_NAME                         BLOCKS EMPTY_BLOCKS
------------------------------ ---------- ------------
TEST03                                 14            2
SQL> select
  2    ds.segment_name,
  3    ds.segment_type,
  4    ds.header_file,
  5    ds.header_block,
  6    ds.bytes,
  7    ds.blocks,
  8    ds.extents
  9  from
 10    dba_segments ds
 11  where
 12    ds.segment_name = 'TEST03';
 
SEGMENT_NAME   SEGMENT_TYPE       HEADER_FILE HEADER_BLOCK      BYTES     BLOCKS    EXTENTS
-------------- ------------------ ----------- ------------ ---------- ---------- ----------
TEST03         TABLE                        6          186     131072         16          2

在move之前我们查看了数据块AAASNxAAGAAAACY的信息,一共有242行,在move之后,我们再去查看该数据块,发现没有数据存在。经过查看,id=4340的行信息之前存在该数据块,我们可以去看一下目前该行数据存在哪个数据块,找到新的数据块之后查看数据。

--查看了数据块AAASNxAAGAAAACY的信息,发现没有数据,说明数据已经转移到新的数据块中去了
SQL> select rowid,id,name from test03 where rowid like 'AAASNxAAGAAAACY%';
 
ROWID                      ID NAME
------------------ ---------- ---------------
 
--先前的数据块中存在id=4340这一行数据,我们看一下该行数据目前的rowid
SQL> select rowid,id,name from test03 where id=4340; 
 
ROWID                      ID NAME
------------------ ---------- ---------------
AAASNyAAGAAAAC9AHf       4340 euvcg
--通过rowid,我们可以确定该行数据的新的数据块id,查询该数据块信息
SQL> select rowid,id,name from test03 where rowid like 'AAASNyAAGAAAAC9%';
ROWID                      ID NAME
------------------ ---------- ---------------
...                       ... ...
AAASNyAAGAAAAC9ADz        480 euvcg
AAASNyAAGAAAAC9AD0        482 euvcg
AAASNyAAGAAAAC9AD1        484 euvcg
AAASNyAAGAAAAC9AD2        486 euvcg
AAASNyAAGAAAAC9AD3        488 euvcg
AAASNyAAGAAAAC9AD4        490 euvcg
AAASNyAAGAAAAC9AD5       3880 euvcg
AAASNyAAGAAAAC9AD6       3882 euvcg
AAASNyAAGAAAAC9AD7       3884 euvcg
AAASNyAAGAAAAC9AD8       3886 euvcg
AAASNyAAGAAAAC9AD9       3888 euvcg
AAASNyAAGAAAAC9AD+       3890 euvcg
AAASNyAAGAAAAC9AD/       3892 euvcg
...                       ... ...

结论:1.move之后,与先前数据块信息进行对比,发现数据块信息发生了改变,数据已经移到了其它数据块中。多个数据块的信息合并到了同一个数据块,但是数据的顺序并没有发生改变,即数据在原块中的顺序是怎么样的,迁移到新数据块中还是这样的;

        2.move之后,数据块的使用量减少了,说明move收缩空间,降低高水位;














注:本文转载自,少量修正编目错误,主体内容保持原载不变:

https://www.cnblogs.com/lijiaman/p/7190305.html

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。