Détachement permanent d'une base de données

10

Si une base de données est détachée d'une instance de manière permanente, y a-t-il des tâches de nettoyage à effectuer?

cspell
la source
1
Pouvez-vous expliquer le cas d'utilisation pour détacher définitivement une base de données? Pourquoi ne pas simplement le laisser tomber?
Joe Obbish

Réponses:

13

Si vous détachez une base de données d'une instance, vous devrez effectuer une suppression du fichier au niveau du système d'exploitation. L'approche la plus sûre consiste à supprimer la base de données à la place.

Ce que je suggère, c'est de faire une sauvegarde finale de la base de données après l'avoir mise en mode lecture seule (car cela garantira qu'aucune activité ne se produit pendant la sauvegarde), après quoi la supprimer de votre système au moyen d'une commande Drop Database .

L'ensemble complet des commandes ressemblerait à ce qui suit:

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

Après cela, vous voudrez rechercher tous les travaux qui ont exécuté des scripts sur la base de données. Je vous suggère d'attendre pour voir ce qui échoue (après quoi vous pouvez créer un script / supprimer le travail) car il existe de nombreuses façons qu'un travail peut référencer une base de données (qui ne sont pas toutes faciles à identifier).

Enfin, vous souhaiterez supprimer tous les utilisateurs de l'instance qui n'avaient accès qu'à cette base de données. Ce script devrait identifier qui sont ces utilisateurs, bien que la version de Max soit beaucoup plus propre (je n'ai réalisé qu'il a posté une approche qu'après avoir modifié ma réponse pour l'inclure):

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
la source
13

J'ai surévalué la réponse de John; Je voudrais juste ajouter quelques détails sur d'autres éléments que vous voudrez peut-être nettoyer.

  1. Les tâches et les alertes de l'Agent SQL Server peuvent référencer la base de données. Les nettoyer empêchera de signaler des erreurs inutiles.

  2. Supprimez toutes les connexions créées spécifiquement pour la base de données. Le T-SQL suivant identifiera les éventuelles connexions candidates que vous pourriez étudier pour voir si elles sont utilisées. Le code identifie les connexions qui ne sont référencées par aucune base de données.

    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. Des périphériques de sauvegarde peuvent exister pour cette base de données. Bien qu'il ne soit pas strictement nécessaire de les supprimer, s'ils ne sont pas utilisés, ils devraient permettre d'éliminer toute confusion future potentielle.

  4. Les déclencheurs au niveau du serveur peuvent référencer la base de données.

  5. Recherchez les plans de maintenance qui font référence à la base de données - ceux-ci échoueront s'ils ne sont pas mis à jour pour supprimer la base de données manquante.

Max Vernon
la source
De plus, les fichiers OS de la base de données sont toujours là. Aucun impact sur l'environnement du serveur SQL, mais il peut être nécessaire de les supprimer ou de les archiver pour libérer de l'espace disque
CaM
@CaM: Cela a été expliqué par la réponse de John. La suggestion de John est de supprimer la base de données au lieu de la détacher, et la suppression d'une base de données dans SQL Server signifie la suppression des fichiers DB du système de fichiers.
Andriy M
1

Tous les points majeurs ont déjà été traités. Voici mes 2 cents:

Le détachement d'une base de données n'est jamais une solution permanente car il était destiné à être utilisé pour déplacer les fichiers de base de données au sein du serveur ou vers un autre serveur. La suppression définitive d'une base de données peut être effectuée par l'option Supprimer dans SSMS ou la commande DROP database comme mentionné ci-dessus.

Habituellement, les bases de données qui sont intentionnellement gardées hors ligne et continuent de générer des alertes sont celles que nous détacherons et conserverons jusqu'à ce qu'elles puissent être définitivement supprimées (Supprimé).

Tâche préalable au détachement: exécutez sp_helpdb dbnamepour connaître les emplacements des fichiers.

Tâches de nettoyage:

  1. Supprimez les fichiers mdf, ndf et ldf de la base de données des emplacements où ils résident.
  2. Les anciens fichiers de sauvegarde de la base de données doivent être supprimés ou déplacés vers un autre serveur en fonction de votre période de conservation.

Outre les connexions, les travaux d'agent, les déclencheurs et les points déjà mentionnés par Max, ces 2 peuvent également être examinés.

Ramakant Dadhichi
la source