none
SQL Server 2008 R2 Express [SP2]において、トランザクション処理でデータベースに書込んだ内容が無効にされる時がある RRS feed

  • 質問

  • 【手順】
    A.グローバル一時テーブルを作成する(B.と直接関係のあるデータではない)
    B.特定テーブルの特定項目のデータを取得(値をXとする)
    C.トランザクション処理で特定テーブルの特定項目のデータを値(X+1)で書き換える
     例外が出ない場合は、最後にコミット(COMMIT;)
    (C+.コミット直後にCHECKPOINT;を実行)
    D.特定テーブルの特定項目のデータを取得(値をYとする)
    E.同時にファイルにこの値(Y)を書き出す ※この時点ではY=X+1となっています。
    F.グローバル一時テーブルを削除する
     (=参照しているユーザーがすべていなくなるタイミングで自動削除される。
     ※SQL Server はシングルユーザーのみでアクセスされていて、その接続をいったん切り、また接続します)
    G.特定テーブルの特定項目のデータを取得(値をZとする)
    H.ファイルに書き出したデータ(Y)と特定項目のデータ(Z)を比較する

    I.ある環境(確率=1/10)で、ある条件(確率=1/1)で、ある確率(1/50)で、
     データ(Z)とデータ(Y)が異なっている。
     具体的にはデータ(Z)はデータ(X)と同じである。

    ・ある環境:Windows10 Pro 64bitにSQL Server 2008 R2 Express [SP2]を複数台に個別インストール、80台中8台くらいなど
    ・ある条件:SQL Server 2008 R2 Express [SP2] 起動後の最初のトランザクション処理の書き込み直後
          ※同起動、2回目以降のトランザクション処理の書き込み直後では、ほとんどこの事象は起こらない
    ・ある確率:1/50くらいの確率。毎回かならず起こるわけではない。
    -------------
    箇条書き
    A.グローバル一時テーブル作成
    B.[特定テーブル特定項目]取得→X
    C.[特定テーブル特定項目]更新←X+1
    D.[特定テーブル特定項目]取得→Y
    E.上記の値(Y)をファイルに書き出す。※この時点ではY=X+1となっています。
    F.グローバル一時テーブル(自動)削除
    G.[特定テーブル特定項目]取得→Z
    H.ZとYを比較する。
    I.Z=YのはずがZ=Xになることがある。
    -------------

    データベースは内容が書き換えられても、逐一ファイルに書き込むのでなく、
    キャッシュに一時保存され、必要な時にファイルに書き込むという機構になっていると聞きました。

    (I)が起きた時は、必ず(値Z)は、かならず(値X)になっていました。
    これから、類推するに、ある事象がかさなると
    「サーバー起動後、初回トランザクションで更新されたデータベースのキャッシュ内容がクリアされた状態になることがある」
    と思われます。

    また、C.の直後に 「C+.コミット直後にCHECKPOINT;を実行」(必ず物理ディスク(ファイル)に書き出してくれるはずだが)
    しても状況は変わりませんでした。

    毎日複数台で運用しているのですが、データベースへの書き換えが無効になり、データが合わなくなり非常に困っています。
    正式なサポートも終了してしまい、何か対策方法があるのか知りたくて、藁をもすがる気持ちで投稿しています。

    ----
    1.この事象の原因を知りたいです。
    2.もし対策方法があれば知りたいです。
    3.SP3へのアップデートで修正されるかどうかを知りたいです。

    以上、よろしくお願いいたします。
    2020年8月17日 4:12

回答

  • おたずねのことを答えられる人はいないのでは?と感じました。

    1:原因を答えられるのは、その事象に遭遇して試行錯誤を重ねたリバースエンジニアリングによって動作を推測できている人か、Microsoft の中の人に限られ、ここでは後者の情報を得られないため。

    2:回避になるかはわかりませんが、最初の 1 回目だけならゴミテーブルか何かにトランザクションかける…みたいな起動後 1 回目だけの消えても構わない処理を入れてみるとか…? (当てずっぽうです)

    3:これはご自身で検証用環境を作って様子を見るのが早いのでは?と思います。
    情報を探してみるなら、ここ とか、ここ になります。

    2020年8月17日 13:17
  • 以下のURLの各CUで該当しそうな不具合が存在するかを確認することはできるかと思います。

    The SQL Server 2008 R2 builds that were released after SQL Server 2008 R2 Service Pack 2 was released
    https://support.microsoft.com/en-us/help/2730301/the-sql-server-2008-r2-builds-that-were-released-after-sql-server-2008

    なお、非同期に更新されるのは、データベース物理ファイル(.mdf/.ndf)のみであり、トランザクションログにはトランザクション情報が即座に書き込みが行われます。(最新のバージョンでは SLOG などが追加されて少し複雑になっていますが)
    SQL Serverの実装から考えると、Commitが完了したデータがデータベースに反映されないという現象は、ほぼ発生しないと思います。
    再現頻度が高い点からも、中枢の機能で頻繁にデータが反映されないという現象が発生するとは考えにくく、疑われるのはアプリケーション側の実装の問題でしょうか。
    再現性があるのであれば、サーバートレース、拡張イベントの何れかを現象発生時、正常時とで採取して比較されると問題の原因を特定できる可能性もあるかもしれません。

    https://www.nobtak.com/entry/strace0
    • 編集済み NOBTA 2020年8月17日 13:57
    • 回答としてマーク madoka777hiroshi 2020年8月20日 4:57
    2020年8月17日 13:56
  • まあそもそも「SQL Server 2008 R2は、Windows10またはWindows Server 2016ではサポートされていません。」なわけですが。 https://support.microsoft.com/ja-jp/help/2681562/using-sql-server-in-windows-8-and-later-versions-of-windows-operating

    jzkey

    2020年8月18日 1:04

すべての返信

  • おたずねのことを答えられる人はいないのでは?と感じました。

    1:原因を答えられるのは、その事象に遭遇して試行錯誤を重ねたリバースエンジニアリングによって動作を推測できている人か、Microsoft の中の人に限られ、ここでは後者の情報を得られないため。

    2:回避になるかはわかりませんが、最初の 1 回目だけならゴミテーブルか何かにトランザクションかける…みたいな起動後 1 回目だけの消えても構わない処理を入れてみるとか…? (当てずっぽうです)

    3:これはご自身で検証用環境を作って様子を見るのが早いのでは?と思います。
    情報を探してみるなら、ここ とか、ここ になります。

    2020年8月17日 13:17
  • 以下のURLの各CUで該当しそうな不具合が存在するかを確認することはできるかと思います。

    The SQL Server 2008 R2 builds that were released after SQL Server 2008 R2 Service Pack 2 was released
    https://support.microsoft.com/en-us/help/2730301/the-sql-server-2008-r2-builds-that-were-released-after-sql-server-2008

    なお、非同期に更新されるのは、データベース物理ファイル(.mdf/.ndf)のみであり、トランザクションログにはトランザクション情報が即座に書き込みが行われます。(最新のバージョンでは SLOG などが追加されて少し複雑になっていますが)
    SQL Serverの実装から考えると、Commitが完了したデータがデータベースに反映されないという現象は、ほぼ発生しないと思います。
    再現頻度が高い点からも、中枢の機能で頻繁にデータが反映されないという現象が発生するとは考えにくく、疑われるのはアプリケーション側の実装の問題でしょうか。
    再現性があるのであれば、サーバートレース、拡張イベントの何れかを現象発生時、正常時とで採取して比較されると問題の原因を特定できる可能性もあるかもしれません。

    https://www.nobtak.com/entry/strace0
    • 編集済み NOBTA 2020年8月17日 13:57
    • 回答としてマーク madoka777hiroshi 2020年8月20日 4:57
    2020年8月17日 13:56
  • まあそもそも「SQL Server 2008 R2は、Windows10またはWindows Server 2016ではサポートされていません。」なわけですが。 https://support.microsoft.com/ja-jp/help/2681562/using-sql-server-in-windows-8-and-later-versions-of-windows-operating

    jzkey

    2020年8月18日 1:04
  • madoka777hiroshiさん、こんにちは。フォーラムオペレーターのKumoです。 
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    ご質問いただいた件ですが、その後いかがでしょうか。
    皆様から寄せられた投稿はお役に立ちましたか。

    参考になった投稿には [回答としてマーク] をお願い致します。

    設定いただくことで、
    他のユーザーもお役に立つ回答を見つけやすくなります。

    お手数ですが、ご協力の程どうかよろしくお願いいたします。

    MSDN/ TechNet Community Support Kumo ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2020年8月20日 2:42
    モデレータ
  • ご回答ありがとうございます。

    ダメ元だったので、回答していただける方がいらっしゃるだけでありがたいです。

    1:はその通りだと思います。

    2:は、最後の手段だと考えております。汚い物に蓋をするようで、、うまくいくかは今のところ分からないです。

    3:SP3で更新をかけて様子を見ることにしました。アプリ全域のテストが大変ですが、正攻法だと考えています。

    以上です。

    2020年8月20日 4:49
  • ご回答ありがとうございます。

    COMMITでデータベースへ即座に反映されているのですが、

    グローバル一時テーブルの削除のあと、データベースに反映されたものが、なぜか剥がれ落ちてしまうことがあるのです。

    サーバートレース、拡張イベントの何れかを現象発生時、正常時とで採取して比較されると問題の原因を特定できる可能性もあるかもしれません。

    時間が許せばチャレンジしてみたいと思っています。

    対策として、正攻法で、SP3への更新を行うことにしました。

    SP3では、重大な欠陥がいくつも修正されていますので。

    いままでやっていなかったのがおかしくらいですね。

    以上、ありがとうございました。

    2020年8月20日 4:57
  • そのとおりですが、

    この現象は、2010年の時点ですでに起きていました。
    OSは、ほとんど関係ない現象だととらえています。

    さらに、SQL Server 2008 R2は、Windows10でサポートされていないことを承知で使用を続けています。

    ご指摘ありがとうございました。

    2020年8月20日 5:01