sql >> データベース >  >> RDS >> Oracle

HikariCP:Oracle11gのmaxLifetimeを設定するために考慮すべきデータベースレベルのタイムアウト

    簡単な答え:なし(デフォルト)。

    記録のために(リンクが変更された場合に備えてここに詳細を含めるために)、プロパティmaxLifetimeについて話します。 HikariCPの:

    このプロパティは、プール内の接続の最大存続期間を制御します。使用中の接続が廃止されることはありません。閉じられた場合にのみ、接続が削除されます。 この値を設定することを強くお勧めします。この値は、データベースまたはインフラストラクチャに課せられた接続時間制限よりも少なくとも30秒短くする必要があります。 値0は、最大存続期間(無限の存続期間)がないことを示します。もちろん、idleTimeout設定に従います。デフォルト:1800000(30分)

    私の経験では、HikariCPがそれを行うのは良いことです。私が知る限り、デフォルトでは、Oracleは接続の最大存続期間を強制しません (JDBCドライバー側(1)でもサーバー側(2)でもありません)。したがって、この点で、「インフラストラクチャによって課される接続時間制限 "は+無限大です-これは、長寿命の接続で問題が発生したことを確認したため、私たちにとって問題でした。これは、値が"少なくとも30秒少ないことも意味します。 "、デフォルトを含む:)

    だと思います 接続層は、そのようなことを処理するために上のプール層に依存しているため、これについては何もしません。 (現在は非推奨の)暗黙的な接続プールでは不可能であり、UCP(代替)がそれを行うかどうかはわかりませんが、HikariCPを使用する場合はそれらを使用しません。

    これで、特定の接続の30分後(通常はさまざまな目的で何度も再利用した後)、HikariCPは接続を閉じて、新しい接続を作成します。これには非常に小さなコストがかかり、長寿命の接続に関する問題が修正されました。このデフォルトには満足していますが、万が一の場合に備えて構成可能にしています(以下の2を参照)。

    (1)OracleDataSource それを制御するための構成ポイント(プロパティまたはシステムプロパティ)を提供していません。私は観察しました 無限の寿命。

    (2)サーバー側の制限については、プロファイルパラメータIDLE_TIMEを参照してください。 。この答えを引用する:

    Oracleはデフォルトでは、非アクティブのために接続を閉じません。 IDLE_TIMEを使用してプロファイルを構成し、Oracleが非アクティブな接続を閉じるようにすることができます。

    IDLE_TIMEの値を確認するには ユーザーのために、このQ&Aからの回答を組み合わせます:

    select p.limit
    from dba_profiles p, dba_users u
    where p.resource_name = 'IDLE_TIME' and p.profile = u.profile and u.username = '...'
    ;
    

    デフォルト値はUNLIMITEDです 。

    干渉する可能性のある他の制限(ファイアウォール...)が適用される可能性があることに注意してください。したがって、構成可能にする方がよいでしょう。 、製品の展開時にそのような問題が発見された場合。

    Linuxでは、物理接続の最大有効期間を確認できます。 データベースに接続されているTCPソケットを監視します。私は自分のサーバーで以下のスクリプトを実行しています(DBの観点からはクライアント host)、1つの引数、ip:portを取ります netstat -tanの出力に表示されるOracleノードの (または複数のノードがある場合はパターン)

    #!/bin/bash
    target="$1"
    dir=$(mktemp -d)
    while sleep 10
    do
        echo "------------ "$(date)
        now=$(date +%s)
        netstat -tan | grep " $target " | awk '{print $4}' | cut -f2 -d: | while read port
        do
            file="p_$port"
            [ ! -e $file ] && touch $file
            ftime=$(stat -c %Z "$file")
            echo -e "$port :\t "$(( now - ftime))
        done
    done
    \rm "$dir"/p_*
    \rmdir "$dir"
    

    それを実行し、sleep中にctrl-cで停止した場合 時間の経過とともに、ループを終了して一時ディレクトリをクリーンアップする必要がありますが、これは100%絶対確実ではありません

    結果では、どのポートも1800秒を超える値を表示しないはずです (つまり30分)、与えるか、1分かかります。以下の出力例を参照してください。最初のサンプルは、1800年代より上の2つのソケットを示していますが、10秒後になくなっています。

    ------------ Thu Jul 6 16:09:00 CEST 2017
    49806 :  1197
    49701 :  1569
    49772 :  1348
    49782 :  1317
    49897 :  835
    49731 :  1448
    49620 :  1830
    49700 :  1569
    49986 :  523
    49722 :  1498
    49715 :  1509
    49711 :  1539
    49629 :  1820
    49732 :  1448
    50026 :  332
    49849 :  1036
    49858 :  1016
    ------------ Thu Jul 6 16:09:10 CEST 2017
    49806 :  1207
    49701 :  1579
    49772 :  1358
    49782 :  1327
    49897 :  845
    49731 :  1458
    49700 :  1579
    49986 :  533
    49722 :  1508
    49715 :  1519
    49711 :  1549
    49732 :  1458
    50026 :  342
    49849 :  1046
    49858 :  1026
    

    以前に存在したソケットの経過時間を認識していないため、スクリプトを30分以上実行して確認する必要があります




    1. MySQLで年齢を計算する(InnoDb)

    2. 列を変更してデフォルト値を変更するにはどうすればよいですか?

    3. SQL ServerのFORMAT()でサポートされている標準の日付/時刻形式の文字列

    4. 実行計画のStarJoinInfo