Postgresql में रिकॉर्ड की अधिकतम संख्या रखना संभव है?


9

मूल रूप से हमारी Postgresql तालिका का हिस्सा सर्वर एक्सेस लॉग रखने के लिए उपयोग किया जाता है, और जैसे कभी-कभी उत्पादन के दौरान यह बहुत बड़ा हो सकता है। क्या पोस्टग्रैक्स्ल में सेट करने का कोई तरीका है, जिसमें एक मेज पर अधिकतम रिकॉर्ड हो सकता है और सबसे पुराना रिकॉर्ड बंद करने के लिए?

जवाबों:


12

आप अपनी इच्छित पंक्ति संख्या बनाए रखने के लिए ट्रिगर को परिभाषित कर सकते हैं:

CREATE OR REPLACE FUNCTION trf_keep_row_number_steady()
RETURNS TRIGGER AS
$body$
BEGIN
    -- delete only where are too many rows
    IF (SELECT count(id) FROM log_table) > rownum_limit
    THEN 
        -- I assume here that id is an auto-incremented value in log_table
        DELETE FROM log_table
        WHERE id = (SELECT min(id) FROM log_table);
    END IF;
END;
$body$
LANGUAGE plpgsql;

CREATE TRIGGER tr_keep_row_number_steady 
AFTER INSERT ON log_table
FOR EACH ROW EXECUTE PROCEDURE trf_keep_row_number_steady();

यह शायद सबसे अच्छा प्रदर्शन करने वाला विकल्प नहीं है, लेकिन एक बार जब आप सीमा तक पहुंच जाते हैं, तो यह कभी भी पार नहीं होगा। यदि उतार-चढ़ाव के लिए जगह है, तो आप समय-समय पर पंक्ति संख्या की जांच कर सकते हैं और शुरुआत से अतिरिक्त पंक्तियों को हटा सकते हैं।

संपादित करें: यदि आपके पास विभाजन की तुलना में वास्तव में बड़े लॉग (प्रति माह एक लाख कहते हैं)सबसे आसान समाधान हो सकता है। आप तब अनावश्यक तालिकाओं को छोड़ सकते हैं (जहां कहोmax(timestamp) < CURRENT_DATE - 1 year)। श्रेणी विभाजन के लिए आप अपने टाइमस्टैम्प (या व्युत्पन्न तिथि) का उपयोग कर सकते हैं।

लेकिन पुराने लॉग को छोड़ने से पहले सावधान रहें। क्या आप वाकई उन लोगों की आवश्यकता नहीं हैं?


हम समय-समय पर इसे निष्पादित कर सकते हैं, और हमें यकीन है कि हमें इसकी आवश्यकता होने के बाद एक बार मेज की आवश्यकता नहीं होने पर हम उन्हें ज़रूरत होगी, मैं बस यथासंभव डीबी रखरखाव को स्वचालित करने की कोशिश कर रहा हूं :)
झारवुड

मैं यह भी उम्मीद कर रहा था कि पोस्टग्रैड्स बता सकते हैं कि कौन सा खुद से बड़ा था, लेकिन अगर हमारे पास आईडी नहीं है, तो वह हमारी तारीख का उपयोग टाइमस्टैम्प क्षेत्र में बना सकता है "2012-06-22 17: 17: 52.692514"
झारवुड

@ झारवुड - ने मेरे उत्तर को संपादित किया। अगर आपको और जानकारी चाहिए तो कृपया मुझे बताएं।
dezso

2
विभाजन के सुझाव पर +1। यदि आप हर बार तालिका को स्कैन करने के चरम ओवरहेड के बिना एक गिनती के साथ जाना चाहते हैं, तो आप एक अंजीर के लिए pg_class.reltuples का उपयोग कर सकते हैं आप एक "नियंत्रण" तालिका में एक गिनती बनाए रखने के लिए ट्रिगर का उपयोग कर सकते हैं।
18

4

मैंने एक अधिक सामान्य, तालिका स्वतंत्र कार्य बनाया।

CREATE OR REPLACE FUNCTION keep_row_number_steady()
RETURNS TRIGGER AS
$body$
DECLARE
    tab text;
    keyfld text;
    nritems INTEGER;
    rnd DOUBLE PRECISION;
BEGIN
    tab := TG_ARGV[0];
    keyfld := TG_ARGV[1];
    nritems := TG_ARGV[2]; 
    rnd := TG_ARGV[3];

    IF random() < rnd
    THEN 
        EXECUTE(format('DELETE FROM %s WHERE %s < (SELECT %s FROM %s ORDER BY %s DESC LIMIT 1 OFFSET %s)', tab, keyfld, keyfld, tab, keyfld, nritems));
    END IF;
    RETURN NULL;
END;
$body$
LANGUAGE plpgsql;

CREATE TRIGGER log_table_keep_row_number_steady_trigger
AFTER INSERT ON log_table
FOR EACH STATEMENT EXECUTE PROCEDURE keep_row_number_steady('log_table', 'id', 1000, 0.1);

फ़ंक्शन 4 पैरामीटर लेता है:

  • टैब: टेबल का नाम
  • कीफल्ड: संख्यात्मक, प्रगतिशील कुंजी क्षेत्र
  • nritems: बनाए रखने के लिए मदों की संख्या
  • रैंड: यादृच्छिक संख्या, 0 से 1 तक; यह जितना बड़ा होगा, उतनी ही बार-बार तालिका साफ की जाएगी (0 = कभी नहीं, 1 = हमेशा, 0.1 = 10% बार)

इस तरह से आप एक ही फ़ंक्शन को कॉल करने के लिए कितने ट्रिगर बना सकते हैं।

उम्मीद है की यह मदद करेगा।


0

मैंने यह खरीद बनाई और पीजी एजेंट (या विंडोज़ जॉब या क्रॉन जॉब के आधार पर) से इसे चलाया। मेरे पास अधिक पंक्तियां हो सकती हैं, यह सिर्फ मेरी लॉग टेबल को बहुत बड़ा नहीं रखता है। ट्रिगर का उपरी भाग बचाता है।

CREATE or replace FUNCTION activitylogcleanup(_MaxRows int) RETURNS void
    LANGUAGE plpgsql
    AS $$
DECLARE
   minid    int;
BEGIN
    SELECT logid into minid FROM activitylogapplication 
     order by logid desc limit 1 OFFSET _MaxRows;

    if not found then 
        return;
    END IF; 

    Delete from activitylogapplication where logid < minid;
END;
$$;

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.