Scollegamento permanente di un database


10

Se un database è staccato definitivamente da un'istanza, ci sono attività di pulizia che dovrebbero essere fatte?


1
Puoi spiegare il caso d'uso per il distacco permanente di un database? Perché non lasciarlo cadere?
Joe Obbish,

Risposte:


13

Se si stacca un database da un'istanza, sarà necessario eseguire un'eliminazione del file a livello di sistema operativo. L'approccio più sicuro è invece quello di eliminare il database.

Quello che suggerisco è di eseguire un backup finale del database dopo averlo impostato in modalità Sola lettura (poiché ciò garantirà che non si verifichino attività durante il backup), dopodiché rimuoverlo dal sistema mediante un comando Drop Database .

L'intero set di comandi sarebbe simile al seguente:

-- 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

Successivamente, ti consigliamo di cercare tutti i lavori che eseguivano script sul database. Ti suggerisco di aspettare solo per vedere cosa non funziona (dopo di che puoi eseguire lo script / eliminare il lavoro) in quanto vi sono numerosi modi in cui un lavoro può fare riferimento a un database (non tutti sono facili da identificare).

Infine, ti consigliamo di rimuovere tutti gli utenti dall'istanza che hanno avuto accesso solo a questo database. Questo script dovrebbe identificare chi sono quegli utenti, sebbene la versione di Max sia molto più pulita (non mi ero reso conto che aveva pubblicato un approccio fino a quando non ho modificato la mia risposta per includerlo):

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

13

Ho votato a favore della risposta di John; Vorrei solo aggiungere alcuni dettagli su altri elementi che potresti voler ripulire.

  1. I lavori e gli avvisi di SQL Server Agent potrebbero fare riferimento al database. La loro pulizia eviterà la segnalazione di errori non necessari.

  2. Rimuovere eventuali accessi creati appositamente per il database. Il seguente T-SQL identificherà i possibili accessi candidati che è possibile esaminare per vedere se vengono utilizzati. Il codice identifica gli accessi a cui non fa riferimento alcun database.

    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. Potrebbero esistere dispositivi di backup per quel database. Mentre rimuoverli non è strettamente necessario, se non vengono utilizzati, dovrebbero andare per eliminare la potenziale confusione futura.

  4. I trigger a livello di server possono fare riferimento al database.

  5. Cerca i piani di manutenzione che fanno riferimento al database: falliranno se non vengono aggiornati per rimuovere il database mancante.


Anche i file del sistema operativo dal DB sono ancora lì. Nessun impatto sull'ambiente del server SQL, ma potrebbe essere necessario eliminarli o archiviarli per liberare spazio su disco
CaM

@CaM: questo è stato spiegato dalla risposta di John. Il suggerimento di John è di eliminare il database invece di staccarlo e rilasciare un DB in SQL Server significa eliminare i file DB dal file system.
Andriy M,

1

Tutti i punti principali sono già stati coperti. Di seguito sono i miei 2 centesimi:

Il distacco di un database non è mai una soluzione permanente in quanto è stato progettato per essere utilizzato per spostare i file del database all'interno del server o su un altro server. La rimozione permanente di un database può essere eseguita tramite l'opzione Elimina in SSMS o il comando DROP database come indicato sopra.

Di solito i database che sono tenuti intenzionalmente offline e continuano a generare avvisi sono quelli che stacciamo e li conserviamo fino a quando non possono essere rimossi permanentemente (eliminati).

Attività pre scollegamento: eseguire sp_helpdb dbnameper conoscere i percorsi dei file.

Attività di pulizia:

  1. Elimina i file mdf, ndf e ldf del database dalle posizioni in cui risiedono.
  2. I vecchi file di backup per il database devono essere eliminati o spostati su un altro server in base al periodo di conservazione.

Oltre a Login, Processi agenti, Trigger e punti già menzionati da Max, questi 2 possono anche essere considerati.

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.