قصة حذف 300 مليون سجل فعليًا في MySQL

المقدمة



مهلا. أنا ningenMe ، مطور ويب.



كما يقول العنوان ، قصتي تدور حول حذف 300 مليون سجل فعليًا في MySQL.



أصبحت مهتمة بهذا ، لذلك قررت أن أقدم مذكرة (تعليمات).



ابدأ - تنبيه



يحتوي خادم الدُفعات الذي أستخدمه وصيانته على عملية منتظمة تجمع البيانات للشهر الماضي من MySQL مرة واحدة يوميًا.



عادةً ما تكتمل هذه العملية في غضون ساعة واحدة تقريبًا ، ولكن هذه المرة لم تكتمل لمدة 7 أو 8 ساعات ، ولم يتوقف التنبيه عن الزحف ...



البحث عن سبب



حاولت إعادة العملية ، وإلقاء نظرة على السجلات ، لكنني لم أر شيئًا فظيعًا.

تمت فهرسة الطلب بشكل صحيح. لكن عندما تساءلت عما يحدث ، أدركت أن حجم قاعدة البيانات كبير جدًا.



hoge_table | 350'000'000 |


350 مليون سجل. يبدو أن الفهرسة تعمل بشكل صحيح ، ولكنها بطيئة جدًا.



كان جمع البيانات المطلوبة شهريًا حوالي 12 مليون سجل. يبدو أن الأمر select استغرق وقتًا طويلاً ولم يتم تنفيذ المعاملة لفترة طويلة.



DB



في الأساس ، هو جدول ينمو بنحو 400000 سجل كل يوم. كان من المفترض أن تجمع قاعدة البيانات البيانات للشهر الماضي فقط ، وبالتالي ، كان الحساب قائمًا على حقيقة أنها ستتحمل هذا القدر من البيانات بالضبط ، ولكن ، للأسف ، لم يتم تضمين عملية التناوب.



لم يتم تطوير قاعدة البيانات هذه بواسطتي. لقد استلمتها من مطور آخر ، لذلك شعرت أنها ديون تقنية.



جاءت اللحظة التي أصبح فيها حجم البيانات المدرجة يوميًا كبيرًا ووصل أخيرًا إلى الحد الأقصى. من المفترض أن العمل مع مثل هذه الكمية الكبيرة من البيانات ، سيكون من الضروري فصلها ، لكن هذا ، للأسف ، لم يتم.



ثم تدخلت.



تصحيح



كان من المنطقي تقليص قاعدة البيانات نفسها وتقليل وقت معالجتها بدلاً من تغيير المنطق نفسه.



يجب أن يتغير الوضع بشكل كبير إذا تم مسح 300 مليون سجل ، لذلك قررت أن أفعل ذلك ... آه ، اعتقدت أنه سيعمل بالتأكيد.



الخطوة 1



بعد أن أعددت نسخة احتياطية موثوقة ، بدأت أخيرًا في إرسال الطلبات.



تقديم طلب 」



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


「...」



「...」



“هممم ... لا إجابة. ربما تستغرق العملية وقتا طويلا؟ " - فكرت ، ولكن فقط في حالة ما إذا نظرت في grafana ورأيت أن تحميل القرص كان ينمو بسرعة كبيرة.

"خطير" - فكرت مرة أخرى وأوقفت الطلب على الفور.



الخطوة 2



بعد تحليل كل شيء ، أدركت أن كمية البيانات كانت أكبر من أن تحذف كل شيء دفعة واحدة.



قررت أن أكتب نصًا يمكنه حذف حوالي مليون سجل وتشغيله.



「قمت بتنفيذ البرنامج النصي」



فكرت "الآن ستعمل بالتأكيد"



الخطوه 3



الطريقة الثانية نجحت ، لكنها أثبتت أنها تستغرق وقتًا طويلاً.

سيستغرق الأمر حوالي أسبوعين للقيام بكل شيء بدقة ، دون أعصاب غير ضرورية. لكن مع ذلك ، هذا السيناريو لم يستوف متطلبات الخدمة ، لذلك اضطررت إلى الابتعاد عنه.



لذلك ، هذا ما قررت فعله:



انسخ الجدول وأعد تسميته



من الخطوة السابقة ، أدركت أن حذف مثل هذه الكمية الكبيرة من البيانات يخلق حملًا كبيرًا بنفس القدر. لذلك ، قررت إنشاء جدول جديد من البداية باستخدام إدراج ونقل البيانات التي كنت سأحذفها فيه.



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


إذا جعلت الجدول الجديد بالحجم نفسه كما هو مذكور أعلاه ، فيجب أيضًا أن تصبح سرعة المعالجة 1/7 أسرع.



بعد إنشاء الجدول وإعادة تسميته ، بدأت في استخدامه كجدول رئيسي. الآن إذا أسقطت جدولًا به 300 مليون سجل ، فسيكون كل شيء على ما يرام.

اكتشفت أن الاقتطاع أو الإسقاط أقل تكلفة من الحذف وقررت استخدام هذه الطريقة.



أداء



تقديم طلب 」



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


「...」

「...」

「اه ...?」



الخطوة 4



اعتقدت أن الفكرة السابقة ستنجح ، ولكن بعد تقديم طلب الإدراج ، ظهر خطأ متعدد. MySQL لا تدخر.



لقد كنت بالفعل متعبة للغاية لدرجة أنني بدأت أفكر في أنني لا أريد القيام بذلك بعد الآن.



جلست وفكرت وأدركت أنه ربما كان هناك عدد كبير جدًا من طلبات الإدراج لمرة واحدة ...

حاولت إرسال طلب إدراج لكمية البيانات التي يجب أن تعالجها قاعدة البيانات في يوم واحد. حدث!



حسنًا ، بعد ذلك نواصل إرسال طلبات للحصول على نفس الكمية من البيانات. نظرًا لأننا نحتاج إلى إزالة الكمية الشهرية من البيانات ، فإننا نكرر هذه العملية حوالي 35 مرة.



إعادة تسمية الجدول



هنا ، كان الحظ في جانبي: كل شيء سار بسلاسة.



ذهب التنبيه



زادت سرعة معالجة الدفعات.



في السابق ، كانت هذه العملية تستغرق حوالي ساعة ، والآن تستغرق حوالي دقيقتين.



بعد أن اقتنعت أنه تم حل جميع المشكلات ، قمت بإسقاط 300 مليون سجل. لقد حذفت جدول البيانات وشعرت بالولادة من جديد.



تلخيص



أدركت أنه تم التغاضي عن المعالجة المتناوبة في معالجة الدُفعات وكانت هذه هي المشكلة الرئيسية. هذا الخطأ المعماري مضيعة للوقت.



هل تفكر في تحميل النسخ المتماثل من خلال حذف السجلات من قاعدة البيانات؟ دعونا لا نفرط في تحميل MySQL.



أولئك الذين هم على دراية جيدة بقواعد البيانات لن يواجهوا بالتأكيد مثل هذه المشكلة. بالنسبة للبقية ، آمل أن يكون هذا المقال مفيدًا.



شكرا للقراءة!



سنكون سعداء للغاية إذا أخبرتنا ما إذا كنت قد أحببت هذه المقالة ، هل كانت الترجمة واضحة ، هل كانت مفيدة لك؟



All Articles