Melepaskan basis data secara permanen

10

Jika database terlepas dari instance secara permanen, apakah ada tugas pembersihan yang harus dilakukan?

cspell
sumber
1
Bisakah Anda menjelaskan kasus penggunaan untuk melepaskan basis data secara permanen? Kenapa tidak dijatuhkan saja?
Joe Obbish

Jawaban:

13

Jika Anda melepaskan basis data dari sebuah instance, Anda perlu melakukan penghapusan file-level OS. Pendekatan yang lebih aman adalah dengan menjatuhkan database.

Apa yang saya sarankan adalah mengambil cadangan final dari database setelah Anda memasukkannya ke mode Read Only (karena ini akan memastikan tidak ada aktivitas yang terjadi selama cadangan), setelah itu hapus dari sistem Anda melalui perintah Drop Database .

Set lengkap perintah akan terlihat mirip dengan yang berikut:

-- Use master db to ensure you don't have an active connection to the db you wish to affect
USE [master]
GO

-- This will kill any active transactions, but will force the database into a Read-Only state
ALTER DATABASE [db_name] SET READ_ONLY WITH ROLLBACK IMMEDIATE
GO

BACKUP DATABASE [db_name] -- Fill in more options here or use the UI to take a backup if you chooose
GO

-- This will kick out all connections from the database allowing you to drop it.
ALTER DATABASE [db_name] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO

-- Drop the database (which automatically removes the files from the OS)
DROP DATABASE [db_name]
GO

Setelah ini, Anda akan ingin mencari Pekerjaan yang menjalankan skrip terhadap basis data. Saya akan menyarankan Anda hanya menunggu untuk melihat apa yang gagal (setelah itu Anda dapat skrip / menghapus pekerjaan) karena ada banyak cara pekerjaan dapat referensi database (tidak semuanya mudah untuk diidentifikasi).

Terakhir, Anda ingin menghapus semua pengguna dari instance yang hanya memiliki akses ke database ini. Skrip ini harus mengidentifikasi siapa pengguna itu, meskipun versi Max jauh lebih bersih (saya tidak menyadari dia memposting pendekatan sampai setelah saya mengedit jawaban saya untuk memasukkan ini):

DECLARE @ExecString NVARCHAR (4000)

-- Create Empty Table in a very lazy manner
SELECT  name, principal_id, CAST('' AS NVARCHAR(128)) as database_name
INTO ##tmp_AllDBUsers
FROM sys.server_principals
WHERE 1 = 2

-- Declare Cursor to iterate through all DBs on the instance
DECLARE dbCursor CURSOR
FOR
        SELECT name
        FROM sys .databases


DECLARE @name NVARCHAR (128)
OPEN dbCursor
FETCH NEXT FROM dbCursor
INTO @name

WHILE @@FETCH_STATUS = 0
BEGIN

    SET @ExecString = 
    'USE [' + @name + '];
    INSERT INTO ##tmp_AllDBUsers
    SELECT sp.name, sp.principal_id, DB_NAME()
    FROM sys.server_principals sp INNER JOIN sys.database_principals dp
        ON sp.sid = dp.sid'

    EXEC(@ExecString)

    FETCH NEXT FROM dbCursor
    INTO @name
END

-- Close and deallocate the cursor because you've finished traversing all it's data
CLOSE dbCursor
DEALLOCATE dbCursor

-- Show all logins that do not belong to a server-level role nor have access to any databases
SELECT sp.*
FROM sys.server_principals sp LEFT JOIN ##tmp_AllDBUsers adu
    ON sp.principal_id = adu.principal_id
WHERE adu.principal_id IS NULL
    AND sp.principal_id NOT IN (SELECT member_principal_id
                            FROM sys.server_role_members)
    AND TYPE IN ('S', 'U', 'G')

-- cleanup
DROP TABLE ##tmp_AllDBUsers
John Eisbrener
sumber
13

Saya telah mengangkat jawaban John; Saya hanya ingin menambahkan beberapa detail tentang item lain yang mungkin ingin Anda bersihkan.

  1. Pekerjaan dan peringatan SQL Server Agent mungkin merujuk pada database. Membersihkannya akan mencegah kesalahan yang tidak perlu dilaporkan.

  2. Hapus semua login yang dibuat khusus untuk database. T-SQL berikut ini akan mengidentifikasi calon yang masuk yang mungkin Anda selidiki untuk melihat apakah mereka sedang digunakan. Kode mengidentifikasi login yang tidak dirujuk oleh basis data apa pun.

    DECLARE @cmd nvarchar(max);
    SET @cmd = '    SELECT sp.sid
        FROM master.sys.server_principals sp
    ';
    SELECT @cmd = @cmd + '  EXCEPT 
        SELECT dp.sid
        FROM ' + QUOTENAME(d.name) + '.sys.database_principals dp
    '
    FROM sys.databases d
    WHERE d.[state] <> 6; --ignore offline DBs
    
    SET @cmd = 'SELECT spr.*
    FROM (
    ' + @cmd + '
    ) src
        INNER JOIN master.sys.server_principals spr
            ON src.sid = spr.sid
    WHERE spr.type <> ''R''
        AND spr.name NOT LIKE ''%##MS_%''
        AND spr.name NOT LIKE ''NT %''
        AND NOT EXISTS (
            SELECT 1
            FROM sys.server_role_members srm
            WHERE srm.member_principal_id = spr.principal_id
                )
    ORDER BY spr.name;
    ';
    EXEC sys.sp_executesql @cmd;
  3. Perangkat cadangan mungkin ada untuk database itu. Meskipun menghapusnya tidak sepenuhnya diperlukan, jika mereka tidak digunakan, mereka harus pergi untuk menghilangkan potensi kebingungan di masa depan.

  4. Pemicu tingkat server dapat merujuk database.

  5. Cari paket perawatan yang merujuk pada basis data - ini akan gagal jika tidak diperbarui untuk menghapus database yang hilang.

Max Vernon
sumber
File OS dari DB juga masih ada. Tidak ada dampak pada lingkungan SQL server, tetapi mereka mungkin perlu dihapus atau diarsipkan untuk membebaskan ruang disk
CaM
@ CmM: Itu sudah dipertanggungjawabkan oleh jawaban John. Saran John adalah untuk menjatuhkan database daripada melepaskannya, dan menjatuhkan DB di SQL Server berarti menghapus file DB dari sistem file.
Andriy M
1

Semua poin utama telah dibahas. Di bawah ini adalah 2 sen saya:

Melepaskan basis data tidak pernah merupakan solusi permanen karena memang dimaksudkan untuk digunakan untuk memindahkan file basis data di dalam server atau ke server lain. Menghapus database secara permanen dapat dilakukan dengan opsi Hapus di SSMS atau perintah database DROP seperti yang disebutkan di atas.

Biasanya basis data yang sengaja disimpan offline dan terus menghasilkan Lansiran adalah yang kami lepaskan dan simpan hingga dapat dihapus secara permanen (Dihapus).

Tugas pra-lepas: Jalankan sp_helpdb dbnameuntuk mengetahui lokasi file.

Tugas pembersihan:

  1. Hapus file mdf, ndf, dan ldf dari database dari lokasi mereka berada.
  2. File cadangan lama untuk database perlu Dihapus atau dipindahkan ke server lain mengingat periode penyimpanan Anda.

Selain Login, Agen Pekerjaan, Pemicu dan poin yang telah disebutkan oleh Max, 2 ini juga dapat dilihat.

Ramakant Dadhichi
sumber