Riduci un database al di sotto della sua dimensione iniziale


10

Ho un database di sviluppo di SQL Server 2005 che è una copia di 30 GB di live. Abbiamo eliminato alcuni dati non necessari in dev, il che porta lo spazio del file di dati utilizzato a 20 GB. Quindi abbiamo circa il 33% inutilizzato.

Ho bisogno di recuperare lo spazio, che ci permetterà di avere un secondo DB di sviluppo sul server (basato sulla versione ridotta); tuttavia, non posso recuperare lo spazio, ho fatto quanto segue:

  • La dimensione iniziale del file SMS2_Dataè di 30 GB.

    DBCC SHRINKFILE (N'SMS2_Data' , 0, TRUNCATEONLY)

    seguito da

    DBCC SHRINKFILE (N'SMS2_Data' , 19500)

Nessuna gioia. Ho provato a fare un backup, creando un nuovo DB con una dimensione iniziale bassa quindi ripristinando, senza gioia poiché la dimensione iniziale viene sovrascritta. Hanno anche provato:

ALTER DATABASE SMS2HazSub MODIFY FILE (NAME = 'SMS2_Data', SIZE = 20000) 

Ciò ha errato, dicendo:

MODIFICA FILE non riuscito. La dimensione specificata è inferiore alla dimensione corrente.

Ho provato il 20800 e poi ho continuato a salire fino a 29000 (29GB) e ancora non mi permette di cambiarlo.

Hanno fatto lo strizzacervelli poi cambiato la modalità di recupero da FULLa SIMPLEe viceversa. Nessuna gioia.

Ho pensato che avesse a che fare con alcuni TEXTcampi. Ne abbiamo circa 6 in tutto il sistema. Quindi come test li ho lasciati tutti e poi ho fatto un restringimento del file e ancora nessun cambiamento.

L'unica opzione rimasta è reimportare i dati su un altro DB. Questo non è pratico, come dovrebbe essere fatto sul DB live, che comporta troppi rischi. Prendiamo semi-regolarmente una copia del DB live e sovrascriviamo dev / test. Abbiamo qualcosa come 500 tavoli. Vorrei un modo di farlo che non avrebbe il rischio di esportare dati in un nuovo DB.

Ho provato a spostare i dati in un altro file e ho copiato tutto tranne il 5% dei dati. Questo è ciò che mi ha portato a provare a eliminare tutte le colonne di testo.

Il server è in modalità compatibilità 90, ma è SP2. Ora ho fatto le seguenti 3 volte: reindicizzare tutte le tabelle, il database di backup, il file di riduzione, il database di riduzione. Ancora nessuna gioia.

EXECUTE sp_spaceused ritorna:

database_name   database_size   unallocated space
SMS2Tests       31453.94 MB     13903.16 MB

reserved     data         index_size   unused
16545568 KB  10602264 KB  4254360 KB   1688944 KB

Risposte:


3

Come alcune persone hanno già detto, potresti creare un nuovo database e "copiare" cose dal vecchio database. Questa sarebbe l'opzione migliore per te. Tuttavia ho notato che vuoi farlo abbastanza regolarmente. Quindi l'opzione migliore è Redgate Data Compare e Redgate Compare . Entrambi fanno parte del pacchetto Redgate SqlToolbelt .

Quindi cosa fai:

  1. Creare un DB vuoto con dimensioni iniziali ridotte.
  2. Utilizzare Redgate Compare per copiare la struttura del db, le funzioni ecc. Dal vecchio db
  3. Utilizzare Redgate Data Compare per copiare i dati dal vecchio database al nuovo
  4. Lavori sul database di sviluppo e poi in qualsiasi momento esegui solo Confronto dati e aggiorni regolarmente il DB di sviluppo, oppure se apporti modifiche a db puoi distribuirle usando Redgate Compare e quindi facendo Redgate Data Compare.

Ciò che è buono con Data Compare è che dopo aver copiato quei 30 GB di dati (puoi farlo iniziando solo con alcune tabelle) dopo un po 'deve solo "ricompilare" solo alcune modifiche e non interi 30 GB di dati. Ciò significa che avrà un impatto molto minore su entrambi i database rispetto a copiarlo normalmente.


2

Alcune possibilità qui.

Prima di tutto, sei su SQL 2005 SP3 o versioni successive? Alcuni hanno segnalato problemi SHRINKFILE su versioni precedenti (consultare http://www.sqlservercentral.com/Forums/Topic981292-146-6.aspx#bm985164 )

In secondo luogo, è possibile verificare che il database sia impostato sulla compatibilità con la modalità 90 e non con la modalità 80? Apparentemente questo era un problema con SQL 2000, ma la limitazione è stata eliminata in SQL 2005. Se il database è ancora impostato sulla compatibilità con la modalità 80, questo potrebbe essere ancora un problema.

In terzo luogo, questo potrebbe essere un problema con i dati LOB (text, ntext, varchar (max)). Vedi l'eccellente articolo di Paul Randall qui

Suppongo che tu capisca cosa fa realmente SHRINKing e che possa influenzare negativamente la tua performance:

  • SHRINK funziona spostando ciecamente le pagine dalla fine del file all'inizio
  • Pertanto, può frammentare in modo orribile gli indici, il che può causare significativi problemi di prestazioni
  • Poiché si tratta di un'operazione ad alta intensità di dati, la riduzione potrebbe richiedere molto tempo

Normalmente consiglierei di seguire il restringimento con un reindex completo (che recupererà parte dello spazio che è stato appena liberato), ma non sembra che tu sia nemmeno in grado di arrivare a quel punto.

Se osservi il tuo SPID ridotto nel monitor attività, sembra che stia facendo qualcosa? (I contatori IO e CPU cambiano) O è bloccato? L'unica altra cosa che mi viene in mente è se ci sono altre attività nel database, bloccando la riduzione. Assicurarsi che nessun altro spid attivo stia utilizzando il database in quel momento.

Passare alla modalità di ripristino semplice durante questo processo è anche una buona idea, per evitare che il registro cresca troppo.


1

SHRINKDATABASE ridurrà il database (nella migliore delle ipotesi) al suo MinSize, in modo che non ti aiuti.

Quando si tenta di ridurre il FILE tramite l'interfaccia utente SSMS utilizzando i valori predefiniti, utilizza "DBCC SHRINKFILE (N'MyDB", 0, TRUNCATEONLY) ". Tale comando ridurrà il file (nella migliore delle ipotesi) fino all'ultima estensione assegnata.

Se si desidera ridurre il file al di sotto di MinSize, è sufficiente modificare il parametro DBCC SHRINKFILEda 0 alla dimensione in cui si desidera tentare di ridurre il file in MB. Un numero diverso da zero indicherà a SHRINKFILE di ridurre il file a quella dimensione, se possibile. Quindi DBCC SHRINKFILE('MyDB', 300, TRUNCATEONLY)ridurrà il file a 300 MB se il database ha spazio.

Puoi vedere MinSize eseguendo questo:

DBCC TRACEON(3604)
go
DBCC PAGE('MyDB', 1, 0, 3) with tableresults
go

MinSize in MB è calcolato in questo modo: (MinSize * 8) / 1024


0

Se vuoi davvero farlo:

  • impostato per ripristinare la modalità su semplice
  • fare attenzione a: DBCC SHRINKDATABASE (MyDatabase, TRUNCATEONLY);

0

Se hai, per esempio, 20003 (mb) di dati effettivi nel database, allora "SIZE = 20000" sarebbe troppo piccolo. Prova con 21000 o 25000, vedi se funziona. (E ricorda, 1 GB = 1024 MB.)


0

Provare

DBCC SHRINKDATABASE (N'SMS2_Data' , 0)

L'ho usato su un database SQL 2005 che ho qui e lo spazio allocato per il file di dati è passato da 10,2 GB a 3 GB.

Cordiali saluti, questo è un processo lungo e ci sono voluti poco più di 19 minuti per il mio database.


ps Ho appena controllato e il modello di recupero per il mio database è impostato su Semplice.

Non ha fatto alcuna differenza, sono abbastanza sicuro che sia lo stesso che viene fatto tramite il front-end.

0

Suppongo che tu abbia un singolo file di database con il nome logico SMS2_Data. Nel database sono presenti anche uno o più file di registro delle transazioni.

Hai una sfida che non può essere risolta sulla copia corrente del database. L'importante informazione dichiarata è che la "dimensione originale del file di database è di 30 GB". Sfortunatamente, questo file non può essere ridotto rispetto alla sua dimensione originale.

Come hai già sperimentato, SHRINKDB e SHRINKFILE non ti danno ciò che desideri. Questi comandi seguono la regola non può ridursi più piccola della dimensione originale. Quindi, puoi solo ridurre un database alla dimensione originale e non più piccola.

Anche il backup e il ripristino del database su un database esistente di dimensioni inferiori non funzionano. Quando si esegue un ripristino del database, i file del database vengono ripristinati alle dimensioni dei file come durante il backup. Inoltre, il modello di recupero (semplice, completo, ecc.) Non ha rilevanza per questo problema.

E, ultimo punto di cattive notizie. Potresti considerare di aggiungere altri file di database più piccoli al database, trasferire tutti i dati dal file da 30 GB e quindi rilasciarli. Sfortunatamente, questo non funzionerà neanche perché non è possibile eliminare il file iniziale dal database.

Quindi, la soluzione migliore è copiare i dati in un altro database. Hai alcune opzioni qui e forse ne sei già a conoscenza. Il primo passo è creare un nuovo database con una dimensione inferiore alla dimensione dei dati. Quindi, è possibile espandere la dimensione del database alla dimensione richiesta.

È possibile considerare SSIS come un modo per trasferire i dati da un database all'altro. Troverai un'attività di copia del database che ti aiuterà. È possibile utilizzare i seguenti passaggi:

  1. Creare un nuovo database con dimensioni inferiori rispetto al database di origine
  2. Installa il pacchetto SSIS con l'attività del database di trasferimento. Imposta l'attività per utilizzare il trasferimento online.
  3. Esegui il pacchetto SSIS.
  4. Il pacchetto SSIS può modificare le dimensioni del database in modo che corrispondano alle dimensioni del database di origine. Riduci questo database, perché ha una dimensione del file originale più piccola.

Vedere ulteriori informazioni sull'attività del database di trasferimento SSIS .


0

Uno spazio inutilizzato nel database è normale.
Se hai molti record di grandi dimensioni (diciamo stringhe lunghe), potrebbe esserci molto spazio inutilizzato nelle pagine dei dati (perché un record di solito non è suddiviso tra le pagine).
Un'altra cosa è un fattore di riempimento: inizialmente, gli indici cluster non vengono creati al 100% per evitare la divisione delle pagine (un'operazione costosa) sugli inserimenti successivi.
Se molti dati sono stati eliminati dal database, lo spazio precedentemente occupato da questi dati non verrà recuperato automaticamente, ma rimarrà allocato alla tabella.

Prova a chiamare DBCC DBREINDEX (table_name, '', 100)tutte le tabelle del tuo database: ricostruirà tutti gli indici con un fattore di riempimento del 100%, quindi i dati verranno posizionati nel modo più compatto possibile. Quindi provare a ridurre nuovamente il database.


0

Ho scoperto che ridurre un database di SQL Server può essere problematico. Sembra che tu debba fare una canzone e una routine di ballo.

Questo è il processo che di solito seguo:

Backup Riduci database Backup Riduci file di registro e database separatamente. Backup Ripetere fino a quando non si restringe definitivamente.

Ho dovuto fare questo processo alcune volte fino a tre volte perché funzioni finalmente. Abbiamo avuto un database di dimensioni superiori a 68 GB, con uno spazio inutilizzato del 98%. Ha superato questa routine di canzoni e balli diverse volte, ma alla fine si è ridotta a meno di 1 GB.


0

Avrei cercato di ridurre prima la dimensione iniziale del file mdf a 29.000 MB, quindi a 28.000 rilevando il colpo ravvicinato.

È irragionevole aspettarsi di ridurre il 30% delle dimensioni del file di database eliminando il 30% dei dati.

È possibile stimare la quantità di spazio inutilizzato nel database per

execute sp_spaceused

nel contesto del tuo database (usa il tuo nome database;)
Puoi pubblicare il risultato della sua esecuzione?


Aggiornamento:
ho pubblicato la mia domanda correlata su di esso:


Non ha funzionato troppo bene. 13903.16mb spazio non allocato. Indice non utilizzato 1688944 KB
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.