การแยกฐานข้อมูลอย่างถาวร


10

หากฐานข้อมูลถูกแยกออกจากอินสแตนซ์อย่างถาวรจะมีงานการล้างข้อมูลที่ควรทำหรือไม่?


1
คุณสามารถอธิบายกรณีการใช้สำหรับการลบฐานข้อมูลอย่างถาวรได้หรือไม่? ทำไมไม่ลองวางมันล่ะ?
โจ Obbish

คำตอบ:


13

หากคุณแยกฐานข้อมูลออกจากอินสแตนซ์คุณจะต้องทำการลบไฟล์ในระดับระบบปฏิบัติการ วิธีที่ปลอดภัยกว่าคือการปล่อยฐานข้อมูลแทน

สิ่งที่ฉันแนะนำคือการสำรองข้อมูลขั้นสุดท้ายของฐานข้อมูลหลังจากที่คุณวางไว้ในโหมดอ่านอย่างเดียว (เพื่อให้แน่ใจว่าไม่มีกิจกรรมใดเกิดขึ้นระหว่างการสำรองข้อมูล) หลังจากนั้นลบออกจากระบบของคุณโดยใช้คำสั่งDrop Database

ชุดคำสั่งเต็มรูปแบบจะมีลักษณะคล้ายกับต่อไปนี้:

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

ฉัน upvoted คำตอบของ John; ฉันต้องการเพิ่มรายละเอียดเกี่ยวกับรายการอื่นที่คุณอาจต้องการล้างข้อมูล

  1. งานและการแจ้งเตือนของ SQL Server Agent อาจอ้างอิงฐานข้อมูล การล้างข้อมูลจะช่วยป้องกันการรายงานข้อผิดพลาดที่ไม่จำเป็น

  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

@CaM: นั่นเป็นคำตอบของจอห์น ข้อเสนอแนะของจอห์นคือการปล่อยฐานข้อมูลแทนการถอดมันทิ้งฐานข้อมูลใน SQL Server หมายถึงการลบไฟล์ฐานข้อมูลออกจากระบบไฟล์
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.