SQL 2016 SQL Serverアサーション:ファイル:<pageref.cpp>、line = 951失敗したアサーション


8

現在、データウェアハウスをSQL 2012からSQL 2016にアップグレードしています。新旧両方のDWを並行して実行しています。

私のETLプロセス(サードパーティがSSISで開発したフレームワーク)は2012年に2年以上正常に実行されましたが、2016年には失敗しています。これまでのところ、データベースとETLプロセスは同じです。

どちらのサーバーも、VMWareで実行される仮想マシンです。古いサーバーはWin 2008で、24GbのRAMを搭載しています。SQL 2012標準 最大メモリは16Gbに設定されています。新しいサーバーは64GbのRAMを備えたWin 2012です。SQL 2016開発者。最大メモリは50Gbに設定されています。新しいDWはv13.0.1601.5 RTM Developer Edition(64ビット)を実行しています。

ETLプロセスの実行中に、SQL Mergeを使用してディメンションまたはファクトテーブルにロードするステップは、次のエラーで失敗します。

全文:

説明:SQL Serverアサーション:ファイル:、行= 951失敗したアサーション= 'IS_OFF(BUF_MINLOGGED、m_buf-> bstat)|| pageModifyType!= PageModifyType_Contents || GetPagePtr()-> IsTextPage() '。このエラーはタイミングに関連している可能性があります。ステートメントを再実行してもエラーが解決しない場合は、DBCC CHECKDBを使用してデータベースの構造的な整合性をチェックするか、サーバーを再起動してメモリ内のデータ構造が破損していないことを確認してください。

推奨されるとおり、DBCCを実行しましたが、エラーは見つかりませんでした。SQLも再起動しました。次に、ETLプロセスを再起動したところ、同じエラーが発生しました。

このエラーを検索したところ、SQL 2008、2012、2014の既知のエラーであり、その後の修正プログラムと累積的な更新で修正されたことがわかりました。2016年に再び表示されるのを見て少し驚いています。

私が見つけたリンクは、データベースがシンプルまたは一括ログ復旧モデルである場合に挿入を行おうとすると、SSISに影響を与えると言っています。(私は単純復旧モデルで実行しています)

推奨される回避策は、DB復旧モデルをFULLに変更することです。私はこれを試してみましたがうまくいきましたが、それはデータウェアハウスの解決策ではありません。

2016年に他の誰かがこれに遭遇しましたか?

誰かが代替の回避策を提案できますか?

アップデート:

2016年7月26日:重要な更新KB3164398(v13.0.1708.0)を適用しましたが、問題はまだ存在しています。

2016年7月27日:累積的な更新プログラムCU1 KB3164674(v13.0.2149.0)を適用しました。

2016年3月8日:最小のキューブでエラーが一晩発生しました。CU1は問題を修正しませんでした。本日、私はMSコネクトのバグ報告し、マイクロソフトとのサポートコールも記録しました。

2016年12月8日:最初にMS-Supportが応答しましたが、「それに対する修正はありません」という応答でした。サポート担当者は、同僚とそれについて話し合い、私に連絡するつもりでした。8日後、彼から連絡がありません。

「解決策」はありませんが、自分に適した回避策を見つけました。私の投稿した回答をご覧ください。

2016年9月9日。先週CU2を適用しました。Thursayで、同じエラーで再び失敗した古いバージョンのマージを誤って実行しました。CU2はそれを修正していません。

2017 1 月23日2016 SP1 CU1を適用しました。これで問題が解決したと思います。特にKB3205964

回答:


2

KBを見ると、いくつかのオプション/回避策があります。

  1. 完全復旧モデルに切り替えます。「これは倉庫のオプションではありません」と言いますが、実際には、トランザクションログのバックアップを定期的に(たとえば15分間)設定し、廃棄するだけです。SSIS /メンテナンスプランには、これ行うためのストックタスクがありますます。一括ログに記録されたトランザクションは失われますが、これらがランタイムに大きな違いをもたらしたことは一度もありません。ログサイズだけです。ここでは説明しませんが、nulにログをバックアップすることもできます。どうすればよいかわからない場合は、ローカルのDBAに問い合わせてください。ディスク容量とトランザクションログバックアップの保持は、致命的なエラーよりも解決が容易な問題です。この問題が最終的に解決したら、元に戻すことができます。
  2. KBでは、「単一分散トランザクション内の複数のBULK INSERTステートメント」について言及しています。一括挿入がどのように設定されているかは、質問からは明らかではありません。SSISを使用して、SQLを実行するタスクを実行していますか。MERGEコマンド?ここで「複数の一括挿入」とはどういう意味ですか?たとえば、一度に1つずつ、単一のBULK INSERTにアプローチを変換する方法はありますか?たとえば、SSISでは、 'MaxConcurrentExecutables'を一時的に1に設定できます。これが役立つかどうかを確認してください。後で変更できるように、それを構成変数に結び付けます。明らかにそれは物事を遅くしますが、あなたはあなたのETLがすぐに失敗するよりも終了することを好みます。並列処理は優れたパターンであり、SSISの真の強みですが、最も遅いコンポーネントと同じ速度でしか実行できません。1分かかる10個のディメンションと1時間かかる1つのファクトがあるとすると、ETLは1時間の並列実行、または1時間10分の連続実行で終了します。
  3. MERGEいいですが、いくつかの問題があります。INSERT/に戻すことを検討してくださいUPDATE。また、あなたが使用する必要がありますHOLDLOCKMERGEに従ってここに。そのヒントを使用しますか?あなたがそうするなら、それはこの問題に何らかの違いをもたらしますか?SQL 2014の初期のビルドで問題がありました。MERGE構成可能なDML(OUTPUT句)を列ストアに使用すると、この種のアサーションが発生しました。列ストアインデックスをディメンションから削除するように指示しました。
  4. どのようなトランザクション処理を行っていますか?ETLを使用すると、再実行するだけで位置を再現できる場合があります。失敗してロールバックする必要がある場合があります。これをどのように実装しましたか?「単一分散トランザクション」ではないように変更できますか?

幸運を。


こんにちは@wBob返信ありがとうございます。あなたの質問に答えるために。1. 1ステップで20〜30Gbのテーブルを抽出することについて話している。100Gbを超えるデータの移動。TXのログとストレージのブローアウトが心配です。たぶん、抽出ごとにログバックアップをETLのステップにできますか?2.はい。SSISはSQLタスクを呼び出してマージを実行します。各ステップは順次実行されます。マージが実行されているとき、それは実行されている唯一のタスクです。3. ETLツールは、ベンダーが提供するフレームワークです。これがどのように機能するかです。ヒントについてはわかりません。チェックします。4. TX処理なし。ストレートSQL。
Swears-a-lot卿16/07/27

したがって、正常な実行が続行されない場合は、テーブルを移動するたびにログバックアップを含む100GBのtログを試してください。明らかに、テストする必要があります。ターゲットについて知っておくべきその他の機能はありますか?列ストア、パーティション化、過度のインデックス付け?
wBob 2016

現在、2012 stdの既存のDWにまだ含まれていない機能はありません。新しいDW / Datamartsはオリジナルの完全なコピーであり、列ストアやパーティション化はありません。最小限の(しかし効果的な)インデックス。現在のところ、プラットフォームの移行に重点を置いています。最終的に、新しい製品のDWは2016 Enterpriseになります。ただし、基本が機能するまでエンタープライズレベルの機能は追加しません。
-a-lot卿

こんにちは@wBob挿入のマージを解除して、提案を実装しました。しかし、私が質問した方法を考えると、何が正解と見なされるのかわかりません。しかし、あなたは私を有効で実行可能な回避策に導いたと思います。
サー誓う-ロット



1

別の回避策が見つかったと思います。私は自分の答えを有用だと思うので投稿しています。これはwBobの提案とは十分に異なります。

元のターゲットではなく一時テーブルに挿入するように、mergeステートメントの挿入部分を変更しました。

mergeステートメントが実行されると、#tableからターゲットに挿入されます。

これは理想的ではありませんが、少なくともマージでは、廃止または期限切れになった行をマークすることにより、「アップサート」の複雑さを処理します。

これは、マージを完全に別の挿入と更新として書き直すのと比較して、許容できるトレードオフであることがわかりました。

CREATE TABLE #Activity(
[ETL_ActivitySurrogateKey] [int] IDENTITY(1,1) NOT NULL,
[Field1] [varchar](255) NULL,
)

-- Insert statements for procedure here
INSERT INTO #Activity ( [Field1],2,3,etc )

SELECT [Field1],2,3,etc
FROM 
(
    MERGE [DDS_OZ_CC].[dimActivity] AS target 
    USING (
      SELECT [Field1],2,3,etc
      FROM [STAGE_OZ_CC].[Transform_Activity]
      ) as source
    ON
    (
      target.RowIsCurrent = source.RowIsCurrent
         AND target.[Field1] = source.[Field1]
    )
    WHEN MATCHED 
        AND (        
        EXISTS (SELECT target.Level5Id EXCEPT SELECT source.Level5Id)
    )
    THEN
      UPDATE SET 
        ETL_ValidToDateTime = source.ETL_ValidFromDateTime 
       ,ETL_RowIsCurrent = 0 
       ,ETL_LastTouchedBy = source.ETL_LastTouchedBy 
       ,ETL_RowChangeReason = 'SCD2 Retired' 

    WHEN NOT MATCHED THEN 
    INSERT 
    (    
     [Field1],2,3,etc
    )
    VALUES (      
      source.[Field1],2,3,etc
    )
       WHEN NOT MATCHED BY SOURCE AND target.ETL_RowIsCurrent = 1
       THEN UPDATE SET
       ETL_RowIsCurrent = 0 
       ,ETL_RowChangeReason = 'Fact Removed' 
       ,ETL_LastTouchedBy = 'Unknown'

  OUTPUT
    $action      
      ,source.[Field1],2,3,etc    

  ) AS MergeOutput
  (
    action  
    ,[Field1],2,3,etc   
  ) 

  WHERE ACTION = 'UPDATE' AND ETL_RowIsCurrent = 1

    INSERT INTO [DDS_OZ_CC].[dimActivity]
    ( [Field1],2,3,etc  )
    SELECT [Field1],2,3,etc
    FROM #Activity

    END

ピーターに感謝します。ちょっと興味があったので、HOLDLOCKヒントを試しましたか?
wBob 2016

いいえ、しませんでした。Aaron Bertrandsの記事を読んだ後、私の理解は、実際には複数のユーザーの同時実行に関する問題であるということでした。私たちの場合、ETLプロセスだけが実行されています。
Swears-a-lot卿

異なる動作をするかどうかを確認するだけでも価値があったと思います。また、おそらくベストプラクティスです。同時に並行していないと言っても、将来はないかもしれません。とにかく、解決策を見つけて次の問題を解決することに
成功しました

したかったのですが、残念ながら時間の制約があります。実行可能な解決策が見つかると、上司は次に進むように呼びかけました。
Swears-a-lot卿
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.