کار ایندکس Online را برای محیط SQL Server خود اختصاصی کنید:
اخیراً کار نگهداری ایندکس ها را به عهده گرفته ام. به رئیسم گفتم که بلوکه کردن که به وسیله سازمان دهی مجدد ایندکس ها انجام می شود و قفل کردن جدول که به وسیله بازسازی های ایندکس Offline انجام میشود، غیر قابل قبول هستند، زیرا محیط SQL Server ما از تمام سیستم های Enterprise Edition از SQL Server 2008 و2005 تشکیل شده است و من تصمیم دارم از مشکلات این چنینی جلوگیری کنم. من یک راه حل مناسب با قابلیت اختصاصی شدن را جستجو کردم. در نهایت، راه حل خاص خودم را ایجاد کردم، یک کار ایندکس Online که در این مقاله آن را با شما به اشتراک گذاشته امیدوارم برای شما نیز مفید واقع شود. نحوه ایجاد این کار، نحوه پیاده سازی این کار و پرامترهای مختلف کار را به شما نشان خواهم داد.
ایجاد کار ایندکس Online:
نیازمندی های اولیه من برای این کار ساده بود. ابتدا باید مشخص می کردم کدام ایندکس ها می توانند به صورت online بازسازی شوند. با نگاه سریعی به MSDN، دستور العمل های خاصی مشخص می شود. انواع داده شی بزرگ (LOB) مثل ، varchar(max ، nvarchar(max ، text ntex ، image varbinary (max و (XML) باید ایجاد و بازسازی شوند یا به صورت offline حذف شوند. ایندکس های خوشه بندی نشده منحصر به فرد می توانند به صورت online ایجاد شوند، هنگامی که این جدول حاوی انواع داده LOB است، ولی هیچ یک از این ستون ها در تعریف ایندکس به عنوان ستون کلید یا غیر کلید استفاده نمی شوند. ایندکس های خوشه بندی نشده که با ستون های نوع داده LOB تعریف می شوند، باید به صورت Offline ایجاد یا بازسازی شوند. مشخص کنید که کدام ایندکس ها می توانند به صورت online بازسازی شوند، زیرا بازسازی با گزینه ایندکس online در ایندکسی صادر می شود که با معیار offline باید متناسب باشد که این امر منجر به یک خطا و رها شدن ایندکس بدون پردازش می شود. بعد از تعیین این که کدام ایندکس ها می توانند به درستی به صورت online بازسازی شوند، پارامترهای مختلفی را به مراحل مختلف کار ایندکس اضافه کردم. برای ایندکس هایی که نمی توانند به صورت online بازسازی شوند، می توانید آن ها را سازمان دهی مجدد کنید، از آن ها صرف نظر نمایید یا آن ها را به صورت offline بازسازی کنید (اگر مدل کسب و کار شما اجازه می دهد). هم چنین پرامترهایی را اضافه کردم که به شما اجازه می دهند ایندکس ها را سازمان دهد مجدد کنید، البته اگر آن ها تحت درصد قطعه بندی خاصی باشند و در صورتی آن ها را بازسازی کنید که روی درصد خاصی از قطعه بندی باشند. سپس ویژگی هایی را برای ردیابی مدت زمان هر ایندکس، زمان شروع و زمان پایان، پیشرفت، قطعه بندی قبل و بعد از اجرای کار و هر بلوکه کردن نتیجه ای را تعبیه کردم. در نهایت، گزینه ای را برای کنار گذاشتن پایگاه داده ها و جداول از عملیات ایندکس اضافه کرده ام. ولی به رئیسم نگفتم که بلوکه کردن در نتیجه سازمان دهی مجدد قابل قبول نبود؟ برای رفع این مشکل، SPID عملیات ایندکس را ردیابی کرده ام و یک کار فرعی را برای پایش هر بلوکه کردن ایجاد کردم که این عملیات ممکن است به وجود آیند. اگر بلوکه کردن برای بیش از X دقیقه در یک ردیف و بلوک های بیشتر از X فرآیند وجود داشته باشد، SPID کشته می شود، دوره زمانی طی می گردد و عملیات ایندکس بر می گردد. بر طبق گفته مایکروسافت، سازمان دهی مجدد، قفل های بلوکه کردن را در دراز مدت نگه نمی دارد؛ بنابراین، SQL Server به هنگام رسانی ها یا پرس و جوهای در حال اجرا را بلوکه نمی کند. هر چند، در محیط های شدیداً تبادلی نمی توانند از 1800 تراکنش در هر دقیقه فراتر روند، هنگامی که در محیط خودم هستم، باید مراقب سازمان دهی های مجدد باشم، بنابراین تشخیص دهنده بلوکه کردن خودم را دارم. اگر تشخیص دهنده بلوکه کردن، یک SPID را بکشد که در فرآیند انجام یک بازسازی است، چه اتفاقی می افتد؟ به دلیل این که عملیات بازسازی به عنوان تراکنش های مستقل روی می دهند، rollback تحمیل شده از کشتن یک بازسازی offline روی یک ایندکس بزرگ که در حال تکمیل شدن بوده است، خیلی بدتر از این است که به عملیات اجازه ادامه داده بدهیم. به این دلیل، آن ها را با تشخیص دهنده بلوکه مدنظرقرار ندادم. همچنین با بازسازی Online به دلایل مختلفی را مد نظر نداشتم ، از قبیل پیچیدگی های کارآیی احتمال مربوط به برگشت به نگاشت ایندکس ها. بر طبق Microsoft SQL Server "2005
Index Operations" (technet.microsoft.com/en-us/library/cc966402.aspx
"فقط دوره های زمانی خیلی کوتاهی وجود دارد که در آن ها، از عملیات Select و DML هم زمان جلوگیری می شود". هر بلوکه کردنی باید قابل تحمل باشد و جایگزین هایی داشته باشد. یک سازمان دهی مجدد، داستان متفاوتی است. به دلیل این که یک سازمان دهی مجدد فقط روی یک جفت صفحه در یک زمان عمل می کند، اگر کشته شود، فقط عملیات جایگزینی فعلی تحت تأثیر قرار می گیرد. مرتبه بعدی که یک سازمان دهی مجدد صادر می شود، این کار هنگامی بهبود می یابد که از آ ن دست بکشیم .
پیاده سازی کار ایندکس:
برای ایجاد کار ایندکس، این کد را اجرا کنید که می توانید آن را از www.sqlmag.com با InstantDOC ID 101777 به این ترتیب دان لود کنید:
1-Usp_update_schedule_enabler.sql
2-Index_BuildlndexKey.sql
3-Index_Processlndexes.sql
4-Index_PostCleanup_sql
5-Index_PostFragCale.sql
6-Index_HandleBlocking/sql
7-jod_Blocking_Killer.sql
8-job_Indexing_Master.sql
توجه داشته باشید که از پایگاه داده ای به نام "Common" برای میزبانی عملکرد مشترک بین چندین سرور استفاده کردم. قبل از اجرای این فایل های اجرایی، بایدCommon را در هر اسکریپت با مراجعی جایگزین کنید تا مناسب محیط شما باشد. هم چنین، در رویه Index_BuildIndexKey، جداولی را در یک گروه فایل "Tables" ایجاد کردم. باید Tables را به نام گروه فایل تغییر دهید، وگرنه کار ناموفق خواهد بود. هنگام اجرای job_Indexing_Master.sql، چهار هشدار مرحله ناموجود را دریافت خواهید کرد. صرف نظر کردن از آن ها ایمن است. هر مرحله در یک کار باید به صورت ترتیبی ایجاد شود و برخی مراحل، برای صرف نظر کردن از مراحل بعدی در رویداد عدم موفقیت مرحله ای تنظیم می شوند. مثلاً، اگر مرحله 2 نا موفق باشد، کار به مرحله8 می رود. هنگامی که مرحله 2 ایجاد می شود، قطعاً مرحله8 هنوز وجود ندارد و هشداری صادر می شود. بعد از اجرای اسکریپت های فراهم شده، دو کار SQL Server Agent غیر فعال جدید را خواهید دید: DB Maint-Blocking Killer و DB-Maint IndexMaint . مراحل کار DB-Maint IndexMaint را طوری نام گذاری کرده ام که خود توضیح باشند. در ادامه سریعی بر این مراحل داریم: *مرحله1 یک جدول ردیابی را می سازد که به وسیله تمام مراحل بعد برای انجام عملیات آن ها مصرف می شود. این مرحله حاوی بررسی ویرایش و بررسی نگارش است. اگر از ویرایش و نگارش مناسب برای بازسازی online استفاده می کنید، تمام ایندکس های مدنظر برای بازسازی به صورت offline انجام خواهند شد. *مرحله2 و مرحله8 برای تنظیم مدت پشتیبان گیری در صورت لزوم هستند. این عملکرد به رشد و پر شدن logهای تراکنش شما بسته به پیکربندی های درایو و رشد خودکار کمک می کند. بخاطر داشته باشید که logهای تراکنش شما در طی یک عمل بازسازی شفاف نیستند، زیرا همان گونه که بیان کردم، یک عمل بازسازی به عنوان یک تراکنش منفرد روی می دهد. *مرحله 3 و مرحله7 کار DB Maint-Blocking Killer ایجاد شده قبل را برای پایش مقدار بلوکه کردن توسط یک عمل ایندکس خاص به وجود آمده است، فعال و غیر فعال می کنند. اگر بخواهید این ویژگی را اجرا کنید، این مراحل را حذف کنید. *مرحله4 و مرحله9 در صورتی انجام می شوند که بتوانید از مدل بازیافت در محیط سوییچ کنید. من روش بهترین شیوه مایکروسافت را در هر مرحله کار گنجانده ام تا به مدل های بازیافت مختلف توجه داشته باشیم. این ویژگی را به خاطر دارم که بازسازی یک عمل باlog حجیم است، بدین معنی که هنگامی که پایگاه داده شما در مدل بازیافت logged حجیم است، در حداقل log بماند. بر طبق "SQL Server2005 Online Index Operations" هنگام بازسازی یک ایندکس در یک پایگاه داده با logged حجیم، نسبت log به داده، 10درصد نسبت log به داده بازیافت کامل است. logging حداقل هنگامی مفید است که بخواهید اندازه log تراکنش را قابل مدیریت نگه دارید، مخصوصاً در محیط های کپی برداری. *مرحله5 تمام ایندکس ها را در جدول ایجاد شده در مرحله 1 پردازش می کند. می توانید retry interval و retry attempts را در این مرحله با زمان مناسب برای انتظار در رویدادی که در آن blocking killer این مرحله را خاتمه می دهد، تغییر دهید. *مرحله 6 هر یک از عملیات ناقص یا نا موفق را در log خطای SQL Server ثبت می کند. *مرحله 10 برگشته و قطعه بندی را دوباره محاسبه می کند، بنابراین می توانید تصویر قبل و بعد را ببینید. *مرحله 10 و مرحله1 از دیدگاه مدیریت پویا (DMV) sys.dm_db_index_physical_stats برای جمع آوری اطلاعاتی درباره ایندکس ها استفاده می کنند که فقط نیاز به یک قفل جدول IS دارد، بدون توجه به حالتی که در آن اجرا می شود. شکل 1 تمام مراحل فهرست شده بالا را در SQL Server Management Studio SSMS)) نشان می دهد.
پرامترهای کار:
باید نحوه استفاده از تمام پرامترهای ورودی را برای اختصاص کردن طراحی کار ایندکس برای محیط خود بدانید. رویه ذخیره شده در اولین مرحله کار DB-Maint Index Maint (Build Indexing Key تعداد پارامتر را می پذیرد.
@minFragPercent حداقل درصد قطعه بندی یک ایندکس است که باید قبل از در نظر گرفتن یک عملیات ایندکس لحاظ شود. می توانید حداقل درصد قطعه بندی را بر طبق نیازهای خاص خود تنظیم کنید. هر چیزی در زیر این آستانه، صرف نظر خواهد شد.@maxAttempts تعداد دفعاتی است که یک عملیات ایندکس که قبلاً توسط کار DB Maint-Blocking Killer به خاطر بلوکه کردن مازاد کشته شده است، برگردانده خواهد شد. اگر بخواهید فقط یک یا دو پایگاه داده را مد نظر قرار دهید، از @databaselncludelist استفاده کنید که یک varchar با حائل کاما است. اگر بخواهید فقط تعدادی پایگاه داده را کنار بگذارید، از @databaseExcludelist استفاده کنید که آن هم یک varchar با حائل کامل است. سرانجام، اگر بخواهید فقط یک جدول خاص را کنار بگذارید، می توانید این کار را با استفاده از @table Excludelist انجام دهید. رویه ذخیره شده در مرحله 5 کار ایندکس نیز تعدادی پارامتر را می گیرد که شکل 2 نشان می دهد @reorgMinFragPercent حداقل مقدار قطعه بندی است که باید برای سازمان دهی مجدد وجود داشته باشد. این مقدار نباید زیر مقدار @minFragPercent در مرحله Build Index Key باشد. @rebuildMinFragPercent حداقل قطعه بندی است که باید برای بازسازی وجود داشته باشد. مثلاً، اگر این مقادیر را با 20 درصد و 30 درصد تنظیم کنید، هر چیزی زیر 20 درصد قطعه بندی صرف نظر خواهد شد، هر چیزی بین 20 و 30 درصد قطعه بندی سازمان دهی مجدد می شود و هر چیزی بزرگ تر یا مساوی 30 درصد، در صورت امکان به صورت online بازسازی می شود. اگر این دو درصد را مساوی یکدیگر تنظیم کنید، فقط بازسازی روی خواهند داد. تنظیم @onlineOnly با 1بدین معنی است که قصد دارید فقط بازسازی های online را انجام دهید. تنظیم این مقدار با 0 موجب خواهد شد ایندکس ها در صورت امکان به صورت online ساخته شوند، در غیر این صورت به صورت offline ساخته می شوند. @reorgNonOnline در صورت تنظیم با 1 به همراه @onlineOnly که با 1 تنظیم شده است، به ایندکس ها اجازه می دهد که نتوانند بازسازی شوند. اگر تمام ایندکس های شما بتوانند سازمان دهی مجدد شوند، @globalAllowReargs را اضافه کرده ام تا ایمنی ناموفق نهایی باشد که اجازه می دهد سازمان دهی های مجدد در مقیاس جهانی روی دهند. در محیط من، مطلقاً حیاتی است که برخی ایندکس ها مجدداً سازمان دهی نشوند. اگر تمام ایندکس های شما بتوانند سازمان دهی مجدد شوند، @globalAllowReargs می تواند با 1 تنظیم شود. سرانجام،DB Maint-Blocking Killer حاوی یک مرحله است که شامل یک رویه ذخیره شده است که دو پارامتر را می پذیر. @blockingMins تعداد دقایقی است که یک SPID به عنوان بلوکه شده تشخیص داده شده است. این کار هر دقیقه اجرا می شود و بررسی بلوکه شدن را انجام می دهد. اگر SPID را بیابد که یک عملیات ایندکس را انجام می دهد، @blockingMins را در یک ردیف بلوکه می کند و SPID را می کشد. برای تعریف بلوکه کردن، پارامتر @blockingProcesses را اضافه کرده ام. اگر SPID بلوکه شده بیش از فرآیندهای @blockingProcesses بلوکه شده باشد، خاطی در نظر گرفته شده و تعداد بلوکه آن تکرار می شود. به خاطر زمان و فضا، در این مقاله، مستندات جامع کد توصیف کننده هر مرحله و پارامترهای آن ها را نیاورده ام. هنگام پیکربندی DB-Maint Index Maint طبق سلیقه خود، تعیین زمان بندی را داشته باشید، مطمئن شوید که آن را در SSMS با کلیک راست روی کار و انتخاب Enable فعال کرده اید.
حداقل کردن کارآیی ایندکس:
به دلیل این که عملیات بازسازی به عنوان تراکنشی مستقل روی می دهد، rollback تحمیلی از کشتن بازسازی offline روی یک ایندکس بزرگ که در حال تکمیل است، خیلی بدتر از اجازه دادن به ادامه آن عملیات است. این راه حل به شما اجازه می دهد حداکثر کارآیی را در مورد ایندکس های خود بدون اجبار در قربانی کردن چیزی داشته باشید. من نتوانستم عملکردی را به این کار اضافه کنم، ولی تشخیص دادم که هیچ کاری به طور کامل در تمام برنامه ها نوشته نمی شود، یا به کار گرفته نمی شود. در این کد، به تعدادی توضیح توجه خواهید کرد که در توسعه حداقل هستند. این ها تعدادی پارامتر اضافی هستند که می توانند استفاده شوند، توسعه یابند یا حذف شوند تا این کار طبق محیط شما طراحی شود. من امیدوارم این کار ایندکس به شما کمک کند به سادگی بازسازی ایندکس ها را به صورت online انجام دهید.
منبع:ماهنامه ی رایانه شماره 188