एक प्रदर्शन करने वाले MySQL डेटाबेस सर्वर के प्रमुख कारकों में से एक अच्छा मेमोरी आवंटन और उपयोग है, खासकर जब इसे उत्पादन वातावरण में चलाते हैं। लेकिन आप कैसे निर्धारित कर सकते हैं कि MySQL उपयोग अनुकूलित है या नहीं? क्या उच्च स्मृति उपयोग करना उचित है या इसके लिए ठीक ट्यूनिंग की आवश्यकता है? क्या होगा अगर मैं स्मृति रिसाव के खिलाफ आऊं?
आइए इन विषयों को कवर करते हैं और उन चीजों को दिखाते हैं जिन्हें आप उच्च स्मृति उपयोग के निशान निर्धारित करने के लिए MySQL में देख सकते हैं।
MySQL में मेमोरी आवंटन
इससे पहले कि हम विशिष्ट विषय शीर्षक में तल्लीन हों, मैं केवल इस बारे में एक संक्षिप्त जानकारी दूंगा कि MySQL मेमोरी का उपयोग कैसे करता है। समवर्ती लेनदेन को संभालने और बड़े प्रश्नों को चलाने के दौरान मेमोरी गति और दक्षता के लिए एक महत्वपूर्ण संसाधन निभाता है। MySQL में प्रत्येक थ्रेड मेमोरी की मांग करता है जिसका उपयोग क्लाइंट कनेक्शन को प्रबंधित करने के लिए किया जाता है, और ये थ्रेड समान बेस मेमोरी साझा करते हैं। वेरिएबल्स जैसे थ्रेड_स्टैक (थ्रेड्स के लिए स्टैक), net_buffer_length (कनेक्शन बफर और परिणाम बफर के लिए), या max_allowed_packet के साथ जहां जरूरत पड़ने पर कनेक्शन और परिणाम गतिशील रूप से इस मान तक बढ़ जाएंगे, वे वेरिएबल हैं जो मेमोरी उपयोग को प्रभावित करते हैं। जब किसी थ्रेड की आवश्यकता नहीं रह जाती है, तो उसे आवंटित मेमोरी को छोड़ दिया जाता है और सिस्टम में वापस कर दिया जाता है जब तक कि थ्रेड थ्रेड कैश में वापस नहीं जाता। उस स्थिति में, स्मृति आवंटित रहती है। क्वेरी जॉइन, क्वेरी कैश, सॉर्टिंग, टेबल कैशे, टेबल डेफिनिशन के लिए MySQL में मेमोरी की आवश्यकता होती है लेकिन इन्हें सिस्टम वेरिएबल के साथ जिम्मेदार ठहराया जाता है जिन्हें आप कॉन्फ़िगर और सेट कर सकते हैं।
ज्यादातर मामलों में, कॉन्फ़िगरेशन के लिए सेट किए गए मेमोरी-विशिष्ट चर को स्टोरेज-आधारित विशिष्ट कॉन्फ़िगरेशन जैसे MyISAM या InnoDB पर लक्षित किया जाता है। जब एक mysqld उदाहरण होस्ट सिस्टम के भीतर उत्पन्न होता है, तो MySQL एक विशिष्ट कॉन्फ़िगरेशन पर सेट किए गए मानों के आधार पर डेटाबेस संचालन के प्रदर्शन को बेहतर बनाने के लिए बफ़र्स और कैश आवंटित करता है। उदाहरण के लिए, प्रत्येक DBA द्वारा InnoDB में सेट किए जाने वाले सबसे सामान्य चर हैं innodb_buffer_pool_size और innodb_buffer_pool_instances जो दोनों बफर पूल मेमोरी आवंटन से संबंधित हैं जो InnoDB तालिकाओं के लिए कैश्ड डेटा रखता है। यह वांछनीय है यदि आपके पास बड़ी मेमोरी है और बफर पूल को कई बफर पूल इंस्टेंस में विभाजित करके समवर्ती में सुधार करने के लिए innodb_buffer_pool_instances सेट करके बड़े लेनदेन को संभालने की उम्मीद कर रहे हैं।
MyISAM के लिए, आपको key_buffer_size से निपटने के लिए मेमोरी की मात्रा को संभालने के लिए कुंजी बफर संभालना होगा। MyISAM प्रत्येक समवर्ती थ्रेड के लिए बफर आवंटित करता है जिसमें एक टेबल संरचना, प्रत्येक कॉलम के लिए कॉलम संरचनाएं, और आकार 3 * N का बफर आवंटित किया जाता है (जहां एन अधिकतम पंक्ति लंबाई है, बीएलओबी कॉलम की गिनती नहीं)। MyISAM आंतरिक उपयोग के लिए एक अतिरिक्त पंक्ति बफर भी रखता है।
MySQL अस्थायी तालिकाओं के लिए भी स्मृति आवंटित करता है जब तक कि यह बहुत बड़ी न हो जाए (tmp_table_size और max_heap_table_size द्वारा निर्धारित)। यदि आप MEMORY तालिकाओं का उपयोग कर रहे हैं और चर max_heap_table_size बहुत अधिक सेट है, तो यह एक बड़ी मेमोरी भी ले सकता है क्योंकि max_heap_table_size सिस्टम चर निर्धारित करता है कि तालिका कितनी बड़ी हो सकती है, और ऑन-डिस्क प्रारूप में कोई रूपांतरण नहीं है।
MySQL में एक प्रदर्शन स्कीमा भी है जो निम्न स्तर पर MySQL गतिविधियों की निगरानी के लिए एक विशेषता है। एक बार यह सक्षम हो जाने पर, यह गतिशील रूप से मेमोरी को वृद्धिशील रूप से आवंटित करता है, इसके मेमोरी उपयोग को सर्वर स्टार्टअप के दौरान आवश्यक मेमोरी आवंटित करने के बजाय वास्तविक सर्वर लोड तक बढ़ाता है। एक बार मेमोरी आवंटित हो जाने के बाद, सर्वर के पुनरारंभ होने तक इसे मुक्त नहीं किया जाता है।
MySQL को इसके बफर पूल के लिए मेमोरी के बड़े क्षेत्रों को आवंटित करने के लिए भी कॉन्फ़िगर किया जा सकता है यदि लिनक्स का उपयोग कर रहा है और यदि कर्नेल बड़े पृष्ठ समर्थन के लिए सक्षम है, अर्थात HugePages का उपयोग कर रहा है।
MySQL मेमोरी के उच्च होने पर क्या जांचें
चल रही क्वेरी जांचें
MySQL DBA के लिए सबसे पहले आधार को छूना बहुत आम है कि चल रहे MySQL सर्वर के साथ क्या हो रहा है। सबसे बुनियादी प्रक्रियाएं हैं प्रक्रिया सूची की जांच करना, सर्वर की स्थिति की जांच करना और भंडारण इंजन की स्थिति की जांच करना। इन चीजों को करने के लिए, मूल रूप से, आपको केवल MySQL में लॉग इन करके प्रश्नों की श्रृंखला चलानी होगी। नीचे देखें:
चल रही क्वेरी देखने के लिए,
mysql> SHOW [FULL] PROCESSLIST;
वर्तमान प्रक्रिया सूची को देखने से उन प्रश्नों का पता चलता है जो सक्रिय रूप से चल रहे हैं या यहां तक कि निष्क्रिय या स्लीपिंग प्रक्रियाएं भी चल रही हैं। यह बहुत महत्वपूर्ण है और चल रहे प्रश्नों का रिकॉर्ड रखना एक महत्वपूर्ण दिनचर्या है। जैसा कि इस बात पर ध्यान दिया गया है कि MySQL मेमोरी को कैसे आवंटित करता है, चल रहे प्रश्न मेमोरी आवंटन का उपयोग करेंगे और मॉनिटर न किए जाने पर प्रदर्शन के मुद्दों को काफी हद तक पैदा कर सकते हैं।
MySQL सर्वर स्थिति चर देखें,
mysql> SHOW SERVER STATUS\G
या विशिष्ट चर जैसे फ़िल्टर करें
mysql> SHOW SERVER STATUS WHERE variable_name IN ('<var1>', 'var2'...);
MySQL की स्थिति चर आपकी सांख्यिकीय जानकारी के रूप में कार्य करती है ताकि यह निर्धारित किया जा सके कि आपका MySQL स्थिति मानों द्वारा दिए गए काउंटरों को देखकर यह निर्धारित करता है कि आपका MySQL कैसा प्रदर्शन करता है। यहां कुछ मूल्य हैं जो आपको एक नज़र देते हैं जो स्मृति उपयोग को प्रभावित करता है। उदाहरण के लिए, थ्रेड्स की संख्या, टेबल कैश की संख्या या बफर पूल के उपयोग की जाँच करना,
...
| Created_tmp_disk_tables | 24240 |
| Created_tmp_tables | 334999 |
…
| Innodb_buffer_pool_pages_data | 754 |
| Innodb_buffer_pool_bytes_data | 12353536 |
...
| Innodb_buffer_pool_pages_dirty | 6 |
| Innodb_buffer_pool_bytes_dirty | 98304 |
| Innodb_buffer_pool_pages_flushed | 30383 |
| Innodb_buffer_pool_pages_free | 130289 |
…
| Open_table_definitions | 540 |
| Open_tables | 1024 |
| Opened_table_definitions | 540 |
| Opened_tables | 700887 |
...
| Threads_connected | 5 |
...
| Threads_cached | 2 |
| Threads_connected | 5 |
| Threads_created | 7 |
| Threads_running | 1 |
इंजन की मॉनिटर स्थिति देखें, उदाहरण के लिए, InnoDB स्थिति
mysql> SHOW ENGINE INNODB STATUS\G
InnoDB स्थिति उस लेनदेन की वर्तमान स्थिति को भी प्रकट करती है जिसे स्टोरेज इंजन संसाधित कर रहा है। यह आपको लेन-देन का ढेर आकार देता है, अनुकूली हैश इंडेक्स इसके बफर उपयोग को प्रकट करता है, या आपको नीचे दिए गए उदाहरण की तरह ही इनोडब बफर पूल जानकारी दिखाता है:
---TRANSACTION 10798819, ACTIVE 0 sec inserting, thread declared inside InnoDB 1201
mysql tables in use 1, locked 1
1 lock struct(s), heap size 1136, 0 row lock(s), undo log entries 8801
MySQL thread id 68481, OS thread handle 139953970235136, query id 681821 localhost root copy to tmp table
ALTER TABLE NewAddressCode2_2 ENGINE=INNODB
…
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 528, free list len 43894, seg size 44423, 1773 merges
merged operations:
insert 63140, delete mark 0, delete 0
discarded operations:
insert 0, delete mark 0, delete 0
Hash table size 553193, node heap has 1 buffer(s)
Hash table size 553193, node heap has 637 buffer(s)
Hash table size 553193, node heap has 772 buffer(s)
Hash table size 553193, node heap has 1239 buffer(s)
Hash table size 553193, node heap has 2 buffer(s)
Hash table size 553193, node heap has 0 buffer(s)
Hash table size 553193, node heap has 1 buffer(s)
Hash table size 553193, node heap has 1 buffer(s)
115320.41 hash searches/s, 10292.51 non-hash searches/s
...
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 2235564032
Dictionary memory allocated 3227698
Internal hash tables (constant factor + variable factor)
Adaptive hash index 78904768 (35404352 + 43500416)
Page hash 277384 (buffer pool 0 only)
Dictionary cache 12078786 (8851088 + 3227698)
File system 1091824 (812272 + 279552)
Lock system 5322504 (5313416 + 9088)
Recovery system 0 (0 + 0)
Buffer pool size 131056
Buffer pool size, bytes 2147221504
Free buffers 8303
Database pages 120100
Old database pages 44172
Modified db pages 108784
Pending reads 0
Pending writes: LRU 2, flush list 342, single page 0
Pages made young 533709, not young 181962
3823.06 youngs/s, 1706.01 non-youngs/s
Pages read 4104, created 236572, written 441223
38.09 reads/s, 339.46 creates/s, 1805.87 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 12 / 1000 not 5 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 120100, unzip_LRU len: 0
I/O sum[754560]:cur[8096], unzip sum[0]:cur[0]
…
जोड़ने के लिए एक और बात, आप अपने MySQL सर्वर द्वारा मेमोरी खपत और उपयोग की निगरानी के लिए प्रदर्शन स्कीमा और sys स्कीमा का भी उपयोग कर सकते हैं। डिफ़ॉल्ट रूप से, अधिकांश इंस्ट्रूमेंटेशन डिफ़ॉल्ट रूप से अक्षम होते हैं इसलिए इसका उपयोग करने के लिए मैन्युअल चीजें हैं।
स्वैपनेस की जांच करें
किसी भी तरह से, यह संभव है कि MySQL अपनी मेमोरी को डिस्क पर स्वैप कर रहा हो। यह अक्सर एक बहुत ही सामान्य स्थिति होती है, खासकर जब MySQL सर्वर और अंतर्निहित हार्डवेयर अपेक्षित आवश्यकताओं के समानांतर इष्टतम रूप से सेट नहीं होते हैं। कुछ ऐसे मामले हैं जिनमें यातायात की मांग का अनुमान नहीं लगाया गया है, स्मृति तेजी से बढ़ सकती है, खासकर यदि खराब क्वेरी चलाई जाती हैं, जिससे बहुत अधिक मेमोरी स्पेस का उपभोग या उपयोग होता है, जिससे प्रदर्शन में गिरावट आती है क्योंकि डेटा को बफर के बजाय डिस्क पर चुना जाता है। स्वैपनेस की जांच करने के लिए, बस नीचे की तरह फ्रीमेम कमांड या vmstat चलाएँ,
[[email protected] ~]# free -m
total used free shared buff/cache available
Mem: 3790 2754 121 202 915 584
Swap: 1535 39 1496
[[email protected] ~]# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 40232 124100 0 937072 2 3 194 1029 477 313 7 2 91 1 0
0 0 40232 123912 0 937228 0 0 0 49 1247 704 13 3 84 0 0
1 0 40232 124184 0 937212 0 0 0 35 751 478 6 1 93 0 0
0 0 40232 123688 0 937228 0 0 0 15 736 487 5 1 94 0 0
0 0 40232 123912 0 937220 0 0 3 74 1065 729 8 2 89 0 0
आप procfs का उपयोग करके भी जांच कर सकते हैं और /proc/vmstat या /proc/meminfo पर जाने जैसी जानकारी एकत्र कर सकते हैं।
मैसिफ के साथ Perf, gdb, और Valgrind का उपयोग करना
perf, gdb, और valgrind जैसे टूल का उपयोग करने से आपको MySQL मेमोरी उपयोग को निर्धारित करने की अधिक उन्नत विधि में खुदाई करने में मदद मिलती है। कई बार एक दिलचस्प परिणाम स्मृति खपत को सुलझाने का एक रहस्य बन जाता है जो MySQL में आपकी घबराहट की ओर ले जाता है। यह अधिक संदेह करने की आवश्यकता में बदल जाता है और इन उपकरणों का उपयोग करने से आपको यह जांचने में मदद मिलती है कि MySQL मेमोरी को आवंटित करने से लेकर लेनदेन या प्रक्रियाओं को संसाधित करने के लिए इसका उपयोग करने के लिए कैसे उपयोग कर रहा है। उदाहरण के लिए यह उपयोगी है यदि आप देख रहे हैं कि MySQL असामान्य रूप से व्यवहार कर रहा है जो खराब कॉन्फ़िगरेशन का कारण बन सकता है या मेमोरी लीक का निष्कर्ष निकाल सकता है।
उदाहरण के लिए, MySQL में perf का उपयोग करने से सिस्टम स्तर की रिपोर्ट में अधिक जानकारी का पता चलता है:
[[email protected] ~]# perf report --input perf.data --stdio
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 54K of event 'cpu-clock'
# Event count (approx.): 13702000000
#
# Overhead Command Shared Object Symbol
# ........ ....... ................... ...................................................................................................................................................................................................
#
60.66% mysqld [kernel.kallsyms] [k] _raw_spin_unlock_irqrestore
2.79% mysqld libc-2.17.so [.] __memcpy_ssse3
2.54% mysqld mysqld [.] ha_key_cmp
1.89% mysqld [vdso] [.] __vdso_clock_gettime
1.05% mysqld mysqld [.] rec_get_offsets_func
1.03% mysqld mysqld [.] row_sel_field_store_in_mysql_format_func
0.92% mysqld mysqld [.] _mi_rec_pack
0.91% mysqld [kernel.kallsyms] [k] finish_task_switch
0.90% mysqld mysqld [.] row_search_mvcc
0.86% mysqld mysqld [.] decimal2bin
0.83% mysqld mysqld [.] _mi_rec_check
….
चूंकि यह खुदाई करने के लिए एक विशेष विषय हो सकता है, हमारा सुझाव है कि आप इन वास्तव में अच्छे बाहरी ब्लॉगों को अपने संदर्भ के रूप में देखें, MySQL प्रोफाइलिंग के लिए मूल बातें, MySQL स्केलिंग समस्याओं का पता लगाना perf का उपयोग करना, या सीखें कि कैसे मैसिफ़ के साथ वालग्रिंड का उपयोग करके डीबग करें।
MySQL मेमोरी उपयोग की जांच करने का कुशल तरीका
ClusterControl का उपयोग करने से किसी भी परेशानी वाली दिनचर्या से छुटकारा मिलता है जैसे कि आपकी रनबुक को पढ़ना या यहां तक कि अपनी खुद की प्लेबुक बनाना जो आपके लिए रिपोर्ट वितरित करेगी। ClusterControl में, आपके पास डैशबोर्ड हैं (SCUMM का उपयोग करके) जहां आप अपने MySQL नोड का त्वरित अवलोकन कर सकते हैं। उदाहरण के लिए, MySQL सामान्य डैशबोर्ड देखना,
आप यह निर्धारित कर सकते हैं कि MySQL नोड कैसा प्रदर्शन करता है,
आप देखते हैं कि ऊपर दी गई इमेज में वेरिएबल का पता चलता है जो MySQL मेमोरी उपयोग को प्रभावित करते हैं। आप जांच सकते हैं कि सॉर्ट कैश, अस्थायी टेबल, थ्रेड कनेक्टेड, क्वेरी कैश, या स्टोरेज इंजन इनोडब बफर पूल या माईसाम के कुंजी बफर के लिए मीट्रिक कैसे हैं।
ClusterControl का उपयोग करना आपको वन-स्टॉप उपयोगिता उपकरण प्रदान करता है जहां आप उन प्रक्रियाओं (प्रश्नों) को निर्धारित करने के लिए चल रहे प्रश्नों की जांच कर सकते हैं जो उच्च स्मृति उपयोग को प्रभावित कर सकते हैं। उदाहरण के लिए नीचे देखें,
MySQL की स्थिति चर देखना आसान है,
आप प्रदर्शन पर भी जा सकते हैं -> इनोडब स्थिति के साथ-साथ प्रकट करने के लिए आपके डेटाबेस नोड्स की वर्तमान InnoDB स्थिति। साथ ही, ClusterControl में, एक घटना का पता चलता है, यह घटना को एकत्रित करने का प्रयास करेगा और इतिहास को एक रिपोर्ट के रूप में दिखाएगा जो आपको InnoDB स्थिति प्रदान करती है जैसा कि हमारे पिछले ब्लॉग में MySQL फ्रीज फ्रेम के बारे में दिखाया गया है।
सारांश
उच्च मेमोरी उपयोग पर संदेह होने पर अपने MySQL डेटाबेस का समस्या निवारण और निदान करना तब तक मुश्किल नहीं है जब तक आप उपयोग करने के लिए प्रक्रियाओं और उपकरणों को जानते हैं। सही टूल का उपयोग करने से आपको बेहतर परिणाम की संभावना के साथ समाधान या समाधान देने के लिए अधिक लचीलापन और तेज़ उत्पादकता मिलती है।