sql >> データベース >  >> RDS >> Sqlserver

SQLServerのトランザクションレプリケーションの問題

    SQLServerトランザクションレプリケーションの問題については以前から話し始めました。次に、頻繁に直面するレプリケーションパフォーマンスの問題と、それらを正しくトラブルシューティングする方法を理解するために、さらにいくつかのハンズオンデモを続けます。

    構成の問題、アクセス許可の問題、接続の問題、データの整合性の問題などの問題について、トラブルシューティングと修正とともにすでに説明しました。次に、SQLServerレプリケーションに影響を与えるさまざまなパフォーマンスの問題と破損の問題に焦点を当てます。

    破損の問題は大きなトピックであるため、この記事でのみ、破損の影響について説明します。詳細については説明しません。私の経験に基づいて、パフォーマンスと破損の問題に該当する可能性のあるいくつかのシナリオを選択しました。

    • パフォーマンスの問題
      • パブリッシャーデータベースで実行されているアクティブなトランザクション
      • 記事に対する一括INSERT/UPDATE/DELETE操作
      • 1回のトランザクションで大量のデータが変更される
      • ディストリビューションデータベースのブロック
    • 汚職関連の問題
      • パブリッシャーデータベースの破損
      • ディストリビューションデータベースの破損
      • サブスクライバーデータベースの破損
      • MSDBデータベースの破損

    パフォーマンスの問題

    SQL Serverトランザクションレプリケーションは、パブリッシャーデータベース、ディストリビューター(ディストリビューション)データベース、サブスクライバーデータベース、SQLServerエージェントジョブとして実行されるいくつかのレプリケーションエージェントなどのいくつかのパラメーターを含む複雑なアーキテクチャです。

    これまでの記事でこれらすべての項目について詳しく説明してきたので、レプリケーション機能に対する各項目の重要性を理解しています。これらのコンポーネントに影響を与えるものはすべて、SQLServerレプリケーションのパフォーマンスに影響を与える可能性があります。

    たとえば、Publisherデータベースインスタンスは、1秒あたりのトランザクション数が多い重要なデータベースを保持しています。ただし、サーバーリソースには、90%を超える一貫したCPU使用率や90%を超えるメモリ使用量などのボトルネックがあります。これは、パブリッシャーデータベースのトランザクションログから変更データを読み取るログリーダーエージェントジョブのパフォーマンスに確実に影響します。

    同様に、ディストリビューターまたはサブスクライバーのデータベースインスタンス全体でこのようなシナリオが発生すると、スナップショットエージェントまたはディストリビューションエージェントに影響を与える可能性があります。したがって、DBAとして、CPU、物理メモリ、ネットワーク帯域幅などのサーバーリソースが、パブリッシャー、ディストリビューター、サブスクライバーのデータベースインスタンスに対して効率的に構成されていることを確認する必要があります。

    パブリッシャー、サブスクライバー、およびディストリビューターのデータベースサーバーが正しく構成されていると仮定すると、以下のシナリオが発生した場合でも、レプリケーションのパフォーマンスの問題が発生する可能性があります。

    パブリッシャーデータベースで実行されているアクティブなトランザクション

    名前が示すように、長時間実行アクティブトランザクションは、トランザクションスコープ内でアプリケーション呼び出しまたはユーザー操作が長時間実行されていることを示します。

    実行時間の長いアクティブなトランザクションを見つけることは、トランザクションがまだコミットされておらず、アプリケーションによってロールバックまたはコミットできることを意味します。これにより、トランザクションログが切り捨てられなくなり、トランザクションログファイルのサイズが継続的に増加します。

    Log Reader Agentは、トランザクションログからのレプリケーションのマークが付けられたすべてのコミット済みレコードを、ログシーケンス番号(LSN)に基づいてシリアル化された順序でスキャンし、レプリケートされない記事に対して発生する他のすべての変更をスキップします。長時間実行アクティブトランザクションコマンドがまだコミットされていない場合、Replicationはそれらのコマンドの送信をスキップし、他のすべてのコミットされたトランザクションをディストリビューションデータベースに送信します。長時間実行アクティブトランザクションがコミットされると、レコードが配布データベースに送信され、それまで、パブリッシャーDBのトランザクションログファイルの非アクティブな部分がクリアされないため、パブリッシャーデータベースのトランザクションログファイルのサイズが大きくなります。

    以下の手順を実行することで、長時間実行されるアクティブトランザクションシナリオをテストできます。

    デフォルトでは、Distribution Agentはサブスクライバーデータベースにコミットされたすべての変更をクリーンアップし、ログシーケンス番号(LSN)に基づいて新しい変更を監視するために最後のレコードを保持します。

    以下のクエリを実行して、 MSRepl_Commandsで使用可能なレコードのステータスを確認できます。 テーブルまたはsp_browsereplcmdsの使用 ディストリビューションデータベースの手順:

    exec sp_browsereplcmds
    GO
    SELECT * FROM MSrepl_commands
    

    次に、新しいクエリウィンドウを開き、以下のスクリプトを実行して、 AdventureWorksで長時間実行されるアクティブなトランザクションを作成します。 データベース。以下のスクリプトには、ROLLBACKまたはCOMMITTRANSACTIONコマンドが含まれていないことに注意してください。したがって、これらの種類のコマンドを本番データベースで実行しないことをお勧めします。

    BEGIN TRANSACTION 
    
    SET IDENTITY_INSERT Person.ContactType ON;
    insert into person.ContactType (ContactTypeId, Name, ModifiedDate) values ( 22, 'Test New Position', GETDATE());
    SET IDENTITY_INSERT Person.ContactType OFF;
    

    この新しいレコードがサブスクライバデータベースに複製されていないことを確認できます。そのために、 Person.ContactTypeに対してSELECTステートメントを実行します。 サブスクライバーデータベースのテーブル:

    上記のINSERTコマンドがLogReaderAgentによって読み取られ、ディストリビューションデータベースに書き込まれたかどうかを確認しましょう。

    手順1の部分のスクリプトを再度実行してください。結果には同じ古いステータスが引き続き表示され、パブリッシャーデータベースのトランザクションログからレコードが読み取られなかったことが確認されます。

    次に、新しいクエリを開きます ウィンドウを開き、以下のUPDATEスクリプトを実行して、ログリーダーエージェントが長時間実行されているアクティブなトランザクションをスキップし、このUPDATEステートメントによって行われた変更を読み取ることができたかどうかを確認します。

    UPDATE AdventureWorks.dbo.AWBuildVersion
    SET ModifiedDate  = GETDATE()
    

    LogReaderAgentがこの変更をキャプチャできるかどうかをディストリビューションデータベースで確認します。ステップ1の一部としてスクリプトを実行します:

    上記のUPDATEステートメントはPublisherデータベースでコミットされているため、Log Reader Agentはこの変更をスキャンして、ディストリビューションデータベースに挿入できます。その後、以下に示すように、この変更をサブスクライバーデータベースに適用しました。

    Person.ContactTypeに挿入します INSERTトランザクションがパブリッシャーデータベースでコミットされた後にのみ、サブスクライバーデータベースにレプリケートされます。コミットする前に、長時間実行アクティブトランザクションを識別して理解し、効率的に処理する方法をすばやく確認できます。

    実行時間の長いアクティブなトランザクションを特定する

    データベースで長時間実行されているアクティブなトランザクションを確認するには、新しいクエリウィンドウを開きます。 確認する必要のあるそれぞれのデータベースに接続します。 DBCC OPENTRANを実行します consoleコマンド–実行時にデータベースで開いているトランザクションを表示するためのデータベースコンソールコマンドです。

    USE AdventureWorks
    GO
    DBCC OPENTRAN
    

    これで、 SPIDがあったことがわかりました。 サーバープロセスID )69が長時間実行されています。 DBCC INPUTBUFFER を使用して、そのトランザクションで実行されたコマンドを確認しましょう。 consoleコマンド(選択したサーバープロセスIDで実行されているコマンドまたは操作を識別するために使用されるデータベースコンソールコマンド)。

    読みやすくするために、 EventInfoをコピーしています。 フィールド値とそれをフォーマットして、以前に実行したコマンドを表示します。

    選択したデータベースに長時間実行中のアクティブなトランザクションがない場合は、次のメッセージが表示されます。

    DBCC OPENTRANに似ています コンソールコマンド、 SELECT DMVから 名前付きsys.dm_tran_database_transactions より詳細な結果を取得するには(詳細については、MSDNの記事を参照してください)。

    これで、長時間実行トランザクションを識別する方法がわかりました。トランザクションをコミットして、INSERTステートメントがどのように複製されるかを確認できます。

    Person.ContactTypeにレコードを挿入したウィンドウに移動します トランザクションスコープ内のテーブルを作成し、以下に示すようにCOMMITTRANSACTIONを実行します。

    COMMIT TRANSACTIONを実行すると、レコードがパブリッシャーデータベースにコミットされました。したがって、ディストリビューションデータベースとサブスクライバーデータベースに表示されるはずです。

    お気づきの方もいらっしゃると思いますが、ディストリビューションデータベースの古いレコードは、ディストリビューションエージェントのクリーンアップジョブによってクリーンアップされました。 Person.ContactTypeでのINSERTの新しいレコード テーブルはMSRepl_cmdsに表示されていました テーブル。

    テストから、次のことを学びました。

    • SQLServerトランザクションレプリケーションのログリーダーエージェントジョブは、パブリッシャーデータベースのトランザクションログからのみコミットされたレコードをスキャンし、サブスクライバーデータベースに挿入します。
    • サブスクライバーに送信されるパブリッシャーデータベース上の変更されたデータの順序は、レプリケートされたデータがパブリッシャーデータベースと同じ時間であっても、パブリッシャーデータベースのコミット済みステータスと時間に基づきます。
    • 実行時間の長いアクティブなトランザクションを特定すると、パブリッシャー、ディストリビューター、サブスクライバー、または任意のデータベースのトランザクションログファイルの増加を解決するのに役立ちます。

    記事に対する一括SQLINSERT/ UPDATE/DELETE操作

    パブリッシャーデータベースに巨大なデータが存在するため、複製されたテーブルに巨大なレコードを挿入、更新、または削除する必要が生じることがよくあります。

    INSERT、UPDATE、またはDELETE操作が単一のトランザクションで実行される場合、それは間違いなくレプリケーションが長時間スタックすることになります。

    レプリケートされたテーブルに1,000万レコードを挿入する必要があるとします。これらのレコードを1回のショットで挿入すると、パフォーマンスの問題が発生します。

    INSERT INTO REplicated_table
    SELECT * FROM Source_table
    

    代わりに、 WHILEに0.1または50万レコードのバッチでレコードを挿入できます。 ループ またはCURSORループ 、そしてそれはより速い複製を確実にします。関連するテーブルに多くのインデックスがない限り、INSERTステートメントで大きな問題が発生しない可能性があります。ただし、これにより、UPDATEまたはDELETEステートメントのパフォーマンスが大幅に低下します。

    約1,000万レコードのReplicateテーブルに新しい列を追加したと仮定します。この新しい列をデフォルト値で更新します。

    理想的には、以下のコマンドが正常に機能して、デフォルト値が Abcの1,000万レコードすべてを更新します。 :

    -- UPDATE 10 Million records on Replicated Table with some DEFAULT values
    UPDATE Replicated_table
    SET new_column = 'Abc'
    

    ただし、レプリケーションへの影響を回避するには、パフォーマンスの問題を回避するために、上記のUPDATE操作を0.1または50万レコードのバッチで実行する必要があります。

    -- UPDATE in batches to avoid performance impacts on Replication
    WHILE 1 = 1
    BEGIN
    	UPDATE TOP(100000) Replicated_Table
    	SET new_Column = 'Abc'
    	WHERE new_column is NULL
    
    	IF @@ROWCOUNT = 0
    	BREAK
    END
    

    同様に、レプリケートされたテーブルから約1,000万件のレコードを削除する必要がある場合は、バッチで削除できます。

    -- DELETE 10 Million records on Replicated Table with some DEFAULT values
    DELETE FROM Replicated_table
    
    -- UPDATE in batches to avoid performance impacts on Replication
    WHILE 1 = 1
    BEGIN
    	DELETE TOP(100000) Replicated_Table
    
    	IF @@ROWCOUNT = 0
    	BREAK
    END
    

    BULK INSERT、UPDATE、またはDELETEを効率的に処理すると、レプリケーションの問題を解決するのに役立ちます。

    プロのヒント :Publisherデータベースのレプリケートテーブルに巨大なデータを挿入するには、SSMSのIMPORT / EXPORTウィザードを使用します。これにより、10000のバッチで、またはSQLServerによってより高速に計算されたレコードサイズに基づいてレコードが挿入されます。

    単一のトランザクション内での大量のデータ変更

    アプリケーションまたは開発の観点からデータの整合性を維持するために、多くのアプリケーションでは、重要な操作に対して明示的なトランザクションが定義されています。ただし、単一のトランザクションスコープ内で多くの操作(INSERT、UPDATE、またはDELETE)が実行される場合、前述のように、ログリーダーエージェントは最初にトランザクションが完了するのを待ちます。

    トランザクションがアプリケーションによってコミットされると、ログリーダーエージェントは、パブリッシャーデータベースのトランザクションログで実行されたこれらの膨大なデータ変更をスキャンする必要があります。そのスキャン中に、ログリーダーエージェントに警告または情報メッセージが表示されます。

    ログリーダーエージェントは、複製されるコマンドのトランザクションログをスキャンしています。パス#xxxxで約xxxxxxのログレコードがスキャンされ、そのうちレプリケーションのマークが付けられました。経過時間xxxxxxxxx(ms)

    このシナリオの解決策を特定する前に、ログリーダーエージェントがトランザクションログからレコードをスキャンし、レコードをディストリビューションデータベースに挿入する方法を理解する必要があります MSrepl_transactions およびMSrepl_cmds テーブル。

    SQL Serverの内部には、トランザクションログ内にログシーケンス番号(LSN)があります。 Log Reader Agentは、LSN値を使用して、SQLServerレプリケーション用にマークされた変更を順番にスキャンします。

    LogReaderAgentはsp_replcmdsを実行します パブリッシャーデータベースのトランザクションログからレプリケーション用にマークされたコマンドをフェッチするための拡張ストアドプロシージャ。

    Sp_replcmds @maxtransという名前の入力パラメータを受け入れます トランザクションの最大数をフェッチします。デフォルト値は1です。これは、ログから利用可能なトランザクションの数をスキャンして、ディストリビューションデータベースに送信することを意味します。単一のトランザクションを介して実行され、パブリッシャーデータベースでコミットされたINSERT操作が10個ある場合、単一のバッチに10個のコマンドを含む1個のトランザクションが含まれる可能性があります。

    少ないコマンドで多くのトランザクションが識別された場合、ログリーダーエージェントは複数のトランザクションまたは XACT を結合します 単一のレプリケーションバッチへのシーケンス番号。ただし、別の XACTとして保存されます シーケンス 番号 MSRepl_transactions テーブル。そのトランザクションに属する個々のコマンドは、 MSRepl_commandsにキャプチャされます。 テーブル。

    上記で説明したことを確認するために、 ModifiedDateを更新しています。 dbo.AWBuildVersionの列 今日の日付の表を作成して、何が起こるかを確認してください:

    UPDATE AdventureWorks.dbo.AWBuildVersion
    SET ModifiedDate  = GETDATE()
    

    UPDATEを実行する前に、 MSrepl_commandsに存在するレコードを確認します。 およびMSrepl_transactions テーブル:

    次に、上記のUPDATEスクリプトを実行し、これら2つのテーブルに存在するレコードを確認します。

    UPDATE時刻の新しいレコードがMSrepl_transactionsに挿入されました 近くのentry_timeのあるテーブル 。このxact_seqnoのコマンドを確認します sp_browsereplcmdsを使用して論理的にグループ化されたコマンドのリストを表示します 手順。

    レプリケーションモニターでは、パブリッシャーからディストリビューターへの1つのコマンドで1つのトランザクションの下でキャプチャされた単一のUPDATEステートメントを確認できます。

    また、同じコマンドがディストリビューターからサブスクライバーにわずか1秒の差で配信されていることがわかります。これは、レプリケーションが適切に行われていることを示しています。

    ここで、1つの xact_seqnoに結合された膨大な数のトランザクションがある場合 5000個のコマンドを含む10個のトランザクションが配信されたなどのメッセージを確認できます。 。

    2つの異なるテーブルで同時にUPDATEを実行して、これを確認しましょう。

    MSrepl_transactionsに2つのトランザクションレコードが表示されます 2つのUPDATE操作に一致するテーブルとno。そのテーブル内のレコードの数に一致します。更新されたレコードの数。

    MSrepl_transactionsの結果 テーブル:

    MSrepl_commandsの結果 テーブル:

    ただし、これら2つのトランザクションは、ログリーダーエージェントによって論理的にグループ化され、109225コマンドを使用して2つのトランザクションとして1つのバッチに結合されていることに気付きました。

    ただし、その前に、複製されたトランザクションの配信、xactカウント:1、コマンドカウント46601などのメッセージが表示される場合があります。 。

    これは、ログリーダーエージェントが変更の完全なセットをスキャンし、2つのUPDATEトランザクションがトランザクションログから完全に読み取られたことを識別するまで発生します。

    コマンドがトランザクションログから完全に読み取られると、109225コマンドを使用した2つのトランザクションがログリーダーエージェントによって配信されたことがわかります。

    ディストリビューションエージェントは巨大なトランザクションが複製されるのを待っているため、複製されたトランザクションの配信のようなメッセージが表示される場合があります。 複製される巨大なトランザクションがあったことを示しており、完全に複製されるのを待つ必要があります。

    複製されると、ディストリビューションエージェントにも以下のメッセージが表示されます。

    これらの問題を解決するには、いくつかの方法が役立ちます。

    方法1:新しいSQLストアドプロシージャを作成する

    新しいストアドプロシージャを作成し、トランザクションのスコープ内でアプリケーションロジックをカプセル化する必要があります。

    作成したら、そのストアドプロシージャの記事をレプリケーションに追加し、記事のプロパティReplicateをストアドプロシージャの実行に変更します。 オプション。

    発生していた個々のデータの変更をすべて複製するのではなく、サブスクライバーでストアドプロシージャの記事を実行するのに役立ちます。

    ストアドプロシージャの実行の方法を確認しましょう 複製のオプションは、複製の負荷を軽減します。そのために、以下に示すようにテストストアドプロシージャを作成できます。

    CREATE procedure test_proc
    AS
    BEGIN
    UPDATE AdventureWorks.dbo.AWBuildVersion
    SET ModifiedDate  = GETDATE()
    
    UPDATE TOP(10) Production.TransactionHistoryArchive
    SET ModifiedDate  = GETDATE()
    
    UPDATE TOP(10) Person.Person
    SET ModifiedDate  = GETDATE()
    END
    

    上記の手順により、 AWBuildVersionの単一のレコードが更新されます。 Production.TransactionHistoryArchiveのテーブルと10個のレコード およびPerson.Person 合計21件のレコード変更を行うテーブル。

    パブリッシャーとサブスクライバーの両方でこの新しいプロシージャを作成した後、それをレプリケーションに追加します。そのためには、パブリケーションを右クリックします デフォルトのストアドプロシージャ定義のみを使用して、レプリケーションのプロシージャ記事を選択します。 オプション。

    完了すると、 MSrepl_transactionsで利用可能なレコードを確認できます。 およびMSrepl_commands テーブル。

    それでは、Publisherデータベースで手順を実行して、追跡されているレコードの数を確認しましょう。

    分布テーブルで次のことがわかりますMSrepl_transactions およびMSrepl_commands

    3つのxact_seqno MSrepl_transactionsの3つのUPDATE操作用に作成されました テーブル、および21個のコマンドが MSrepl_commandsに挿入されました テーブル。

    Replication Monitorを開き、それらが3つの異なるレプリケーションバッチとして送信されるのか、3つのトランザクションが一緒に含まれる単一のバッチとして送信されるのかを確認します。

    3つのxact_seqno 単一のレプリケーションバッチとして統合されました。したがって、21個のコマンドを使用した3つのトランザクションが正常に配信されたことがわかります。

    レプリケーションからプロシージャを削除し、2番目のストアドプロシージャの実行で再度追加してみましょう。 オプション。次に、手順を実行して、レコードがどのように複製されるかを確認します。

    配布テーブルからレコードを確認すると、以下の詳細が表示されます。

    次に、Publisherデータベースで手順を実行し、配布テーブルに記録されているレコードの数を確認します。プロシージャを実行すると、以前と同様に21レコード(1レコード、10レコード、および10レコード)が更新されました。

    配布テーブルを確認すると、以下のデータが表示されます。

    sp_browsereplcmdsをざっと見て、実際に受信したコマンドを確認しましょう。

    コマンドは“ {call“ dbo”。” test_proc”}” これはサブスクライバーデータベースで実行されます。

    レプリケーションモニターでは、1つのコマンドを含む1つのトランザクションのみがレプリケーションを介して配信されたことがわかります。

    テストケースでは、21のデータ変更のみの手順を使用しました。ただし、何百万もの変更を伴う複雑な手順に対してこれを行う場合は、ストアドプロシージャの実行を使用したスト​​アドプロシージャアプローチを使用します。 オプションは、レプリケーションの負荷を軽減するのに効率的です。

    プロシージャに、パブリッシャーデータベースとサブスクライバーデータベースの同じレコードセットのみを更新するロジックがあるかどうかを確認することにより、このアプローチを検証する必要があります。そうしないと、パブリッシャーとサブスクライバー間でデータの不整合の問題が発生します。

    方法2:MaxCmdsInTran、ReadBatchSize、およびReadBatchThresholdログリーダーエージェントパラメーターの構成

    MaxCmdsInTran –パブリッシャーデータベースのトランザクションログからデータを読み取り、ディストリビューションデータベースに書き込むときに、トランザクション内で論理的にグループ化できるコマンドの最大数を示します。

    以前のテストでは、約109225個のコマンドが単一のレプリケーションの正確なシーケンスに蓄積され、わずかな速度低下または遅延が発生することに気付きました。 MaxCmdsInTranを設定した場合 パラメータを10000に設定し、単一の正確なシーケンス 番号は11に分割されます xactシーケンスにより、パブリッシャーからディストリビューターへのコマンドの配信が高速化されます 。このオプションは、ディストリビューションデータベースの競合を減らし、パブリッシャーからサブスクライバーデータベースへのデータの複製を高速化するのに役立ちますが、このオプションを使用するときは注意が必要です。元のトランザクションスコープが終了する前に、サブスクライバデータベースにデータを配信し、サブスクライバデータベーステーブルからデータにアクセスすることになる可能性があります。

    ReadBatchSize –このパラメーターは、単一の巨大なトランザクションシナリオには役立たない場合があります。ただし、パブリッシャーデータベースで発生する小規模なトランザクションが多数ある場合に役立ちます。

    トランザクションあたりのコマンド数が少ない場合、ログリーダーエージェントは複数の変更を1つのレプリケーションコマンドトランザクションスコープに結合します。読み取りバッチサイズは、ディストリビューションデータベースに変更を送信する前にトランザクションログで読み取ることができるトランザクションの数を示します。値は500から10000の間です。

    ReadBatchThreshold –完全なログファイルをスキャンするためにデフォルト値0でサブスクライバーに送信される前に、パブリッシャーデータベースのトランザクションログから読み取られるコマンドの数を示します。ただし、この値を10000または100000コマンドに制限することで、この値を減らしてデータをより高速に送信できます。

    方法3:SubscriptionStreamsパラメーターの最適な値を構成する

    サブスクリプションストリーム –ディストリビューション・エージェントがディストリビューション・データベースからデータをフェッチし、それをサブスクライバー・データベースに伝搬するために並行して実行できる接続の数を示します。デフォルト値は1で、ディストリビューションからサブスクライバデータベースへのストリームまたは接続が1つだけであることを示します。値は1〜64のいずれかです。サブスクリプションストリームをさらに追加すると、CXPACKET輻輳が発生する可能性があります。 (言い換えれば、並列処理)。したがって、本番環境でこのオプションを構成するときは注意が必要です。

    要約すると、単一のトランザクションで巨大なINSERT、UPDATE、またはDELETEを回避してみてください。これらの操作を排除できない場合は、上記の方法をテストし、特定の条件に最も適した方法を選択するのが最善の方法です。

    ディストリビューションデータベースのブロック

    ディストリビューションデータベースはSQLServerトランザクションレプリケーションの中心であり、適切に維持されていないと、多くのパフォーマンスの問題が発生します。

    ディストリビューションデータベースの構成に推奨されるすべてのプラクティスを要約するには、以下の構成が適切に行われていることを確認する必要があります。

    1. 配布データベースのデータファイルは、高IOPSドライブに配置する必要があります。パブリッシャーデータベースに大量のデータ変更がある場合は、ディストリビューションデータベースがIOPSの高いドライブに配置されていることを確認する必要があります。ログリーダーエージェントから継続的にデータを受信し、ディストリビューションエージェントを介してサブスクライバーデータベースにデータを送信します。レプリケートされたすべてのデータは、ディストリビューションクリーンアップジョブを介して10分ごとにディストリビューションデータベースから削除されます。
    2. ディストリビューターデータベースの初期ファイルサイズと自動拡張プロパティを、パブリッシャーデータベースのアクティビティレベルに基づいた推奨値で構成します。そうしないと、データとログファイルの断片化が発生し、パフォーマンスの問題が発生します。
    3. ディストリビューションデータベースが配置されているサーバーで構成されている通常のインデックスメンテナンスジョブにディストリビューションデータベースを含めます。
    4. 特定の問題のトラブルシューティングを行うために、完全バックアップジョブのスケジュールに配布データベースを含めます。
    5. 配布のクリーンアップ:配布を確認します デフォルトのスケジュールに従って、ジョブは10分ごとに実行されます。そうしないと、ディストリビューションデータベースのサイズが増え続け、パフォーマンスの問題が発生します。

    これまでに気付いたように、ディストリビューションデータベースでは、関連する主要なテーブルは MSrepl_transactions およびMSrepl_commands 。レコードは、ログリーダーエージェントジョブによって挿入され、配布エージェントジョブによって選択され、サブスクライバデータベースに適用されてから、配布クリーンアップエージェントジョブによって削除またはクリーンアップされます。

    ディストリビューションデータベースが適切に構成されていないと、これら2つのテーブルでセッションがブロックされ、SQLServerレプリケーションのパフォーマンスの問題が発生する可能性があります。

    以下のクエリを任意のデータベースで実行して、SQLServerの現在のインスタンスで使用可能なブロッキングセッションを表示できます。

    SELECT * 
    FROM sys.sysprocesses
    where blocked > 0
    order by waittime desc
    

    上記のクエリで結果が返された場合は、 DBCC INPUTBUFFER(spid)を実行することで、ブロックされたセッションのコマンドを特定できます。 コンソールコマンドを実行し、それに応じてアクションを実行します。

    汚職関連の問題

    SQL Serverデータベースは、そのアルゴリズムまたはロジックを使用してデータをテーブルに格納し、エクステントまたはページに保持します。データベースの破損は、データベース関連のファイル/エクステント/ページの物理的な状態が通常の状態から不安定な状態または非取得状態に変化し、データの取得が困難または不可能になるプロセスです。

    すべてのSQLServerデータベースは、データベースが破損する傾向があります。原因は次のとおりです。

    • ディスク、ストレージ、コントローラーの問題などのハードウェア障害。
    • パッチの問題などのサーバーOSの障害;
    • サーバーの突然のシャットダウンまたはデータベースの不適切なシャットダウンにつながる電源障害。

    データを失うことなくデータベースをリカバリまたは修復できれば、SQLServerレプリケーションは影響を受けません。ただし、破損したデータベースの回復または修復中にデータが失われた場合は、以前の記事で説明した多くのデータ整合性の問題が発生し始めます。

    破損は、次のようなさまざまなコンポーネントで発生する可能性があります。

    • パブリッシャーデータ/ログファイルの破損
    • サブスクライバーデータ/ログファイルの破損
    • 配布データベースデータ/ログファイルの破損
    • Msdbデータベースデータ/ログファイルの破損

    If we receive a lot of data integrity issues after fixing up Corruption issues, it is recommended to remove the Replication completely, fix all Corruption issues in the Publisher, Subscriber, or Distributor database and then reconfigure Replication to fix it. Otherwise, data integrity issues will persist and lead to data inconsistency across the Publisher and Subscriber. The time required to fix the Data integrity issues in case of Corrupted databases will be much more compared to configuring Replication from scratch. Hence identify the level of Corruption encountered and take optimal decisions to resolve the Replication issues faster.

    Wondering why msdb database corruption can harm Replication? Since msdb database hold all details related to SQL Server Agent Jobs including Replication Agent jobs, any corruption on msdb database will harm Replication. To recover quickly from msdb database corruptions, it is recommended to restore msdb database from the last Full Backup of msdb database. This also signifies the importance of taking Full Backups of all system databases including msdb database.

    結論

    Thanks for successfully going through the final power-packed article about the Performance issues in the SQL Server Transactional Replication. If you have gone through all articles carefully, you should be able to troubleshoot almost any Transactional Replication-based issues and fix them out efficiently.

    If you need any further guidance or have any Transactional Replication-related issues in your environment, you can reach out to me for consultation. And if I missed anything essential in this article, you are welcome to point to that in the Comments section.


    1. 動的ファイル名でコピー

    2. VDP AdvancedSQLAgentを使用したSQLデータベースのバックアップ

    3. SQL Serverで「time」を「smalldatetime」に変換する(T-SQLの例)

    4. PostgreSQLのトレンド:エンタープライズで最も人気のあるクラウドプロバイダー、言語、VACUUM、クエリ管理戦略、導入タイプ