5.1 Bir vaqtning o'zidaga muammo
Har qanday axborot tizimi (yoki shunchaki dastur), dasturchilar tomonidan yaratilgan bo'lsa, bir necha odatiy bloklardan iborat. Masalan, kesh resurs talab etuvchi operatsiyaning natijasini eslab qolish uchun ishlatiladi, mijoz tomonidan ma'lumotlarni tezroq o'qish uchun. Oqimni qayta ishlash vositalari boshqa komponentlarga xabarlar yuborishga imkon beradi asinxron ishlov berish uchun. Paketli ishlov berish vositalari ba'zi davr mobaynida to'planib qolgan ma'lumotlarni hal qilish uchun ishlatiladi.
Amalda har bir dasturda ma'lumotlar bazalari (MB) ishlatiladi, ular odatda ikkita funktsiyani bajaradi: sizdan ma'lumotlarni qabul qilib ularni saqlash va sizga so'rov bo'yicha ulardan foydalanish imkonini yaratadi. Ko'plab tayyor yechimlar mavjud, lekin sizning dasturningizga mos keladiganini qanday tanlash kerak?
Shunday qilib, tasavvur qilaylik, siz mobil interfeysga ega dastur yaratdingiz, bu avval saqlangan uy ishlari ro'yxatini yuklash va uni yangi vazifalar bilan to'ldirish, shuningdek har bir vazifaga 1 (eng yuqori) dan 3 (eng past) gacha ustuvorliklarni belgilash imkonini beradi. Faraz qilaylik, sizning mobil dasturingiz hozirda faqat bitta foydalanuvchi tomonidan foydalaniladi. Lekin siz o'zingiz yaratgan narsani onangizga aytib berishga qaror qildingiz va u ikkinchi doimiy foydalanuvchi bo'ldi. Agar siz va onangiz bir vaqtning o'zida, bir xil millisekundda "oynalarni yuvish" vazifasiga turli xil ustuvorlik darajasini bersangiz, nima sodir bo'ladi?
Sizning va onangizning ma'lumotlar bazasiga yuborilgan so'rovlari ikkita jarayon sifatida tasavvur qilinish mumkin. Jarayon - bu bir yoki bir nechta oqimda bajarilishi mumkin bo'lgan dasturdir. Uda mashina kodi, xotira, kontekst va boshqa resurslar mavjud. Shunday qilib, jarayon bu dasturining protsessorda bajarilishi. Dastur MBga so'rov yuboradi, MB so'rovni bitta jarayondan qabul qiladi. Agar dasturni ikki foydalanuvchi ishlatsa, jarayonlar ham ikki xil bo'ladi.
Jarayon MBga so'rov yuboradi, u biron bir holatda topadi. Holat tizimi ("stateful") - bu o'tgan voqealarni eslab qoladigan va ma'lumotni saqlaydigan tizim. Buni "holat" deb atashadi. integer sifatida e'lon qilingan o'zgaruvchilar 0, 1, 2 yoki 42 bo'lishi mumkin. Mutex (o'zaro chiqarib tashlash) ikkita holatda bo'lishi mumkin: locked yoki unlocked, shuningdek ikkilik semafor ("required" yoki "released") va faqat ikki holatga ega bo'lishi mumkin bo'lgan o'zgaruvchilar - 1 yoki 0.
Ko'plab matematik va muhandislik tuzilmalari holat tushunchasiga asoslanadi. Bunday tuzilmalarning misoli sifatida oxirgi avtomat va "holat" dizayn shabloni keltirilishi mumkin. Ushbu shablonda ob'ektning xulq-atvori uning ichki holatidan, masalan, bir o'zgaruvchining qiymatidan bog'liq.
Shunday qilib, mashina dunyosidagi ko'pgina ob'ektlar qandaydir holatga ega bo'lib, u vaqt o'tishi bilan o'zgarishi mumkin. Masalan, katta ma'lumotlar paketini qayta ishlovchi pipeline xato berishi va failed holatiga o'tishi mumkin. Yoki "Hamyon" ob'ektining xususiyati, foydalanuvchi hisobidagi qolgan mablag' miqdorini saqlaydigan, ish haqi kelib tushgandan so'ng o'zgarishi mumkin.
Bir holatdan boshqa holatga o'tish operatsiya deb ataladi. CRUD operatsiyalari create, read, update, delete yoki ularga o'xshash HTTP: POST, GET, PUT, DELETE metodlari. Operatsiya murakkabroq bo'lishi mumkin va masalan validate() deb atilishi mumkin. Ushbu operatsiyalar jarayonlarni bajarishini amalga oshiradi.
Har qanday operatsiya - bu funksiya bo'ladimi yoki tarqatilgan tizimlarda boshqa serverga so'rov yuborilishi bo'ladimi - ikki xususiyatga ega: qo'ng'iroq vaqti (invocation time) va yakunlanish vaqti (completion time), bu qo'ng'iroq vaqtidan qat'iy ravishda katta bo'ladi. Jepsen tadqiqotchilari nazariy farazdan chiqib, bu qo'ng'iroq vaqti va yakunlanish vaqti bo'yicha maxsus, to'liq sinxronlashtirilgan va global mavjud soatlar beriladi, deb hisoblashadi.
Bizning ishlar ro'yxatini tasavvur qilaylik. Siz mobil interfeys orqali MBga so'rov yuborasiz 14:00:00.014 va onangiz 13:59:59.678 vaqtida (ya'ni undan 336 millisekund oldin) o'sha interfeys orqali ishlar ro'yxatini yangilab, idish yuvishga qo'shadi. Agar onangizning do'stlari ham shu dasturdan foydalansa, MB sizning so'rovingizni qayta ishlagandan so'ng onangizning so'rovini bajarishi mumkin. Bu sizning vaqtingizda siz va onangizning do'stlarining so'rovlari bir vaqtning o'zida yuborilishi mumkinligini anglatadi.
Shu tarzda biz MB va tarqatilgan dasturlar sohasida muhim tushunchaga - concurrencyga yetib keldik. Bu tushuncha ikkita operatsiyaning bir vaqtda bajarilishini anglatadi. Bu T1 va T2 bir-biriga ta'sir qilmasdan paralel bajarilishi mumkinligini anglatadi va shu sababli barcha tizim jarayonlarining mustaqilligi va xavfsizligini ta'minlaydi. Masalan, taqsimlangan MB uchun bu bir vaqtning o'zida bir nechta so'rovlarni ma'lumotlar butunligini yo'qotmasdan qayta ishlash imkoniyatini beradi.
- 1-vazifa 2-vazifa boshlanishidan oldin boshlanishi mumkin, lekin 2-vazifa boshlanishi va tugatilishi orasida tugallanadi.
- 2-vazifa 1-vazifa boshlanishidan oldin boshlanishi va 1-vazifa boshlanishi va oxiri orasida tugallanadi.
- 1-vazifa boshlangan va tugatilishi 1-vazifa boshlanishi va tugatilish sanalari orasida bo'lishi mumkin.
- va 1-vazifa va 2-vazifa bir-birini bajarish vaqtida bir nechta umumiy vaqt mavjud bo'lgan har qanday boshqa senariy.
Ma'lumki, ushbu maqolada biz MBda so'rovlar haqida gapiramiz va MBni boshqarish tizimi ularga qanday munosabatda bo'lishini muhokama qilamiz. "Konkurrentsiya" atamasi operatsion tizimlar kontekstida ham muhimdir. Garchi men mavzudan aloqamdan chetlanmaydim, shuni aytib o'tish kerakki, biz aytib o'tgan konkurrentsiya operatsion tizimlar va yuqori samarali hisoblashlar kontekstida muhokama qilingan konkurrentsiya va paralellik dilemmosiga aloqasi yo'q.
Paralellik - bu bir nechta yadrolar, protsessorlar yoki kompyuterlar bilan muh itda konkurrentsiyaga erishishning bir usulidir. Biz aytayotgan konkurrentsiya esa umumiy ma'lumotlarga bir nechta jarayonning bir vaqtda kirishiga tegishli.
Nima noto'g'ri ketishi mumkin?
Umumiy ma'lumotlar bilan ishlashda ko'plab muammolar yuzaga kelishi mumkin, ular "race conditions" nomi bilan tanilgan.
Birinchi muammo shundaki, jarayon o'ziga tegishli bo'lmagan ma'lumotlarni oladi: to'liq bo'lmagan, vaqtinchalik, bekor qilingan yoki boshqa sabablar tufayli "noto'g'ri" ma'lumotlar.
Ikkinchi muammo - bu jarayon eskirgan ma'lumotlarni oladi, ya'ni MBning oxirgi saqlangan holatiga mos kelmaydigan ma'lumotlar. Masalan, qandaydir dastur foydalanuvchi hisobidan nol balansdan pul olib qoldi, chunki MB oxirgi pul yig'ish ma'lumotni hisobdan olib qolmasdan dasturga berdi, bu bir necha millisekund oldin sodir bo'lgan. Juda yoqimli emas, to'g'rimi?
5.2 Tranzaksiyalar bizni qutqarish uchun keldi
Bu kabi muammolarni hal qilish uchun tranzaksiya tushunchasi - MBda ketma-ket operatsiyalar (holat o'zgarishlari) guruhi, bu mantiqan bir butun operatsiya sifatida kiritilgan. Masalan, bir bank hisobidan ikkinchi bank hisobiga pul o'tkazish: avval pul miqdorini chiqish hisobidan olib tashlash, keyin esa maqsadli hisobga qo'shish kerak.
Bu tranzaksiya uchun dastur MBda bir necha harakatlarni bajarishi kerak: yuboruvchining balansini tekshirish, yuboruvchining hisobida miqdorni bloklash, oluvchining hisobiga miqdorni qo'shish va yuboruvchidan miqdorni ayirish. Bunday tranzaksiya uchun talablar bir necha bo'ladi. Masalan, dastur faqat dolzarb va to'g'ri ma'lumotlarni olishini talab qiladi. Shuningdek, dastur boshqa tranzaksiyalarning muvaffaqiyatsiz tugaganligi haqida ma'lumot olishni istamaydi.
Bu muammoni hal qilish uchun tranzaksiya "izolyatsiya" xususiyati o'ylab topilgan: bizning tranzaksiyamiz shunday bajariladiki, go'yo boshqa bir vaqtda bajarilayotgan tranzaksiyalar mavjud emas. Bizning MB bir vaqtning o'zida amalga oshiriladigan operatsiyalarni ketma-ketlikda bajarilgandek bajaradi - bu eng yuqori izolyatsiya darajasi, "Strict Serializable" deb ataladi. Ha, bu eng yuqori daraja, lekin boshqalari ham bor.
Men har bir amaliyot chaqirish vaqti va bajarilish vaqti borligini qanday tasvirlaganligimni eslaylik. Chaqirish va bajarishni ikkita amal deb ko'rish mumkin. Shunda barcha bunday amallar ro'yxati DBning tarixi deb ataladi. Tranzaksiya izolyatsiyasi darajasi - bu tarixlar to'plami. Ular qaysi tarixlar "yaxshi" ekanligini aniqlaydilar. Agar tarix "syrializatsiyaga buzilgan" yoki "syrializatsiyaga ega emas" bo'lsa, bu uni syrializatsiyalangan hikoyalar to'plamiga kirmasligini anglatadi.
Shunda to'liq bo'lmagan o'qishlar kabi anomaliyalar mavjud. Masalan, bir tranzaksiya boshqa tranzaksiya tomonidan o'zgartirilgan satrdan ma'lumot o'qiydi, lekin hali o'zgarishlarini tugatmagan. Yoki bekor qilingan tranzaksiya, masalan, pul olib tashlash amaliyoti, yana bir misol.
Bunday anomaliyalar bir nechta mumkin. Bu MBga kirish paytida istalmagan holatlar bo'lib, ular ketma-ket kirishga olib keladi. MB bunday istalmagan holatlarni oldini olish uchun turli izolyatsiya darajalaridan foydalanadi. ANSI SQL-92 standarti 4 ta bunday darajani sanaydi.
Ba'zi tadqiqotchilar ushbu darajalarni tavsiflashni noaniq deb bilishadi va o'zlarining aniqroq klassifikatsiyalarini taklif qiladilar. Hermitage loyihasi kabi, bu qanday turli izolyatsiya darajalarini MySQL yoki PostgreSQL kabi muayyan MB boshqarish tizimlarida taklif etilishini aniqlash uchun mo'ljallangan. Repozitoriyning qanday anomaliyalarni MBda sinovdan o'tkazish uchun qanday SQL buyruqlar ketma-ketligini ko'rishingiz mumkin. Masalan, repozitoriydan bir misol:
-- Ma'lumotlar bazasi: MySQL
-- Testdan oldin sozlash
create table test (id int primary key, value int) engine=innodb;
insert into test (id, value) values (1, 10), (2, 20);
-- "Intermediate Reads" (G1b) anomaliyasida "read uncommited" izolatsiya darajasini sinab ko'ring
set session transaction isolation level read uncommitted; begin; -- T1
set session transaction isolation level read uncommitted; begin; -- T2
update test set value = 101 where id = 1; -- T1
select * from test; -- T2. 1 => 101 ko'rsatadi
update test set value = 11 where id = 1; -- T1
commit; -- T1
select * from test; -- T2. Endi 1 => 11 ko'rsatadi
commit; -- T2
-- Natija: G1bni oldini olmaydi
Bir xil MB uchun bir necha turli izolyatsiya turlaridan birini tanlash mumkin. Nima uchun eng kuchli izolyatsiyani tanlamaslik kerak? Chunki bu bajarilish tezligiga muvofiqlik bo'lishi kerak: izolyatsiya darajasi qanchalik kuchli bo'lsa, so'rovlar sekinroq qayta ishlanadi. Dasturning talablari nima ekanligini tushunish kerak, shunda qanday izolyatsiya darajasi kerakligini bilib olishi mumkin.
Agar tanlangan MB ushbu darajani taklif qilsa, hujjatlarni o'rganish kerak bo'ladi. Ko'pgina dasturlar uchun bu yetarli bo'ladi, lekin agar sizda maxsus talablar mavjud bo'lsa, Hermitage loyihasida bo'lgani kabi test o'tkazish yaxshiroqdir.
5.3 "I" va ACIDdagi boshqa harflar
Izolyatsiya - bu ACID haqida gapirayotganida odamlar nima anglatishini bildiradi. Shuning uchun biz izolyatsiyani tahlil qilishni boshqacha boshlab, lekin ketma-ketlik bo'yicha emas, boshladik. Keling, qolgan uchta harfni ko'rib chiqaylik.
Barcha hisob qaytarish misolini eslaylik. Tranzaksiya bir hisobdan pul chiqarish va ikkinchi hisobga qo'shishni o'z ichiga oladi. Agar qo'shishni amalga oshirib bo'lmasa, chiqarish hullas o'lmasligi kerak. Bu tranzaksiya butunlay bajarilishi kerak yoki umuman bajarilmasligi kerakligini anglatadi. Bu atmosfer birligidir va bu ACIDda "A" harfidir.
Bizning tranzaksiyamiz bajarilganda, u MBni bir to'g'ri holatdan boshqa to'g'ri holatga o'tkazadi. Ba'zi MBlar cheklovlar deb ataladigan narsalarni taklif qilishadi - saqlanadigan ma'lumotlarga qo'llaniladigan qoidalar, masalan, birlamchi yoki ikkilamchi kalitlar, indekslar, standart qiymatlar, ustun turlari va boshqalar. Tranzaksiyani amalga oshirishda biz barcha ushbu cheklovlar bajarilishiga ishonch hosil qilishimiz kerak. Bu yerda ular haqida ko'proq bilib olish mumkin.
Bu kafolat "kelishuv" (consistency) deb nomlangan va ACIDda C harfi deb belgilanadi (tarqatilgan dasturlar dunyosidan kelishuv bilan chalkashtirmaslik kerak, bu keyinroq muhokama qilinadi). Masalan, onlayn-do'kon dasturi orders jadvaliga product_id qiymatini kiritadigan satr qo'shmoqchi va bu products jadvalidagi mos IDga ishora qiladi - odatiy foreign key.
Agar mahsulot to'plamdan olib tashlangan va, shunga ko'ra, MBdan o'chirilgan bo'lsa, satr kiritish amaliyoti amalga oshirilmasligi kerak va biz xato olamiz. Bu kafolat, boshqa kafolatlar bilan solishtirganda, menimcha, biroz cho'zilgan - hech bo'lmaganda, agar biz CHECK kabi cheklovni aytadigan bo'lsaq, MBning ma'lumotlar mas'uliyatini (shuningdek, qisman biznes mantiqini) MBdan dasturga o'tkazadi, deb aytgan narsa uncha yaxshi emas.
Va nihoyat, D - "barqarorlik" (durability) qoladi. Sistematik xato yoki boshqa bir yong'in tranzaksiyaning natijalarini yoki MB tarkibini yo'qotmasligi kerak. Ya'ni, agar MB tranzaksiya muvaffaqiyatli amalga oshirildi, deb javob bergan bo'lsa, bu ma'lumotlar kuchli mustaqil xotirada - masalan, qattiq diskda saqlanadi. Bu keyingi read-so'rovda ma'lumotlarni darhol ko'rishingizni anglatmaydi.
Shunday qilib, endi biz ACID kafolatlari nima ekanligini va ular nima uchun foydali ekanligini bilamiz. Ammo baribir, ACID kafolatlari dastur ishlab chiqish uchun qanchalik muhimligini tushunish muhim. Ularni har bir loyihada ishlatish kerakmi? Va bu kafolatlarni qo'llab-quvvatlamaydigan MB qanday alternativlar taklif qilinadi? ACID kafolatlari MBning barqarorligini va samaradorligini ta'minlashga yordam bersa ham, ma'lum bir dastur uchun to'g'ri qarorni tanlash qanchalik muhimligini tushunish kerak. Ba'zi vaziyatlarda ACID kafolatlari shunchaki kerak emas, balki loyihani rivojlantirishga to'sqinlik qilishi mumkin.
GO TO FULL VERSION