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>