2014-04-16 15 views
7

में किसी विशेष तालिका पर TOAST काम कर रहा है या नहीं, मेरे पास एक तालिका है जिसमें दो टेक्स्ट फ़ील्ड हैं जिनमें बहुत अधिक टेक्स्ट है। किसी कारण से हमारी तालिका तेजी से बढ़ने लगी है। मुझे संदेह है कि टोस्ट (पोस्टग्रेज़ में टेक्स्ट फ़ील्ड के लिए संपीड़न) स्वचालित रूप से काम नहीं कर रहा है। हमारी तालिका परिभाषा में हमने इन क्षेत्रों के संपीड़न को मजबूर करने के लिए किसी भी खंड को परिभाषित नहीं किया है। क्या जांचने का कोई तरीका है कि उस तालिका पर संपीड़न काम कर रहा है या नहीं?पोस्टग्रेस

+0

क्या आप नियमित रूप से खाली हो रहे हैं? – SingleNegationElimination

+0

हाँ ऑटो वैक्यूम नियमित रूप से काम कर रहा है। लेकिन तालिका 5 दिनों में 80 जी से 165 जी तक फूट गई और फिर हमने पूर्ण वैक्यूम चलाया और तालिका का आकार केवल 1 9 जी तक कम हो गया। लेकिन फिर यह घातीय गति पर फूला हुआ हो रहा है। – jindal

उत्तर

7

From the docs। । ।

एक तालिका के कॉलम में से किसी टोस्ट सक्षम हैं, तो तालिका एक संबद्ध टोस्ट मेज, जिसका OID तालिका के pg_class.reltoastrelid प्रविष्टि में संग्रहीत किया जाता होगा। आउट ऑफ़ लाइन TOASTed मान TOAST तालिका में रखे गए हैं, जैसा कि नीचे विस्तार से बताया गया है।

तो आप यह निर्धारित कर सकते हैं कि pg_class system catalog से पूछताछ करके TOAST तालिका मौजूद है या नहीं। यह आपको जो कुछ ढूंढ रहा है उसके करीब ले जाना चाहिए।

select t1.oid, t1.relname, t1.relkind, t2.relkind, t2.relpages, t2.reltuples 
from pg_class t1 
inner join pg_class t2 
on t1.reltoastrelid = t2.oid 
where t1.relkind = 'r' 
    and t2.relkind = 't'; 

psql में, आप \d+ का उपयोग कर सकते हैं। मैं एक उदाहरण के रूप में pg_class सिस्टम कैटलॉग का उपयोग करूंगा; आप अपना खुद का टेबल नाम इस्तेमाल करेंगे।

sandbox=# \d+ pg_class 
    Column  | Type | Modifiers | Storage | Stats target | Description 
----------------+-----------+-----------+----------+--------------+------------- 
relname  | name  | not null | plain |    | 
relnamespace | oid  | not null | plain |    | 
[snip] 
relacl   | aclitem[] |   | extended |    | 
reloptions  | text[] |   | extended |    | 

कहाँ भंडारण 'विस्तारित' है, PostgreSQL लाइन से बाहर डेटा भंडारण के द्वारा तो पहले संपीड़ित करके पंक्ति आकार को कम करने, की कोशिश करेंगे। जहां संग्रहण 'मुख्य' है (दिखाया नहीं गया है), PostgreSQL संपीड़ित करने का प्रयास करेगा।

अपने विशेष मामले में, आपको समय के साथ आकार में परिवर्तनों की निगरानी करने में मदद मिल सकती है। आप इस क्वेरी का उपयोग कर सकते हैं, और परिणामों को बाद में विश्लेषण के लिए सहेज सकते हैं।

select table_catalog, table_schema, table_name, 
     pg_total_relation_size(table_catalog || '.' || table_schema|| '.' || table_name) as pg_total_relation_size, 
     pg_relation_size(table_catalog || '.' || table_schema|| '.' || table_name) as pg_relation_size, 
     pg_table_size(table_catalog || '.' || table_schema|| '.' || table_name) as pg_table_size 
from information_schema.tables 

PostgreSQL admin functions क्या प्रत्येक कार्य अपनी गणना में शामिल के बारे में विवरण है।

0

यदि रई टेबल को खाली करने से इसे 80 जीबी से 1 9 जीबी तक स्ट्रिप किया जाता है, तो आप जो काम कर रहे हैं वह एमवीसीसी काम पर है: मृत पंक्तियां खाली होने या फिर से उपयोग होने तक स्थान लेती हैं।

http://wiki.postgresql.org/wiki/MVCC

+0

यह प्रणाली लंबे समय से ठीक काम कर रही थी। अचानक यह मुद्दा हो रहा है। – jindal

+0

शायद आपके पास हाल ही में डीबी लिखने की असामान्य मात्रा थी? वैक्यूम और टोस्ट "काम करने" मेरे ज्ञान के सर्वोत्तम हैं, किसी भी तरह से सहसंबंधित नहीं हैं। और एकमात्र यथार्थवादी स्पष्टीकरण मैं डीबी आकार में पांच गुना वृद्धि के बारे में सोच सकता हूं, एमवीसीसी है और अभी तक मृत पंक्तियों को खाली कर दिया गया है जो पृष्ठ विभाजन के बाद चारों ओर झूठ बोल रहे हैं (तालिका बनाने/भरने के कारक पर पीजी दस्तावेज़ देखें)। –

+0

बस अगर यह पर्याप्त स्पष्ट नहीं था: मेरा मतलब यह है कि आप जो देख रहे हैं वह वास्तव में बी * सामान्य * हो सकता है: डीबी आकार को लंबे समय तक स्थिर (बार नई प्रविष्टियां) स्थिर करना चाहिए; आप जंगली झूलों को ध्यान में रखते हुए देख सकते हैं क्योंकि आपने वैक्यूम पूर्ण किया था और ऑपरेशन के कुछ दिनों या हफ्तों के बाद यार्ड स्टिक को स्थापित करने के बजाय वहां से निगरानी शुरू कर दी थी। –

0

यह पुराना है, लेकिन मुझे हाल ही में इसी तरह के मुद्दे के साथ कुछ सफलता मिली है। विश्लेषण VERBOSE ने खुलासा किया कि हमारी कुछ तालिकाएं प्रति टुपल डिस्क के 1 पृष्ठ तक बढ़ी हैं, और एक्स्पिन एनालिज ने खुलासा किया कि अनुक्रमिक स्कैन 27K पंक्तियों की तालिका में 30 सेकंड तक ले जा रहे थे। सक्रिय पंक्तियों की संख्या के अनुमान आगे और आगे हो रहे थे।

अधिक खोज के बाद, मैंने सीखा कि पंक्तियों को केवल तभी खाली किया जा सकता है जब कोई लेनदेन नहीं किया गया है, जिसे अपडेट किया गया था। इस तालिका को हर 3 मिनट में फिर से लिखा गया था, और एक कनेक्शन था जो "लेनदेन में निष्क्रिय" था जो 3 दिन पुराना था। आप गणित कर सकते हैं।

इस मामले में, हम

  1. पड़ा खुला लेन-देन
  2. पुनः कनेक्ट डेटाबेस के लिए के सिलसिले मार डालते हैं। दुर्भाग्यवश पंक्तियों के लिए अधिकतम लेनदेन आईडी जिसे वैक्यूम किया जा सकता है वर्तमान में (9.3 के रूप में) कनेक्शन में संग्रहीत है, इसलिए पूर्ण वैक्यूम काम नहीं करेगा।
  3. वैक्यूम अपनी तालिका को पूर्ण करें (यह एक एक्सेस विशेष लॉक लेगा, जो सबकुछ पढ़ने सहित सभी को अवरुद्ध कर देगा। आप वाक्यूम पूर्ण समय को तेज करने के लिए पहले VACUUM (गैर-अवरुद्ध) चला सकते हैं।

यह आपकी समस्या नहीं हो सकती है, लेकिन यदि आप देखना चाहते हैं कि आपके डेटाबेस में टेबल प्रभावित हैं, तो मैंने डिस्क के एक पृष्ठ में संग्रहीत टुपल्स की औसत संख्या से तालिकाओं को ऑर्डर करने के लिए एक क्वेरी लिखी है। बड़ी पंक्तियों वाले टेबल्स शीर्ष पर होना चाहिए - विश्लेषण वर्बोज़ आपको इन तालिकाओं में मृतकों के रहने के लिए मृतकों के अनुपात का विचार देना चाहिए। 9.3 के लिए मान्य - यह शायद अन्य संस्करणों के लिए कुछ मामूली बदलाव की आवश्यकता होगी:

SELECT rolname AS owner, 
     nspname AS schemaname 
    , relname AS tablename 
    , relpages, reltuples, (reltuples::FLOAT/relpages::FLOAT) AS tuples_per_page 
FROM pg_class 
JOIN pg_namespace ON relnamespace = pg_namespace.oid 
JOIN pg_roles  ON relowner  = pg_roles.oid 
WHERE relkind = 'r' AND relpages > 20 AND reltuples > 1000 
    AND nspname != 'pg_catalog' 
ORDER BY tuples_per_page; 
1

आप देख सकते हैं -E पैरामीटर के साथ यह शुरू, तो सामान्य आदेशों चलाकर क्या psql रन प्रश्नों:

इस में उदाहरण के लिए, एक है कि करने के लिए नीचे आया था, पहली देखने अपनी मेज के OID:

SELECT c.oid, 
    n.nspname, 
    c.relname 
FROM pg_catalog.pg_class c 
    LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace 
WHERE c.relname ~ '^(YOUR_TABLE_NAME_HERE)$' 
    AND pg_catalog.pg_table_is_visible(c.oid) 
ORDER BY 2, 3; 

तो यह कार्यान्वित इस इसके बारे में अधिक आँकड़े देखने के लिए:

+०१२३५१६४१०६
SELECT a.attname,                                   pg_catalog.format_type(a.atttypid, a.atttypmod), 
    (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128) 
    FROM pg_catalog.pg_attrdef d 
    WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef), 
    a.attnotnull, a.attnum, 
    (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t 
    WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation, 
    NULL AS indexdef, 
    NULL AS attfdwoptions, 
    a.attstorage, 
    CASE WHEN a.attstattarget=-1 THEN NULL ELSE a.attstattarget END AS attstattarget, pg_catalog.col_description(a.attrelid, a.attnum) 
FROM pg_catalog.pg_attribute a 
WHERE a.attrelid = '57692' AND a.attnum > 0 AND NOT a.attisdropped 
ORDER BY a.attnum; 

x.attrstorage क्या आपको p परवाह है, प्लेन है, x विस्तारित है I wager।