Quantcast
Channel: Microsoft SQL Server Japan Support Team Blog
Viewing all 153 articles
Browse latest View live

[SQL Troubleshooting] 第6回:ブロッキング情報を採取する (SQL Server 2000 ~ 2008 R2)

$
0
0

 

[このエントリについて]

SQL Server のブロッキングを調査する為の情報、いわゆるブロッキング情報の採取手順を紹介します。

SQL Server サポートでは、ブロッキング発生が疑われる際に、一般的に以下の手順で情報採取をお願いしています。

 

[手順概要]

事前に情報採取の準備を行い、ブロッキングが発生する前に情報採取を開始し、現象発生を確認後に情報採取を停止し、出力情報を採取します。

おおまかな情報採取の流れは以下となります。

1. sp_blocker_pss80 ストアド プロシージャの作成を作成する

2. ストアドプロシージャを定期的に呼び出すスクリプトを作成する

3. ブロッキング情報の採取を開始

4. 調査対象の処理を実行

5. 現象(クエリ遅延など)発生を確認

6. ブロッキング情報の採取を停止

7. 出力情報を採取

 

[手順詳細]

それでは、実際の手順について順を追って説明します。

1. sp_blocker_pss80 ストアド プロシージャの作成を作成する

以下のサイトにアクセスし、sp_blocker_pss80 ストアド プロシージャ作成用スクリプトを入手します。

 

<タイトル : SQL Server 2005 および SQL Server 2000 のブロッキングを監視する方法>

URL : http://support.microsoft.com/kb/271509/ja

 

※URL の公開情報は SQL Server 2005 、SQL Server 2000 を対象としていますが、SQL Server 2008 、 SQL Server 2008 R2 においても、同一手順で情報を取得できます。

※スクリプトはサイト中の 「以下は、sp_blocker_pss80 ストアド プロシージャを作成するためのスクリプトです。 」の下に記載しています。

blocking_01

SQL Server Management Studio などから調査対象のインスタンスに接続し、入手したスクリプトを実行します。

02

注:スクリプトを実行すると下記のエラーが発生しますが、 これはスクリプトの構成上発生する可能性のあるエラーとなります。対処は必要ありませんので、無視してください。

-------------

メッセージ 2714、レベル 16、状態 3、プロシージャ sp_blocker_pss80、行 271

データベースに 'sp_blocker_pss80' という名前のオブジェクトが既に存在します。

-------------

03

スクリプト実行後、master データベースに、sp_blocker_pss80 ストアドプロシージャが作成された事を確認します。

 04

 

2. ストアドプロシージャを定期的に呼び出すスクリプトを作成する

メモ帳などで任意の場所に checkblk.sql ファイルを作成し、次のスクリプトを入力し、保存します。

---ここから---

WHILE 1=1

BEGIN

EXEC master.dbo.sp_blocker_pss80

WAITFOR DELAY '00:00:15'

END

GO

---ここまで---


WAITFOR DELAY に設定した間隔で sp_blocker_pss80 ストアドプロシージャが繰り返し実行されます。

現象発生の期間の間、ブロッキング情報を少なくとも 3 回程度取得したいので、例えば処理の実行時間が 60 秒の現象を調査する場合、15 秒程度に設定します。

上記クエリでは 15 秒間隔で実行するように指定しています。
-------------
WAITFOR DELAY '00:00:15'
-------------

 

3. ブロッキング情報の採取を開始

いよいよ情報採取を開始します。

先の手順 2. で作成した checkblk.sql を、SQLCMD ユーティリティもしくは OSQL ユーティリティから実行します。

対象マシン上でコマンドプロンプトを開き、以下のコマンドを実行します。

※Vista、Windows7 では「管理者として実行」でコマンドプロンプトを起動します。

 

<SQLCMD ユーティリティの場合>

sqlcmd -E -S <インスタンス名> -i <パス名>checkblk.sql -o <出力先パス名>checkblk.out -w 2000

 

<OSQL ユーティリティの場合>

osql -E -S <インスタンス名> -i <パス名>checkblk.sql -o <出力先パス名>checkblk.out -w 2000

 

実行例)

インスタンス名:Ryo01\SQLSERVER2008R2

checkblk.sql のパス:C:\Blocking\checkblk.sql

checkblk.out のパス:C:\Blocking\checkblk.out

上記条件の場合のコマンドは以下となります。

sqlcmd-E –S VRyo01\SQLSERVER2008R2 –i C:\Blocking\checkblk.sql –o C:\Blocking\checkblk.out -w 2000

07 

コマンドプロンプトは開いたままにしておきます。

 

4. 調査対象の処理を実行

ブロッキング情報の採取が開始された事を確認した上で、調査対象の処理を実行します。処理の開始時刻をメモしておきます。

 

5. 現象(クエリ遅延など)発生を確認

クエリ遅延など調査対象の現象が発生した事を確認します。

 

6. ブロッキング情報の採取を停止

コマンドプロンプトで CTRL+C キー を押し、ブロッキング情報の採取を停止します。

14

 

7. 出力情報を採取

ブロッキング情報の採取開始時に -o 引数で指定した出力先パスから、アウトプットファイル checkblk.out を採取します。

 13

 

[参考]

メモ帳などのテキストエディタで checkblk.out を開いてみましょう。

どうやら SPID55 のトランザクションが SPID 58 のトランザクションをブロックしているようです。

out_01

out_02

out_03

 

ブロッキング情報の採取手順は以上です。

 

SQL Server トラブルシューティング 6 回シリーズのご案内

※本記事は、当初第6回でのご案内を予定しておりましたが、第5回に先行してご案内いたします。

他の記事は以下をご参照ください。
http://blogs.msdn.com/b/jpsql/archive/2012/03/30/sql-server-6.aspx

第1回 SQL Server のログ、イベントログの確認方法 (03/30 UP)
第2回 パフォーマンスログの採取方法 (04/20 UP)
第3回 パフォーマンスログの確認方法 (05/07 UP)
第4回 サーバートレースの解析方法 1 (05/18 UP)
第5回 サーバートレースの解析方法 2 (02/18 UP)
第6回 ブロッキング情報の確認方法 (★ 07/24 UP 本記事)


[SSRS] Response.Redirect でページ遷移すると画像が見えなくなる(deleteAfterServicing パラメーター)

$
0
0

横井 羽衣子(よこい ういこ)
SQL Developer Support Engineer

皆様ごきげんよう。今日は、Chart コントロールの再表示の問題と、簡単な切り分け方法についてご案内いたします。

【今日のお題】
ASP.NET Web アプリケーションで、chart コントロールを利用し、レポートからデータを取得している。
chart 表示ページから別のページに遷移し、Response.Redirect で遷移元のページに移動すると、
複数ある chart の画像のうち、いくつかがランダムに表示されない状態 [x]になることがある。
image← こんな感じ
ただし、例外は発生しておらず、イベント ハンドラに渡されたパスも NULL ではなく、データがあるように見える。 なお、静的リンクや、Server.Transfer などを使うと問題なく表示される。また F5 を押し、リフレッシュなどすると表示される。なぜこうした状況になるか。
   

1. 対処 : deleteAfterServicing パラメーターを明示的に False にする

Chart コントロールを追加すると、Web.config ファイルに "ChartImageHandler" として自動的に ChartHttpHandler が登録されます。対処としては、このChartHttpHandler のvalue 属性で deleteAfterServicing パラメーターを false にしてあげることになります。

例)  <add key="ChartImageHandler" value="storage=file;timeout=20;url=~/Files/;deleteAfterServicing=false" />

このパラメーターを明示的に指定しない場合は既定値 Trueとなりますが、この値が有効な状態においては、Chart などのイメージはダウンロードされた後に削除されることになります
そのため、表示されない状態が発生します。

この問題のポイントは、Response.Redirect で遷移を行うという点です。

Server.Transfer や、静的リンクで遷移すると表示されるのは、リクエストの再要求を行わず、前のページの情報をそのまま使うためですが、Response.Redirect では、以下のような動きになります。

1. Chart を描画する(ページ描画中にイメージが生成され、Web サーバのディスクに保存される。保存されたイメージはクライアントにダウンロードされる)
2. 別ページに一度遷移する
3. Response.Redirect で 1. の Chart を使用しているページに遷移する(ページ描画中に再度イメージのダウンロードを試みる)

この動作において、deleteAfterServicing が既定値 True であると、上記のフェーズ 1 ではすでに Chart の実際のイメージのダウンロードが完了していますので、Web サーバのディスク上に保存されたイメージはファイルの参照元から削除されることになります。
そのため、フェーズ 3. で再度同じ Chart イメージをダウンロードしようとした場合、Chart の実イメージが存在することは保証されません。F5 を押すと描画されるのは、実イメージが再生成されるためです。(よーくみると、画像の URL が変わります)
deleteAfterServicing を False にすると、再度リクエスト要求があってもイメージを残しておくことが可能になります。

2. deleteAfterServicing = false の場合画像競合しないか

製品上ファイル上書きなどの競合、セキュリティも保護されるよう設計されています。

イメージ ファイルの管理
http://msdn.microsoft.com/ja-jp/library/dd456629.aspx
既定では、ImageStorageMode プロパティは UseHttpHandler に設定されます。この設定では、表示されたグラフ イメージの管理に、Web.config ファイルに登録されている ChartHttpHandler が使用されます。
次の場合にグラフ HTTP ハンドラーを利用できます。
• サーバー クラスターまたは複数プロセス サイトで、ファイル上書きの競合を防ぎます。
• 他のユーザーが表示しているグラフ イメージをダウンロードしないように、表示されたグラフ イメージのセキュリティを保護します。
• メモリや他のストレージ オプション (Microsoft SQL Server など) にイメージ ファイルを保存することで、ディスク操作を減らします。    

  

3. 参考ドキュメント

グラフ イメージの表示
http://msdn.microsoft.com/ja-jp/library/dd456682.aspx
既定で、ASP.NET のグラフ コントロールでは、この方法を使用してグラフ イメージを表示します。 これは最も単純な表示方法です。 表示されたグラフ イメージはメモリまたは一時ファイルにキャッシュされます。 そのため、頻繁にアクセスされる静的なデータおよび外観を持つグラフの場合、パフォーマンスが改善されます。
使用法
RenderType プロパティを ImageTag に設定します。 表示されたイメージを管理する方法を指定できます。 詳細については、「イメージ ファイルの管理」を参照してください。    
イメージ ファイルの管理
http://msdn.microsoft.com/ja-jp/library/dd456629.aspx
deleteAfterServicing
クライアントからのダウンロードを正常終了した後に、イメージを削除するかどうか。
既定値は true です。    
     

4. おまけ : 切り分けをしてみよう!

画像が表示されないなどの場合、HTTP ステータスが何であったかによって対処が変わります。 例えば良くある 404 = Not Found の場合は、対象のファイルが無いということを調査の端緒にします。しかし、実際には別のステータスのこともあります。それによって、例えば認証を疑ってみるなど、アプローチ方法が変わることもあります。 ご自身で切り分けをされる際は、Fiddler や HTTPREPLAY ツールなどをご利用いただくことも良いかと思います。 例えば、今回この問題を弊社で調査した流れは、以下のような形でした。

1. 動作の把握
2. クライアント、レポートのいずれに問題があるかの確認
3. MSDN ライブラリにおける関連情報の確認
4. サンプルの動作に基づく事例調査
5. 有効性の評価

まず、画像のロードに失敗し [x] が表示される状態になったときの要因を探るため、クライアント (Web ブラウザ)、レポートのいずれに問題があるのかについて切り分けるため、画像が表示されない状況が HTTP 通信としてどのような状況であるのかを HTTP 通信を確認することができる "Fiddler2" ツールを用いて把握しました。

Fiddler2 は、以下よりご入手いただけます。
http://www.fiddler2.com/fiddler2/

image

Fiddler2 を起動させた状態にして、Internet Explorer を起動し、再現試験を実施します。現象の発生するページ中の [x] になっている Chart イメージを右クリックし、アドレスを表示させます。すると、以下のように表示されていることがわかります。

例 : 
http://localhost/MychartTest/ChartImg.axd?i=chart_0_14.png&g=8408b888301548928040242f5ea09832

たとえば、この問題の場合、このタイミングで Fiddler の左ペインの Web Sessions を見ていくと、赤い三角に ! マークのアイコンとともに、404が発生していることがわかります。

image

URL を見ると、そのうち、IE の画像のプロパティの URL で確認したものと同一のものが確認できます。
(Web Sessions を右クリックし、[Copy] – [Full Summary] で以下のようにコピー可能です)

# Result Protocol Host URL Body Caching Content-Type Process Comments Custom
36 404 HTTP (略)/ChartImg.axd?i=chart_0_19.png&g=a6f70d78a90947c2b3f91922f2087762     1,289 private   text/html iexplore:7076 [#22] 

image

図 : IE 上の [X] 状態の画像 (上) と Fiddler 上の表示 (下)

image

これにより、今回の画像の問題は、404 = Not Found であることがわかりますので、参照先が何らかの状況により見つからない状態である、あるいはそうした判断に準ずる状況になっていると判断することができることになります。
ChartImageHandler と 404 関連でライブラリなど参考情報を確認しましたところ、deleteAfterServicing の項にて、クライアントからのダウンロードを正常終了した後に、イメージを削除するという動作であることをみとめました。
この MSDN ライブラリの動作の説明の内容と、HTTP ステータス 404 であったことを検討し、同プロパティの影響の可能性が高いと判断することになりました。

補足 : 
Fiddler2 を用いる場合、HTTPS 通信が使われる場合は、詳しくリクエストの状況を確認するには設定が必要です。

1. Fiddler2 の [Tools...] - [Fiddler Options] を開きます。
2. HTTPS タブを開きます。
3. "Capture HTTPS CONNECTS" チェックボックスと、"Decrypt HTTPS traffic" チェックボックス双方にチェックし、[OK] ボタンを押します。

image

これで、HTTPS の通信も見ることができます。

image

それでは皆様ごきげんよう。

Microsoft SQL Server JDBC Driver は Android OS をサポートしない

$
0
0

横井 羽衣子(よこい ういこ)
SQL Developer Support Engineer

皆様ごきげんよう。今日は、Microsoft SQL Server JDBC ドライバは Android OS で動くか?という点についてお送りします。

【今日のお題】
Microsoft SQL Server JDBC ドライバを使って SQL Azure とかにつなぎたいの!出来る?出来ない?

端的に申しますと、残念ながら弊社 JDBC ドライバは Android OS 上では事実上使うことが出来ません。
また、製品として使用されることも想定されていません。将来的にサポートされる予定も現時点ではありません。(2012/10 月現在)

Microsoft JDBC Driver 4.0 for SQL Server
http://www.microsoft.com/ja-jp/download/details.aspx?id=11774

サポートされているオペレーティングシステムは、上記リンクにてご確認いただけますが、下記の通り Android OSは含まれておりません。

システム要件

サポートされているオペレーティング システム:Linux, Unix, Windows 7, Windows Server 2008 R2, Windows Vista

  • 上記のリストは、サポートされているオペレーティング システムの例の一部です。JDBC Driver は、Java 仮想マシン (JVM) の使用をサポートするすべてのオペレーティング システムで機能するように設計されています。ただし、テストされているのは、Sun Solaris、SUSE Linux、および Windows オペレーティング システムだけです。
  • Java Development Kit: 5.0 および 6.0

弊社のリリースしている JDBC ドライバは、Type 4 ネイティブ プロトコルと呼ばれるタイプです。
基本、Type 4 なので、プラットフォームに依存せず動くという建前ではありますが、どうしても、接続に使用されるパスワード保護の処理の一環である Kerberos が関わる処理でプラットフォームに依存せざるを得ない部分があります。フルセットの Java VM (Oracle JVM / IBM JDK) であればこれらの処理に必要な処理をすることが出来ますが、Android OS の場合サブセットであるため処理を行うための完全な機能が足りず、接続が出来ない状況になってしまうのです。 

以下のエラーの例は、SQL Azure に対する接続を試行した場合の内容です。SQL Azure は接続レベルでの暗号化を要求しますが、上述の理由より Android OS の機能では十分に対応が出来ず、こうしたエラーになります。残念ながら、これはユーザ側で制御はできません。 

エラーの例

com.microsoft.sqlserver.jdbc.SQLServerException:
The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption.
Error: "Socket closed".

image

  

今後の弊社のシナリオとしても、動作保証対象になる予定はございません。
ないないづくしで非常に心苦しい限りですが、たとえば Java サーブレットと通信する、Web サービスと SQL Server で通信をさせ、結果を Web サービスで返すなどの実装にしていただくなどのシナリオをご検討ください。

[SQL Connectivity] Case Study : 認証 DC ダウン時の SSPI エラーについて

$
0
0

横井 羽衣子(よこい ういこ)
SQL Developer Support Engineer

皆様ごきげんよう。今日は、接続できない系問題の一つをご紹介いたします。

【今日のお題】
複数台ドメイン コントローラ (DC) がある環境でサーバーメンテナンスをした。その時一台の DC だけが再起動処理に入ったタイミングで、ドメイン内の SQL Server に Windows 認証で接続を試みたら、なぜか "SSPI コンテキストを生成できません" エラーが返されて接続できなかった。
せっかく DC が複数台あるんだから、一台が使用不可の場合においても、自動的にその他の稼働中の DC に接続し、処理が行われるものじゃないの?
なんで DC が複数台あってこんな現象が発生するの??

これは「SQL Server が最初にアクセスする認証 DC がダウンしているタイミングで認証処理をしにいくと、生存中の他の DC へ問い合わせを切り替える動作に時間がかかるのでタイムアウトしちゃう」という話となります。
DC がダウンしている状況下において SQL Server に対して接続を実施したり、ADSI などの DC で認証を行うアプリケーションなどで一般的に発生し得る現象です。例えば、SharePoint など、SQL Server をバックエンドに持つ環境でも影響を受けます。

はじめに : SSPIエラーとは

SQL Server に Windows 認証による接続を試行した際に発生する SSPI エラーは、一般的には、Active Directory の問題などにより正常に認証が行えないことが要因で SQL Server への接続が失敗したことを表します。

例えば SharePoint Server を使用する場合には、SharePoint 内の処理で SQL Server に接続するために Windows 認証を使用しますが、この場合既定で Kerberos 認証を使用します。その過程において、 DC への問い合わせし、認証処理が発生します。つまり、認証先 DC が、再起動などにより応答しない場合には、切り替わりに発生する時間帯には、SQL Server への接続時も認証が出来ない状況になるということです。 

SQL Server の認証先 DC は?

認証は最初に接続した DC と継続してやり取りを行います。認証先の DC がダウンしている場合は一定期間認証先の DC に対し問い合わせを行い、応答がない場合に別の DC を探しに行くという動作になります。ところが、SQL Server の接続処理は無限に待機するわけではなく、タイムアウト値(私これだけ待つことができます値)が存在しています。タイムアウト値を明示的に指定していない場合も、実は 15 秒という値が存在します。この 15 秒の間に必要な処理が終わらない場合、接続に失敗します。

上記お題のシナリオの場合、DC がダウンしている最中に接続失敗のエラーとして、 SSPI エラーが発生していたとのことですので、このダウンしていた DC が SQL Server からの認証先 DC であり、別の DC への切り替えまでに時間を要した結果、タイムアウト値の期間内に認証処理を正しく行えなかった結果、問題が発生していると判断することができます。

処理の流れ (1) : 正常時の接続処理

通常、SQL Server から DC への接続要求において OS レベルでのセッションが確立され、認証処理に入った場合以下のような処理の流れになります。

接続要求の処理の流れ
image

   SQL Server [secur32.dll(1) -> LPC(2)] --> NetLogon(3)—> DC

SQL Server サービスと、NetLogon サービスは別のプロセスです。 つまり、直接 SQL Server サービスから DC に認証を要求するのではありません。

(1) SQL Server サービスは secur32.dll 内にある AcceptSecurityContext API を呼び出します。
(2) さらに Local Procedure Call (LPC) 経由で NetLogon サービス (lsass.exe) に渡されます。
(3) 次に NetLogon サービスは、Remote Procedure Call (RPC) 経由で DC に認証を求めます。

処理の流れ (2) : DC ダウン時の接続処理

一方、今回のように接続先の DC がダウンしている場合は以下のような処理の流れになります。

<キャッシュされた DC が応答しない場合の処理の流れ>
(1) SQL Server から RPC でキャッシュされた DC に対して認証要求を実行します。
image
(2) DC から応答がない場合、RPC のタイムアウト待ち状態になり、DC からの応答待ちになります。
(3) レスポンスがない場合再度リクエストを出します。
 image
(4) 応答待ち期間に応答がない場合、RPC_S_SERVER_UNAVAILABLE エラーが返り、DC との通信が終わります。
image
(5) DsGetDcName 関数を DS_FORCE_REDISCOVERY フラグで呼び出し、他の DC を探索します。
image
(6) 一番最初に応答した DC と接続確立します。
image

NetLogon サービスでは RPC プロトコルを利用してキャッシュ情報にある DC に接続しますが、最終的に 45 秒以内 に応答が得られない場合、SQL Server の動作して いるコンピュータ上の NetLogon サービスのプロセスである lsass.exe が DsGetDcName() API を使って DC を再検索します。
この "45 秒" という値は、残念ながらシステムに固定値として保持されており、変更することはできません。

参考情報
Windows でのドメイン コントローラの検索方法
http://support.microsoft.com/kb/247811/ja

DsGetDcName 関数
http://msdn.microsoft.com/en-us/library/ms675983(VS.85).aspx

対処方法

1. SQL Server に接続する元がプログラムの場合

以下のいずれかを実施することで対処可能です。

a. Connection Timeout キーワードを入れて、明示的に試行時間を延ばす
b. Retry 処理をする (接続処理からやりなおす)

なお、待機時間延長を実施してもすぐにレスポンスがあれば全体の処理遅延は起こりえません。あくまでも、レスポンスが来ない場合に効果を発揮するキーワードだからです。

image

なぜタイムアウト値の延長が有効なのか

前述 “処理の流れ (2) : DC ダウン時の接続処理” でご案内したように、つながっていた DC が応答してくれない場合、あきらめて別の素敵なDCを探しに行く動作まで 45 秒かかります。しかし、Connection timeout キーワードを明示的に指定しない場合は、タイムアウト値は既定で 15 秒となります。そのために問題が起こってしまうわけです。よって、タイムアウト値を 45 秒以上長くすれば、タイムアウトになるリスクを回避できるということになるのです。

例えば、タイムアウト値を 60 にしたとします。すると、接続先の DC の切り替え時間より長い間待つので、タイムアウトにならない可能性が高くなります。60 だとちょっとギリギリかもしれないので、90 くらいでもいいかもしれません。

image

さらに、接続に失敗して例外がスローされたタイミングですでに切り替えも終わったくらいの時間でもう一度接続しなおせば(リトライ)、対応可能な DC を探すところから対応しますので、接続できるようになります。

image

2. 接続元が SharePoint の場合

SharePoint としては、以下のコマンドを実行することで接続タイムアウトを変更することが可能です。

Database-connection-timeout : Stsadm プロパティ (Windows SharePoint Services)
http://technet.microsoft.com/ja-jp/library/cc287950(office.12).aspx

3. 接続元の接続文字列設定を操作できない場合

残念ながら、この上記の一連の動作における時間をを制御するのに有効なレジストリ等設定はありませんが、当該 DC がシャットダウンされることがあらかじめ分かっている場合は、当該 DC のシャットダウンの前のタイミングで、SQL Server の構成され��マシン上の DC に関するキャッシュ情報をクリアにし、他の稼動している DC とセキュア チャネルを明示的に張ることを対処策として実施することができます。これには SQL Server の構成されたマシン上で nltest.exe を使用し、以下のコマンドを実行することで対処可能です。
しかし、再起動のタイミングが予期できない場合は、対処が難しい状況になります。

nltest /SC_RESET:<ドメイン名>\<DC 名>

nltest はクライアント側のコマンドであり、ドメイン コントローラ側で実施する必要はありません。
また、AD に対し認証を実施する動作を行うプログラム(サービス含む)が動作してない環境であれば、nltest を実施頂く必要はありません。

参考情報
ドメイン セキュア チャネル ユーティリティ -- Nltest.exe
http://support.microsoft.com/kb/158148/ja

・・・・・・・・・

みなさんいかがでしたでしょうか。
SQL などプログラム自身が認証をしておらず、認証をする別のプロセスに任せているというような動きになっているというところは意外に思われた方もいらっしゃるのではないでしょうか。
OS では、共通化できる機能は共通化していますので、こんな感じで各処理分担して一つのプロセスが成り立っています。
これはすなわち、トラブルが起きたときにどこに目を付けるかというところに関係してくる重要な視点だと思います。
ご参考になれば幸いです。

それでは皆さんごきげんよう。

[SQL Connectivity] Case Study : クラスタ化された構成の SQL Server 2008 Service Pack 1 以前のバージョンの名前付きインスタンスに Windows Vista 以降から接続できない

$
0
0

横井 羽衣子 (よこい ういこ)
SQL Developer Support Engineer
- Data Access

皆様ごきげんよう。本日は、「クラスタ化された構成の SQL Server 2008 Service Pack 1 以前のバージョンの名前付きインスタンスに Windows Vista 以降から接続できない」という現象についてお知らせいたします。

【今日のお題】
名前付きインスタンスが動作しているクラスタ化された SQL Server の環境に対し、Windows XP からは正常に接続ができるのに、Windows Vista 以降では接続時に以下のエラーが発生してしまう。なお、SQL Server Browser サービスを用いて接続することを想定している。
SQL Server のバージョンは、2005 と、2008 サービス パックなしの環境でも同一の事象が発生する。

接続できませんでした。
SQLState: '01000'
SQL Serverエラー: 11004
[Microsoft][ODBC SQL Server Driver][TCP/IP Sockets]ConnectionOpen(Connect()) 接続できませんでした。
SQLState: '08001'
SQL Server エラー: 6
[Microsoft][ODBC SQL Server Server Driver][TCP/IP Sockets]指定された SQL Serverが見つかりません。

Windows Firewall ログを取ってみてみたところ、SQL Server Browser サービスの利用する UDP 1434 あてのパケットがファイアウォールまで到達している状況だった。取り急ぎ、クライアントアプリケーションで、接続先インスタンスのポート番号を指定してみたところ、接続はできるようになったが、この対処の妥当性などについても不安。

この現象について

以下の条件がそろった場合に、上記エラーが発生します。これらの条件は、AND 条件です。

・SQL Server のバージョンが 2000 および 2005、2008 サービス パックなしの環境
・クラスタ構成
・名前付きインスタンス
・Windows Vista 以降のバージョンから接続を実施する

クラスタ構成の場合、接続先の IP アドレスは物理 IP と仮想 IP が存在しますが、Windows Vista 以降のセキュリティ強化されたファイアウォールは、通信パケットの IP アドレスが両者の IP で合致しない(厳密なソース マッピングが出来ない)ために、応答パケットを破棄してしまいます。
これにより、上記のようなエラーが発生することになります。

クライアント OS として Windows Vista がリリースされて以降、弊社研究開発本部ではこの動作を問題として認識し、SQL Server 側で対処を実施しました。
しかしながら、SQL Server 2008 サービス パック 1 以降から対処がなされているため、SQL Server 2005 (全サービス パックのバージョン) および SQL Server 2008 RTM (サービス パック適用なし) から SQL Server 2008 サービス パック 1 より前のバージョンにおいては、例外のプログラムやリモート IP を登録いただく運用回避を取っていただく必要があります。 

対処方法

ご利用の SQL Server によって、それぞれ以下のように対処いただく必要があります。

SQL Server 2000、2005
… 上記シナリオの対処の通り、クライアントマシン側で例外のプログラムやリモート IP を登録します。

SQL Server 2008 サービス パックなし
クライアントマシン側で例外のプログラムやリモート IP を登録するか、あるいはサービス パック 1 を適用します。

しかし、SQL Server 2000、2005 の場合や、SQL Server 2008 環境でも、なかなかサービス パックを適用するのが難しい場合もあると思います。そうした場合は、例外プログラムやリモート IP を登録する方法で対処します。では、方法を見てみましょう。

クライアント アプリケーションの動作環境側で対処する

(1)特定のアプリケーションに対してのみ対処する場合

以下のいずれか接続元アプリケーションに対して実施します。

1. 接続文字列で、接続先の名前付きインスタンスの TCP ポート番号を指定する。
2. 名前付きパイプ プロトコルで接続をするようにする。

(2)クライアント マシン全体に有効な対処をする場合(複数のアプリケーションが動作している場合など)

アプリケーションが動作するマシン上の Windows Firewall で以下の対処のいずれかを実施します。

A. SQL Server に接続するアプリケーション用の送信の規則を作成する。
1. コントロール パネルの [システムとメンテナンス] をクリックし、[管理ツール] をクリックします (クラシック表示の場合は [管理ツール] をダブルクリックします)。
2. [管理ツール] の [セキュリティが強化された Windows ファイアウォール] をダブルクリックします。
3. [セキュリティが強化された Windows ファイアウォール] で [送信の規則] をクリックし、[新規の規則] をクリックします。
4. [プログラム] をクリックし、[次へ] をクリックします。
5. [このプログラムのパス] をクリックし、アプリケーションのパスを指定し、[次へ] をクリックします。
6. [接続を許可する] をクリックし、[次へ] をクリックします。
7. 新規の送信の規則ウィザードの手順を完了します。

B. リモー�� サーバーで使用可能なすべての IP アドレス、またはフェールオーバー クラスタ インスタンス用に構成されている使用可能なすべての IP アドレスからのトラフィックを許可する受信の規則を作成する。

1. コントロール パネルの [システムとメンテナンス] をクリックし、[管理ツール] をクリックします (クラシック表示の場合は [管理ツール] をダブルクリックします)。
2. [管理ツール] の [セキュリティが強化された Windows ファイアウォール] をダブルクリックします。
3. [セキュリティが強化された Windows ファイアウォール] で [受信の規則] をクリックし、[新規の規則] をクリックします。
4. [カスタム] をクリックし、[次へ] をクリックします。
5. [すべてのプログラム] をクリックし、[次へ] をクリックします。
6. [プロトコルの種類] ボックスの一覧で [任意] をクリックし、[次へ] をクリックします。
7. [この規則はどのリモート IP アドレスに一致しますか?] の [これらの IP アドレス] をクリックし、[追加] をクリックします。
8. [IP アドレス] ダイアログ ボックスの [この IP アドレスまたはサブネット] の下に、いずれかの IP アドレスを入力し、[OK] をクリックします。
9. その他の IP アドレスを追加するには、手順 7. ~ 8. を繰り返し [次へ] をクリックします。
10.[接続を許可する] をクリックし、[次へ] をクリックします。
11.新規の受信の規則ウィザードの手順を完了します。

※ netsh firewall コマンドで一括登録するという手法もあります。
Netsh を使用して Windows ファイアウォールを管理する
http://technet.microsoft.com/ja-jp/library/cc776229(v=ws.10).aspx

では、次項でなぜこんなことになるか、見ていきましょう。 

SQL Server の名前付きインスタンスに接続するまでの動作の流れと問題発生のメカニズム

本事象は、今回のように SQL Server 環境がクラスタ化されている場合の他、複数の IP アドレスを持つ場合に発生することが報告されています

名前付きインスタンスに接続する場合には、下記の流れで接続します。

1. クライアントは SQL Server の待ち受けポートを確認するために、データベース サーバーに対して UDP 要求パケットを送信します。
2. SQL Server 側で、UDP 要求パケットを受信します。
3. 要求を受けて、SQL Server 側では、SQL Server Browser サービスが、SQL Server のインスタンス名と待ち受けポートに関する情報を含む UDP 応答パケットをクライアントへ送信します。
4. クライアントは、UDP 応答パケットを受信します。
5. クライアントは、UDP 応答パケットで受け取ったポート番号を使用して SQL Server に接続を行います。

しかし、前述の条件を満たす環境において、4. の処理(サーバからの UDP 応答パケットの受信)までは完了していますが、Windows Vista 以降の OS では、ファイア ウォールにおいて、UDP 応答パケットを破棄することになります。これにより、フェーズ 5. の接続処理に至らない状況となり、問題が発生します。この動作については、弊社でも問題と捉えており、SQL Server 2008 SP1 にて動作が変更され、事象が発生しないように実装変更が行われました。  

image

この現象については、以下をご参照ください。

Windows Vista または Windows Server 2008 を実行しているクライアント コンピュータ上で SQL Server の名前付きインスタンスに接続するとエラー メッセージ "指定された SQL Server が見つかりません" または "指定された Server/Instance の位置を特定しているときにエラーが発生しました" が表示される
http://support.microsoft.com/kb/944390

技術情報 944390について

この問題を例えていうと、「うちの娘に良くわからん素性のやつは会わせられん」とお父様が勝手に彼氏からの手紙を捨てちゃって、娘からすると彼から連絡がないのでもういいわ…あきらめましょう、となって関係が終わっちゃったという感じです。

…はい、わけわかりませんね。ちょっと整理します。

・娘さん    … 接続元のクライアントのアプリケーション
・お父さん… Windows Firewall
・素性の良くわからない彼氏 … クラスタ化された SQL Server
※ 娘とお父さんはおなじおうち ( = 同じマシン) に住んでいます。

上記の一連の接続までの流れのうち、フェーズ 3.において、SQL Server 側は UDP 応答パケットに SQL Server が稼動しているマシンの "物理" IP アドレスを含めます。しかしクラスタ環境の場合、クライアントから見える IP アドレスは "仮想" IP アドレスになります。
そのため、クラスタ環境では上記 2 つの異なる IP アドレスが存在する形となります。    

しかし、Windows Vista 以降 (Windows 7 も含む) の OS の Windows ファイアウォールはセキュリティが強化されているため、このような "厳密でない" ソース マッピングを許可しません。
これにより、Windows ファイア ウォールは SQL Server から送信された UDP 応答パケットを破棄することになります。

今回の場合には、ポートとしては、サーバー側で許可されているポート、クライアント側で許可されているポートのいずれも、フェーズ 1. から 5. のやり取りが可能なポートが許可されています。 しかしながら、クラスタ環境の SQL Server からのパケットはこうした理由により、クライアント側の Windows Firewall で破棄されてしまいます。それにより接続できない事象が発生します。   

■ 問題発生時の動作の流れ

1. クライアントは SQL Server の待ち受けポートを確認するために、データベース サーバーに対して UDP 要求パケットを送信します。     
2. SQL Server 側で、UDP 要求パケットを受信します。 

image

図 : クライアントアプリケーションは、SQL Server へ接続要求を実施する

3. 要求を受けて、SQL Server 側では、SQL Server Browser サービスが、SQL Server のインスタンス名と待ち受けポートに関する情報を含む UDP 応答パケットをクライアントへ送信します。
4. クライアントの Windows Firewall が、SQL Server からの UDP 応答パケットを受信し、内容を確認します。

image      
図 : Windows Firewall はアプリケーションに先んじてパケットを受け取る

4. パケットの差出人の IP アドレスは仮想 IP アドレスなのに、接続先情報は物理 IP アドレスであるという状態のパケットであるため、Windows Firewall がパケットを破棄してしまいます。

image

図 : Windows Firewall は厳密ではないソースマッピングのパケットを破棄してしまう

5. SQL Server に接続したいアプリケーションには、情報は届きません。しかし、アプリケションには自分の環境の Windows Firewall が SQL server からのパケットを破棄したということまではわかりません。

image

図 : アプリケーションは、Windows Firewall がパケットを削除したことなどわからないので、接続先がわからず接続に失敗する

6. SQL Server の情報が届かないため、クライアントのアプリケーションでは「指定された SQL Serverが見つかりません。 」エラーが発生し、SQL Server への接続が失敗します。

補足 : 接続問題の際の対処について

今回のエラーは、SQL Server のインスタンスに到達していませんので、SQL Server Profiler など SQL Server 側のデータでは確認できません。 接続については、その内容によって一連の接続処理のうち何れで問題が発生しているかについて、エラー メッセージから確認をします。 以下の記事においてそれぞれの問題発生のタイミングにあわせた情報採取方法などについてご案内しております。

Troubleshooting: Connectivity #1 - SQL Server への接続
http://blogs.msdn.com/b/jpsql/archive/2011/11/28/troubleshooting-connectivity-1-sql-server.aspx

Troubleshooting: Connectivity #2 - エラー情報からわかる失敗原因
http://blogs.msdn.com/b/jpsql/archive/2012/04/05/troubleshooting-connectivity-2.aspx

Troubleshooting Connectivity #3 - 予期しない接続切断
http://blogs.msdn.com/b/jpsql/archive/2012/07/20/troubleshooting-connectivity-3.aspx

いかがでしたでしょうか。何とも、クライアントの “マシン” にサーバーからのパケットは到達してるのに、それが Windows firewall が捨ててしまうので、その先のマシンの中の箱入り娘(接続元のプログラム)には届かないので接続できないなんてことがあるんですね。

それでは皆さんごきげんよう。

Troubleshooting Connectivity #4 - 接続エラーの調査方法

$
0
0

 

高橋 理香
SQL Developer Support Escalation Engineer

 

こんにちは。

SQL Server への接続シリーズも今回で 4 回目となりました。だいぶ時間空いてますけど、その点はご容赦ください。。。

それでも、少しでも、読んでくださっている皆さんのお役に立っているといいなと思う今日この頃です。

Troubleshooting: Connectivity #1 - SQL Server への接続
Troubleshooting: Connectivity #2 - エラー情報からわかる失敗原因
Troubleshooting: Connectivity #3 - 予期しない接続切断

さて今回は、これまでの Troubleshooting ではなんとかならなかった、もしくは、きちんと裏を取ってから対処を行いたい、という場合にどんな情報を採取したらよいかについてご紹介したいと思います。また、実際のログなどを例に調査ポイントを説明します。

1. SQL Server への接続失敗についてまず確認すること


基本的には一般的なトラブルシューティングの場合と同様に 5W1H で考えてみましょう。

ログ採取は時には負荷を伴う場合もありますので、そういった場合には、これらの情報を頼りに、採取すべき情報の最小化を検討することになります。

WHAT (発生している現象) :

  • どのようなエラーが発生するか。もしくは、何を見て接続の問題と判断したか。

WHERE (現象発生環境の範囲) :

  • ツールやアプリケーションをどこで実行しているか。(SQL Server が動作しているサーバー上か、それとも、リモートのクライアントか。)
  • クライアントも複数存在する場合にはそれら全部かそれとも一部のみか。
  • SQL Server のインスタンスやサーバーが複数ある場合にはそれらのすべてに対してかそれとも一部のみか。

WHEN (再現性) :

  • 問題のツールやアプリケーションを使用する場合には常にエラーとなるか。それとも時々発生するか。
  • 使い始めた以降で成功していたことはあるか。今まで問題なかったとしたら、いつから問題が出るようになったか。

WHO (現象発生ユーザー状況) :

  • 接続しようとしているユーザーによる違いはあるか。(接続試行するアプリケーションを実行しているユーザーや、SQL Server への認証に使用するユーザー)

HOW (具体的な操作内容) :

  • どのような処理を行った場合に接続エラーが発生するか。(エラーが発生したツール、アプリケーションにおける操作内容等。また、一方で、接続が成功するツールやアプリケーションはあるか。SQL Server 付属の Management Studio、Visual Studio で開発した System.Data.SqlClient を使用するアプリケーション、など)
  • 開発アプリケーションの場合には、アプリケーションのどのような処理でエラーになるか。(SqlConnection.Open の処理でエラーとなる、など)

また、上記に加えて、補足となるような情報もあるはずですので、その内容も押さえます。

EXTEND (補足情報) :

  • エラー発生前に実施した作業内容
  • エラー発生後に試した作業内容

  

例えば上記に沿って接続失敗の情報を収集した例は以下の通りです。

※例1

発生している現象               
以下のエラーが発生して SQL Server に接続できない。
----------
System.Data.SqlClient.SqlException: SQL Server への接続を確立しているときにネットワーク関連またはインスタンス固有のエラーが発生しました。サーバーが見つからないかアクセスできません。インスタンス名が正しいこと、および SQL Server がリモート接続を許可するように構成されていることを確認してください。 (provider: 名前付きパイプ プロバイダ, error: 40 - SQL Server への接続を開けませんでした)
----------
このエラーはデバッグ実行で画面上に表示された。

現象発生環境の範囲
新規に用意した Windows 7 のマシンにアプリケーションを配置して実行した。
SQL Server は 2008 R2 で別の Windows Server 2008 R2 上で動作している。
以前に導入済みの他のクライアントについては正常動作している。
SQL Server はこの 1 つの既定インスタンスしかインストールしていない。               
               
再現性
新規のマシンでは一度も成功したことはない。

現象発生ユーザー状況
ユーザーによる違いはない。

具体的な操作内容
Visual Studio 2008 C# で開発した Windows フォーム アプリケーション。
SQL Server へのアクセスには System.Data.SqlClient を使用している。
SqlConnection.Open の個所でエラーとなる。


補足情報
SQL Server 構成マネージャーから、共有メモリプロトコルと TCP/IP の待ち受けが有効となっていることは確認済み。
また、TCP/IP のポート番号は 1500 と表示されていた。
Windows ファイアウォールは有効だが、 TCP ポート 1500 を例外として許可するよう設定されている。
SQL Server Browser サービスは開始している。
クライアントからサーバーへの telnet での接続も可能であることは確認した。

実は上記の情報があれば、すでに原因と対処はお伝えできるレベルなのですが、以降では、これを情報採取しながら調査することを考えてみましょう。

 

2. SQL Server への接続失敗についての調査で参考となる情報にはどのようなものがあるか


2-1. 確実にいただきたい情報

接続エラーについての調査では、様々なログやトレースを使用することができます。

どのようなパターンにおいてもまずご用意いただきたいのが、以下の情報です。

  • アプリケーション情報
    • エラーとなったツールの名前、アプリケーション開発で使用したテクノロジーがわかるようなソース ファイル等
    • 指定した接続先サーバー名、ユーザー名等の接続情報 (接続文字列) を含むスクリーンショットやファイル
  • 発生したエラー情報 (エラー番号、メッセージ、スタックトレース等) を含むスクリーンショットやログ ファイル
  • SQL Server エラーログ
    [SQL Troubleshooting] 第1回 :Tips - SQL Server エラーログとイベント ログを採取する (SQL 2000 ~ 2008 R2)
  •  

特に、先のブログや先の WHAT でも記載しましたが、何はなくともエラー情報の確認が必要です。時々、「エラーは表示されたけど忘れた」といったことを伺うこともありますが、本当に、本当に、なんとかして取得をお願いします。画面のスクリーンショットを取ってメールに貼り付けるなどの方法でも十分です。

2-2. 再現性がある場合に、切り分けのために実施いただきたい接続テスト

引き続き接続が失敗している状況 (再現性のある状況) では、以下のような検証を行った結果も問題個所を特定するための切り分け情報として参考となります。

  • ping 実行結果
    • コマンドは以下の3つ。
      ping 接続先IPアドレス
      ping 接続先ホスト名
      ping -a 接続先IP アドレス
  • telnet 実行結果
    • コマンドは以下の2つ。
      telnet 接続先IPアドレス 待ち受けポート番号
      telnet 接続先ホスト名 待ち受けポート番号
  • いずれかの付属ツールを使用した Windows 認証/SQL Server 認証での接続テスト結果
    • sqlcmd ユーティリティでの接続テスト結果
      SQL Server への接続、クエリの実行等で使用されるコマンド ライン ユーティリティです。SQL Server や付属のツールがインストールされている環境で使用可能です。このユーティリティを使用して、プロトコルを明示的に指定した接続、認証方法を変更しての接続のテスト等が可能です。ツールの詳細については、
      sqlcmd ユーティリティのページをご覧ください。
    • コマンドプロンプトからの実行例は以下の通りです。

      - プロトコル指定なし、Windows 認証で接続する

      sqlcmd –S 接続先SQLServer名 –E –m-1

      - プロトコル指定なし、SQL Server 認証で接続する

      sqlcmd –S 接続先SQLServer名 –U ログイン名 -P パスワード –m-1

      - TCP/IP、ポート 2500 に対して Windows 認証で接続する

      sqlcmd –S tcp:接続先SQLServer名,2500 –E –m-1

      - 名前付きパイプ、SQL Server 認証で接続する

      sqlcmd –S np:接続先SQLServer名 –U ログイン名 -P パスワード –m-1

      • ODBC アドミニストレーターでの接続テスト結果
      • ODBC アドミニストレーターを使って、sqlcmd ユーティリティの場合と同様に、接続先 SQL Server 名にプロトコルやポート番号を指定した場合や、認証方法を変更した場合に接続が可能かのテストが可能です。
        以下は ODBC アドミニストレーターでの接続手順です。(ODBC ドライバとして SQL Server Native Client 10.0 を使用した場合の例です。)

        1) odbcad32.exe を起動します。(WOW64 の場合には、%Windir%\SysWOW64\odbcad32.exe)
        2) [追加] ボタンをクリックすると、ODBC ドライバ選択の画面が表示されるので、使用したい ODBC ドライバを選択して [完了] します。(図では SQL Server Native Client 10.0 を選択しています。)
        image

        3) [名前] の欄には任意の名前を指定し、[サーバー] には接続先 SQL Server 名を指定して、[次へ] をクリックします。
        image

        4) 認証方法を選択して、[次へ] をクリックします。"SQL Server に接続して追加の構成オプションの既定設定を取得する" のチェックが入っている場合、ここで SQL Server へ接続します。
        image

        接続が成功すると、次のような画面が表示されます。失敗すると、エラーメッセージが表示されます。
        image

      • UDL ファイルを使用した接続テスト結果
      • UDL ファイル (データ リンク ファイル) を使用すると、OLE DB Provider を使って、sqlcmd ユーティリティの場合と同様に、接続先 SQL Server 名にプロトコルやポート番号を指定した場合や、認証方法を変更した場合に接続が可能かのテストが可能です。
        以下は UDL ファイルによる接続テスト手順です。(OLE DB Provider として SQL Server Native Client 10.0 を使用した場合の例です。)

        1) デスクトップ上の空いているところで右クリックし、[新規作成] - [テキスト ドキュメント] を選択します。
        image

        2) ファイル名を拡張子 .udl のついた任意の名前に変更し、右クリックで [プロパティ] を選択します。
        image

        3) [プロバイダー] タブで接続に使用する OLE DB プロバイダーを選択し、[接続] タブを表示します。
        image  image

        4) サーバー名に接続先 SQL Server 名を入力し、ログオンのための情報を選択、入力した後、データベースの選択はせずに [接続テスト] をクリックします。成功すると、次のメッセージが表示されます。失敗すると、エラーメッセージが表示されます。
        image

    2-3. 接続エラーについて調査する際に採取できるトレースやログ

    上記以外では、以下のような情報が調査する上で参考となります。

    • 接続関連のレジストリ情報

    プロトコルの優先順位、別名の設定などを確認するのに役立ちます。
    この情報は、エラー発生環境と、正常に接続可能な環境があればその両方で採取します。

      • 参照レジストリは以下の通りです。
        32 bit 環境
        [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer]
        64bit 環境
        [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer]
        および
        [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer]
    • 接続元と接続先の両端で採取したネットワーク トレース

    クライアントから送信した接続要求が SQL Serer まで到達しているかどうかなど、通信経緯を把握するのに役立ちます。
    採取方法については、他チームですが、ブログにて紹介しているのでそちらをご覧ください。

    ご存じですか、Microsoft Network Monitor はコマンドラインでも操作できます
    • 接続元で採取した BID トレース

    データアクセス コンポーネント (ADO.NET、ODBC、OLE DB 等) のデバッグログを取得するためトレース機能です。ネットワークトレースでは把握できないアプリケーション側での処理経緯を把握するのに役立ちます。採取方法等については、以下のブログにて紹介しているのでそちらをご覧ください。

    HowTo: BID トレース - データアクセス アプリケーションのトレースを採取する 
    • 接続元で採取した Process Monitor トレース

    ファイルやレジストリへのアクセスをトレースするためのツールです。これにより、レジストリに格納されている情報をどのように読み取っているかなどを把握することができます。ツールの入手、ならびに、使用方法等については Process Monitorのページでご覧ください。

    • 接続先で採取したパフォーマンス ログ

    接続の問題は、接続元、ネットワーク、接続先等、通信経路上の各所における負荷に起因して発生することが多いので、パフォーマンス監視も有効です。これは平常時に採取しておき、エラー時との比較をすることに意味があります。

    [SQL Troubleshooting] 第2回 : Tips -パフォーマンス ログの採取方法 (Windows Server 2003 ~ Windows Server 2008 R2)
    • SQL Server で採取したサーバー トレース

    SQL Server へのクエリ実行経緯を把握する必要がある場合に役立ちます。

    SQL トレーススクリプトの作成、実行 (SQL Server 2005, 2008, 2008 R2) 
    • イベントログ (サーバー側のシステム、セキュリティ、アプリケーション)

    OS やサービスの再起動の状況、ハードウェアに関連したエラー等、対象マシン全体の状態を把握するために確認します。

    [SQL Troubleshooting] 第1回 :Tips - SQL Server エラーログとイベント ログを採取する (SQL 2000 ~ 2008 R2)

    • システム情報

    サービスの状態、起動アカウント、NIC のドライバー等の情報を確認します。
    採取のためのコマンドは以下の通りです。出力には少々時間がかかります。

    Windows Server 2003/Windows XP の場合:

      winmsd /report <システム情報出力パス>

    Windows Vista、Windows 7、Windows Server 2008、Windows Server 2008 R2 の場合:

      msinfo32 /report <システム情報出力ファイルパス>

    • 接続元でのポート利用状況確認 (netstat) 結果
    • TCP ポート枯渇による接続失敗等の可能性がないかを確認するのに役立ちます。コマンドは以下の通りです。           

      netstat –ano

      20秒間隔で実行した結果をファイルに書き出す場合には以下の通り。

      netstat –ano 20 > c:\temp\netstat.log

       

      3. 採取した情報からどのようなことがわかるか


      先の例1 の場合について調査してみましょう。

      まず、エラー情報はありますので、次に SQL Server のエラーログをメモ帳で開いてみます。
      この内容から、先にまとめられた確認事項を裏付ける情報を確認でき、また、特にエラーなどは発生していないために、サーバーとしては接続が可能な状態となっていると判断できます。

      2012-11-01 16:20:15.93 Server Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.1 (X64)
      Apr 2 2010 15:48:46
      Copyright (c) Microsoft Corporation
      Express Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)

      2012-11-01 16:20:15.96 Server (c) Microsoft Corporation.
      2012-11-01 16:20:15.96 Server All rights reserved.
      2012-11-01 16:20:15.96 Server Server process ID is 11728.
      2012-11-01 16:20:15.96 Server System Manufacturer: 'Hewlett-Packard', System Model: 'HP Compaq dc7800p Convertible Minitower'.

      SQL Serevr のバージョンは 10.50.1600.1 で Enterprise Edition x64 版であることがわかります。また、OS は 6.1 ですので、Windows 7 または Windows Server 2008 R2 で SP1 が適用されています。

      2012-11-01 16:20:15.96 Server Authentication mode is MIXED.
      2012-11-01 16:20:15.96 Server Logging SQL Server messages in file 'c:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESSR2\MSSQL\Log\ERRORLOG'.
      2012-11-01 16:20:15.99 Server This instance of SQL Server last reported using a process ID of 1932 at 2012/06/15 16:20:09 (local) 2012/06/15 7:20:09 (UTC). This is an informational message only; no user action is required.
      2012-11-01 16:20:15.99 Server Registry startup parameters:
      -d c:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLServer\MSSQL\DATA\master.mdf
      -e c:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLServer\MSSQL\Log\ERRORLOG
      -l c:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLServer\MSSQL\DATA\mastlog.ldf
      2012-11-01 16:20:16.04 サーバー SQL Server is starting at normal priority base (=7). This is an informational message only. No user action is required.
      2012-11-01 16:20:16.04 サーバー Detected 2 CPUs. This is an informational message; no user action is required.
      2012-11-01 16:20:16.34 サーバー Using dynamic lock allocation. Initial allocation of 2500 Lock blocks and 5000 Lock Owner blocks per node. This is an informational message only. No user action is required.
      2012-11-01 16:20:16.89 サーバー Node configuration: node 0: CPU mask: 0x0000000000000003:0 Active CPU mask: 0x0000000000000003:0. This message provides a description of the NUMA configuration for this computer. This is an informational message only. No user action is required.
      2012-11-01 16:20:17.17 spid7s Starting up database 'master'.
      2012-11-01 16:20:17.37 spid7s Recovery is writing a checkpoint in database 'master' (1). This is an informational message only. No user action is required.
      2012-11-01 16:20:17.75 spid7s FILESTREAM: effective level = 0, configured level = 0, file system access share name = 'MSSQLServer'.
      2012-11-01 16:20:17.97 spid7s SQL Trace ID 1 was started by login "sa".
      2012-11-01 16:20:18.01 spid7s Starting up database 'mssqlsystemresource'.
      2012-11-01 16:20:18.06 spid7s The resource database build version is 10.50.1600. This is an informational message only. No user action is required.
      2012-11-01 16:20:18.33 spid10s Starting up database 'model'.

      認証モードは混合 (SQL Server 認証モードと Windows 認証モード) の設定です。

      2012-11-01 16:20:18.34 spid7s Server name is 'Server01'. This is an informational message only. No user action is required.
      2012-11-01 16:20:18.46 spid7s Starting up database 'msdb'.
      2012-11-01 16:20:19.08 spid10s Clearing tempdb database.
      2012-11-01 16:20:19.34 サーバー A self-generated certificate was successfully loaded for encryption.

      この SQL Server の名前は Server01 で既定インスタンスです。

      2012-11-01 16:20:19.62 サーバー Server is listening on [ 'any' <ipv6> 1500].
      2012-11-01 16:20:19.62 サーバー Server is listening on [ 'any' <ipv4> 1500].
      2012-11-01 16:20:19.64 サーバー Server local connection provider is ready to accept connection on [ \\.\pipe\SQLLocal\MSSQLServer ].
      2012-11-01 16:20:19.64 サーバー Server local connection provider is ready to accept connection on [ \\.\pipe\sql\query ].
      2012-11-01 16:20:19.64 サーバー Dedicated administrator connection support was not started because it is disabled on this edition of SQL Server. If you want to use a dedicated administrator connection, restart SQL Server using the trace flag 7806. This is an informational message only. No user action is required.

      TCP/IP については、ipv4 および ipv6 のいずれについても受信可能で、そのポート番号は 1500 です。

      名前付きパイプも既定の名前で待ち受けしています。

      2012-11-01 16:20:19.79 サーバー The SQL Server Network Interface library successfully registered the Service Principal Name (SPN) [ MSSQLSvc/Server01.domain01.com ] for the SQL Server service.
      2012-11-01 16:20:19.79 サーバー The SQL Server Network Interface library successfully registered the Service Principal Name (SPN) [ MSSQLSvc/Server01.domain01.com:1500 ] for the SQL Server service.

      Kerberos 認証を使用するために必要となる SPN も登録が成功しています。

      2012-11-01 16:20:19.80 サーバー SQL Server is now ready for client connections. This is an informational message; no user action is required.
      2012-11-01 16:20:20.24 spid10s Starting up database 'tempdb'.
      2012-11-01 16:20:20.50 spid13s The Service Broker protocol transport is disabled or not configured.
      2012-11-01 16:20:20.50 spid13s The Database Mirroring protocol transport is disabled or not configured.
      2012-11-01 16:20:20.58 spid13s Service Broker manager has started.
      2012-11-01 16:20:20.62 spid7s Recovery is complete. This is an informational message only. No user action is required.

      クライアントからの接続待ち受けが完了しています。

       

      では次に、今回は問題の環境では常に接続が失敗していますので、切り分け検証を行ってみます。
      その結果から、アプリケーション独自の問題ではなく、このクライアント環境から SQL Server への接続が失敗する状況であると判断できます。

        • ping 実行結果
          • 正常に応答が得られる。
          • telnet 実行結果
            • 画面が黒くなる。つまり、接続は成功している。
            • いずれかの付属ツールを使用した Windows 認証/SQL Server 認証での接続テスト結果
              • sqlcmd コマンドユーティリティ

              C:\Windows\system32>sqlcmd -E -S Server01

              HResult 0x5、レベル 16、状態 1
              名前付きパイプのプロバイダー : SQL Server への接続を開けませんでした [5].
              Sqlcmd: エラー: Microsoft SQL Server Native Client 10.0: SQL Server への接続の確立中に、ネットワーク関連のエラーまたはインスタンス固有のエラーが発生しました。サーバーが見つからないか、アクセスできません。インスタンス名が正しいことと、SQL Server がリモート接続を許可するように構成されていることを確認してください。詳細については、SQL Server オンライン ブックを参照してください。。
              Sqlcmd: エラー: Microsoft SQL Server Native Client 10.0: ログイン タイムアウトが時間切れになりました。

                  • ODBC アドミニストレーターでの接続テスト結果
                  image

                      • UDL ファイルを使用した接続テスト結果
                      image

                      では、このクライアントのみで問題が発生するのはなぜなのか、他の情報を採取して確認してみましょう。

                        • 接続関連のレジストリ情報 (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer)
                            • 正常に接続可能な環境 (抜粋)

                        キー名:              HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer
                        クラス名:             <クラスなし>
                        最���書き込み時刻:  2012/06/19 - 14:57

                        キー名:              HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client
                        クラス名:             <クラスなし>
                        最終書き込み時刻:  2012/11/01 - 11:30
                        値 0
                          名前:            SharedMemoryOn
                          種類:            REG_DWORD
                          データ:            0

                        キー名:              HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo
                        クラス名:             <クラスなし>
                        最終書き込み時刻:  2012/11/01 - 12:02
                        値 0
                          名前:            Server01
                          種類:            REG_SZ
                          データ:            DBMSSOCN,Server01,1500













                        Server01 に対して TCP/IP で (DBMSSOCN)、ポート番号 1500 で接続するための別名 Server01 が作成されています。

                            • エラー発生環境 (抜粋)

                            キー名:              HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer
                            クラス名:             <クラスなし>
                            最終書き込み時刻:  2012/06/19 - 14:57

                            キー名:              HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client
                            クラス名:             <クラスなし>
                            最終書き込み時刻:  2012/11/01 - 11:30
                            値 0
                              名前:            SharedMemoryOn
                              種類:            REG_DWORD
                              データ:            0

                            キー名:              HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo
                            クラス名:             <クラスなし>
                            最終書き込み時刻:  2012/09/05 - 9:45












                            正常に接続できる環境とは異なり、別名の設定はありません。

                            上記のレジストリ設定の情報から、エラーの原因は別名が作成されていないことであり、正常に接続できる環境と同じ設定で別名を作成することで、対処となる可能性が高いことがわかります。

                            では、なぜ別名が作成されていないとエラーとなるのかについて引き続き情報採取によって確認してみましょう。

                            • 接続元と接続先の両端で採取したネットワーク トレース    
                              • エラー発生環境 - 接続元 (抜粋)

                            Frame Number Time And Date Source Destination Protocol Name Description
                            112 12:17:38 2012/11/01 192.168.1.100 192.168.1.200 TCP TCP:Flags=......S., SrcPort=39025, DstPort=1433, PayloadLen=0, Seq=207727522, Ack=0, Win=8192 ( Negotiating scale factor 0x8 ) = 8192 {TCP:71, IPv4:70}
                            572 12:17:41 2012/11/01 192.168.1.100 192.168.1.200 TCP TCP:[SynReTransmit #112]Flags=......S., SrcPort=39025, DstPort=1433, PayloadLen=0, Seq=207727522, Ack=0, Win=8192 ( Negotiating scale factor 0x8 ) = 8192 {TCP:71, IPv4:70}
                            1057 12:17:47 2012/11/01 192.168.1.100 192.168.1.200 TCP TCP:[SynReTransmit #112]Flags=......S., SrcPort=39025, DstPort=1433, PayloadLen=0, Seq=207727522, Ack=0, Win=65535 ( Negotiating scale factor 0x8 ) = 65535 {TCP:71, IPv4:70}

                            上記から、接続先サーバーにポート 1433 でアクセスしようとしており (SYN パケットの送信)、さらに、その再転送 (Retransmission) が初回から 3秒後、2回目から 6 秒後と、2 回行われていることを確認できます。これは TCP/IP での接続時の再転送の既定のタイムアウト時間に沿った動作であり、2回目の送信から 12 秒は待って接続試行は終了します。     

                            この内容から、SQL Server が本来待ち受けている TCP ポート 1500 ではなく、既定インスタンスの既定の待ち受けポート番号 1433 へのアクセスを行っているために接続が失敗したと判断できます。また、接続成功のためには、クライアントで 1500 という番号を渡すようにしなければならないことがわかります。これが別名を作成しなければならない理由です。

                            なお、もしも待ち受けは 1433 で間違いない場合には、接続先サーバーでもネットワークトレースを採取することで、上記のパケットが到着しているかどうかを確認しましょう。到着していなければネットワーク中継機器を疑い、到着しているならば遅延の可能性を疑うことができます。

                                   

                            さて、上記で原因と対処はわかりましたので他の情報はこの時点で採取する必要はないのですが、動作についての説明のために、BID トレースと Process Monitor トレースについても見てみましょう。

                            • 接続元で採取した BID トレース
                              • エラー発生環境 (抜粋 - 列もフィルタしたもの)

                            Event Name, Clock-Time, 

                            System.Data, 129963234805588042, "<prov.DbConnectionHelper.ConnectionString_Set|API> 1#, 'Data Source=Server01;Initial Catalog=testdb;Integrated Security=SSPI;' "
                            System.Data, 129963234805597716, "enter_01 <sc.SqlConnection.Open|API> 1# "

                            System.Data, 129963234805686434, "<prov.DbConnectionPool.
                            TransactedConnectionPool.TransactedConnectionPool|RES|CPOOL> 1#, Constructed for connection pool 1# "
                            System.Data, 129963234805686469, "<prov.DbConnectionPool.DbConnectionPool|RES|CPOOL> 1#, Constructed. "
                            System.Data, 129963234805686600, "<prov.DbConnectionPool.Startup|RES|INFO|CPOOL> 1#, CleanupWait=190000 "
                            System.Data, 129963234806527032, "<prov.DbConnectionPool.GetConnection|RES|CPOOL> 1#, Getting connection. "
                            System.Data, 129963234807420624, "<prov.DbConnectionPool.GetConnection|RES|CPOOL> 1#, Creating new connection. "
                            System.Data, 129963234807420866, "<prov.DbConnectionPool.ReclaimEmancipatedObjects|RES|CPOOL> 1# "
                            System.Data, 129963234807421659, "<sc.SqlInternalConnectionTds.LoginNoFailover|ADV> 4#, host=Server01"



                            指定した接続文字列


                            接続処理開始

                            System.Data, 129963234807917653, "<sc.TdsParser.Connect|SEC> SSPI authentication "
                            System.Data.SNI, 129963234807918234, "enter_02 <SNIOpenSyncEx|API|SNI> pConsumerInfo: 00000000002CD638, wszConnect: 'Server01', ppConn: 00000000002CD630, fIntSec: 1{BOOL}, cbBuffer: 65791, pBuffer: 0000000002901A80, pInstanceName: 0000000002911C10, fOverrideCache: 0{BOOL}, fSync: 1{BOOL}, timeout: -1 "

                             

                            System.Data.SNI, 129963234807918411, "enter_03 <ConnectParameter::ParseConnectionString|API|SNI> szConnect: 'Server01' "
                            System.Data.SNI, 129963234807918915, "<ConnectParameter::ParseConnectionString|SNI> m_szProtocolName: '', m_szServerName: 'server01', m_szInstanceName: '', m_szProtocolParameter: '', m_szAlias: 'server01', m_fCanUseCache: 0{bool} "

                            接続文字列の解析

                            System.Data.SNI, 129963234807920051, "enter_03 <Connect|API|SNI> pConsumerInfo: 00000000002CD638, pProtElem: 0000000000B59260, ppConn: 00000000002CD630, fIntSec: 1{BOOL}, cbBuffer: 65791, pBuffer: 0000000002901A80, fSync: 1{BOOL}, timeout: -1 "

                             

                            System.Data.SNI, 129963234807920809, "enter_05 <Tcp::Open|API|SNI> pConn: 0000000000B59AA0{SNI_Conn*}, pProtElem: 0000000000B59260{ProtElem}, ppProv: 00000000002CC7B8{SNI_Provider**}, timeout: -1 "
                            System.Data.SNI, 129963234807920863, "ObtainIDa 2# <Tcp::Tcp|ID|SNI> 0000000000B59C00{.} created by 1#{SNI_Conn}"
                            System.Data.SNI, 129963234807920913, "enter_06 <Tcp::FInit|API|SNI> 2# "
                            System.Data.SNI, 129963234807920944, "<Tcp::FInit|RET|SNI> 0{WINERR} "
                            System.Data.SNI, 129963234807920956, "leave_06 "
                            System.Data.SNI, 129963234808086531, "enter_06 <Tcp::SocketOpenSync|API|SNI> AI: 000000001C4D9900{ADDRINFO*}, ai_family: 2, event: FFFFFFFFFFFFFFFF{HANDLE}, timeout: -1 "

                            TCP/IP による通信のための処理開始              
                                          
                                             

                                              
                                              
                                             

                            System.Data.SNI, 129963235018256483, "<Tcp::SocketOpenSync|RET|SNI> 10060{WINERR} "
                            System.Data.SNI, 129963235018256513, "leave_06 "
                            System.Data.SNI, 129963235018256594, "enter_06 <Tcp::SocketOpenSync|API|SNI> AI: 000000001C4D9880{ADDRINFO*}, ai_family: 23, event: FFFFFFFFFFFFFFFF{HANDLE}, timeout: -1 "
                            System.Data.SNI, 129963235228544667, "<Tcp::SocketOpenSync|RET|SNI> 10060{WINERR} "
                            System.Data.SNI, 129963235228544694, "leave_06 "
                            System.Data.SNI, 129963235228544775, "enter_06 <Tcp::SocketOpenSync|API|SNI> AI: 000000001C4D98C0{ADDRINFO*}, ai_family: 23, event: FFFFFFFFFFFFFFFF{HANDLE}, timeout: -1 "
                            System.Data.SNI, 129963235438833102, "<Tcp::SocketOpenSync|RET|SNI> 10060{WINERR} "
                            System.Data.SNI, 129963235438833129, "leave_06 "

                            通信の結果はエラーコード 10060 (WSAETIMEDOUT)

                            System.Data.SNI, 129963235438833233, "<Tcp::Open|ERR|SNI> ProviderNum: 7{ProviderNum}, SNIError: 0{SNIError}, NativeError: 10060{WINERR} "
                            System.Data.SNI, 129963235438833283, "RecycleIDa 2# <Tcp::~Tcp|ID|SNI> "
                            System.Data.SNI, 129963235438833437, "<Tcp::Open|RET|SNI> 10060{WINERR} "

                            TCP/IP による通信を 10060 のエラーコードで処理終了。

                            System.Data.SNI, 129963235438833753, "enter_03 <Connect|API|SNI> pConsumerInfo: 00000000002CD638, pProtElem: 0000000000B59680, ppConn: 00000000002CD630, fIntSec: 1{BOOL}, cbBuffer: 65791, pBuffer: 0000000002901A80, fSync: 1{BOOL}, timeout: -1 "

                             

                            System.Data.SNI, 129963235438834469, "enter_05 <Np::Open|API|SNI> pConn: 0000000000B59AA0{SNI_Conn*}, pProtElem: 0000000000B59680{ProtElem*}, ppProv: 00000000002CC7B8{SNI_Provider**} "
                            System.Data.SNI, 129963235438834526, "ObtainIDa 4# <Np::Np|ID|SNI> 0000000000B59C00{.} created by 3#{SNI_Conn}"
                            System.Data.SNI, 129963235438834549, "enter_06 <Np::FInit|API|SNI> 4# "
                            System.Data.SNI, 129963235438834584, "<Np::FInit|RET|SNI> 0{WINERR} "
                            System.Data.SNI, 129963235438834596, "leave_06 "
                            System.Data.SNI, 129963235438834642, "enter_06 <Np::OpenPipe|API|SNI> 4#, szPipeName: '\\server01\PIPE\sql\query', dwTimeout: 5000 "
                                 

                            プロトコルを名前つきパイプに切り替えての接続試行開始。

                            System.Data.SNI, 129963235438937041, "<Np::OpenPipe|ERR|SNI> ProviderNum: 1{ProviderNum}, SNIError: 40{SNIError}, NativeError: 5{WINERR} "
                            System.Data.SNI, 129963235438937076, "<Np::OpenPipe|RET|SNI> 5{WINERR} "

                            System.Data.SNI, 129963235438937095, "leave_06 "
                            System.Data.SNI, 129963235438937187, "RecycleIDa 4# <Np::~Np|ID|SNI> "
                            System.Data.SNI, 129963235438937249, "<Np::Open|RET|SNI> 5{WINERR} "

                            名前付きパイプによる接続試行はエラー コード 5 で失敗。

                            System.Data, 129963235439806503, "<sc.SqlError.SqlError|ERR> infoNumber=5, errorState=0, errorClass=20, errorMessage='SQL Server への接続を確立しているときにネットワーク関連またはインスタンス固有のエラーが発生しました。サーバーが見つからないかアクセスできません。インスタンス名が正しいこと、および SQL Server がリモート接続を許可するように構成されていることを確認してください。 (provider: 名前付きパイプ プロバイダ, error: 40 - SQL Server への接続を開けませんでした)', procedure='None', lineNumber=0 "
                            System.Data, 129963235439897488, "<sc.TdsParserStateObject.DecrementPendingCallbacks|ADV> 1#, after decrementing _pendingCallbacks: 0 "
                            System.Data, 129963235439897523, "<sc.TdsParser.Connect|ERR|SEC> Login failure "
                            System.Data, 129963235441072408, "<sc.SqlInternalConnectionTds.LoginFailure|RES|CPOOL> 4# "

                            名前つきパイプによる通信も失敗したので、この結果を踏まえてのエラーメッセージ

                              上記からは、接続先として指定した接続文字列の内容や、使用したプロトコル、通信の結果としてのエラーコードやメッセージがわかります。もしも、実行しているアプリケーションがどのような API を使用して接続しようとしているのかがわからない場合や、アプリケーションが本来のエラーメッセージをラップしているような場合には、このトレースを採取することで概ね把握することもできる可能性があるといえます。

                              なお、上記の Clock-Time はシステムの時刻です。パフォーマンスの問題などの場合には、各ステップの差分からどの処理に時間を要していたのかを把握できます。今回の例では Tcp::SocketOpenSync の処理で約 21秒 (210169952) の差分があります。先の通り、TCP/IP の場合には 2回の Retransmission でタイムアウトする時間は 21 秒ですので、それとほぼ一致しています

                              なお、以下のような方法で日付時刻のフォーマットに変換できます。

                                String clocktime = Console.ReadLine();
                                long l = long.Parse(clocktime);
                                DateTime dt = DateTime.FromFileTime(l);
                                Console.WriteLine(dt.ToString("yyyy/MM/dd HH:mm:ss.fffffff"));

                               

                              • 接続元で採取した Process Monitor トレース
                                • 正常に接続可能な環境 (抜粋)

                              19:46:16.1343971    WinSQLConNDP2CS.exe    9400    RegOpenKey    HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo    SUCCESS    Desired Access: Read
                              19:46:16.1344333    WinSQLConNDP2CS.exe    9400    RegQueryValue    HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo\Server01    SUCCESS    Type: REG_SZ, Length: 58, Data: DBMSSOCN,Server01,1500
                              19:46:16.1344599    WinSQLConNDP2CS.exe    9400    RegQueryValue    HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo\Server01    SUCCESS    Type: REG_SZ, Length: 58, Data: DBMSSOCN,Server01,1500
                              19:46:16.1344922    WinSQLConNDP2CS.exe    9400    RegCloseKey    HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo    SUCCESS
                                 





                              別名 Server01 が検索で見つかり、そのプロトコルは TCP/IP (DBMSSOCN) で、ポート番号は 1500 であることを確認している。

                                  • エラー発生環境 (抜粋)

                                19:36:33.2226684    WinSQLConNDP2CS.exe    9400    RegQueryKey    HKLM    SUCCESS    Query: HandleTags, HandleTags: 0x0
                                19:36:33.2227049    WinSQLConNDP2CS.exe    9400    RegOpenKey    HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo    SUCCESS    Desired Access: Read
                                19:36:33.2227642    WinSQLConNDP2CS.exe    9400    RegQueryValue    HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo\Server01    NAME NOT FOUND    Length: 144
                                19:36:33.2228073    WinSQLConNDP2CS.exe    9400    RegCloseKey    HKLM\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo    SUCCESS
                                   






                                別名 Server01 を検索したが見つからなかった。

                                19:36:36.2773011    WinSQLConNDP2CS.exe    9400    TCP Reconnect    Client01.domain01.com:34017 -> Server01.domain01.com:ms-sql-s    SUCCESS    Length: 0, seqnum: 0, connid: 0
                                19:36:42.2833091    WinSQLConNDP2CS.exe    9400    TCP Reconnect    Client01.domain01.com:34017 -> Server01.domain01.com:ms-sql-s    SUCCESS    Length: 0, seqnum: 0, connid: 0
                                19:36:57.2905622    WinSQLConNDP2CS.exe    9400    TCP Reconnect    Client01.domain01.com:34021 -> Server01:ms-sql-s    SUCCESS    Length: 0, seqnum: 0, connid: 0

                                TCP/IP で Server01 の ms-sql-s つまりポート 1433 に接続試行。

                                19:37:36.3351328    WinSQLConNDP2CS.exe    9400    CreateFile    \\server01\PIPE\sql\query    ACCESS DENIED    Desired Access: Generic Read/Write, Disposition: Open, Options: Non-Directory File, Attributes: N, ShareMode: None, AllocationSize: n/a

                                名前つきパイプで既定のパイプに接続試行したがアクセスが拒否された。

                                  上記からは、最初に別名を検索していることを確認できます。また、成功する環境では別名から接続先の待ち受けポートが 1500 であることを検知しています。一方でエラーとなる環境では、別名は存在しないため、既定の待ち受けポートである 1433 への TCP/IP でのアクセス、ならびに、名前付きパイプでの接続試行を行って失敗しています。Process Monitor を使用することで、レジストリやファイルアクセスを確認できますので、クライアントによって動作が異なるような場合にはその比較のための資料として活用できます。

                                   

                                   

                                  今回の情報採取に関しては以上です。

                                  次回は、上記でも出てきた別名など、接続試行するまでにどのようなアクセスが行われるか、特に名前付きインスタンスの場合を中心にご紹介する予定です。

                                  DO’s&DONT’s #16: やってはいけないこと - ログ配布プライマリデータベースのログバックアップ

                                  $
                                  0
                                  0

                                  神谷 雅紀
                                  Escalation Engineer

                                  ログ配布 (Log Shipping) のプライマリデータベースに対して、ログ配布バックアップジョブ以外のトランザクションログバックアップは行ってはいけません。

                                  なぜ?

                                  COPY_ONLY オプション (もしくは NO_TRUNCATE オプション) を指定しないトランザクションログバックアップは、トランザクションログをバックアップすると同時に、バックアップしたトランザクションログレコードを切り捨てます。ログ配布のバックアップジョブ以外がトランザクションログバックアップを行った時にトランザクションログが切り捨てられてしまうことで、ログ配布によりバックアップされるトランザクションログの連続性が失われます。その結果、セカンダリサーバーでは、ログ配布により配信されたトランザクションログバックアップをリストアすることができなくなります。

                                  例えば、以下の例では、ログ配布以外によりバックアップ A が作成されています。ログ配布コピージョブによりバックアップ A がセカンダリーサーバーにコピーされない場合、セカンダリーサーバーでは、バックアップ 3 の前にリストアすべきバックアップ A があるため、ログ配布リストアジョブは、バックアップ A がコピーされてくるのを待ちます。バックアップ 3 はリストアされません。

                                   

                                  logshipping

                                  上の状況が発生し、長期間同期していない場合に警告を発するように設定している場合、エラーログやイベントログには以下の警告が記録されるようになります。

                                   

                                  エラー: 14421、重大度: 16、状態: 1。
                                  The log shipping secondary database SERVER\INSTANCE.DATANASE has restore threshold of XXX minutes and is out of sync. No restore was performed for XXX minutes. Restored latency is XXX minutes. Check agent log and logshipping monitor information.
                                  ログ配布のセカンダリ データベース SERVER\INSTANCE.DATANASEは復元のしきい値が XXX 分間ですが、同期されていません。復元は XXX 分間実行されていません。復元される待機時間は XXX 分間です。エージェント ログおよびログ配布モニターの情報を調べてください。

                                   

                                  ログ配布モニタの履歴には、コピー済みのトランザクションログをスキップした旨が記録されるようになります。上の例では、バックアップ A がセカンダリサーバーでリストアされるまでは、バックアップ 3 はスキップされ、リストアされません。

                                   

                                  ログ バックアップ ファイルがスキップされました。セカンダリ DB: 'DATABASE'、ファイル: 'DBName-YYYYMMDDSS.trn'

                                   

                                  バックアップの連続性の確認方法

                                  バックアップが作成されると、エラーログおよびイベントログには、記録が残ります。以下は、エラーログに記録されるバックアップに関するメッセージのサンプルです。

                                  バックアップの連続性を確認する場合、LSN を確認します。first LSN は、直前のバックアップの last LSN と同じ値になります。last LSN は、直後のバックアップの first LSN と同じ値になります。

                                   

                                  2012-12-17 15:48:08.12 バックアップ      Log was backed up. Database: AdventureWorks, creation date(time): 2011/10/28(14:39:10), first LSN: 43:3510:1, last LSN: 43:3601:1, number of dump devices: 1, device information: (FILE=1, TYPE=DISK: {'C:\Program Files\Microsoft SQL Server\MSSQL10_50.KJ1\MSSQL\Backup\AdventureWorks_normal_log1.bak'}). This is an informational message only. No user action is required.
                                  2012-12-17 15:48:08.30 バックアップ      Log was backed up. Database: AdventureWorks, creation date(time): 2011/10/28(14:39:10), first LSN: 43:3601:1, last LSN: 43:3606:1, number of dump devices: 1, device information: (FILE=1, TYPE=DISK: {'C:\Program Files\Microsoft SQL Server\MSSQL10_50.KJ1\MSSQL\Backup\AdventureWorks_normal_log2.bak'}). This is an informational message only. No user action is required.
                                  2012-12-17 15:48:08.53 バックアップ      Log was backed up. Database: AdventureWorks, creation date(time): 2011/10/28(14:39:10), first LSN: 43:3606:1, last LSN: 43:3607:1, number of dump devices: 1, device information: (FILE=1, TYPE=DISK: {'C:\Program Files\Microsoft SQL Server\MSSQL10_50.KJ1\MSSQL\Backup\AdventureWorks_normal_log3.bak'}). This is an informational message only. No user action is required.

                                   

                                  エラーログに記録されているメッセージの各項目の意味は以下の通りです。

                                   

                                  yyyy-mm-dd hh:mm:ss.mmバックアップ完了時の日時。
                                  Log was backed up.ログがバックアップされたことを示します。データベースの場合は “Database was backed up.” となります。
                                  Databaseバックアップ対象データベース名。
                                  creation date(time)バックアップ対象データベースが作成された日時。
                                  first LSNこのバックアップに含まれる最初の LSN。
                                  last LSNこのバックアップに含まれる最後の LSN。
                                  number of dump devicesバックアップデバイス (ファイルやテープ) の数。バックアップは複数のバックアップデバイスに分散格納することが可能。
                                  device informationバックアップデバイス内のバックアップ格納位置、デバイスタイプ (DISK, TAPE)、デバイス名 (ファイル名)。例えば、ひとつのファイルに複数のバックアップを格納していて、先頭から 3 番目の位置にバックアップされた場合は、FILE = 3 となる。

                                   

                                  ※ LSN (Log Sequence Number) : トランザクションログレコードに付与される番号

                                   

                                  first/last LSN は、バックアップヘッダーにも格納されているため、RESTORE HEADERONLY ステートメントによりバックアップヘッダーを確認することでも、バックアップの連続性を確認することができます。

                                   

                                  lsn 

                                   

                                  SQL Server の最新モジュール情報 (まとめページ)

                                  $
                                  0
                                  0

                                  [SQL Troubleshooting] 第5回 サーバートレースの解析方法 – (2)

                                  $
                                  0
                                  0

                                   

                                  福原 宗稚
                                  SQL Server Support Engineer

                                   

                                  第4回 サーバートレースの解析方法 – (1)では、サーバートレースの出力をテーブルに格納し、CPU Time の値が大きいクエリや、reads や writes の値が大きいクエリを、簡単に見つける方法をご案内しました。今回は、さらにサーバートレースとパフォーマンスログの結果を簡単に関連付けて確認する方法をご紹介します。

                                  例えば、CPU 使用率の値が大きいクエリやreads や writes の値が大きいクエリがあったが、その時サーバー全体として負荷は高かったのか、逆に CPU 使用率が高い時間帯があったが、その時どのようなクエリが実行されていたのかということを SQL Server Profiler を使用して確認できます。

                                  a. サーバートレースとパフォーマンスログの準備

                                  b. サーバートレースとパフォーマンスログの関連付け

                                  c. サーバートレースからの確認

                                  d. パフォーマンスログからの確認

                                  e. まとめ

                                       

                                  ※ Books Online では、下記のトピックとしてご紹介しています。

                                  トレースと Windows パフォーマンス ログ データの関連付け (SQL Server Profiler) 

                                   

                                  a. サーバートレースとパフォーマンスログの準備

                                  必要な情報は、サーバートレースとパフォーマンスログです。

                                  サーバートレースの採取方法、採取するイベントは、第4回 サーバートレースの解析方法 – (1)をご参照ください。

                                  パフォーマンスログの採取方法は、第2回 パフォーマンスログの採取方法をご参照ください。また、下記のカウンタを採取します。

                                    

                                  • Memory
                                  • Physical Disk
                                  • Process
                                  • Processor
                                  • SQL Server: Buffer Manager
                                  • SQL Server: Memory Manager
                                  • System

                                   

                                  ※ 実際の調査時に取得するカウンタは、第3回 パフォーマンスログの確認方法を参照し、ご検討ください。

                                   

                                  b. サーバートレースとパフォーマンスログの関連付け

                                  SQL Server Profiler で、サーバートレースとパフォーマンスログを開き、関連付けます��

                                  1) SQL Server Profiler を起動し、 [ファイル] – [開く] – [トレース ファイル] から、採取したサーバートレース (trc ファイル) を開きます。

                                  2) [ファイル] – [パフォーマンス データのインポート] から、採取したパフォーマンスログ (blg ファイル、csv ファイル) を開きます。

                                  3) [パフォーマンス カウンター制限ダイアログ ボックス] で、表示させたいカウンタを選択します。 

                                  03

                                  4) 画面上部にトレースが、画面下部にパフォーマンスログが表示されます。 

                                  04

                                      

                                  c. サーバートレースからの確認

                                  確認したいクエリをトレース部分で選択します。

                                  例えば、reads が高かったクエリ「exec proc1」 に関して、実行されていた時間帯のパフォーマンスを確認してみます。

                                  1) 該当のサーバートレースの行を選択します。

                                  05

                                  2) するとパフォーマンスログが連動して、その時刻が赤い線で示されます。「exec proc1」 実行開始直後から、青色の線で示された Avg. Disk Queue Length 等のディスクの負荷を示す指標が他の時間帯と比べて高い値を示しており、ディスクがボトルネックとなっていた可能性が推測できます。

                                  06

                                  d. パフォーマンスログからの確認

                                  確認したい時間帯のパフォーマンスログを選択します。

                                  例えば、CPU 使用率が 100% に達して非常に負荷が高かった時間帯があったため、その時間帯にどのようなクエリが実行されていたかを確認してみます。

                                  1) パフォーマンスログ部分で、緑色の線で示された %Processor Time の値が高い時間帯を選択します。

                                  07

                                   

                                  2) すると、その時間帯で実行されていたクエリの行がトレースで選択されます。

                                  この行の前後を確認することで、該当の時間帯でどのようなクエリが実行されていたのかを特定できます。複数のクエリが実行されている場合、トレース部分で CPU 列に着目し、この値が特に大きいクエリが CPU 使用率を押し上げていると判断できます。

                                  08

                                   

                                  e. まとめ

                                  SQL Server Profiler で実行されていたクエリを、Performance Monitor でパフォーマンスを、それぞれ別々に確認することはできますが、SQL Server Profiler 上で関連付けて表示させることで、より簡単に調査対象のタイミングのクエリ、パフォーマンスの関係性を確認することができます。是非ご活用ください。

                                   

                                  SQL Server トラブルシューティング 6 回シリーズのご案内

                                  本記事は、第 5 回目となります。他の記事は以下をご参照ください。
                                  http://blogs.msdn.com/b/jpsql/archive/2012/03/30/sql-server-6.aspx

                                  第1回 SQL Server のログ、イベントログの確認方法 (03/30 UP)
                                  第2回 パフォーマンスログの採取方法 (04/20 UP)
                                  第3回 パフォーマンスログの確認方法 (05/07 UP)
                                  第4回 サーバートレースの解析方法 1 (05/18 UP)
                                  第5回 サーバートレースの解析方法 2 (★ 02/18 UP 本記事)
                                  第6回 ブロッキング情報の確認方法 (07/24 UP)

                                  Troubleshooting Connectivity #5 - セッション確立までの動作

                                  $
                                  0
                                  0

                                   

                                   

                                  高橋 理香
                                  SQL Developer Support Escalation Engineer

                                   

                                  こんにちは。

                                  四半期に一回のペースでしかアップできていないのですが、この Troubleshooting Connectivity シリーズはまだネタはあるので、もう少し続けたいと思います。

                                   

                                  さて今回ですが、Troubleshooting Connectivity #1でご説明した接続 3 過程のうちの OS レベルのセッション確立の試行までの動作についてご紹介します。わかりやすくするために、TCP/IP プロトコルを使用した場合を例に説明します。

                                   

                                  TCP/IP のセッションを確立するために必要な情報とは何か (復習)


                                  TCP/IP プロトコルを使用して SQL Server との間にセッションを確立するためには、SQL Server が動作するサーバーの IP アドレス (フェールオーバー クラスタ構成の場合には、SQL Server 用に割り当てた IP アドレス) と待ち受けているポート番号が必要です。

                                  SQL Server 7.0 までは、そもそも同一マシン上に複数インスタンスをインストールする機能はなかったので、SQL Server のポート番号といえば 1433 でよかったのですが、SQL Server 2000 以降は複数インスタンスを単一マシン上で動作させることができますので、クライアントからの接続待ち受けには各インスタンスで異なるポート番号を使用するよう構成する必要があります。既定では、既定のインスタンスはこれまで通りの 1433 で待ち受け、名前付きインスタンスは動的にポート番号が割る振られるようになっています。

                                  このように、サーバーでは待ち受けポート番号が各インスタンスによって異なりますので、接続元では、名前付きインスタンスがどのポート番号で待ち受けしているのかを都度確認する必要がある状況といえます。この、都度の確認に使用されるのが SQL Server Browser サービスです。(SQL Server 2000 は当サービスは SQL Server サービスに統合されていました。)接続元では SQL Server Browser サービスに待ち受けポートが何番なのかを問い合わせ、得られた情報を使って接続試行を行います。

                                  SQL Server Browser サービスを介して名前付きインスタンスへアクセスするまでの動作については、以下のブログページの「SQL Server の名前付きインスタンスに接続するまでの動作の流れと問題発生のメカニズム」において図入りで説明がありますので、こちらも併せて参考にしてみてください。

                                  [SQL Connectivity] Case Study : クラスタ化された構成の SQL Server 2008 Service Pack 1 以前のバージョンの名前付きインスタンスに Windows Vista 以降から接続できない

                                   

                                  名前付きインスタンスへの接続で SQL Server Browser サービスは必須か


                                  SQL Server Browser サービスの役割が待ち受けポート番号の通知ということだとするならば、名前付きインスタンスが動的ポートではなく、あらかじめ固定のポートを使用するように設定されており、そのポート番号をサーバーの管理者より通知されて知っている場合、それでも SQL Server Browser サービスを介した接続をしなければならないのでしょうか。

                                   

                                  答えは No です。

                                   

                                  接続に必要となる情報が揃っていれば、SQL Server Browser サービスを介さずに接続試行することができます。
                                  具体的には、以下のいずれかの方法を使用します。

                                  • 接続先として、プロトコルとポート番号を指定する。
                                  • クライアント側で別名を作成し、別名の設定内であらかじめ通知されているポート番号を指定しておく。

                                  上記のような設定の場合には、最初から SQL Server に接続試行を行います。
                                  いずれもサポートされる接続方法です。

                                   

                                  以下に使用例をご紹介します。

                                   

                                  例1: プロトコルとポート番号を指定した接続を行う

                                  VBScript/ADO で SQLNCLI10 を使用して TCP/IP プロトコル、ポート番号 1435 に接続

                                  Dim cn
                                  Set cn = CreateObject("ADODB.Connection")
                                  cn.ConnectionString = "Provider=SQLNCLI10;Data Source=tcp:SERVER01\INST01,1435;Integrated Security=SSPI;"
                                  cn.Open

                                  C# のアプリケーションで System.Data.SqlClient を使用して TCP/IP プロトコル、ポート番号 1500 に接続

                                  string strcn = "Data Source=tcp:SEREVER01\INST01,1500;Integrated Security=SSPI;";
                                  SqlConnection connection = new SqlConnection(strcn);
                                  connection.Open();

                                   

                                  例2: 別名を作成し、それを上記の VBScript で使用する

                                  別名を作成するには、クライアント側で以下のいずれかのツールを使用します。

                                  • SQL Server 構成マネージャー (SQL Server Configuration Manager)
                                  • SQL クライアント設定ユーティリティ

                                   

                                  SQL Server 構成マネージャーは、SQL Server の [クライアント ツール] をインストールしている場合に利用できます。起動は、SQL Server のメニューから [構成ツール] - [SQL Server 構成マネージャー] を選択します。

                                  以下では、新規に別名 "ALIAS01" を作成しており、その接続先 SQL Server は "SERVER01"、プロトコルは "TCP/IP"、ポート番号は "1500" です。

                                  image

                                  もしも 64 bit Windows 上で 32bit アプリケーション用に別名を作成する必要がある場合には、[SQL Native Client 10.0 の構成 (32 ビット)] の方で設定します。

                                  image

                                   

                                  SQL クライアント設定ユーティリティは OS 同梱のため、どの Windows OS であっても利用できます。64 bit Windows 上で 64 bit アプリケーション用のために別名を作成する場合には、System32 フォルダ配下にある cliconfg.exe を、32 bit アプリケーション用の場合には、SysWOW64 フォルダ配下にある cliconfg.exe を起動します。

                                  以下は、SQL Server 構成マネージャーでの別名設定と同じ内容で設定した場合の例です。

                                  image

                                  別名はレジストリに格納されますが、どちらのツールを使って作成しても同じ場所に格納されます。

                                  • 64bit 用の設定: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo
                                  • 32bit 用の設定: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo

                                   

                                  このように、作成した別名を C# のアプリケーションで使用する場合には接続文字列で次のように指定します。

                                  string strcn = "Data Source=ALIAS01;Integrated Security=SSPI;";
                                  SqlConnection connection = new SqlConnection(strcn);
                                  connection.Open();

                                   

                                  ※注意: SQL Server が動的ポートの設定となっている場合には、サービス再起動によって異なるポート番号で待ち受けする可能性があります。別名や接続文字列に指定したポート番号とは異なる番号で待ち受けしている場合には接続は失敗しますので、都度変更する必要があります。別名や接続文字列でのポート番号の指定を行う場合には、SQL Server のポート番号も固定することをお勧めします。

                                  ※補足:作成した別名は削除することもできます。SQL Server 構成マネージャーでの別名操作については以下のトピックをご覧ください

                                  クライアントが使用するサーバーの別名の作成または削除 (SQL Server 構成マネージャー)

                                   

                                  SQL Server Browser サービスが停止していたら必ず接続は失敗するか


                                  ご紹介した 2 つの方法 (接続文字列でのプロトコルとポート番号指定、または、別名の作成) を採用していない場合、SQL Server Browser サービスが停止していると接続は失敗するものでしょうか。

                                   

                                  答えは Yes でもあるし No でもあります。

                                   

                                  実は、Microsoft が提供している SQL Server 用の各種接続コンポーネントには、接続情報のキャッシュが存在します。

                                  キャッシュは接続元の環境 (クライアント/サーバーの場合にはクライアント側) に存在し、以前に SQL Server への接続が成功したときに使用したポート番号を保持します。これにより、次回の同一接続先への接続要求では、そのキャッシュされたポート番号を使用して SQL Server に接続試行することになります。(※) したがって、SQL Server Browser サービスが停止していても、そのポート番号が接続試行時点で有効であれば、接続は成功することになります。

                                  image

                                  では、SQL Server サービス再起動によって以前とは異なるポート番号で待ち受けしてしまったらどうなるのでしょう。

                                  このようにサーバー側で待ち受けポート番号が変わっても、その時点で同サーバーを使用する各クライアントのキャッシュの情報までクリアするような操作は行いません。そして、新たな接続要求では、キャッシュ内の古いポート番号の情報を使用して接続試行が行われることになります。そのため、この接続試行は失敗することになります。でも、ご安心ください。接続コンポーネントでは、キャッシュを使用した接続試行が失敗した場合には、キャッシュを古いものとして認識してクリアし、SQL Server Browser サービスへ問い合わせることで適切なポート番号を取得してから接続試行を行うよう動作します。つまり、この時点で SQL Server Browser サービスが停止していれば接続が失敗することになります。

                                  image

                                  もしも SQL Server Browser サービスが起動していれば、セッション確立まで処理を進めることができます。

                                  image

                                  このように、キャッシュは SQL Server Browser サービスへの問い合わせ分のオーバーヘッドを減らす目的として用意されてはいますが、キャッシュによって接続できることを保証するものではなく、また、キャッシュが古い場合には SQL Server Browser サービスへの問い合わせは接続成功のためには必要となります。別名や接続文字列へのポート番号指定がない限りは、SQL Server Browser サービスを開始した状態にて利用するようにしましょう。

                                  ※ここで説明しているキャッシュは接続プールとは異なるものです。接続プールは、SQL Server への接続は切断せずに保持した状態でプールし、以降の接続要求で接続試行の段階からの処理を行うことなく再利用することで接続時のオーバーヘッドを減らす目的で使用されます。同一プロセス内の接続要求にのみ再利用が許可されます。一方で今回ご紹介しているキャッシュは、プロトコルやポート番号の情報のみを保持し、接続そのものの実体は保持していません。同一のマシン同一の接続コンポーネントを利用した接続にのみ再利用が許可されます。

                                   

                                  別名やキャッシュはどのような順番で利用されるのか


                                  別名が存在し、キャッシュも存在する環境の場合など、接続試行までに何がどのような順番でチェックされるのでしょうか。
                                  の順番をまとめると以下の通りとなります。
                                  1. 指定された接続先と合致する別名が存在するかどうかをチェックし、存在する場合には、その別名の設定にしたがって接続試行する。
                                  2. 別名が存在せず接続先としてプロトコルやポート番号が明示的に指定されている場合には、その設定にしたがって接続試行する。
                                  3. 別名が存在せずプロトコルやポート番号の指定がない場合において、以前に成功した接続の情報がキャッシュ内に存在する場合、そのキャッシュの情報を使用して接続試行する。
                                  4. キャッシュが存在しない場合において、接続先に \ マークが含まれる場合、接続先は名前付きインスタンスと判断する。
                                  5. 名前付きインスタンスの場合、指定された接続先が IP アドレスである場合、そのホスト名の取得のために名前解決 (逆引き) を行う。
                                  6. 名前付きインスタンスの場合、解決した名前を使って SQL Server Browser サービスへ問い合わせ、待ち受けプロトコルやポート番号を取得する。
                                  7. 既定インスタンスの場合、指定された接続先と TCP ポート 1433 を使い、名前付きインスタンスの場合、取得したプロトコル情報やポート番号を使って、SQL Server に接続試行する。

                                  ※上記で使用されている「接続試行する」とは、SYN パケット送信によるセッション確立からの処理を指します。

                                  もしも名前付きインスタンスへの接続でセッション確立に失敗しているような状況が見られた場合には、上記を参考に、プロトコルやポート番号を指定することで SQL Server Browser サービスを介さずに接続ができるかを確認してみてください。これによって、SQL Server Browser サービスへのアクセスの問題か、キャッシュによる恩恵を受けていたかなどを切り分けることもできます。

                                  この内容がトラブル時の対策の一助となればと思います。

                                   

                                  次回は・・・接続における問題のトラブルシューティングの一助となるようなものをご紹介したいと思います。

                                  [SSRS] Reporting Services の詳細ログ

                                  $
                                  0
                                  0

                                  SQL Server Support Engineer

                                  福原 宗稚

                                    

                                  概要

                                  Reporting Services で何か問題があった場合に、まずは Reporting Services のトレースログを見ることがよくあります。 トレースログには、Reporting Services サービスの起動に関する情報や、エラー、設定変更等さまざまな情報が出力されています。既定では、「例外、再起動、警告、状態メッセージ」が出力される設定になっていますが、「詳細モード」に変更することで、どのユーザーによって何のレポートが参照されたのか、どのような形式 (Excel や PDF 等) でのエクスポート要求があったのかという詳細な情報も出力されます。

                                  また、SQL Server 2008 以降では、HTTP ログが出力されるように設定することで、HTTP 要求や HTTP 応答に関する情報も出力されるようになります。

                                  そのため、これらの情報は、何か問題があったという報告を受けた際に、どのような要求がサーバーに来ていたのか、サーバー側でもエラーが発生していなかったのかという調査に非常に有効です。

                                  今回は、Reporting Services のトレースログを詳細モードに変更し、HTTP ログの出力を有効にするための手順をご紹介します。SQL Server 2005 と SQL Server 2008 以降では、設定するためのファイルが異なるため、それぞれ分けて記載しています。

                                   

                                  SQL Server 2008 以降の設定手順

                                  1) 事前に、ReportingServicesService.exe.config ファイルをコピーして保存しておきます。 詳細モードを解除して、 設定をもとに戻す時に使用します。

                                  既定では、下記のフォルダに配置されています。

                                  - SQL Server 2008
                                  C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\ReportServer\bin

                                  - SQL Server 2008 R2
                                  C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportServer\bin

                                  - SQL Server 2012
                                  C:\Program Files\Microsoft SQL Server\MSRS11.MSSQLSERVER\Reporting Services\ReportServer\bin
                                   

                                  ※赤字部分が、Reporting Services のインスタンス名になります。Reporting Services を既定のインスタンスとしてインストールしている場合には、ここが MSSQLSERVER になります。名前付きインスタンスとしてインストールしている場合には、インスタンス名となります。(該当のフォルダが分からない場合には、後述の 「Reporting Services のインストール先の確認方法」をご覧ください。)

                                  2) ReportingServicesService.exe.config ファイルを開きます。
                                  3) ReportingServicesService.exe.config 内の DefaultTraceSwitch の値を 4 に変更します。
                                   
                                  設定例:

                                    <system.diagnostics>
                                      <switches>
                                        <add name="DefaultTraceSwitch" value="4" />
                                      </switches>
                                    </system.diagnostics>


                                  4) RStrace セクションに上書きする形で以下のセクション全体を貼り付けます。

                                  <RStrace>
                                        <add name="FileName" value="ReportServerService_" />
                                        <add name="FileSizeLimitMb" value="32" />
                                        <add name="KeepFilesForDays" value="14" />
                                        <add name="Prefix" value="tid, time" />
                                        <add name="TraceListeners" value="debugwindow, file" />
                                        <add name="TraceFileMode" value="unique" />
                                        <add name="HttpTraceFileName" value="ReportServerService_HTTP_" />
                                        <add name="HttpTraceSwitches" value="date,time, clientip,username,serverip,serverport,host,method,uristem,uriquery,protocolstatus,bytesreceived,timetaken,protocolversion,useragent,cookiereceived,cookiesent,referrer" />
                                        <add name="Components" value="all:4,http:4" />
                                  < /RStrace>


                                  5) Reporting Services を再起動します。 

                                  ※Reporting Services 構成マネージャーや、SQL Server 構成マネージャー 、net stop/net start コマンド、サービス画面等、任意の方法で結構です。
                                  ※詳細ログの取得終了後は、ReportingServicesService.exe.config を事前にコピーしておいたものと入れ替え、Reporting Services を再起動すると元の設定に戻せます。 
                                   
                                  6) ログフォルダに詳細ログが出力されます。

                                  既定では、下記のフォルダがログフォルダになります。

                                  - SQL Server 2008
                                  C:\Program Files\Microsoft SQL Server\MSRS10.MSSQLSERVER\Reporting Services\Logfiles

                                  - SQL Server 2008 R2
                                  C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\Logfiles

                                  - SQL Server 2012
                                  C:\Program Files\Microsoft SQL Server\MSRS11.MSSQLSERVER\Reporting Services\Logfiles  

                                     

                                  SQL Server 2005 の設定手順

                                  1) 事前に、Web.config ファイルをコピーして保存しておきます。 詳細モードを解除して、 設定をもとに戻す時に使用します。

                                  既定では、下記のフォルダに配置されています。

                                  C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\ReportServer

                                   

                                  ※ 「MSSQL.3」の数値部分は、該当環境にインストールされているインスタンス数やインストールした順番によって異なります。この数値は、次のレジストリキーで確認可能です。

                                  [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS]

                                  ※該当のフォルダが分からない場合には、後述の 「Reporting Services のインストール先の確認方法」をご覧ください。

                                   

                                  2) Web.config 内の DefaultTraceSwitch の値を 4 に変更します。

                                  設定例:

                                  <system.diagnostics>
                                    <switches>
                                      <!-- 1 = error, 2 = warning, 3 = info, 4 = verbose –>
                                      <add name="DefaultTraceSwitch" value="4" />
                                    </switches>


                                  3) Reporting Services 構成マネージャを起動し、Reporting Services を再起動します。   

                                  ※Reporting Services 構成マネージャや、SQL Server 構成マネージャ、net stop/net start コマンド、サービス画面等、任意の方法で結構です。
                                  ※詳細ログの取得終了後は、Web.config を事前にコピーしておいたものと入れ替え、Reporting Services を再起動すると元の設定に戻せます。

                                   

                                  4) ログフォルダに詳細ログが出力されます。

                                  既定では、下記のフォルダがログフォルダになります。

                                  C:\Program Files\Microsoft SQL Server\MSSQL.3\Reporting Services\LogFiles

                                  ※SQL Server 2005 の Reporting Services は、Web サーバーとしてIIS を使用しています。HTTP 要求やHTTP 応答を確認する場合には、IIS ログもあわせて確認します。IIS ログは既定で下記フォルダに出力されています。

                                  C:\WINDOWS\system32\LogFiles\W3SVC1

                                   

                                  Reporting Services のインストール先の確認方法

                                  1) [SQL Server 構成マネージャー] を起動します。

                                  01

                                  2) [SQL Server のサービス] で、対象の Reporting Services を右クリックし、[プロパティ] を選択します。

                                  3) [SQL Server Reporting Services (<インスタンス名>)のプロパティ] で、[サービス] タブを選択します。

                                  4) [バイナリパス] に、Reporting Services の実行ファイルのパスが表示されています。

                                  02

                                  例えば、SQL Server 2008 R2 で既定のインスタンスの場合、下記のように表示されています。赤字部分でインストール先のフォルダと判断できます。この配下に、LogFiles フォルダも配置されています。

                                  バイナリパス : “C:\Program Files\Microsoft SQL Server\MSRS10_50.MSSQLSERVER\Reporting Services\ReportServer\bin\ReportingServicesService.exe”

                                   

                                  参考資料

                                  今回変更した設定項目の詳細は、下記ページでもご案内していますので、あわせてご参照ください。

                                  - SQL Server 2008 以降

                                  レポート サーバー サービスのトレース ログ
                                  http://msdn.microsoft.com/ja-jp/library/ms156500.aspx

                                  レポート サーバーの HTTP ログ
                                  http://msdn.microsoft.com/ja-jp/library/bb630443.aspx

                                  - SQL Server 2005

                                  Reporting Services のトレース ログ
                                  http://msdn.microsoft.com/ja-jp/library/ms156500(v=sql.90).aspx

                                  DO’s&DONT’s #12: やった方がいいこと - max server memory を設定する

                                  $
                                  0
                                  0

                                   

                                  神谷 雅紀
                                  Escalation Engineer

                                   

                                  サーバースローダウンなどの事象

                                  SQL Server の一時的な無応答、処理の遅延 (サーバースローダウン)、クエリタイムアウト、ログインタイムアウト、ネットワークエラー、既存のクライアント接続の切断、MSFC フェールオーバーの発生、MSFC での SQL Server クラスタリソース再起動、ミラーリングフェールオーバー、ミラーリングパートナータイムアウト、CPU 高負荷 (使用率 100%) といった事象が発生することがあります。これらの原因のひとつがページング (paging) です。ページングにより SQL Server プロセスのワーキングセット (working set) が小さくなることで、SQL Server 上で行われるすべての処理が遅くなり、また、SQL Server が動作するサーバー全体のパフォーマンスが悪化します。

                                  このような事象が発生した場合、定常監視項目として Memory:Pages/secProcess:Working Set, SQLServer: Buffer Manager\Total pagesパフォーマンスカウンタを採取している場合には、それらのカウンタを確認してみて下さい。問題の事象の発生と同時に Memory:Pages/secの値が上昇し、sqlservr プロセスの Process:Working Setの値が大きく減少してるにも関わらず、SQLServer: Buffer Manager\Total pagesがそれと同等の減少をしていない場合、その事象はページングが原因であると考えて間違いありません。

                                   

                                  対応方法

                                  ページングによるスローダウンを防ぐために、まず最初にすべきことは、max server memory 値の設定です。既定では、max server memory は 2147483647 に設定されています。この設定は、「そのサーバーで使用可能なメモリはすべて SQL Server が使用することを許可する」という設定です。

                                  SQL Server がバッファプールとして使用するメモリ領域を小さくすることで、他のプロセスやサービス、ドライバなどがメモリを要求したとしても、物理メモリが不足する状況が発生しないようにします。そのために、max server memory を物理メモリサイズよりも小さなサイズに設定します。

                                  設定するサイズは、物理メモリサイズから、Windows OS を含む SQL Server 以外が使用するであろう最大サイズを差し引いたサイズを指定します。これを基準として、物理メモリの空き (Memory: Available MBytes) やページングの発生 (Pages/sec) を観察します。max server memory 設定後もページングが発生している場合には、max server memory の設定をさらに小さくします。ページングが発生せず、物理メモリに一定量の空きが常にある場合には、max server memory の値を大きくすることができます。

                                  設定変更は、T-SQL でも Management Studio GUI でも可能です。Management Studio GUI から設定を変更する場合は、サーバーのプロパティの「メモリ」ページから設定変更可能です。

                                  max server memory 変更後、SQL Server の再起動は必ずしも必要ありません。設定変更時点の SQL Server バッファプールのサイズが max server memory に指定されたサイズよりも大きい場合は、SQL Server は解放可能なメモリを解放することでバッファプールのサイズを指定値以下にしようとしますので、徐々に SQL Server の使用メモリは減少します。

                                   

                                  T-SQL での変更

                                  以下は 10240MB に設定する場合の例です。

                                  sp_configure ‘max server memory’, 10240
                                  go
                                  reconfigure
                                  go
                                  sp_configure ‘max server memory’
                                  go

                                   

                                  Management Studio GUI での変更

                                  赤枠内の「最大サーバーメモリ」を変更します。

                                  maxservermemory

                                   

                                  max server memory を設定しても、ページングによって SQL Server のワーキングセットが切り詰められる状況が頻発する場合には、SQL Server サービスアカウントに「ページのロック」(Lock pages in memory) 権限を付与し、バッファプールをページングの対象外とすることを検討します。

                                  Lock Pages in Memory オプションを有効にする方法 (Windows)

                                   

                                  ページング

                                  SQL Server が使用するメモリの大半はデータベースデータや実行プランをキャッシュすることを目的としています。キャッシュとは、データをメモリ上に留めることでパフォーマンスを向上させることを目的としているため、可能な限り多くのデータを可能な限り長くメモリ上に留めておくことで、キャッシュの効果は高まります。

                                  SQL Server は、定期的に Windows に対して物理メモリの使用状況を確認しますが、Windows が物理メモリの空きが少ないと報告しない限りは、キャッシュできるデータを多くするために必要に応じてメモリを確保し続けます。より長くデータをキャッシュするために、Windows に対する物理メモリ使用状況確認において物理メモリの空きが少ないと報告されない限り、一度確保したメモリは解放しません。

                                  SQL Server が Windows に問い合わせた時点では物理メモリに空きがある状況であっても、その直後に何らかのプロセスやサービス、ドライバなどが多くのメモリを要求すれば、次に SQL Server が Windows に物理メモリの空き状況を問い合わせる前に、物理メモリの不足が発生する可能性があります。Windows への問合わせにより SQL Server が物理メモリの不足を知ったとしても、使用中のデータが置かれているメモリは解放できないため、その不足分すべてを補うだけのメモリを即座に解放できるとは限りません。このような場合に、ページングが発生します。

                                  SQL Server のメモリ管理 - Part 2

                                  How To:Ghost Record を確認する方法

                                  $
                                  0
                                  0

                                  Ghost Record とは?

                                  SQL Server の Books Onlineでは、以下のように説明があるものです。

                                  実体レコード (ghost record)
                                  削除対象として指定されているものの、まだデータベース エンジンによって削除されていない、インデックスのリーフ レベルの行。

                                  簡単に書くと、DELETE したけど、まだ実際には削除されていないレコードのことです。SQL Server はDELETEを実行する際に、パフォーマンスの観点から、対象レコードに「削除した」というマークだけを付けています。実際にこのマークされたレコードは、「Ghost Cleanup Task」という処理が削除してくれて、初めてその削除されたレコードが使っていた領域が、再利用可能になるという、そんな感じの仕組みです。なお、インデックスとありますが、Heap(クラスタ化インデックスがないテーブル)でもGhost Recordは発生します。

                                  今回のポストは、このGhost Recordを確認する方法をご紹介します。

                                  「何故確認方法が必要なのか?」といいますと、このGhost Recordが「Ghost Cleanup Task」によってCleanupされないという状況が発生する場合があるためです。この状況になっていると、レコードは全然ないのに圧縮できないといった状態になります。もし、「レコード件数は少ないのに、妙にテーブルのサイズが大きい」とか「レコード削除したはずなのに、データベースが思ったように圧縮されない」という現象を経験したら、Ghost Recordが大量に溜まっていないか、一度確認してみてください。

                                  確認方法:SQL Server 2005/2008/2008 R2

                                  sys.dm_db_index_physical_stats 動的管理関数を使用することで、確認が可能です。例えば、対象のデータベースで下記のように実行すれば、ghost_record_count が存在しているテーブルを確認することができます。

                                  select object_name(object_id) as [Name],ghost_record_count,* from sys.dm_db_index_physical_stats(DB_ID(),NULL,NULL,NULL,'DETAILED') where ghost_record_count>0

                                  確認方法:SQL Server 2000

                                  残念ながら公開されている確認方法はありません。

                                  対処方法

                                  対象のインデックスを再構築することで、大量に溜まったGhost Recordを消し去ることが可能です。

                                  Heapの場合、一旦���ラスタ化インデックスを作成し、削除することで対処可能です(断片化解消と同じ方法です)。

                                  エラー666

                                  $
                                  0
                                  0

                                  概要

                                  エラー666という滅多に見かけることがないエラーがあります。下記のようなメッセージのエラーとなります。

                                  メッセージ 666、レベル 16、状態 2、行 1
                                  パーティション ID が 72057594039828480 のインデックスで、重複するグループに対するシステム生成の一意値が最大値を超えました。この問題はインデックスを削除し、再作成することで解決できます。それ以外の場合は、別のクラスター化キーを使用してください。

                                  目を引くエラー番号なのですが、どのような条件で発生するエラーなのか情報がないので、何故インデックスを再作成(再構築)することで解決するのか等々、よく判りませんでした。そこで、動きを確認して見ましたので、その結果をBlogで共有しておこうと思います。

                                  なお、本検証結果はあくまでも検証ベースの結果であり、ソースコードの確認等で得られたものではありません。また、SQL Server 2008 R2 での確認になりますので、将来のバージョンでの動作については異なる可能性もあります。この点についはご理解いただいた上で、ご参照ください。

                                  動作について

                                  まず、メッセージにある「重複するグループに対するシステム生成の一意値」が何か?というところですが、これは下記の SQL Server 2008 R2 Books Online に説明があります。

                                  クラスタ化インデックスの設計ガイドライン
                                  UNIQUE プロパティを指定せずにクラスタ化インデックスが作成された場合、データベース エンジンにより、4 バイトの uniqueifier列が自動的にテーブルに追加されます。必要があれば、各キーを一意にするため、データベース エンジンにより自動的に uniqueifier値が行に追加されます。この列とその値は、内部的に使用されるもので、ユーザーが参照したりアクセスすることはできません。

                                  平たく書くと、「一意でないクラスタ化インデックスでは、内部的に4バイトの列が追加されて、この値を一意性を保つのに使います」ということです。エラー666は、この値が最大値を超えてしまったために発生するということですね。

                                  後は、この内部的な4バイトの列がどのように動作するか確認すればOKということで、検証してみました。どのような検証を行ったかは後述しますが、結論を書くと以下のような動作になりました。

                                  1) この値は重複するグループ毎に振られる値です
                                  例えば、以下のような構成のインデックスの場合、c1とc2の値が重複するレコードが同じグループとしてまとめられます。c1=1c2=2、c3=1,C4=N’A’とc1=1c2=2、c3=2、c4=N’A’というレコードをINSERTするとグループにまとめられ、2件目のレコードでこの値は1になるようです。c1=1c2=3、c3=1,c4=N’A’というレコードは、違うグループになります。

                                  create table test666(c1 int,c2 int,c3 int,c4 nchar(10))
                                  go
                                  create clustered index idx_c1c2 on test666(c1,c2)
                                  go

                                  2) INSERT時に割り振られる値は、そのグループの現在の最大値+1です
                                  例えば、1)の例のc1=1c2=2のグループの値が100まで進んでいれば、次のINSERTされるc1=1c2=2のグループのレコードは101になります。

                                  ここで重要なのは、「現在の最大値」ということです。100まで一旦カウントアップしたところで、値が2のレコード以外が削除された後、同じグループにレコードがINSERTされた場合、値は3になります。

                                  3) 最大値は、2147483646です
                                  INSERTするタイミングで、現在の最大値+1が2147483647(4バイトの符号付INTの最大値)となった場合に、このエラー666を出力しているようです。よって、値が2147483646になったら、INSERTできなくなります。

                                  対応方法について

                                  メッセージに「インデックスを削除し、再作成することで解決できます」とあるのは、"動作について"の2)で説明した動作があるためとなります。現在の値が進みすぎているので、再作成(再構築)することで値を小さくすることが回避方法となります。古いレコードは削除されていると期待して、振り直せば値が小さくなると信じている対応方法です。

                                  では、「2147483647レコード実際にあってINSERTできない状況になっていたら?」という話ですが、「それ以外の場合は、別のクラスター化キーを使用してください」というのが回避方法になります。クラスタ化キーの構成の見直しをお願いします。

                                  検証方法

                                  "検証方法"と書くほどの事ではないのですが、「インサイドMicrosoft SQL Server 2005」等で紹介されています DBCC PAGE という公開していないコマンドを使用して、地道に検証しました。私たちサポートチームも、内部の動作を確認するためには、こうしたコマンドに頼って検証をしています。

                                  SQL Server 2008 R2 Reporting Services 不具合情報 – “値 'x' は無効です。有効な値は、'xx' から 'xxx' です。”

                                  $
                                  0
                                  0

                                  横井 羽衣子
                                  SQL Developer Support Engineer

                                  今回は、マイクロソフト サポート記事で公開されていない不具合情報をご報告いたします。

                                  対象製品

                                  Windows Server 2008 R2 Reporting Services
                                  (※ Windows Server 2008 では発生しません)

                                  現象

                                  SQL Server 2008 R2 Reporting Service (SSRS) にて、Tablix を含む "可能な場合は、1 ページに収める (Keep together on one page if possible)" オプションを付けたレポートで、印刷のプレビューを行った際、以下のエラーが発生することがあります。

                                  値 'x' は無効です。有効な値は、'xx' から 'xxx' です。

                                  Reporting Services のログを確認すると、以下のような例外が発生していることが確認できます。

                                  Microsoft.ReportingServices.ReportProcessing.RenderingObjectModelException: The value 'x' is invalid.  Valid values are between 'xx' and 'xxx'.; 
                                  ※ x および xx、xxx は発生時それぞれの値が入ります。 例) 値 '3' は無効です。有効な値は、'0' から '2' です。

                                  問題の詳細と対処方法

                                  この事象は、SQL Server 2008 R2 Reporting Services の改ページ (Page Break) 関連の処理に問題があることに起因して発生している問題です。
                                  Reporting Services は、SQL Server 2008 R2 Reporting Services から実装が大幅に変更されているため、SQL Server 2008 Reporting Services ではこの現象は発生いたしません
                                  現象の発生要因は複合的であり、後述のような様々な要因が関連します。印刷サイズと、レポートの構成、実データが入った状態でのサイズなどを調整するための計算結果に依存する現象です。また、Tablix を使っていない場合は、本現象は発生しません。

                                  ・データの量
                                  ・Tablix の設定、レイアウト
                                  ・縦横比
                                  ・設定された用紙のサイズ

                                  これらの内容を 1 ページ内に収めようと計算した結果、計算結果に誤差を生じる場合があります。
                                  ���の誤差が、さらに Page Braak 処理上処理できない値になった場合に発生するため、問題発生率が非常に低い現象です。
                                  なお、本現象は計算結果に誤差が発生した場合に発生しますが、上述のようにレポート運用下の条件が可変であるため、残念ながら事前に完全に抑止する方法はございません。

                                  対処方法は、Tablix のプロパティの  “可能な場合は、1 ページに収める (Keep together on one page if possible)” のチェックボックスを外していただくこととなります。
                                  このプロパティは、レポート出力時、データが少しだけ余る状況などにおいて、1 ページ以内に収まるよう調整させるかどうかを決定するものです。
                                  チェックボックスを オフにしていただいた場合の影響は、改ページの際に若干データが次のページに送られることになることとなります。

                                  clip_image002

                                  参考情報

                                  現在お客様がご利用の SQL Server のバージョンを確認する方法は下記技術情報に詳細が記載されております。

                                  SQL Server のバージョンとエディションを識別する方法
                                  http://support.microsoft.com/kb/321185

                                  本不具合のため、運用上お困りになられているお客様もいらっしゃることかと存じます。弊社製品の不具合によりご迷惑をおかけしておりますことを心よりお詫び申し上げます。
                                  お手数ですが、上記回避策の対処をご検討くださいますようお願い申し上げます。


                                  [SQL Troubleshooting] 第1回 : Tips - SQL Server エラーログとイベント ログを採取する (SQL 2000 ~ 2008 R2)

                                  $
                                  0
                                  0

                                  横井 羽衣子
                                  SQL Developer Support Engineer

                                   

                                  今回は、SQL Server のエラーログと、イベント ログの取得方法についてご紹介します。
                                  これらのログは、お問い合わせをいただく際に、殆ど必ず採取をお願いしておりますが、ログはテキストファイルであり、特別な解析ツールを必要としません。
                                  ログをお客様ご自身でご覧いただくことで、お急ぎの状況などで SQL Server でトラブルが発生した際に、SQL Serverでどのようなエラーが発生しているかをご自身で把握することもできます。また、弊社にお問い合わせいただく際は、SQL Server エラーログとイベントログをご提供いただくことで、SQL Server 内部の問題であるか、それともクライアントからSQL Serverに接続するまでの間の問題であるかなどの初動の判断が早くなり、解決までの時間の短縮が図れますので、事前提供を是非ご検討ください。

                                   

                                  SQL Server エラーログとは

                                   

                                  SQL Server "エラー" ログという名前から、エラーが記録されているだけのファイルのイメージをお持ちになる方もいらっしゃるかもしれませんが、実際には SQL Server エラーログには、エラーだけでなく、様々な情報が記録されています。トラブルシュート時だけでなく、たとえばサポート技術情報 321185“SQL Server のバージョンとエディションを識別する��法”にある T-SQL を発行しなくても SQL Server の詳細なバージョン情報を取得できたり、今現在対象のインスタンスの待ち受けは何であるかなども把握することができる重要なファイルです。

                                   

                                  SQL Server のエラーログの場所

                                   

                                  SQL Server のエラー ログは、製品バージョンによって場所が若干異なりますが、現在のログの名前はいずれも "ERRORLOG" (※拡張子なし) になります。
                                  既定では、SQL Server を起動するたび、ERRORLOG が作成されます。その前のログは、ERRORLOG.1 に変更され、その前のログもそれにあわせて ERRORLOG.1 は ERRORLOG.2 に、ERRORLOG.2 は ERRORLOG.3 へと名前が変更されていきます。
                                  最新のログを見たい場合は、ERRORLOG を確認し、過去の特定の事象についてのログを見たいのであれば、Windows エクスプローラの更新日時を見て、現象の発生時点の時間を含むと思われるログを開きます。

                                   

                                  なお、お問い合わせの際は、Log 格納フォルダ全体を Zip などに圧縮いただき、ご提供をお願いします

                                   

                                  image

                                   

                                  SQL Server 2000
                                  既定ではエラーログの場所は以下となります。

                                   

                                  C:\Program Files\Microsoft SQL Server\MSSQL\LOG

                                   

                                  具体的に格納先を確認するには、以下の方法をとります。

                                   

                                  1. "スタート" - "すべてのプログラム" - "Microsoft SQL Server" - "Enterprise Manager" を選択します。
                                  ---> [SQL Server Enterprise Manager] 画面が表示されます。
                                  2. "コンソール ルート" - "Microsoft SQL Server" - "SQL Server グループ" - "(<該当のンスタンス名>) (Windows NT)" - 右クリック - "プロパティ" を選択します。
                                  ---> [SQL Server のプロパティ(設定) - (<該当のインスタンス名>)] 画面が表示されます。
                                  3. "全般" タブ - [起動時のパラメータ] ボタンを押します。
                                  ---> [起動時のパラメータ - (<該当のインスタンス名>)] 画面が表示されます。
                                  4. "-e" から始まるパラメータの文字列を確認します。

                                   

                                  [例]
                                  ;-eC:\Program Files\Microsoft SQL Server\MSSQL\LOG\ERRORLOG

                                   

                                  5. 上記手順 4 にて確認しましたパスへ移動し、"LOG" フォルダ直下全てのファイルを採取します。
                                   
                                  image

                                   

                                  SQL Server 2005
                                  SQL Server 2005 のエラーログは、既定では下記フォルダに保存されています。

                                   

                                  C:\Program Files\Microsoft SQL Server\MSSQL.n\MSSQL\LOG

                                   

                                  MSSQL.n の n は整数値です。複数のインスタンスを構成している環境の場合など、1 や 2 と数字が割り当てられます。
                                  対象のインスタンスのログの格納先を確認する方法は下記のとおりです。

                                   

                                  1. [スタート] - [すべてのプログラム] - [Microsoft SQL Server 2005] - [構成ツール] - [SQL Server 構成マネージャ] を選択します。

                                   


                                  image

                                   

                                  2. [SQL Server Configuration Manager] 画面が表示されますので、[SQL Server 2005 のサービス] - [SQL Server(<該当のインスタンス名>)] - 右クリック - "プロパティ" を選択しますと、[SQL Server(<該当のインスタンス名>)のプロパティ] 画面が表示されます。

                                   

                                  image

                                   

                                  (おまけ) SQL Server 2005 が、SQL Server 2008 以降と共存した環境の場合は、SQL Server 2008 (もしくは R2) の構成マネージャから情報を見ることもできます。

                                   

                                  image

                                   

                                  3. [詳細設定] タブ - [起動時のパラメータ] に指定されている文字列をコピーし、メモ帳などに貼り付けます。

                                   

                                  image

                                   

                                  image

                                   


                                  4. "-e" から始まるパラメータの文字列を確認し、SQL Server のエラーログの場所を確認します。その際は、"ERRORLOG" の前までがフォルダになります。

                                   

                                  -eC:\Program Files(x86)\Microsoft SQL Server\MSSQL.1\MSSQL\LOG\ERRORLOG

                                   

                                  上記例の場合は、”C:\Program Files(x86)\Microsoft SQL Server\MSSQL.1\MSSQL\LOG\” までがログ格納フォルダになります。

                                   

                                  SQL Server 2008
                                  SQL Server 2008 のエラーログは、既定では下記フォルダに保存されています。
                                  MSSQL10.<インスタンス名> というのがポイントです。

                                   

                                  C:\Program Files\Microsoft SQL Server\MSSQL10.<インスタンス名>\MSSQL\LOG

                                   

                                  1. [スタート] - [すべてのプログラム] - [Microsoft SQL Server 2008] - [構成ツール] - [SQL Server 構成マネージャ] を選択し、[SQL Server Configuration Manager] 画面が表示されます。

                                   

                                  image
                                  SQL Server 2008 と SQL Server 2008 R2 が共存している環境においては、構成マネージャは SQL Server 2008 R2と共通になります。その場合は、上記手順 1. において、[スタート] - [すべてのプログラム] - [Microsoft SQL Server 2008 R2] - [構成ツール] - [SQL Server 構成マネージャ] を選択してください。

                                   

                                  2. "SQL Server のサービス" - "SQL Server(<該当のインスタンス名>)" - 右クリック - "プロパティ" を選択します。[SQL Server(<該当のインスタンス名>)のプロパティ] 画面が表示されます。
                                  3. [詳細設定] タブ - [起動時のパラメータ] に指定されている文字列をコピーし、メモ帳などに貼り付けます。

                                   

                                  image

                                   

                                  image

                                   

                                  image

                                   

                                  4. "-e" から始まるパラメータの文字列���確認します。"ERRORLOG" の前までが格納フォルダのパスになります。

                                   

                                  例) 上記例の場合

                                   

                                  ;-eC:\Program Files\Microsoft SQL Server\MSSQL10.SQL2008\MSSQL\Log\ERRORLOG

                                   

                                  例) 既定のインスタンスの場合

                                   

                                  ;-eC:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Log\ERRORLOG

                                   

                                  SQL Server 2008 R2 および Windows Server 2008 と Windows Server 2008 R2 が共存した環境
                                  SQL Server 2008 のエラーログは、既定では下記フォルダに保存されています。
                                  SQL Server 2008 R2 の場合、MSSQL10_50.<インスタンス名>という形式になります。

                                   

                                  C:\Program Files\Microsoft SQL Server\MSSQL10.<インスタンス名>\MSSQL\LOG

                                   

                                  1. [スタート] - [すべてのプログラム] - [Microsoft SQL Server 2008 R2] - [構成ツール] - [SQL Server 構成マネージャ] を選択し、[SQL Server Configuration Manager] 画面が表示されます。
                                  2. "SQL Server のサービス" - "SQL Server(<該当のインスタンス名>)" - 右クリック - "プロパティ" を選択します。[SQL Server(<該当のインスタンス名>)のプロパティ] 画面が表示されます。
                                  3. [詳細設定] タブ - [起動時のパラメータ] に指定されている文字列をコピーし、メモ帳などに貼り付けます。

                                   


                                  image

                                   

                                  image

                                   

                                  4. "-e" から始まるパラメータの文字列を確認します。"ERRORLOG" の前までが格納フォルダのパスになります。

                                   

                                  例) 上記例の場合

                                   

                                  ;-eC:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSQL\Log\ERRORLOG

                                   

                                  例) 既定のインスタンスの場合

                                   

                                  ;-eC:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Log\ERRORLOG

                                   

                                   

                                   

                                  SQL Server エラーログからわかる情報

                                   

                                  SQL Server エラーログでエラー以外に確認することができる情報としては、以下のようなものがあります。

                                   

                                  ・SQL Server のバージョン、エディション、Service Pack、累積アップデートの適用状況
                                  ・構成されている OS のバージョン、エディション
                                  ・通信プロトコル(TCP/IP、名前付きパイプなど)と待ち受けポート
                                  ・認証モードの種類(混合モード、Windows 認証のみなど)
                                  ・インスタンスが既定か名前付きか
                                  ・待ち受け可能な状況となった時間

                                   

                                  例) 認証モード
                                  混合認証モードの場合のログの記録

                                   

                                  2012-03-16 15:23:11.51 Server     Authentication mode is MIXED.

                                   

                                  Windows 認証モードのみの場合のログ

                                   


                                  2012-03-16 15:23:22.12 Server      Authentication mode is WINDOWS-ONLY.

                                   

                                  例) インスタンスの種類
                                  名前付きインスタンスの場合、"Server name is" の後、<Server名>\<インスタンス名> のように、"\" が入った形が続きます。
                                  以下の例では、"UIKOUSQLV" の後に、"\" が続きます。このことから、インスタンスは名前付きであり、インスタンス名 "SQL2008R2" であることがわかります。
                                  なお、SQL Server Express Edition は、既定のインストールでも、名前付きインスタンスになります。(<Server名>\SQLEXPRESS)

                                   


                                  2012-03-16 15:23:22.12 spid7s      Server name is 'UIKOUSQLV\SQL2008R2'. This is an informational message only. No user action is required.

                                   

                                  既定のインスタンスの場合は、"\" は含まれない形の名前が、"Server name is" に続きます。以下の場合、"\" が含まれていませんため、インスタンスは既定、すなわち "MSSQLSERVER" であると判断できます。

                                   


                                  2012-03-16 15:28:13.52 spid7s      Server name is 'UIKOUSQL'. This is an informational message only. No user action is required.

                                   

                                  例) 通信プロトコル(TCP/IP、名前付きパイプなど)と待ち受けポート
                                  "Server is listening on" で、エラーログを検索します。

                                   

                                  2012-03-16 15:23:23.04 サーバー       Server is listening on [ 'any' <ipv6> 1433].
                                  2012-03-16 15:23:23.05 サーバー        Server is listening on [ 'any' <ipv4> 1433].
                                  2012-03-16 15:23:23.05 サーバー        Server local connection provider is ready to accept connection on [ \\.\pipe\SQLLocal\MSSQLSERVER ].
                                  2012-03-16 15:23:23.05 サーバー        Server named pipe provider is ready to accept connection on [ \\.\pipe\sql\query ].
                                  2012-03-16 15:23:23.10 サーバー        Server is listening on [ ::1 <ipv6> 1434].
                                  2012-03-16 15:23:23.11 サーバー        Server is listening on [ 127.0.0.1 <ipv4> 1434].

                                   

                                  上記例では、ポート 1433と、1434が Listen 状態であること、また “ready to accept connection on”のつぎに、”\\.\pipe\とあるので、名前付きパイプの待ち受けもなされているということが判ります。
                                  次は、"SQL Server is now ready for" でログを確認しますと、接続可能な状態であるかどうか確認できます。
                                  以下の例では、03/16 15:24:12以降は、接続可能な状態であったと判断できます。

                                   

                                  例)
                                  2012-03-16 15:24:12.01サーバー        SQL Server is now ready for client connections. This is an informational message; no user action is required.

                                   

                                  イベント ログ

                                   

                                  イベント ログは、システムおよびアプリケーション イベント ログを txt 形式で保存していただくことが可能です。
                                  これにより、たとえば SQL Server についてのログを確認したいときに、ログを開くマシンに SQL Server が構成されていなくても、情報を確認することができます。

                                   

                                  1. イベントビューアを起動します。

                                   

                                  ※ Windows Server 2008 以降の場合、管理ツール (コントロール パネルの中に既定ではあります) – イベント ビューアーを起動します。

                                   


                                  image

                                   

                                  ※Windows Server 2003 も同様に、管理ツールからイベント ビューアを起動します。

                                   

                                  image

                                   

                                  ※ 全 Windows OS 共通で、[ファイル名を指定して実行 (Windows キー + R キー)] もしくは、Windows Server 2008 以降のスタートメニューの検索部分で、eventvwrと入力しますと、eventvwr.exe が選択されますので、ここから起動するという方法もあります。

                                   

                                  imageimage

                                   

                                  2. 左のペインの中から 「アプリケーション」 を選択し、右クリックします。(※Windows Server 2008 以降は、[Windows ログ] の下にあります)
                                  3.「すべてのイベントを名前を付けて保存(E)」(Windows Server 2008 以降)、または 「ログファイルの名前を付けて保存(A)」(Windows Server 2003) を選択します。

                                   

                                  ※ Windows Server 2003

                                   

                                  image

                                   

                                  ※ Windows Server 2008 以降

                                   

                                  image

                                   

                                  4. ファイル名に適当な名前を指定します。
                                  5. ファイルの種類に「テキスト(タブ区切り)」を指定して保存します。

                                   

                                  ※Windows Server 2003
                                  image

                                   

                                  6. 同様に 「システム」 を選択し、3. ~ 5. を実行します。

                                   

                                  まとめ

                                   

                                  ・SQL Server エラーログはエラーだけを記録しているのではなく、サーバの構成情報も含まれる
                                  ・SQL Server エラーログは各バージョン毎に格納場所が異なるので、確認が必要
                                  ・イベント ログはテキストで保存することで SQL Server が存在しない環境においても情報が確認可能になる

                                   

                                  参考情報

                                   

                                  SQL Server エラー ログの表示
                                  SQL Server 2005
                                  http://msdn.microsoft.com/ja-jp/library/ms187885(v=sql.90).aspx
                                  SQL Server 2008
                                  http://msdn.microsoft.com/ja-jp/library/ms187885(v=sql.100).aspx
                                  SQL Server 2008 R2
                                  http://msdn.microsoft.com/ja-jp/library/ms187885.aspx
                                  SQL Server 2012
                                  http://technet.microsoft.com/ja-jp/library/ms187109.aspx

                                   

                                  お問い合わせの際は、SQL Server マシン上でイベント ログも保存してご提供ください。また、その際は問題の発生時刻が確認できている場合は、時間も添えていただくことでピンポイントで状況を把握することができます。

                                  ★ SQL Server トラブルシューティング 6 回シリーズのご案内 ★

                                  本記事は、第 1 回目となります。他記事は以下をご参照ください。
                                  http://blogs.msdn.com/b/jpsql/archive/2012/03/30/sql-server-6.aspx

                                  第1回 SQL Server のログ、イベントログの確認方法 (03/30 UP、本記事)
                                  第2回 パフォーマンスログの採取方法 (04/20 UP)
                                  第3回 パフォーマンスログの確認方法 (05/07 UP)
                                  第4回 サーバートレースの解析方法 1 (05/18 UP)
                                  第5回 サーバートレースの解析方法 2 (02/18 UP)
                                  第6回 ブロッキング情報の確認方法 (07/24 UP)

                                  Troubleshooting: Connectivity #2 - エラー情報からわかる失敗原因

                                  $
                                  0
                                  0

                                   

                                  高橋 理香
                                  SQL Developer Support Escalation Engineer

                                  第一回目からだいぶ時間が空いてしまいました。。。
                                  SQL Server への接続エラー発生時のトラブルシューティング 2 回目の今回は、接続時に発生するエラー情報を参考に解説します。

                                  SQL Server への接続失敗の主な原因は?

                                  前回、SQL Server へ接続するにあたって事前に必要となる準備についてご紹介しました。それらの事前チェック項目をすべて網羅することで基本的には接続は可能となりますが、それでもエラーになることはあります。エラーメッセージには、その原因を示す内容も含まれますので、主な原因を把握しておくことも重要です。これにより、第一回でご紹介した「OS レベルのセッション確立」、「ログイン認証」、「データベース アクセス」のいずれで問題があったのかを把握したり、さらに深く問題個所を絞り込むこともできます。

                                  そこで、まずは接続処理のそれぞれの過程での失敗について、それらの一般的な原因をご紹介します。

                                  OS レベルのセッション確立が失敗する原因は?

                                  OS レベルのセッション確立が失敗するということは、一定時間内に接続先サーバーを見つけられなかった、もしくは、遅延により確立完了に至らなかったことを指します。そのため、主な原因としては以下の通りです。

                                  • 接続元で TCP ポートが枯渇していたために、接続要求の送信 (Syn パケット送信) に至らなかった。
                                  • 接続先サーバーへの接続要求が中継機器などで拒否されたなどの理由により、接続先サーバーに到達しなかった。
                                  • 順引き/逆引き両方での名前解決ができないため、SQL Server Browser サービスへの問い合わせが失敗した。
                                  • SQL Server Browser サービスが停止していたため、接続先の待ち受けポート番号を得られず、接続先サーバーに到達しなかった。
                                  • 接続先サーバーや SQL Server サービスが停止していた。
                                  • 指定されたプロトコルで待ち受けしていなかった。
                                  • クライアント/ネットワーク/サーバー等、通信経路上の負荷が高かったために、接続先サーバーとの通信に遅延が生じた。これにより、接続要求が接続サーバーへ到達しなかった、もしくは、接続先サーバーからの応答が接続元に到達しなかった。 
                                  ログイン認証が失敗する原因は?

                                  認証処理が失敗するということは、指定されたログインが適切なアカウントで、かつ、SQL Server にアクセスするのに適切な権限を持っているかのチェックで拒否されたか、もしくは、そのチェックが一定時間内に完了しなかったことを指します。そのため、主な原因としては以下の通りです。

                                  • SQL Server にログインとして登録されていない。
                                  • SQL Server 認証で接続しようとしたが、パスワード ポリシーのチェックのために SQL Server からドメイン コントローラーへの問い合わせを行おうとしたが、遅延が生じたために完了できなかった。
                                  • SQL Server 認証で接続しようとしたが、SQL Server の認証モードが "Windows 認証モード" であった。
                                  • Windows 認証で接続しようとしたが、SQL Server からドメイン コントローラーへの問い合わせに遅延が生じたために認証処理を完了できなかった。
                                  • Windows 認証で接続しようとしたが、Kerberos 認証で必要となる SPN に関して、その登録が重複しているなどの問題があったために Kerberos 認証が失敗した。  
                                  データベースアクセスが失敗する原因は?

                                  データベース アクセスが失敗するということは、対象のデータベースへのアクセスが拒否された、もしくは、一定時間内にデータベースがアクセスできる状態とならなかったことを指します。そのため、主な原因としては以下の通りです。

                                  • データベースが存在しない。
                                  • データベースがオフライン、復旧中など、アクセス受け入れ状態になっていない。
                                  • 対象のデータベースへのアクセス権が不足している。

                                   

                                    SQL Server への接続失敗時にどのようなエラーが返されるのか?

                                    接続処理のどの過程において、どのような問題でエラーとなったのかを判断するための最も簡単で重要な手段は、"エラーメッセージを確認する" ことです。私たちサポート エンジニアが接続エラーについてお問い合わせ頂く場合も、必ず接続失敗時にどんなエラーが発生したのかを伺っています。そして、接続エラーが不明で再現できない場合には、有効な情報をお出しできないことがほとんどです。そのため、様々なツールを使って接続エラーを再現できる状態の場合には、SQL Server への接続テスト時に発生したエラーを記録しておくようにしてください。また、もしも SQL Server にアクセスするアプリケーションを開発している方ならば、エラーハンドラではエラーメッセージを取得できるよう実装することを検討ください。

                                    では、エラーメッセージからはどのようなことがわかるのでしょうか?

                                    以下に、それぞれの接続処理過程で発生しうる主なエラーメッセージを記載しました。もし SQL Server への接続が失敗する場合、以下から該当のエラーメッセージを探してみましょう。また、どの過程で失敗したのかを把握できたら、前回の「Troubleshooting: Connectivity #1 - SQL Server への接続」の事前チェック項目をあらためて確認してみてください。そして、事前チェック項目はすべて網羅しているにもかかわらずエラーとなる場合には、エラーメッセージから原因を推測してみましょう。

                                    なお、ご紹介するエラーメッセージは SQL Native Client 10.0 を使用して SQL Server 2008 R2 に接続した場合に発生するものです。また、参考として MDAC/Windows DAC (SQL ODBC/SQLOLEDB) の場合の例も一部記載しています。SQL Native Client  10.0 を使用していても、接続に使用するツールによっては、以下のエラー メッセージが追加の文章とともに記録されますが、以下でご紹介するメッセージが含まれているかどうかをチェックすることで、原因は判別可能です。

                                    OS レベルのセッション確立

                                    一定時間内に接続先が見つけることができないことが原因ですので、エラーメッセージにも主に接続先が見つからないことを示す内容が含まれます

                                    [遅延等により接続先サーバーに到達できなかった場合]

                                    TCP Provider: そのようなホストは不明です。

                                    [接続先 SQL Server が停止している、TCP/IP で待ち受けしていない、SQL Server Browser サービスへの問い合わせが失敗した場合]

                                    指定された Server/Instance の位置を特定しているときにエラーが発生しました [xFFFFFFFF].

                                     

                                    ※参考

                                    SQL ODBC や SQLOLEDBの場合には、いずれのケースも以下のメッセージが返されます。

                                    指定された SQL Server が見つかりません。

                                    名前付きパイプによる接続試行時は以下のとおりです。

                                    SQL Server が存在しないか、アクセスが拒否されました。

                                     

                                    ログイン認証

                                    認証処理が失敗するということは、指定されたログインが適切なアカウントで、かつ、SQL Server にアクセスするのに適切な権限を持っているかのチェックで拒否されたか、もしくは、そのチェックが一定時間内に完了しなかったことを指します。また、エラーメッセージは主に SQL Server から返されますので、SQL Server のエラーログにもエラーが記録されている場合があります。

                                    [SQL Server にログインとして登録されていない場合]

                                    ユーザー 'xxx' はログインできませんでした。

                                    SQL Server のエラーログには、もう少し詳細な情報として次のように記録されます。

                                    エラー: 18456、重大度: 14、状態: 5。
                                    ユーザー 'xxx' はログインできませんでした。 理由: 指定された名前に一致するログインが見つかりませんでした。

                                    [SQL Server 認証で指定したパスワードが間違っている場合]

                                    ユーザー 'xxx' はログインできませんでした。

                                    SQL Server のエラーログには、もう少し詳細な情報として次のように記録されます。

                                    エラー: 18456、重大度: 14、状態: 8。
                                    ユーザー 'xxx' はログインできませんでした。 理由: パスワードが、指定されたログインのパスワードと一致しませんでした。

                                    [Windows 認証モードの SQL Server に SQL Server 認証で接続しようとした場合]

                                    ユーザー 'xxx' はログインできませんでした。

                                    SQL Server のエラーログには、もう少し詳細な情報として次のように記録されます。

                                    エラー: 18456、重大度: 14、状態: 58。
                                    ユーザー 'xxx' はログインできませんでした。 理由: SQL 認証を使用したログインに失敗しました。サーバーは、Windows 認証専用に構成されています。

                                    [Windows 認証で、ドメイン コントローラーへの問い合わせが失敗した場合]

                                    SSPI コンテキストを生成できません

                                    SQL Server 側では以下のエラーが記録されている場合があります。

                                    エラー: 18452、重大度: 14、状態: 1。
                                    ユーザー 'xxx' はログインできませんでした。このログインは SQL Server ログインなので、Windows 認証では使用できません。

                                    または

                                    エラー: 17806、重大度: 20、状態: 2。
                                    SSPI のハンドシェイク統合セキュリティでは、接続を確立中にエラー コード xxxxxxxxxx のために失敗しました。接続が閉じられました。

                                    ※参考

                                    SQL Server エラー ログの表示
                                    http://msdn.microsoft.com/ja-jp/library/ms187885(v=sql.105).aspx

                                    MSSQLSERVER_18456
                                    http://msdn.microsoft.com/ja-jp/library/cc645917(v=sql.105).aspx

                                     

                                    データベースアクセス

                                    データベース アクセスが失敗するということは、対象のデータベースへのアクセスが拒否された、もしくは、一定時間内にデータベースがアクセスできる状態とならなかったことを指します。こちらもエラーメッセージは主に SQL Server から返されますので、SQL Server のエラーログにもエラーが記録されている場合があります。

                                    [存在しないデータベースにアクセスしようとした、データベースがオフラインである、対象のデータベースへのアクセス権が不足している場合]

                                    このログインで要求されたデータベース "xxxxx" を開けません。ログインに失敗しました。
                                    ユーザー 'xxx' はログインできませんでした。

                                    SQL Server のエラーログには、もう少し詳細な情報として次のように記録されます。

                                    エラー: 18456、重大度: 14、状態: 38。
                                    ユーザー 'xxx' はログインできませんでした。 理由: 明示的に指定されたデータベースを開けませんでした。

                                     

                                     

                                    いかがでしたでょうか。接続失敗時に見られるエラーから、おおよその原因が推測できる点が少しでもお分かりいただけたらうれしいです。

                                    次回は引き続き、一度確立した接続がエラーによって切断される場合についてご紹介する予定です。

                                    デッドロック調査用の情報採取

                                    $
                                    0
                                    0

                                    ■初めに

                                    デッドロックについては以前ポストしましたが、やはり多くのお客様が悩まれる問題であると認識しています。SQL Server の Books Online でも下記のような情報を公開しており、以前に比べると必要な情報を確認いただける状態にはなっていると考えています。

                                    デッドロックの検出と終了

                                    SQL Server Profiler を使用したデッドロックの分析

                                    しかしながら、実際に我々サポート部門にお問い合わせを頂戴し、デッドロック調査用の情報採取手順を回答差し上げることも多いのは事実です。そこで、このポストではお問い合わせいただいた際に採取情報として回答している内容を、一般化してまとめたものを紹介したいと思います。このポストが、お客様でのデッドロックの調査の一助となれば幸いです。

                                    なお、ここで提示した情報を用いた方法のみが調査手法ではありませんので、あくまで1つの方法論としてお読みください。

                                    また、対象はSQL Server 2005以降となりますが、トレースフラグ 1222 以外は SQL Server 2000 でも使用可能な情報ですので、SQL Server 2000 のデッドロック調査もこの方法で行えると考えております。

                                    採取情報

                                    一般的にデッドロックを調査する場合、以下の情報を採取いただくことをお願いしています。

                                    a. トレースフラグの出力結果
                                    b. サーバトレースの出力結果
                                    c. スキーマ情報

                                    a. のトレースフラグの出力結果は、Books Online でも紹介しております、トレースフラグ1204および1222の出力結果となります。トレースフラグを有効とすることで、SQL Server の ERRORLOG に出力が行われます。基本的に、デッドロックの調査においてベースとなる情報と考えていただいて問題ありません。どちらかだけでも、基本的な情報は得ることができますが、このポストでは両方を有効とする手順を紹介します。

                                    b.のサーバトレースは、「SQL トレーススクリプトの作成、実行 (SQL Server 2005, 2008, 2008 R2)」で紹介している機能です。このサーバトレースを使用して、"関連するステートメント"、"実行プラン"、"トランザクション単位"を確認します。後述しますが、一般的に大量のデータが出力されるため、長時間の採取には向かない情報となります。

                                    c.は、b.で確認した関連するステートメントが参照しているテーブルについて、インデックスを含めた作成スクリプトをご提供いただくことをお願いしています。これは、インデックス構成を確認し、必要なインデックスを作ることで回避可能かを検討するためとなります。

                                    採取の流れ

                                    上記「採取情報」で説明した情報を採取することになりますが、サーバトレースは大量の情報が出力されるため、長時間の採取には適さない情報となります。そのため、調査対象のデッドロックについて、どこまで切り分けを行っていただけているかによって、段階を踏んで調査を行うことを提案しています。

                                    デッドロックが再現できない状況
                                    デッドロックが発生したことがあるが、どのような処理が関わっていたかわからず、再現ができない状況や発生頻度が低くタイミングが不明な状況である場合、a.のトレースフラグを設定し、まずデッドロックに関わっている処理を特定することを提案しています。この情報を元にデッドロックが再現できれば、「デッドロックが再現するか頻発する状況」の作業を行い、調査が行えるようになります。

                                    なお、発生頻度が極めて低いデッドロックであれば、クライアントサイドでのリトライが現実的な対応となります。調査した結果、同じタイミングで同一レコードへの更新、参照によって発生するような回避不可能なデッドロックであった場合は、結局リトライでの対応となります。

                                    デッドロックが再現するか頻発する状況
                                    デッドロックが再現可能か、もしくは特定時間帯に頻発することが判っている場合、一気に情報を取得するのが解決への最短コースとなります。そのため、以下の流れで情報の採取をしていただいています。

                                    1) トレースフラグの有効化
                                    2) サーバトレースの開始
                                    3) デッドロックの再現確認
                                    4) サーバトレースの停止
                                    5) トレースフラグの無効化

                                    この作業の後、我々サポート部門での解析をご依頼いただく際は、以下の情報をご提供いただいています。

                                    - SQL Server の Log フォルダ内のすべてのファイル
                                    - サーバトレースの出力結果
                                    - テーブルおよびインデックスの作成スクリプト(*1)

                                    *1 通常、サーバトレースの解析後にご提供をお願いしています。

                                    トレースフラグの設定方法

                                    トレースフラグの有効化、無効化の方法を紹介いたします。トレーフラグを設定する方法には、以下の2つの方法があります。

                                    a. DBCC TRACEON/TRACEOFF の使用
                                    b. 起動オプションへの設定

                                    DBCC TRACEON で設定した場合、コマンド実行後から直ぐにトレーフラグが有効となります。ただし、SQL Server を再起動した場合、再びコマンドを実行し直す必要があります。その為、起動オプションへの設定を行い、次回再起動で有効になるようにした上で、再起動まではDBCC TRACEONで有効化しておくという方法も取れます。

                                    a-1. DBCC TRACEON での有効化
                                    以下のコマンドを実行いただくことで、有効化が行えます。

                                    DBCC TRACEON (1204,1222,-1)
                                    go

                                    a-2. DBCC TRACEOFF での無効化
                                    以下のコマンドを実行いただくことで、無効化が行えます。

                                    DBCC TRACEOFF (1204,1222,-1)
                                    go

                                    b.起動オプションへの設定方法
                                    以下の手順で設定が行えます。無効とする際は、追加した文字列を削除いただき、SQL Server の再起動を行います。

                                    1) SQL Server Configuration Manager (構成マネージャ)を起動します
                                    2) SQL Serverのサービス -> SQL Server (MSSQLSERVER/もしくはインスタンス名) を右クリックし、プロパティを開きます
                                    3) 詳細設定タブ -> 起動時のパラメータに、次の文字列を追加します

                                    ;-T1204;-T1222

                                    * セミコロンで区切ってパラメータを追加するイメージです

                                    サーバトレースの使用方法

                                    サーバトレースの実際の使用方法は、以前のポストである「SQL トレーススクリプトの作成、実行 (SQL Server 2005, 2008, 2008 R2)」を参照してください。ここでは、選択すべきイベントについて紹介いたします。

                                    とりあえず、ベースとして以下のイベントが入っていれば問題ないと考えています。ただし、イベントとしては多いため、大量の情報が出力されます。このベースを元に、不要なイベントを削除して情報採取をしていくことになります。例えば、ストアドプロシージャが関連していないことが判っているのであれば Stored Procedures イベントを外すことができます。イベントについてはどのような情報が取れるか、実際にテスト環境などで確認した上で、選択してください。

                                    Errors and Warnings
                                    ※ すべてのイベント

                                    Locks
                                    Lock: Deadlock
                                    Lock: Escalation

                                    Performance
                                    Showplan All

                                    Security Audit
                                    Audit Login
                                    Audit Logout

                                    Sessions
                                    ExistingConnection

                                    Stored Procedures
                                    RPC: Completed
                                    PRC: Starting
                                    SP: Completed
                                    SP: Starting
                                    SP: StmtStarting

                                    TSQL
                                    SQL: BatchCompleted
                                    SQL: BatchStarting
                                    SQL: StmtStarting

                                    Transactions
                                    ※ TransactionLog 以外すべて

                                    [SQL Troubleshooting] 第2回 : Tips -パフォーマンス ログの採取方法 (Windows Server 2003 ~ Windows Server 2008 R2)

                                    $
                                    0
                                    0

                                    福原 宗稚
                                    SQL Developer Support Engineer

                                     

                                    パフォーマンス ログとは

                                    Windows に付属のツールを使用して採取する、Windows や SQL Server 等のパフォーマンスに関する情報です。事前に指定したカウンタ (よく言われる「CPU使用率」を示す Processor%Processor Time、「空きメモリ」を示す Memory%Available Bytes 等)を、一定間隔で記録します。

                                    例えば、SQL Server へのクエリがタイムアウトする、SQL Server のパフォーマンスが低下する、SQL Server への接続が切断されることがあるといった問題の場合、「サーバーの負荷が高い」可能性が考えられます。この「サーバーの負荷が高い」という点から一歩踏み込んで、CPU使用率が高いのか、メモリが枯渇しているのか、ディスク IO の量が多く待ちとなっているのかといったボトルネックを確認するために使用します。一般的には、通常時と、現象発生時のカウンタの値を比較し、現象発生時に突出して高くなっている値があれば、それが現象と関係している可能性が高いと判断できます。

                                    これさえあればパフォーマンスの問題が解決できる!とついつい期待してしまいますが、これまでの経験からは、あくまでも補助的な情報であり、場合によっては威力を発揮するという印象があります。

                                    現象発生時に、カウンタがこの値を示していたということは分かりますが、たまたまその値を示していただけで現象に関係していないといった場合や、このサーバーのスペックや使われ方によっては、この値を示していても問題がないという場合も数多くあります。パフォーマンスログ単体で見ると問題を見誤る可能性がありますので、注意が必要です。

                                    一方、パフォーマンスログがなければ、エラーログにこういうエラーが出力されているので、サーバーの負荷が高かった可能性がある、という結論で終わるところが、パフォーマンスログがあることで、その時実際には特定のディスクのIOが非常に高かったということや、あるアプリケーションがメモリを大量に消費していたといった一歩踏み込んだ調査ができるため、その結果に応じた対処まで確立できる可能性が出てきます。

                                     

                                    考慮する点

                                    採取にあたって、考慮する点は大きく2つあります。

                                    1) 採取するカウンタ
                                    調査対象である問題によって、採取するカウンタは変わってきます。もっとも避けなければならないのは、見たいカウンタが足りなかったので、取り直しが発生するということです。パフォーマンスカウンタは、Windows に付属しておりスケジュール実行やファイルのローテーションなど柔軟に設定でき、かつ採取時の負荷も比較的低いため、発生頻度が低い現象でも常時設定しておいて、現象が発生した場合には採取するという使い方もされます。
                                    そのため、取りこぼしがないように、少し多すぎるかなと思われるくらいの種類のカウンタをまずは採取するのが良いと思います。そして、問題が絞り込めて来た場合には、徐々にカウンタを絞っていくのがお勧めです。

                                    SQL Server に関する調査で使用するカウンタについては、今後公開するパフォーマンスンログの確認方法でご案内する予定です。

                                    2) 採取間隔
                                    こちらも調査対象である問題によって、採取間隔は変わってきます。現象が発生している間に、可能であれば、2回以上の記録があることが望ましいです。最低限1回の記録は必須ですが、1回の記録の場合には、現象と関係あるのか、もしくは現象と関係なくたまたまその値となっていただけなのかという判断が難しいためです。現象が発生している間に記録されている2回の記録や3回の記録がすべてその値であるということなれば、その値となっていることが現象と関係あるという可能性が非常に高くなります。

                                    例えば、1分くらい継続する現象の場合には、15秒や20秒間隔で採取します。また、15秒くらい継続する現象の場合には、5秒間隔で採取します。最短で1秒間隔まで設定することが可能です。特定の現象について調査を行う場合に1秒単位といった設定を行う場合がありますが、定常的な監視で1秒間隔での採取は一般的には不要です。

                                     

                                    注意事項

                                    ログファイルを出力するディスクは、調査対象となる SQL Server への影響を避けるため、可能であれば、SQL Server のデータベース ファイルが存在しないドライブを指定します。

                                    採取するカウンタ数、採取間隔、採取する時間によって、ログファイルが大きくなることが予想されますので、実行前にログファイルが生成されるドライブには十分な空き領域があることを確認します。

                                     

                                    設定手順(Windows Server 2003, Windows Server 2003 R2)

                                    1. スタートメニューから、[すべてのプログラム] - [管理ツール] - [パフォーマンス] を選択します。
                                    もしくは、スタートメニューから、[ファイル名を指定して実行] で、perfmon と入力します。

                                    2. パフォーマンス モニタが起動したら、[パフォーマンス ログと警告] - [カウンタ ログ] を右クリックし、[新しいログの設定] を選択します。

                                     

                                     

                                    3. [新しいログの設定] ダイアログで、任意の名称を入力します。

                                     

                                     

                                    4. [全般] タブで、[カウンタの追加] ボタンをクリックします。

                                     

                                     

                                    5. [次のコンピュータからカウンタを選ぶ] で対象のサーバーが表示されていることを確認します。採取するカウンタを [パフォーマンス オブジェクト]、[すべてのカウンタ] もしくは [一覧からカウンタを選ぶ]、[すべてのインスタンス] もしくは [一覧からインスタンスを選ぶ] からそれぞれ選択し、[追加] ボタンをクリックして追加します。全てのカウンタを追加し終えたら、[閉じる] をクリックします。

                                     

                                     

                                    6. 追加したカウンタは、[カウンタ] 部分から確認できます。続いて、[データのサンプル間隔] で、カウンタを採取する間隔を設定します。

                                     

                                     

                                    7. [ログ ファイル] タブでは、ファイルの種類や出力先等を必要に応じて変更します。

                                     

                                     

                                    8. [スケジュール] タブでは、採取開始や終了を行うためのスケジュール設定を行います。既定のスケジュール設定では、設定完了後即座に採取が開始されます。

                                     

                                     

                                    9. [OK] をクリックして、設定を完了します。

                                    10. 該当のログを右クリックし、[停止] を選択することで、採取を停止します。また、[開始] を選択することで、採取を開始します。

                                     


                                    ※ logman start <ログの名称> コマンドで採取開始、logman stop <ログの名称> コマンドで採取停止を行うこともできます。例えば、バッチ処理の開始前に採取開始し、バッチ処理の終了後に採取停止するといった場合に便利です。(logman コマンドの詳細は、コマンドプロンプトから、logman /? を実行することで確認できます。)

                                    開始例 : logman start Performance
                                    停止例 : logman stop Performance


                                    設定手順(Windows Server 2008, Windows Server 2008 R2)

                                    1. スタートメニューから、[すべてのプログラム] - [管理ツール] - [パフォーマンス モニター] を選択します。(Windows Server 2008 の場合は、[信頼性とパフォーマンス モニタ] という名称になります。)
                                    もしくは、スタートメニューから、[ファイル名を指定して実行] で、perfmon と入力します。

                                    2. パフォーマンス モニター が起動したら、[データ コレクター セット] - [ユーザー定義] を右クリックし、[新規作成] – [データ コレクター セット] を選択します。

                                     

                                    3. [この新しいデータ コレクター セットの作成方法を選択してください。] 画面で、任意の名称を入力し、[手動で作成する] を選択し、[次へ] をクリックします。

                                     

                                    4. [含めるデータの種類を選択してください。] 画面で、[データログを作成する]、[パフォーマンス カウンター] を選択し、[次へ] をクリックします。

                                     

                                    5. [記録するパフォーマンス カウンターを選択してください。] 画面で、[追加] ボタンをクリックします。


                                     

                                    6. [次のコンピューターからカウンターを選んでください] で対象のサーバーが選択されていることを確認します。採取するカウンタをパフォーマンスオブジェクトの一覧���[選択したオブジェクトのインスタンス] からそれぞれ選択し、[追加] ボタンをクリックして追加します。全てのカウンタを追加し終えたら、[OK] をクリックします。

                                     

                                    7. 追加したカウンタは、[パフォーマンス カウンター] 部分から確認できます。続いて、[サンプルの間隔] で、カウンタを採取する間隔を設定し、[次へ] をクリックします。

                                     

                                    8. [データの保存場所を選択してください。] 画面では、ログの保存先を指定し、[次へ] をクリックします。

                                     

                                    9. [データ コレクター セットを作成しますか?] 画面では、[保存して閉じる] を選択し、[完了] をクリックします。

                                     

                                    10. 該当のデータ コレクター セット を右クリックし、[開始] を選択することで、採取を開始します。また、[停止] を選択することで、採取を停止します。

                                    ※ logman start <ログの名称> コマンドで採取開始、logman stop <ログの名称> コマンドで採取停止を行うこともできます。例えば、バッチ処理の開始前に採取開始し、バッチ処理の終了後に採取停止するといった場合に便利です。(logman コマンドの詳細は、コマンドプロンプトから、logman /? を実行することで確認できます。)

                                    開始例 : logman start Performance
                                    停止例 : logman stop Performance

                                    ※ データ コレクター セット を右クリックし、[プロパティ] を選択することで、プロパティを表示することができます。データ コレクター セットのプロパティでは、ファイルの種類や出力先等の変更、スケジュールの設定等を行うことができます。

                                    SQL Server トラブルシューティング 6 回シリーズのご案内

                                    本記事は、第 2 回目となります。他の記事は以下をご参照ください。
                                    http://blogs.msdn.com/b/jpsql/archive/2012/03/30/sql-server-6.aspx

                                    第1回 SQL Server のログ、イベントログの確認方法 (03/30 UP)
                                    第2回 パフォーマンスログの採取方法 (04/20 UP、本記事)
                                    第3回 パフォーマンスログの確認方法 (05/07 UP)
                                    第4回 サーバートレースの解析方法 1 (05/18 UP)
                                    第5回 サーバートレースの解析方法 2 (02/18 UP)
                                    第6回 ブロッキング情報の確認方法 (07/24 UP)

                                    FAQ:実行時間の長い I/O を示すエラー833について

                                    $
                                    0
                                    0

                                    SQL Server の ERRORLOG に記録される下記のメッセージについて、「ERRORLOG に出てたのですが何か影響がありますか?」といったお問い合わせを頂くことがあります。公開されている情報もありますが、改めてここでメッセージの意味などについて情報を纏めておこうと思います。

                                    2011-02-14 12:01:53.79 spid2s      SQL Server has encountered 4 occurrence(s) of I/O requests taking longer than 15 seconds to complete on file [C:\XXXXX.mdf] in database [XXXXX] (6).  The OS file handle is 0x0000000000001708.  The offset of the latest long I/O is: 0x00000f08302000

                                    メッセージの意味

                                    このメッセージは、SQL Server がディスクに要求した I/O リクエストが、15 秒以上経過しても完了していないことを示します。

                                    SQL Server はディスクに対して非同期の I/O リクエストを行います。このメッセージは、おおよそ 10 秒間隔で非同期 I/O のリクエストをチェックし、まだ完了しておらずかつ 15 秒以上経過している I/O リクエストが存在した場合に出力されます。この事からお判り頂けると思いますが、SQL Server 内部で問題が発生していることを示しているわけではなく、SQL Server の外部で I/O リクエストが遅延している状況を示すメッセージとなります。

                                    影響

                                    メッセージからは、どの様な処理の書き込み or 読み取りが影響を受けたかについては、判断を行うことはできません。判ることは対象のデータベースファイルへの I/O リクエストが遅延しているという事実だけとなるため、対象データベースへの処理が遅延した可能性があると判断できます(クエリがタイムアウトする等の影響が出たかまでは判りませんが……)。

                                    対応

                                    稀に単体で記録されるようなシチュエーションで、特に影響などの報告が無ければ、無視いただいても問題はありません。

                                    定期的に出力される状況であれば、ディスク I/O がボトルネックとなっていないか、ハードウェアに関する問題が発生していないか等を確認し、状況に応じた対応を行う必要があります。

                                    SQL Server の Books Online では、ウィルス対策プログラムの影響を排除するため、スキャン対象から SQL Server 関連のファイルを除外するように記載があります。関連ファイルなどについては、下記のサポート技術情報を確認してください。

                                    KB309422
                                    How to choose antivirus software to run on computers that are running SQL Server

                                    参考情報

                                    KB2137408
                                    SQL Server logs "Msg 833" when I/O delay problems occur

                                    SQL Server 2012 Books Online
                                    MSSQLSERVER_833

                                    Viewing all 153 articles
                                    Browse latest View live


                                    <script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>