MySQL-dagi 300 million yozuvning jismoniy o'chirilishi haqidagi hikoya

kirish

Salom. Men ningenMe, veb-dasturchiman.

Sarlavhada aytilganidek, mening hikoyam MySQL-da 300 million yozuvni jismonan yo'q qilish hikoyasidir.

Men bunga qiziqib qoldim, shuning uchun men eslatma (ko'rsatmalar) qilishga qaror qildim.

Uy - Ogohlantirish

Men foydalanadigan va qo'llab-quvvatlaydigan ommaviy serverda kuniga bir marta MySQL-dan o'tgan oyning ma'lumotlarini to'playdigan muntazam jarayon mavjud.

Odatda bu jarayon taxminan 1 soat ichida yakunlanadi, lekin bu safar u 7 yoki 8 soat davomida tugamaydi va ogohlantirish paydo bo'lishidan to'xtamadi...

Sabab izlash

Jarayonni qayta ishga tushirishga va jurnallarga qarashga harakat qildim, lekin hech qanday noto'g'ri narsani ko'rmadim.
So'rov to'g'ri indekslangan. Ammo nima noto'g'ri ketayotgani haqida o'ylaganimda, ma'lumotlar bazasi hajmi juda katta ekanligini angladim.

hoge_table | 350'000'000 |

350 million yozuvlar. Indekslash to'g'ri ishlayotganga o'xshaydi, juda sekin.

Oyiga kerakli ma'lumotlarni yig'ish taxminan 12 000 000 yozuvni tashkil etdi. Ko'rinishidan, tanlash buyrug'i uzoq vaqt talab qildi va tranzaksiya uzoq vaqt davomida bajarilmadi.

DB

Bu har kuni taxminan 400 000 ta yozuvga o'sadigan jadval. Ma'lumotlar bazasi faqat oxirgi oy uchun ma'lumotlarni to'plashi kerak edi, shuning uchun u aynan shu miqdordagi ma'lumotlarga bardosh berishi kutilgan edi, ammo, afsuski, aylantirish operatsiyasi kiritilmagan.

Ushbu ma'lumotlar bazasi men tomonidan ishlab chiqilmagan. Men uni boshqa ishlab chiquvchidan oldim, shuning uchun u hali ham texnik qarzdek tuyuldi.

Kundalik kiritiladigan ma'lumotlar hajmi kattalashib, nihoyat o'z chegarasiga yetgan payt keldi. Bunday katta hajmdagi ma'lumotlar bilan ishlashda ularni ajratish kerak bo'ladi, deb taxmin qilinadi, ammo bu, afsuski, amalga oshirilmadi.

Va keyin men harakatga keldim.

Tuzatish

Mantiqni o'zgartirishdan ko'ra, ma'lumotlar bazasi hajmini kamaytirish va uni qayta ishlash vaqtini qisqartirish yanada oqilona edi.

Agar siz 300 million yozuvni o'chirib tashlasangiz, vaziyat sezilarli darajada o'zgarishi kerak, shuning uchun men shunday qilishga qaror qildim ... Eh, bu albatta ishlaydi deb o'yladim.

1-harakat

Ishonchli zaxira nusxasini tayyorlab, nihoyat so'rovlar yuborishni boshladim.

「So'rov yuborish」

DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';

"..."

"..."

“Hm... Javob yo‘q. Balki jarayon uzoq davom etar?” — deb oʻyladim, lekin har ehtimolga qarshi grafanaga qaradim va diskdagi yuk juda tez oʻsib borayotganini koʻrdim.
"Xavfli", deb yana o'yladim va darhol so'rovni to'xtatdim.

2-harakat

Hamma narsani tahlil qilgandan so'ng, men bir vaqtning o'zida hamma narsani o'chirish uchun ma'lumotlar hajmi juda katta ekanligini angladim.

Men 1 000 000 ga yaqin yozuvlarni o'chiradigan skript yozishga qaror qildim va uni ishga tushirdim.

「Men skriptni amalga oshiraman」

"Endi bu albatta ishlaydi", deb o'yladim men.

3-harakat

Ikkinchi usul ishladi, lekin juda ko'p mehnat talab qiladigan bo'lib chiqdi.
Har bir narsani ehtiyotkorlik bilan, keraksiz nervlarsiz bajarish uchun taxminan ikki hafta kerak bo'ladi. Ammo shunga qaramay, ushbu stsenariy xizmat ko'rsatish talablariga javob bermadi, shuning uchun biz undan uzoqlashishga majbur bo'ldik.

Shunday qilib, men nima qilishga qaror qildim:

Jadvaldan nusxa oling va nomini o'zgartiring

Oldingi qadamdan shuni angladimki, bunday katta hajmdagi ma'lumotlarni o'chirish bir xil darajada katta yukni yaratadi. Shuning uchun men insert yordamida noldan yangi jadval yaratishga qaror qildim va o'chirmoqchi bo'lgan ma'lumotlarni unga ko'chirdim.

| hoge_table     | 350'000'000|
| tmp_hoge_table |  50'000'000|

Agar siz yangi jadvalni yuqoridagi kabi o'lchamda qilsangiz, ma'lumotlarni qayta ishlash tezligi ham 1/7 ga tezroq bo'lishi kerak.

Jadvalni yaratib, nomini o'zgartirgandan so'ng, men uni asosiy jadval sifatida ishlatishni boshladim. Endi men 300 million yozuvlar bilan jadvalni tashlasam, hammasi yaxshi bo'ladi.
Men kesish yoki tushirish o'chirishdan ko'ra kamroq yuk hosil qilishini bilib oldim va bu usuldan foydalanishga qaror qildim.

Ijroiya

「So'rov yuborish」

INSERT INTO tmp_hoge_table SELECT FROM hoge_table create_time > 'YYYY-MM-DD HH:MM:SS';

"..."
"..."
"Em...?"

4-harakat

Oldingi fikr ishlaydi deb o'yladim, lekin qo'shish so'rovini yuborganimdan so'ng bir nechta xatolar paydo bo'ldi. MySQL kechirimli emas.

Men allaqachon juda charchagan edim, endi buni qilishni xohlamayman deb o'ylay boshladim.

Men o'tirdim va o'yladim va bir marta juda ko'p so'rovlar borligini angladim ...
Maʼlumotlar bazasi 1 kun ichida qayta ishlanishi kerak boʻlgan maʼlumotlar miqdori uchun qoʻshish soʻrovini yuborishga harakat qildim. Bo'ldi!

Xo'sh, shundan keyin biz bir xil miqdordagi ma'lumotlar uchun so'rovlarni yuborishni davom ettiramiz. Bir oylik ma'lumotlarni olib tashlashimiz kerak bo'lganligi sababli, biz ushbu operatsiyani taxminan 35 marta takrorlaymiz.

Jadval nomini o'zgartirish

Bu erda omad men tomonda edi: hammasi muammosiz o'tdi.

Ogohlantirish yo'qoldi

To'plamni qayta ishlash tezligi oshdi.

Ilgari bu jarayon taxminan bir soat davom etgan bo'lsa, hozir taxminan 2 daqiqa davom etadi.

Barcha muammolar hal qilinganiga amin bo'lganimdan so'ng, men 300 million yozuvni tashladim. Jadvalni o'chirib tashladim va qayta tug'ilganimni his qildim.

Xulosa

Men partiyani qayta ishlashda aylanish jarayoni etishmayotganini angladim va bu asosiy muammo edi. Bunday arxitektura xatosi vaqtni behuda sarflashga olib keladi.

Ma'lumotlar bazasidan yozuvlarni o'chirishda ma'lumotlarni takrorlash paytida yuk haqida o'ylaysizmi? MySQL-ni ortiqcha yuklamaylik.

Ma'lumotlar bazalarini yaxshi biladiganlar, albatta, bunday muammoga duch kelmaydilar. Qolganlar uchun ushbu maqola foydali bo'ldi deb umid qilaman.

O'qiganingiz uchun tashakkur!

Ushbu maqola sizga yoqdimi yoki yo'qmi, tarjimasi tushunarlimi, siz uchun foydali bo'lganmi, aytsangiz juda xursand bo'lamiz?

Manba: www.habr.com

a Izoh qo'shish