OOM किलर - ने MySQL सर्वर को मार दिया


10

हमारे एक MySQL मास्टर पर, OOM किलर ने आक्रमण किया और MySQL सर्वर को मार दिया, जिससे बड़े आउटेज हो गए। निम्नलिखित कर्नेल लॉग है:

[2006013.230723] mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0
[2006013.230733] Pid: 1319, comm: mysqld Tainted: P           2.6.32-5-amd64 #1
[2006013.230735] Call Trace:
[2006013.230744]  [<ffffffff810b6708>] ? oom_kill_process+0x7f/0x23f
[2006013.230750]  [<ffffffff8106bde2>] ? timekeeping_get_ns+0xe/0x2e
[2006013.230754]  [<ffffffff810b6c2c>] ? __out_of_memory+0x12a/0x141
[2006013.230757]  [<ffffffff810b6d83>] ? out_of_memory+0x140/0x172
[2006013.230762]  [<ffffffff810baae8>] ? __alloc_pages_nodemask+0x4ec/0x5fc
[2006013.230768]  [<ffffffff812fca02>] ? io_schedule+0x93/0xb7
[2006013.230773]  [<ffffffff810bc051>] ? __do_page_cache_readahead+0x9b/0x1b4
[2006013.230778]  [<ffffffff810652f8>] ? wake_bit_function+0x0/0x23
[2006013.230782]  [<ffffffff810bc186>] ? ra_submit+0x1c/0x20
[2006013.230785]  [<ffffffff810b4e53>] ? filemap_fault+0x17d/0x2f6
[2006013.230790]  [<ffffffff810cae1e>] ? __do_fault+0x54/0x3c3
[2006013.230794]  [<ffffffff812fce29>] ? __wait_on_bit_lock+0x76/0x84
[2006013.230798]  [<ffffffff810cd172>] ? handle_mm_fault+0x3b8/0x80f
[2006013.230803]  [<ffffffff8103a9a0>] ? pick_next_task+0x21/0x3c
[2006013.230808]  [<ffffffff810168ba>] ? sched_clock+0x5/0x8
[2006013.230813]  [<ffffffff81300186>] ? do_page_fault+0x2e0/0x2fc
[2006013.230817]  [<ffffffff812fe025>] ? page_fault+0x25/0x30

इस मशीन में 64GB रैम है।

निम्नलिखित mysql config चर हैं:

innodb_buffer_pool_size        = 48G
innodb_additional_mem_pool_size = 512M
innodb_log_buffer_size         = 64M

कुछ नैगियोस प्लगइन्स और मीट्रिक संग्रह स्क्रिप्ट को छोड़कर, इस मशीन पर कुछ और नहीं चलता है। क्या कोई मुझे यह पता लगाने में मदद कर सकता है कि ओओएम हत्यारे को क्यों मिला और भविष्य में इसे कैसे रोका जा सकता है। क्या कोई ऐसा तरीका है जिससे मैं OOM हत्यारे को mysql सर्वर को नहीं मार सकता। मुझे पता है कि हम oom_adjOOM हत्यारे को मारने से रोकने के लिए एक प्रक्रिया के लिए बहुत कम मूल्य निर्धारित कर सकते हैं । लेकिन क्या इससे बचाव का कोई और तरीका है।


2
स्मृति के उपयोग में अधिक होगा की तुलना में 48G+ 512M+ 64Mभी है क्योंकि वहाँ कुछ भूमि के ऊपर और अन्य संरचनाओं पर विचार करने के लिए; इसके लिए कहीं न कहीं एक फॉर्मूला था लेकिन मैं इसे अभी खोज नहीं सकता। यकीन नहीं है कि अगर यह इसे उड़ाने का कारण होगा 64G। हालांकि, यह सुनिश्चित करने के लिए कि पहली जगह में उपलब्ध हैं की freeपुष्टि करता 64Gहै?
frostschutz

@frostschutz: हाँ, फ्री कमांड 64G दिखाता है।
प्रदीपचेत्री

OOM किलर को Mysqld को नहीं मारने के बारे में बताने से बहुत ही कम समय के लिए आपदा आने में देरी होगी। बेहतर अपने विन्यास को ठीक करें।
स्काइ

जवाबों:


25

लिनक्स मैमोरी ओवरकमिट करता है। इसका मतलब है कि यह प्रक्रिया को सिस्टम पर वास्तव में उपलब्ध से अधिक मेमोरी का अनुरोध करने की अनुमति देता है। जब कोई प्रोग्राम मॉलोक () की कोशिश करता है, तो कर्नेल कहता है "ओके आपको मेमोरी मिल गई", लेकिन इसे आरक्षित न करें। मेमोरी केवल तभी आरक्षित होगी जब प्रक्रिया इस स्पेस में कुछ लिख देगी।

अंतर देखने के लिए, आपके पास 2 संकेतक हैं: वर्चुअल मेमोरी और रेजिडेंट मेमोरी। वर्चुअल प्रक्रिया द्वारा मांगी गई मेमोरी है, रेजिडेंट वास्तव में प्रक्रिया द्वारा उपयोग की जाने वाली मेमोरी है।

इस प्रणाली के साथ, आप "ओवरबुकिंग" में जा सकते हैं, कर्नेल उपलब्ध से अधिक मेमोरी प्रदान करता है। फिर, जब आपका सिस्टम मुफ्त मेमोरी के 0 बाइट पर जाता है और स्वैप करता है, तो उसे मुफ्त मेमोरी हासिल करने के लिए एक प्रक्रिया का त्याग (मारना) करना चाहिए ।

जब OOM किलर एक्शन में जाता है। OOM उसकी मेमोरी खपत के आधार पर एक प्रक्रिया का चयन करता है, और कई अन्य तत्व (माता-पिता अपने बच्चों के स्कोर का 1/2), यदि यह एक रूट स्वामित्व प्रक्रिया है, तो स्कोर 4 से विभाजित है, आदि .. लिनक्स पर एक नजर है- MM.org/OOM_Killer

आप /proc/MySQL_PID/oom_adjफ़ाइल को ट्यून करके OOM स्कोरिंग पर प्रभाव डाल सकते हैं । इसे सेट करने से -17, आपकी प्रक्रिया कभी भी नहीं मारी जाएगी। लेकिन ऐसा करने से पहले , आपको MySQL मेमोरी उपयोग को सीमित करने के लिए अपनी MySQL कॉन्फ़िगरेशन फ़ाइल को ट्वीक करना चाहिए । अन्यथा, OOM किलर अन्य सिस्टम प्रक्रिया (जैसे SSH, crontab, आदि ...) को मार देगा और आपका सर्वर बहुत अस्थिर स्थिति में होगा, शायद डेटा भ्रष्टाचार के लिए अग्रणी जो किसी भी चीज़ से बदतर है।

इसके अलावा, आप अधिक स्वैप का उपयोग करने पर विचार कर सकते हैं।

[संपादित करें]

आप भी बदल सकते हैं यह इन 2 sysctls के माध्यम से व्यवहार को ओवरकम कर रहा है:

vm.overcommit_memory
vm.overcommit_ratio

जैसा कि कर्नेल डॉक्यूमेंटेशन में कहा गया है

overcommit_memory:

इस मान में एक ध्वज होता है जो मेमोरी को ओवरकॉमिट करता है।

जब यह ध्वज 0 होता है, तो कर्नेल मुक्त मेमोरी की मात्रा का अनुमान लगाने का प्रयास करता है जब उपयोगकर्ता स्थान अधिक मेमोरी का अनुरोध करता है।

जब यह ध्वज 1 होता है, तो कर्नेल दिखावा करता है कि हमेशा पर्याप्त मेमोरी है जब तक कि यह वास्तव में बाहर नहीं निकलता।

जब यह ध्वज 2 वर्ष का होता है, तो कर्नेल एक "कभी न खत्म होने वाली" नीति का उपयोग करता है जो मेमोरी के किसी भी ओवरकॉम्पट को रोकने का प्रयास करता है। ध्यान दें कि user_reserve_kbytes इस नीति को प्रभावित करता है।

यह सुविधा बहुत उपयोगी हो सकती है क्योंकि बहुत सारे प्रोग्राम हैं जो कि मॉलोक () भारी मात्रा में मेमोरी "जस्ट-इन-केस" हैं और इसका ज्यादा उपयोग नहीं करते हैं।

डिफॉल्यू मूल्य शून्य है।

अधिक जानकारी के लिए दस्तावेज़ीकरण / vm / overcommit- लेखा और सुरक्षा / commoncap.c :: cap_vm_enough_memory () देखें।

overcommit_ratio:

जब overcommit_memory को 2 पर सेट किया जाता है, तो प्रतिबद्ध पता स्थान को भौतिक RAM के इस प्रतिशत से अधिक स्वैप करने की अनुमति नहीं है। ऊपर देखो।

[/ संपादित करें]


1
यह सही जवाब है। मैं इसे ठीकoom_score_adj करने के लिए उपयोग करने के आसपास के लेख देख रहा हूं , लेकिन वे वास्तव में स्कोर तंत्र को नहीं समझते हैं।
3manuek
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.