投稿

ラベル(.Net Core)が付いた投稿を表示しています

PostgreSQLとNpgsqlのコネクションプールの挙動

Npgsqlを用いてPostgreSQLと接続したときのコネクションプールの挙動について検証したものをトピック形式でメモしておく。 バージョン ・PostgreSQL 13 ・Npgsql 8.0.1 Npgsqlの接続プールは各プロセス内のメモリで管理される NpgsqlのコネクションプールはNpgsql名前空間内のstaticなクラスで管理されている。プロセスを複数立ち上げればそれぞれ別々にプールされる。 接続プールは接続文字列ごとに管理される 接続プールは接続文字列ごとに管理され同じ接続文字列の場合にのみ再利用される。またプールされる数も接続文字列ごとにカウントされる。 これは仮に接続先が同じでもパラメータが違うだけで別々となる。 接続プール数、保持時間は接続文字列で指定する パラメータ名 意味 未指定時 Pooling プール有無 true MinPoolSize 最小数 1 MaxPoolSize 最大数 100 ConnectionLifeTime 保持時間(秒) 500 接続の再利用時、セッションパラメータはリセットされる プールされた接続は再利用前に次の文を発行して状態をリセットしている。 SET SESSION AUTHORIZATION DEFAULT RESET ALL 不意の停止でサーバ側にセッションが残る場合がある コネクションプールはプロセスの終了時にすべて切断される。ただしプロセスの強制中断などで解放処理が走らないとサーバ側でセッションが残ってしまう。残ったセッションはサーバの同時接続数の枠を埋めてしまう。 接続がプールされた状態でDBを再起動すると次の利用時にエラーになる コネクションプールが残った状態でPostgreSQLサーバを停止・再起動してもプールされた接続のインスタンスは破棄されない。そして次にその接続が再利用されるとNpgsqlException (0x80004005)が発生する。 DBのみ再起動すると予期せぬタイミングで接続エラーとなってしてしまう可能性がある。 最大プール数を超えた場合は待機状態になる MaxPoolSizeを超えてOpenを行ったとき、接続数に空きが出るまで他の処理の終了を待機する。待機する時間は通常の接続タイムアウトと同じで接続文字列(Timeout)で指定できる。 タイム...

システム時刻を変更したときの.Netプログラムの時間関係への影響

サーバー系のプログラムでは一定時間ごとに処理を行う定期処理を組む場合がある。もし動作中にOSのシステム時刻を変更された場合にどうなるのか。今回は.NetでのWindowsのシステム時刻を変更したときの動作を確認した。 SleepとDelay まずはSleep系の挙動を確認する。恐らくクロックカウントを利用しているのでシステム時刻の影響は無いと想定される。 Thread.SleepとTask.Delayで次のようなコードを書いた。なお環境は.Net Core3.1だ。 void TestSleep() { while (true) { Thread.Sleep(10000); Debug.WriteLine("tick"); } } async Task TestDelay() { while (true) { await Task.Delay(10000); Debug.WriteLine("tick"); } } プログラムを起動した状態でシステム時刻を適当にずらす。ストップウォッチを持って計測したところ、システム時刻を進めても戻してもきちんと10秒ごとにデバッグ文が出力された。 Thread.SleepとTask.Delayはシステム時刻に影響を受けないことが確認できた。 DateTime.Now 次にDateTimeの現在日時を確認する。Sleepが定期動作することが分かったので次のコードを書く。 void TestDateTime() { while (true) { Thread.Sleep(10000); Debug.WriteLine($"{DateTime.Now:MM/dd HH:mm:ss}"); } } 結果 11/12 21:40:33 11/12 21:40:43 _ここで5秒時間を戻す 11/12 21:40:48 11/12 21:40:58 当然ではあるがシステム時刻に合わせて日時が変わった。このことからDateTime.Nowを経過時間の判定に利用する場合は、時刻飛びや遡りが起きることに注意が必要だ。 Stopwatch 次は高性能...

ソフトウェアにおける日本時間のズレ

日本時間(JST)の時差は世界標準時(UTC)+9時間である。日本は国内時差は無いしサマータイムも採用していないので、それだけ覚えておけば大丈夫。 と思っていたのだが、この度そうでないことを知った。切っ掛けはWindowsのASPで動くバックエンドとChromeブラウザ間でUNIX時刻でやり取りをしていたとき。明治生まれの人の誕生日が微妙にずれる時があるのだ。 日本時間のブレ 調べた結果、日本時間は次の2パターンで+9時間でない場合がある。 1)~1888年 今の日本標準時が設定されたのがこの年(明治21年)だそうだ。ということはこれより前は日本時間自体が存在しないわけだが、システムによっては+9時間18分が採用されている。 2)1949年~1951年の夏 この時期は日本でもサマータイムが導入されていたらしい。なのでこの年の夏季はUNIX時刻も1時間ずれる。 環境による違い 例えばChromeブラウザでJavascriptを動かすと、上記の通りの結果が返ってる。 > new Date(1887, 0, 1, 0, 0, 0) Sat Jan 01 1887 00:00:00 GMT+0918 (日本標準時) > new Date(1950, 7, 1, 0, 0, 0) Tue Aug 01 1950 00:00:00 GMT+1000 (日本標準時) それぞれ+9時間18分、+10時間のタイムゾーンになっている。 今度はWindows PowerShellでやってみる。 > ((Date "1887/1/1") - (Date "1887/1/1" -AsUTC)).ToString() 09:00:00 > ((Date "1950/8/1") - (Date "1950/8/1" -AsUTC)).ToString() 09:00:00 両方ともUTCとの時間差は+9時間となっている。 ChromeブラウザやLinuxなどはタイムゾーンの設定をパブリックなデータベースの「tz database」から取得している。一方でWindowsの場合はMicrosoftが管理する時差データを使っている。Microsoftのデータベースでは上記2ケースの例外は考...