Il log delle transazioni per il database è pieno


108

Ho un lungo processo che tiene aperta una transazione per l'intera durata.

Non ho alcun controllo sul modo in cui viene eseguito.

Poiché una transazione viene tenuta aperta per l'intera durata, quando il registro delle transazioni si riempie, SQL Server non può aumentare la dimensione del file di registro.

Quindi il processo fallisce con l'errore "The transaction log for database 'xxx' is full".

Ho tentato di impedirlo aumentando la dimensione del file di registro delle transazioni nelle proprietà del database, ma ottengo lo stesso errore.

Non sono sicuro di cosa dovrei provare dopo. Il processo dura diverse ore, quindi non è facile giocare per tentativi ed errori.

Qualche idea?

Se qualcuno è interessato, il processo è un'importazione dell'organizzazione in Microsoft Dynamics CRM 4.0.

C'è molto spazio su disco, abbiamo il registro in modalità di registrazione semplice e abbiamo eseguito il backup del registro prima di avviare il processo.

- = - = - = - = - AGGIORNAMENTO - = - = - = - = -

Grazie a tutti per i commenti finora. Quanto segue è ciò che mi ha portato a credere che il log non sarebbe cresciuto a causa della transazione aperta:

Ricevo il seguente errore ...

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

Quindi seguendo quel consiglio sono andato a " log_reuse_wait_desc column in sys.databases" e ha tenuto il valore " ACTIVE_TRANSACTION".

Secondo Microsoft: http://msdn.microsoft.com/en-us/library/ms345414(v=sql.105).aspx

Ciò significa quanto segue:

Una transazione è attiva (tutti i modelli di ripristino). • Potrebbe esistere una transazione di lunga durata all'inizio del backup del log. In questo caso, liberare lo spazio potrebbe richiedere un altro backup del log. Per ulteriori informazioni, vedere "Transazioni attive di lunga durata" più avanti in questo argomento.

• Viene differita una transazione (solo SQL Server 2005 Enterprise Edition e versioni successive). Una transazione differita è effettivamente una transazione attiva il cui rollback è bloccato a causa di una risorsa non disponibile. Per informazioni sulle cause delle transazioni differite e su come spostarle fuori dallo stato differito, vedere Transazioni differite.

Ho frainteso qualcosa?

- = - = - = - AGGIORNAMENTO 2 - = - = - = -

Ho appena avviato il processo con la dimensione del file di registro iniziale impostata su 30 GB. Questo richiederà un paio d'ore per completare.

- = - = - = - AGGIORNAMENTO finale - = - = - = -

Il problema era effettivamente causato dal file di registro che consumava tutto lo spazio disponibile su disco. Nell'ultimo tentativo ho liberato 120 GB e lo utilizzava ancora tutto e alla fine non è riuscito.

Non mi ero reso conto che ciò stesse accadendo in precedenza perché quando il processo era in esecuzione durante la notte, tornava indietro in caso di fallimento. Questa volta sono stato in grado di controllare la dimensione del file di registro prima del rollback.

Grazie a tutti per il vostro contributo.


re "... ed è stato eseguito il backup del registro" .... se il database è in modalità semplice, non sarà possibile eseguire il backup del registro, i backup del registro non sono applicabili per la modalità semplice. È registrato in blocco?
SqlACID

1
Ho eseguito il backup dell'intero DB e l'ho ridotto, il che ha comportato la riduzione del registro a 1 MB. Ho quindi aumentato la dimensione del file di registro inizialmente a 20 GB e ora a 30 GB.
Jimbo

Risposte:


19

È un copione una tantum o un lavoro che si verifica regolarmente?

In passato, per progetti speciali che richiedono temporaneamente molto spazio per il file di registro, ho creato un secondo file di registro e l'ho reso enorme. Una volta completato il progetto, abbiamo rimosso il file di registro aggiuntivo.


Non direi che è un lavoro una tantum, ma è raro che dobbiamo farlo. Non ho creato un secondo file di registro, ma ho aumentato la dimensione iniziale del mio file di registro corrente a 30 GB. Durante la mia ultima esecuzione era impostato su 20 GB e ancora non funzionava.
Jimbo

Avere un secondo file di registro sarebbe in qualche modo meglio che averne uno grande dato che ho solo un disco con cui lavorare?
Jimbo

Per quanto ricordo ora, il file aggiuntivo ci ha permesso principalmente di accedere a un'altra unità più grande.
Mike Henderson

2
Quanto sono grandi i dati importati? Se stai importando 30 GB di dati, il tuo file di registro potrebbe dover essere grande almeno quanto
Mike Henderson

3
La dimensione del registro è la chiave. L'attività corrente non è riuscita di nuovo e non potevo credere ai miei occhi quando ho visto la dimensione del file di registro nel punto in cui non era riuscito. Ha elaborato solo la metà degli account ed era già a 53 GB. Sembra che dovrò cancellare da qualche parte in prossimità di altri 60-70 GB per poter completare questo processo.
Jimbo

95

Per risolvere questo problema, modificare il modello di ripristino in Semplice, quindi ridurre il registro dei file

1. Proprietà database> Opzioni> Modello di ripristino> Semplice

2. Attività database> Riduci> File> Registro

Fatto.

Quindi controlla la dimensione del file di registro del database in Proprietà database> File> File di database> Percorso

Per controllare il log completo del server SQL: apri il Visualizzatore file di log in SSMS> Database> Gestione> Registri SQL Server> Corrente


10
No, questo non risolve il problema. Il problema era che il file di registro cresceva durante un lungo processo fino a quando non esauriva lo spazio su disco. È stato corretto spostando temporaneamente il file di registro su un'altra unità con 1 TB di spazio disponibile. Non è possibile ridurre il file di registro mentre è in corso un processo di lunga esecuzione, che tiene aperta una transazione. Quel processo era l'unico responsabile della crescita del file.
Jimbo

Come ha già detto @Jimbo, questo non risolve il problema dell'OP. Potrebbe liberare dello spazio attualmente inutilizzato, ma non appena una lunga transazione sarà di nuovo in esecuzione, lo spazio verrà ripreso (e probabilmente fallirà anche prima)
Marcel

Perfetto! Grazie!
Yuri Monteiro

Questo non ha risolto il problema. Il mio registro ha solo 500 byte. Penso che questo problema sia iniziato dopo aver fatto un backup ieri.
Ricardo França

Questa è sicuramente la soluzione se hai ancora un paio di megabyte da risparmiare sull'unità completa.
Steve Bauman

36

Ho avuto questo errore una volta ed è finito per essere il disco rigido del server che esaurisce lo spazio su disco.


1
Leggi gli aggiornamenti dell'OP. Questo si è rivelato essere il problema.
Colm

18

Sono abilitate entrambe le funzioni Abilita crescita automatica e Crescita file illimitata per il file di registro? Puoi modificarli tramite SSMS in "Proprietà database> File"


Sì. È impostato per aumentare automaticamente il 10%, senza restrizioni. Il problema è che l'aumento automatico delle dimensioni non funzionerà durante una transazione aperta.
Jimbo

1
Hai idea di quanto sarà grande la transazione? prova a impostare la dimensione del registro delle transazioni più grande di quella stima, comunque se l'allocazione del disco non è un problema, alloca all'inizio molto spazio, anche per i dati e il registro. Migliora le prestazioni. Non aumentare automaticamente del 10% , fallo con pochi GB, quindi le prestazioni saranno abbastanza buone.
Luis LL

3
SQL Server aumenterà automaticamente il log durante una transazione se è necessario più spazio per completare quella transazione.
Ross McNab

Ciao Ross, ho fornito la mia logica per pensare che la transazione aperta stia impedendo la crescita di un aggiornamento alla domanda. Sono errato nel mio ragionamento?
Jimbo

1
@Jimbo SQL Server non richiede di averlo riservato. Se si dispone di aumento automatico delle dimensioni, SQL Server esegue l'aumento automatico delle dimensioni durante la transazione. Averlo abbastanza grande può far risparmiare molto tempo, ma non dovrebbe influire sul processo.
Luis LL

10

Questo è un approccio vecchia scuola, ma se stai eseguendo un aggiornamento iterativo o un'operazione di inserimento in SQL, qualcosa che viene eseguito per molto tempo, è una buona idea chiamare periodicamente (programmaticamente) "checkpoint". La chiamata "checkpoint" fa sì che SQL scriva su disco tutte quelle modifiche di sola memoria (vengono chiamate pagine sporche) e gli elementi memorizzati nel registro delle transazioni. Ciò ha l'effetto di ripulire periodicamente il registro delle transazioni, prevenendo così problemi come quello descritto.


1
Purtroppo non ho alcun controllo sul modo in cui viene eseguito il processo. Dynamics CRM è un'applicazione Microsoft e il processo di importazione dell'organizzazione fa parte di tale applicazione.
Jimbo

1

Quanto segue troncerà il registro.

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
Ehi Pinal, questa funzionalità è stata rimossa completamente da SQL Server 2008 e versioni successive: brentozar.com/archive/2009/08/…
Conor

3
Con le versioni successive, prova BACKUP LOG <myDB> TO DISK = N'NUL: '
HansLindgren

1

Se il modello di ripristino del database è pieno e non si dispone di un piano di manutenzione del backup del log, verrà visualizzato questo errore perché il log delle transazioni è pieno a causa di LOG_BACKUP.

Ciò impedirà qualsiasi azione su questo database (ad esempio, la riduzione) e il motore di database di SQL Server genererà un errore 9002.

Per ovviare a questo comportamento ti consiglio di controllare questo Il log delle transazioni per il database 'SharePoint_Config' è pieno a causa di LOG_BACKUP che mostra i passaggi dettagliati per risolvere il problema.


0

Ho riscontrato l'errore: "Il log delle transazioni per il database" ... "è pieno a causa di" ACTIVE_TRANSACTION "durante l'eliminazione di vecchie righe dalle tabelle del mio database per liberare spazio su disco. Mi sono reso conto che questo errore si sarebbe verificato se il numero di righe da essere cancellato era più grande di 1000000. Così, invece di usare 1 istruzione DELETE, ho diviso l'attività di cancellazione usando DELETE TOP (1000000) .... istruzione.

Per esempio:

invece di usare questa dichiarazione:

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

usando ripetutamente la seguente dichiarazione:

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

0

Il mio problema è stato risolto con l'esecuzione multipla di eliminazioni limitate come

Prima

DELETE FROM TableName WHERE Condition

Dopo

DELETE TOP(1000) FROM TableName WHERECondition

-1

La risposta alla domanda non sta eliminando le righe da una tabella ma è lo spazio tempDB che viene occupato a causa di una transazione attiva. questo accade principalmente quando è in esecuzione una fusione (upsert) in cui proviamo a inserire l'aggiornamento ed eliminare le transazioni. L'unica opzione è assicurarsi che il database sia impostato su un modello di ripristino semplice e aumentare il file allo spazio massimo (aggiungere un altro gruppo di file). Sebbene questo abbia i suoi vantaggi e svantaggi, queste sono le uniche opzioni.

L'altra opzione che hai è dividere l'unione (upsert) in due operazioni. uno che fa l'inserimento e l'altro che aggiorna ed elimina.


Se leggi la domanda, sapresti che il DB era già in modalità di ripristino semplice mentre stava accadendo. Questo non aiuta quando si dispone di una transazione aperta di lunga durata. Il file continua a crescere fino a quando non viene eseguito il commit o il rollback della transazione. Leggi la prima riga della domanda "Ho un lungo processo che tiene aperta una transazione per l'intera durata".
Jimbo

-1

Prova questo:

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 

Spero possa essere d'aiuto.


Questa è stata una delle prime cose tentate ed è persino menzionata nel testo della domanda. Ciò non risolve il problema di una singola transazione aperta che riempie il registro e utilizza tutto lo spazio disponibile su disco. L'intero processo si è svolto in modalità semplice. Tuttavia, sei una delle tante persone che ha offerto questa risposta esatta non avendo letto la domanda ...
Jimbo,

-1

Ecco il mio codice eroe. Ho affrontato questo problema. E usa questo codice per risolvere questo problema.

 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);

Inserisci la tua risposta sempre nel contesto invece di incollare semplicemente il codice. Vedi qui per maggiori dettagli.
gehbiszumeis

-1

Prova questo:

Se possibile, riavviare i servizi MSSQLSERVER e SQLSERVERAGENT .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.