SQL Server2005 ロック状態の調査・解除方法

SQL Serverでデーターがロックされてしまった場合に,ロックしているプロセスを確認したりロックを強制的に解除したりする方法.

1. SQL Server Management Studioを起動
2. 利用状況モニタを表示
   [管理]→[利用状況モニタ]→右クリックでプロセスの表示
3. [プロセス情報]のブロッキング,ブロック元列を参考にロックしているプロセスIDを探す.
   行を右クリック→[詳細]で実行中のSQL文が表示されるのでこれも参考になる.

4. ロックしているプロセスIDが見つかったら,その行を右クリック→[強制終了]

【注意】
利用状況モニタの情報は,「更新」を押さないと最新の情報にならない.
※2009.12.16追記:ロックしているだけではダメで,ロックによって他のクエリー等がブロックされている状態にならなければブロッキングはカウントされない.そしてその状態の時に「更新」を押す必要がある.

・Management Studioが使えない場合
ストアドsp_whoを実行.
blk列にロックしているプロセスIDが表示される.
コマンドプロンプトから, Kill プロセスID

【注意】
サーバー上で管理者権限でおこなうこと.
※2010.1.22追記:SQL Server Management Studioを使う場合でもプロセスの強制終了は、サーバー上の管理者権限でSQL Server Management Studioを使う必要がある。

SQL Server2005 sys.sysobjvalues 整合性エラー修復方法

SQL Server2005で次のような整合性エラーが発生する場合がある。


失敗:(-1073548784) クエリ “DBCC CHECKDB WITH NO_INFOMSGS
” の実行が次のエラーで失敗しました: “オブジェクト ID 60、インデックス ID 1、パーティション ID 281474980642816、アロケーション ユニット ID 71776119065149440 (型 LOB data) のページ (1:193) の PFS 空き領域情報が不適切です。予想値   0_PCT_FULL、実際の値 100_PCT_FULL。
CHECKDB により、テーブル ‘sys.sysobjvalues’ (オブジェクト ID 60) に 0 個のアロケーション エラーと x 個の一貫性エラーが見つかりました。


SQL Serverのバグらしい。

http://www.sqlservercentral.com/Forums/Topic766849-266-1.aspx(英語)

http://www.sqlskills.com/BLOGS/PAUL/post/Corruption-bug-that-people-are-hitting-Msg-8914-PFS-free-space.aspx(英語)


【修復方法】 REPAIR_ALLOW_DATA_LOSSオプションはデーターが失われる可能性があるため注意する必要がある

(1)シングルユーザーモードにする(しないとREPAIR_ALLOW_DATA_LOSSオプションが使えない)
ALTER DATABASE [DB名] SET SINGLE_USER

(2)DBをバックアップ(REPAIR_ALLOW_DATA_LOSSオプションはデーターが失われる可能性があるため)

(3)修復
DBCC CHECKDB (‘DB名’, REPAIR_ALLOW_DATA_LOSS)

(4)整合性チェック
DBCC CHECKDB (‘DB名’)
DBCC CHECKCONSTRAINTS

(5)マルチユーザーモードに戻す
ALTER DATABASE [DB名] SET MULTI_USER

参考:
http://msdn.microsoft.com/ja-jp/library/ms176064.aspx

【注意】
データーが失われる可能性があるためバックアップを取っておくこと.
修復後にデーターが失われていないか確認する手段を準備しておくこと.
修復中はサーバーが無反応に近くなる場合がある.
したがって,あらかじめテスト環境等で作業に要する時間を調査しておくこと.
作業時間には修復に失敗した場合のリストア時間も含めること.

VB2005 + SQL (複数テーブル参照でCommandBuilderが使えない場合)

データーをストアドからDataTableへ受け取り,グリッドに表示
  (複数テーブル参照でCommandBuilderが使えない場合)
  CommandBuilderが使えない場合は,InsertCommand・UpdateCommand・DeleteCommandをそれぞれ自前で作る

    Dim cn As SqlClient.SqlConnection
    Dim da As New SqlClient.SqlDataAdapter()
    Dim dt As New DataTable

    Private Sub a1()
        Dim cmd As New SqlClient.SqlCommand(“stHoge”, cn)
        Try
            cmd.CommandType = CommandType.StoredProcedure
            da.SelectCommand = cmd

            ‘Insert
            cmd = New SqlClient.SqlCommand(“stHogeInsert”, cn)
            cmd.CommandType = CommandType.StoredProcedure
            cmd.Parameters.Clear()
            cmd.Parameters.Add(“@a1”, SqlDbType.Int, 4, “a1”)
            ‘ID値を返す(これがないとIDが不定となる)
            Dim parameter As SqlClient.SqlParameter = cmd.Parameters.Add(“@Identity”, SqlDbType.Int, 4, “ID”)
            parameter.Direction = ParameterDirection.Output
            da.InsertCommand = cmd

            ‘Update
            cmd = New SqlClient.SqlCommand(“stHogeUpdate”, cn)
            cmd.CommandType = CommandType.StoredProcedure
            cmd.Parameters.Clear()
            cmd.Parameters.Add(“@ID”, SqlDbType.Int, 4, “ID”)
            cmd.Parameters.Add(“@a2”, SqlDbType.Int, 4, “a2”)
            da.UpdateCommand = cmd

            ‘Delete
            cmd = New SqlClient.SqlCommand(“stHogeDelete”, cn)
            cmd.CommandType = CommandType.StoredProcedure
            cmd.Parameters.Clear()
            cmd.Parameters.Add(“@ID”, SqlDbType.Int, 4, “ID”)
            da.DeleteCommand = cmd

            dt.PrimaryKey = Nothing
            dt.Locale = System.Globalization.CultureInfo.InvariantCulture
            dt.Clear()
            da.Fill(dt)
            ‘dt.PrimaryKey = New DataColumn() {dt.Columns(“ID”)}

            DGV.DataSource = dt

        Finally
            cmd.Dispose()
        End Try

    End Sub