چگونه پایگاه داده ها جداسازی را تضمین می کنند – کنترل همزمانی بدبینانه در مقابل خوش بینانه توضیح داده شده است
ACID (اتمیسیته، سازگاری، جداسازی و دوام) مجموعه ای از تضمین ها هنگام کار با DBMS است. کنترل همزمانی بدبینانه و خوش بینانه توضیح می دهد که چگونه پایگاه های داده به "I" در ACID دست می یابند.
جداسازی تضمینی است که تراکنشهای در حال اجرا همزمان نباید با یکدیگر تداخل داشته باشند. این مسلما مهمترین ویژگی ACID است، زیرا DBMS های مختلف اغلب می توانند سطوح جداسازی پیش فرض متفاوتی داشته باشند. و ممکن است لازم باشد این مورد را بر اساس آنچه برای برنامه شما نیاز است تغییر دهید.
در مقاله قبلی ، دو سطح جداسازی اصلی مورد استفاده توسط اکثر DBMS ها را توضیح دادم. اینها سطوح جداسازی خواندن متعهد و قابل تکرار هستند.
کنترلهای همزمان بدبینانه و خوشبینانه اساساً برخی از راههایی را که یک پایگاه داده قادر به دستیابی به این دو تضمین جداسازی است، توضیح میدهد.
فهرست مطالب
مثالی در دنیای واقعی از کنترل همزمان بدبینانه
مزایا و معایب کنترل بدبینانه همزمانی
چگونه سطح جداسازی متعهد Read را تضمین می کند
نمونه واقعی از کنترل همزمان خوش بینانه
مزایا و معایب کنترل خوشبینانه همزمانی
چگونه سطح جداسازی خواندن قابل تکرار را تضمین می کند
کنترل همزمان بدبینانه
با کنترل بدبینانه همزمانی، DBMS فرض می کند که تضاد بین تراکنش ها احتمالا رخ می دهد. بدبینانه است - یعنی فرض می کند که اگر چیزی اشتباه پیش برود، اشتباه خواهد شد. این بدبینی با جلوگیری از بروز درگیری ها قبل از اینکه فرصتی برای شروع پیدا کنند، از بروز آنها جلوگیری می کند.
برای جلوگیری از این تضادها، داده هایی را که تراکنش استفاده می کند تا زمانی که تراکنش کامل شود قفل می کند. این رویکرد «بدبینانه» است، زیرا بدترین سناریو را فرض میکند - که هر معامله ممکن است منجر به تضاد شود. پس داده ها قفل می شوند تا از وقوع درگیری جلوگیری شود.
من در اینجا به دو اصطلاح فنی اشاره کردم که نیاز به توضیح دارند: قفل و درگیری .
قفل چیست؟
قفل مکانیزمی است که برای کنترل دسترسی به یک آیتم پایگاه داده مانند یک ردیف یا جدول استفاده می شود. قفل ها یکپارچگی داده ها را تضمین می کنند، اگر چندین تراکنش به طور همزمان انجام شود.
به عبارت بسیار ساده، قفل مشابه رزرو در مورد پایگاه داده است. یک رزرو، خواه رستوران، هتل یا قطار باشد، از استفاده افراد دیگر از منبعی که رزرو کرده اید برای مدت زمان مشخصی جلوگیری می کند. قفل ها به روشی مشابه کار می کنند.
دو نوع قفل وجود دارد: قفل خواندن و قفل نوشتن.
یک قفل خواندن را می توان توسط چندین تراکنش که سعی در خواندن یک مورد پایگاه داده دارند به اشتراک گذاشته شود. اما دیگر تراکنش ها را از به روز رسانی آن آیتم پایگاه داده مسدود می کند.
قفل نوشتن انحصاری است - یعنی فقط با یک تراکنش می تواند نگه داشته شود. تراکنش با قفل نوشتن بر روی آیتم پایگاه داده، هر تراکنش دیگری را از خواندن یا به روز رسانی آن آیتم پایگاه داده مسدود می کند.
تعارضات چیست؟
تضاد به وضعیتی اطلاق میشود که در آن چندین تراکنش تلاش میکنند به طور همزمان به دادههای یکسان دسترسی پیدا کرده و آنها را اصلاح کنند، به نحوی که میتواند منجر به ناسازگاری یا خطا در پایگاه داده شود.
قیاس کتابخانه ای برای کنترل همزمانی بدبینانه
ابتدا اجازه دهید یک قیاس برای قفل نوشتن شرح دهیم.
تصور کنید در یک کتابخانه هستید و می خواهید نسخه چاپی یک کتاب محبوب، مثلاً گتسبی بزرگ اثر F. Scott Fitzgerald را امانت بگیرید.
با قفل نوشتن، کتابدار فرض میکند که ممکن است در مورد اینکه چه کسی کتاب را به امانت میگیرد، درگیری وجود داشته باشد. پس ، آنها یک قانون سختگیرانه را برای جلوگیری از درگیری اجرا می کنند: فقط یک نفر می تواند رزرو یک کتاب فیزیکی را در یک زمان انجام دهد.
وقتی کتاب را رزرو می کنید، هیچ کس دیگری نمی تواند آن را امانت بگیرد. کتاب فقط پس از بازگرداندن برای رزرو مجدد موجود است. این شبیه به نحوه عملکرد قفل نوشتن است.
قفل های نوشتن انحصاری هستند. این بدان معنی است که آنها فقط می توانند او را با یک معامله در هر زمان نگه دارند. به طور مشابه، رزرو یک کتاب فیزیکی از کتابخانه به این معنی است که هیچ کس دیگری به آن دسترسی ندارد. فقط شخصی که رزرو کرده است می تواند کتاب را بخواند یا در آن بنویسد (اگرچه نوشتن در کتاب کتابخانه شکل بدی است).
قفل خواندن کمی متفاوت عمل می کند.
قفل خواندن شبیه به کسی است که برای قرض گرفتن یک کتاب الکترونیکی رزرو می کند. امانت گرفتن یک کتاب الکترونیکی کار بسیار محبوبی نیست، اما برخی از کتابخانه ها چنین خدماتی را دارند.
بسیاری از افراد می توانند برای یک کتاب الکترونیکی یکسان رزرو کنند بدون هیچ گونه تضادی. یک نفر که نسخه کتاب الکترونیکی گتسبی بزرگ را قرض می گیرد، دیگران را از انجام همین کار باز نمی دارد. اما هیچکسی که کتاب الکترونیکی را قرض میگیرد نمیتواند آن را بهروزرسانی کند، مثلاً با نوشتن یادداشتهایی در آن که توسط دیگران قابل مشاهده باشد.
کنترل بدبینانه همزمانی بسیار ایمن است زیرا با مسدود کردن آنها قبل از اینکه فرصتی برای شروع پیدا کنند، از وقوع درگیری ها جلوگیری می کند. قفل نوشتن روی یک آیتم پایگاه داده از خواندن یا به روز رسانی آن آیتم توسط سایر تراکنش ها در حالی که آن قفل نگه داشته شده است جلوگیری می کند، شبیه به روشی که یک کتابخانه بیش از یک نفر را از تلاش برای امانت گرفتن یک کتاب فیزیکی به طور همزمان باز می دارد.
قفل خواندن در یک آیتم پایگاه داده به سایر تراکنشها اجازه میدهد تا قفل خواندن برای آن آیتم را نیز دریافت کنند، اما از بهروزرسانی آن آیتم از تراکنشها جلوگیری میکند. این مشابه قرض گرفتن یک کتاب الکترونیکی است، که در آن چندین نفر می توانند همزمان یک کتاب الکترونیکی مشابه را قرض بگیرند، اما نمی توانند هیچ به روز رسانی برای آن انجام دهند.
یک مثال ساده در دنیای واقعی از کنترل بدبینانه همزمانی در عمل
بیایید نحوه عملکرد کنترل همزمانی بدبینانه را با استفاده از یک مثال ساده که شامل جدول پایگاه داده موجودی بانک است، نشان دهیم. فرض کنید جدولی به نام Accounts با ستون های زیر داریم: AccountID و Balance.
دو تراکنش T1 و T2 قصد دارند موجودی حساب 12345 را به روز کنند. T1 می خواهد 300 دلار برداشت کند و T2 می خواهد 400 دلار واریز کند. در پایان این دو تراکنش، موجودی حساب باید 1600 دلار باشد
در اینجا مراحل نحوه کار با استفاده از قفل نوشتن آورده شده است:
شروع T1 (خروج): T1 درخواست بهروزرسانی موجودی AccountID 12345 را میدهد. سیستم پایگاه داده یک قفل نوشتن انحصاری روی ردیف برای AccountID 12345 قرار میدهد و از خواندن یا نوشتن سایر تراکنشها در این ردیف تا پایان T1 جلوگیری میکند. T1 موجودی (1500 دلار) را می خواند.
پردازش T1: T1 موجودی جدید را 1200 دلار (1500 تا 300 دلار) محاسبه می کند.
Commit T1: T1 موجودی جدید (1200 دلار) را به پایگاه داده می نویسد. پس از انجام موفقیت آمیز، T1 قفل انحصاری AccountID 12345 را آزاد می کند.
شروع T2 (سپرده) پس از تکمیل T1: اکنون که T1 تکمیل شده و قفل آزاد شده است، T2 می تواند شروع شود. T2 سعی می کند موجودی حساب 12345 را بخواند و به روز کند. سیستم پایگاه داده یک قفل انحصاری روی ردیف برای AccountID 12345 برای T2 قرار می دهد و اطمینان می دهد که هیچ تراکنش دیگری نمی تواند تداخل داشته باشد. T2 موجودی به روز شده را می خواند (1200 دلار).
پردازش T2: T2 موجودی جدید را 1600 دلار (1200 دلار + 400 دلار) محاسبه می کند.
Commit T2: T2 موجودی جدید (1600 دلار) را به پایگاه داده می نویسد. پس از انجام موفقیت آمیز، T2 قفل انحصاری AccountID 12345 را آزاد می کند.
نتیجه: جدول حساب ها با استفاده از قفل ها بعد از T1 به روز می شود: 1200 دلار بعد از T2: 1600 دلار
بدون قفل نوشتن در این مثال، T1 و T2 می توانند موجودی اصلی 1500 دلار را همزمان بخوانند. پس ، به جای موجودی 1200 دلار پس از تعهد T1، T2 همچنان موجودی اصلی 1500 دلار را می خواند و 400 دلار اضافه می کند. این باعث می شود که موجودی نهایی 1500 دلار + 400 دلار = 1900 دلار (به جای 1600 دلار) باشد.
عدم قفل باعث ایجاد پول رایگان شده است که هرگز برای مشتری بد نیست. اما، اگر به دلیل این تضادها بتوان پول را از هوا بیرون آورد، می تواند ناپدید شود و به طور تصادفی موجودی بانکی کوچک شدن راهی سریع برای ناراضی کردن مشتریان است.
مزایا و چالش های کنترل بدبینانه همزمانی
درست همانطور که رزرو یک کتاب تضمین می کند که برای یک نفر کنار گذاشته شده است، کنترل بدبینانه همزمانی داده ها را برای یک تراکنش قفل می کند. تا زمانی که قفل آزاد نشود، سایر تراکنش ها نمی توانند به این داده ها دسترسی داشته باشند یا آنها را تغییر دهند.
این روش از تلاش دو نفر برای بیرون آوردن یک کتاب محبوب به طور همزمان جلوگیری می کند و در نتیجه از اختلاف نظر جلوگیری می کند. به طور مشابه، در پایگاه های داده، تضادهای ناشی از تراکنش های همزمان را قبل از اینکه فرصتی برای شروع پیدا کنند، متوقف می کند.
اما این رویکرد می تواند ناکارآمد باشد. کتاب رزرو شده ممکن است برای مدتی در قفسه رزرو شده بنشیند و دیگران را از خواندن آن باز دارد.
در پایگاههای داده، این مکانیسم قفل میتواند منجر به استفاده ناکافی از منابع و کاهش سرعت انجام تراکنشها شود، زیرا زیرمجموعهای از دادهها قفل شده و برای سایر تراکنشها غیرقابل دسترسی است.
چگونه کنترل های بدبینانه همزمانی سطح جداسازی متعهد خواندن را تضمین می کند
پس ، کنترل همزمان بدبینانه دقیقاً چگونه در تضمین ضمانت جداسازی کار می کند، یعنی "I" در ACID؟ جزئیات پیاده سازی می تواند در DBMS های مختلف متفاوت باشد. اما توضیح در اینجا رویکرد کلی را نشان می دهد.
به یاد داشته باشید که سطح جداسازی متعهد خواندن از نوشتن کثیف و خواندن کثیف جلوگیری می کند.
جلوگیری از نوشتن کثیف
رونویسی دادههایی که قبلاً توسط تراکنش دیگری نوشته شدهاند اما هنوز متعهد نشدهاند، نوشتن کثیف نامیده میشود. یک رویکرد رایج برای جلوگیری از نوشتن کثیف، استفاده از کنترل همزمان بدبینانه است. به عنوان مثال، با استفاده از قفل نوشتن در سطح ردیف.
هنگامی که تراکنش می خواهد یک ردیف را اصلاح کند، روی آن سطر قفل می گیرد و آن را تا پایان تراکنش نگه می دارد. به یاد بیاورید که قفل های نوشتن فقط با یک تراکنش قابل نگهداری هستند. این کار از گرفتن قفل دیگری برای تغییر آن ردیف جلوگیری می کند.
جلوگیری از کثیف خواندن
خواندن داده های تراکنش دیگری که هنوز انجام نشده است، خواندن کثیف نامیده می شود. با استفاده از قفل خواندن یا نوشتن از خواندن کثیف جلوگیری می شود. هنگامی که یک تراکنش قفل خواندنی را در مورد پایگاه داده به دست آورد، از به روز رسانی آن مورد جلوگیری می کند.
اما چه اتفاقی میافتد اگر بخواهید چیزی را بخوانید که در حال بهروزرسانی است اما تراکنش هنوز انجام نشده است؟ در این مثال، قفل نوشتن دوباره روز را نجات می دهد.
از آنجایی که قفلهای نوشتن انحصاری هستند (نمیتوان آنها را با سایر تراکنشها به اشتراک گذاشت)، هر تراکنشی که بخواهد همان مورد پایگاه داده را بخواند باید منتظر بماند تا تراکنش با قفل نوشتن انجام شود (یا در صورت شکست، لغو شود). این کار از خواندن تغییرات غیرمتعهد دیگر تراکنش ها جلوگیری می کند.
کنترل همزمان خوشبینانه
با کنترل خوشبینانه همزمانی، تراکنشها هنگام خواندن یا نوشتن روی دادهها قفل نمیشوند. "خوشبین" در نام از این فرض ناشی می شود که احتمال وقوع درگیری وجود ندارد، پس نیازی به قفل نیست. اگر مشکلی پیش بیاید، باز هم از درگیری جلوگیری می شود و همه چیز درست خواهد بود.
بر خلاف کنترل بدبینانه همزمانی - که با مسدود کردن آنها قبل از اینکه فرصتی برای شروع پیدا کنند، از وقوع تضادها جلوگیری می کند - کنترل همزمانی خوشبینانه در پایان تراکنش، تضادها را تحلیل می کند.
با کنترل خوشبینانه همزمانی، چندین تراکنش میتوانند یک مورد پایگاه داده را بدون دریافت قفل بخوانند یا بهروزرسانی کنند. این دقیقا چگونه کار میکند؟
هر بار که یک تراکنش می خواهد یک آیتم پایگاه داده، مثلاً یک ردیف را به روز کند، دو ستون اضافی که توسط DBMS به هر جدول اضافه می شود را می خواند - مهر زمانی و شماره نسخه. قبل از اینکه آن تراکنش متعهد شود، با تأیید یکسان بودن شماره نسخه و مهر زمانی تحلیل می کند که آیا تراکنش دیگری در آن ردیف تغییری ایجاد کرده است یا خیر.
اگر آنها تغییر کرده اند، به این معنی است که تراکنش دیگری آن ردیف را به روز کرده است، پس تراکنش اولیه باید دوباره امتحان شود.
یک مثال ساده در دنیای واقعی از کنترل خوشبینانه همزمانی در عمل
بیایید نحوه عملکرد کنترل همزمانی خوشبینانه را با استفاده از یک مثال ساده که شامل جدول پایگاه داده موجودی بانک است، نشان دهیم. فرض کنید جدولی به نام Accounts با ستون های زیر داریم: AccountID، Balance، VersionNumber و Timestamp.
دو تراکنش T1 و T2 قصد دارند موجودی حساب 12345 را همزمان به روز کنند. T1 می خواهد 200 دلار برداشت کند و T2 می خواهد 300 دلار واریز کند. در پایان این دو تراکنش، موجودی حساب باید 1100 دلار باشد
در اینجا مراحل نحوه کار این است:
شروع تراکنش ها: T1 موجودی، شماره نسخه و مُهر زمانی AccountID 12345 را می خواند. به طور همزمان، T2 همان ردیف را با همان موجودی، شماره نسخه و مهر زمانی می خواند.
پردازش: T1 موجودی جدید را 800 دلار (1000 تا 200 دلار) محاسبه میکند، اما آن را بلافاصله پس نمینویسد. T2 موجودی جدید را 1300 دلار (1000 دلار + 300 دلار) محاسبه می کند، اما منتظر می ماند تا متعهد شود.
تلاش برای انجام T1: قبل از انجام، T1 شماره نسخه فعلی و مهر زمان حساب ID 12345 را در پایگاه داده تحلیل میکند. از آنجایی که هیچ تراکنش دیگری ردیف را تغییر نداده است، T1 موجودی را به 800 دلار به روز می کند، VersionNumber را به 2 افزایش می دهد، Timestamp را به روز می کند و با موفقیت انجام می شود.
تلاش برای انجام T2: T2 ابتدا با تأیید VersionNumber و Timestamp تلاش میکند تا commit را انجام دهد. T2 متوجه می شود که VersionNumber و Timestamp تغییر کرده اند (اکنون VersionNumber 2 است و Timestamp به روز شده است)، که نشان می دهد تراکنش دیگری (T1) ردیف را به روز کرده است. از آنجایی که شماره نسخه و مهر زمانی تغییر کرده است، T2 متوجه می شود که یک تضاد وجود دارد.
قطعنامه برای T2: T2 باید تراکنش خود را دوباره راه اندازی کند. موجودی به روز شده 800 دلار، نسخه شماره 2 جدید و مهر زمانی به روز شده را دوباره می خواند. T2 موجودی جدید را مجدداً 1100 دلار (800 دلار + 300 دلار) محاسبه می کند، VersionNumber را به 3 به روز می کند، Timestamp را به روز می کند و با موفقیت انجام می دهد.
نتیجه: جدول حساب ها به صورت متوالی و ایمن بدون هیچ قفلی به روز می شود: بعد از T1: 800 دلار، شماره نسخه: 2. بعد از T2: 1100 دلار، شماره نسخه: 3.
مزایا و چالش های کنترل همزمان خوش بینانه
از جنبه مثبت، اجتناب از قفل اجازه می دهد تا سطوح بالایی از همزمانی را داشته باشید. این امر به ویژه در بارهای کاری سنگین خواندنی مفید است که در آن تراکنشها احتمال تضاد کمتری دارند و به سیستم اجازه میدهد تا تراکنشهای بیشتری را در یک دوره معین انجام دهد. به عنوان مثال، پشتیبان گیری از پایگاه داده و پرس و جوهای تحلیلی معمولاً در یک انبار داده استفاده می شود.
اما در سناریوهایی که تضادها مکرر هستند، هزینه بازگرداندن مکرر و تلاش مجدد تراکنشها میتواند بیشتر از مزایای اجتناب از قفل باشد و کنترل خوشبینانه همزمانی را کارآمدتر کند.
چگونه کنترل های همزمان خوش بینانه سطح جداسازی خواندن تکراری را تضمین می کند
خواندن تکرارشونده سطح جداسازی دقیقتری دارد، زیرا تضمینهایی مشابه با جداسازی متعهد خواندن دارد، به علاوه تضمین میکند که خواندنها تکرارپذیر هستند.
خواندن تکرارپذیر تضمین میکند که اگر یک تراکنش یک ردیف از دادهها را بخواند، هر خواندن بعدی از همان ردیف داده در همان تراکنش، بدون توجه به تغییرات ایجاد شده توسط سایر تراکنشها، همان نتیجه را به همراه خواهد داشت. این ثبات در طول مدت معامله حفظ می شود.
چگونه می توان به یک خواندن تکرار پذیر دست یافت؟ کنترل بدبینانه با استفاده از قفل خواندن می تواند به این امر کمک کند، زیرا تراکنش با قفل خواندن در یک آیتم پایگاه داده از به روز رسانی آن آیتم جلوگیری می کند. اما این می تواند ناکارآمد باشد، زیرا یک تراکنش خواندن طولانی مدت می تواند مانع از انجام به روز رسانی ها برای آن مورد پایگاه داده شود.
Multi-Version Concurrency Control (MVCC) یک روش کنترل همزمانی است که توسط برخی از DBMS ها استفاده می شود تا به چندین تراکنش اجازه دسترسی به داده های مشابه را به طور همزمان بدون قفل کردن داده ها بدهد. این باعث می شود که آن را به یک انتخاب محبوب برای کاهش اختلاف قفل و بهبود مقیاس پذیری پایگاه داده تبدیل کند.
MVCC با نگهداری چندین نسخه از اشیاء داده به این امر دست می یابد، که به مدیریت سطوح مختلف دید برای تراکنش ها بسته به مهر زمانی یا شماره نسخه آنها کمک می کند.
آوردن آن با هم
قفل مکانیزمی است که برای کنترل دسترسی به یک آیتم پایگاه داده مانند یک ردیف یا جدول استفاده می شود. به عبارت بسیار ساده، آن را شبیه به رزرو در یک آیتم پایگاه داده است.
کنترل همزمانی بدبینانه بدترین را فرض می کند. فرض میکند که تضادها احتمالاً رخ میدهند، پس از قفلها برای مسدود کردن تراکنشهایی استفاده میشود که میتوانند حتی قبل از اینکه فرصتی برای شروع پیدا کنند، باعث درگیری شوند.
در شرایطی که تضادها رایج هستند، مانند برنامه سنگین نوشتن، این رویکرد میتواند با اطمینان از دسترسی انحصاری به موارد پایگاه داده در طول تراکنشها، از هزینههای سربار مرتبط با بازگشتهای مکرر و تلاشهای مجدد (که در کنترل خوشبینانه همزمانی اتفاق میافتد) جلوگیری کند.
کنترل همزمانی خوشبینانه بهترین را فرض می کند. فرض بر این است که تضادها بعید به وقوع می پیوندند، پس برای متوقف کردن تراکنش ها قبل از شروع، قفل لازم نیست. در عوض، تضادهای احتمالی در پایان تراکنش تحلیل میشوند و در صورت یافتن، تراکنش لغو میشود یا دوباره امتحان میشود.
کنترل همزمانی خوش بینانه برای خواندن تراکنش های سنگین با نوشتن نادر مفید است، زیرا به چندین تراکنش اجازه می دهد بدون نیاز به استفاده از قفل انجام شود که می تواند ناکارآمد باشد.
ارسال نظر