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

SQLServerトランザクションレプリケーションの問題のトラブルシューティング

    SQL Serverトランザクションレプリケーションは、複数の宛先にデータをコピーまたは配布するために使用される最も一般的なレプリケーション手法の1つです。

    以前の記事では、SQL Serverレプリケーション、それが内部でどのように機能するか、およびレプリケーションウィザードまたはT-SQLアプローチを介してレプリケーションを構成する方法について説明しました。ここでは、SQLレプリケーションの問題とそれらの正しいトラブルシューティングに焦点を当てます。

    SQLレプリケーションの問題

    SQL Server Transactional Replicationを使用する顧客の大多数は、主にサブスクライバーデータベースインスタンスで利用可能なほぼリアルタイムのデータを実現することに重点を置いています。したがって、レプリケーションを管理するDBAは、発生する可能性のあるさまざまなSQLレプリケーション関連の問題を認識している必要があります。また、DBAはこれらの問題を短時間で解決できる必要があります。

    すべてのSQLレプリケーションの問題を以下のカテゴリに分類できます(私の経験に基づく):

    構成の問題

    • 最大テキストレプリケーションサイズ
    • SQLServerエージェントサービスが自動モードを開始するように設定されていません
    • 監視されていないレプリケーションインスタンスは、初期化されていないサブスクリプション状態になります
    • SQLServer内の既知の問題

    権限の問題

    • SQLServerエージェントのジョブ権限の問題
    • スナップショットエージェントのジョブクレデンシャルがスナップショットフォルダのパスにアクセスできません
    • ログリーダーエージェントのジョブクレデンシャルがパブリッシャー/ディストリビューションデータベースに接続できません
    • ディストリビューションエージェントのジョブクレデンシャルがディストリビューション/サブスクライバーデータベースに接続できません

    接続の問題

    • パブリッシャーサーバーが見つからないか、アクセスできませんでした
    • 配信サーバーが見つからないか、アクセスできませんでした
    • サブスクライバーサーバーが見つからないか、アクセスできませんでした

    データの整合性の問題

    • 主キーまたは一意キー違反エラー
    • 行が見つかりませんエラー
    • 外部キーまたはその他の制約違反エラー

    パフォーマンスの問題

    • パブリッシャーデータベースで実行されているアクティブなトランザクション
    • 記事に対する一括INSERT/UPDATE/DELETE操作
    • 1回のトランザクションで大量のデータが変更される
    • ディストリビューションデータベースのブロック

    汚職関連の問題

    • パブリッシャーデータベースの破損
    • パブリッシャートランザクションログファイルの破損
    • ディストリビューションデータベースの破損
    • サブスクライバーデータベースの破損

    デモ環境の準備

    SQLレプリケーションの問題について詳しく説明する前に、デモ用の環境を準備する必要があります。以前の記事で説明したように、トランザクションレプリケーションのサブスクライバーデータベースで発生したデータの変更は、パブリッシャーデータベースに直接表示されません。したがって、学習目的でサブスクライバーデータベースに直接特定の変更を加えます。

    細心の注意を払い、本番データベースでは何も変更しないでください。これは、サブスクライバーデータベースのデータ整合性に影響を与えます。実行されたすべての変更のバックアップスクリプトを取得し、それらのスクリプトを使用してSQLレプリケーションの問題を修正します。

    変更1-Person.ContactTypeテーブルへのレコードの挿入

    Person.ContacTypeにレコードを挿入する前 テーブル、そのテーブル構造、いくつかのデフォルトの制約、および以下のスクリプトで編集された拡張プロパティを見てみましょう。

    CREATE TABLE [Person].[ContactType](
    	[ContactTypeID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
    	[Name] [dbo].[Name] NOT NULL,
    	[ModifiedDate] [datetime] NOT NULL,
     CONSTRAINT [PK_ContactType_ContactTypeID] PRIMARY KEY CLUSTERED 
    (
    	[ContactTypeID] ASC
    ) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    

    列が少ないため、このテーブルを選択しました。テスト目的にはより便利です。それでは、その構造について私たちが得たものを確認しましょう:

    • ContactTypeId IDENTITY COLUMNとして定義されます–プライマリキー値を自動生成し、複製用ではありません。
    • NOT FOR REPLICATIONは、テーブル、外部キー制約などの制約、チェック制約、トリガー、パブリッシャーまたはサブスクライバーのID列などのさまざまなオブジェクトタイプで、レプリケーション方法のいずれかのみを使用して使用できる特別なプロパティです。これにより、DBAはレプリケーションを計画または実装して、レプリケーションの使用中にパブリッシャー/サブスクライバーで特定の機能が異なる動作をするようにすることができます。
    • この場合、Publisherデータベースでのみ生成されたIDENTITY値を使用するようにSQLServerに指示します。 IDENTITYプロパティは、 Person.ContactTypeでは使用しないでください。 サブスクライバデータベースのテーブル。同様に、このオプションを使用してレプリケーションが構成されている間、制約またはトリガーを変更して、それらが異なる動作をするようにすることができます。
    • 他の2つのNOTNULL列がテーブルで使用可能です。
    • テーブルには、 ContactTypeIdで定義された主キーがあります 。思い出してください。主キーはレプリケーションの必須要件です。テーブルにそれがないと、テーブルの記事を複製することはできません。

    それでは、サンプルレコードを Personに挿入しましょう。 。ContactType AdventureWorks_REPLのテーブル データベース:

    Identityプロパティはレプリケーションでのみ無効になっているため、テーブルの直接INSERTはサブスクライバデータベースで失敗します。 NOTFORREPLICATIONオプションによる。 INSERT操作を手動で実行する場合は常に、次のようにSETIDENTITY_INSERTオプションを使用する必要があります。

     SET IDENTITY_INSERT AdventureWorks_REPL.Person.ContactType ON;
    
     INSERT INTO AdventureWorks_REPL.Person.ContactType(ContactTypeID, Name, ModifiedDate)
     VALUES (21, 'Test Position', GETDATE())
    SET IDENTITY_INSERT AdventureWorks_REPL.Person.ContactType OFF;
    

    SET IDENTITY_INSERTオプションを追加すると、レコードを Person.ContactTypeに正常に挿入できます。 テーブル。

    テーブルでSELECTを実行すると、新しく挿入されたレコードが表示されます。

    Person.ContactType のPublisherデータベースでは利用できない、Subscriberデータベースにのみ新しいレコードを追加しました。 テーブル。

    Publisherデータベースの同じテーブルでSELECTを実行しても、レコードは表示されません。したがって、サブスクライバデータベースで行われた変更は、パブリッシャデータベースに複製されません。

    変更2–Person.ContactTypeテーブルから2つのレコードを削除する

    おなじみのPerson.ContactType テーブル。サブスクライバーデータベースからレコードを削除する前に、それらのレコードがパブリッシャーとサブスクライバーの両方に存在するかどうかを確認する必要があります。以下を参照してください:

    これで、これら2つの ContactTypeIdを削除できます。 次のステートメントを使用します:

    DELETE FROM AdventureWorks_REPL.Person.ContactType
    WHERE ContactTypeID IN (19,20)
    

    上記のスクリプトを使用すると、 Person.ContactTypeから2つのレコードを削除できます。 サブスクライバーデータベースのテーブル:

    Person.ContactTypeからこれら2つのレコードを削除できないようにする外部キー参照があります。 テーブル。このシナリオは、子テーブルの外部キー制約を一時的に無効にすることで処理できます。スクリプトは以下のとおりです:

    ALTER TABLE [Person].[BusinessEntityContact] NOCHECK CONSTRAINT [FK_BusinessEntityContact_ContactType_ContactTypeID];

    外部キーを無効にすると、 Person.ContactTypeからレコードを正常に削除できます。 テーブル:

    これにより、2つのテーブル間の外部キー参照制約も変更されました。このシナリオに基づいて、SQLレプリケーションの問題をシミュレートすることができます。

    現在のシナリオでは、 Person.ContactType テーブルには、パブリッシャーとサブスクライバー間で同期されたデータがありませんでした。

    私を信じてください。いくつかの実稼働環境では、開発者またはDBAがサブスクライバーデータベースでいくつかのデータ修正を行います。以前に実行したすべての変更と同様に、同じテーブル内のパブリッシャーデータベースとサブスクライバーデータベース全体でデータの整合性の問題が発生しました。 DBAとして、私はこれらの種類の不一致を検証するためのより単純なメカニズムが必要です。そうでなければ、DBAの人生は哀れなものになります。

    これが、パブリッシャーとサブスクライバーのテーブル間のデータの不一致を検証できるMicrosoftのソリューションです。はい、あなたはそれを正しく推測しました。これは、以前の記事で説明したTableDiffユーティリティです。

    TableDiffユーティリティ

    TableDiffユーティリティは、主にレプリケーション環境で使用されます。 2つのSQLServerテーブルを非収束について比較する必要がある他の場合にも使用できます。それらを比較して、これら2つのテーブルの違いを特定できます。次に、ユーティリティは宛先の同期に役立ちます テーブル ソーステーブル 必要なINSERT/UPDATE/DELETEスクリプトを生成します。

    TableDiffは、レプリケーションコンポーネントをインストールすると、デフォルトでC:\ Program Files \ Microsoft SQL Server \ 130\COMにインストールされるスタンドアロンプ​​ログラムtablediff.exeです。デフォルトのパスは、SQLServerのインストールパラメータによって異なる場合があることに注意してください。パス内の数字130は、SQL Serverのバージョン(SQL Server 2016)を示します。したがって、SQLServerインストールのバージョンごとに異なります。

    TableDiffユーティリティには、コマンドプロンプトを介して、またはバッチファイルからのみアクセスできます。ユーティリティには、使用するための凝ったウィザードやGUIがありません。 TableDiffユーティリティの詳細な構文は、MSDNの記事にあります。現在の記事では、いくつかの必要なオプションのみに焦点を当てています。

    TableDiffユーティリティを使用して2つのテーブルを比較するには、ソースサーバー名、ソースデータベース名、ソーススキーマ名、ソーステーブル名、宛先サーバー名、宛先データベース名、宛先など、ソーステーブルと宛先テーブルの必須の詳細を提供する必要があります。スキーマ名と宛先テーブル名。

    Person.ContactTypeを使用してTableDiffをテストしてみましょう パブリッシャーとサブスクライバーで違いがあるテーブル。

    コマンドプロンプトを開き、TableDiffユーティリティパスに移動します(そのパスが環境変数に追加されていない場合)。

    使用可能なすべてのパラメーターのリストを表示するには、コマンド「tablediff-?」を入力します。使用可能なすべてのオプションとパラメータを一覧表示します。結果は以下のとおりです。

    Personを確認しましょう。ContactType 以下のコマンドを実行して、パブリッシャーデータベースとサブスクライバーデータベース全体のテーブルを作成します。

    tablediff -sourceserver RRJ -sourcedatabase AdventureWorks -sourceschema Person -sourcetable ContactType -destinationserver RRJ -destinationdatabase AdventureWorks_REPL -destinationschema Person -destinationtable ContactType

    sourceuserを提供していないことに注意してください 、 sourcepassword destinationuser 、および destinationpassword 私のWindowsログインはテーブルにアクセスできるので。 Windows認証の代わりにSQLクレデンシャルを使用する場合は、上記のパラメータは比較のためにテーブルにアクセスするために必須です 。そうしないと、エラーが発生します。

    正しいコマンド実行の結果:

    これは、3つの不一致があることを示しています。 1つは宛先データベースの新しいレコードであり、2つのレコードは宛先データベースでは使用できません。

    それでは、その他を簡単に見てみましょう。 TableDiffユーティリティで使用できるオプション。

    • -et –結果の要約を宛先テーブルに記録します
    • -dt –結果の宛先テーブルがすでに存在する場合は削除します
    • -f –INSERT / UPDATE /DELETEステートメントを使用してT-SQLDMLスクリプトを生成し、宛先テーブルをソーステーブルと収束させます。
    • -o –オプション -fの場合はファイル名を出力します コンバージェンスファイルを生成するために使用されます。

    -fを使用して収束ファイルを作成します および-o 以前のコマンドのオプション:

    tablediff -sourceserver RRJ -sourcedatabase AdventureWorks -sourceschema Person -sourcetable ContactType -destinationserver RRJ -destinationdatabase AdventureWorks_REPL -destinationschema Person -destinationtable ContactType -f -o C:\PersonContactType.sql

    コンバージェンスファイルが正常に作成されました:

    ご覧のとおり、セキュリティ上の理由から、C:ドライブのルートフォルダに新しいファイルを作成することは許可されていません。したがって、エラーメッセージが表示され、出力ファイルDIFFIX。*。sqlファイルが作成されます。 TableDiffユーティリティフォルダにあります。そのファイルを開くと、以下の詳細が表示されます:

    INSERTスクリプトは、削除された2つのレコードに対して作成され、DELETEスクリプトは、サブスクライバーデータベースに新しく挿入されたレコードに対して作成されました。このツールは、宛先の必要に応じてIDENTITY_INSERTオプションを使用することも考慮します。 テーブル。したがって、このツールは、DBAが2つのテーブルを同期する必要がある場合に非常に役立ちます。

    この場合、SQLレプリケーションの問題をシミュレートするためにこれらの差異が必要になるため、スクリプトを実行しません。

    TableDiffユーティリティの利点

    • TableDiffは、テーブルの比較または収束に使用されるSQLServerレプリケーションコンポーネントのインストールの一部として提供される無料のユーティリティです。
    • コンバージェンス作成スクリプトは、手動で介入しなくても作成できます。

    TableDiffユーティリティの制限

    • TableDiffユーティリティは、コマンドプロンプトまたはバッチファイルからのみ実行できます。
    • 複数のテーブルを比較するために複数のコマンドプロンプトを並行して開いていない限り、コマンドプロンプトから一度に実行できるテーブル比較は1つだけです。
    • TableDiffユーティリティを使用して比較する必要のあるソーステーブルには、主キーまたはID列が定義されているか、行ごとの比較を実行するために使用できるROWGUID列が必要です。 -strictの場合 オプションを使用する場合、Destinationテーブルには、主キー、Identity列、または使用可能なROWGUID列も必要です。
    • ソーステーブルまたは宛先テーブルにsql_variantが含まれている場合 データ型列の場合、TableDiffユーティリティを使用して比較することはできません。
    • 巨大なレコードを含むテーブルでTableDiffユーティリティを実行すると、これらのテーブルで行ごとの比較が実行されるため、パフォーマンスの問題に気付く可能性があります。
    • TableDiffユーティリティによって作成された収束スクリプトには、 varchar(max)などのBLOB文字データ型の列は含まれていません。 、 nvarchar(max) varbinary(max)テキスト ntext 、または画像 列、および xml またはタイムスタンプ 列。したがって、これらのデータ型列を持つテーブルを処理するには、別のアプローチが必要です。

    ただし、これらの制限がある場合でも、TableDiffユーティリティを任意のSQL Serverテーブルで使用して、データの検証や収束チェックを迅速に行うことができます。ただし、優れたサードパーティツールを購入することもできます。

    それでは、さまざまなSQLレプリケーションの問題について詳しく見ていきましょう。

    構成の問題

    私の経験から、重大なSQLレプリケーションの問題につながる可能性のある頻繁に見落とされるレプリケーション構成オプションを分類しました。 構成として 問題。それらのいくつかは以下にあります。

    最大テキストレプリケーションサイズ

    最大テキストReplサイズ 最大テキストレプリケーションサイズ(バイト単位)を指します 。 char(max)、nvarchar(max)、varbinary(max)、text、ntext、varbinary、xml、などのすべてのデータ型に適用されます。 および画像

    SQL Serverには、複製される文字列データ型の最大列長(バイト単位)を 65536として制限するデフォルトのオプションがあります。 バイト。

    レプリケーションがデータベース用に構成されている場合は常に、最大テキストReplサイズを慎重に評価する必要があります。そのためには、上記のすべてのデータ型列を確認し、レプリケーションを介して転送される可能性のある最大バイトを特定する必要があります。

    値を-1に変更すると、制限がないことを示します。ただし、文字列の最大長を評価し、その値を構成することをお勧めします。

    SSMSまたはT-SQLを使用して最大テキストReplサイズを構成できます。

    SSMSで、サーバー名を右クリックします>プロパティ >高度な

    65536をクリックするだけです それを変更します。テストでは、65536を1000000に変更し、[ OK]をクリックしました。 :

    T-SQLを介してMaxTextRepl Sizeオプションを構成するには、新しいクエリウィンドウを開き、マスターデータベースに対して次のスクリプトを実行します。

    EXEC sys.sp_configure N'max text repl size (B)', N'-1'
    GO
    RECONFIGURE WITH OVERRIDE
    GO
    

    このクエリにより、レプリケーションは上記のデータ型列のサイズを制限しなくなります。

    確認するために、 sys.configurationsでSELECTを実行できます。 DMVを実行し、 value_in_useを確認します 以下の列:

    SQLServerエージェントサービスが自動モードを開始するように設定されていません

    レプリケーションは、SQLServerエージェントジョブとして実行されるレプリケーションエージェントに依存しています。したがって、一部のSQL Serverエージェントサービスで問題が発生すると、レプリケーション機能に直接影響します。

    SQLServerおよびSQLServerエージェントサービスの開始モードが自動に設定されていることを確認する必要があります。手動に設定されている場合、いくつかのアラートを構成する必要があります。サーバーが計画的または計画外のサービスを再起動したときに、DBAまたはサーバー管理者にSQLServerエージェントサービスを開始するように通知します。

    そうしないと、レプリケーションが長時間実行されない可能性があり、他のSQLServerエージェントジョブにも影響します。

    監視されていないレプリケーションインスタンスが初期化されていないサブスクリプション状態になります

    SQL Serverエージェントサービスの監視と同様に、SQLServerインスタンスでデータベースメールサービスを構成することは、DBAまたは構成された人にタイムリーに警告する上で重要な役割を果たします。ジョブの失敗や問題が発生した場合は、ログリーダーエージェントや配布エージェントなどのSQL Serverエージェントジョブを構成して、DBAまたはそれぞれのチームメンバーに電子メールでアラートを送信できます。 Replication Agentジョブの実行に失敗すると、以下のシナリオが発生する可能性があります。

    ログリーダーエージェントジョブの非実行 。パブリッシャーデータベースのトランザクションログファイルは、コマンドがレプリケーション用にマークされた後にのみ再利用されます。 Log Reader Agentによって読み取られ、ディストリビューションデータベースに正常に送信されます。それ以外の場合、 log_reuse_wait_desc sys.databasesの列 値がレプリケーションとして表示されます。これは、変更がディストリビューションデータベースに正常に転送されるまで、データベースログを再利用できないことを示します。したがって、ログリーダーエージェントを実行しないと、パブリッシャーデータベースのトランザクションログファイルのサイズが大きくなり続け、フルバックアップ中にパフォーマンスの問題が発生したり、パブリッシャーデータベースインスタンスのディスク容量の問題が発生したりします。

    配布エージェントジョブの非実行。 ディストリビューションエージェントジョブは、ディストリビューションデータベースからデータを読み取り、サブスクライバデータベースに送信します。次に、それらのレコードをディストリビューションデータベースで削除するようにマークします。ディストリビューションエージェントジョブが実行されていない場合、ディストリビューションデータベースのサイズが大きくなり、レプリケーション全体のパフォーマンスにパフォーマンスの問題が発生します。デフォルトでは、以下のTransaction Retentionプロパティに示すように、ディストリビューションデータベースは最大0〜72時間のレコードを保持するように構成されています。レプリケーションが72時間以上失敗した場合、対応するサブスクリプションは初期化されていないものとしてマークされ、サブスクリプションを再構成するか、新しいスナップショットを生成してレプリケーションを再度機能させる必要があります。

    配布クリーンアップの非実行:配布ジョブ 。ディストリビューションクリーンアップジョブは、ディストリビューションデータベースから複製されたすべてのレコードを削除して、ディストリビューションデータベースのサイズを制御できるようにします。このジョブを実行しないと、ディストリビューションデータベースのサイズが大きくなり、レプリケーションのパフォーマンスの問題が発生します。

    これらの監視されていない問題に遭遇しないようにするには、データベースメールを構成して、すべてのジョブの失敗または再試行をそれぞれのチームメンバーに報告して迅速に対応する必要があります。

    SQLServer内の既知の問題

    特定のSQLServerバージョンには、RTMバージョンまたはそれ以前のバージョンで既知のレプリケーションの問題がありました。これらの問題は、後続のServicePackまたはCUパックで修正されました。したがって、QA環境でテストした後、すべてのSQLServerで利用可能になった最新のServicePackまたはCUパックを適用することをお勧めします。これはSQLServerを実行しているサーバーの一般的な推奨事項ですが、レプリケーションにも適用できます。

    権限の問題

    SQL Serverトランザクションレプリケーションが構成されている環境では、アクセス許可の問題を頻繁に観察できます。パブリッシャー、ディストリビューター、またはサブスクライバーデータベースインスタンスでのレプリケーション構成またはメンテナンスアクティビティ中にこれらに直面する可能性があります。その結果、資格情報または権限が失われます。ここで、レプリケーションに関連するいくつかの頻繁な権限の問題を観察してみましょう。

    SQLServerエージェントのジョブアクセス許可の問題

    すべてのレプリケーションエージェントはSQLServerエージェントジョブを使用します。スナップショットまたはログリーダーエージェント、または配布に関連する各SQL Serverエージェントジョブは、以下に示すように、いくつかのWindowsまたはSQLログインクレデンシャルの下で実行されます。

    SQL Serverエージェントジョブを開始するには、 SQLAgentOperatorRoleのいずれかを所有している必要があります。 すべてのジョブを開始するか、 SQLAgentUserRole またはSQLAgentReaderRole あなたが所有する仕事を始めるために。正しく開始できなかったジョブがある場合は、ジョブの所有者がそのジョブを実行するために必要な権限を持っているかどうかを確認してください。

    スナップショットエージェントのジョブ資格情報がスナップショットフォルダパスにアクセスできない

    以前の記事では、Snapshotエージェントを実行すると、ローカルまたは共有フォルダーパスに記事のスナップショットが作成され、Distributionエージェントを介してサブスクライバーデータベースに伝達されることに気付きました。スナップショットパスの場所は、パブリケーションプロパティで識別できます。 >スナップショット

    スナップショットエージェントがこのスナップショットファイルの場所にアクセスできない場合、エラーが発生する可能性があります:

    パス「C:\ ProgramFiles \ Microsoft SQL Server \ MSSQL13.MSSQLSERVER \ MSSQL \ repldata \ unc \ XXXX \YYYYMMDDHHMISS\」へのアクセスが拒否されました。

    この問題を解決するには、フォルダパスへの完全なアクセスを許可することをお勧めします C:\ Program Files \ Microsoft SQL Server \ MSSQL13.MSSQLSERVER \ MSSQL \ repldata \ unc \ スナップショットエージェントが実行されるアカウントの場合。この構成では、SQL Serverエージェントアカウントを使用し、SQLServerエージェントサービスはRRJ\RRJアカウントで実行されています。

    ログリーダーエージェントのジョブクレデンシャルがパブリッシャー/ディストリビューションデータベースに接続できません

    Log Reader Agentは、パブリッシャーデータベースに接続して、 sp_replcmdsを実行します。 パブリッシャーデータベースのトランザクションログからレプリケーション用にマークされたトランザクションをスキャンする手順。

    Publisherデータベースのデータベース所有者が適切に設定されていない場合、次のエラーが発生する可能性があります。

    プロセスは「RRJ」で「sp_replcmds」を実行できませんでした。

    または

    プリンシパル「dbo」が存在しないか、このタイプのプリンシパルを偽装できないか、権限がないため、データベースプリンシパルとして実行できません。

    この問題を解決するには、Publisherデータベースのデータベース所有者プロパティが saに設定されていることを確認してください または別の有効なアカウント(以下を参照)。

    パブリッシャーを右クリックします データベース( AdventureWorks )>プロパティ >ファイル 所有者であることを確認してください フィールドはsaに設定されています または有効なログインで空白ではない

    パブリッシャーまたはディストリビューションデータベースに接続しているときにアクセス許可の問題が発生した場合は、ログリーダーエージェントに使用されている資格情報を確認し、それらのデータベースにアクセスするためのアクセス許可を付与します。

    ディストリビューションエージェントのジョブクレデンシャルがディストリビューション/サブスクライバーデータベースに接続できません

    アカウントがディストリビューションデータベースへのアクセスまたはサブスクライバデータベースへの接続を許可されていない場合、ディストリビューションエージェントに権限の問題が発生する可能性があります。この場合、次のエラーが発生する可能性があります。

    手順2の実行を開始できません(理由:プロキシRRJ \ RRJの認証エラー、システムエラー:ユーザー名またはパスワードが正しくありません)

    プロセスはサブスクライバー「RRJ」に接続できませんでした。

    ユーザー「RRJ\RRJ」のログインに失敗しました。

    これを解決するには、サブスクリプションプロパティで使用されているアカウントをチェックし、ディストリビューションデータベースまたはサブスクライバーデータベースに接続するために必要なアクセス許可があることを確認します。

    接続の問題

    通常、トランザクションレプリケーションは、同じネットワーク内のサーバー間または地理的に分散した場所間で構成されます。ディストリビューションデータベースがパブリッシャーまたはサブスクライバーとは別の専用サーバーにある場合、ネットワークパケットの損失(接続の問題)の影響を受けやすくなります。

    このような問題が発生した場合、レプリケーションエージェント(ログリーダーまたはディストリビューションエージェント)は以下のエラーを報告できます。

    パブリッシャーサーバーが見つからないか、アクセスできませんでした

    配信サーバーが見つからないか、アクセスできませんでした

    サブスクライバーサーバーが見つからないか、アクセスできませんでした

    これらの問題のトラブルシューティングを行うために、SSMSのパブリッシャー、ディストリビューター、またはサブスクライバーデータベースに接続して、問題なくこれらのSQLServerインスタンスに接続できるかどうかを確認する場合があります。

    接続の問題が頻繁に発生する場合は、サーバーに継続的にpingを実行して、パケット損失を特定できます。また、必要なチームメンバーと協力してこれらの問題を解決し、Replicationがデータの転送を再開できるようにサーバーを稼働させる必要があります。

    データの整合性の問題

    トランザクションレプリケーションは一方向のメカニズムであるため、サブスクライバーで(手動またはアプリケーションから)発生するデータの変更は、パブリッシャーに反映されません。パブリッシャーとサブスクライバー間でデータの差異が生じる可能性があります。

    データの整合性に関連するこれらの問題を確認し、それらを解決する方法を見てみましょう。 Person.ContactTypeにレコードを挿入したことに注意してください テーブルを作成し、 Person.ContactTypeから2つのレコードを削除しました サブスクライバデータベースのテーブル。これらの3つのレコードを使用して、エラーを見つけます。

    主キーまたは一意キー違反エラー

    Person.ContactTypeでINSERTレコードをテストします テーブル。そのレコードをパブリッシャーデータベースに挿入して、何が起こるか見てみましょう:

    レプリケーションモニターを起動して、その動作を確認します。エラーが発生します:

    パブリッシャーの拡張 および出版物 、次の詳細を取得します:

    レプリケーションアラートを構成し、メールアラートを受信するようにそれぞれの担当者を割り当てた場合、次のエラーメッセージを含む適切な電子メール通知を受信します。一意のインデックス'AK_ContactType_Nameを持つオブジェクト'Person.ContactType'に重複するキー行を挿入できません'重複するキー値は(テスト位置)です。 (ソース:MSSQLServer、エラー番号:2601)

    一意キー違反または主キーの問題に関する問題を解決するために、いくつかのオプションがあります。

    • このエラーが発生した理由、サブスクライバデータベースでレコードがどのように利用可能であったか、および誰がどのような理由でレコードを挿入したかを分析します。必要かどうかを確認します。
    • スキップエラーを追加します エラー番号2601をスキップするディストリビューションエージェントプロファイルのパラメータ またはエラー番号2627 主キー違反の場合。

    この場合、このエラーを受け取るために意図的にデータを挿入しました。この問題を処理するには、手動で挿入されたレコードを削除して、パブリッシャーから受け取った変更の複製を続行します。

    DELETE from Person.ContactType
    where ContactTypeID = 21
    

    他のオプションを調べ、これら2つのアプローチの違いを比較するために、最初のオプション(効率的で推奨)をスキップし、 -skiperrorsを追加して2番目のオプションに進みます。 配布エージェントジョブのパラメータ。

    Distribution Agent Jobを編集することで実装できます。 >手順 >エージェントの実行という名前の2つのジョブステップをクリックします >[編集]をクリックします 使用可能なコマンドを表示するには:

    ここで、 -SkipErrors 2601を追加します。 最後にキーワード(2601はエラー番号です。レプリケーションの一部として受信したエラー番号はスキップできます)を選択し、[ OK]をクリックします。 。

    To make sure that the Distribution job is aware of this configuration change, we need to restart the Distribution agent job. For that, stop it and start again from Step 1 as shown below:

    The Replication Monitor displays that one of the error records is skipped from the Replication, that started working fine.

    Since the Replication issue is resolved successfully, we’d recommend removing the -SkipErrors parameter from the Distribution Agent job. Then, restart the job to get the changes reflected.

    Thus, we’ve fixed the replication issue, but let’s compare the data across the same Person.ContactType in the Publisher and Subscriber databases. The results show the data variance, or the data integrity issue

    ModifiedDate is different across the Publisher and Subscriber databases. It happens because the data in the Subscriber database was inserted earlier (when we were preparing the test data), and the data in the Publisher database has just been inserted.

    If we deleted the record from the Subscriber database, the record from the Publisher would have been inserted to match the data across the Publisher and the Subscriber databases.

    Most of the newbie DBAs simply add the -SkipErrors option to get the replication working immediately without detailed investigations of the issue. Hence, it is recommended not to use the -SkipErrors option as a primary solution without proper examination of the problem. The Person.ContactType table had only 3 columns. Assume that the table has over 20 columns. Then, we have just screwed up the Data integrity of this table with that -SkipErrors コマンド。

    We used this approach just to illustrate the usage of that option. The best way is to examine and clarify the reason for variance and then perform the appropriate DELETE statements on the Subscriber database to maintain the Data Integrity across the Publisher and Subscriber databases.

    Row Not Found Errors

    Let’s try to perform an UPDATE on one of the records that were deleted from the Subscriber database:

    Let’s check the Replication Monitor to see the performance. We have the following error:

    The row was not found at the Subscriber when applying the replicated UPDATE command for Table ‘[Person].[ContactType]’ with Primary Key(s):[ContactTypeID] =19 (Source:MSSQLServer, Error number:20598).

    There are two ways to resolve this error. First, we can use -SkipErrors for Error Number 20598 。 Or, we can INSERT the record with ContactTypeID =19 (shown in the error message) to get the data changes reflected.

    If we skip this error, we’ll lose the record with ContactTypeId =19 from the Subscriber database permanently. It can cause data inconsistency issues. Hence, we aren’t going to use the -SkipErrors オプション。 Instead, we’ll apply the INSERT approach.

    The Replication resumes correctly by sending the UPDATE to the Subscriber database.

    It is the same when we try to delete the ContactTypeId =20 from the Publisher database and see the error popping up in the Replication Monitor.

    The Replication Monitor shows us a message similar to the one we already noticed:

    The row was not found at the Subscriber when applying the replicated DELETE command for Table ‘[Person].[ContactType]’ with Primary Key(s):[ContactTypeID] =20 (Source:MSSQLServer, Error number:20598)

    Similar to the previous error, we need to identify the missing record and insert it back to the Subscriber database for the DELETE statement to get replicated properly. For DELETE scenario, using -SkipErrors doesn’t have any issues but can’t be considered as a safe option, as both missing UPDATE or missing DELETE record are captured with the same error number 20598 and adding -SkipErrors 20598 will skip applying all records from the Subscriber database.

    We can also get more details about the problematic command by using the sp_browsereplcmds stored procedure which we have discussed earlier as well. Let’s try to use sp_browsereplcmds stored procedure for the previous error we have received out as shown below.

    exec sp_browsereplcmds @xact_seqno_start = '0x000000A500001160000600000000'
    			, @xact_seqno_end = '0x000000A500001160000600000000'
    			, @publisher_database_id = 1
    			, @command_id = 1
    

    @xact_seqno_start and @xact_seqno_end will be the same value. We can fetch that value from the Transaction Sequence number in the Replication Monitor along with Command ID.

    @publisher_database_id can be fetched from the id column of the distribution..MSPublisher_databases DMV.

    select * from MSpublisher_databases 

    Foreign Key or Other Constraint Violation Errors

    The error messages related to Foreign keys or any other data issues are slightly different. Microsoft has made these error messages detailed and self-explanatory for anyone to understand what the issue is about.

    To identify the exact command that was executed on the Publisher and resolve it efficiently, we can use the sp_browsereplcmds procedure explained above and identify the root cause of the issue.

    Once the commands are identified as INSERT/UPDATE/DELETE which caused the errors, we can take corresponding actions to resolve the problems correctly which is more efficient compared to simply adding -SkipErrors approach. Once corrective measures are taken, Replication will start resuming fine immediately.

    Word of Caution Using -SkipErrors Option

    Those who are comfortable using -SkipErrors option to resolve error quickly should remember that -SkipErrors option is added at the Distribution agent level and applies to all Published articles in that Publication. Command -SkipErrors will result in skipping any number of commands related to that particular error across all published articles any number of times resulting in discrepancies we have seen in demo resulting in data discrepancies across Publisher and Subscriber without knowing how many tables are having discrepancies and would require efforts to compare the tables and fix it out.

    結論

    Thanks for going through another robust article. I hope it was helpful for you to understand the SQL Server Transactional Replication issues and methods of troubleshooting them. In our next article, we’ll continue the discussion about the SQL Transaction Replication issues, examine other types, such as Corruption-related issues, and learn the best methods of handling them.


    1. mysqlピボット/クロス集計クエリ

    2. Access2016で複数のフィールドでレポートをグループ化する方法

    3. テキストファイルソースの接続文字列パラメータ

    4. SalesforceデータのEDI形式への変換