ملخص تنفيذي
MariaDB لا يتوقف بسبب تلف أو مشكلة Galera أو خطأ SQL. Kernel Linux يقتل العملية mariadbd بسبب تجاوز سعة الذاكرة.
الدليل واضح في systemd وسجل kernel:
mariadb.service: Failed with result 'oom-kill'
Out of memory: Killed process 1177 (mariadbd) total-vm:22267612kB, anon-rss:16649820kB
Memory cgroup out of memory: Killed process 1146610 (mariadbd)
البيئة
| مكون | القيمة |
|---|---|
| إجمالي ذاكرة الوصول العشوائي | 19.5 جيجا |
| مبادلة | ~1 جيجابايت |
| سيستيم دي ميموري ماكس | 16 جيجا |
| innodb_buffer_pool_size | 2 جيجابايت (تقليص تلقائي → 1 جيجابايت) |
| rocksdb_block_cache_size | 4 جيجا |
| tmp_table_size (تجاوز الحذف) | 768 ميجا |
| max_heap_table_size (تجاوز الاسترداد) | 768 ميجا |
| sort_buffer_size | 32 ميجا |
| max_connections | 100 |
ماذا يحدث قبل القتل
يكتشف MariaDB ضغط الذاكرة ويحاول حماية نفسه عن طريق تقليل تجمع المخزن المؤقت InnoDB:
Memory pressure event shrunk innodb_buffer_pool_size=1536m from 2048m
→ 1280m → 1152m → 1088m → 1056m → 1040m → 1032m → 1024m
Memory pressure event disregarded; innodb_buffer_pool_size=1024m,
innodb_buffer_pool_size_auto_min=1024m
لقد قام InnoDB بالفعل بتقليل تجمع المخزن المؤقت الخاص به إلى الحد الأدنى (1 جيجابايت). ولكن هذا ليس كافيا. المستهلكون الآخرون لا يتراجعون.
حساب الحالة الأسوأ
مع 100 اتصال متزامن، أسوأ استهلاك للذاكرة لكل جلسة:
100 × (768 MB tmp_table + 768 MB heap + 32 MB sort) = ~153 GB
من الواضح أنه لا تقوم جميع الجلسات بإنشاء جداول مؤقتة بحجم 768 ميجابايت. لكن الأمر لا يستغرق سوى 20 جلسة لإجراء استعلامات باستخدام GROUP BY أو ORDER BY على مجموعات بيانات كبيرة لتفجير الـ 16 جيجابايت:
InnoDB buffer pool : 1 GB (shrunk)
RocksDB cache : 4 GB (fixe, ne recule pas)
20 sessions × 768 MB : 15 GB
Total : 20 GB → kill
العامل المشدد: عاصفة الاتصال ProxySQL
قبل OOM مباشرةً، يعرض السجل MariaDB الاتصالات المجهضة جماعيًا من 10.68.68.103 (ProxySQL):
Aborted connection ... user: 'unauthenticated' host: '10.68.68.103'
Too many connections
المزيد من الاتصالات = المزيد من ذاكرة الجلسة = المزيد من الضغط.
الإصلاح
إجراءات فورية
- تقليل ذاكرة الجلسة:
tmp_table_size = 128M
max_heap_table_size = 128M
sort_buffer_size = 8M
- الرجوع إلى دورة systemd:
MemoryMax=18G
- تدقيق ذاكرة التخزين المؤقت RocksDB — قد يكون حجمها 4 جيجابايت أكبر من اللازم:
rocksdb_block_cache_size = 2G
إجراءات متوسطة المدى
- حذف ملف Relem الذي يتجاوز القيم (
/etc/mysql/releem.conf.d/z_aiops_mysql.cnf) - مراقبة
memory_mysqldعبر PmaControl للتنبيه قبل القتل - قم بتكوين ProxySQL باستخدام
max_connectionsعلى الجانب الخلفي أقل منmax_connectionsMariaDB
ما ليس كذلك
هذا ليس:
- فشل بدء التشغيل
- انتعاش Galera مكسور
- datadir الفاسدة
- مشكلة في واصفات الملفات
تمت إعادة تشغيل MariaDB بشكل نظيف وإرجاع active (running) على الفور.
الخلاصة
دفعت أداة الضبط التلقائي (Relem) tmp_table_size إلى 768 ميجابايت - وهي قيمة تبدو معقولة بمعزل عن غيرها. ولكن عند دمجه مع الحد الأقصى لسعة النظام الذي يبلغ 16 جيجابايت، وذاكرة التخزين المؤقت RocksDB التي تبلغ 4 جيجابايت وعواصف الاتصال ProxySQL، يصبح قنبلة موقوتة.
يتم حساب ذاكرة خادم MariaDB في أسوأ الحالات، وليس في الحالة المتوسطة.
تعليقات (0)
لا توجد تعليقات حتى الآن.
اترك تعليقا