
スタッフブログ
SQL Server のログに「パフォーマンスが低下する可能性があります」と出た話
こんにちは。NANAシステム開発SYです。今回は技術ネタです。
ある日、DB サーバのイベントログを眺めていたところ、
「SQL Server のメモリがページアウトされ、パフォーマンスが低下する可能性があります」
という、なかなか不穏な警告が出ているのに気づきました。該当するログはこれです。
イベント ID 17890(ソース:MSSQLSERVER)
SQL Server プロセス メモリの重要な部分がページ アウトされました。
これにより、パフォーマンスが低下する可能性があります。
文面だけ読むと、
- メモリが枯渇している?
- 実はもう遅くなっている?
- 何か設定を変えないとまずい?
と、つい身構えてしまいがちですが、、、
こういうログこそ一旦落ち着いて事実を整理するのが大事だと思います。
イベント ID 17890 とは何か
まず、このイベント ID 17890 ですが、SQL Server が「自分のプロセスに割り当てられているメモリのうち、物理メモリとして保持されている割合がかなり低い状態だな」と判断したときに出す警告ログです。ポイントは、Warning(警告)であってエラーではない今すぐ障害、という意味ではないというところ。
要は、「この状態が続くと、パフォーマンスに影響する可能性があるよ」という、いわば事前注意的なログってことです。
ログに出てくる各数値の意味
このイベントには、だいたい以下の数値がセットで出力されます。今回のログでは、こうなっていました。
Duration(秒):603
Working set (KB):339,944(約 340MB)
Committed (KB):783,632(約 780MB)
Memory utilization (%):43
これだけだと、何事か分からないので、それぞれ順に説明していきますね。
■ Duration(秒数)
ページアウト状態がどれくらいの時間続いているか を示します。
0 秒 → 検出直後
数百秒 → 「しばらくこの状態」
今回は 603 秒なので、一瞬ではなく、ある程度継続していたことが分かります。
■ Working set(作業セット)
SQL Server プロセスが、実際に物理メモリ(RAM)上に置いてもらえている量です。OS が「ちょっとメモリ空けたいな」と判断すると、ここが削られ、ページアウトされていきます。
■ Committed(コミット済みメモリ)
SQL Server が「自分はこれだけメモリを確保している」と認識している総量です。これは、実メモリとページファイル(仮想メモリ)を合わせた概念になります。
■ Memory utilization(%)
「確保しているメモリのうち、何%が物理メモリに載っているか」を見るための指標です。次の計算結果が表示されています。
Working set ÷ Committed × 100
では、上記の理解を元に今回の数値が示していることを整理していきます。
確保しているメモリ:約 780MB
実際に物理上にあるメモリ:約 340MB
つまり、物理メモリ上にあるのは約 43% という状態です。
SQL Server は、この状態を見て、「確保してるメモリの半分以上がページアウトされちゃってるな」と判断し、イベント ID 17890 を出した、という流れになります。
一般的にこの警告は、Working set ÷ Committed の比率が 50% を大きく下回る状態が一定時間続いた場合に出やすいと言われています。
※ なお、これはMicrosoftの公式サイトによると、公開された厳密な仕様値というより、SQL Server 内部の判断ロジックによるものです。実務的には「50% が一つの目安」と考えて問題ないと思います。
今回は問題になるのか?
ここが一番気になるところですが、結論から言うと 今回は特に問題になるケースではなさそうです。というのも、以下の要因が判っていたからです。
・ログが出ている時間帯で、大きなクエリやバッチが動いていない
・SQL Server は低負荷時に大量の物理メモリを保持し続ける必要がない
・OS 側の都合で一時的にページアウトされるのは普通に起きる
そもそもなんですが、SQL Server は、
1.まず物理メモリを使う
2.足りなければページングに回る
という性質を持っています。そのため、今後負荷が上がれば、
1.物理メモリが再び割り当てられる
2.Working set が増える
3.Memory utilization が回復して、この警告も自然に出なくなる
という動きになる可能性が高いと考えます。
設定変更で消すべきか?
ちなみに、「この警告が出るのが嫌だから何か設定を変えたい」という話であれば、
min server memory を 0 ではなく、ある程度大きな値(例えば 10GB など)にする、という選択肢はあります。
ただしこれは、実際に性能問題が起きているわけではないのに、単にログを見えなくするだけの目的で行うため、OS 側のメモリ余裕を減らすリスクもあります。
そういった点を考えると、あまり意味のある対処とは言えないかな、という印象です。
結論
まとめると、
・イベント ID 17890 は即障害を示すものではないことが判った。
・今回の数値で警告が出た理由は、仕組み的に妥当だった。
・低負荷時に一時的に出る分には特に問題ないと考えてもいいと思う。
・実際の性能劣化がなければ、基本は放置で OKと思う。
という事なので、
今回は「仕組みとして理解しておけば十分な警告」
という結論に落ち着きました。
今後もし、
・高負荷時にも頻繁に出る
・体感できる遅延とセットで起きる
・OS 全体のメモリ逼迫が見える
といった状況になったら、その時は改めて深掘りすれば良いかなと考えています。
皆様のお役に立てれば幸いです。
ラーメン 三太♪
皆様、こんにちは♪ NANAシステム開発HYです。
今回は、ラーメンを食べに行ったお話です。
先日、浜松駅近くのモール街にある「ラーメン三太」に行ってきました♪
ここのお店は、会社メンバーが大好きなお店です。
https://www.trest-hamamatsu.com/santa/
私はねぎ醤油に、キムチをトッピングしました。
美味しかった~♪
ラーメン、好きなんですよね~。笑。
とんこつラーメンなのですが、臭みがなく、個人的には大好きな味です。
少し遅い時間に行ったのですが、お客さんがいっぱいでした。
また行こうっと♪
バロック式とジャーマン式♪
皆様、こんにちは♪ NANAシステム開発HYです。
今回は、リコーダー♬のお話です。
タイトルを見て、すぐにソプラノリコーダーの事だと理解した方は、リコーダーが好きな方だと思います。
今まで私は、ジャーマン式のソプラノリコーダーを吹いていましたが、今回、バロック式の方を購入しちゃいましたっ♪
並べてみるとよくわかるのですが、穴の大きさが違うんですね。
木目調の方が、今まで吹いていたジャーマン式。
エポニー調の方が、今回購入したバロック式。
なぜ今回バロック式を購入したのか、というと、
①リコーダーを永く楽しむならバロックの方が指使いが良いと教えてもらった。
②ソプラノだけでなく、アルトリコーダーも吹くようになった。アルトはバロック式。
という理由です。
今回購入したリコーダーって、3000円程度。
それでいて、しっかり楽器なので、コスパ最強の楽器だと思っています。
【SQL Server】TEMPDB のデータファイルが巨大で困ったけど…調べたら “むしろ適正”?
こんにちは。NANAシステム開発SYです。今回は技術ネタです。
■最適サイズを探っていくための記録
SQL Server を運用していると、tempdb のサイズが気づいたらとんでもなく大きくなっていた――という経験は多くの管理者が一度は通る道ではないでしょうか。
先日、まさに自分の環境で同じ状況に遭遇し、「これはさすがに大きすぎるのでは?」と思って調査を始めました。
ところが色々調べていくうちに、
「あれ?これ Microsoft の推奨サイズ(=適正サイズ)に近いのでは…?」
という結論に近づいていきました。
今回はその気づきと、実際に tempdb がどれだけ使われているかを記録し、最適サイズを導き出すまでのプロセスをまとめます。
■ そもそも tempdb は “大きくなるもの”
tempdb は SQL Server の作業領域として、次のような処理に使われるようです。
・ORDER BY / GROUP BY など大規模ソート
・ハッシュ結合・ハッシュ集計
・一時テーブル・テーブル変数
・Snapshot Isolation / RCSI のバージョンストア
・インデックス再構築(ONLINE)
このため、上記をガンガン行うアプリケーションほど tempdb はよく伸びます。
しかも、SQL Server はサービス再起動のたびに tempdb を初期サイズにリセットするため、
初期サイズが小さいとピーク負荷時に一気に巨大化してしまうことがあります。
なので、「ファイルを小さくしても、また必要に応じて大きくなった」と感じることがあります。
「縮小 → 拡張 → 縮小 → 拡張」
という悪循環が起き、パフォーマンスを落としていたように思います。
■ Microsoft の推奨サイズに “落ち着いていた” という気づき
tempdb の適正サイズは
「CPU コア数 ×(8GB 〜 16GB / ファイル)」
というのが Microsoft の基本推奨です。
例えば CPU 8コアなら:
・ファイル数:8個
・1ファイル初期サイズ:8GB
・合計:64GB
巨大化したと悩んでいた環境でふと確認すると、まさに この推奨レンジに収まっていた のです。
「巨大化した!」と焦ったわりには、ただの最適化された姿だったわけです。
■ とはいえ、“実際にどれだけ使っているか” を知らないままでは判断できない
でも、いくら推奨値に収まっているとはいえ、本当に適正かどうかはワークロードを見て決めるべきです。
そこで、tempdb の使用量を 時系列でログに残す仕組み を作りました。
▼ TEMPDB の“実際の使用量”をログに残す T‑SQL
以下のようにログテーブルを作り、
SQL Server Agent で 1分ごとに実行することで
ピーク時の tempdb 消費量を詳細に把握できます。
▼ ログテーブル作成
▼ 採取用プロシージャ
■ ログを取り始めてわかったこと
最初の数日記録をとってみて分かったのは、
・殆ど使っていない時間帯が多い
・逆に特定時間帯だけドカンと増える
ということ。
■ 今後の方針:実測しながら最適値に寄せていく
今後はログデータをもとに、
・ピーク使用量 + 20〜30% の余裕
・拡張が発生しない初期サイズ
・適切な autogrowth 設定(%ではなく固定MB)
これらを調整し、tempdb を“業務に最適化されたサイズ”へ整えていく予定です。
■ まとめ
・TEMPDB は負荷によって大きくなるのが普通
・縮小してもまた必要に応じて拡張する
・Microsoft 推奨サイズに近いことも多い
・本当に妥当かどうかは、実際の使用量をログに残して判断するべき
・ログを取るとワークロードの癖が見えてくる
・そこから初めて “最適サイズ” の議論ができる
tempdb の巨大化は “壊れている” のではなく、「あなたのワークロードを反映した姿」 であることが多いです。なので大事なのは、まずは実測から始めることだと感じました。
これが tempdb 最適化のスタート地点だと実感した出来事でした。些細な情報ですが、皆様のお役に立てれば幸いです。
ハンバーグランチ♪
皆様、こんにちは♪ NANAシステム開発HYです。
今回は、ハンバーグを食べに行ったお話です。
先日、昼休みにZAZA中央館の近くを散歩していたら、気になるお店を発見!
ひとりではちょっと寂しかったので、お客様を誘って、一緒に行ってきました。
「ハンバーグランチ Cafe de 一休」さんです。
https://hamamatsu-machinaka.jp/news/50353/
美味しかったです!
私は和風ハンバーグを注文したのですが、大根おろしがてんこ盛りで、とっても美味しかったです。
また行こうっと♪
【Unity】Windowsユーザー名が日本語だとBuildが落ちる問題にハマった話
こんにちは。NANAシステム開発SYです。たまに技術的なことも書いていこうと思います。
今回は Unity でビルドをしたときに遭遇した、「Windowsログインユーザー名が日本語だとビルドがこける」という問題について書いてみます。Unityが外国製なので、仕方ないと言えばそうなんですが、解消しないといけないですからね。
検索して出てくる解決策は、ほとんど以下の内容でした。
「1バイト文字のユーザー名で Windows ユーザーを作り直す」
でも、ユーザー作り直しってそんな簡単にやりたいもんじゃないですよね。
ということで、今回は 「何が起きているのか?」を正しく理解して対処する という方針で進めました。
■ まずはエラーログから読み解く
Unity のビルド時に表示されたエラーメッセージはこちら。
[CXX1429] error when building with cmake …
C++ build system [prefab] failed while executing
さらに詳細ログを見ていくと以下のようなことが書いています。
つまり、cmake が 2 バイト文字(日本語)を含むパスを処理できずに落ちているわけです。
Unity は表向きは日本語表記に対応しているのですが、
内部のビルド処理ではまだまだ 1 バイト文字前提の部分が残っています。
これが原因で、.gradle や Temp が参照されるタイミングでエラーになります。
■ 解決方針
ポイントは次の2つ。
1. cmake が参照する “ユーザーホーム” を 1 バイト文字のパスに置き換える
2. Unity や Windows が一時利用するフォルダ(Temp)も同様に変更する
では順番に設定していきます。
【対応方法①】Unity 側のパス設定を変更する
Unity の External Tools と GI Cache の設定を変更します。
▼ External Tools の設定
Edit → Preferences → External Tools
ここで以下を設定します
- User Home
空欄になっている場合、1 バイト文字だけで構成されたフォルダ を指定します。
例)C:\UnityUserHome など
※ フォルダは先に作っておく必要あり
- keystores Dedicated Location
こちらも同じく 1 バイト文字パス を指定します。
▼ GI Cache の設定
Preferences → GI Cache
1.「Custom cache location」 にチェック
2. Browse から 1 バイト文字のパスを選択
3. Clean Cache を押してキャッシュをクリア
これで、Unity が内部で参照するキャッシュフォルダが安全なパスへ切り替わります。
【対応方法②】Windows の TEMP/TMP を変更する
cmake が参照する –output パスは Windows の TEMP/TMP に紐づくため、ここも 1 バイト文字パスに変更します。
▼ 環境変数を変更する手順
1.タスクバーの虫眼鏡アイコンから「sysdm.cpl」を検索して開く
2. 詳細設定 → 環境変数 をクリック
3. ユーザー環境変数の TEMP と TMP を編集し、1 バイト文字だけのパス に変更する
例) C:\Temp
C:\WorkTmp
※ ここも事前にフォルダを作っておく必要があります。
▼ 最後に再起動
環境変数の変更は OS 再起動が必須です。
再起動後に Unity を開いてビルドすると…
無事にビルドが通りました!🎉
■ まとめ
今回の問題は、
・cmake が 2 バイト文字(日本語ユーザー名)を含むパスを処理できない
・Unity/Gradle の内部処理が ユーザープロファイル配下を参照する仕様
という2つが重なったことで発生していました。
「ユーザーを作り直す」という力技ではなく、Unity と OS の参照パスを1バイト文字に逃がすことで解決できます。同じ問題にハマった方の助けになればうれしいです!















