PDA

View Full Version : خطا در زمان پشتیبانگیری از دیتابیس حجیم تحت شبکه (خطای بدجنس)



abbasi.naft
دوشنبه 01 دی 1393, 00:18 صبح
سلام به خدمت مدیران محترم و دوستان بزرگوار

گاهی اوقات ، یه خطاهایی گریبان انسان رو میگیره که حتی فکرش رو هم نمیکردید.

exeception of type 'system.outofMemoryException' was thrown

برنامه با سی شارپ نوشته شده و بانک اسکیوال سرور هم نگارش 2005 هست و روی سرور قرار گرفته و بعد از مدتی کار حجم دیتابیس به 3 گیگ رسیده و حالا که کلاینتها میخوان پشتیان بگیرن ، این خطای بدجنس نمایان میشه و متاسفانه راه حل خاصی براش ندارم.

البته میتونم برم و روی سرور یه Job بنویسم ولی میخوام ببینم راه حلی داره؟؟؟؟

پیشاپیش از حسن توجه و همکاری شما اساتید محترم ، کمال تشکر و قدردانی را دارم.

mohammad reza beizavi
شنبه 06 دی 1393, 01:48 صبح
درود
این خطا ب موقعی اتفاق میفته که یه process بخواد حجم زیادی رو stream کنه و ram سیستم مورد نظر (اینجا همون سرور SQL ) قادر به stream کردن این حجم نباشه. به خاطر تبادل اطلاعات stream شده با فضای روی هارد بهتره برید توی run و این بنویسید %temp% تا پوشه حاوی فایلهاو چوشه های موقت رو ببینید و اونا رو حذف کنید تا این مشکل حل بشه.

اما برای پشتیبان گیری از پایگاه داده اونم با این حجم می بایست راهکارهای بهتر از دادن اختیار اینکار به دست کاربر یا حتی مدیر سیستم در نظر بگیرید.
پیروز باشید.

abbasi.naft
یک شنبه 07 دی 1393, 08:38 صبح
خیلی ممنون که به این سوال پاسخ دادید.

فرمایش شما کاملا متین.
اما برنامه بعد از مدت زمان یک سال به این حجم رسیده است، و از آنجایی که سیستم سرور هدف مربوط به یکی از ادارات کل استانمون می باشد و تعداد کلاینتها به مرور زمان ممکن است زیاد شود و دیتا آنها مهم تلقی میشود لذا امر پشتیبانگیری بایستی به سوپروایزر مربوطه محول گردد.
لذا تنها راه پشتیبانگیری از طریق برنامه می باشد.

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

mohammad reza beizavi
سه شنبه 09 دی 1393, 00:38 صبح
درود دوباره
این مشکل به دلیل کمبود resource سیستم شما که در اینجا Memory هست اتفاق میفته. شما می تونید با آزاد کردن مقدار فضای مورد نیاز برای stream کردن حجم مورد نیاز ببینید که این مشکل حل میشه.
اما برای backup گرفتن از دیتابیس حجیم راهکارهای بهتری به نظرم میرسه که در صورت تمایل بیشتر در این خصوص بحث می کنیم

abbasi.naft
سه شنبه 09 دی 1393, 22:07 عصر
سلام مجدد
خیلی ممنون که علمتون رو از دیگران دریغ نمیکنید.

صحبتتون در مورد Memory کاملا درست ، اما من قبلا جای دیگه دیده بودم که حجم دیتابیس بیش از 6 گیگ بوده و به راحتی با همین نگارش اسکیوال 2005 از آن ، توسط کلاینتها پشتیبان گرفته میشده است.

حالا من یک سوال برام پیش اومده ، اونم اینه که یعنی مایکروسافت ، این محصول ارزشمندش رو محدود به فضای رم سیستم کرده؟ یعنی اگه سرور هدف نهایتا 4 گیگ یا کمتر فضای رم داشت ، باید قید اسکیوال سرور رو برای مقاصد و نرم افزار های سازمانی بزرگش بزنه و بره به سراغ اُراکل؟

مشخصات سرور هدفی که من از اون بهره میبرم : میندوز سرور 2003 , رم 4 گیگ , فضای خالی درایو سی هم حداقل 40 گیگ هست.

میتونم از گزینه های دیگه نظیر تعریف Job استفاده بکنم ، اما با توجه به خصوصیاتی که از Job الان به خاطر دارم ، اینه که در زمان های مشخص و توسط خود اسکیوال سرور گرفته میشه ، حالا اگه سوپروایزر سیستم در زمان اداری نیاز به پشتیبان داشته باشه ، تکلیف چیه؟ آیا راهی به جز محول کردن این وظیفه به کلاینتها وجود داره که به لحاظ زمانی محدودیتی نداشته باشه؟

این بحث Stream که میفرمایید ، کاملا متین ، اما کاربر در صورتی که سروری با مشخصات بالا داشته باشه ، باید از قابلیت های ارزشمند اسکیوال سرور بی بهره بمونه؟
مگه هدف ذخیره پشتیبان بر روی هارد نیست؟
قاعدتا همین طوره ، پس مایکروسافت نمیتونه فضای رم رو پر و خالی بکنه تا کل اطلاعات پشتیبان به هارد منتقل بشه.

لطفا این پیش فرض رو در نظر داشته باشید که یوزر نهایی که میخواد از نرم افزار استفاده بکنه ، فرق دست راست و چپش رو به زحمت میفهمه و تنها میدونه که دکمه ای که با فونت بزرگ روش نوشته ، پشتیبانگیری ، باید از اون استفاده بکنه.

پیشاپیش از حسن توجه و همکاری شما استاد گرامی کمال تشکر و قدردانی را دارم.

mohammad reza beizavi
پنج شنبه 11 دی 1393, 00:25 صبح
درود بر شما
پوزش بابت اینکه دیر جواب میدم
منظورم از کم آوردن Memory هنگام استفاده از SQL Server حالا یا با Management studio یا SQLCMD بود و این مورد درصورتی پیش میاد که فایلتون از سه برابر اندازه Memory بیشتر باشه (یعنی 1 بار Memory و 2 برابر آن Virtual Memory که قابل تنظیم هست) و پوشه temp توی سیستم عامل هم هیچ جای خالی نداشته باشه. پس برخورد با این مشکل به ندرت پیش میاد و بیشتر فاجعه هست تا مشکل.

اما موردی که در اینجا مطرح می کنید مربوط به Microsoft SQL Server نیست و بیشتر به IIS بر می گرده (در صورت استفاده از تکنولوژی web). احتمال بسیار زیاد میدم که شما می تونید با یک دستور ساده Backup یا با استفاده از wizard خیلی سریع و ساده از پایگاه داده نسخه پشتیبان بگیرید البته داخل Local system اینکار به سرعت انجام میشه در صورتی که مشکل بالا رو نداشته باشید. با استفاده از Management studio و از روی شبکه هم اینکار راحت انجام میشه و فقط اگر فایل رو می خواید از روی شبکه به Client یا ماشینی غیر از Server منتقل کنید، این زمان رو هم (انتقال فایل از روی شبکه) به مدت زمان کار اضافه کنید و منتظر بمونید.
پس دنبال تنظماتی در IIS بگردید که امکان انتقال فایل با حجم بالا رو برای شما فراهم کنه که البته این تنظیمات برای هاست شما در web.config نوشته میشه.

این قسمت رو باید از اساتید C#‎‎‎‎‎‎ و web بپرسید اما با یه جستجوی ساده به این گزینه ها رسیدم،امکان داره مشکلتون رو حل نکنه اما میدونم مشکل از انتقال large file هاست و در این صفحات توضیحات خوبی موجود هست:
http://msdn.microsoft.com/en-US/library/9w766t6y(v=vs.80).aspx
http://msdn.microsoft.com/en-us/library/system.outofmemoryexception(v=vs.110).aspx

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

پیروز باشید

abbasi.naft
پنج شنبه 11 دی 1393, 18:46 عصر
سلام مجدد
خواهش میکنم، همیقدر که پایه کار هستید، بر سرم منت گذاشتید.

برنامه برپایه فریم ورک 2 و ویندوز اپلیکیشن هست.
یه سوال برام پیش امده، مگه این temp که میفرمایید ، جزئی از پوشه های درایو ویندوز نیست؟ قاعدتا جواب مثبته و temp درون درایوی که ویندوز در آن نصب شده هست وجو دارد که معمولا این درایو، درایو سی می باشد.
پس اگه درایو سی ، 40 گیگ فضا داره ، پس temp هم فضا دارد، پس اون فرمولی که در بالا فرمودید ، بایستی همچنان پابرجا باشد.

پس اگه بحث Stream مشکل داشته باشه ، پس استفاده از Job هم ، باید همین مشکل رو داشته باشه؟ (پس این دفعه که میرم،بازم ضایع میشم:گریه:)

این کلاسی هست که از اون استفاده میکنم.


public class Database{
public static readonly string DBName = "Heiat_DB"; public static readonly string DBName2 = "Heiat_Images_DB"; public static string cnnStr = "Data Source=TAJMIOSTAN;Initial Catalog=Heiat_DB;User ID=sa;password=abbasinaft";
public static string ConnectionString { get { return cnnStr; } set { cnnStr = value; con = new SqlConnection(cnnStr); cmd = new SqlCommand("", con); } }
private static SqlConnection con = new SqlConnection(cnnStr); private static SqlCommand cmd = new SqlCommand("", con);
/// <summary> /// /// </summary> public static SqlParameterCollection Parameters { get { return cmd.Parameters; } }
public static DataTable RunCommand(string command) { try { command = command.ToString().Replace('ي', 'ی').Replace('ك', 'ک'); cmd.CommandText = command; cmd.CommandType = CommandType.Text; con.Open(); DataTable dt = new DataTable(); dt.Load(cmd.ExecuteReader()); return dt; } finally { Parameters.Clear(); con.Close(); } }
public static DataTable RunProcedure(string procedure) { try { con.Open(); cmd.CommandText = procedure; cmd.CommandType = CommandType.StoredProcedure; DataTable dt = new DataTable(); dt.Load(cmd.ExecuteReader()); return dt; } finally { Parameters.Clear(); con.Close(); } }
public static void AddParameter(string name, object value) { value = value.ToString().Replace('ي', 'ی').Replace('ك', 'ک').Trim(); Parameters.AddWithValue(name, value); }
public static void AddParameter(string name, object value, bool nullAble, bool forienKey) { if (nullAble && (value == null || (forienKey && double.Parse(value.ToString()) < 1))) return; value = value.ToString().Replace('ي', 'ی').Replace('ك', 'ک').Trim(); Parameters.AddWithValue(name, value); }
public static void ClearParameters() { cmd.Parameters.Clear(); }
public static void BackupDB(string DatabaseName, string Destination) { RunCommand("backup database [" + DatabaseName + "] to disk = N'" + Destination + "' with format"); } public static void RestoreDB(string BackupSource, string DatabaseName) { if (!DatabaseName.Contains(@"\")) { RunCommand("ALTER DATABASE [" + DatabaseName + "] SET Single_User WITH Rollback Immediate"); } RunCommand("USE [master]; RESTORE DATABASE [" + DatabaseName + "] FROM DISK = N'" + BackupSource + " ' WITH FILE = 1, NOUNLOAD, REPLACE, STATS = 10"); if (!DatabaseName.Contains(@"\")) { RunCommand("ALTER DATABASE [" + DatabaseName + "] SET Multi_User"); } }}

در داخل دکمه هم در رخداد کلیک تابع Database.BackupDB رو استفاده میکنم.

mohammad reza beizavi
جمعه 12 دی 1393, 18:52 عصر
به نظر من یه رویه رو دنبال کنید تا گام به گام از مشکل به وجود آمده و اینکه علت کجاست مطمئن بشید. اینجور با مباحث تئوریک وقتتون گرفته نمیشه.
شما ابتدا همین نسخه پشتیبان رو روی سرور بگیرید تا از کارکرد SQL Server مطمئن بشید. (البته در صورت داشتن فضای کافی من در این مورد مطمئنم)
بعد یه script خیلی ساده برای همین کار رو از روی Client انجام بدید که البته مقصد فایل روی همون Server باشه.
بعد همینکار رو با مسیر فایل رو Client انجام بدید.
این مراحل رو برید متوجه قسمت مسئله دار خواهید شد و با هم بررسی خواهیم کرد

abbasi.naft
جمعه 12 دی 1393, 22:49 عصر
سلام مجدد
بله ، حق با شماست.
روی سرور در حال حاضر دوتا دیتابیس وجود داره ، یکی حجمش خیلی خیلی پایینه و زیر 100 مگ هست و اون یکی دیگه متاسفانه حجمش چند گیگ شده.
اون دیتابیس زیر 100 مگ ، به راحتی از روی خود سرور و هم از روی کلاینتها به کمک برنامه سی شارپ به راحتی عملیات پشتیبانگیری را به انجام میرسانند.
پس تا اینجای کار هیچ مشکلی نیست.

دیتابیس حجیم رو دفعه آخر کدهاش رو اینگونه تغییر دادم که پس از دریافت دستور پشتیبانگیری که از سوی کلاینت به سمت سرور ارسال میشود، بر روی فضای هارد خود سرور ، پشتیبان ذخیره شود. که نتیجه همون خطایی شد که خدمتتون ارسال کردم. ولی از روی خود سرور اقدام به گرفتن پشتیبان نکردم.
به همین خاطر داخل منزل بصورت شبیه سازی شده دیتابیسی با حجم بالاتر حدود 5 گیگ درست کردم، ولی باز هم متاسفانه به خطا خوردم. ولی خطا اینبار چیز دیگه بود که الان حضور ذهن ندارم ، چون بدلیل حجم زیاد دیتابیس ، پاکش کردم.
یه لطفی میکنید ، اگه زمان دارید و روی سیستمتون SQL server نصب دارید ، یک دیتابیس با حجم مشابه 5 گیگ بسازید و اقدام به پشتیبانگیری نمایید و ببینید که شما هم به مشکل من برمیخورید ، یا خیر.
در صورتی که به مشکل بر نخوردید به معنی این هست که نگارش اسکیوال من دارای نقاط ضعفی هست که تابحال خود را نشان نداده است.
من از نگارش استاندارد 2005 استفاده میکنم.

با اینکه قرار شد سر مسائل تئوریک در حال حاضر بحث نکنیم، بازم برای جای سواله که هیچجوری مایکروسافت این رو پوشش نداده؟ چرا هرچی توی وب میگردم و تست میکنم، بازم قصه همون قبلیه هست.

از اینکه همچنان به حل این مشکل علاقه نشون میدید، از شما کمال تشکر و قدردانی را دارم.

mohammad reza beizavi
دوشنبه 15 دی 1393, 21:45 عصر
درود بر شما
پوزش برای دیر شدن پاسخگویی
من بانک اطلاعاتی 2008 ، 2012 و 2014 با حجم بالای 5 گیگ دارم و آزمایش کردم، مورد خاصی ندارم
در خصوص نسخه که فرمودید نظر خاصی ندارم چون تا آخر هفته امکان آزمایشش رو ندارم، در کوتاهترین زمان نتایج رو به اظلاع دوستان می رسونم

در ضمن پاسخگویی در stackoverflow.com و تالار گفتگوی Microsoft جای بسیار مناسبی برای رسیدن به اینچنین سوالاهایی هست.
و اگر ابهام یا اشکال اثبات شده ای رو به Micorsoft ارجاع بدید علاوه بر رفع یا راهنمایی به شما،گزارش دهی خوبی هم در تمام مراحل برای شما خواهند داشت

در مورد انتقال نسخه پشتیبان به Client هم توی محصولات شرکت استفاده شده که با حجم بالا هم مشکلی نداشتیم، در مورئ تکنیک و جزییات اطلاعاتی رو می گیرم و برای شما و دوستان به اشتراک میذارم.

abbasi.naft
دوشنبه 15 دی 1393, 23:34 عصر
سلام مجدد
خیلی ممنون که وقت گذاشتید و امتحان کردید.
من خودم هم از اینکه با این خطا روبرو شده بوده کمی متعجب شده بودم.
انشاالله طی چند روز آینده ، نگارش اسکیوال سیستمم رو به بالاترین نگارش ممکنه ارتقا میدم و برای تست دیتابیس 5 گیگ ازش استفاده میکنم ، اگه مشکلی رخ نداد ( امیدوارم که این طور باشه. ) ، انشاالله سر ماه با دست پُر میرم و سرور اون اداره مورد نظر رو برای چند ساعت میخوابونم.

خیلی خیلی ممنون دوست گرامی و استاد ارجمند که وقت ارزشمندتون رو برای کسی که نمیشناسیدش ، صرف کرده و میکنید.:قلب: