Nega «texnik tanaffus» yomon reja
Vazifa kompaniya eski hisob tizimidan yangisiga ko‘chganda (CRM yoki ERP) yoki platforma o‘z omboridan o‘sib chiqqanda paydo bo‘ladi. Infratuzilma qismi — Cloud va DevOps sahifasida. «Kechasi to‘rt soatga o‘chiramiz» rejasi oddiy ko‘rinadi va deyarli har doim bir xil barbod bo‘ladi: ko‘chirish hisoblanganidan uzoqroq davom etadi, o‘rtasida yozuvlarning bir qismi tekshiruvdan o‘tmayotgani ma’lum bo‘ladi, ortga qaytish esa allaqachon kech — eski tizim to‘xtatilgan, yangisi to‘liq to‘ldirilmagan. Ertalab soat oltida qarorni muhandis emas, charchoq qabul qiladi.
Bundan ham yomoni: texnik tanaffus natijani maksimal stress paytida tekshirishga majbur qiladi. Maydonlarni moslashtirishdagi xato bir haftadan keyin, ma’lumot allaqachon o‘zgargan va uni tiklashga manba qolmaganda aniqlanadi.
Sanoat usuli parallel o‘zgarish deb ataladi: avval tizimni eski va yangisi birga yashaydigan qilib kengaytiramiz, keyin ko‘chiramiz, keyin eskisini olib tashlaymiz (expand — migrate — contract).
O‘tishning besh bosqichi
- 01
Ikki tomonlama yozuv
Ilova ikkala omborga yozadi, o‘qishni esa avvalgidek eskisidan qiladi. Shu paytdan yangi ombor barcha yangi o‘zgarishlarni oladi — va biz tarix bilan xotirjam shug‘ullana olamiz.
- 02
Tarixni ko‘chirish
Fon jarayoni eski yozuvlarni paketlar bilan, yangilaridan eskilariga qarab ko‘chiradi. Ko‘chirish idempotent va to‘xtatib bo‘ladigan bo‘lishi shart: uni to‘xtatishadi, va bir marta emas.
- 03
Solishtirish
Tarkibni taqqoslaymiz: avval diapazonlar bo‘yicha nazorat yig‘indilari, keyin farqlar bo‘yicha satrma-satr. Parallel ravishda soyali o‘qishni yoqamiz — ikkala ombordan o‘qib, javoblarni taqqoslaymiz, foydalanuvchiga eskisini beramiz.
- 04
O‘qishni o‘tkazish
O‘qish bayroq bilan yangi omborga o‘tkaziladi, avval trafikning bir qismi uchun. Yozuv esa avvalgidek ikkalasiga ketadi — aynan shu ortga qaytishni bir zumda qiladi.
- 05
Eskisini o‘chirish
Faqat yangisi to‘liq yuklama ostida oylik va choraklik stsenariylarni ko‘rgudek uzoq ishlagandan keyin. So‘ng ikki tomonlama yozuv kodi o‘chiriladi — aks holda u abadiy qoladi.
Ikki tomonlama yozuv: u qayerda buziladi
Sodda ikki tomonlama yozuv ketma-ket ikkita chaqiruvga o‘xshaydi va xato o‘z ichiga oladi: agar ikkinchi yozuv yiqilsa, sizda allaqachon farq bor, foydalanuvchiga esa muvaffaqiyatli saqlangan ma’lumot ustida xato qaytdi. «Qaysi ombor asosiy» degan savolga javob butun o‘tish davomida bir xil bo‘lishi kerak.
async function save(record: Record) {
// O'tish davrida haqiqat manbai — eski ombor.
await legacy.save(record);
try {
await next.save(record);
} catch (err) {
// So'rovni yiqitmaymiz: foydalanuvchi o'zi bilmagan migratsiyadan
// aziyat chekmasligi kerak. Farqni qayd etamiz va fonda tuzatamiz.
metrics.increment('migration.dual_write.failed');
await outbox.enqueue({ type: 'migration.resync', id: record.id });
}
}Solishtirish: nazorat yig‘indilari, tanlab tekshirish emas
«O‘nta yozuvni ochdik, hammasi mos keldi» hech nimani isbotlamaydi. Ishlaydigan usul — diapazonlar bo‘yicha nazorat yig‘indilari: ma’lumotni oraliqlarga bo‘lamiz, har biri bo‘yicha ikkala omborda agregatni hisoblaymiz va taqqoslaymiz. Farq darhol lokallashadi, satrma-satr esa faqat shubhali oraliqni taqqoslash kerak bo‘ladi.
select
date_trunc('day', created_at) as bucket,
count(*) as rows,
sum(amount) as total,
md5(string_agg(id::text || ':' || amount::text, ','
order by id)) as checksum
from operation
where created_at < :cutoff
group by 1
order by 1;Soyali o‘qish ikkinchi, mustaqil signal qo‘shadi: tizim so‘rovni eski ombordan bajaradi, parallel ravishda o‘sha so‘rovni yangisiga yuboradi va natijalarni taqqoslaydi. Farqlar logga yoziladi. Bu ma’lumot solishtirishi ko‘rmaydigan narsani tutadi — tanlash mantiqidagi farqlarni: boshqa saralash tartibi, NULL da boshqacha xatti-harakat, boshqa yaxlitlash.
Aslida nima buziladi
Yozuvlar deyarli hech qachon butunlay yo‘qolmaydi — ularning ma’nosi yo‘qoladi. Quyidagi ro‘yxat solishtirishda haqiqatan chiqadigan narsalardan yig‘ilgan.
- Bo‘sh satrga qarshi `NULL`. Eski bazada «qiymat yo‘q»
''sifatida yozilgan, yangisida —NULL. Filtrlar yozuvlarni topmay qo‘yadi, hisobotlar esa jimgina raqamlarini o‘zgartiradi. - Vaqt mintaqalari. Vaqt zonasiz saqlangan va mahalliyni nazarda tutgan; yangi bazada —
timestamptz. Amallar bir necha soatga siljiydi va bu faqat sutka chegaralarida ko‘rinadi — ya’ni hisobotlarda. - Pulni yaxlitlash. Eski tizimdagi
floatva yangisidaginumerictiyinlarda farq beradi, u to‘planadi va yakunlarda to‘g‘ri chiqmaydi. - Avtoinkrementlar. Yangi ombor raqamlashni birdan boshlaydi va ko‘chirilgan identifikatorlar ustiga chiqadi. Hisoblagich yozuvni yoqishdan oldin aniq qo‘yiladi.
- Unikallik. Eski bazada yangi sxema yo‘l qo‘ymaydigan dublikatlar to‘plangan. Ularni ko‘chirishdan oldin hal qilish kerak — bu dasturchining emas, biznesning qarori.
Ortga qaytish rejasi qanday ko‘rinadi
Ortga qaytish rejasi — bu «zaxiradan tiklaymiz» emas. Ikki tomonlama yozuv ketayotganda ortga qaytish o‘qish bayrog‘ini qaytarish demakdir: eski ombor shu vaqt davomida to‘liq va dolzarb qolgan. Aynan shuning uchun ikki tomonlama yozuv bosqichi o‘tkazishdan keyin darhol yig‘ishtirilmaydi — u arzon turadi va qaytish imkoniyatini sotib oladi.
- O‘qishni o‘tkazadigan bayroq va uni qaytarishning tekshirilgan tartibi.
- Solishtirish tanlanmada emas, barcha oraliqlarda to‘g‘ri chiqadi.
- Soyali o‘qish real yuklama ostida farqsiz ishlagan.
- Monitoring faqat texnik ko‘rsatkichlarni emas, asosiy biznes ko‘rsatkichlarini oldin va keyin taqqoslaydi.
- Ortga qaytish haqida qaror qabul qiladigan odam va u buni qiladigan chegara belgilangan.
Ko‘p so‘raladigan savollar
Bunday o‘tish qancha vaqt oladi?
O‘rtacha hajmdagi bitta jadval uchun ikki haftadan, yuz millionlab yozuv tarixi bo‘lgan tizim uchun bir necha oygacha. Asosiy vaqt ko‘chirishga emas, solishtirishga va u topgan farqlarni tahlil qilishga ketadi: aynan o‘sha yerda maydonlar ma’nosining mos kelmasligi chiqadi.
Ikki tomonlama yozuvsiz iloji bormi?
Agar tizimni to‘xtatish mumkin bo‘lsa va ma’lumot hajmi kichik bo‘lsa — ha, va bu arzonroq bo‘ladi. Ikki tomonlama yozuv to‘xtatish imkonsiz yoki hajm ko‘chirishni soatlab qiladigan joyda kerak. Fintech, sog‘liqni saqlash va tashqi majburiyatlari bor har qanday tizim deyarli har doim shu toifaga tushadi.
Solishtirish topgan farqlar bilan nima qilish kerak?
Bittalab tuzatmasdan, turlar bo‘yicha tahlil qilish. Yakka farq deyarli har doim boshqacha ishlagan qoidaning oqibati; sababni tuzatib, siz yuzlab satrni bir yo‘la yopasiz. Sabab aniqlanmasdan alohida yozuvlarni qo‘lda tuzatish takrorlanishni kafolatlaydi.
Eski omborni o‘chirsa bo‘lishini qanday bilamiz?
Yangisi kamdan-kam stsenariylarni — oy yopilishi, choraklik hisobotlar, o‘sishlarni — qamrab olgudek uzoq to‘liq yuklama ostida ishlaganda. To‘liq hisobot tsiklidan oldin o‘chirishni maslahat bermaymiz: odatda aynan unda yaxlitlash farqi ochiladi.
Manbalar
Maqoladagi da’volarni tekshirish mumkin: quyida qayta hikoya emas, birlamchi manbalar.
- 01Martin Fowler — Parallel Change (expand/contract) — butun o‘tish sxemasi shu usulga asoslanadi
- 02PostgreSQL — Transaction Isolation — ikkala sxemaga parallel yozishda baza nimani kafolatlaydi
Maqolalarni loyihalarda ishlayotgan muhandislar yozadi — lekin ism bilan imzolanmaydi. Sabab saytda mijoz logotiplari yo‘qligi bilan bir xil: deyarli barcha loyihalar NDA yoki white-label ostida boradi, va to‘lov yadrosi haqidagi maqola muallifi mijozni logotipdan kam bo‘lmagan darajada ko‘rsatadi. Ism o‘rniga matn uchun qoidalar bilan javob beramiz — bundan mustasno: o‘z ochiq kodimiz haqidagi maqolalar muallif ismi bilan imzolanadi.
Qanday yozamiz va nimani tekshiramiz