dbit.one© 2026
000
booting_
Loading experience0%
dbit.one

Bazani yuklama ostida ko‘chirish va yozuvlarni yo‘qotmaslik

Qisqacha: «yakshanba kechasi ko‘chiramiz» — bu reja emas, garov. Ishlaydigan usul boshqacha: bir muddat tizim ikkala omborga bir vaqtda yozadi, tarix fonda ko‘chiriladi, ma’lumot solishtiriladi va faqat shundan keyin o‘qish yangisiga o‘tadi. Oxirgi qadamgacha har doim ortga qaytish mumkin.

5 daqiqa o‘qish

Qisqacha

  • O‘tish besh bosqichga bo‘linadi, va to‘rtinchisigacha ortga qaytish bitta konfiguratsiya satriga turadi.
  • Ikki tomonlama yozuv — «ikkita bazaga yozamiz» emas, «ikkita bazaga yozamiz va ikkinchisining ishdan chiqishidan omon qolamiz».
  • Diapazonlar bo‘yicha nazorat yig‘indilari tanlab tekshirish topa olmaydigan narsani topadi.
  • Migratsiyadagi eng qimmat narsa ko‘chirish emas, ma’nolarning mos kelmasligi: bo‘sh satrga qarshi NULL, vaqt mintaqalari, yaxlitlash.

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

Ikki tomonlama yozuv01Tarixni ko‘chirish02Solishtirish03Yangisidan o‘qish04Eskisi o‘chirildi05Bu nuqtagacha ortga qaytish mumkinFoydalanuvchi hech narsani sezmaydi
Qaytib bo‘lmaydigan nuqta migratsiyaning boshlanishi emas, eski omborga yozuvni o‘chirish. Unga qadar qaytish bayroqni o‘zgartirishga turadi.
  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

typescript
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 });
  }
}
Asosiy bo‘lib eski ombor qoladi. Yangisining ishdan chiqishi foydalanuvchi stsenariysini buzmasligi kerak — farqni solishtirish tutadi.

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.

sql
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;
Bunday so‘rov ikkala omborda bajariladi, natijalar kalit bo‘yicha taqqoslanadi. Barcha oraliqlar bo‘yicha summa va sonning mos kelishi — tanlab tekshirishdan farqli o‘laroq, kuchli tasdiq.

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 float va yangisidagi numeric tiyinlarda 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‘tkazishdan oldin tayyor bo‘lishi kerak
  • 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.

  1. 01Martin Fowler — Parallel Change (expand/contract)butun o‘tish sxemasi shu usulga asoslanadi
  2. 02PostgreSQL — Transaction Isolationikkala sxemaga parallel yozishda baza nimani kafolatlaydi
dbit.one injiniring tahririyati
Bu tizimlarni quradigan muhandislar

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

Tegishli xizmatlar

Keyingi o‘qish

Loyihangiz bo‘yicha savollar bormi?

Vazifangizni tasvirlang — 24 soat ichida baho, muddat va reja bilan qaytamiz.

[email protected]