Amazon RDS for Oracleの一時表領域用インスタンスストアを試してみた

# 1. はじめに

2022/9/14 に [「Amazon RDS for Oracle に、M5d/R5d インスタンス向けの一時テーブルスペース用インスタンスストアおよびデータベーススマートフラッシュキャッシュのサポートを追加」](https://aws.amazon.com/jp/about-aws/whats-new/2022/09/amazon-rds-oracle-instance-store-temporary-tablespace-database-smart-flash-cache-m5d-r5d/) が発表された。

RDS for Oracleにおいて、Oracle上からは通常は参照できないインスタンスストアの領域を、データベースの一時表領域またはスマートフラッシュキャッシュとして利用できる、という機能となる。
今回はいったん一時表領域としての利用について試してみた。

###### [インスタンスストア](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/InstanceStorage.html)
インスタンスストアと呼ばれる直接アタッチされたブロックデバイスストレージの形式。
インスタンスストアボリュームは基本的には永続化されない領域ではあるが、NVMe SSDドライブのため高速。

###### [一時表領域](https://docs.oracle.com/cd/F19136_01/admin/managing-tablespaces.html#GUID-6B941DE0-D109-4AD5-A13C-753AD37335DC)
Oracleの一時表領域はメモリに収まらない範囲のデータをソートするとき等に利用される。

###### [スマートフラッシュキャッシュ](https://docs.oracle.com/cd/F19136_01/admin/managing-memory.html#GUID-31E0885D-53DB-442D-BC5F-DDE0588C915A)
Oracleのスマートフラッシュキャッシュは 11gR2 で搭載された機能で、データベースバッファキャッシュをメモリ上からスマートフラッシュキャッシュに拡張することができ、高速なデータアクセスが可能となる。
なお、Oracle Enterprise Editionでのみ利用可能。

# 2. インスタンスストアについて

#### インスタンスストアのサイズ

RDS for Oracleで利用可能なインスタンスタイプではm5d,r5dで利用可能で、インスタンスストアのサイズは以下となる。

| インスタンスタイプ |メモリサイズ(GiB) | インスタンスストアサイズ(GB)|
|-|-|-|
|  m5d.large    | 8| 75    |
|  m5d.xlarge   | 16| 150   |
|  m5d.2xlarge  | 32| 300   |
|  m5d.4xlarge  | 64| 600   |
|  m5d.8xlarge  | 128| 1200  |
|  m5d.12xlarge | 192| 1800  |
|  m5d.16xlarge | 256| 2400  |
|  m5d.24xlarge | 384| 3600  |
|  r5d.large    | 16| 75    |
|  r5d.xlarge   | 32| 150   |
|  r5d.2xlarge  | 64| 300   |
|  r5d.4xlarge  | 128| 600   |
|  r5d.8xlarge  | 256| 1200  |
|  r5d.12xlarge | 384| 1800  |
|  r5d.16xlarge | 512| 2400  |
|  r5d.24xlarge | 768| 3600  |

#### インスタンスストアを利用できるデータ領域
※今回は一時表領域としての利用について検証します
|データ領域|一時表領域|スマートフラッシュキャッシュ|
|--|--|--|
|用途|大規模なデータのソート、ハッシュ集計、および結合処理が実施される<br>通常はメモリ上のPGAにて実施される|ディスクから読み取られたデータ・ブロックが格納される<br>通常はメモリ上のバッファキャッシュ(db_cache_size)にて実施される|
|利用できる<br>エディション|Standard Edition2, Enterprise Edition|Enterprise Edition|

#### インスタンスストアを利用する際のメリット・デメリット
以下のように高速なアクセスが可能となる点がメリットとなる。

- 読み取りレイテンシの短縮
- より高いスループット
- Amazon EBS ボリュームの負荷を軽減
- ストレージとスナップショットのコスト削減(インスタンスストアのコストはインスタンスのコストに含まれている)

デメリットとしては、インスタンスが停止した際に中身を保持できない、という点があるが、RDS for Oracleの一時表領域やスマートフラッシュキャッシュで利用する場合には、いずれにせよ中身を保持する必要がないため、明らかなデメリットはないと考えている。
なお、その他の制限等については [ユーザガイド](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Oracle.advanced-features.instance-store.html) に記載があるため、利用する際には確認しておくことが望ましい。

# 3. インスタンスストアの一時表領域としての利用

m5d, r5dのインスタンスタイプであれば、インスタンスストアを利用するための前提条件は整っている。

#### 3.1 インスタンスストアに一時表領域(temp01)を新規に作成する

インスタンスストアへの一時表領域の作成は [ユーザガイド](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.Oracle.CommonDBATasks.Database.html#Appendix.Oracle.CommonDBATasks.creating-tts-instance-store) に記載がある。
以下のコマンドでは、 temp01 という名称の一時表領域をインスタンスストアに作成している。

```SQL:インスタンスストアへの一時表領域(temp01)の作成
SQL> EXEC rdsadmin.rdsadmin_util.create_inst_store_tmp_tblspace(p_tablespace_name => 'temp01');
SQL> select tablespace_name, block_size, max_size, status, contents from dba_tablespaces where tablespace_name like 'TEMP%';

TABLESPACE_NAME                BLOCK_SIZE   MAX_SIZE STATUS    CONTENTS
------------------------------ ---------- ---------- --------- ---------------------
TEMP                                 8192 2147483645 ONLINE    TEMPORARY
TEMP01                               8192 2147483645 ONLINE    TEMPORARY
```

#### 3.2 ユーザが利用する一時表領域をインスタンスストアの一時表領域(temp01)に変更する

testusrの一時表領域をtemp01へ変更している。
```SQL:testusrの一時表領域をtemp01へ変更
SQL> alter user testusr temporary tablespace temp01;
SQL> select username, temporary_tablespace from dba_users where username='TESTUSR';

USERNAME               TEMPORARY_TABLESPACE
---------------------- ------------------------------
TESTUSR                TEMP01
```

上記では検証のためtestusr個別に一時表領域を設定している。
本格的に利用する場合には[一時表領域グループ](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Oracle.advanced-features.instance-store.html#CHAP_Oracle.advanced-features.instance-store.temp-ebs)の作成や[デフォルト一時表領域の設定変更](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.Oracle.CommonDBATasks.Database.html#Appendix.Oracle.CommonDBATasks.SettingDefTempTablespace)も可能。

#### 3.3 インスタンスストアの一時表領域(temp01)を利用してみる

SORTが発生するSQLをTESTUSRから実行し、前後でtempfileの状況を確認すると、SORT実行後にTEMP01側(FILE# 2)でBYTES, BLOCKSが増加していることが確認できた。

```SQL:v$tempfile
     FILE# CREATION_CHANGE#      BYTES     BLOCKS NAME                                                        
---------- ---------------- ---------- ---------- ------------------------------------------------------------
         2          1797607 5368709120     655360 /rdslocalstorage/rds_inst_store_tempfile_TESTDB.tmp     

●SORTが発生するSQLの実行

     FILE# CREATION_CHANGE#      BYTES     BLOCKS NAME                                                        
---------- ---------------- ---------- ---------- ------------------------------------------------------------
         2          1797607 2.1475E+10    2621440 /rdslocalstorage/rds_inst_store_tempfile_TESTDB.tmp             
```

ちなみにアラートログを確認すると 5GB ずつ拡張されていることが確認できた。
また、MAXSIZEは **67,123MB** であり、m5d.large のインスタンスストアサイズ **75GB** に合わせて作成されていることがわかる。

```sql:alert log(抜粋)
2022-10-04T18:56:33.163654+09:00
alter database /*rdsadmin_util*/ tempfile '/rdslocalstorage/rds_inst_store_tempfile_TESTDB.tmp' autoextend on next 5120M maxsize 67123M
Completed: alter database /*rdsadmin_util*/ tempfile '/rdslocalstorage/rds_inst_store_tempfile_TESTDB.tmp' autoextend on next 5120M maxsize 67123M
2022-10-04T19:00:14.208857+09:00
Resize operation completed for file# 202, fname /rdslocalstorage/rds_inst_store_tempfile_TESTDB.tmp, old size 5242880K, new size 10485760K
2022-10-04T19:01:37.453122+09:00
Resize operation completed for file# 202, fname /rdslocalstorage/rds_inst_store_tempfile_TESTDB.tmp, old size 10485760K, new size 15728640K
2022-10-04T19:03:00.699786+09:00
Resize operation completed for file# 202, fname /rdslocalstorage/rds_inst_store_tempfile_TESTDB.tmp, old size 15728640K, new size 20971520K
```
#### 3.4 インスタンスストアの一時表領域(temp01)を利用した効果
以下二点で違いを確認できた。

1. 性能(基本的にOracleのベンチマーク結果は公開できないため参考程度)
約20GB程度のデータをソートする処理を複数回実施したところ、**約5%** 程度インスタンスストアの方が実行時間が短くなった。Fetchの時間が含まれており、且つクライアント側が貧弱(t3.small利用)であるため正確なデータではないが、基本的にインスタンスストアの方が性能が向上すると考えてよいと想定している。

1. ストレージ負荷
一時表領域へのアクセスは全てEBSではなくインスタンスストアの負荷になるため、EBSへのソート負荷等が発生しなくなることが確認できた。RDSでは通常は一時表領域もEBS上に作成され、一時表領域として利用したストレージ容量も消費される。インスタンスストアを一時表領域として利用することで、一時表領域がEBSを利用する必要がなくなり、その分ユーザデータの利用に充てることが可能となる。

●EBSの一時表領域を利用：SORT中にEBSの書き込み、FETCH時の読み取りが発生
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/f13d43d6-2c05-e3ce-633d-056ffcd002fb.png)

●インスタンスストアの一時表領域を利用：SORT中のEBSの書き込みが発生しなくなる（インスタンスストアのREAD/WRITEは現時点では確認はできない）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/8eede0cf-b6b3-2571-519f-8e64780e39aa.png)


# まとめ

インスタンスストアを一時表領域として利用することで性能向上、また、ストレージ負荷分離が行えることが確認できた。
特にストレージ負荷分離は、RDSでは単一のストレージタイプしか利用できない中でのストレージへの負荷が分散できるため、ワークロードによっては大きな効果が見込める可能性がある。
取り立ててデメリットはないと認識しており、RDS for Oracleを利用している場合には積極的な利用が推奨されると考えている。

なお、EEではインスタンスストアは [スマートフラッシュキャッシュとしても利用](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Oracle.advanced-features.instance-store.html#CHAP_Oracle.advanced-features.instance-store.configuring) できる。
こちらもワークロードに応じて利用することで性能向上を図ることができると考えている。
(インスタンスストアを分割して両方で利用することも可能)


#### おまけ：インスタンスストアの一時表領域の縮小
インスタンスストアの一時表領域を縮小したい場合、alterコマンドで変更することができない。

```SQL:alter コマンドによる縮小
SQL> alter tablespace temp01 shrink space keep 100M;
alter tablespace temp01 shrink space keep 100M
*
ERROR at line 1:
ORA-04088: error during execution of trigger 'RDSADMIN.RDS_DDL_TRIGGER2'
ORA-00604: error occurred at recursive SQL level 1
ORA-20900: You cant use ALTER TABLESPACE on tablespaces that have tempfiles on the instance store. Use the RDSADMIN.RDSADMIN_UTIL procedures.
ORA-06512: at "RDSADMIN.RDSADMIN_TRIGGER_UTIL", line 317
ORA-06512: at line 2
```

RDSADMIN_UTILを使え、と怒られるのでマニュアルには載ってないが探してみるとRESIZE_TEMP_TABLESPACEというコマンドがあった。
実行してみると無事縮小することができた。

```SQL:RESIZE_TEMP_TABLESPACE
SQL> exec rdsadmin.rdsadmin_util.RESIZE_TEMP_TABLESPACE('TEMP01','100M');

PL/SQL procedure successfully completed.


     FILE# CREATION_CHANGE#      BYTES     BLOCKS NAME                                                        
---------- ---------------- ---------- ---------- ------------------------------------------------------------
         2          1797607 104857600       12800 /rdslocalstorage/rds_inst_store_tempfile_TESTDB.tmp         
```