प्रोफाइलिंग उपयोगिता perf लिनक्स कर्नेल के साथ जहाज सिस्टम-वाइड और मल्टी-प्रोसेस व्यवहार की जांच के लिए बेहद उपयोगी है - लेकिन यह सीपीयू प्रोफाइलिंग की तुलना में बहुत अधिक करता है जिसका अक्सर उपयोग किया जाता है। आपने शायद perf top -az . देखा होगा या परफ टॉप-यू पोस्टग्रेज आउटपुट, लेकिन यह जो कुछ भी कर सकता है, उसका केवल थोड़ा सा हिस्सा है। (यदि आप TL/DR संस्करण चाहते हैं, तो "उपयोगकर्ता स्थान गतिशील जांच" पर जाएं)।
perf . के बड़े लाभों में से एक क्या यह गैर-घुसपैठ है। आपको डीबगर संलग्न करने और निष्पादन को बाधित करने की आवश्यकता नहीं है। आपको किसी विशेष वातावरण में सीधे प्रोफाइलर के तहत कमांड चलाने की आवश्यकता नहीं है। समस्याग्रस्त कार्यभार को डीबग करने के लिए सर्वर को फिर से शुरू करने की आवश्यकता नहीं है, और अक्सर डिबग विकल्पों के साथ फिर से संकलन करने की आवश्यकता नहीं होती है। यह तब बहुत उपयोगी होता है जब आप किसी लाइव सिस्टम में प्रदर्शन समस्याओं को ट्रैक करने का प्रयास कर रहे होते हैं, क्योंकि यह आपको इस बारे में सिद्धांतों का परीक्षण करने देता है कि क्या हो रहा है जल्दी और न्यूनतम प्रभाव के साथ।
परफ सिर्फ एक प्रोफाइलर नहीं है, इसमें ट्रेसिंग सपोर्ट भी है। प्रोफाइलिंग हार्डवेयर या सॉफ्टवेयर प्रदर्शन काउंटर द्वारा ट्रिगर होने पर सिस्टम की स्थिति के नमूने पर आधारित होती है; यह उन बिंदुओं का एक सांख्यिकीय नमूना देता है जहां सिस्टम सबसे अधिक समय व्यतीत करता है। इसके बजाय ट्रेसिंग नमूने लेता है जब भी कोई विशेष ट्रेस घटना होती है, इसलिए यह दुर्लभ लेकिन महत्वपूर्ण घटनाओं के लिए अधिक उपयोगी है।
PostgreSQL के साथ काम करते समय perf . की सबसे रोमांचक विशेषताओं में से एक उपयोगकर्ता-स्थान प्रक्रियाओं का पता लगाने . की क्षमता है . जानना चाहते हैं कि आपका PostgreSQL कितनी बार WAL सेगमेंट की अदला-बदली कर रहा है, यह कितनी बार विदेशी कुंजी लुकअप करता है, आदि? एक PostgreSQL बैकएंड के लिए या पूरे क्लस्टर में? परफ इसमें मदद कर सकते हैं।
यूजर-स्पेस और कर्नेल-स्पेस ट्रेसपॉइंट्स को मिलाया जा सकता है और सिस्टम की एक अच्छी तस्वीर प्राप्त करने में आपकी मदद करने के लिए प्रदर्शन काउंटर प्रोफाइलिंग के रूप में एक ही समय में उपयोग किया जा सकता है। परफ कर्नेल और उपयोगकर्ता-स्थान दोनों से स्टैक ट्रेस कैप्चर कर सकते हैं, और सांख्यिकीय विज़ुअलाइज़ेशन भी कर सकते हैं। उपयोक्ता-स्थान ट्रेसपॉइंट गतिशील जांच के साथ बनाए जाते हैं; कर्नेल-स्पेस वाले पूर्व-परिभाषित हो सकते हैं या गतिशील जांच हो सकते हैं।
तो, आप इनमें से कुछ सुविधाओं का उपयोग कैसे करते हैं?
टूल इंस्टॉल करें
सबसे पहले, सुनिश्चित करें कि आप मौजूदा perf . का उपयोग कर रहे हैं . यह लेख फेडोरा 19 पर perf 3.11.6 . के साथ लिखा गया था x86_64 पर, और कुछ सुविधाएं अपेक्षाकृत नई हैं।
यदि आप उपयोगकर्ता-स्थान स्टैक परिणाम चाहते हैं, तो आप चाहते हैं कि जिस कोड को आप देख रहे हैं वह -Og -ggdb -fno-omit-frame-pointer के साथ बनाया जाए . अगर आप परफ़ . का उपयोग कर रहे हैं libunwind . के साथ निर्मित आपको फ्रेम-पॉइंटर्स की आवश्यकता नहीं है; यह स्टैक ओवरफ्लो पोस्ट और आरएच बगजिला #1025603 देखें। यदि आप केवल कर्नेल साइड डेटा में रुचि रखते हैं, तो इनमें से किसी की भी आवश्यकता नहीं है। यदि आप डिस्ट्रो पैकेज का उपयोग कर रहे हैं तो आपको -debuginfo . इंस्टॉल करना पड़ सकता है पैकेज भी।
निम्नलिखित सभी परीक्षण एक perf का उपयोग करके http://yum.postgresql.org/ से स्टॉक PGDG PostgreSQL 9.2 पैकेज के साथ चलाए गए थे। libunwind . के साथ फिर से बनाया गया उपरोक्त निर्देशों के अनुसार समर्थन करें।
कर्नेल ट्रेसपॉइंट और जांच
परफ पूर्व-निर्धारित कर्नेल ट्रेसपॉइंट्स से डेटा कैप्चर कर सकते हैं, जिनमें से कुछ मेमोरी फ़्रेग्मेंटेशन, डिस्क I/O, आदि के मुद्दों को देखते समय जानकारीपूर्ण होते हैं। आप sudo perf list के साथ ट्रेसपॉइंट्स की एक सूची प्राप्त कर सकते हैं। . ट्रेसपॉइंट सूचियां निर्दिष्ट की जा सकती हैं और वाइल्डकार्ड समर्थित हैं। उदाहरण के लिए, यदि हम चल रहे PostgreSQL इंस्टेंस पर राइट और डिस्क फ्लश आँकड़े प्राप्त करना चाहते हैं तो हम चला सकते हैं:
sudo perf record -g dwarf -e block:block_rq_issue,syscalls:sys_enter_fsync -u postgres sleep 10
डेटा कैप्चर करने के लिए। स्लीप के बजाय आप नो कमांड का उपयोग कर सकते हैं और जब आप कैप्चरिंग कर रहे हों तो कंट्रोल-सी को हिट कर सकते हैं, या आप किसी अन्य कमांड जैसे psql -c का उपयोग कर सकते हैं। उस कार्यभार को ट्रिगर करने के लिए जिसे आप मापना चाहते हैं।
-यू पोस्टग्रेज उपयोगकर्ता के रूप में चल रही सभी प्रक्रियाओं को प्रोफाइल करता है पोस्टग्रेज . आप इसके बजाय -a . का उपयोग कर सकते हैं सभी सीपीयू में पूरे सिस्टम प्रोफाइलिंग के लिए। केवल एक बैकएंड का पता लगाना भी संभव है। प्रारंभ करें psql , चुनें pg_backend_pid() run चलाएं , perf . चलाएं -p $the_pid . के साथ , फिर उसी psql . में कार्यभार शुरू करें सत्र।
जब आप PostgreSQL के साथ काम कर रहे हों तो डिफ़ॉल्ट लक्ष्य प्रक्रिया, जो कि perf के नियंत्रण में चलने वाली कमांड है , आमतौर पर बहुत उपयोगी नहीं होता क्योंकि बैकएंड अधिकांश काम करता है, psql नहीं . परीक्षण कार्यभार और समय को नियंत्रित करने के लिए उप-आदेश का उपयोग करना अभी भी उपयोगी है।
एक बार जब आप डेटा कैप्चर कर लेते हैं तो आप perf रिपोर्ट . का उपयोग कर सकते हैं इसकी जांच करने के लिए। यहां चर्चा करने के लिए बहुत सारे विकल्प हैं - परिणाम एकत्रीकरण और सरलीकरण को नियंत्रित करने के लिए, स्टैक ट्रेस डिस्प्ले, इंटरेक्टिव शाप बनाम टेक्स्ट रिपोर्ट आउटपुट, और बहुत कुछ।
इस सत्र को एक उदाहरण के रूप में लें, जहां एक शेल सत्र (टर्मिनल "T2") और डेटाबेस "regress" (टर्मिनल "T1") से जुड़ा एक पोस्टग्रेज सत्र है:
T1| regress=> select pg_backend_pid(); T1| pg_backend_pid T1| ---------------- T1| 4495 T1|(1 row)
T2| $ sudo perf record -g dwarf -e block:block_rq_*,syscalls:sys_enter_write,syscalls:sys_enter_fsync -p 4495
T1| regress=> create table x as select a FROM generate_series(1,1000000) a; T1| regress=>
T2| $ ^C T2| [ perf record: Woken up 332 times to write data ] T2| [ perf record: Captured and wrote 86.404 MB perf.data (~3775041 samples) ] T2| T2| $ sudo perf report -g
आप परफ रिपोर्ट . का उपयोग कर सकते हैं ट्रेस में खोदने के लिए शाप देता है, या आप perf रिपोर्ट --stdio का उपयोग कर सकते हैं डेटा को stdout में स्ट्रीम करने के लिए इसे प्राप्त करने का विकल्प। उदाहरण के लिए, यदि आप स्टैक ट्रेस चाहते हैं तो आप चला सकते हैं:
$ sudo perf report -g --stdio ... blah blah ... # Samples: 1 of event 'syscalls:sys_enter_fsync' # Event count (approx.): 1 # # Overhead Command Shared Object Symbol # ........ ........ ............. ..................... # 100.00% postgres libc-2.17.so [.] __GI___libc_fsync | --- __GI___libc_fsync mdimmedsync heap_sync intorel_shutdown standard_ExecutorRun ExecCreateTableAs PortalRunUtility PortalRunMulti PortalRun PostgresMain ServerLoop PostmasterMain main __libc_start_main _start (nil) ... blah blah...
यह दिखा रहा है कि घटना के लिए syscalls:sys_enter_fsync उपरोक्त स्टैक के साथ एक घटना थी, एक fsync जिसे ExecCreateTableAs के माध्यम से लागू किया गया था ।
(एक कारण से मैं अभी तक अंतिम fsync() . को पिन नहीं कर पाया हूं ऐसा लगता है कि perf . द्वारा कब्जा नहीं किया गया है जब psql सीधे perf . के नियंत्रण में चलाया जाता है . यह perf stat . के साथ कोई समस्या नहीं है , केवल पूर्ण रिकॉर्ड . इसलिए मैं उपरोक्त पिड द्वारा बैकएंड को पूर्व-चयन करने के लिए हुप्स के माध्यम से कूद रहा हूं।)
उपयोगकर्ता-स्थान गतिशील जांच
कभी-कभी आप PostgreSQL द्वारा ट्रिगर किए गए कर्नेल के भीतर की घटनाओं की तुलना में PostgreSQL के भीतर होने वाली किसी चीज़ में अधिक रुचि रखते हैं। perf . के नए संस्करण उपयोगकर्ता-अंतरिक्ष कार्यक्रमों में कॉल पर ट्रिगर होने वाले डायनेमिक ट्रेसपॉइंट डालने से इसमें मदद मिल सकती है।
मान लें कि आप WAL गतिविधि देखने में रुचि रखते हैं, और यह देखना चाहते हैं कि XLogFlush कब , XLogFileInit या XLogFileOpen कहा जाता है। आप perf . के साथ इन कॉलों के लिए डायनामिक ट्रेसपॉइंट सम्मिलित कर सकते हैं :
sudo perf probe -x `which postgres` XLogFileInit sudo perf probe -x `which postgres` XLogFileOpen sudo perf probe -x `which postgres` XLogFlush
जब तक आपने -ggdb के साथ निर्माण नहीं किया है, तब तक आप केवल बाहरी प्रतीकों की जांच कर सकते हैं (गैर-स्थिर, -fvisibility फ़्लैग द्वारा छिपा नहीं) . परफ शिकायत करेंगे कोई प्रतीक नहीं मिला यदि आप किसी ऐसे प्रतीक का उपयोग करने का प्रयास करते हैं जो मौजूद नहीं है। लिखते समय perf जांच के लिए प्रतीकों को देखने के लिए बाहरी डिबगइन्फो का उपयोग करने का समर्थन नहीं करता है, हालांकि यह इसे स्टैक विश्लेषण के लिए उपयोग कर सकता है। सामान्य तौर पर, अगर यह src/include . में एक बाहरी है आप इसका उपयोग perf . के साथ कर सकते हैं ।
प्रत्येक ट्रेसपॉइंट बनाए गए ट्रेसपॉइंट के नाम को प्रिंट करेगा और आप perf जांच -l का उपयोग कर सकते हैं वैसे भी उन सभी को सूचीबद्ध करने के लिए:
$ sudo perf probe -l probe_postgres:XLogFileInit (on 0x000000000009a360) probe_postgres:XLogFileOpen (on 0x000000000009a860) probe_postgres:XLogFlush (on 0x00000000000a0670)
ये जांच अब पूर्ण घटना के रूप में प्रयोग करने योग्य हैं। आइए एक नमूना कार्यभार के दौरान xlog गतिविधि पर एक नज़र डालें, जब मैं एक pgbench रन करता हूँ तो पूरे क्लस्टर पर निगरानी रखता है:
sudo perf record -g dwarf -u postgres -e probe_postgres:XLogFileInit,probe_postgres:XLogFileOpen,probe_postgres:XLogFlush
perf रिपोर्ट -g . के साथ इसे स्वयं आज़माएं . यहां बताया गया है कि परिणाम कैसे दिखते हैं। आप -g फ्रैक्टल,0 . जैसे विकल्पों का उपयोग कर सकते हैं विवरण को नियंत्रित करने के लिए। आप किसी दिए गए काउंटर के हिट का प्रतिशत देख पाएंगे जो एक स्टैक शाखा या किसी अन्य, पीआईडी और प्रक्रिया, आदि से आए थे। --sort विकल्प आपको एकत्रीकरण और समूहीकरण पर अधिक नियंत्रण प्रदान करते हैं।
लेकिन रुकिए, और भी बहुत कुछ है
आपको परफ स्टेट . भी देखना चाहिए और परफ टॉप आदेश। वे वही इवेंट-सूचियां परफ रिकॉर्ड . के रूप में ले सकते हैं , हालांकि किसी अजीब कारण से उनका प्रोसेस-फ़िल्टर समर्थन अलग है।
यहां एक उदाहरण दिया गया है जो डमी वर्कलोड चलाता है और रन के दौरान I/O कर्नेल ट्रेसपॉइंट्स को देखता है:
$ sudo perf stat -e block:block_rq_*,syscalls:sys_enter_write,syscalls:sys_enter_fsync -a -r 5 -- psql -q -U postgres craig -c "drop table if exists x; create table x as select a FROM generate_series(1,1000000) a;"; Performance counter stats for 'psql -U postgres craig -c drop table if exists x; create table x as select a FROM generate_series(1,1000000) a;' (5 runs): 0 block:block_rq_abort [100.00%] 0 block:block_rq_requeue [100.00%] 97 block:block_rq_complete ( +- 14.82% ) [100.00%] 96 block:block_rq_insert ( +- 14.97% ) [100.00%] 98 block:block_rq_issue ( +- 14.67% ) [100.00%] 0 block:block_rq_remap [100.00%] 10,607 syscalls:sys_enter_write ( +- 0.17% ) [100.00%] 1 syscalls:sys_enter_fsync 0.908835058 seconds time elapsed ( +- 18.31% )
आप देख सकते हैं कि यह औसतन लगभग 100 ब्लॉक लेयर I/O अनुरोधों को 10k राइट () से अधिक कर रहा है और एक एकल fsync () कर रहा है। उनमें से कुछ सिस्टम पृष्ठभूमि शोर है क्योंकि हम सभी सिस्टम प्रोफाइलिंग कर रहे हैं (-a ), लेकिन चूंकि सिस्टम काफी निष्क्रिय है, यह ज्यादा नहीं है, और इसका औसत पांच रन से अधिक है।
इसी तरह, पहले जोड़े गए डायनेमिक प्रोब का उपयोग करके, pgbench रन के दौरान xlog गतिविधि पर नज़र रखें:
$ sudo perf stat -e probe_postgres:XLogFileInit,probe_postgres:XLogFileOpen,probe_postgres:XLogFlush -a -- /usr/pgsql-9.2/bin/pgbench -U postgres craig -c 2 -t 10000 starting vacuum...end. transaction type: TPC-B (sort of) scaling factor: 100 query mode: simple number of clients: 2 number of threads: 1 number of transactions per client: 10000 number of transactions actually processed: 20000/20000 tps = 715.854663 (including connections establishing) tps = 716.092133 (excluding connections establishing) Performance counter stats for '/usr/pgsql-9.2/bin/pgbench -U postgres craig -c 2 -t 10000': 64 probe_postgres:XLogFileInit [100.00%] 0 probe_postgres:XLogFileOpen [100.00%] 55,440 probe_postgres:XLogFlush 27.987364469 seconds time elapsed
आप और भी बहुत कुछ कर सकते हैं, जिसमें perf जांच के साथ स्थानीय चर की स्थिति को कैप्चर करना शामिल है। . मैं उसके कुछ उपयोगी उदाहरण बाद में लिखूंगा। इस बीच, एक नए नैदानिक टूल के साथ खेलें, एक्सप्लोर करें और मज़े करें।
अपडेट करें: Michael Paquier ने हाल ही में PostgreSQL को सिस्टमटैप के साथ ट्रेस करने के बारे में एक संबंधित लेख लिखा था जो इस के पाठकों के लिए रुचिकर हो सकता है। आपको उस दृष्टिकोण का उपयोग करने के लिए पीजी को पुन:संकलित करना होगा, लेकिन वाक्यविन्यास अच्छा है और यह कुछ अन्य फायदे प्रदान करता है।