ASM を味わう ~ DISK の I/O を偏らせてみる ~ その11
<ASM を味わう ~ DISK の I/O を偏らせてみる ~ その11>
ペンネーム:ダーリン
前回、 ASM を使った環境では表領域の作成時に DISK Group を構成する各
DISK に比較的均等にデータファイルを分散して格納している様子を確認しま
した。ということはデータにアクセスする際の DISK I/O も均等になるのでは
!?と期待したいのですが、「ASM を味わう その9」で見たようにデータの
均等配置と同じようには I/O は分散できていないようです。
今回はこれを確認してみます。
ASM を味わう その9バックナンバー
https://old.insight-tec.com/mailmagazine/ora3/vol265.html
まず、表領域を構成するデータファイルは DISK Group 全体にわたって均等に
配置できました。次に、この表領域にテーブルを作成します。
SQL> create table tbl001 (c1 number,c2 varchar(4000)) storage (initial 1m) Table created. SQL> select owner, segment_name segment, segment_type seg_type 2 , tablespace_name, extent_id ext_id, file_id, block_id blk_id 3 , bytes, blocks 4 from dba_extents 5 where owner = 'DARLING' 6 and segment_name = 'TBL001'; OWNER SEGMENT SEG_TYPE TABLESPACE EXT_ID FILE_ID BLK_ID BYTES BLOCKS ------- ------- -------- ---------- ------ ------- ------ ------- ------ DARLING TBL001 TABLE TEST001 0 6 9 1048576 128
次にデータを投入します。
SQL> begin 2 for i in 1..3840 loop 3 insert into tbl001 (c1,c2) values (i,lpad(i,4000,'0')); 4 end loop; 5 commit; 6 end; 7 / PL/SQL procedure successfully completed. SQL> select count(*) from tbl001; COUNT(*) ---------- 3840
この時点で、EXTENTの発生状況を確認しましょう。
SQL> select segment_name segment, segment_type seg_type, tablespace_name 2 , extent_id, block_id, bytes, blocks 3 from dba_extents 4 where owner = 'DARLING' 5 and segment_name = 'TBL001' SQL> / SEGMENT SEG_TYPE TABLESPACE EXTENT_ID BLOCK_ID BYTES BLOCKS ------- -------- ---------- ---------- -------- ---------- ---------- TBL001 TABLE TEST001 0 9 1048576 128 TBL001 TABLE TEST001 1 137 1048576 128 TBL001 TABLE TEST001 2 265 1048576 128 TBL001 TABLE TEST001 3 393 1048576 128 TBL001 TABLE TEST001 4 521 1048576 128 ............. TBL001 TABLE TEST001 28 3593 1048576 128 TBL001 TABLE TEST001 29 3721 1048576 128 TBL001 TABLE TEST001 30 3849 1048576 128 31 rows selected.
1 レコードに 4000 bytes 以上のデータを INSERT しているので、1 BLOCK に
1 レコードの割合で格納されているはずです。なので、BLOCK ID 9 から
BLOCK ID 3848 までで収まってほしかったのですが、ちょっとはみ出してしま
いました。とにかく、約 30 EXTENT 発生させました。これらは果たして各
DISK に均等に配置されているのでしょうか? つまり、約 30 EXTENT なので、
各 DISK に 10 EXTENT ずつ配置できているのでしょうか。
現状、これについてはなんともわかりません。
その手がかりになる情報はないでしょうか。 DISK の 物理 I/O 量を使って間
接的に状況を把握することは出来ないでしょうか。
試してみましょう。
上記のとおり、データを投入しました。1 BLOCK につき、1 レコードの状態で
格納されていることを確認しましょう。
SQL> analyze table tbl001 compute statistics; Table analyzed. SQL> select table_name, num_rows, blocks from user_tables 2 where table_name = 'TBL001'; TABLE_NAME NUM_ROWS BLOCKS ----------- -------- ---------- TBL001 3840 3840
では、この状態で検索し、どの DISK に I/O が発生するか確認します。
例えば特定のレコードを検索しそのレコードがその DISK にあるかを確認する
ことにします。もしかすると特定の条件で、ある DISK に I/O が偏るように
仕向けてもいいかもしれません。 今回はこの方法を試します。
その前に準備が必要です。全件検索してしまうと、すべての DISK に I/O が
発生してしまいますね。なので、インデックスを、別の DISK Group に作成
します。
SQL> create tablespace test001_idx datafile '+DATA' size 5m autoextend on next 1m; Tablespace created. SQL> alter user darling quota unlimited on test001_idx ; User altered. SQL> connect darling/darling SQL> create unique index ui_tbl001 on tbl001 (c1) tablespace test001_idx; Index created.
では、検索してみます。
特定の条件で DISK I/O を偏らせるのですが、今回は、EXTENT ごとに各 DISK
に配置されていることが予想されるので、特定の EXTENT に存在するデータ
を検索しましょう。
今回 BLOCK_SIZE = 8192 で作成している、1 MB の EXTENT には、128 レコー
ド存在するはずです。なので、128 レコードに対して、検索を行ってみます。
また、3 EXTENT ごとに同じ DISK にデータが配置されている可能性があるので、
さらに、3 EXTENT 後に格納されていると予測されるレコードも検索してみます。
SQL> declare 2 c2_buff varchar2(4000) := null; 3 begin 4 for i in 1..128 loop 5 for j in 1..10 loop 6 select c2 into c2_buf from tbl01 where c1 = i+384*j; 7 end loop; 8 end loop; 9 end; 10 / PL/SQL procedure successfully completed.
では、I/O はどうだったでしょうか。
検索前
~~~~~~~~~~~~~
SQL> select a.name 2 , a.path 3 , a.reads 4 , a.writes 5 , a.bytes_read 6 , a.bytes_written 7 from v$asm_disk a 8 , v$asm_diskgroup b 9 where a.group_number = b.group_number 10 and b.name = 'DG_0001'; NAME PATH READS WRITES BYTES_READ BYTES_WRITTEN ---------- --------------- ---------- ---------- ---------- ------------- DISK_003 /dev/raw/raw5 243 854 18653184 63755264 DISK_002 /dev/raw/raw4 348 901 29921280 65025536 DISK_001 /dev/raw/raw3 345 5039 1441792 81199616
検索後
~~~~~~~~~~~~~
SQL> / NAME PATH READS WRITES BYTES_READ BYTES_WRITTEN ---------- --------------- ---------- ---------- ---------- ------------- DISK_003 /dev/raw/raw5 275 854 23449600 63755264 DISK_002 /dev/raw/raw4 404 901 39313408 65025536 DISK_001 /dev/raw/raw3 346 5042 1445888 81211904
DISK_001 346 - 345 = 1 DISK_002 404 - 348 = 54 DISK_003 275 - 243 = 32
DISK_001 にはほとんど発生していません。v$asm_disk を検索すると、この
READS が毎回 1 上昇することを考えると、TBL001 の検索では、DISK_001
にアクセスしていないと考えてもいいでしょう。
本当は、1つの DISK にアクセスが集中すると面白かったのですが、残念なが
らそうはいきませんでした。セグメントヘッダや、ローカルエクステント管理
表領域のビットマップ管理領域もあるので、その分検索対象データをオフセッ
トするべきだったのでしょう。
来週ももう少し、I/O について見ていきます。
日本シリーズはどちらを応援しようか… 悩ましい茅ヶ崎にて