محمد نصیری
بنیانگذار توسینسو ، هکر کلاه سفید ، کارشناس امنیت اطلاعات و ارتباطات و عاشق طبیعت

آموزش Snapshot گرفتن از SQL Server

Snapshot به معنی عکس گرفتن است ، به عکس های قدیمی خود نگاه کنید ، در روزگار جوانی چه شکلی بودید الان چه شکلی شده اید البته خوشتیپ بودید هستید و خواهید بود . هر وقت به این عکس ها نگاه می کنید یاد این مسئله می افتید که ای کاش می شد زمان به عقب بر می گشت و من دوباره به سنی که در عکس می بینم بر می گشتم ، اینکار برای شما ممکن نیست اما برای نرم افزارها و Database ها ممکن است.

دوره های شبکه، برنامه نویسی، مجازی سازی، امنیت، نفوذ و ... با برترین های ایران
آموزش اسنپ شات گیری از SQL

با معرفی مفهومی به نام Snapshot در تکنولوژی های امروزی مرتبط با کامپیوتر شما می توانید از لحظه فعلی یک عکس یا Snapshot بگیرید و هر موقع که دوست داشتید به زمانی بازگردید که این عکس یا Snapshot را گرفته اید. این مفهوم در SQL سرور هم وجود دارد ، شاید شما با نرم افزارهایی مثل VMware کار کرده باشید آنها هم قابلیت Snapshot گرفتن را دارند ، بنده در همین وب سایت یک مقاله در خصوص Snapshot گرفتن از اکتیودایرکتوری را نیز نوشته ام ، تقریبا دنیا دنیای Snapshot شده است. تمامی مفاهیم اصلی این قابلیت در نرم افزارهای مختلف یکی است و تا اسم Snapshot به گوش یک ITPRO می خورد تداعی کننده همین موضوع است.

آشنایی با مفهوم Snapshot

مفهوم عکس را به خاطر دارید که ؟ شما در یک لحظه زمانی یک عکس یا بهتر بگوییم یک Image از چهره خود در زمان ثبت می کنید. در Database این مفهوم به این شکل است که شما با عکس گرفتن یا Snapshot گرفتن از Database خود در واقع یک Image کامل از داده ها و وضعیت کامل Database در لحظه فعلی ثبت می کنید و در قالب یک فایل جداگانه در کنار Database نگهداری می کنید. Snapshot ها کار کردن با Database ها را بسیار جالب می کنند و امکانات ویژه ای را در اختیار شما قرار می دهند.

شما می توانید بعد ها با استفاده از همین Snapshot هایی که از Database های خود گرفته اید ، داده های خود به همراه Database های خود و تمامی تنظیماتی که در لحظه ثبت Snapshot بر روی آنها وجود داشته است را به یکباره Restore کنید و در یک حالت عملیاتی از آن استفاده کنید.

نمی خواهم از این لفظ استفاده کنم اما بارها دیده ام که از Snapshot به عنوان Backup هم استفاده می کنند که اصلا این مورد درست نیست ، اولین نکته در خصوص SQL Snapshot ها این است که آنها بصورت پیشفرض فقط خواندی یا Read Only هستند و بر خلاف فایل های Backup که آنها را می توانیم بصورت جداگانه در محل دیگری و حتی در کامپیوتر دیگری ذخیره کنیم .

ما نمی توانیم Snapshot ها را از کنار Database های اصلی ( Source Database) دور کنیم و آنها در کنار Database ها همیشه قرار دارند. شما می توانید از یک Database موجود روی SQL سرور خود چندین Snapshot در وهله های زمانی معین داشته باشید و هربار که دوست داشتید داده های خود را به وضعیتی که در آن Snapshot گرفته اید برگردانید. SQL Snapshot ها را تا زمانیکه بصورت دستی از روی سرور حذف نکنید بر روی سرور Database های شما وجود خواهند داشت.

Database های SQL Snapshot ها در سطح Page ها عملیاتی می شوند. Snapshot ها باتوجه به اینکه از فضاهای پراکنده سیستم استفاده می کنند در بدو ایجاد معمولا فضای بسیار کمی از سیستم عامل را به خود اختصاص می دهند. زمانیکه یک Page در Database اصلی یا همان Source Database تغییر کند این Page تغییر کرده

در داخل دیتابیس Snapshot نیز کپی می شود و به مرور باعث افزاریش حجم فایل Snapshot خواهد شد. توجه کنید که اگر Page ای دستکاری نشده باشد و از درون Snapshot خوانده شود ، این Page در واقع از Source Database خوانده می شود به زبان دیگر تغییراتی که در Source Database انجام می شود کاملا بر روی Snapshot Database تاثیر متقابل دارند. Snapshot ها در مواقع بسیاری به کمک شما می آیند و مفید هستند :

  1. همانطور که اشاره کردیم Snapshot ها در حالت Read Only هستند و بهترین گزینه برای تهیه گزاش به حساب می آیند. تمامی فرآیند هایی که برای گرفتن گزارش می خواهیم انجام دهیم را براحتی می توانی با استفاده از Snapshot ها انجام بدهیم بدون اینکه به Source Database نیازی داشته باشیم. با اینکار Load کاری بر روی Database اصلی نیز کاهش پیدا می کند. همچنین به دلیل Read Only بودن این Database خیالمان از بابت تغییرات ناخواسته و تصادفی بر روی Database نیز راحت است.
  2. شما می توانید با استفاده از SQL Snapshot ها فرآیندهای تحلیلی و آنالیزهای داده های خود را در وهله های زمانی معین بصورت ثبت شده نگهداری کنید. برای مثال شما می توانید در انتهای هر سال کاری یک Snapshot کامل از Database های خود بگیرید و بعد از چند سال از گذشته این رویه می توانید روند رشد و تحلیل هایی که نیازمند دسترسی به داده های دقیق سالهای گذشته می باشد را در کنار هم قرار دهید و در نتیجه بهترین گزارش ها را دریافت کنید.
  3. Snapshot ها می توانند برای بازگردانی یا Restore کردن داده ها نیز مورد استفاده قرار بگیرند. شما می توانید داده های خود را دقیقا به زمانی بازگردانی کنید که در آن زمان Snapshot گرفته شده است . برای مثال شما می خواهید تغییراتی را بر روی Database های خود انجام دهید که ممکن است آنها را دچار اختلال کند ، برای اینکه بتوانید بدون استرس اطلاعات خود را مانند قبل به حالت عملیاتی بازگردانید کافیست قبل از انجام هر عملیاتی یک Snapshot از SQL دیتابیس های خود بگیرید.

یک نکته را فراموش نکنید ، هیچوقت کل دیتابیس های شما در Snapshot قرار نمی گیرد . در واقع SQL Snapshot یک اشاره گر یا Pointer به Database اصلی شما می باشد ، اگر شما از آن Query بگیرید متوجه می شوید که Query های شما به Database اصلی Refer داده می شود.

اما این اتفاق تا زمانی رخ می دهد که Page های Database اصلی شما تغییر نکرده باشند ، اگر کوچکترین تغییری در Page های Database اصلی ایجاد شود ابتدا تمامی اطلاعات Page اصلی در Snapshot کپی خواهد شد و سپس داده های جدید در Database اصلی کپی می شوند.

این باعث می شود که Snapshot شما همیشه داده های اصلی را درون خود داشته باشد. توجه کنید که تا زمانیکه Snapshot ها فعال هستند شما نمی توانید Database اصلی را Drop کنید. برای اینکه بتوانید Database خود را Drop کنید ابتدا باید Snapshot های خود را حذف کنید و سپس Database را Drop یا حذف کنید.

همانطور که قبلا هم اشاره کردیم Snapshot ها فضای زیادی را نمی گیرند زیرا فقط داده های که تغییر می کنند را درون خود نگه می دارند و اگر داده ای تغییر نکرده باشد آن را به Source Database متصل می کنند. در آموزش بعدی به شما روش ایجاد کردن یک SQL Snapshot ، حذف کردن داده ها از Database اصلی و در نهایت بازیابی اطلاعات از SQL Snapshot را آموزش خواهیم داد. 

چگونه Snapshot بگیریم؟

در ادامه می خواهیم به شما آموزش دهیم که چگونه بصورت عملی از Database های خود Snapshot بگیرید و داده ای را حذف و از طریق Snapshot آنرا بازیابی کنید.

خوب بیابید با مثالی Snapshot را به خوبی یاد بگیریم. توجه کنید که این مثال فعلا در محیط تست و پایلوت قابل اجرا است و در محیط واقعی کمی بار کاری بر ریو CPU و دیسک و حافظه شما ایجاد خواهد شد ، در این خصوص که چگونه این مشکلات در محیط واقعی باید حل شوند بعد ها صحبت خواهیم کرد ، سناریو به این شکل خواهد بود :

  • یک Database ایجاد می کنیم
  • از این Database داده ای را حذف می کنیم
  • از طریق Snapshot داده مربوطه را بازیابی می کنیم

در اولین مرحله یک Database را با استفاده از دستورات زیر به همراه یک سری داده های آزمایشی ایجاد می کنیم ، در محیط واقعی قاعدتا شما دارای Database می باشید و نیازی به ایجاد کردن آن ندارید نام Database را در اینجا RegularDB قرار می دهیم و چند Table نیز به آن اضافه می کنیم و در نهایت همانطور که در توضیحات دستورات T-SQL هم مشاهده می کنید Snapshot را ایجاد می کنیم :

USE master
GO
-- Create Regular Database
CREATE DATABASE RegularDB
GO
USE RegularDB
GO
-- Populate Regular Database with Sample Table
CREATE TABLE FirstTable (ID INT, Value VARCHAR(10))
INSERT INTO FirstTable VALUES(1, 'First');
INSERT INTO FirstTable VALUES(2, 'Second');
INSERT INTO FirstTable VALUES(3, 'Third');
GO
-- Create Snapshot Database
CREATE DATABASE SnapshotDB ON
(Name ='RegularDB',
FileName='c:\SSDB.ss1')
AS SNAPSHOT OF RegularDB;
GO
-- Select from Regular and Snapshot Database
SELECT * FROM RegularDB.dbo.FirstTable;
SELECT * FROM SnapshotDB.dbo.FirstTable;
GO

بعد از اینکه Table های فرضی را ایجاد کردیم از Database اصلی یک سری داده را با استفاده از دستور زیر حذف می کنیم :

-- Delete from Regular Database
DELETE FROM RegularDB.dbo.FirstTable;
GO
-- Select from Regular and Snapshot Database
SELECT * FROM RegularDB.dbo.FirstTable;
SELECT * FROM SnapshotDB.dbo.FirstTable;
GO

زمانیکه شما دستور بالا برای حذف داده ها از Database را وارد کردید ابتدا و قبل از حذف داده ها در Snapshot کپی می شوند. البته دقت کنید که داده ها در سطح Page ها کپی خواهند شد. قبل از حذف داده ها فایل Snapshot ظرفیت چندانی نخواهد داشت اما بعد از حذف به دلیل اینکه ابتدا در Snapshot کپی شده و بعد حذف می شود حجم فایل Snapshot ما بالا خواهد رفت. حالا با استفاده از دستورات زیر داده ای که حذف کرده ایم را Restore یا بازیابی می کنیم. قاعدتا در این قسمت از Snapshot برای بازگردانی داده ها استفاده خواهیم کرد :

-- Restore Data from Snapshot Database
USE master
GO
RESTORE DATABASE RegularDB
FROM DATABASE_SNAPSHOT = 'SnapshotDB';
GO
-- Select from Regular and Snapshot Database
SELECT * FROM RegularDB.dbo.FirstTable;
SELECT * FROM SnapshotDB.dbo.FirstTable;
GO
-- Clean up
DROP DATABASE [SnapshotDB];
DROP DATABASE [RegularDB];
GO

خوب در این مرحله اگر به Database اصلی مراجعه کنید متوجه می شوید که FirstTable را که حذف کرده بودیم با استفاده از Snapshot بازیابی شده است ، امیدوارم مورد توجه شما قرار گرفته باشد.


محمد نصیری
محمد نصیری

بنیانگذار توسینسو ، هکر کلاه سفید ، کارشناس امنیت اطلاعات و ارتباطات و عاشق طبیعت

هکر با کلاه ، کارشناس امنیت اطلاعات و ارتباطات و کشف جرائم رایانه ای ، بیش از 12 هزار ساعت سابقه تدریس در بیش از 40 سازمان دولتی ، خصوصی و نظامی ، علاقه مند به یادگیری بیشتر و عاشق محیط زیست ، عضو کوچکی از مجموعه توسینسو

نظرات