Meja 200GB terpotong tetapi ruang disk tidak dirilis


23

Saya hanya memiliki 2GB tersisa, jadi saya harus menghapus tabel riwayat ini. Tabel ini sekarang kosong tetapi ruang disk basis data tidak dirilis. Dan file database adalah 320GB.


Saya menemukan beberapa jejak Replikasi pada basis data, ini meningkatkan ukuran log secara dramatis dan mencegah untuk menghapus atau menyusut.
Lucas Rodrigues Sena

Jawaban:


25

Jika Anda merujuk konsumsi file database aktual pada volume, maka SQL Server tidak menanganinya secara otomatis . Hanya karena Anda menghapus data dari basis data tidak berarti file basis data akan menyusut agar hanya sesuai dengan data yang ada.

Apa yang Anda cari, jika Anda harus mendapatkan kembali ruang pada volume, akan menyusutkan file tertentu dengan DBCC SHRINKFILE. Perlu dicatat beberapa praktik terbaik, sesuai dokumentasi itu:

Praktik terbaik

Pertimbangkan informasi berikut ketika Anda berencana untuk mengecilkan file:

  • Operasi menyusut paling efektif setelah operasi yang menciptakan banyak ruang yang tidak digunakan, seperti tabel truncate atau operasi drop table.

  • Sebagian besar database membutuhkan ruang kosong untuk operasi sehari-hari. Jika Anda mengecilkan basis data berulang kali dan memperhatikan bahwa ukuran basis data tumbuh lagi, ini menunjukkan bahwa ruang yang menyusut diperlukan untuk operasi reguler. Dalam kasus ini, berulang kali menyusutkan database adalah operasi yang sia-sia.

  • Operasi penyusutan tidak mempertahankan status fragmentasi indeks dalam database, dan umumnya meningkatkan fragmentasi hingga taraf tertentu. Ini adalah alasan lain untuk tidak menyusutkan database berulang kali.

  • Kecilkan beberapa file dalam database yang sama secara berurutan alih-alih secara bersamaan. Kontensi pada tabel sistem dapat menyebabkan penundaan karena pemblokiran.

Juga dari catatan:

DBCC SHRINKFILE operasi dapat dihentikan pada titik mana saja dalam proses, dan semua pekerjaan yang diselesaikan tetap dipertahankan.

Pasti ada beberapa hal yang perlu dipertimbangkan ketika melakukan ini, dan saya sarankan Anda melihat posting blog Paul Randal tentang apa yang terjadi ketika Anda melakukan operasi ini.

Langkah pertama pasti akan memverifikasi berapa banyak ruang dan ruang kosong yang benar-benar dapat Anda ganti, serta ruang yang digunakan pada file:

use AdventureWorks2012;
go

;with db_file_cte as
(
    select
        name,
        type_desc,
        physical_name,
        size_mb = 
            convert(decimal(11, 2), size * 8.0 / 1024),
        space_used_mb = 
            convert(decimal(11, 2), fileproperty(name, 'spaceused') * 8.0 / 1024)
    from sys.database_files
)
select
    name,
    type_desc,
    physical_name,
    size_mb,
    space_used_mb,
    space_used_percent = 
        case size_mb
            when 0 then 0
            else convert(decimal(5, 2), space_used_mb / size_mb * 100)
        end
from db_file_cte;

6

Ini adalah perilaku normal ketika Anda memotong tabel dan yang melibatkan penghapusan lebih dari 128 ekstensi sebagai Per Buku Daring

Ketika Anda menjatuhkan atau membangun kembali indeks besar, atau menjatuhkan atau memotong tabel besar, Mesin Database mempertahankan deallocations halaman aktual, dan kunci yang terkait, sampai setelah transaksi dilakukan. Implementasi ini mendukung transaksi autocommit dan eksplisit dalam lingkungan multi-pengguna, dan berlaku untuk tabel besar dan indeks yang menggunakan lebih dari 128 ekstensi.

Mesin Database menghindari kunci alokasi yang diperlukan untuk menjatuhkan objek besar dengan memecah proses dalam dua fase terpisah: logis dan fisik.

Pada fase logis, unit alokasi yang ada yang digunakan oleh tabel atau indeks ditandai untuk deallokasi dan dikunci hingga transaksi dilakukan. Dengan indeks berkerumun yang dijatuhkan, baris data disalin dan kemudian dipindahkan ke unit alokasi baru yang dibuat ke toko baik indeks berkerumun dibangun kembali, atau tumpukan. (Dalam kasus indeks membangun kembali, baris data juga disortir.) Ketika ada rollback, hanya fase logis ini perlu digulung kembali.

Fase fisik terjadi setelah transaksi dilakukan. Unit alokasi yang ditandai untuk deallokasi dijatuhkan secara fisik dalam batch. Tetes ini ditangani di dalam transaksi singkat yang terjadi di latar belakang, dan tidak memerlukan banyak kunci.

Karena fase fisik terjadi setelah transaksi dilakukan, ruang penyimpanan tabel atau indeks mungkin masih tampak tidak tersedia. Jika ruang ini diperlukan untuk pertumbuhan basis data sebelum fase fisik selesai, Mesin Basis Data mencoba memulihkan ruang dari unit alokasi yang ditandai untuk deallokasi. Untuk menemukan ruang yang saat ini digunakan oleh unit alokasi ini, gunakan tampilan katalog sys.allocation_units.

Operasi drop ditangguhkan tidak melepaskan ruang yang dialokasikan segera, dan mereka memperkenalkan biaya overhead tambahan di Mesin Database. Oleh karena itu, tabel dan indeks yang menggunakan 128 atau lebih sedikit luasan dijatuhkan, terpotong, dan dibangun kembali seperti di SQL Server 2000. Ini berarti fase logis dan fisik terjadi sebelum transaksi dilakukan.

Anda harus menunggu dan tentu saja Anda harus mengecilkan file secara manual untuk mendapatkan kembali ruang yang juga layak disebutkan bahwa penyusutan menyebabkan fragmentasi logis dan harus dihindari kecuali jika kebutuhan Anda serius. Anda harus bagaimana keseimbangan antara menyusut dan fragmentasi. Lebih baik bertanya pada diri sendiri apakah shrink akan benar-benar menyelesaikan masalah dengan mempertimbangkan skenario di mana data akan kembali tumbuh bagaimanapun.

Gunakan kueri di bawah ini untuk memeriksa seberapa banyak ruang kosong yang ada di database

SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB
FROM sys.database_files;

6

Selain jawaban Tom dan Shanky, jika database Anda berisi data LOB / BLOB, DBCC SHRINKFILE mungkin tidak berfungsi. Jika itu masalahnya, maka Anda memiliki dua opsi, tergantung pada apakah Anda dapat membuat basis data offline atau tidak. Jika Anda dapat membuat database offline, maka Anda harus menyalin data dan menyalinnya kembali untuk menghapus ruang kosong. Anda dapat melakukannya dengan salah satu dari yang berikut:

  1. Menggunakan pernyataan SELECT INTO untuk mentransfer seluruh tabel ke tabel baru. Lepaskan tabel asli, jalankan DBCC SHRINKFILE . Ganti nama tabel baru dengan nama tabel asli.
  2. Menggunakan bcp untuk menyalin tabel dalam mode asli, letakkan tabel, jalankan DBCC SHRINKFILE , buat tabel, lalu bcp data ke dalam tabel.
  3. Menggunakan Ekspor / Impor untuk memindahkan semua data ke database baru, drop database yang sudah ada, ganti nama database baru ke nama database asli.

Jika Anda tidak dapat membuat database offline, maka Anda dapat menggunakan perintah DBCC SHRINKFILE dengan opsi EMPTYFILE .

Detail untuk salinan luring: http://support.microsoft.com/kb/324432/en-us

Informasi terkini untuk opsi EMPTYFILE http://msdn.microsoft.com/en-us/library/ms189493(v=sql.105).aspx

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.