วิธีตรวจจับการเปลี่ยนแปลงใด ๆ ในฐานข้อมูล (DDL และ DML)


13

มีฐานข้อมูลจำนวนมากบนเซิร์ฟเวอร์ SQL ของลูกค้าของฉัน ฐานข้อมูลเหล่านี้อยู่ระหว่างการพัฒนาเพื่อให้นักพัฒนาสามารถออกแบบปรับโครงสร้างทำการแก้ไขข้อมูลและอื่น ๆ มีฐานข้อมูลบางส่วนที่เปลี่ยนแปลงได้ยาก ลูกค้าของฉันต้องรักษาความปลอดภัยทั้งหมด (สำรองข้อมูล) และใช้เวลาในการจัดการสภาพแวดล้อม (บริษัท ไม่มีตำแหน่งผู้ดูแลฐานข้อมูลที่ บริษัท ) หลังจากการสนทนาที่ยาวนานลูกค้าได้ตัดสินใจใช้กลยุทธ์การสำรองข้อมูลเต็มรูปแบบรายวันเนื่องจากความสะดวกในการกู้คืน

ดังนั้นนี่คือบทสรุปของสถานการณ์:

  • จำนวนฐานข้อมูลสามารถเปลี่ยนแปลงได้ทุกวัน
  • ฐานข้อมูลที่เปลี่ยนแปลง (หมายถึงข้อมูลและ / หรือโครงสร้างที่มีการเปลี่ยนแปลง) จะถูกสำรอง
  • ฐานข้อมูลที่ไม่เปลี่ยนแปลงจะไม่ถูกสำรอง
  • โซลูชันจะไม่ส่งผลกระทบต่อโครงสร้างฐานข้อมูล (ไม่ จำกัด ข้อกำหนด)
  • "เครื่องมือสำรอง" นี้จะทำงานโดยอัตโนมัติ

ปัญหาหลัก: วิธีการตรวจสอบว่ามีการเปลี่ยนแปลงฐานข้อมูล ส่วนแรกของปัญหา (DDL เปลี่ยนแปลง) สามารถแก้ไขได้โดยการใช้ทริกเกอร์ DDL แต่การเปลี่ยนแปลงข้อมูล (การเปลี่ยนแปลง DML) เป็นปัญหา เป็นไปไม่ได้ที่จะใช้ทริกเกอร์ DML กับทุกตารางของฐานข้อมูลทั้งหมดเพื่อติดตามการเปลี่ยนแปลง (ประสิทธิภาพการจัดการวัตถุที่ขยายเพิ่ม ... ) เอ็นจิ้นการสำรองข้อมูลต้องติดตามการเปลี่ยนแปลงทั้งหมดเพื่อทำเครื่องหมายแต่ละฐานข้อมูลว่าพร้อมสำหรับการสำรองข้อมูล

  • Change Data Captureเป็นวิธีแก้ปัญหา แต่ดูเหมือนว่าหนักเกินไป (ต้องใช้ SQL Server Enterprise Edition ด้วย)

  • อีกวิธีหนึ่งคือการติดตามการเปลี่ยนแปลงไฟล์ฐานข้อมูล (ขนาดหรือเวลาการเปลี่ยนแปลงล่าสุด) แต่ทำงานไม่ถูกต้อง: ฐานข้อมูลสามารถเปลี่ยนขนาดได้เมื่อเกินพื้นที่ว่างที่สงวนไว้ทั้งหมดและsp_spaceusedไม่ใช่วิธีแก้ปัญหา

  • การติดตามเป็นวิธีแก้ปัญหา แต่ทำให้เกิดปัญหาด้านประสิทธิภาพและต้องมีการจัดการเพิ่มเติม

มีวิธีใดบ้างในการคำนวณขนาดการใช้ฐานข้อมูลจริงโดยไม่มีผลกระทบต่อวัตถุการจัดการฐานข้อมูลอื่น (เช่นสถิติ .. ) ได้รับว่าการเปลี่ยนแปลงข้อมูลของตารางที่ไม่เปลี่ยนขนาดของตารางจะไม่ทำให้เกิด (ฉันคิดว่า) แต่มันดีกว่าไม่มีอะไร ฉันกำลังมองหาโซลูชันโดยตรงหรือโดยอ้อมสำหรับ SQL Server 2008

ขอบคุณสำหรับความคิดเห็นการแก้ปัญหาและความคิดใด ๆ

เพิ่ม:

นี่คือวิธีแก้ปัญหา (ขอบคุณMarian ):

Select
    NextLSN = MAX(fn.[Current LSN])
    ,Databasename = DB_NAME()
 from fn_dblog(NULL,    NULL) fn
     LEFT JOIN sys.allocation_units au
         ON fn.AllocUnitId = au.allocation_unit_id
     LEFT  JOIN sys.partitions p
         ON p.partition_id = au.container_id
     LEFT  JOIN sys.objects so
         ON so.object_id = p.object_id  
    WHERE 
    (
        (Operation IN 
       ('LOP_INSERT_ROWS','LOP_MODIFY_ROW',
            'LOP_DELETE_ROWS','LOP_BEGIN_XACT','LOP_COMMIT_XACT') 
            AND so.is_ms_shipped = 0)
        OR 
        ([Lock Information] like '%ACQUIRE_LOCK_SCH_M OBJECT%')
    )

คุณทำเช่นนี้เป็นส่วนหนึ่งของงานหรือไม่? ฉันชอบที่จะมีวิธีการแสดงผลรายวัน (พูดตอนตีสอง) ทุกการเปลี่ยนแปลงจาก 24 ชั่วโมงก่อนหน้านี้ไปยังไดเรกทอรีเพื่อให้ฉันสามารถเปลี่ยนแปลงเล็กน้อยสำหรับตัวเอง
jcolebrand

@ jcolebrand ใช่ฉันทำ ในกรณีของฉันฉันต้องตรวจสอบกิจกรรมฐานข้อมูลใด ๆ แล้วทำการสำรองข้อมูล (เต็มหรือส่วนต่าง) ฉันกำลังตรวจสอบ LSN (คีย์หลักของบันทึกการทำงาน) ฟังก์ชั่นนั้นกลับมา fn_dblog นั้นคือทั้งหมด. ฉันไม่คิดว่ามันจะทำงานในกรณีของคุณ ฉันไม่ได้ตรวจสอบคุณสมบัติทั้งหมดของข้อมูลที่สามารถส่งคืนได้โดย fn_dblog แต่ฉันคิดว่ามันไม่ได้ส่งคืนข้อมูลทั้งหมดที่ต้องทำ อย่างที่คุณเห็นมีตารางระบบอื่น ๆ มากมายที่เข้าร่วม หากเป็นเรื่องง่ายเราจะมีเครื่องมือราคาถูกจำนวนมากตามปกติ :)
garik

คำตอบ:


7

แนวคิดหนึ่งที่จะทำ snapshot ทุกวันและตรวจสอบขนาดไฟล์ snapshot บนดิสก์โดยใช้ไฟล์มอนิเตอร์ สแน็ปช็อตจะเพิ่มขนาดของมันก็ต่อเมื่อมีการเพิ่มข้อมูลที่นั่นดังนั้นจึงเป็นความคิดที่ถูกต้องหากคุณจะพบเครื่องมือในการตรวจสอบขนาดจริง (ขนาดรายงาน)

ตอนนี้ .. ฉันไม่ได้ใช้สิ่งนี้ดังนั้นจึงไม่สามารถให้ข้อมูลเชิงลึกด้านเทคนิคแก่คุณ :-)

อีกแนวคิดหนึ่งคือการตรวจสอบบันทึกธุรกรรมของแต่ละฐานข้อมูล (ถ้าคุณใช้โหมดการกู้คืนเต็มรูปแบบที่แน่นอน) ด้วยฟังก์ชั่นบางอย่างที่ฉันเคยเห็นในฟอรัม (db_fnlog .. หรือบางอย่าง) ที่อ่านการดำเนินการจากบันทึก และดูว่าคุณมีการลบ / แทรก / ปรับปรุงใด ๆ

สิ่งเหล่านี้ไม่ใช่เรื่องง่ายที่จะทำ .. แต่ฉันหวังว่าคุณจะพบว่ามีประโยชน์

PS: พบบทความที่มีฟังก์ชั่นบันทึกการอ่าน (มัน fndblog โดยวิธีการ :-): อ่านล็อกธุรกรรมโดย Jens เค Suessmeyer


1
ฉันไม่ได้พูดถึงขนาดไฟล์ db แต่เกี่ยวกับสแน็ปช็อตไฟล์ภายในเครื่องซึ่งสร้างขึ้นด้วย: สร้างฐานข้อมูล xxxdb เป็นสแน็ปช็อตของ yyydb ดูรายละเอียดเกี่ยวกับภาพรวมที่นี่: msdn.microsoft.com/en-us/library/ms175158.aspx
Marian

1
  • สำหรับการเปลี่ยนแปลง DDL คุณอาจอ่าน Trace เริ่มต้น
  • สำหรับการปรับเปลี่ยน DML เนื่องจากคุณพบว่า CDC ค่อนข้างหนักคุณอาจเรียกใช้การติดตามฝั่งเซิร์ฟเวอร์ของคุณเองซึ่งทำการติดตามเฉพาะเหตุการณ์ที่เกี่ยวข้อง

1

สำหรับการเปลี่ยนแปลง DDL ทริกเกอร์ DDL ของคุณ แต่การเปลี่ยนแปลง DML คุณสามารถลองใช้ 3 ตัวเลือกที่แตกต่างกัน

1) การติดตามการเปลี่ยนแปลง 2) CDC (เปลี่ยนการเก็บข้อมูล) 3) คุณสมบัติการตรวจสอบ

สำหรับการเปลี่ยนแปลงการติดตาม .. คุณสามารถดูลิงค์ด้านล่างhttp://www.mssqltips.com/sqlservertip/1819/using-change-tracking-in-sql-server-2008/

การติดตามการเปลี่ยนแปลงนี้จะใช้เฉพาะในกรณีที่ตารางมีการเปลี่ยนแปลงหรือไม่ ... แต่มันยากมากที่จะค้นหาว่าข้อมูลใดมีการเปลี่ยนแปลง .. หากคุณต้องการค้นหาข้อมูลที่มีการเปลี่ยนแปลงคุณสามารถไปที่การจับข้อมูลของ Chnage

สำหรับ Aduit ใน sqlserver .. คุณสามารถตรวจสอบลิงค์ด้านล่างได้ที่ http://blogs.msdn.com/b/manisblog/archive/2008/07/21/sql-server-2008-auditing.aspx


1
+1 แต่ CDC จัดส่งพร้อม Enterprise Edition
garik

1

สำหรับการเปลี่ยนแปลง DML คุณสามารถใช้คุณสมบัติการตรวจสอบ SQL Server แบบท้องถิ่นต่อไปนี้:

  • การติดตามการเปลี่ยนแปลงของเซิร์ฟเวอร์ SQL
  • SQL Server เปลี่ยนการดักจับข้อมูล
  • การตรวจสอบเซิร์ฟเวอร์ SQL

แต่ละข้อมีข้อดีและข้อเสีย แต่การตรวจสอบบัญชีเป็นการนำเสนอครั้งล่าสุดโดย Microsoft ดังนั้นจึงเป็นความคิดที่ดีที่จะสร้างโซลูชันปัจจุบันและอนาคตของคุณ

โปรดทราบว่าเฉพาะคุณลักษณะการตรวจสอบเท่านั้นที่ให้ข้อมูลเกี่ยวกับใคร / เมื่อ / อย่างไร


0

คุณสามารถตรวจจับการเปลี่ยนแปลง ddl ใด ๆ โดยใช้ไฟล์การติดตาม ด้านล่างนี้เป็นสคริปต์เพื่อรับการเปลี่ยนแปลง

SELECT 
    te.name AS eventtype
    ,t.loginname
    ,t.spid
    ,t.starttime
    ,t.objectname
    ,t.databasename
    ,t.hostname
    ,t.ntusername
    ,t.ntdomainname
    ,t.clientprocessid
    ,t.applicationname  
FROM sys.fn_trace_gettable
(
    CONVERT
    (VARCHAR(150)
    ,(
        SELECT TOP 1 
            value
        FROM sys.fn_trace_getinfo(NULL)  
        WHERE property = 2
    )),DEFAULT
) T 
INNER JOIN sys.trace_events as te 
    ON t.eventclass = te.trace_event_id 
WHERE eventclass=164

คุณสามารถตรวจจับการดัดแปลงใด ๆ บนโต๊ะและขั้นตอนการจัดเก็บโดยใช้สคริปต์นี้:

SELECT 
    SO.Name
    ,SS.name 
    ,SO.type_desc 
    ,SO.create_date
    ,SO.modify_date 
 FROM sys.objects AS SO
INNER JOIN sys.schemas AS SS 
    ON SS.schema_id = SO.schema_id 
WHERE DATEDIFF(D,modify_date, GETDATE()) < 50
AND TYPE IN ('P','U')
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.