[アップデート] Amazon DevOps Guru for RDS でも予測的(プロアクティブ)インサイトが生成されるようになりました

2023.03.05

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

いわさです。

先日のアップデートで Amazon DevOps Guru for RDS でも予測的インサイトが生成されるようになりました。

DevOps Guru for RDS は Performance Insights によって収集されたデータを分析し、データベースのパフォーマンスの問題を検出して、アラートの送信と解決するための推奨事項の提示までおこなってくれる機械学習を活用したサービスです。

DevOps Guru が生成するインサイトは現時点で異常が発生していることを示す事後的(リアクティブ)インサイトと、将来異常が発生する予兆を示す予測的(プロアクティブ)インサイトの 2 種類があります。
これまで DevOps Guru for RDS では事後的インサイトのみがサポートされましたが、今回のアップデートで予測的インサイトもサポートされるようになった形です。

インサイトの生成まで実際に確認してみましたので紹介します。

Aurora PostgreSQL 作成と DevOps Guru 有効化

まずはインサイト生成対象の RDS を用意します。
本日時点では DevOps Guru for RDS は Aurora MySQL と Aurora PostgreSQL でサポートされており、そのどちらでも予測的インサイトを利用することが出来ます。

今回は Aurora PostgreSQL で試してみることにします。

DevOps Guru for RDS の前提条件として RDS Performance Insights が有効化されている必要があります。
DevOps Guru が有効化されていない場合は以下のような形で RDS コンソール上から有効化することも可能です。

データベースを作成出来たら、DevOps Guru ダッシュボードから分析対象リソースを確認してみましょう。

次のように分析されたリソースにデータベースリソースが表示されていれば分析対象になっています。

インサイト生成

では続いて何らからのインサイトを生成していきましょう。

CodeGuru Detector Library のように検出仕様がわかる何かがあると助かるのですが、DevOps Guru は生成するインサイトの一覧を本日時点で(おそらく)公開していません。

こいつは困ったぞと思っていたところで、調べてみると今回のアップデートにあわせて公式ブログが公開されていることに気が付きました。

ここではいくつかのインサイトの例が挙げられていて、PostgreSQL の場合は長時間の Idle In Transaction が存在している場合にインサイトが発生するようです。
これは Begin Transaction したあとに Commit や Rollback されていない状態を指しています。
DevOps Guru for RDS の予測的インサイトの場合は 1,800 秒と 3,600 秒の 2 段階でインサイトが生成されるようです。

データベースとテーブルを作成

まずは、作成した Aurora PostgreSQL へ接続しデータベースとテーブル、レコードを適当に作成しておきます。

[ec2-user@ip-172-31-4-101 ~]$ psql -h hoge0305postgreaurora.cluster-cpnu9ipu74g4.ap-northeast-1.rds.amazonaws.com -p 5432 -U postgres
Password for user postgres: 
psql (13.10, server 13.7)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128, compression: off)
Type "help" for help.

postgres=> create database hogedb;
CREATE DATABASE
postgres=> \c hogedb
psql (13.10, server 13.7)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES128-GCM-SHA256, bits: 128, compression: off)
You are now connected to database "hogedb" as user "postgres".
hogedb=> create table piyo (id int primary key, name2 text);
CREATE TABLE
hogedb=> insert into piyo values (1, '111');
INSERT 0 1
hogedb=> select * from piyo;
 id | name2 
----+-------
  1 | 111
(1 row)

トランザクション開始

次のようにトランザクションを開始して、そのまま一定時間放置させてみます。

hogedb=> begin;
BEGIN
hogedb=*> insert into piyo values (2, '222');
INSERT 0 1

この時 pg_stat_activity では次のようにidle in transactionのレコードを確認することが出来ます。

hogedb=> SELECT xact_start, state, query FROM pg_stat_activity where state = 'idle in transaction';
          xact_start           |        state        |          query          
-------------------------------+---------------------+-------------------------------------
 2023-03-05 00:42:49.104734+00 | idle in transaction | insert into piyo values (2, '222');
(1 row)

このまま 30 分 ~ 1 時間放置しておきます。

生成されたインサイトを確認する

45 分ほど経過したタイミングで DevOps Guru をウォッチしている SNS トピックに次のメッセージが送信されました。
インサイトが生成されたようです。

{
    "AccountId": "123456789012",
    "Region": "ap-northeast-1",
    "MessageType": "NEW_INSIGHT",
    "InsightId": "AMxSFH12NiEZZsr-jfHFv2kAAAAAAAAABI9JEljAspyrigPkDSFhyIgEF5aXkZgR",
    "InsightUrl": "https://ap-northeast-1.console.aws.amazon.com/devops-guru/insight/proactive/AMxSFH12NiEZZsr-jfHFv2kAAAAAAAAABI9JEljAspyrigPkDSFhyIgEF5aXkZgR",
    "InsightType": "PROACTIVE",
    "InsightDescription": "RDS Idle In Transaction Max Time Anomalous",
    "InsightSeverity": "medium",
    "StartTime": 1678006980000,
    "Anomalies": [
        {
            "Id": "ASxlS55FIDOTY5ZI7JWVVH5IME6INWC53KQHNSF2PA7BSBAUIZK3UWCKJV4LAC5X",
            "StartTime": 1678006980000,
            "Description": "Starting on Sun Mar 05 09:03:00 UTC 2023, a connection has been in the \u0027idle in transaction\u0027 state for more than 1800 seconds, raising a warning. This issue might impact performance.",
            "AnomalyResources": [
                {
                    "Type": "AWS::RDS::DBInstance",
                    "Name": "hoge0305postgreaurora-instance-1"
                }
            ],
            "SourceDetails": [
                {
                    "DataSource": "PI_METRICS",
                    "DataIdentifiers": {
                        "metricQuery": "{\"metric\":\"db.state.idle_in_transaction_max_time.avg\",\"filter\":null,\"groupBy\":null}",
                        "unit": "Seconds",
                        "metricDisplayName": "Idle In Transaction Max Time"
                    }
                }
            ]
        }
    ],
    "awsInsightSource": "aws.devopsguru"
}

マネジメントコンソールを確認してみると「継続中の予測的インサイト」に 1 件表示されています。やったー。

RDS のサービスヘルス状況を確認してみると「異常」表示となっていますね。

インサイト一覧の予測的タブを開くと「RDS Idle In Transaction Max Time 異常」という名前で重要度中のインサイトが生成されていることが確認できます。

インサイト詳細

さらにそのインサイトの詳細画面を開くと、インサイトの説明・メトリクス・推奨事項を確認することが出来ます。

説明

説明では Idle in transaction が 1,800 秒を経過したことがわかります。
後述しますが、別のインサイトの場合だと違った表示となります。

メトリクス

メトリクスはインサイトの基になった指標値のタイムラインを表示しています。
閾値として重要度中が 1,800 秒、重要度高が 3,600 秒とされていますね。

推奨事項

インサイトに対する推奨事項が提示されています。

コミットやロールバックするというのは普通ですが、idle_in_transaction_session_timeout を構成することも出来るようです。

開いたトランザクションが、指定された時間(単位はミリ秒)を超えてアイドルだった場合に、セッションを終了します。 これにより、そのセッションが獲得したロックを解放し、コネクションスロットを再利用できるようになります。 また、このトランザクションからのみ見えるタプルがVACUUMできるようになります。

19.11. クライアント接続デフォルト より引用

「DevOps Guru がこれを推奨しているのはなぜですか?」ではこれによって生じる可能性のある問題について案内されています。
ここでは簡単にいうと「VACUUM できなくなるので困ることになるで」と言われています。

RDS コンソールでも確認

今回初めて知ったのですが、インサイトが発生したことは RDS コンソール上でも確認することが出来ます。
インサイトの詳細を確認するためには DevOps Guru コンソールまで遷移する必要がありますが、どのインスタンスでどのくらいの重要度の DevOps Guru インサイトが作成されたのかがすぐにわかります。これはとても良いですね。

RDS コンソール上で DevOps Guru のインサイトが発生していることに気がついたらチーム内で対処方法を検討してください。

3,600 秒経過時のインサイト

ちなみに、その後もうトランザクションを閉じずに放置するとインサイトの重要度が「高」になりました。

対処

次のようにコミットしてみました。

hogedb=> begin;
BEGIN
hogedb=*> insert into piyo values (4, '444');
INSERT 0 1
hogedb=*> commit;
COMMIT
hogedb=> SELECT xact_start, query_start, state_change, state, query FROM pg_stat_activity where state = 'idle in transaction';
 xact_start | query_start | state_change | state | query 
------------+-------------+--------------+-------+-------
(0 rows)

メトリクス上はすぐに下りましたが、インサイトはしばらく出続けていました。
いまで 2 時間くらいなのでいつまで発生するのかわからないですが DevOps Guru for Serverless の時も、対処後にインサイトが消えるまで少し時間がかかったので同じ感じかなと思っています。

ちなみに、今回設定まではしていませんでしたが、Aurora PostgreSQL 13 のデフォルトパラメータだとidle_in_transaction_session_timeoutは次のようになっていました。

hogedb=> SELECT name, setting FROM pg_settings WHERE name LIKE 'idle_in_transaction_session_timeout';
                name                 | setting  
-------------------------------------+----------
 idle_in_transaction_session_timeout | 86400000
(1 row)

ミリ秒なのでデフォルト 24 時間ですね。
3,600 秒を超えてインサイトが継続し続けていても 24 時間経過で自動的にタイムアウトでセッションの終了はされそうです。

idle in transaction については state_change を確認していそう?

ちなみに、自動切断周りを気にして次のように一定間隔で SELECT クエリを発行し続けるパターンも試してみたんですがこちらは検出されませんでした。

hogedb=> begin;
BEGIN
hogedb=*> insert into piyo values (3, '333');
INSERT 0 1
hogedb=*> select * from piyo; \watch 60
 id | name2 
----+-------
  1 | 111
  3 | 333
(2 rows)

Sun Mar  5 01:37:15 2023 (every 60s)

 id | name2 
----+-------
  1 | 111
  3 | 333
(2 rows)

Sun Mar  5 01:38:15 2023 (every 60s)

 id | name2 
----+-------
  1 | 111
  3 | 333
(2 rows)
hogedb=> SELECT xact_start, query_start, state_change, state, query FROM pg_stat_activity where state = 'idle in transaction';
          xact_start           |          query_start          |         state_change          |        state        |        query        
-------------------------------+-------------------------------+-------------------------------+---------------------+---------------------
 2023-03-05 01:36:33.304488+00 | 2023-03-05 08:06:40.953931+00 | 2023-03-05 08:06:40.954075+00 | idle in transaction | select * from piyo;
(1 row)

上記の場合は pg_stat_activity が次のようになります。
xact_start から起算しているのかなと思ったのですが、state_change をベースにアイドル時間を計算していそうな挙動でした。
検証が十分ではない気もするので参考までに。

さいごに

本日は Amazon DevOps Guru for RDS でも予測的(プロアクティブ)インサイトが生成されるようになったので試してみました。

最初良いなと思ったのですが、公式ブログを見る限りだともしかしてサポートされているインサイトは MySQL で 2 つ、PostgreSQL で 1 つだけだったりするのですかね。(少ない?)
改めてインサイト一覧が欲しいなと思いました。
こんなん検出してくれますよ!コストメリットありますよ!という訴求をしたい気持ちです。

DevOps Guru for RDS を使っている方は自動で予測的インサイトも生成されるので、予測的インサイトも生成されるようになったという点だけまず覚えておくと良さそうです。