دلایل Crash کردن Database
Table is marked as crashed and should be repaired
گاهی Table های دیتابیس با خطای زیر مواجه هستند:
mysqld: Table is marked as crashed and should be repaired
دلایل crash کردن جداول Database بصورت زیر می باشد:
سیستم عامل ناپایدار
مشکل با سخت افزار
مشکل برق
خراب شدن داده ها یا فایل index
Kill شدن سرویس SQL در هنگام بروز شدن
برنامه های خارجی که باعث دستکاری داده ها و یا index شده است.
طراحی مناسب دیتابیس(یا پایگاه داده) در وبسایت ها و برنامه های تحت وب، تاثیری زیادی در کارایی و توسعه آنها دارد. ارتباط با دیتابیس کمی تجربه بیشتری نیاز دارد، ولی آن هم غیر ممکن نیست.
10 اشتباه شایع در طراحی و پیاده سازی دیتابیس MySQL بصورت زیر است:
۱- استفاده از MyISAM بجای InnoDB یا بالعکس
MySQL تعدادی موتور(بخوانید engine) دارد ولی بیشتر برنامه نویسان، بدون توجه به کارایی هر کدام، از موتور MyISAM که بصورت پیش فرض انتخاب می شود استفاده می کنند؛ این در حالی است که انتخاب این موتور برای همه حالتهای ذخیره سازی اشتباه است! این موتور از کلیدهای خارجی(foreign keys) و ارتباطات آنها پشتیبانی نمیکند. یعنی شما نمی توانید جدولهایی بسازید که با هم ارتباط موثر داشته باشند(مثلا جدول محتوا و جدول دسته بندی در یک سیستم مدیریت محتوا که اگر ارتباط درستی داشته باشند، با تغییر یا حذف یک دسته بندی تمام محتواهای مرتبط با آن تغییر کرده یا حذف می شوند). مشکل دیگری که ممکن است پیش بیاید، تداخل داده ها است. زمانی که تقدم و تاخر در ورود اطلاعات مهم باشد، باید بتوان اولویت را به یک جدول داد و موقع insert و update جدول را بست.
برای حل این مشکلات از موتور InnoDB استفاده کنید.
پس کارایی MyISAM چه میشود؟ این موتور در جایی که نیاز به توابع خاصی مثل fulltext search دارید کارایی دارد. برای جستجوی جمله در دیتابیس MySQL، استفاده از LIKE و … ارزش جستجوی شما را تا حد زیادی پایین میآورد. پس برای جداولی که نیاز به جستجوی متنی در آنها دارید از موتور MyISAM استفاده نمایید.
۲- استفاده از توابع مستقیم برای دسترسی به MySQL
همیشه زبان php و MySQL دو جز جدایی ناپذیر بودهاند. بهمین دلیل php، برای ارتباط و کار با MySQL، دارای توابع توکاری هست که اجازه دسترسی و کار با MySQL را براحتی فراهم میسازد. توابع mysql_connect، mysql_query، mysql_fetch_assoc و … خیلی برای برنامه نویسان آشنا است؟! بعد از رواج برنامه نویسی شی گرا، استفاده از کتابخانه های شی گرا اهمیت زیادی پیدا کرده است. پس میتوان بجای توابع قدیمی گفته شده از کتابخانه های جدیدی مانند mysqli و … استفاده نمایید(حتماً بخاطر داشته باشید که در سرور شما باید قابلیت استفاده از آنها وجود داشته باشد). از جمله مزیتهای کار با این کتابخانه ها، امنیت بالاتر، ساختار شیگرا و پشتیبانی از چند دستور همزمان است.
کتابخانه فوق العاده دیگر PDO است، که برای ارتباط با انواع دیتابیس مثل MS SQL، ORACLE و POSGER علاوه بر MySQL مناسب است.
۳- اطمینان به داده های کاربران
یک اصل مهم در امنیت وبسایت وجود دارد و آن این است که “هیچگاه به داده های ورودی توسط کاربر اطمینان نداشته باشید”، همیشه ممکن از هکری بعنوان یک کاربر، اطلاعات آلوده را وارد برنامه شما کند. همیشه اطلاعات وارد شده توسط کاربر را در سمت سرور اعتبارسنجی کنید. هیچگاه به اعتبارسنجی هایی سمت کاربر(client-side) مثل جاوااسکریپت اطمینان نکنید. یک نمونه کد ساده که براحتی اجازه نفوذ(sql inject) به سایت شما را خواهد داد!
$username = $_POST[“name”];
$password = $_POST[“password”];
$sql = “SELECT userid FROM usertable WHERE username=’$username’ AND password=’$password’;”;
تنها کافی است که هکر بجای نام کاربری admin’; را وارد کند. به این صورت بجای مدیر سیستم، وارد سیستم می شود.
نکته جالب اینجاست که، هکر حتی بخود زحمت وارد کردن پسورد را هم نمیدهد، چون query بالا معادل این query میشود.
SELECT userid FROM usertable WHERE username=’admin’;
4- عدم استفاده از utf-8
این مورد بیشتر برای انگلیسی زبانها پیش می آید، ولی در خیلی از موارد ما نیز بجای استفاده از یونیکد صحیح از Unicode های پیشفرض استفاده می کنیم. توجه داشته باشید که برای پشتیبانی از زبانهای غیر لاتین در دیتابیس، باید از Unicode درست استفاده کنید. مثلاً برای زبانهای فارسی، عربی و … باید از utf8 استفاده شود. در خیلی از تالارهای گفتگو(forumها) در مورد نمایش فارسی MySQL و چاپ صحیح متن فارسی MySQL پرسیده می شود. برای اینکار لازم است که نوع دیتابیس، جدول و فیلدهای مورد نظر را utf8 انتخاب کنید.
۵- ترجیح دادن توابع php به MySQL
خیلی از تازه کارها، بجای استفاده از توبع داخلی MySQL از توابع php استفاده می کنند. مثلاً بجای استفاده از تابع AVG() در MySQL از یک حلقه برای تولید میانگین در php استفاده میکنند. این را بخاطر داشته باشید که سرعت اجرای توابع در MySQL خیلی بیشتر از php است. درست از که برای تولید نتیجه مناسب گاهی نیاز به پیمایش نتایج در حلقه داریم، ولی تا جایی که امکان دارد از توابع داخلی MySQL استفاده کنید.
۶- بهینه نکردن پرس و جوها(queries)
99% مشکلات کارایی و سرعت در برنامه های php به دیتابیس و پرس وجوهای نادرست آن مربوط میشود. عدم بهینه سازی پرس و جوها و استفاده نادرست از دستورات علت اصلی این مشکلات است.
۷- استفاده از نوع داده های(data types) اشتباه
MySQL انواع داده ی زیادی دارد. انتخاب درست نوع داده برای هر فیلد تاثیر زیادی در کارایی و سرعت فهرست بندی(indexing) جداول دارد. مثلاً اگر قرار است تاریخ ذخیره کنید، نوع داده DATE یا DATETIME را انتخاب کنید. استفاده از INT یا STRING باعث افزایش پیچیدگی می شود. البته میتوانید زمان را بصورت timestamp هم ذخیره نمایید که حجم کمتری از دیتابیس گرفته و محاسبات آن ساده تر انجام میشود.
بعضی اوقات نیز اتفاق می افتد که انواع داده جدیدی توسط برنامه نویس در دیتابیس ذخیره می شود. مثل ذخیره کردن یک object بصورت serialize، که بعد از ذخیره سازی ممکن است اطلاعات آن توسط دیتابیس آسیب ببیند.
۸- استفاده از * در پرس و جوهای دیتابیس
هیچگاه از * برای دریافت تمامی فیلدهای یک جدول استفاده نکنید، همیشه سعی کنید تنها فیلدهایی که نیاز دارید را صدا بزنید! یک راه این است که اگر تعداد فیلدهای یک جدول خیلی زیاد است؛ آن جدول را تغییر دهید تا نیازی به درخواست تمامی فیلدها نباشد. دلیل این همه تاکید میتواند کاهش سرعت این نوع پرس وجوها باشد.
۹- استفاده نامناسب از فهرستسازی(indexing)
بعنوان یک قاعده کلی، ما برای دسترسی به اطلاعات ذخیره شده دیتابیس از index ها برای SELECT استفاده میکنیم.
فرض کنید که یک جدول برای ذخیره اطلاعات کاربران داریم که دارای یک شماره ID بعنوان کلید اصلی(primary key) و یک ایمیل است. حال برای لاگین کردن کاربر، نیاز است که اطلاعات آن از دیتابیس خوانده شود؛ MySQL برای جستجوی ایمیل شخص باید تعیین کند که مربوط به چه ID ای است. با استفاده از همین فهرست(index) MySQL با الگوریتم پرسرعت خود، ایمیل مورد نظر را به سرعت پیدا میکند. بدون این فهرست(index)، MySQL باید تمامی داده ها موجود را به ترتیب بررسی کند تا نتیجه لازم پیدا شود.
درست است که استفاده از indexing خیلی در سرعت جستجوی اطلاعات موثر است، ولی این نباید باعث شود ما تمامی ستونها را index کنیم؛ بهرحال همیشه نباید از indexing استفاده کرد، چرا که کارایی را پایین می آورد. تنها در مواقع لازم از این قابلیت استفاده کنید.
۱۰- فراموش کردن backup
این موارد ممکن است خیلی نادر باشد، دیتابیس crash میکند. هارد دیسک میتواند متوقف شود. سرور می تواند منفجر شود. میزبان وب می تواند ورشکسته شود. از دست دادن اطلاعات فاجعه بار است، بنابراین شما باید پشتیبان گیری خودکار و تکرارپذیری در محلی امن داشته باشید. سرویس های تحت وب زیادی برای این کار وجود دارند که میتوان از آنها برای تهیه پشتیبان استفاده نمود.