ASSM and MSSM, Row Chaining, by Example


#1

MSSM & ASSM (Manual & Automatic Segment Space Management)

Locally Managed Tablespace-т сегментийг Automatic эсвэл Manual тохиргоогоор удирддаг. Manual нь сегментийн сул зайг зохицуулахын тулд FREELIST гэх зүйл ашигладаг бол Automatic тохиргоо нь bitmap ашигладаг. Автоматаар тохируулах нь илүү сайн бөгөөд self-tuning хийгдэж байдаг.

Жишээгээр тайлбарлая.

MSSM


a) Сул зайны мэдээлэл freelist-д халгалагдана.
b) PCTFREE болон PCTUSED параметруудыг ашиглан тохируулж болно.

ASSM


a) Сул зайнууд bitmaps -д хадгалагдаж байдаг
b) PCTREE параметрийг л ашиглаж тохируулна.

SQL> conn / as sysdba
Connected.
SQL> show user
USER is "SYS"
SQL> 
SQL> ----- ASSM тохиргоотой tablespace үүсгэе ------
SQL> 
SQL> create tablespace TEST_ASSM datafile '/u01/app/oracle/oradata/DB11G/test_assm01.dbf' size 500m extent management local autoallocate segment space management auto;

Tablespace created.

SQL> 
SQL> ----- MSSM тохиргоотой tablespace үүсгэе ------
SQL>
SQL> create tablespace TEST_MSSM datafile '/u01/app/oracle/oradata/DB11G/test_mssm01.dbf' size 500m extent management local autoallocate segment space management manual;

Tablespace created.

SQL> -- scott хэрэглэгчид үүсгэсэн tablespace-ээс ашиглах зайг оноон өгнө
SQL> alter user scott quota unlimited on TEST_ASSM;
User altered.

SQL> alter user scott quota unlimited on TEST_MSSM;
User altered.

SQL>  --- шалгах --- 
SQL> select tablespace_name, segment_space_management from dba_tablespaces where tablespace_name in ('TEST_ASSM','TEST_MSSM');

TABLESPACE_NAME 	       SEGMEN
------------------------------ ------
TEST_ASSM		       AUTO
TEST_MSSM		       MANUAL

SQL>
SQL>
SQL> ----- scott хэрэглэгчээр нэвтрэе
SQL>
SQL> conn scott/s
Connected.
SQL> show user
USER is "SCOTT"
SQL>
SQL> --- өмнө үүсгэсэн tablespace үүдэд тус тусад нь хүснэгт үүсгэе ---
SQL>
SQL> CREATE TABLE TEST_MSSM_TBL
   (    "EMPNO" NUMBER,
        "ENAME" VARCHAR2(30),
        "EAGE" NUMBER,
        "GENDER" VARCHAR2(6),
        "DEPT" VARCHAR2(30)
   ) PCTFREE 10 PCTUSED 50 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
  TABLESPACE "TEST_MSSM"
/

Table created.

SQL>
SQL>
SQL> CREATE TABLE TEST_ASSM_TBL
   (    "EMPNO" NUMBER,
        "ENAME" VARCHAR2(30),
        "EAGE" NUMBER,
        "GENDER" VARCHAR2(6),
        "DEPT" VARCHAR2(30)
   ) PCTFREE 10 PCTUSED 50 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
  TABLESPACE "TEST_ASSM"
/ 

Table created.

SQL>

Дээрхи жишээний хувьд биз ASSM болон MSSM тохиргоо бүхий tablespace-үүд дээр нэг нэг хүснэгт үүсгэсэн бөгөөд ижил утгыг блок болон extent хэмжигдэхүүнүүдэд оноож өгсөн болно.

Дараах коммандыг sys эрхээр ажиллуулж мэдээллийг хацгаая.

SQL> select table_name, PCT_FREE,PCT_USED, INITIAL_EXTENT, FREELISTS , tablespace_name from dba_tables where table_name in ('TEST_MSSM_TBL','TEST_ASSM_TBL');

TABLE_NAME	  PCT_FREE   PCT_USED INITIAL_EXTENT  FREELISTS TABLESPACE_NAME
--------------- ---------- ---------- -------------- ---------- ---------------
TEST_MSSM_TBL		10	   50	       65536	      1 TEST_MSSM
TEST_ASSM_TBL		10		       65536		TEST_ASSM

SQL>

PCT_USED, FREELISTS утгууд өөр өөр байгааг та харж байгаа байх. Үргэлжлүүлэн тайлбарлая.

MSSM


Дээрхи үр дүнгээс харахад MSSM нь хоосон блокуудыг удирдахын тулд FREELISTS ашигладаг нь харагдах бөгөөд PCT_USED параметр нь хамгийн ихдээ блокын хэдэн хувьд мэдээлэл хадгалахыг тодорхойлж харуулна. Дээрх үр дүнгээс 50% гэдэг нь хэрэв блокт агуулагдаж буй мэдээлэл 50%-с бага бол уг блок freelist-д орж шинэ мэдээллийг уг блокт хадгалах боломжтой болох бөгөөд 50% хүрвэл freelist-ээс хасагдаж уг блокт нэмж мэдээлэл бичигдэхгүй гэсэн үг юм.

ASSM


Automatic segment space management тохиргоотой сегментүүд freelist-ийн оронд bitmaps ашиглан сул блокуудыг тодорхойлдог. Мөн PCT_USED утгыг өөрчилж болохгүй учраас блокын ашиглалт нь block overheads мэдээллүүдийг оруулан 100% ашиглагдах боломжтой гэсэн үг юм. Энэ төрлийн асуудлаас аль болох зайлсхийх хэрэгтэй. Тиймээс PCTFREE утгыг заавал тохируулж өгөх шаардлагай бөгөөд 0 утга өгөхгүй байсан нь дээр. Дээрхээс харахад PCT_FREE=10 гэж байгаа нь тухайн блокын 10%-ийг сул байлгаж цаашид хийгдэх update үйлдлүүдэд зориулагдсан тохиргоо юм.

PCT_USED нь блокын агуулж бүх мэдээллийн хэмжээ (block overhead оруулаад) тухайн заасан хувь хүрэхэд тухайн блокт нэмж мэдээлэл авахгүй болгох тохиргоо учраас ямар үед хэрхэн ашиглах вэ гэдгийг мөн tablespace-ийн ямар тохиргоо ашиглаж байгаагаас улбаалан хэд байх шаардлагатайг тооцоолсны үндсэн дээр өгөх нь зөв юм.

Row Chaining


Хэрэв мэдээлэл нэг блокт багтахгүй бол яах вэ гэдэг асуудал гарч ирнэ. Тиймээс олон блокуудад хувааж байршуулах бөгөөд үүнийг Row Chaining гэж нэрлэнэ. Түүнчлэн block дүүрэлтээс шалтгаалан мэдээлэл хуваагдаж байрших тохиолдолд байж болно.

SQL> insert into SCOTT.TEST_ASSM_TBL values(1,'aa',11,'M','aaaaaa');
SQL> insert into SCOTT.TEST_MSSM_TBL values(1,'aa',11,'M','aaaaaa');
SQL> commit;
Commit complete.

SQL>
SQL> select segment_name, extent_id, block_id, blocks from dba_extents where segment_name in ('TEST_ASSM_TBL','TEST_MSSM_TBL');

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_ASSM_TBL		      0        128	    8
TEST_MSSM_TBL		      0        128	    8

SQL>

Үр дүнгээс харахад 8 блок 1 extent байна гэсэн үг.

Одоо нэг мөрт 8к мэдээлэл байхаар хүснэгтийг засварлая.

SQL> alter table test_assm_tbl add (details varchar2(4000), full_details varchar2(4000));

Table altered.

SQL> alter table test_mssm_tbl add (details varchar2(4000), full_details varchar2(4000));

Table altered.

SQL> desc test_assm_tbl;
 Name					   Null?    Type
 ----------------------------------------- -------- ----------------------------
 EMPNO						    NUMBER
 ENAME						    VARCHAR2(30)
 EAGE						    NUMBER
 GENDER 					    VARCHAR2(6)
 DEPT						    VARCHAR2(30)
 DETAILS					    VARCHAR2(4000)
 FULL_DETAILS					    VARCHAR2(4000)

SQL> desc test_mssm_tbl;
 Name					   Null?    Type
 ----------------------------------------- -------- ----------------------------
 EMPNO						    NUMBER
 ENAME						    VARCHAR2(30)
 EAGE						    NUMBER
 GENDER 					    VARCHAR2(6)
 DEPT						    VARCHAR2(30)
 DETAILS					    VARCHAR2(4000)
 FULL_DETAILS					    VARCHAR2(4000)

SQL>

Одоо хүснэгт бүрт 1000 мөр мэдээллүүд оруулцгаая.

SQL> begin
       for i in 1..1000 loop
               insert into test_assm_tbl values (i,dbms_random.string('U',30),32,'M','IT',dbms_random.string('U',4000),dbms_random.string('U',4000));
               insert into test_mssm_tbl values (i,dbms_random.string('U',30),32,'M','IT',dbms_random.string('U',4000),dbms_random.string('U',4000));
       end loop;
     commit;
     end;
/   

PL/SQL procedure successfully completed.

SQL>

Уг хүснэгтүүдийн талаарх блокын мэдээллийг харъя.

SQL>
SQL> conn / as sysdba
SQL>
SQL> select segment_name, extent_id, block_id, blocks from dba_extents where segment_name in ('TEST_ASSM_TBL','TEST_MSSM_TBL') order by 1, 2;

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_ASSM_TBL		      0        128	    8
TEST_ASSM_TBL		      1        136	    8
TEST_ASSM_TBL		      2        144	    8
TEST_ASSM_TBL		      3        152	    8
TEST_ASSM_TBL		      4        160	    8
TEST_ASSM_TBL		      5        168	    8
TEST_ASSM_TBL		      6        176	    8
TEST_ASSM_TBL		      7        184	    8
TEST_ASSM_TBL		      8        192	    8
TEST_ASSM_TBL		      9        200	    8
TEST_ASSM_TBL		     10        208	    8

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_ASSM_TBL		     11        216	    8
TEST_ASSM_TBL		     12        224	    8
TEST_ASSM_TBL		     13        232	    8
TEST_ASSM_TBL		     14        240	    8
TEST_ASSM_TBL		     15        248	    8
TEST_ASSM_TBL		     16        256	  128
TEST_ASSM_TBL		     17        384	  128
TEST_ASSM_TBL		     18        512	  128
TEST_ASSM_TBL		     19        640	  128
TEST_ASSM_TBL		     20        768	  128
TEST_ASSM_TBL		     21        896	  128

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_ASSM_TBL		     22       1024	  128
TEST_ASSM_TBL		     23       1152	  128
TEST_ASSM_TBL		     24       1280	  128
TEST_ASSM_TBL		     25       1408	  128
TEST_ASSM_TBL		     26       1536	  128
TEST_ASSM_TBL		     27       1664	  128
TEST_ASSM_TBL		     28       1792	  128
TEST_ASSM_TBL		     29       1920	  128
TEST_ASSM_TBL		     30       2048	  128
TEST_MSSM_TBL		      0        128	    8
TEST_MSSM_TBL		      1        136	    8

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_MSSM_TBL		      2        144	    8
TEST_MSSM_TBL		      3        152	    8
TEST_MSSM_TBL		      4        160	    8
TEST_MSSM_TBL		      5        168	    8
TEST_MSSM_TBL		      6        176	    8
TEST_MSSM_TBL		      7        184	    8
TEST_MSSM_TBL		      8        192	    8
TEST_MSSM_TBL		      9        200	    8
TEST_MSSM_TBL		     10        208	    8
TEST_MSSM_TBL		     11        216	    8
TEST_MSSM_TBL		     12        224	    8

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_MSSM_TBL		     13        232	    8
TEST_MSSM_TBL		     14        240	    8
TEST_MSSM_TBL		     15        248	    8
TEST_MSSM_TBL		     16        256	  128
TEST_MSSM_TBL		     17        384	  128
TEST_MSSM_TBL		     18        512	  128
TEST_MSSM_TBL		     19        640	  128
TEST_MSSM_TBL		     20        768	  128
TEST_MSSM_TBL		     21        896	  128
TEST_MSSM_TBL		     22       1024	  128
TEST_MSSM_TBL		     23       1152	  128

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_MSSM_TBL		     24       1280	  128
TEST_MSSM_TBL		     25       1408	  128
TEST_MSSM_TBL		     26       1536	  128
TEST_MSSM_TBL		     27       1664	  128
TEST_MSSM_TBL		     28       1792	  128
TEST_MSSM_TBL		     29       1920	  128
TEST_MSSM_TBL		     30       2048	  128

62 rows selected.

SQL>

Ойролцооноор 30 орчим extent ашиглагдсан бөгөөд 16 дахь extent-с эхэлэн блокын тоо 128 болсон байна. Tablespace extent management нь autoallocate тохиргоотой байгаа учраас oracle extent-ийн хэмжээг 16 дахь extent-с эхэлэн автоматаар тохируулж 128 блоктой болгосныг харуулж байна.

Segment-ийн одоогийн хэмжээг харъя.

SQL> select segment_name, bytes/1024/1024 "MB" from dba_segments where segment_name in ('TEST_ASSM_TBL','TEST_MSSM_TBL');

SEGMENT_NAME		     MB
-------------------- ----------
TEST_MSSM_TBL		     16
TEST_ASSM_TBL		     16

SQL>

Segment тус бүр 16МБ болох нь харагдаж байна.

Илүү дэлгэрэнгүй мэдээлэл гаргаж харцгаая.

SQL>
SQL> exec dbms_stats.gather_table_stats ('SCOTT','TEST_ASSM_TBL');

PL/SQL procedure successfully completed.

SQL> exec dbms_stats.gather_table_stats ('SCOTT','TEST_MSSM_TBL');

PL/SQL procedure successfully completed.

SQL> select table_name, avg_row_len/1024 "K", (avg_row_len*num_rows)/1024/1024 "M" from dba_tables where table_name in ('TEST_ASSM_TBL','TEST_MSSM_TBL');

TABLE_NAME		 K	    M
--------------- ---------- ----------
TEST_MSSM_TBL	7.84863281 7.67234516
TEST_ASSM_TBL	7.84863281 7.67234516

SQL>

Үр дүнгээс харахад дундаж мэдээлэл 7.8КБ бөгөөд 1000 бичлэгийг хадгалсан яг ашиглагдсан хэмжээ нь 7.6МБ байна. Өмнөх үр дүнд segment нь 16МБ гэж үзүүлж байсан билээ. Яагаад 7.6МБ буюу 50% хүрэхгүй хувь ашиглагдсан байхад 16МБ гэж харуулж байгаа юм бол?

Өмнө тайлбарласанчлан блок бүр 10% хоосон зайтай байх тохиргоог санаж байгаа байх.
Одоо тооцоолъё.

SQL> select segment_name, sum(blocks) "Total Blocks", sum(blocks)*8192/1024/1024 "Blocks Size in MB" from dba_extents where segment_name
     in ('TEST_ASSM_TBL','TEST_MSSM_TBL') group by segment_name;  

SEGMENT_NAME	     Total Blocks Blocks Size in MB
-------------------- ------------ -----------------
TEST_MSSM_TBL		     2048		 16
TEST_ASSM_TBL		     2048		 16

SQL>

16МБ-ийн 10% нь 1.6МБ.
7.6МБ + 1.6МБ = 9.2МБ
Бид одоогоор 16МБ - 9.2МБ = 6.8МБ мөн л дутаж байна.

Одоо хичнээн хоосон блок байгааг харцгаая.

ROWID_BLOCK_NUMBER функц нь блокын дугаарыг харахад хэрэглэгддэг. Эхний 10 мөрийг харъя.

SQL>
SQL> select rowid, dbms_rowid.rowid_block_number(rowid) from scott.test_assm_tbl where empno < 10;

ROWID		   DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------ ------------------------------------
AAASQmAAGAAAACEAAA				    132
AAASQmAAGAAAACEAAB				    132
AAASQmAAGAAAACGAAA				    134
AAASQmAAGAAAACIAAA				    136
AAASQmAAGAAAACJAAA				    137
AAASQmAAGAAAACMAAA				    140
AAASQmAAGAAAACOAAA				    142
AAASQmAAGAAAACTAAA				    147
AAASQmAAGAAAACVAAA				    149
AAASQmAAGAAAACXAAA				    151

10 rows selected.

SQL>
SQL> select rowid, dbms_rowid.rowid_block_number(rowid) from scott.test_mssm_tbl where empno < 10;

ROWID		   DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------ ------------------------------------
AAASQlAAHAAAACBAAA				    129
AAASQlAAHAAAACCAAA				    130
AAASQlAAHAAAACEAAA				    132
AAASQlAAHAAAACGAAA				    134
AAASQlAAHAAAACIAAA				    136
AAASQlAAHAAAACKAAA				    138
AAASQlAAHAAAACMAAA				    140
AAASQlAAHAAAACOAAA				    142
AAASQlAAHAAAACQAAA				    144
AAASQlAAHAAAACSAAA				    146

10 rows selected.

SQL>

Дээрхийг харахад нэг мөр 2 млокд хадгалагдсан байна.
Тайлбар: AAASQmAAGAAAACGAAA мөр 134 дугаартай блокд хадгаладсан боловч дараагийн мөрний блокын дугаар 136-с эхэлж байна. Энэ нь 134 дугаар бүхий блокт мэдээлэл нь хадгалагдаж хүрэлцэхгүй байсан учраас 2 блок ашиглажээ.

Нэг мөрийн хэмжээ 7.8КБ бөгөөд нэг блокт хадгалж хүрэлцэхгүй тул 1 мөр хадгалахын тулд 2 блок ашиглагдсан байна. Үүнийг CHAINED ROWS гэж нэрлэнэ. Хичнээн ийм мөр байгааг тооцоолъё.

SQL>
SQL>  create table CHAINED_ROWS (
owner_name         varchar2(30),
table_name         varchar2(30),
cluster_name       varchar2(30),
partition_name     varchar2(30),
subpartition_name  varchar2(30),
head_rowid         rowid,
analyze_timestamp  date
);

Table created.

SQL>
SQL>  analyze table test_assm_tbl list chained rows;

Table analyzed.

SQL>  analyze table test_mssm_tbl list chained rows;

Table analyzed.

SQL> select table_name, count(*) from chained_rows group by table_name;

TABLE_NAME			 COUNT(*)
------------------------------ ----------
TEST_MSSM_TBL			     1000
TEST_ASSM_TBL			     1000

SQL>

Дээрхээс харахад 1 мөр 2 блок ашиглаж байгаа өгөөд тус бүр 7.85КБ хэмжээтэй учраас CHAINED ROWS-с шалтгаалан 16МБ харуулж байгаа нь тодорхой боллоо.
Одоо хүснэгтүүдээ буцааж хоосолоход уг ASSM-ийн хувьд bitmaps, MSSM -ийн хувьд freelist ээ шинэжилж хадгалах болно.

SQL>
SQL> delete from TEST_MSSM_TBL ;

1001 rows deleted.

 SQL> delete from TEST_ASSM_TBL;

1001 rows deleted.

SQL> commit;

Commit complete.

SQL>

Одоо 1 мөр 1 блокт багтах хэмжээний мэдээлэл оруулж шалгацгаая.

SQL>
SQL> begin
       for i in 1..1000 loop
               insert into scott.test_assm_tbl values (i,dbms_random.string('U',30),32,'M','IT',dbms_random.string('U',4000),dbms_random.string('U',3000));
               insert into scott.test_mssm_tbl values (i,dbms_random.string('U',30),32,'M','IT',dbms_random.string('U',4000),dbms_random.string('U',3000));
       end loop;
     commit;
     end;  2    3    4    5    6    7
  8  /

PL/SQL procedure successfully completed.

SQL> exec dbms_stats.gather_table_stats ('SCOTT','TEST_ASSM_TBL');

PL/SQL procedure successfully completed.

SQL> exec dbms_stats.gather_table_stats ('SCOTT','TEST_MSSM_TBL');

PL/SQL procedure successfully completed.

SQL>
SQL> select table_name, avg_row_len/1024 "K", (avg_row_len*num_rows)/1024/1024 "M" from dba_tables where table_name in ('TEST_ASSM_TBL','TEST_MSSM_TBL');

TABLE_NAME		 K	    M
--------------- ---------- ----------
TEST_MSSM_TBL	6.87988281 6.71863556
TEST_ASSM_TBL	6.87988281 6.71863556

SQL>
SQL>  select segment_name, extent_id, block_id, blocks from dba_extents where segment_name in ('TEST_ASSM_TBL','TEST_MSSM_TBL') order by 1, 2;

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_ASSM_TBL		      0        128	    8
TEST_ASSM_TBL		      1        136	    8
TEST_ASSM_TBL		      2        144	    8
TEST_ASSM_TBL		      3        152	    8
TEST_ASSM_TBL		      4        160	    8
TEST_ASSM_TBL		      5        168	    8
TEST_ASSM_TBL		      6        176	    8
TEST_ASSM_TBL		      7        184	    8
TEST_ASSM_TBL		      8        192	    8
TEST_ASSM_TBL		      9        200	    8
TEST_ASSM_TBL		     10        208	    8

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_ASSM_TBL		     11        216	    8
TEST_ASSM_TBL		     12        224	    8
TEST_ASSM_TBL		     13        232	    8
TEST_ASSM_TBL		     14        240	    8
TEST_ASSM_TBL		     15        248	    8
TEST_ASSM_TBL		     16        256	  128
TEST_ASSM_TBL		     17        384	  128
TEST_ASSM_TBL		     18        512	  128
TEST_ASSM_TBL		     19        640	  128
TEST_ASSM_TBL		     20        768	  128
TEST_ASSM_TBL		     21        896	  128

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_ASSM_TBL		     22       1024	  128
TEST_ASSM_TBL		     23       1152	  128
TEST_ASSM_TBL		     24       1280	  128
TEST_ASSM_TBL		     25       1408	  128
TEST_ASSM_TBL		     26       1536	  128
TEST_ASSM_TBL		     27       1664	  128
TEST_ASSM_TBL		     28       1792	  128
TEST_ASSM_TBL		     29       1920	  128
TEST_ASSM_TBL		     30       2048	  128
TEST_MSSM_TBL		      0        128	    8
TEST_MSSM_TBL		      1        136	    8

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_MSSM_TBL		      2        144	    8
TEST_MSSM_TBL		      3        152	    8
TEST_MSSM_TBL		      4        160	    8
TEST_MSSM_TBL		      5        168	    8
TEST_MSSM_TBL		      6        176	    8
TEST_MSSM_TBL		      7        184	    8
TEST_MSSM_TBL		      8        192	    8
TEST_MSSM_TBL		      9        200	    8
TEST_MSSM_TBL		     10        208	    8
TEST_MSSM_TBL		     11        216	    8
TEST_MSSM_TBL		     12        224	    8

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_MSSM_TBL		     13        232	    8
TEST_MSSM_TBL		     14        240	    8
TEST_MSSM_TBL		     15        248	    8
TEST_MSSM_TBL		     16        256	  128
TEST_MSSM_TBL		     17        384	  128
TEST_MSSM_TBL		     18        512	  128
TEST_MSSM_TBL		     19        640	  128
TEST_MSSM_TBL		     20        768	  128
TEST_MSSM_TBL		     21        896	  128
TEST_MSSM_TBL		     22       1024	  128
TEST_MSSM_TBL		     23       1152	  128

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_MSSM_TBL		     24       1280	  128
TEST_MSSM_TBL		     25       1408	  128
TEST_MSSM_TBL		     26       1536	  128
TEST_MSSM_TBL		     27       1664	  128
TEST_MSSM_TBL		     28       1792	  128
TEST_MSSM_TBL		     29       1920	  128
TEST_MSSM_TBL		     30       2048	  128

62 rows selected.

SQL>

Шинэ extent үүд хуваарилагдлаа.

SQL>
SQL> conn scott/s
SQL>
SQL> truncate table chained_rows;

Table truncated.

SQL> analyze table test_assm_tbl list chained rows;

Table analyzed.

SQL> analyze table test_mssm_tbl list chained rows;

Table analyzed.

SQL> select table_name, count(*) from chained_rows group by table_name;

no rows selected

SQL>

Дээрхи үр дүн ямар ч CHAINED ROWS байхгүйг харуулж байна.

ASSM харцгаая

SQL>
SQL> truncate table SCOTT.TEST_ASSM_TBL;

Table truncated.

SQL>
SQL> truncate table SCOTT.TEST_MSSM_TBL;

Table truncated.

SQL> begin
       for i in 10..60 loop
               insert into scott.test_assm_tbl values (i,dbms_random.string('U',30),32,'M','IT',dbms_random.string('U',400),dbms_random.string('U',410));
               insert into scott.test_mssm_tbl values (i,dbms_random.string('U',30),32,'M','IT',dbms_random.string('U',400),dbms_random.string('U',410));
       end loop;
     commit;
     end;
/   2    3    4    5    6    7    8

PL/SQL procedure successfully completed.

SQL> select segment_name, extent_id, block_id, blocks from dba_extents where segment_name in ('TEST_ASSM_TBL','TEST_MSSM_TBL') order by 1, 2;

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_ASSM_TBL		      0        128	    8
TEST_ASSM_TBL		      1        136	    8
TEST_MSSM_TBL		      0        128	    8

SQL>
SQL> select dbms_rowid.rowid_block_number(rowid), count(*) from scott.test_assm_tbl group by dbms_rowid.rowid_block_number(rowid) order by 1;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)   COUNT(*)
------------------------------------ ----------
				 131	      8
				 132	      8
				 133	      8
				 134	      8
				 135	      8
				 139	      8
				 140	      3

7 rows selected.

SQL> select dbms_rowid.rowid_block_number(rowid), count(*) from scott.test_mssm_tbl group by dbms_rowid.rowid_block_number(rowid) order by 1;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)   COUNT(*)
------------------------------------ ----------
				 129	      8
				 130	      8
				 131	      8
				 132	      8
				 133	      8
				 134	      8
				 135	      3

7 rows selected.

SQL>

Дээрхээс харахад 8 бичлэг 1 блокд халгалагдсан байна. Блок бүрээс 3 бичлэг устгая

SQL>
SQL> begin
       for i in 10..60 loop
               if i mod 3 = 0 then
   delete from scott.test_assm_tbl where empno = i;
   delete from scott.test_mssm_tbl where empno = i;
  end if;
       end loop;
     commit;
     end;
/
PL/SQL procedure successfully completed.

SQL>
SQL> select dbms_rowid.rowid_block_number(rowid), count(*) from scott.test_assm_tbl group by dbms_rowid.rowid_block_number(rowid) order by 1;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)   COUNT(*)
------------------------------------ ----------
				 131	      5
				 132	      5
				 133	      5
				 134	      6
				 135	      6
				 139	      5
				 140	      2

7 rows selected.

SQL>
SQL> select dbms_rowid.rowid_block_number(rowid), count(*) from scott.test_mssm_tbl group by dbms_rowid.rowid_block_number(rowid) order by 1;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)   COUNT(*)
------------------------------------ ----------
				 129	      6
				 130	      5
				 131	      5
				 132	      6
				 133	      5
				 134	      5
				 135	      2

7 rows selected.

SQL>

Устгал хийгдсэн тул блокуудад сул зай гарсан байгаа. Тиймээс одоо хэдэн мөр нэмж үзье.

SQL>
SQL> begin
       for i in 10..60 loop
  if i mod 3 = 0 then
  insert into scott.test_assm_tbl values (i,dbms_random.string('U',30),32,'M','IT',dbms_random.string('U',400),dbms_random.string('U',410));
                insert into scott.test_mssm_tbl values (i,dbms_random.string('U',30),32,'M','IT',dbms_random.string('U',400),dbms_random.string('U',410));
         end if;
       end loop;
     commit;
     end;
/   

PL/SQL procedure successfully completed.

SQL>

SQL>
SQL> select segment_name, extent_id, block_id, blocks from dba_extents where segment_name in ('TEST_ASSM_TBL','TEST_MSSM_TBL') order by 1, 2;

SEGMENT_NAME	      EXTENT_ID   BLOCK_ID     BLOCKS
-------------------- ---------- ---------- ----------
TEST_ASSM_TBL		      0        128	    8
TEST_ASSM_TBL		      1        136	    8
TEST_MSSM_TBL		      0        128	    8
TEST_MSSM_TBL		      1        136	    8

SQL>
SQL> select dbms_rowid.rowid_block_number(rowid), count(*) from scott.test_assm_tbl group by dbms_rowid.rowid_block_number(rowid) order by 1;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)   COUNT(*)
------------------------------------ ----------
				 131	      5
				 132	      5
				 133	      5
				 134	      6
				 135	      6
				 137	      8
				 138	      8
				 139	      6
				 140	      2

9 rows selected.

SQL> select dbms_rowid.rowid_block_number(rowid), count(*) from scott.test_mssm_tbl group by dbms_rowid.rowid_block_number(rowid) order by 1;

DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)   COUNT(*)
------------------------------------ ----------
				 129	      6
				 130	      5
				 131	      5
				 132	      6
				 133	      5
				 134	      5
				 135	      8
				 136	      8
				 137	      3

9 rows selected.

SQL>

Дээрхээс харахад test_assm_tbl (The segment managed by ASSM) -д шинэ мөр ороход тэдгээр нь хуучин блокуудыг ашиглаж байна.
Харин test_mssm_tbl (Manual Segment space Management) хүснэгтний хувьд шинэ блокуудыг ашиглаж байна. Учир нь pct_used=50 бөгөөд хуучин блокуудад 50%-с их мэдээллүүд агуулагдаж байна гэсэн үг юм. Тиймээс ASSM дискний хэмжээ хэмнэх тал дээр илүү чухал үүрэг гүйцэтгэж байна.

Row Migration


Row migration гэдэг нь блокд буй мөрийг өөр блок руу шилжүүлэх бөгөөд шинэ байрласан хаягийг хуучин блог дээр хадгалж тухайн мөр дуудагдсан үед шинэ блок руу хуучин блокоос шидэх үйлдэл гэж ойлгож болно. Тиймээс 2 блокоос уншилт явагдаж байгаа тул IO уншилт ихэснэ гэсэн үг юм. Хүснэгтний row movement тохиргоо идэвхжсэн үед ашиглах боломжтой.

SQL> create table a1 (id number);

Table created.

SQL> alter table a1 enable row movement;

Table altered.

SQL>
SQL> SELECT TABLE_NAME,ROW_MOVEMENT FROM tabs WHERE TABLE_NAME='A1';

TABLE_NAME		       ROW_MOVE
------------------------------ --------
A1			       ENABLED

SQL>

#2

Nice article