데이터베이스를 영구적으로 분리


10

데이터베이스가 인스턴스에서 영구적으로 분리 된 경우 수행해야 할 정리 작업이 있습니까?


1
데이터베이스를 영구적으로 분리하는 사용 사례를 설명 할 수 있습니까? 그냥 떨어 뜨리지 그래?
Joe Obbish

답변:


13

인스턴스에서 데이터베이스를 분리하면 파일의 OS 레벨 삭제를 수행해야합니다. 보다 안전한 방법은 대신 데이터베이스를 삭제하는 것입니다.

내가 제안하는 것은 데이터베이스를 읽기 전용 모드로 설정 한 후 (백업 중 활동이 발생하지 않도록 데이터베이스 를 삭제 한 후) 데이터베이스 삭제 명령 을 통해 데이터베이스를 최종 백업하는 것입니다 .

전체 명령 세트는 다음과 유사합니다.

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

그런 다음 데이터베이스에 대해 스크립트를 실행 한 작업을 찾으십시오. 작업이 데이터베이스를 참조 할 수있는 여러 가지 방법 (모두 식별하기 쉬운 것은 아님)이 있기 때문에 실패한 작업 (스크립트를 작성 / 삭제할 수 있음)을 기다리는 것이 좋습니다.

마지막으로이 데이터베이스에만 액세스 할 수있는 인스턴스에서 모든 사용자를 제거하려고합니다. Max의 버전이 훨씬 깨끗하지만이 스크립트는 해당 사용자를 식별해야합니다 (이를 포함하도록 내 답변을 편집 한 후에야 그가 접근 방식을 게시 한 것을 알지 못했습니다).

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. 데이터베이스를 참조하는 유지 보수 계획을 찾으십시오. 누락 된 데이터베이스를 제거하도록 업데이트되지 않으면 실패합니다.


또한 DB의 OS 파일이 여전히 있습니다. SQL Server 환경에는 영향을 미치지 않지만 디스크 공간을 확보하기 위해 삭제 또는 보관해야합니다.
CaM

@CaM : 그것은 John의 답변에 의해 설명되었습니다. John의 제안은 데이터베이스를 분리하는 대신 데이터베이스를 삭제하는 것이며 SQL Server에서 DB를 삭제한다는 것은 파일 시스템에서 DB 파일을 삭제하는 것을 의미합니다.
Andriy M

1

모든 주요 사항은 이미 다루었습니다. 아래는 내 2 센트입니다.

데이터베이스를 분리하는 것은 서버 내에서 또는 다른 서버로 데이터베이스 파일을 이동시키기 위해 사용되는 영구적 인 솔루션이 아닙니다. SSMS의 삭제 옵션 또는 위에서 언급 한 DROP 데이터베이스 명령으로 데이터베이스를 영구적으로 제거 할 수 있습니다.

일반적으로 의도적으로 오프라인 상태로 유지되고 경고를 계속 생성하는 데이터베이스는 영구적으로 제거 (삭제) 될 때까지 분리하여 보관하는 데이터베이스입니다.

사전 분리 작업 : sp_helpdb dbname파일 위치를 알고 실행 합니다.

정리 작업 :

  1. 존재하는 위치에서 데이터베이스의 mdf, ndf 및 ldf 파일을 삭제하십시오.
  2. 보존 기간을 고려하여 데이터베이스의 이전 백업 파일을 삭제하거나 다른 서버로 이동해야합니다.

로그인, 상담원 작업, 트리거 및 Max에서 이미 언급 한 지점 이외에도이 2 개를 볼 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.