it-swarm.asia

Bagaimana cara mengecilkan semua file dengan cepat untuk semua database?

Dalam SQL Server (2008 dalam kasus ini) bagaimana saya bisa dengan cepat menyusutkan semua file, baik log dan data, untuk semua database pada contoh? Saya bisa melalui SSMS dan klik kanan masing-masing dan pilih Tugas -> Kecilkan, tapi saya sedang mencari sesuatu yang lebih cepat.

Saya membuat skrip beberapa "Buat database" dan lupa mereka telah menggelembungkan ukuran untuk default, dan tidak perlu cukup banyak ruang yang disediakan untuk file-file ini pada proyek ini.

47
jcolebrand

Ketika Anda melakukan "Tugas -> Kecilkan" dari GUI itu sebenarnya mengeluarkan DBCC SHRINKDATABASE perintah di belakang layar. Cobalah. Ketika kotak dialog muncul, jangan klik tombol "OK". Sebagai gantinya, klik tombol "Script". Anda akan melihat perintah di jendela kueri. Gabungkan dengan kueri pada sys.databases (tinggalkan master dan msdb), dan Anda bisa membuat skrip untuk mengecilkan semua basis data.

Misalnya (diambil dari komentar jcolebrand):

SELECT 
      'USE [' + d.name + N']' + CHAR(13) + CHAR(10) 
    + 'DBCC SHRINKFILE (N''' + mf.name + N''' , 0, TRUNCATEONLY)' 
    + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) 
FROM 
         sys.master_files mf 
    JOIN sys.databases d 
        ON mf.database_id = d.database_id 
WHERE d.database_id > 4;

Salin output dari permintaan itu dan jalankan untuk mengecilkan semua file Anda.

59
Larry Coleman

Bagaimana dengan satu baris pernyataan sql?

Silakan baca ini posting blog yang sangat menarik sebelum menjalankan pernyataan sql berikut.

EXEC sp_MSForEachDB 'DBCC SHRINKDATABASE (''?'' , 0)'
22
CoderHawk

DBCC SHRINKDB (dan sepupunya SHRINKFILE) sangat lambat, karena ada banyak sekali eksekusi berurutan yang terjadi dalam kode itu.

Cara yang jauh lebih cepat untuk mengecilkan file database adalah ini:

  • Alokasikan filegroup baru ke basis data
  • Jadikan filegroup ini sebesar yang seharusnya (gunakan sp_spaceused untuk menentukan seberapa besar)
  • Bangun kembali semua indeks ke filegroup baru ini
  • Jatuhkan filegroup lama

Karena indeks yang dibangun kembali paralel secara masif, teknik ini sering menghasilkan penyusutan database yang jauh lebih cepat. Tentu saja, itu mengharuskan Anda untuk memiliki sedikit ruang ekstra untuk filegroup baru saat proses berlangsung. Namun, Anda hanya perlu ruang yang cukup di grup fileg baru untuk menampung grup fileg terbesar dalam instance (karena Anda akan mengklaim ruang saat Anda melanjutkan).

Teknik ini juga memiliki manfaat tambahan untuk defragmentasi indeks Anda dalam proses.

15
Thomas Kejser

Saya menyetel sedikit pertanyaan untuk menyusutkan hanya LOG seperti yang diminta:

set nocount on  
SELECT 
      'USE [' + d.name + N']' + CHAR(13) + CHAR(10) 
    + 'DBCC SHRINKFILE (N''' + mf.name + N''' , 0, TRUNCATEONLY)' 
    + CHAR(13) + CHAR(10) + CHAR(13) + CHAR(10) 
FROM 
         sys.master_files mf 
    JOIN sys.databases d 
        ON mf.database_id = d.database_id 
WHERE d.database_id > 4 and mf.type_desc = 'LOG'
13
Frankachela

Kode di bawah ini, dapatkan daftar basis data non-sistem, atur basis data untuk dibaca dan kemudian perkecil file tersebut. Saya telah menyimpan kode ini dalam beberapa kotak SQL Server menggunakan SQL Agent Job, di mana ruang selalu menjadi masalah. Pada Sabtu malam/Minggu setiap minggu, itu mulai berjalan dan mengecilkan semua basis data dalam beberapa jam (tergantung pada ukuran basis data).

declare @db varchar(255)
declare c cursor for
select name from sys.databases where is_read_only=0 and state=0
  and name not in ('master','model','tempdb','msdb')
open c
fetch c into @db
while @@fetch_status=0
begin
  exec SP_dboption @db,'trunc. log on chkpt.','true' 
  DBCC shrinkdatabase (@db)
  fetch next from c into @db
end
close c
deallocate c

Yang ini memperluas jawaban di atas, menggunakan kursor untuk beralih melalui pernyataan SQL satu per satu. Ini tidak sesingkat jawaban Emrah tetapi memungkinkan untuk logika tambahan dalam loop sementara di dalam kursor ..

SELECT 
    'USE [' 
    + databases.name + N']' 
    + CHAR(13) 
    + CHAR(10) 
    + 'DBCC SHRINKFILE (N''' 
    + masterFiles.name 
    + N''' , 0, TRUNCATEONLY)' 
    + CHAR(13) 
    + CHAR(10) 
    + CHAR(13) 
    + CHAR(10)                                                                  AS sqlCommand
INTO
    #shrinkCommands
FROM 
    [sys].[master_files] masterFiles 
    INNER JOIN [sys].[databases] databases ON masterFiles.database_id = databases.database_id 
WHERE 
    databases.database_id > 4; -- Exclude system DBs


DECLARE iterationCursor CURSOR

FOR
    SELECT 
        sqlCommand 
    FROM 
        #shrinkCommands

OPEN iterationCursor

DECLARE @sqlStatement varchar(max)

FETCH NEXT FROM iterationCursor INTO @sqlStatement

WHILE (@@FETCH_STATUS = 0)
BEGIN
    EXEC(@sqlStatement)
    FETCH NEXT FROM iterationCursor INTO @sqlStatement
END

-- Clean up
CLOSE iterationCursor
DEALLOCATE iterationCursor
DROP TABLE #shrinkCommands
0
Alistair

Kecilkan semua file log kecuali master, model, msdb:

EXEC sp_MSforeachdb '
DECLARE @sqlcommand nvarchar (500)
IF ''?'' NOT IN (''master'', ''model'', ''msdb'')
BEGIN
USE [?]
SELECT @sqlcommand = ''DBCC SHRINKFILE (N'''''' + 
name
FROM [sys].[database_files]
WHERE type_desc = ''LOG''
SELECT @sqlcommand = @sqlcommand + '''''' , 0)''
EXEC sp_executesql @sqlcommand
END'
0
Emrah Saglam

Kami dapat mengulangi SHRINKDB dan SHRINKFILE untuk semua basis data secara dinamis:

while @DBID<[email protected]
begin
  -- Used Dynamic SQL for all databases.
  Set @SQL ='Use '[email protected]+ ' '+Char(10)
  Set @SQL += 'DBCC SHRINKFILE('[email protected]+',5)' +Char(10)
  Set @SQL += 'DBCC SHRINKDATABASE('[email protected]+')'+Char(10)

  --#6 Increment DBid for looping over all databases
  Set @DBID = @DBID+1
  Select @DBName = DBName, @Filename=DBFileName from #DBNames where [dbid] = @DBID and type_Desc = 'LOG'
  Print (@SQL)
  Exec (@SQL)
end

Anda dapat menemukan detail di artikel ini .

0
Anup Kulkarni