Постоянное отключение базы данных

10

Если база данных постоянно отсоединяется от экземпляра, нужно ли выполнять какие-либо задачи по очистке?

cspell
источник
1
Можете ли вы объяснить вариант использования для постоянного отключения базы данных? Почему бы просто не бросить это?
Джо Оббиш

Ответы:

13

Если вы отсоедините базу данных от экземпляра, вам потребуется выполнить удаление файла на уровне ОС. Более безопасный подход - удалить базу данных.

Я предлагаю сделать окончательное резервное копирование базы данных после того, как вы переведете ее в режим «Только чтение» (так как это обеспечит отсутствие каких-либо действий во время резервного копирования), после чего удалите ее из системы с помощью команды «Удалить базу данных» .

Полный набор команд будет выглядеть примерно так:

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

После этого вам нужно будет искать любые задания, которые запускали сценарии для базы данных. Я бы посоветовал вам просто подождать, чтобы увидеть, что не получается (после чего вы можете написать сценарий / удалить задание), поскольку существует множество способов, которыми задание может ссылаться на базу данных (не все из них легко определить).

Наконец, вы захотите удалить всех пользователей из экземпляра, которые имели доступ только к этой базе данных. Этот скрипт должен определить, кто эти пользователи, хотя версия Макса намного чище (я не осознавал, что он опубликовал подход, пока я не отредактировал свой ответ, чтобы включить это):

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

Я проголосовал за ответ Джона; Я просто хотел бы добавить некоторые детали о других предметах, которые вы, возможно, захотите убрать.

  1. Задания и предупреждения агента SQL Server могут ссылаться на базу данных. Очистка их предотвратит появление ненужных ошибок.

  2. Удалите все логины, которые были созданы специально для базы данных. Следующий T-SQL идентифицирует возможные входы-кандидаты, которые вы могли бы исследовать, чтобы увидеть, используются ли они. Код идентифицирует логины, на которые не ссылается ни одна база данных.

    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. Резервные устройства могут существовать для этой базы данных. Хотя их удаление не является строго необходимым, если они не используются, они должны пойти на устранение потенциальной путаницы в будущем.

  4. Триггеры уровня сервера могут ссылаться на базу данных.

  5. Ищите планы обслуживания, которые ссылаются на базу данных - они потерпят неудачу, если они не будут обновлены для удаления отсутствующей базы данных.

Макс Вернон
источник
Также файлы ОС из БД все еще там. Нет влияния на окружающую среду SQL сервера, но они , возможно , должны быть удалены или в архив, чтобы освободить дисковое пространство
Кэм
@CaM: Это объясняется ответом Джона. Джон предлагает удалить базу данных вместо того, чтобы отсоединять ее, а удаление базы данных в SQL Server означает удаление файлов базы данных из файловой системы.
Андрей М
1

Все основные моменты уже были рассмотрены. Ниже приведены мои 2 цента:

Отсоединение базы данных никогда не является постоянным решением, так как оно предназначалось для перемещения файлов базы данных внутри сервера или на другой сервер. Окончательное удаление базы данных может быть выполнено с помощью опции Удалить в SSMS или командой базы данных DROP, как упомянуто выше.

Обычно базы данных, которые намеренно хранятся в автономном режиме и продолжают генерировать оповещения, - это те, которые мы отсоединяем и храним до тех пор, пока они не будут окончательно удалены (удалены).

Задание перед отсоединением: запустите, sp_helpdb dbnameчтобы узнать расположение файлов.

Задачи очистки:

  1. Удалите файлы базы данных mdf, ndf и ldf из тех мест, где они находятся.
  2. Старые файлы резервных копий для базы данных необходимо либо удалить, либо перенести на другой сервер с учетом срока хранения.

Помимо логинов, агентских заданий, триггеров и уже упомянутых пунктов Макса, эти 2 также могут быть рассмотрены.

Рамакант Дадхичи
источник