1

私の会社は現在 SQL Server 2000 を実行しており、SQL Server 2012 に移行しようとしていますが、アップグレードに移行する前に、最近発生し、ビジネスを遂行する能力を悩ませているパフォーマンスの問題を解決したいと考えています。 .

数か月前、SQL Server テーブルの 1 つにテキスト フィールドを追加して、特定のイベントをキャプチャすることにしました。日中に列を追加しようと思いましたが、振り返ってみるとこれがおそらく最初の間違いでしたが、人々がテーブルを使用している場合、SQL Server は列の追加を許可しないと考えました。この試行では、余分な列が受け入れられ、テーブルに追加されました。次に、この新しい列に書き込むように Access フロント エンドをコーディングしました。

その後すぐに、ユーザーは Access GUI の「ロックアップ」を経験し始め、最終的にはクエリ タイムアウト エラーがスローされました。

エラーが発生する方法は次のとおりです。VBA で T-SQL ステートメントを作成して新しいレコードを更新または保存する Access フロント エンドの保存ボタンをクリックした後、保存が正常に完了したことやエラーが発生したことを示す Access メッセージ ボックスがユーザーに表示されませんでした。 . 代わりに、クエリのタイムアウトが発生したことを示す Access システムのダイアログ ボックスが表示されます。この時点で、問題が解決することを期待して、追加した列を削除しました。

私はまず、全員に Access プログラムを閉じてもらい、問題を抱えていた人に再度開いてもらい、もう一度保存してもらいました。これはそのユーザーには有効だったので、この時点で他のすべてのユーザーがシステムに戻ることを許可します。もちろん、当時はなぜこれが機能したのかわからなかったので、この問題を詳しく調べてみました。さらに分析した結果、sp_who2 にたどり着きました。これを実行すると、すべてのユーザーとブロックしているユーザーの SPID が表示されます。これにより、問題のある SPID を強制終了し、他のすべてのユーザーが作業を続行できるようになるため、作業を再開するためのより迅速な方法が得られました。もちろん、強制終了するとロールバックが発生するため、すべてのデータが保存されるわけではなく、強制終了されたプロセスの所有者に、すべてのデータをもう一度入力する必要があることを伝える必要があります。今日まで、私はこの方法でこのデータベースを継続的に監視しており、ブロックされているものを見つけたら、

このデータベースの単一のテーブルに問題があることはわかっています。まず、新しい列を入力しようとした後に問題が発生しただけでなく、保存または更新が実行されるたびに、この特定のテーブルに書き込むときにロックされるためです。当時、私がこれを診断したのは、実行しようとしているアクションをユーザーに尋ねたためでした。すべてのケースで、ユーザーはこの特定のテーブルに対して何かをしようとしていたのです。実際、この同じ Db 内の他のテーブルへの変更は問題なく実行されます。したがって、問題はこのテーブルの破損に関連している可能性があると感じました。

私が最初にしたことは、CHECKDB と CHECKTABLE を実行することでしたが、どちらもテーブルに関する問題を返しませんでした。そこで、テーブルを再構築することにしました。テーブルを手動で再構築し、データを元のテーブルから新しいテーブルにコピーしました。これにはSQLツールを使用したと思いますが、挿入を実行した可能性があります。(しばらく経ちましたが、文書化していませんでした。) いずれにせよ、うまくいきませんでした。組織は引き続きブロックされました。そこで、テーブルのインデックスを再作成したところ、約 1 日は機能しているように見えましたが、その後、エラーが「戻ってきました」。それ以来、しばらくの間、ブロックしているユーザーの SPID で毎回実行していた INPUTBUFFER を見つけました。ほとんどの場合、INPUTBUFFER は SELECT ステートメントを返しますが、それがブロックをスローしているとは思いません。Access GUIで保存ボタンを押すと、保存または更新が実行され、選択が実行されてAccess画面が更新されるため、SELECTがブロックをスローしたとは思いません。SELECT が保存が行われたブロックをスローしていた場合、プロセスがブロックを開始し、プロセスが強制終了された後にレコードを呼び出すと、ユーザーの変更はレコードに保存されないと思います。INPUTBUFFER がどのように機能するかは完全にはわかりません。SQL Server に送信された最後のステートメントを返すと思われますが、保存がコミットされなかった場合でも、Access は SQL Server に SQL を送信している可能性がありますか? ただし、プロセスがブロックを開始してプロセスが強制終了された後にレコードを呼び戻すと、ユーザーの変更はレコードに保存されません。INPUTBUFFER がどのように機能するかは完全にはわかりません。SQL Server に送信された最後のステートメントを返すと思われますが、保存がコミットされなかった場合でも、Access は SQL Server に SQL を送信している可能性がありますか? ただし、プロセスがブロックを開始してプロセスが強制終了された後にレコードを呼び戻すと、ユーザーの変更はレコードに保存されません。INPUTBUFFER がどのように機能するかは完全にはわかりません。SQL Server に送信された最後のステートメントを返すと思われますが、保存がコミットされなかった場合でも、Access は SQL Server に SQL を送信している可能性がありますか?

また、SQL Server Management Studio 自体で作業しているときは、ブロックをスローしていないように見えることも付け加えておきます。SQLステートメントをハングさせる既存のブロックの影響を明らかに感じましたが、私の知る限り、ブロックをスローしたことはありません。そのために、ODBC コネクタもすべてのユーザーから 10.0 に更新しました。これは、問題にマイナスまたはプラスの影響を与えていないようです。

だから私は次に何をすべきかわからない。任意の提案をいただければ幸いです。

4

1 に答える 1

1

リンクされたテーブルを操作するときは、SQL Server テーブルに一意の識別子があることを確認してください。

テーブルをリンクする方法に関する私の記事をチェックしてください。

http://craftydba.com/?p=1893

2 番目の質問は、取得しているロックの種類は何ですか?

以下は、私が時々行うプレゼンテーションのコードです。AdventureWorks2012 をデータベース名に変更します。

これにより、どのようなロックが発生しているかがわかります。詳細を確認するには、正しい hobt_id または object_id を選択してください。

--
-- Locked object details
-- 

-- Old school technique
EXEC sp_lock
GO

-- Lock details
SELECT
    resource_type, resource_associated_entity_id,
    request_status, request_mode,request_session_id,
    resource_description 
FROM sys.dm_tran_locks
WHERE resource_database_id = DB_ID('AdventureWorks2012')
GO

-- Page/Key details
SELECT object_name(object_id) as object_nm, *
FROM sys.partitions
WHERE hobt_id = 72057594047037440
GO

-- Object details
SELECT object_name(1266103551)
GO

ブロッキングは、SQL サーバーがセッション間の協調実行を可能にする方法の一部です。問題は、デッドロックになるか、SQL サーバーがデッドロックを検出しない場合です。

いくつかの解決策は、分離レベルを変更することです。しかし、これには独自の問題があります。ファントム リード、ダーティ リード、繰り返し不可能なリード、同時実行性の低さです。最初に確認するのはロック シーケンスです。画像を投稿してください。

SQL Server 2000 を使用しているため、sp_indexoption を確認してください。

概要:

http://technet.microsoft.com/en-us/library/aa213036(v=sql.80).aspx

「たとえば、テーブルが競合点であることがわかっている場合、ページ レベルのロックを禁止して、行レベルのロックのみを許可すると効果的です。または、インデックスまたはテーブルにアクセスするために常にテーブル スキャンが使用される場合、ページ レベルおよび行レベルのロックを許可しないことで、テーブル レベルのロックのみを許可することができます。」

詳細:

http://technet.microsoft.com/en-us/library/aa238800(v=sql.80).aspx

MS Access プログラムがページ ロックを使用しないようにしてください。

BOL からの呼び出しの例:

USE Northwind
GO

EXEC sp_indexoption 'Customers.City', 
   'disallowpagelocks', 
   TRUE
GO

sp_who2 を使用して、ブロックしている 2 つの SPID を取得します。

ここに画像の説明を入力

DBCC INPUTBUFFER を使用して、両方の SPID の実際の SQL ステートメントを取得します。

ここに画像の説明を入力

于 2013-12-09T16:36:47.160 に答える