SQL Server Corruption Recovery - When All Else Fails
تکنیکهایی برای برگرداندن اطلاعات از فایلهای SQL Server که خسارت دیده اند و خراب شده اند و از بخت بد، فایل Backup یا موجود نیست و یا روشهای معمول برگرداندن اطلاعات درست کار نمیکنند.
در این تمرین بانک اطلاعاتی نمونه AdventureWorksLT2008R2 بکار گرفته شده است.
در این تکنیک از کلاس RawDatabase که در پروژه منبع باز OrcaMDF که یک پارسر (Parser) تحت زبان #C برای خواندن فایلهای mdf. بانک اطلاعاتی SQL Server بدون Attach کردن یا اجرای SQL Server میباشد استفاده شده است.
حتی اگر تمام امیدتان را برای برگرداندن اطلاعات از دست داده اید ، هنوز هم گزینه های وجود دارد . ابزار OrcaMDF یا راه حلهای دیگر ممکن است به دلیل یک فاجعه به صورت یک ابزار ارزشمند درآمده باشد. البته این یک جایگزین خوب برای برگرداندن اطلاعات نیست.
تکنیکهایی برای برگرداندن اطلاعات از فایلهای SQL Server که خسارت دیده اند و خراب شده اند و از بخت بد، فایل Backup یا موجود نیست و یا روشهای معمول برگرداندن اطلاعات درست کار نمیکنند.
در این تمرین بانک اطلاعاتی نمونه AdventureWorksLT2008R2 بکار گرفته شده است.
در این تکنیک از کلاس RawDatabase که در پروژه منبع باز OrcaMDF که یک پارسر (Parser) تحت زبان #C برای خواندن فایلهای mdf. بانک اطلاعاتی SQL Server بدون Attach کردن یا اجرای SQL Server میباشد استفاده شده است.
حتی اگر تمام امیدتان را برای برگرداندن اطلاعات از دست داده اید ، هنوز هم گزینه های وجود دارد . ابزار OrcaMDF یا راه حلهای دیگر ممکن است به دلیل یک فاجعه به صورت یک ابزار ارزشمند درآمده باشد. البته این یک جایگزین خوب برای برگرداندن اطلاعات نیست.
برنامههای قدیمی، الزاما خیلی قدیمی هم نیستند؛ برنامههایی هستند پر از کوئریهای ذیل:
ویژگی مهم این نوع کوئریها که با جمع زدن رشتهها و یا مقدار دهی مستقیم فیلدها تشکیل شدهاند، «غیر پارامتری» بودن آنها است.
این نوع مشکلات با بکار گیری ORMها به نحو قابل توجهی کاهش یافتهاست؛ زیرا این نوع واسطها در اغلب موارد، در آخر کار کوئریهایی پارامتری را تولید میکنند.
مشکل کوئریهای غیر پارامتری چیست؟
استفادهی وسیع از کوئریهای غیرپارامتری با SQL Server، مشکلی را پدید میآورد به نام «Cache bloat» یا «کش پُف کرده» و این «پُف» به این معنا است که کش کوئریهای اجرا شدهی بر روی SQL Server بیش از اندازه با Query planهای مختلف حاصل از بررسی نحوهی اجرای بهینهی آنها پر شدهاست. هر کوئری که به SQL Server میرسد، جهت اجرای بهینه، ابتدا پردازش میشود و دستور العملی خاص آن، تهیه و سپس در حافظه کش میشود. وجود این کش به این خاطر است که SQL Server هربار به ازای هر کوئری رسیده، این عملیات پردازشی را تکرار نکند. مشکل از زمانی شروع میشود که SQL Server کوئریهایی را که از نظر یک برنامه نویس مانند هم هستند را به علت عدم استفادهی از پارامترها، یکسان تشخیص نداده و برای هر کدام یک Plan جداگانه را محاسبه و کش میکند. این مساله با حجم بالای کوئریهای رسیده دو مشکل را ایجاد میکند:
الف) مصرف حافظهی بالای SQL Server که گاهی اوقات این حافظهی اختصاص داده شدهی به کش کوئریها به بالای یک گیگابایت نیز میرسد.
ب) CPU Usage بالای سیستم
سیستم قدیمی است؛ امکان تغییر کدها را نداریم.
بدیهی است بهترین راه حلی که در اینجا وجود دارد، پارامتری ارسال کردن کوئریها به SQL Server است تا به ازای هر تغییری در مقادیر آنها، این کوئریها باز هم یکسان به نظر برسند و SQL Server سعی در محاسبهی مجدد Plan آنها نکند. اما ... اگر این امکان را ندارید، خود SQL Server یک چنین قابلیتهایی را به صورت توکار تدارک دیدهاست که باید فعال شوند.
فعال سازی پارامتری کردن خودکار کوئریها در SQL Server
اگر نمیتوانید کدهای یک سیستم قدیمی را تغییر دهید، SQL Server میتواند به صورت خودکار اینکار را برای شما انجام دهد. در این حالت فقط کافی است یکی از دو دستور ذیل را اجرا کنید:
حالت simple بیشتر جهت پارامتری کردن خودکار کوئریهای select بکار میرود. اگر میخواهید تمام کوئریهای select, insert, update و delete را نیز پارامتری کنید، باید از حالت forced استفاده نمائید.
فعال سازی بهبود کارآیی SQL Server با کوئریهای Ad-Hoc زیاد
به کوئریهای غیرپارامتری، کوئریهای Ad-Hoc نیز گفته میشود. اگر سیستم فعلی شما، تعداد زیادی کوئری Ad-Hoc تولید میکند، میتوان فشار کاری SQL Server را برای این مورد خاص، تنظیم و بهینه سازی کرد.
فعال سازی گزینهی ویژهی «Optimize for Ad hoc Workloads» سبب میشود تا SQL Server پس از مدتی به صورت خودکار کش Plan کوئریهایی را که به ندرت استفاده میشوند، حذف کند. همین مساله سبب آزاد شدن حافظه و بهبود کارآیی کلی سیستم میگردد. همچنین باید درنظر داشت که کش Plan کوئریها نامحدود نیست و سقفی دارد. به همین جهت آزاد شدن آن، کش کردن کوئریهایی را که بیشتر استفاده میشوند، سادهتر میکند.
برای اعمال آن به یک بانک اطلاعاتی خاص، نیاز است دستورات ذیل را اجرا کرد:
برای مطالعهی بیشتر
Fixing Cache Bloat Problems With Guide Plans and Forced Parameterization
Optimizing ad-hoc workloads
Optimizing for Ad hoc Workloads
SELECT * FROM table1 WHERE OrderDate ='12 Mar 2004' SET @SQL = 'SELECT * FROM table2 WHERE OrderDate = ' + '''' + @Var + '''' EXEC (@SQL)
این نوع مشکلات با بکار گیری ORMها به نحو قابل توجهی کاهش یافتهاست؛ زیرا این نوع واسطها در اغلب موارد، در آخر کار کوئریهایی پارامتری را تولید میکنند.
مشکل کوئریهای غیر پارامتری چیست؟
استفادهی وسیع از کوئریهای غیرپارامتری با SQL Server، مشکلی را پدید میآورد به نام «Cache bloat» یا «کش پُف کرده» و این «پُف» به این معنا است که کش کوئریهای اجرا شدهی بر روی SQL Server بیش از اندازه با Query planهای مختلف حاصل از بررسی نحوهی اجرای بهینهی آنها پر شدهاست. هر کوئری که به SQL Server میرسد، جهت اجرای بهینه، ابتدا پردازش میشود و دستور العملی خاص آن، تهیه و سپس در حافظه کش میشود. وجود این کش به این خاطر است که SQL Server هربار به ازای هر کوئری رسیده، این عملیات پردازشی را تکرار نکند. مشکل از زمانی شروع میشود که SQL Server کوئریهایی را که از نظر یک برنامه نویس مانند هم هستند را به علت عدم استفادهی از پارامترها، یکسان تشخیص نداده و برای هر کدام یک Plan جداگانه را محاسبه و کش میکند. این مساله با حجم بالای کوئریهای رسیده دو مشکل را ایجاد میکند:
الف) مصرف حافظهی بالای SQL Server که گاهی اوقات این حافظهی اختصاص داده شدهی به کش کوئریها به بالای یک گیگابایت نیز میرسد.
ب) CPU Usage بالای سیستم
سیستم قدیمی است؛ امکان تغییر کدها را نداریم.
بدیهی است بهترین راه حلی که در اینجا وجود دارد، پارامتری ارسال کردن کوئریها به SQL Server است تا به ازای هر تغییری در مقادیر آنها، این کوئریها باز هم یکسان به نظر برسند و SQL Server سعی در محاسبهی مجدد Plan آنها نکند. اما ... اگر این امکان را ندارید، خود SQL Server یک چنین قابلیتهایی را به صورت توکار تدارک دیدهاست که باید فعال شوند.
فعال سازی پارامتری کردن خودکار کوئریها در SQL Server
اگر نمیتوانید کدهای یک سیستم قدیمی را تغییر دهید، SQL Server میتواند به صورت خودکار اینکار را برای شما انجام دهد. در این حالت فقط کافی است یکی از دو دستور ذیل را اجرا کنید:
--Forced ALTER DATABASE dbName SET PARAMETERIZATION FORCED --Simple ALTER DATABASE dbName SET PARAMETERIZATION SIMPLE
فعال سازی بهبود کارآیی SQL Server با کوئریهای Ad-Hoc زیاد
به کوئریهای غیرپارامتری، کوئریهای Ad-Hoc نیز گفته میشود. اگر سیستم فعلی شما، تعداد زیادی کوئری Ad-Hoc تولید میکند، میتوان فشار کاری SQL Server را برای این مورد خاص، تنظیم و بهینه سازی کرد.
فعال سازی گزینهی ویژهی «Optimize for Ad hoc Workloads» سبب میشود تا SQL Server پس از مدتی به صورت خودکار کش Plan کوئریهایی را که به ندرت استفاده میشوند، حذف کند. همین مساله سبب آزاد شدن حافظه و بهبود کارآیی کلی سیستم میگردد. همچنین باید درنظر داشت که کش Plan کوئریها نامحدود نیست و سقفی دارد. به همین جهت آزاد شدن آن، کش کردن کوئریهایی را که بیشتر استفاده میشوند، سادهتر میکند.
برای اعمال آن به یک بانک اطلاعاتی خاص، نیاز است دستورات ذیل را اجرا کرد:
use dbName; -- Optimizing for Ad hoc Workloads exec sp_configure 'show advanced options',1; RECONFIGURE; go exec sp_configure 'optimize for ad hoc workloads',1; RECONFIGURE; Go
برای مطالعهی بیشتر
Fixing Cache Bloat Problems With Guide Plans and Forced Parameterization
Optimizing ad-hoc workloads
Optimizing for Ad hoc Workloads
یکی از قابلیتهای ابزار خط فرمان dotnet، امکان تبدیل یک پروژهی سفارشی سازی شده، به یک قالب نصب پروژههای جدید بر مبنای آن است. برای مثال فرض کنید میخواهیم پروژهی DNTIdentity را تبدیل به یک قالب جدید کنیم تا به سادگی بتوان پروژههای جدید را بر مبنای آن ایجاد کرد.
ساخت پوشهی مخصوص template.config.
اولین قدم جهت تبدیل یک پروژهی از پیش موجود، به قالبی جدید، افزودن پوشهی ویژهای به نام template.config. به ریشهی آن است. سپس فایل خالی template.json را با محتوای ذیل به آن اضافه کنید:
توضیحات:
در اینجا متادیتای تعریف شده شامل موارد ذیل است:
Author: اطلاعات نویسنده است.
Classification: امکان جستجوی بهتر این قالب را فراهم میکند.
Name: توضیحاتی در مورد پروژه.
Identity: نام منحصربفرد پروژه.
ShortName: نامی است که از آن جهت تولید پروژههای جدید، استفاده میشود.
SourceName: مهمترین تنظیم این گروه بوده و نام فضای نام اصلی پروژهاست. زمانیکه پروژهی جدیدی را ایجاد میکنید، این نام به صورت خودکار بر اساس نام جدید انتخابی اصلاح و جایگزین خواهد شد (در تمام پروژههای مربوط به solution جاری).
معرفی قالب تهیه شده به سیستم dotnet
پس از ساخت فایل template.config\template.json. در ریشهی پروژه، اکنون از طریق خط فرمان به ریشهی پروژه وارد شده و دستور ذیل را صادر کنید:
در اینجا dp0~% با آدرس پوشهی جاری جایگزین میشود. اگر نیاز است آنرا به صورت دستی مقدار دهی کنید.
پس از نصب این پوشه به عنوان یک قالب جدید، یکبار از سیستم وجود آنرا کوئری بگیرید:
اگر به خروجی آن دقت کنید، یک سطر ذیل به آن اضافه شدهاست:
نحوهی ایجاد یک پروژهی جدید بر اساس قالب نصب شده
پس از ساخت این قالب جدید و معرفی آن به سیستم، نحوهی کار با آن به صورت ذیل است:
در اینجا dntidentity همان Short Name تنظیم شدهاست و پارامتر n، نام Solution جدید را مشخص میکند. پس از اجرای این دستور مشاهده خواهید کرد که این نام جدید بر روی نام پوشهها و همچنین فضاهای نام تولیدی به صورت خودکار اعمال شدهاست و مقدار «ASPNETCoreIdentitySample» پیشفرض را بازنویسی کردهاست.
ساخت پوشهی مخصوص template.config.
اولین قدم جهت تبدیل یک پروژهی از پیش موجود، به قالبی جدید، افزودن پوشهی ویژهای به نام template.config. به ریشهی آن است. سپس فایل خالی template.json را با محتوای ذیل به آن اضافه کنید:
{ "author": "VahidN <https://www.dntips.ir/>", "classifications": [ "MVC", ".NET Core", "ASP.NET Core" ], "name": "Empty DNT.Identity project", "identity": "DNT.Identity", "shortName": "dntidentity", "tags": { "language": "C#" }, "sourceName": "ASPNETCoreIdentitySample" }
در اینجا متادیتای تعریف شده شامل موارد ذیل است:
Author: اطلاعات نویسنده است.
Classification: امکان جستجوی بهتر این قالب را فراهم میکند.
Name: توضیحاتی در مورد پروژه.
Identity: نام منحصربفرد پروژه.
ShortName: نامی است که از آن جهت تولید پروژههای جدید، استفاده میشود.
SourceName: مهمترین تنظیم این گروه بوده و نام فضای نام اصلی پروژهاست. زمانیکه پروژهی جدیدی را ایجاد میکنید، این نام به صورت خودکار بر اساس نام جدید انتخابی اصلاح و جایگزین خواهد شد (در تمام پروژههای مربوط به solution جاری).
معرفی قالب تهیه شده به سیستم dotnet
پس از ساخت فایل template.config\template.json. در ریشهی پروژه، اکنون از طریق خط فرمان به ریشهی پروژه وارد شده و دستور ذیل را صادر کنید:
dotnet new -i %~dp0
پس از نصب این پوشه به عنوان یک قالب جدید، یکبار از سیستم وجود آنرا کوئری بگیرید:
dotnet new --list
Templates Short Name Language Tags --------------------------------------------------------------------------------------------------------------- Console Application console [C#], F#, VB Common/Console Class library classlib [C#], F#, VB Common/Library Empty DNT.Identity project dntidentity [C#] MVC/.NET Core/ASP.NET Core
نحوهی ایجاد یک پروژهی جدید بر اساس قالب نصب شده
پس از ساخت این قالب جدید و معرفی آن به سیستم، نحوهی کار با آن به صورت ذیل است:
dotnet new dntidentity -n MyNewProj
ک گره جدول ، موجودی موجود در یک طرح گراف را نشان میدهد. هر بار که یک گره جدول ایجاد میشود ، همراه با ستونهای تعریف شده توسط کاربر ، یک ستون ضمنی $node_id ایجاد میشود ، که به طور یونیک به یک مپ میشود. مقادیر $node_id به طور خودکار تولید میشوند و ترکیبی از object_id آن گره جدول و مقدار bigint تولید شده در داخل هستند. با این حال ، وقتی ستون $node_id انتخاب میشود ،...