SQL Serverは、コミットされていない操作を記録しますか?


12

私は頻繁にSQLサーバーのログレコードのようなステートメントがすべてのtransctionとopeationを見ます。

しかし、トランザクションが最終的にロール バックされるときに何が起こるかについて私は混乱しています

:明示的なトランザクションは3文があると言うstatement Astatement Bstatement C、そして最後にrollback statement D

ここで、実行がに達していない場合、SQLサーバーログに記録されrollback statement Dた変更statements A through Cは記録されますか?

理解1

ステートメントAからDはすべて記録されます。SQL Serverは、何があってもすべてを記録します。

理解2:変更はメモリのどこかにのみ保存され、SQL Serverがcommitステートメントを認識したときにのみログに記録されます。rollbackステートメントであることが判明した場合、SQL Serverは単純にトランザクションを無視します。目的を果たさないため、ログへの書き込みは発生しません。ある場合、他の言葉では、SQL Serverがログに記録し、正味の結果の前後の取引が。

少なくとも私には両方とも論理的に思えますが、両方とも正しいとは言えません。助けてくれてありがとう。


こんにちは、[ systoolsgroup.com/sql-log-analyzer.html](SQL Log Analyzer)を試して、ログファイルの内容を分析してください。SysTools SQL Log Analyzerの無料版は、SQLログデータのプレビューのみに使用できます。これがあなたのために働くことを願っています。
Rylan08

回答:


13

1を理解するのは正しいことです。SQL Serverは、データを変更するすべての操作をトランザクションログに記録します。ロールバックはデータの変更であるため、トランザクションログにも記録されます。ステートメントAが実行されると、トランザクションログにデータが書き込まれ、また、ステートメントAをロールバックする必要がある場合に備えて、トランザクションログにデータが予約されます。BとCについても同じことが言えます。トランザクションをロールバックすると、より多くの情報がログに書き込まれます。

これを実際に見る方法はたくさんあるので、以下に簡単なデモを示します。ログに書き込まれた内容を確認するために使用するクエリを次に示します。

SELECT 
  COUNT(*) transaction_count
, SUM(database_transaction_log_bytes_used) used_bytes
, SUM(database_transaction_log_bytes_reserved) reserved_bytes
FROM sys.dm_tran_database_transactions
where database_id = 10;

私のテーブル:

create table TLOGDEMO (FLUFF VARCHAR(1000));

BEGIN TRANSACTION

クエリAは最小限のログを使用します。

INSERT INTO TLOGDEMO WITH (TABLOCK)
SELECT REPLICATE('A', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

Aの後:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1    24006640       175429451 
╚═══════════════════╩════════════╩════════════════╝

クエリBは最小限のログを使用しません。

INSERT INTO TLOGDEMO
SELECT REPLICATE('B', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

Bの後:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1  7352935708      1613986255 
╚═══════════════════╩════════════╩════════════════╝

クエリCが変更するデータが少ない:

INSERT INTO TLOGDEMO
SELECT REPLICATE('C', 1000)
FROM master..spt_values c;

Cの後:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1  7355821748      1614545331 
╚═══════════════════╩════════════╩════════════════╝

ここでROLLBACK、ロールバックが発生している間にDMVを発行してクエリします。以下は、いくつかのスナップショットの表です。

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
 1                  7393305528  1573797677     
 1                  7458767420  1502635737     
 1                  7682482356  1259440979     
 1                  7803881368  1127471233     
 ...                ...         ...            
╚═══════════════════╩════════════╩════════════════╝

の間にROLLBACK、使用されるバイトが増加し、予約済みのバイト数が減少します。これは、SQL Serverがトランザクションを元に戻すために以前に確保したスペースを使用しているためです。トランザクションを元に戻すには、データを変更して、より多くのデータをログに書き込む必要があります。


8

データベーステーブルへの変更は、最初にログファイルに書き込まれ、次にテーブル自体に書き込まれ、最初にメモリに書き込まれ、次に、と呼ばれる非同期プロセスでCHECKPOINTディスクに書き込まれます。このメカニズムはWAL(先行書き込みログ)と呼ばれ、すべてのリレーショナルデータベースに共通です。

ログ自体は、最初にメモリ(正確にはログバッファ)に書き込まれ、次にディスクに書き込まれますが、ログがディスクに書き込まれるまでデータベーステーブルには何も触れられません。

このメカニズムにより、リカバリプロセス中にコミットされたトランザクションのロールフォワードとコミットされていないトランザクションのロールバックの両方が可能になります。あなたの例については、何か悪いことが起こった後statement Ccommit代わりにrollback(これを事前に知ることはできません)、トランザクションのすべてのステップを保存せずに、RDBMSは一貫した方法でデータベースを回復する方法がありません方法およびトランザクションはでD(耐久性)を満たしませんACID

一部の操作がロールバックされる場合、ログファイルではなく、(ネット経由で)ネット変更を受け取るのはデータファイルCHECKPOINTです。


5

1を理解するのは正しいことであり、スパゲッティバとジョーには良い説明があります。

自分でテストすることに興味がある場合(テストインスタンスでお願いします)、以下のスクリプトを使用できます。

--create a database and table for testing
USE master
GO
CREATE DATABASE tranlogtest
GO
USE tranlogtest
GO
CREATE TABLE t1
(junk char(1))

CHECKPOINT
GO

BEGIN TRAN
INSERT t1 VALUES ('a')
INSERT t1 VALUES ('b')
INSERT t1 VALUES ('c')

ROLLBACK
INSERT t1 VALUES ('d')

SELECT *
FROM fn_dblog(NULL,NULL)

SQL Serverは、操作を取り消すための手順を含め、すべてを記録することがわかります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.