SQL Server günlüğü sıralanmamış işlemleri kaydediyor mu?


12

Ben sık sık sql sunucu günlüğü gibi ifadeleri her işlem ve opeation görüyorum.

Ama işlem sonunda ne olacağını hakkında karıştı haddelenmiş geri .

De ki açık bir işlem 3 ifadeleri vardır: statement A, statement B, statement Cve son olarak bir rollback statement D.

Şimdi yürütme ulaşmadığında, sql sunucu günlüğüne kaydedilmesinden rollback statement Dkaynaklanan değişiklikler olacak statements A through Cmı?

Anlama 1 :

A'dan D'ye ifadelerin tümü kaydedilir. SQL Server, ne olursa olsun her şeyi kaydeder.

Anlama 2 : Değişiklikler yalnızca bellekte bir yerde saklanır ve yalnızca SQL Server bir commitifade gördüğünde günlüğe kaydedilir . Bir rollbackdeyim olduğu ortaya çıkarsa , SQL Server işlemi dönüştürmeyi yoksayır, hiçbir amaca hizmet etmediği için günlüğe yazılır. Başka bir deyişle, SQL Server işlemlerden önce ve sonra net bir sonuç olduğunda günlüğe kaydeder .

Her ikisi de en azından bana mantıklı geliyor ama ikisi de haklı olamaz. Herhangi bir yardım için teşekkürler.


Merhaba, Günlük dosyasında neler olup bittiğini analiz etmek için [ systoolsgroup.com/sql-log-analyzer.html] (SQL Log Analyzer) 'ı deneyin . SysTools SQL Log Analyzer'ın ücretsiz sürümünü yalnızca SQL Log Data önizlemesi için deneyebilirsiniz . Umarım bu işe yarar.
Rylan08

Yanıtlar:


13

1'i anlamak doğrudur. SQL Server, verileri işlem günlüğüne değiştiren her işlemi kaydeder. Geri alma, verilerdeki bir değişikliktir, böylece bunu işlem günlüğüne de kaydeder. A ifadesi çalıştırması olarak, işlem günlüğüne veri yazacak ve ayrıca A ifadesinin geri alınması gerektiğinde işlem günlüğüne veri ayıracaktır. Aynı durum B ve C için de geçerlidir. İşlemi geri aldığınızda günlüğe daha fazla bilgi yazılır.

Bunu eylemde görmenin birçok yolu var, bu yüzden aşağıda hızlı bir demo. İşte günlüğe yazılanları görmek için kullanacağım sorgu:

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;

Benim masam:

create table TLOGDEMO (FLUFF VARCHAR(1000));

BEGIN TRANSACTION

A sorgusu en az günlük kaydı kullanır:

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

A sonrası:

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

Sorgu B, minimum günlük kaydı kullanmaz:

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

B'den Sonra:

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

C sorgusu daha az veri değiştirir:

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

C'den sonra:

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

Şimdi bir ROLLBACKgeri vereceğim ve geri alma gerçekleşirken DMV'yi sorgulayacağım. Aşağıda birkaç fotoğraftan oluşan bir tablo bulunmaktadır:

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

Boyunca ROLLBACK, ikinci bayt artar ve bayt ayrılmış sayısı azalır. Bunun nedeni, SQL Server'ın işlemi geri almak için daha önce ayırdığı alanı kullanmasıdır. İşlemi geri almak için, günlüğe daha fazla veri yazması için verileri değiştirmesi gerekir.


8

Veritabanı tablolarında yapılan değişiklikler önce günlük dosyasına, daha sonra tabloların kendilerine, önce bellekte ve daha sonra CHECKPOINTdisk olarak adlandırılan eşzamansız bir işlemle yazılır . Bu mekanizma WAL (İleri Yazma Kaydı) olarak bilinir ve tüm ilişkisel veritabanları için ortaktır.

Günlüğün kendisi önce belleğe (tam olarak günlük arabelleğine ve sonra diske) yazılır, ancak günlük diske yazılana kadar veritabanı tablolarına hiçbir şey dokunulmaz.

Bu mekanizma, kurtarma işlemi sırasında hem taahhütlü işlemleri geri alma hem de taahhüt edilmemiş işlemleri geri alma olanağı sunar. Örneğinizle ilgili olarak, daha sonra kötü bir şey olduysa statement Cve işlemin her adımını kaydetmeden (önceden bilemezsiniz) commityerine bir tane rollbackvarsa, RDBMS'nin veritabanını tutarlı bir şekilde kurtarmanın hiçbir yolu olmazdı ve işlemin D(dayanıklılık) değerini karşılamaz ACID.

Bazı işlemler geri alınır zaman, bu kadar veri (via net değişiklikleri alır dosyası CHECKPOINT) değil, günlük dosyası.


5

1'i anlamak doğrudur ve spaghettidba ve Joe'nun iyi açıklamaları vardır.

Kendiniz için test yapmak istiyorsanız (lütfen bir test örneğinde), aşağıdaki komut dosyasını kullanabilirsiniz:

--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'ın her şeyi kaydettiğini göreceksiniz, hatta işlemleri geri almak için atılan adımlar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.