SQL Server 2008 R2ダーティリード-どのように非アトミックですか?


11

「ダーティ」なダーティリードが、コミットされていない読み取りの分離レベルに達する可能性があるのではないかと思ってます。更新されたがまだコミットされていない行が表示されることを理解していますが、

  1. 行は部分的に更新されたように見えますか?つまり、一部の列は更新され、一部は更新されていませんか?
  2. 1つの列が部分的に更新されたように見えますか?たとえば、完全に更新中のvarchar(4000)列があり、実際には4000文字が含まれていると想定しているとします。前の状態の2k文字と新しい状態の2k文字を読み取ることができますか?長さが> 8kのvarchar(max)はどうですか?

更新:ある程度の議論の後、最小限のコンセンサスは、列のサイズが> 8KBの場合、たとえ列自体の中であってもダーティリードが可能であるということです。

回答:


7

コメントからMSDNフォーラムのリンクを読んだ後、編集されました。非常に興味深いです。

分離レベルに関係なく、2人のユーザーが1つのページを同時に更新したり、部分的に更新されたページを読み取ることはできません。ヘッダーにCol3がバイト17から始まると書かれたページをSQL Serverがどのように処理するかを想像してみてください。しかし、行のその部分はまだ更新されていないため、実際にはバイト25から始まります。データベースがそれを処理できる方法はありません。

ただし、8kより大きい行の場合、複数のページが使用されるため、半分更新された列が可能になります。MSDNリンクからコピーした場合(リンクが壊れた場合)、このクエリを1つのウィンドウで開始します。

if object_id('TestTable') is not null
    drop table TestTable
create table TestTable (txt nvarchar(max) not null)
go
insert into TestTable select replicate(convert(varchar(max),
    char(65+abs(checksum(newid()))%26)),100000)
go 10
update TestTable set txt=replicate(convert(varchar(max),
    char(65+abs(checksum(newid()))%26)),100000)
go 100000

これによりテーブルが作成され、同じ文字の100.000xの文字列で更新されます。最初のクエリの実行中に、このクエリを別のウィンドウで開始します。

while 1=1 begin
 if exists (select * from TestTable (nolock) where left(Txt,1) <> right(Txt,1))
    break
end

2番目のクエリは、半分更新された列を読み取ると停止します。つまり、最初の文字が最後の文字と異なる場合です。それはすぐに終了し、半分更新された列を読み取ることができることを証明します。nolockヒントを削除すると、2番目のクエリは終了しません。

意外な結果!(nolock)XMLの形式が正しくないため、半分更新されたXML列はレポートを壊す可能性があります。


1
social.msdn.microsoft.com/Forums/en-US/transactsql/thread/…によると、これは必ずしも常に正しいとは限りませんが、部分的に更新されているのがわかる列の型はまだいくらか謎です。

@Andomar AFAIKラッチは、部分的に更新されたページの読み取りを防ぎますが、NCIからいくつかの列値が読み取られたが、CIから列を取得するためにブックマークルックアップを実行した場合はどうなりますか。以下の下でNOLOCK、私は確信しているNCIの列が1行のバージョンが異なるバージョンからのCIからのものであった状況を設計することが可能であろう。さらに、オフローデータとLOBページは、データページのラッチによって保護されません。
マーティン・スミス

1
@Martin:同意しましたnolock。元の行が見つからない自己結合を見ました。ただし、フィールドまたは行の単一の読み取りは一貫している必要があります。
Andomar

1
@Andomar(行の列が複数のページにわたる場合を除く)。私のリンクを参照してください。

2
元の答えがどこか正しくなかったため、これは本当にCWであるはずです。マイケルは現在の答えの要点を提供しました。質問に対するコメントは、編集された回答にまだ同意していません。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.