บันทึกธุรกรรมสำหรับฐานข้อมูลเต็ม


110

ฉันมีขั้นตอนการดำเนินการที่ยาวนานซึ่งเก็บธุรกรรมที่เปิดไว้ตลอดระยะเวลาเต็ม

ฉันไม่สามารถควบคุมวิธีดำเนินการนี้ได้

เนื่องจากธุรกรรมถูกเปิดไว้ตลอดระยะเวลาเต็มเมื่อบันทึกธุรกรรมกรอก SQL Server ไม่สามารถเพิ่มขนาดของล็อกไฟล์ได้

"The transaction log for database 'xxx' is full"ดังนั้นกระบวนการล้มเหลวด้วยข้อผิดพลาด

ฉันพยายามป้องกันปัญหานี้โดยการเพิ่มขนาดของไฟล์บันทึกธุรกรรมในคุณสมบัติฐานข้อมูล แต่ฉันได้รับข้อผิดพลาดเดียวกัน

ไม่แน่ใจว่าควรลองอะไรต่อไป กระบวนการนี้ใช้เวลาหลายชั่วโมงดังนั้นจึงไม่ใช่เรื่องง่ายที่จะเล่นแบบลองผิดลองถูก

ความคิดใด ๆ ?

หากใครสนใจกระบวนการนี้เป็นการนำเข้าองค์กร Microsoft Dynamics CRM 4.0.

มีพื้นที่ดิสก์มากมายเรามีการเข้าสู่ระบบในโหมดการบันทึกอย่างง่ายและได้สำรองข้อมูลบันทึกไว้ก่อนที่จะเริ่มกระบวนการ

- = - = - = - = - อัปเดต - = - = - = - = -

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

ฉันได้รับข้อผิดพลาดต่อไปนี้ ...

Import Organization (Name=xxx, Id=560d04e7-98ed-e211-9759-0050569d6d39) failed with Exception:
System.Data.SqlClient.SqlException: The transaction log for database 'xxx' is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases

ดังนั้นตามคำแนะนำนั้นฉันจึงไปที่ " log_reuse_wait_desc column in sys.databases" และมันก็มีค่า " ACTIVE_TRANSACTION"

อ้างอิงจาก Microsoft: http://msdn.microsoft.com/en-us/library/ms345414(v=sql.105).aspx

นั่นหมายถึงสิ่งต่อไปนี้:

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

•ธุรกรรมถูกเลื่อนออกไป (SQL Server 2005 Enterprise Edition และเวอร์ชันที่ใหม่กว่าเท่านั้น) ธุรกรรมที่รอการตัดบัญชีเป็นธุรกรรมที่ใช้งานได้อย่างมีประสิทธิภาพซึ่งการย้อนกลับถูกบล็อกเนื่องจากทรัพยากรบางอย่าง สำหรับข้อมูลเกี่ยวกับสาเหตุของธุรกรรมรอการตัดบัญชีและวิธีการย้ายออกจากสถานะรอการตัดบัญชีโปรดดูธุรกรรมรอการตัดบัญชี

ฉันเข้าใจผิดไปหรือเปล่า?

- = - = - = - อัปเดต 2 - = - = - = -

เพิ่งเริ่มต้นกระบวนการโดยตั้งค่าขนาดไฟล์บันทึกเริ่มต้นเป็น 30GB ขั้นตอนนี้จะใช้เวลาสองถึงสามชั่วโมง

- = - = - = - อัปเดตสุดท้าย - = - = - = -

ปัญหานี้เกิดจากไฟล์บันทึกใช้พื้นที่ดิสก์ที่มีอยู่ทั้งหมด ในความพยายามครั้งล่าสุดฉันได้เพิ่มพื้นที่ 120GB และยังคงใช้งานทั้งหมดและล้มเหลวในที่สุด

ฉันไม่ทราบว่าสิ่งนี้เกิดขึ้นก่อนหน้านี้เพราะเมื่อกระบวนการทำงานข้ามคืนมันกำลังย้อนกลับไปสู่ความล้มเหลว คราวนี้ฉันสามารถตรวจสอบขนาดไฟล์บันทึกก่อนการย้อนกลับได้

ขอบคุณสำหรับข้อมูลของคุณ


re "... และสำรองข้อมูลบันทึก" .... หากฐานข้อมูลอยู่ในโหมด Simple คุณจะไม่สามารถสำรองข้อมูลบันทึกได้การสำรองข้อมูลบันทึกจะไม่สามารถใช้ได้กับโหมดธรรมดา เข้าสู่ระบบจำนวนมากหรือไม่
SqlACID

1
ฉันสำรองฐานข้อมูลทั้งหมดและย่อขนาดซึ่งส่งผลให้บันทึกย่อขนาดเป็น 1MB จากนั้นฉันก็เพิ่มขนาดของไฟล์บันทึกเป็น 20GB ในตอนแรกและตอนนี้ 30 GB
Jimbo

โพสต์ที่เกี่ยวข้อง - TempDB Log Space และ ACTIVE_TRANSACTION
RBT

คำตอบ:


19

นี่เป็นสคริปต์ครั้งเดียวหรืองานที่เกิดขึ้นเป็นประจำ

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


ฉันจะไม่บอกว่ามันเป็นงานครั้งเดียว แต่เป็นเรื่องยากที่เราต้องทำ ฉันไม่ได้สร้างไฟล์บันทึกที่สอง แต่ฉันได้เพิ่มขนาดเริ่มต้นของไฟล์บันทึกปัจจุบันเป็น 30GB ในระหว่างการรันครั้งล่าสุดของฉันถูกตั้งค่าเป็น 20GB แต่ก็ยังล้มเหลว
Jimbo

การมีไฟล์บันทึกที่สองจะดีกว่าการมีไฟล์ขนาดใหญ่เนื่องจากฉันมีเพียงไดรฟ์เดียวที่จะทำงาน
Jimbo

อย่างที่ฉันจำได้ตอนนี้ไฟล์เพิ่มเติมส่วนใหญ่ทำให้เราสามารถเข้าถึงไดรฟ์อื่นที่ใหญ่กว่าได้
Mike Henderson

2
ข้อมูลถูกนำเข้ามากแค่ไหน? หากคุณกำลังนำเข้าข้อมูล 30 GB ไฟล์บันทึกของคุณอาจต้องมีขนาดใหญ่เป็นอย่างน้อย
Mike Henderson

3
ขนาดบันทึกเป็นกุญแจสำคัญ งานปัจจุบันล้มเหลวอีกแล้วและฉันแทบไม่เชื่อสายตาตัวเองเมื่อเห็นขนาดของล็อกไฟล์ในจุดที่มันล้มเหลว มันประมวลผลเพียงครึ่งหนึ่งของบัญชีและอยู่ที่ 53GB แล้ว ดูเหมือนว่าฉันจะต้องเคลียร์ที่ไหนสักแห่งในบริเวณใกล้เคียงอีก 60-70GB เพื่อให้กระบวนการนี้เสร็จสมบูรณ์
Jimbo

96

ในการแก้ไขปัญหานี้ให้เปลี่ยนRecovery Modelเป็นSimpleจากนั้นShrink Files Log

1. คุณสมบัติฐานข้อมูล> ตัวเลือก> โมเดลการกู้คืน> แบบง่าย

2. งานฐานข้อมูล> ย่อขนาด> ไฟล์> บันทึก

เสร็จแล้ว

จากนั้นตรวจสอบขนาดไฟล์บันทึกฐานข้อมูลของคุณที่ คุณสมบัติฐานข้อมูล> ไฟล์> ไฟล์ฐานข้อมูล> เส้นทาง

ในการตรวจสอบบันทึกเซิร์ฟเวอร์ sql แบบเต็ม: เปิด Log File Viewer ที่ SSMS> ฐานข้อมูล> การจัดการ> บันทึกเซิร์ฟเวอร์ SQL> ปัจจุบัน


10
ไม่นั่นไม่สามารถแก้ปัญหาได้ ปัญหาคือไฟล์บันทึกขยายตัวในระหว่างกระบวนการทำงานที่ยาวนานจนพื้นที่ดิสก์หมด ได้รับการแก้ไขโดยการย้ายไฟล์บันทึกชั่วคราวไปยังไดรฟ์อื่นที่มีพื้นที่ว่าง 1TB คุณไม่สามารถย่อขนาดไฟล์บันทึกในขณะที่กำลังดำเนินการอยู่ซึ่งกำลังดำเนินการเปิดธุรกรรมอยู่เป็นเวลานาน กระบวนการนั้นรับผิดชอบ แต่เพียงผู้เดียวสำหรับการเติบโตของไฟล์
Jimbo

ตามที่ @Jimbo ได้กล่าวไปแล้วสิ่งนี้ไม่สามารถแก้ไขปัญหาของ OP ได้ อาจเพิ่มพื้นที่ว่างที่ไม่ได้ใช้ในปัจจุบัน แต่ทันทีที่มีการเรียกใช้ธุรกรรมที่ยาวนานอีกครั้งพื้นที่จะถูกใช้อีกครั้ง (และอาจล้มเหลวก่อนหน้านี้)
Marcel

สมบูรณ์แบบ! ขอบคุณ!
Yuri Monteiro

นั่นไม่ได้ช่วยแก้ปัญหา บันทึกของฉันมีเพียง 500 ไบต์ ฉันคิดว่าปัญหานี้เริ่มต้นขึ้นหลังจากที่ฉันทำการสำรองข้อมูลเมื่อวานนี้
Ricardo França

นี่เป็นการแก้ไขอย่างแน่นอนหากคุณมีเมกะไบต์เหลืออยู่สองสามเมกะไบต์สำหรับไดรฟ์เต็ม
Steve Bauman

37

ฉันมีข้อผิดพลาดนี้หนึ่งครั้งและลงเอยด้วยการเป็นฮาร์ดไดรฟ์ของเซิร์ฟเวอร์ที่มีพื้นที่ดิสก์ไม่เพียงพอ


1
อ่านการอัปเดตของ OP สิ่งนี้กลายเป็นปัญหา
Colm

18

คุณเปิดใช้งาน Enable AutogrowthและUnrestricted File Growthสำหรับล็อกไฟล์หรือไม่ คุณสามารถแก้ไขผ่าน SSMS ใน "คุณสมบัติฐานข้อมูล> ไฟล์"


ใช่. ตั้งค่าเป็น autogrow 10% ไม่ จำกัด ปัญหาคือ autogrow จะไม่ทำงานในขณะที่มีธุรกรรมเปิดอยู่
Jimbo

1
คุณมีความคิดว่าธุรกรรมจะใหญ่แค่ไหน? พยายามตั้งค่าขนาดบันทึกธุรกรรมให้ใหญ่กว่าการประมาณนั้นอย่างไรก็ตามหากการจัดสรรดิสก์ไม่ใช่ปัญหาให้จัดสรรพื้นที่ว่างในตอนต้นสำหรับข้อมูลและบันทึกด้วย ช่วยเพิ่มประสิทธิภาพ อย่าให้เราเติบโตอัตโนมัติ 10%ทำเพียงไม่กี่ GB ดังนั้นประสิทธิภาพจะดีพอ
Luis LL

3
SQL Server จะเขียนล็อกอัตโนมัติในระหว่างการทำธุรกรรมหากต้องการพื้นที่เพิ่มเติมในการทำธุรกรรมนั้น
Ross McNab

สวัสดี Ross ฉันได้ให้เหตุผลของฉันในการคิดว่าธุรกรรมที่เปิดอยู่นั้นขัดขวางการเติบโตในการอัปเดตคำถาม ฉันใช้เหตุผลไม่ถูกต้องหรือไม่?
Jimbo

1
@Jimbo SQL Server ไม่ต้องการให้คุณจองไว้ ถ้าคุณมี autogrow SQL Server จะทำการย้ายอัตโนมัติระหว่างการทำธุรกรรม การมีขนาดใหญ่พอจะช่วยประหยัดเวลาได้มาก แต่ไม่ควรส่งผลกระทบต่อกระบวนการ
Luis LL

10

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


1
น่าเสียดายที่ฉันไม่สามารถควบคุมวิธีการดำเนินการได้ Dynamics CRM เป็นแอปพลิเคชันของ Microsoft และกระบวนการนำเข้าองค์กรเป็นส่วนหนึ่งของแอปพลิเคชันนั้น
Jimbo

1

สิ่งต่อไปนี้จะตัดทอนบันทึก

USE [yourdbname] 
GO

-- TRUNCATE TRANSACTION LOG --
DBCC SHRINKFILE(yourdbname_log, 1)
BACKUP LOG yourdbname WITH TRUNCATE_ONLY
DBCC SHRINKFILE(yourdbname_log, 1)
GO

-- CHECK DATABASE HEALTH --
ALTER FUNCTION [dbo].[checker]() RETURNS int AS BEGIN  RETURN 0 END
GO

4
เฮ้ Pinal ฟังก์ชันนี้ถูกลบออกอย่างสมบูรณ์จาก SQL Server 2008 ขึ้นไป: brentozar.com/archive/2009/08/…
Conor

3
สำหรับรุ่นที่ใหม่กว่าให้ลอง BACKUP LOG <myDB> TO DISK = N'NUL: '
HansLindgren

1

LOG_BACKUPถ้าแบบกู้คืนฐานข้อมูลของคุณเต็มและคุณไม่ได้มีการวางแผนการบำรุงรักษาบันทึกสำรองคุณจะได้รับข้อผิดพลาดนี้เพราะล็อกธุรกรรมจะกลายเป็นไปเนื่องจากเต็ม

ซึ่งจะป้องกันการดำเนินการใด ๆ กับฐานข้อมูลนี้ (เช่นย่อขนาด) และ SQL Server Database Engine จะเพิ่มข้อผิดพลาด 9002

เพื่อเอาชนะพฤติกรรมนี้ฉันขอแนะนำให้คุณตรวจสอบสิ่งนี้บันทึกธุรกรรมสำหรับฐานข้อมูล 'SharePoint_Config' เต็มเนื่องจาก LOG_BACKUPที่แสดงขั้นตอนโดยละเอียดในการแก้ไขปัญหา


0

ฉันพบข้อผิดพลาด: "บันทึกธุรกรรมสำหรับฐานข้อมูล" ... "เต็มเนื่องจาก" ACTIVE_TRANSACTION "ในขณะที่ลบแถวเก่าออกจากตารางในฐานข้อมูลของฉันเพื่อเพิ่มพื้นที่ว่างในดิสก์ฉันตระหนักว่าข้อผิดพลาดนี้จะเกิดขึ้นหากจำนวนแถวถึง ถูกลบมากกว่า 1000000 ในกรณีของฉันดังนั้นแทนที่จะใช้ 1 คำสั่ง DELETE ฉันแบ่งงานลบโดยใช้คำสั่ง DELETE TOP (1000000) ....

ตัวอย่างเช่น:

แทนที่จะใช้คำสั่งนี้:

DELETE FROM Vt30 WHERE Rt < DATEADD(YEAR, -1, GETDATE())

ใช้คำสั่งต่อไปนี้ซ้ำ ๆ :

DELETE TOP(1000000) FROM Vt30 WHERE Rt < DATEADD(YEAR, -1, GETDATE())

0

ปัญหาของฉันแก้ไขได้ด้วยการดำเนินการลบแบบ จำกัด หลายครั้งเช่น

ก่อน

DELETE FROM TableName WHERE Condition

หลังจาก

DELETE TOP(1000) FROM TableName WHERECondition

-1

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

ตัวเลือกอื่น ๆ ที่คุณมีคือการแยกการผสาน (เพิ่มขึ้น) ออกเป็นสองการดำเนินการ หนึ่งที่ทำการแทรกและอีกอันที่ทำการอัพเดตและลบ


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

-1

ลองสิ่งนี้:

USE YourDB;  
GO  
-- Truncate the log by changing the database recovery model to SIMPLE.  
ALTER DATABASE YourDB
SET RECOVERY SIMPLE;  
GO  
-- Shrink the truncated log file to 50 MB.  
DBCC SHRINKFILE (YourDB_log, 50);  
GO  
-- Reset the database recovery model.  
ALTER DATABASE YourDB
SET RECOVERY FULL;  
GO 

ฉันหวังว่ามันจะช่วยได้


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

-1

นี่คือรหัสฮีโร่ของฉัน ฉันประสบปัญหานี้ และใช้รหัสนี้เพื่อแก้ไขปัญหานี้

 USE master;

    SELECT 
        name, log_reuse_wait, log_reuse_wait_desc, is_cdc_enabled 
    FROM 
        sys.databases 
    WHERE 
        name = 'XX_System';

    SELECT DATABASEPROPERTYEX('XX_System', 'IsPublished');


    USE XX_System;
    EXEC sp_repldone null, null, 0,0,1;
    EXEC sp_removedbreplication XX_System;


    DBCC OPENTRAN;
    DBCC SQLPERF(LOGSPACE);
    EXEC sp_replcounters;



    DBCC SQLPERF(LOGSPACE);

โปรดใส่คำตอบของคุณในบริบทเสมอแทนที่จะวางโค้ด ดูที่นี่สำหรับรายละเอียดเพิ่มเติม
gehbiszumeis

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.