話題の記事

【DBのディスクサイズ管理が簡単に】RDSのストレージがストレージの自動スケーリングをサポートしました!

RDSのストレージの空き容量が少なくなりディスクが枯渇してクエリがエラーになったりDBが停止してしまうことがあります。今回DBストレージの自動スケーリングをサポートしたので、ディスク枯渇の恐れが低減し、必要な分のストレージを確保することでランニングコストも低減できます。

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

大栗です。

RDSのストレージの空き容量が少なくなってくると自動で増やしてくれるストレージの自動スケーリングがサポートされたのでレポートしてみます。

2019年6月21日 13:30 JST ストレージのスケーリングでほとんどの場合に停止が発生しない事を追記

RDSのストレージオートスケーリング

RDSではAuroraを除くと事前にストレージサイズを定義して、定義したサイズの料金を支払い使用していました。例えば下図のように300GBのストレージを確保して100GBを使用しているとすると、使用している100 GiBだけでなく使用していない200GBに対しても料金を支払うことになります。

使用していない200GBに対して支払いが発生するのは、あまりクラウド的なモデルではありませんでした。アップデートにより、実際にストレージが少なくなって来ると自動でストレージがサイズアップしてくれるようになり、実際に使う分+αだけ支払えば良くなります。

今までもストレージの余裕が少なくなってきたら手動で増やすことは可能でしたが、タイミングを逸するとストレージ枯渇でデータベースが停止したり、手動で対応するのが面倒だったりと問題が発生しやすい運用となりがちでした。

注意点

以下の状態になるとデータベースの空き容量が不足していると検出されてストレージが自動拡張されます。

  • 使用可能なスペースが割り当てたストレージの10%未満
  • ストレージが不足した状態が少なくとも5分継続する

追加ストレージは、5 GiB以上で最大で割り当てたストレージの10%となります。

なお、筆者が確認したところ2019年6月21日7:00 JST現在ではSQL Serverを除くDBエンジンで対応している模様です。

ほとんどの場合RDSのストレージのスケーリングには停止が不要で、サーバーのパフォーマンスも低下しません。ストレージのスケーリングは6時間または変更状態の期間はストレージの変更ができないので、自動スケーリングでも同様の制約があると思われます。

DB インスタンスストレージの容量を増加する

やってみた

以下の前提で検証しています。

  • リージョン: 東京リージョン
  • DBエンジン: MySQL
  • エンジンバージョン: 5.7.22
  • DBインスタンスクラス: db.t3.medium

RDSのManagement Consoleでデータベースの作成をクリックします。

今回はMySQLを選択して次へをクリックします。

ここでは本番稼動用 - MySQLを選択して次へをクリックします。

今回はストレージ割り当てで20 GiBを割り当てます。ストレージ割り当ては初期状態で実際に使用するストレージサイズです。ストレージの自動スケーリングをチェックして、最大ストレージしきい値を割り当てます。最大ストレージしきい値はストレージが自動スケーリングしたときの最大サイズです。ここでは1000 GiBを設定します。

詳細設定を適切に選択してデータベースの作成をクリックします。

RDSが起動するまで待ちます。

RDSにログインして使用データを増やします。

$ mysql -u awsuser -pmypassword -h storage.cahdiejcylf2.ap-northeast-1.rds.amazonaws.com mydb
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 55
Server version: 5.7.22-log Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [mydb]>

以下のようなテーブルを作成します。

MySQL [mydb]> create table sample_table (
  2  col1 int,
  3  col2 varchar(1024),
  4  col3 date);

元ネタの10レコードを挿入します。

MySQL [mydb]> insert into sample_table (col1, col2, col3)
    ->  values
    ->  (1, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', now()),
    ->  (2, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', now()),
    ->  (3, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', now()),
    ->  (4, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', now()),
    ->  (5, '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234568901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', now()),
    ->  (6, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', now()),
    ->  (7, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', now()),
    ->  (8, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', now()),
    ->  (9, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', now()),
    ->  (10, '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890', now())
    -> ;
Query OK, 10 rows affected, 10 warnings (0.01 sec)
Records: 10  Duplicates: 0  Warnings: 10

MySQL [mydb]>

JOINして1000万レコード(10 * 10 * 10 * 10 * 10 * 10 * 10 レコード)くらいに水増しします。

MySQL [mydb]> insert into sample_table(
    -> select
    -> s1.col1,
    -> s1.col2,
    -> s1.col3
    -> from sample_table s1, sample_table s2, sample_table s3, sample_table s4, sample_table s5, sample_table s6, sample_table s7
    -> );

しばらくすると以下のエラーになりました。ディスクがフルになったようなので結果オーライです。

ERROR 1114 (HY000): The table 'sample_table' is full

数分経ってディスクサイズを確認すると25 GiBに増加しています。元々が20 GiBなので10%では5 GiBを下回るので5 GiBの増加となります。

ストレージの空き容量を確認すると、以下のように空きができています。

さいごに

Amazon Auroraでは実際に使用したデータ量のみの課金となっており、自動でサイズが64TiBまでスケールできます。通常のRDSではユーザ自身で管理する必要があったため、ディスクフルによりDBが停止したり、過剰にサイズを確保して料金やバックアップ時間が長くなったりすることがありました。

今回のアップデートにより、RDSのストレージが必要な分を必要なタイミングで利用することができるようになります。これでランニングコストの低下、バックアップ時間の最適化、運用の手間の低減などが図れます。

ディスク枯渇が発生しないように、有効化しておくと良いと思います。ただしサイズがスケールするまでに数分の遅れが発生するので大量のデータを投入する時には予めサイズを拡張する事を忘れないでください。