none
Crash EventLog.. RRS feed

  • Domanda

  • Ciao,

    Questa mattina lanciando il sito web che utilizza SQL SERVER 2008 R2 presenta questo alert :

    Source: .Net SqlClient Data Provider

    Class: 17
    Number: 1105
    Procedure: AddEventLog
    Message: System.Data.SqlClient.SqlException: Could not allocate space for object 'dbo.EventLog'.'PK_EventLogMaster' in database 'NOMEDELDATABASE' because the 'PRIMARY' filegroup is full...

    Cosa e' successo ? Il database sembra cresciuto tantissimo, da 64 MB a 10.240 MB.

    E possibile recuperare?

    Ho notato che si puo' fare lo Shrink cliccxando con il tasto destro sul database / Tasks / Shrink / qui ci sono 2 voci: Database e Files, a suo tempo con SQL Server 2005 lo Shrink lo facevo schedulato da Management / Maintenance Plans , non esiste piu' questa funzione ? E' consigliabile fare lo Shrink schedulato ogni giorno?

    Grazie

    mercoledì 30 gennaio 2013 07:48

Risposte

  • Allora.. andando per gradi.. se è l'edizione express lo vedi principalmente dal fatto che non l'hai pagata.. (:

    Comunque, c'è un comando che ti restituisce la versione.. lancia in un foglio di query questo

    select serverproperty('edition')

    Seconda di poi, come vedi dalle dimensioni la cosa che è aumentata a sproposito è il file .mdf, dunque quello che contiene i dati.

    L'autogrowth consiste nel dare la possibilità di espandere dinamicamente un archivio (è un termine generico che viene applicato in più campi, in questo caso il file del database) della quantità di spazio preconfigurata.. mi spiego meglio.. 

    Hai un file di database da 1gb preallocato e hai impostato l'autogrowth a 1gb.. questo vuol dire che quando il file arriverà a riempire il primo giga, ne allocherà un'altro e immagazzinerà altre informazioni in quel nuovo giga disponibile.. se nel tuo caso in una notte è cresciuto di 10 giga senza che venissero aggiunte realmente informazioni, probabilmente in configurazione l'hai impostato che abbia una crescita con un passo di 10... può essere? In più, la versione Express di SQL Server 2008 permette database fino a 10 gb se non ricordo male.. e forse da li nascono i tuoi problemi.

    Fai click sul database col pulsante destro e verifica queste informazioni nella sezione "Files"

    • Contrassegnato come risposta pierino20071 giovedì 31 gennaio 2013 13:15
    mercoledì 30 gennaio 2013 09:18
  • L'autogrow secondo me dev'essere un buon compromesso tra spazio, performance e frequenza di aggiornamento dei dati. Mi spiego meglio.. se hai un database che parte da 100mb in cui inserisci ogni giorno per 20 volte 10 mb di informazioni, ti converrà impostare un grow di almeno 200/210 mb alla volta in modo che il sistema non si appesantisca nel tentativo continuo di allocare spazio..

    Aspetta a dire non si recupera.. ancora non abbiamo capito quale sia il tuo problema, io ho fatto delle ipotesi.. e già il fatto che avete aggiornato il CMS, indica un grosso cambiamento nel tuo database.. altro che "non è successo nulla" (:

    Che CMS hai caricato?

    Hai provato a vedere se si sono riscontrati problemi simili durante aggiornamento nei forum del produttore del CMS?

    Provato a controllare effettivamente dov'è che si è gonfiato il tuo database (su quale/quali tabelle) ?

    Questa query può aiutarti nel controllo.

    WITH DataPages AS
    (
    	SELECT 
    		o.object_id, COALESCE(f.name,d.name) AS Storage, s.name AS SchemaName, o.name AS TableName, COUNT(DISTINCT p.partition_id) AS NumberOfPartitions, 
    		CASE MAX(i.index_id) WHEN 1 THEN 'Cluster' ELSE 'Heap' END AS TableType, 
    		SUM(p.rows) AS [RowCount], 
    		SUM(a.total_pages) AS DataPages
    	FROM sys.tables o
    	JOIN sys.indexes i ON i.object_id = o.object_id
    	JOIN sys.partitions p ON p.object_id = o.object_id AND p.index_id = i.index_id
    	JOIN sys.allocation_units a ON a.container_id = p.partition_id
    	JOIN sys.schemas s ON s.schema_id = o.schema_id
    	LEFT JOIN sys.filegroups f ON f.data_space_id = i.data_space_id
    	LEFT JOIN sys.destination_data_spaces dds ON dds.partition_scheme_id = i.data_space_id AND dds.destination_id = p.partition_number
    	LEFT JOIN sys.filegroups d ON d.data_space_id = dds.data_space_id
    	WHERE 
    	o.type = 'U' AND 
    	i.index_id IN (0,1)
    	GROUP BY 
    	s.name, COALESCE(f.name,d.name), o.name, o.object_id 
    ),
    IndexPages AS
    (
    	SELECT o.object_id, o.name AS TableName, COALESCE(f.name,d.name) AS Storage, COUNT(DISTINCT i.index_id) AS NumberOfIndexes, SUM(a.total_pages) AS IndexPages
    	FROM sys.objects o
    	JOIN sys.indexes i ON i.object_id = o.object_id
    	JOIN sys.partitions p ON p.object_id = o.object_id AND p.index_id = i.index_id
    	JOIN sys.allocation_units a ON a.container_id = p.partition_id
    	LEFT JOIN sys.filegroups f ON f.data_space_id = i.data_space_id
    	LEFT JOIN sys.destination_data_spaces dds ON dds.partition_scheme_id = i.data_space_id AND dds.destination_id = p.partition_number
    	LEFT JOIN sys.filegroups d ON d.data_space_id = dds.data_space_id
    	WHERE i.index_id <> 0
    	GROUP BY 
    	o.name, o.object_id, COALESCE(f.name,d.name)
    )
     
    SELECT 
    	t.[SchemaName], t.[TableName], t.[TableType], t.[Storage] AS FileGroupName, t.[NumberOfPartitions], 
    	t.[RowCount], t.[DataPages], (t.[DataPages] * 8) AS SizeOfDataPagesKB, ISNULL(i.[NumberOfIndexes],0) AS NumberOfIndexes, 
    	ISNULL(i.[IndexPages],0) AS IndexPages, (ISNULL(i.[IndexPages],0) * 8) AS SizeOfIndexPagesKB
    FROM DataPages t
    LEFT JOIN IndexPages i ON i.object_id = t.object_id	AND i.Storage = t.Storage
    ;

    • Proposto come risposta _ Luca Gaspari giovedì 31 gennaio 2013 13:10
    • Contrassegnato come risposta pierino20071 giovedì 31 gennaio 2013 13:15
    mercoledì 30 gennaio 2013 12:20
  • Bene.. (: 

    pare tu abbia trovato cosa ha riempito il tuo database!!

    Ora non ti resta che vedere cosa c'è dentro quella tabella, anche se da quel che dice il nome è una tabella di log ( quindi informazioni su cose che sono successe nel tuo sistema ) e capire come mai ti sono stati inseriti più di 3 milioni di record durante la nottata.

    Questo ovviamente per farlo devi leggere (quantomeno gli ultimi log inseriti per capire cosa ci sta scrivendo dentro) ed individuare con che frequenza/chi/cosa li scrive.. magari è solo un bug, per questo puoi sentire quelli che sviluppano il tuo gestionale.

    • Contrassegnato come risposta pierino20071 giovedì 31 gennaio 2013 13:16
    mercoledì 30 gennaio 2013 15:59

Tutte le risposte

  • Ciao Pierino.. (:

    prima di tutto fai un bel backup del tuo database se non hai già l'ultimo salvataggio archiviato, così qualsiasi cosa ci si faccia sopra è recuperabile.

    Quanto spazio effettivo occupano i file .mdf e .ldf? Ci sono state procedure notturne che possono aver riempito il db? Il tuo SQL 2008 è l'edizione Express?

    Seconda di poi, hai impostato l'autogrowth del database? Se si, a quanto l'hai impostato? 

    La mia ipotesi è che tu abbia una versione express del dbms (che permette massimo database da 10 gb), hai impostato un autogrowth troppo alto e di conseguenza nel momento che si espande ti blocca tutto.. 

    mercoledì 30 gennaio 2013 08:53
  • Ciao Luca,

    Dovrebbe essere l' Edizione Express, ma da dove lo vedo? 

    Il file .mdf e' di 10.485.760 KB

    Il file .ldf e' di 1.024 KB

    Non so cosa sia l' autogrowth, come lo vedo? Sarebbe lo Shrink? 

    Secondo te e' una situazione recuperabile ?

    Grazie


    mercoledì 30 gennaio 2013 09:07
  • Allora.. andando per gradi.. se è l'edizione express lo vedi principalmente dal fatto che non l'hai pagata.. (:

    Comunque, c'è un comando che ti restituisce la versione.. lancia in un foglio di query questo

    select serverproperty('edition')

    Seconda di poi, come vedi dalle dimensioni la cosa che è aumentata a sproposito è il file .mdf, dunque quello che contiene i dati.

    L'autogrowth consiste nel dare la possibilità di espandere dinamicamente un archivio (è un termine generico che viene applicato in più campi, in questo caso il file del database) della quantità di spazio preconfigurata.. mi spiego meglio.. 

    Hai un file di database da 1gb preallocato e hai impostato l'autogrowth a 1gb.. questo vuol dire che quando il file arriverà a riempire il primo giga, ne allocherà un'altro e immagazzinerà altre informazioni in quel nuovo giga disponibile.. se nel tuo caso in una notte è cresciuto di 10 giga senza che venissero aggiunte realmente informazioni, probabilmente in configurazione l'hai impostato che abbia una crescita con un passo di 10... può essere? In più, la versione Express di SQL Server 2008 permette database fino a 10 gb se non ricordo male.. e forse da li nascono i tuoi problemi.

    Fai click sul database col pulsante destro e verifica queste informazioni nella sezione "Files"

    • Contrassegnato come risposta pierino20071 giovedì 31 gennaio 2013 13:15
    mercoledì 30 gennaio 2013 09:18
  • Ok,

    La versione l' ho vista lanciando questa query:

    SELECT SERVERPROPERTY('Edition') AS Edizione;

    Express Edition with Advanced Services (64-bit)

    Quindi e' Express

    Nella sezione Files

    Devo cambiare qualcosa?

    Grazie


    mercoledì 30 gennaio 2013 10:03
  • Bhé, l'autogrowth sembra a posto, l'errore potrebbe essere appunto nelle dimensioni del file.

    Prova ad eseguire il comando qua sotto e controlla le dimensioni/il funzionamento

    DBCC SHRINKDATABASE('TuoDatabase')

    mercoledì 30 gennaio 2013 10:33
  • Ok, cosa vuol dire sembra a posto? si puo' settare ?

    Cmq ho lanciato il comando:

    DBCC SHRINKDATABASE('TuoDatabase')

    Vien fuori quanto sopra, cosa e' successo? Il file .mdf e' sempre uguale come dimensioni...

    Grazie

    mercoledì 30 gennaio 2013 10:53
  • Si, è settabile quel parametro.. si può impostare un valore percentuale o un valore fisso in kilo, mega, giga etc..  

    Quello che mi suona davvero strano è che tu mi dici che il database è cresciuto tantissimo (da 64 mega a 10 giga) senza effettuare nessuna operazione.. la prima cosa a cui ho pensato è che avessi una growth ratio nell'ordine dei giga.. guardando però lo spazio usato, sembra tutto pieno.. 

    Sei sicuro dei 64 mega iniziali? Sei sicuro che stanotte non sia girato qualcosa che magari creando un loop ti ha riempito il database fino al limite di SQL Server?

    mercoledì 30 gennaio 2013 11:39
  • Puo' essere accaduto a seguito di un aggiornamento del CMS effettuato ieri. Nel frattempo ho ripristinato una copia, purtroppo non aggiornatissima, e la dimensione del database e' di 45 MB.

    Secondo te non si recupera? Anche per vedere se e' possibile.

    Cmq come dovrei impostare l' autogrow? Ci sono delle regole? Magari evito un crash futuro...

    Grazie

    mercoledì 30 gennaio 2013 12:02
  • L'autogrow secondo me dev'essere un buon compromesso tra spazio, performance e frequenza di aggiornamento dei dati. Mi spiego meglio.. se hai un database che parte da 100mb in cui inserisci ogni giorno per 20 volte 10 mb di informazioni, ti converrà impostare un grow di almeno 200/210 mb alla volta in modo che il sistema non si appesantisca nel tentativo continuo di allocare spazio..

    Aspetta a dire non si recupera.. ancora non abbiamo capito quale sia il tuo problema, io ho fatto delle ipotesi.. e già il fatto che avete aggiornato il CMS, indica un grosso cambiamento nel tuo database.. altro che "non è successo nulla" (:

    Che CMS hai caricato?

    Hai provato a vedere se si sono riscontrati problemi simili durante aggiornamento nei forum del produttore del CMS?

    Provato a controllare effettivamente dov'è che si è gonfiato il tuo database (su quale/quali tabelle) ?

    Questa query può aiutarti nel controllo.

    WITH DataPages AS
    (
    	SELECT 
    		o.object_id, COALESCE(f.name,d.name) AS Storage, s.name AS SchemaName, o.name AS TableName, COUNT(DISTINCT p.partition_id) AS NumberOfPartitions, 
    		CASE MAX(i.index_id) WHEN 1 THEN 'Cluster' ELSE 'Heap' END AS TableType, 
    		SUM(p.rows) AS [RowCount], 
    		SUM(a.total_pages) AS DataPages
    	FROM sys.tables o
    	JOIN sys.indexes i ON i.object_id = o.object_id
    	JOIN sys.partitions p ON p.object_id = o.object_id AND p.index_id = i.index_id
    	JOIN sys.allocation_units a ON a.container_id = p.partition_id
    	JOIN sys.schemas s ON s.schema_id = o.schema_id
    	LEFT JOIN sys.filegroups f ON f.data_space_id = i.data_space_id
    	LEFT JOIN sys.destination_data_spaces dds ON dds.partition_scheme_id = i.data_space_id AND dds.destination_id = p.partition_number
    	LEFT JOIN sys.filegroups d ON d.data_space_id = dds.data_space_id
    	WHERE 
    	o.type = 'U' AND 
    	i.index_id IN (0,1)
    	GROUP BY 
    	s.name, COALESCE(f.name,d.name), o.name, o.object_id 
    ),
    IndexPages AS
    (
    	SELECT o.object_id, o.name AS TableName, COALESCE(f.name,d.name) AS Storage, COUNT(DISTINCT i.index_id) AS NumberOfIndexes, SUM(a.total_pages) AS IndexPages
    	FROM sys.objects o
    	JOIN sys.indexes i ON i.object_id = o.object_id
    	JOIN sys.partitions p ON p.object_id = o.object_id AND p.index_id = i.index_id
    	JOIN sys.allocation_units a ON a.container_id = p.partition_id
    	LEFT JOIN sys.filegroups f ON f.data_space_id = i.data_space_id
    	LEFT JOIN sys.destination_data_spaces dds ON dds.partition_scheme_id = i.data_space_id AND dds.destination_id = p.partition_number
    	LEFT JOIN sys.filegroups d ON d.data_space_id = dds.data_space_id
    	WHERE i.index_id <> 0
    	GROUP BY 
    	o.name, o.object_id, COALESCE(f.name,d.name)
    )
     
    SELECT 
    	t.[SchemaName], t.[TableName], t.[TableType], t.[Storage] AS FileGroupName, t.[NumberOfPartitions], 
    	t.[RowCount], t.[DataPages], (t.[DataPages] * 8) AS SizeOfDataPagesKB, ISNULL(i.[NumberOfIndexes],0) AS NumberOfIndexes, 
    	ISNULL(i.[IndexPages],0) AS IndexPages, (ISNULL(i.[IndexPages],0) * 8) AS SizeOfIndexPagesKB
    FROM DataPages t
    LEFT JOIN IndexPages i ON i.object_id = t.object_id	AND i.Storage = t.Storage
    ;

    • Proposto come risposta _ Luca Gaspari giovedì 31 gennaio 2013 13:10
    • Contrassegnato come risposta pierino20071 giovedì 31 gennaio 2013 13:15
    mercoledì 30 gennaio 2013 12:20
  • L'autogrow secondo me dev'essere un buon compromesso tra spazio, performance e frequenza di aggiornamento dei dati. Mi spiego meglio.. se hai un database che parte da 100mb in cui inserisci ogni giorno per 20 volte 10 mb di informazioni, ti converrà impostare un grow di almeno 200/210 mb alla volta in modo che il sistema non si appesantisca nel tentativo continuo di allocare spazio..

    Ok, ma io faccio le modifiche ogni tanto sul CMS e non so la quantita' di MB impiegati, cosa mi consigli?

    Aspetta a dire non si recupera.. ancora non abbiamo capito quale sia il tuo problema, io ho fatto delle ipotesi.. e già il fatto che avete aggiornato il CMS, indica un grosso cambiamento nel tuo database.. altro che "non è successo nulla" (:

    Che CMS hai caricato?

    Hai provato a vedere se si sono riscontrati problemi simili durante aggiornamento nei forum del produttore del CMS?

    Provato a controllare effettivamente dov'è che si è gonfiato il tuo database (su quale/quali tabelle) ?

    Questa query può aiutarti nel controllo.

    Fatta la query ma le tabelle sono 171, cosa dovrei guardare x capire? Io vedo una tabella molto grossa:

    mercoledì 30 gennaio 2013 14:25
  • Bene.. (: 

    pare tu abbia trovato cosa ha riempito il tuo database!!

    Ora non ti resta che vedere cosa c'è dentro quella tabella, anche se da quel che dice il nome è una tabella di log ( quindi informazioni su cose che sono successe nel tuo sistema ) e capire come mai ti sono stati inseriti più di 3 milioni di record durante la nottata.

    Questo ovviamente per farlo devi leggere (quantomeno gli ultimi log inseriti per capire cosa ci sta scrivendo dentro) ed individuare con che frequenza/chi/cosa li scrive.. magari è solo un bug, per questo puoi sentire quelli che sviluppano il tuo gestionale.

    • Contrassegnato come risposta pierino20071 giovedì 31 gennaio 2013 13:16
    mercoledì 30 gennaio 2013 15:59
  • Ok, grazie Luca sei stato di immenso aiuto!

    Hem, come leggo una tabella cosi' grossa ?

    Grazie 1000 !

    giovedì 31 gennaio 2013 12:06
  • Di nulla, se pensi che abbia risposto alle tue domande in maniera corretta, premi sul tasto "Segna come risposta" presente sotto le risposte al tuo thread.

    Per fare la selezione di un set di dati limitando i risultati, puoi usare la clausola TOP unita alla percentuale o al numero di record che devono essere restituiti, ti conviene ordinarli per un campo data decrescente se vuoi dare un'occhiata alle registrazioni.

    Ad esempio : 

    -- Selezione percentuale
    SELECT TOP(10) PERCENT id, Message, Data
    FROM EventLog
    ORDER BY Data DESC
    ;
    
    -- Oppure con il numero di record
    SELECT TOP(10) id, Message, Data
    FROM EventLog
    ORDER BY Data DESC
    ;


    Un saluto

    giovedì 31 gennaio 2013 13:09
  • Ok, segnate le risposte !

    Sto guardando ma veramente c'e' una mole impressionante di dati, direi che potrei distinguerli per il campo LogEventID che identifica il tipo di errore. E possibile fare una select che mi ritorni la quantita' dei record associata ad ogni singolo valore del campo LogEvenID ? Cosi' potrei vedere ae c'e' un evento che si e' moltiplicato a valanga.

    Grazie

    giovedì 31 gennaio 2013 13:35
  • Certo, devi usare dei raggruppamenti..

    SELECT TuoCampo, COUNT(TuoCampo) AS Ripetizione FROM TuaTabella GROUP BY TuoCampo

    ;


    giovedì 31 gennaio 2013 13:57
  • Ok, benissimo, grazie.

    Un'ultima questione: cosa dovrei fare affinche' il database venga pulito, riorganizzato automaticamente in modo da avere le migliori condizioni di funzionamento? A suo tempo facevo lo Shrink schedulato con la versione SQL 2005.

    Grazie

    venerdì 1 febbraio 2013 08:51
  • Questa è parecchio aperta come domanda.. :) ahaha..

    di base secondo me dipende sempre dalle dimensioni e dalla frequenza di "popolamento" del database.. non mi sento di darti consigli così, ma lo shrink non è proprio una cosa che schedulerei di frequente.. 

    Il modo migliore a parer mio è fare un controllo della frammentazione degli indici di tanto in tanto e quando possibile lanciare la ricostruzione se necessaria, controllare i piani di esecuzione delle tue procedure e vedere dove puoi avere spazi di miglioramento.. e farsi sempre i problemi giusti in relazione all'entità della cosa che ti trovi davanti.. 

    Non servono aerei per scavalcare i muri, non basta una bici per attraversare l'oceano (:

    venerdì 1 febbraio 2013 08:57
  • Ok, ma come si fa il controllo della frammentazione degli indici e la ricostruzione? E' una cosa che posso schedulare? Esiste una cosa tipo: Management / Maintenance Plans del 2005 ?

    Grazie

    venerdì 1 febbraio 2013 10:25
  • Non credo sia il caso che te lo spieghi io quello.. :) ci sono dozzilioni di articoli sul web che sicuramente ti aiuteranno sui manintenance plan più di quanto possa farlo io..! Se poi hai dei dubbi, scrivi pure! 

    Comunque per gli indici, si, puoi fare una procedura che li controlli ed in caso li ricostruisca.. 


    venerdì 1 febbraio 2013 10:33
  • Ok, grazie hai mica un link sottomano? Io faccio un po' di confusione nelle ricerche.. :-(

    Grazie

    venerdì 1 febbraio 2013 10:47
  • MSDN : Maintenance Plans

    Check index fragmentation

    Il web è grande... (: 

    venerdì 1 febbraio 2013 11:17