PostgreSQL कॉन्फ़िगरेशन विकल्पों के ढेर के साथ आता है, लेकिन इनमें से कुछ विकल्पों की डिफ़ॉल्ट सेटिंग्स को बदलने से आपके PostgreSQL सर्वर की अवलोकन क्षमता में काफी सुधार होता है। उत्पादन में समस्याएं आने से पहले आप इन विकल्पों को सेट और कॉन्फ़िगर करना चाहेंगे, क्योंकि वे उन मुद्दों को समझने और हल करने के लिए आवश्यक जानकारी प्रदान कर सकते हैं।
सेटिंग्स और एक्सटेंशन के बारे में अधिक जानने के लिए पढ़ें जो आपके PostgreSQL सर्वर के आंतरिक कामकाज के बारे में मीट्रिक और जानकारी को उजागर करते हैं।
लॉग लाइन उपसर्ग
log_line_prefix कॉन्फ़िगरेशन विकल्प यह निर्धारित करता है कि प्रत्येक लॉग लाइन की शुरुआत में PostgreSQL क्या लिखता है। डिफ़ॉल्ट विशिष्ट लिनक्स वितरण या प्रबंधित समाधान पर निर्भर करता है जिसका आप उपयोग कर रहे हैं, लेकिन अधिकतर इसमें कुछ आइटम शामिल नहीं होते हैं जो ग्राहकों के साथ दुर्व्यवहार करने वाले को ट्रैक करने में बहुत उपयोगी साबित हो सकते हैं। यह कोशिश करें log_line_prefix :
log_line_prefix = '%m [%p] %a %u %d %h '
इसमें टाइमस्टैम्प शामिल है (%m ), बैकएंड प्रक्रिया का पीआईडी (%p ), आवेदन का नाम (%a ) क्लाइंट का, वह उपयोगकर्ता नाम जिसे क्लाइंट ने कनेक्ट किया है (%u ), वह डेटाबेस जिसे क्लाइंट ने कनेक्ट किया है (%d ) और होस्टनाम या आईपी जहां से कनेक्शन आ रहा है (%h ) इसका परिणाम इस तरह लॉगलाइन में होता है:
2021-01-30 05:06:03.675 UTC [73] psql postgres bench 172.17.0.1 ERROR: relation "pgbench_akkounts" does not exist at character 15
2021-01-30 05:06:03.675 UTC [73] psql postgres bench 172.17.0.1 STATEMENT: select * from pgbench_akkounts;
जो डिफ़ॉल्ट की तुलना में बहुत अधिक उपयोगी हैं। आप देख सकते हैं कि एक क्लाइंट 172.17.0.1 . से जुड़ा हुआ है उपयोगकर्ता के रूप में पोस्टग्रेज डेटाबेस के लिए बेंच , और एप्लिकेशन था psql . निश्चित रूप से डिफ़ॉल्ट विकल्प पर एक सुधार, जो केवल यही दिखाता है:
2021-01-30 05:13:22.630 UTC [63] ERROR: relation "pgbench_akkounts" does not exist at character 15
2021-01-30 05:13:22.630 UTC [63] STATEMENT: select * from pgbench_akkounts;
धीमी क्वेरी लॉग करना
PostgreSQL को उन प्रश्नों को लॉग करने के लिए कॉन्फ़िगर किया जा सकता है जो निष्पादित करने के लिए निर्धारित समय से अधिक समय लेते हैं। ये एक ही लॉग फ़ाइल में जाते हैं; MySQL की तरह कोई अलग धीमी क्वेरी लॉग फ़ाइल नहीं है।
उन कथनों को लॉग करने के लिए जिन्हें निष्पादित करने में 1 सेकंड से अधिक समय लगता है, log_min_duration_statement का उपयोग करें इस तरह का विकल्प:
log_min_duration_statement = 1s
ध्यान दें कि log_min_duration_statement सभी कथनों पर विचार करेगा (उदाहरण के लिए, REINDEX TABLE जैसे लंबे समय से चल रहे व्यवस्थापकीय कथनों सहित) ) और न केवल प्रश्न (चुनें ) इस विकल्प द्वारा निर्मित कुछ लॉग प्रविष्टियां यहां दी गई हैं:
2021-01-30 08:42:57.473 UTC [62] psql postgres postgres 172.17.0.1 LOG: duration: 1016.283 ms statement: select pg_sleep(1);
2021-01-30 08:52:00.541 UTC [62] psql postgres postgres 172.17.0.1 LOG: duration: 1118.277 ms statement: select pg_sleep(1.1);
यदि यह समान कथनों के बहुत अधिक लॉग में परिणत होता है, तो आप पोस्टग्रेज़ को इसका केवल एक प्रतिशत का उपयोग करके लॉग इन करने के लिए कह सकते हैं:
log_min_duration_statement = -1
log_min_duration_sample = 1s
log_statement_sample_rate = 0.25
यह केवल 25% कथनों को लॉग करता है जो लॉगिंग के योग्य हो जाते हैं (जिन्हें निष्पादित करने में 1 सेकंड से अधिक समय लगता है)। लॉग आउटपुट पहले जैसा ही है। यह जानने का कोई तरीका नहीं है कि कितने योग्य स्टेटमेंट लॉग नहीं किए गए थे।
सभी कथनों को लॉग करने के लिए, उन्हें निष्पादित करने में लगने वाले समय के साथ, log_statement . का उपयोग करें इसके बजाय विकल्प:
log_statement = mod
log_duration = on
'मॉड' विकल्प पोस्टग्रेज को डीडीएल और डेटा-संशोधित बयानों को लॉग करने के लिए कहता है। इससे इस तरह के लॉग बनते हैं:
2021-01-30 08:35:08.985 UTC [64] pgbench postgres bench 172.17.0.1 LOG: statement: insert into pgbench_tellers(tid,bid,tbalance) values (10,1,0)
2021-01-30 08:35:08.985 UTC [64] pgbench postgres bench 172.17.0.1 LOG: duration: 0.241 ms
सावधान रहें कि यह नहीं है इस तरह से स्टेटमेंट लॉगिंग को सक्षम करने के लिए संभव है, सभी स्टेटमेंट लॉग हो जाएंगे, और आप टन लॉग प्रविष्टियों के साथ समाप्त हो जाएंगे।
लॉगिंग लॉक और डेडलॉक
लॉक प्राप्त करने के लिए प्रश्न बहुत लंबा इंतजार कर सकते हैं। आमतौर पर, lock_timeout . विकल्प का उपयोग करके कितनी देर तक प्रतीक्षा करनी है, इसकी ऊपरी सीमा निर्धारित की जाती है , आमतौर पर क्लाइंट साइड पर। यदि कोई क्वेरी लॉक प्राप्त करने के लिए लंबे समय से प्रतीक्षा कर रही है, तो पोस्टग्रेज़ इस क्वेरी के निष्पादन को रद्द कर देगा और एक त्रुटि लॉग करेगा:
2021-01-30 09:35:52.415 UTC [67] psql postgres testdb 172.17.0.1 ERROR: canceling statement due to lock timeout
2021-01-30 09:35:52.415 UTC [67] psql postgres testdb 172.17.0.1 STATEMENT: cluster t;
मान लें कि आप 1 मिनट का लॉक टाइमआउट सेट करना चाहते हैं, लेकिन लॉग क्वेरी जो लॉक के लिए 30 सेकंड से अधिक समय तक प्रतीक्षा करती हैं। आप इसका उपयोग करके ऐसा कर सकते हैं:
log_lock_waits = on
deadlock_timeout = 30s
यह इस तरह के लॉग बनाएगा:
2021-01-30 09:49:22.331 UTC [70] psql postgres testdb 172.17.0.1 LOG: process 70 still waiting for ShareLock on transaction 493 after 30009.004 ms
2021-01-30 09:49:22.331 UTC [70] psql postgres testdb 172.17.0.1 DETAIL: Process holding the lock: 68. Wait queue: 70.
2021-01-30 09:49:22.331 UTC [70] psql postgres testdb 172.17.0.1 CONTEXT: while locking tuple (0,3) in relation "t"
2021-01-30 09:49:22.331 UTC [70] psql postgres testdb 172.17.0.1 STATEMENT: select * from t for update;
deadlock_timeout . का उपयोग टाइपो नहीं है:यह वह मान है जिसका उपयोग लॉक वेटिंग मैकेनिज्म करता है। आदर्श रूप से, कुछ ऐसा होना चाहिए था जैसे log_min_duration_lock_wait , लेकिन दुर्भाग्य से, ऐसा नहीं है।
वास्तविक गतिरोध के मामले में, Postgres गतिरोध वाले लेन-देन को deadlock_timeout के बाद निरस्त कर देगा अवधि, और आपत्तिजनक बयानों को लॉग करेगा। कोई स्पष्ट कॉन्फ़िगरेशन आवश्यक नहीं है।
2021-01-30 09:55:37.724 UTC [68] psql postgres testdb 172.17.0.1 LOG: process 68 detected deadlock while waiting for ShareLock on transaction 496 after 30007.633 ms
2021-01-30 09:55:37.724 UTC [68] psql postgres testdb 172.17.0.1 DETAIL: Process holding the lock: 70. Wait queue: .
2021-01-30 09:55:37.724 UTC [68] psql postgres testdb 172.17.0.1 CONTEXT: while locking tuple (0,3) in relation "t"
2021-01-30 09:55:37.724 UTC [68] psql postgres testdb 172.17.0.1 STATEMENT: select * from t where a=4 for update;
2021-01-30 09:55:37.725 UTC [68] psql postgres testdb 172.17.0.1 ERROR: deadlock detected
2021-01-30 09:55:37.725 UTC [68] psql postgres testdb 172.17.0.1 DETAIL: Process 68 waits for ShareLock on transaction 496; blocked by process 70.
Process 70 waits for ShareLock on transaction 495; blocked by process 68.
Process 68: select * from t where a=4 for update;
Process 70: select * from t where a=0 for update;
2021-01-30 09:55:37.725 UTC [68] psql postgres testdb 172.17.0.1 HINT: See server log for query details.
2021-01-30 09:55:37.725 UTC [68] psql postgres testdb 172.17.0.1 CONTEXT: while locking tuple (0,3) in relation "t"
2021-01-30 09:55:37.725 UTC [68] psql postgres testdb 172.17.0.1 STATEMENT: select * from t where a=4 for update;
ऑटोवैक्यूम लॉग करना
ऑटोवैक्यूम प्रक्रिया तब शुरू होती है जब पोस्टग्रेज़ यह निर्धारित करता है कि एक तालिका में डेटा एक वैक्यूम और विश्लेषण की गारंटी देने के लिए पर्याप्त रूप से बदल गया है। इस प्रक्रिया पर नज़र रखने के लिए, ऑटोवैक्यूम रन की लॉगिंग सक्षम करें:
log_autovacuum_min_duration = 250ms
यहां एक नमूना प्रविष्टि है जो एक तालिका में अत्यधिक परिवर्तनों के कारण हुई थी:
2021-01-30 10:23:33.201 UTC [63] LOG: automatic vacuum of table "postgres.public.t": index scans: 0
pages: 0 removed, 95 remain, 0 skipped due to pins, 0 skipped frozen
tuples: 8991 removed, 10000 remain, 0 are dead but not yet removable, oldest xmin: 492
buffer usage: 215 hits, 4 misses, 4 dirtied
avg read rate: 1.885 MB/s, avg write rate: 1.885 MB/s
system usage: CPU: user: 0.01 s, system: 0.00 s, elapsed: 0.01 s
WAL usage: 244 records, 1 full page images, 67984 bytes
2021-01-30 10:23:33.222 UTC [63] LOG: automatic analyze of table "postgres.public.t" system usage: CPU: user: 0.01 s, system: 0.00 s, elapsed: 0.01 s
ध्यान दें कि ऑटोवैक्यूम आमतौर पर वैक्यूम के बाद एक विश्लेषण को ट्रिगर करेगा, और यह भी लॉग किया जाएगा।
ये लॉग आपको यह पता लगाने में मदद करेंगे कि ऑटोवैक्यूम मापदंडों को सबसे अच्छा कैसे ट्यून किया जाए, और यह जांचने में मदद करेगा कि क्या और कब ऑटोवैक्यूम उतना प्रभावी नहीं है जितना आपने सोचा था।
लॉगिंग चेकपॉइंट
चेकपॉइंटिंग वाल-लॉग किए गए परिवर्तनों को वास्तविक फाइलों में वापस टेबल में धकेलने की प्रक्रिया है। आदर्श रूप से चेकपॉइंट नियमित-और-बहुत-बार-बार अंतराल पर होने चाहिए, क्योंकि यह एक सीपीयू और डिस्क गहन प्रक्रिया है। विभिन्न कारणों से, चौकियों को भी अगले निर्धारित समय से पहले होने के लिए मजबूर किया जाता है, और इसके परिणामस्वरूप क्वेरी प्रदर्शन कम हो जाता है।
चेकपॉइंट फ़्रीक्वेंसी और दक्षता पर नज़र रखने के लिए, चेकपॉइंट्स की लॉगिंग सक्षम करें:
log_checkpoints = on
यह पोस्टग्रेएसक्यूएल को बताता है कि जब भी कोई चेकपॉइंट होता है तो वह निम्नलिखित लॉग इन करे:
2021-01-30 10:05:57.085 UTC [56] LOG: checkpoint starting: immediate force wait
2021-01-30 10:05:57.159 UTC [56] LOG: checkpoint complete: wrote 0 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.000 s, sync=0.000 s, total=0.074 s; sync files=0, longest=0.000 s, average=0.000 s; distance=0 kB, estimate=0 kB
पहली पंक्ति में वे झंडे होते हैं जो बैकएंड चेकपॉइंट को पास करते हैं। आप देख सकते हैं कि "बल" ने चेकपॉइंट का कारण बना, भले ही चेकपॉइंट में कोई लंबित परिवर्तन नहीं था। यदि "तत्काल" निर्दिष्ट नहीं किया गया होता, तो चेकपॉइंटर checkpoint_completion_target तक चेकपॉइंट करता। ।
अन्य सर्वर-साइड सेटिंग्स
कुछ अन्य सेटिंग्स हैं जिन्हें आप अपने PostgreSQLकॉन्फ़िगरेशन में चालू कर सकते हैं जो समस्याओं के निदान में मदद करेंगे:
- track_io_timeing - इसे चालू . पर सेट करना आपको प्रत्येक क्वेरी के लिए इंडिस्क I/O बिताया गया समय देखने देता है (नीचे वर्णित pg_stat_statements एक्सटेंशन के साथ संयुक्त)। इसे चालू करने के लिए एक चेतावनी के बारे में दस्तावेज़ देखें, लेकिन लगभग किसी भी आधुनिक लिनक्स पर सुरक्षित होना चाहिए। इसे चालू किए बिना किसी क्वेरी की डिस्क I/O लागत को देखना असंभव है।
- track_commit_timestamp - इसे चालू . पर सेट करना डिबगिंग प्रतिकृति अंतराल और अन्य प्रतिकृति-संबंधित मुद्दों में उपयोगी हो सकता है।
pg_stat_statements के ज़रिए क्वेरी आंकड़े
एक्सटेंशन pg_stat_statements किसी भी PostgreSQL परिनियोजन के लिए एक आवश्यक सहायक है। यह निष्पादित प्रत्येक क्वेरी के लिए आंकड़े एकत्र करता है और रिकॉर्ड करता है, और उन्हें "pg_stat_statements" नामक दृश्य के रूप में प्रस्तुत करता है। यह एक एक्सटेंशन है, जिसका अर्थ है कि आपको इसे प्रत्येक डेटाबेस में स्पष्ट रूप से स्थापित करना होगा, जिसके लिए आप कमांड का उपयोग करके डेटा चाहते हैं:
CREATE EXTENSION pg_stat_statements;
चूंकि एक्सटेंशन .so . पर निर्भर करता है , आपको shared_preload_libraries . का उपयोग करके उसे लोड करना होगा :
shared_preload_libraries = 'pg_stat_statements'
दुर्भाग्य से इसके लिए PostgreSQL सर्वर को पुनरारंभ करने की आवश्यकता है; इसलिए सुनिश्चित करें कि आप लाइव होने से पहले ऐसा कर लें।
यदि आपने PostgreSQL के पिछले संस्करण से अपग्रेड किया है, तो निम्न का उपयोग करके अपने pg_stat_statement एक्सटेंशन को भी अपग्रेड करना सुनिश्चित करें:
ALTER EXTENSION pg_stat_statements UPDATE;
pg_stat_statements एक्सटेंशन कुछ भी लॉग नहीं करता है, इसका उपयोग उसी नाम के दृश्य को क्वेरी करके किया जाता है। अधिक जानकारी के लिए, आधिकारिक दस्तावेज देखें।
auto_explain के माध्यम से क्वेरी निष्पादन योजनाएं
auto_explain कोर पोस्टग्रेएसक्यूएल में मौजूद एक और एक्सटेंशन है। यह धीमे प्रश्नों की निष्पादन योजनाओं को लॉग कर सकता है। इसे केवलshared_preload_libraries . में जोड़ने की आवश्यकता है , और इसे एक एक्सटेंशन के रूप में स्थापित करने की आवश्यकता नहीं है। इसमें कुछ अन्य विकल्प भी हैं जिन्हें आम तौर पर गैर-डिफ़ॉल्ट मानों पर सेट करने की आवश्यकता होती है:
shared_preload_libraries = 'pg_stat_statements,auto_explain'
auto_explain.log_min_duration = 1s
auto_explain.log_analyze = on
auto_explain.log_buffers = on
auto_explain.log_triggers = on
auto_explain.log_timing = on
auto_explain.log_verbose = on
auto_explain.log_format = json
उपरोक्त किसी भी क्वेरी के लिए निष्पादन योजना को लॉग करता है जिसे पूरा करने में 1 सेकंड से अधिक समय लगता है। यहाँ एक नमूना आउटपुट है:
2021-01-30 11:28:25.977 UTC [64] psql postgres postgres 172.17.0.1 LOG: duration: 1.305 ms plan:
{
"Query Text": "SELECT n.nspname as \"Schema\",\n c.relname as \"Name\",\n CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' TH
EN 'sequence' WHEN 's' THEN 'special' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'table' WHEN 'I' THEN 'index' END as \"Type\",\n pg_catalog.pg_get_userbyid(c.relowner) as \"Owner\"\nFROM pg_catalog.pg_class c
\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\nWHERE c.relkind IN ('r','p','v','m','S','f','')\n AND n.nspname <> 'pg_catalog'\n AND n.nspname <> 'information_schema'\n AND
n.nspname !~ '^pg_toast'\n AND pg_catalog.pg_table_is_visible(c.oid)\nORDER BY 1,2;",
"Plan": {
"Node Type": "Sort",
"Parallel Aware": false,
"Startup Cost": 32.93,
"Total Cost": 33.01,
"Plan Rows": 32,
"Plan Width": 224,
"Actual Startup Time": 1.292,
"Actual Total Time": 1.298,
"Actual Rows": 0,
[... lots of text snipped ...]
auto_explain के बारे में अधिक जानने के लिए, आधिकारिक दस्तावेज़ देखें।
एक्सटेंशन pg_stat_statements और auto_explain क्वेरी प्रदर्शन प्रबंधन और क्वेरी योजना प्रबंधन के लिए PostgreSQL के पास केवल दो व्यापक रूप से समर्थित विकल्प हैं। इन दो विशेषताओं को जानने और उत्पादन में इनका उपयोग करने के लिए आगे की योजना बनाने के लिए यह भुगतान करता है।
आवेदन का नाम
एप्लिकेशन का नाम क्लाइंट-साइड पैरामीटर है, और आमतौर पर डीएसएन या libpq-शैली कनेक्शन स्ट्रिंग में सेट किया जा सकता है जो आपका एप्लिकेशन कनेक्शन जानकारी के लिए उपयोग करता है। पोस्टग्रेएसक्यूएल ईको सिस्टम में कई टूल और यूटिलिटीज एप्लिकेशन नाम को समझते हैं, और यह इसे एक सार्थक मूल्य पर सेट करने में मदद करता है, उदाहरण के लिए:
application_name = weekly-revenue-report
यह प्रत्येक क्लाइंट एप्लिकेशन के लिए सेट किया जाएगा जो आपके PostgreSQLserver से कनेक्ट होता है।