บันทึก SQL Server บันทึกการดำเนินการที่ไม่ธรรมดาหรือไม่?


12

ฉันมักจะเห็นคำสั่งเช่นบันทึกเซิร์ฟเวอร์ sql บันทึกทุกการกระทำและการเลือกใช้

แต่ผมกำลังสับสนเกี่ยวกับสิ่งที่เกิดขึ้นเมื่อมีการทำธุรกรรมในที่สุดก็กลิ้ง กลับ

บอกว่าการทำธุรกรรมอย่างชัดเจนมี 3 งบ: statement A, statement B, และในที่สุดstatement Crollback statement D

ตอนนี้พูดเมื่อการดำเนินการไม่ถึงrollback statement Dการแก้ไขจะเกิดจากการstatements A through Cบันทึกลงในบันทึกของเซิร์ฟเวอร์ sql หรือไม่

ความเข้าใจที่ 1 :

งบ A ถึง D ทั้งหมดได้รับการบันทึก SQL Server บันทึกทุกอย่างไม่ว่าอะไรก็ตาม

การทำความเข้าใจที่ 2 : การปรับเปลี่ยนจะถูกเก็บไว้ที่ใดที่หนึ่งในหน่วยความจำเท่านั้นและบันทึกไว้เพื่อบันทึกเมื่อ SQL Server เห็นcommitคำสั่ง ถ้าปรากฎว่าเป็นrollbackคำสั่ง SQL Server ก็เพิกเฉยต่อการแปลงข้อมูลไม่มีการเขียนเพื่อบันทึกเกิดขึ้นเพราะไม่มีวัตถุประสงค์ กล่าวอีกนัยหนึ่ง SQL Server บันทึกเมื่อมีผลลัพธ์สุทธิก่อนและหลังธุรกรรม

อย่างน้อยก็สำหรับฉัน แต่พวกเขาทั้งคู่ไม่ถูกต้อง ขอบคุณสำหรับความช่วยเหลือ


สวัสดีลอง [ systoolsgroup.com/sql-log-analyzer.html] (ตัววิเคราะห์บันทึกของ SQL) เพื่อวิเคราะห์สิ่งที่เกิดขึ้นในล็อกไฟล์ คุณอาจลองใช้SysTools SQL Log Analyzerรุ่นฟรีสำหรับดูตัวอย่างข้อมูลบันทึกของ SQL หวังว่าสิ่งนี้จะได้ผลสำหรับคุณ
Rylan08

คำตอบ:


13

ความเข้าใจที่ 1นั้นถูกต้อง SQL Server บันทึกทุกการดำเนินการที่เปลี่ยนแปลงข้อมูลไปยังบันทึกธุรกรรม การย้อนกลับเป็นการเปลี่ยนแปลงข้อมูลดังนั้นจึงเป็นการบันทึกลงในบันทึกธุรกรรมเช่นกัน ในฐานะที่เป็นรันคำสั่งมันจะเขียนข้อมูลไปยังบันทึกการทำธุรกรรมและจะสำรองข้อมูลในบันทึกการทำธุรกรรมในกรณีที่คำสั่ง 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;

หลังจาก:

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

Query 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 
╚═══════════════════╩════════════╩════════════════╝

Query 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 Cและคุณมี a ( commitแทนคุณrollbackไม่สามารถรู้ล่วงหน้า) โดยไม่บันทึกทุกขั้นตอนในการทำธุรกรรม RDBMS จะไม่มีวิธีกู้คืนฐานข้อมูลในรูปแบบที่สอดคล้องกัน วิธีการและการทำธุรกรรมจะไม่ตอบสนองD(ทนทาน) ACIDใน

เมื่อการดำเนินการบางอย่างย้อนกลับเป็นไฟล์ข้อมูลที่ได้รับการเปลี่ยนแปลงสุทธิ (ผ่านCHECKPOINT) ไม่ใช่ไฟล์บันทึก


5

ความเข้าใจที่ 1 นั้นถูกต้องและ spaghettidba และ Joe มีคำอธิบายที่ดี

หากคุณสนใจที่จะทดสอบด้วยตัวเอง (ในตัวอย่างการทดสอบโปรด) คุณสามารถใช้สคริปต์ด้านล่าง:

--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.