PostgreSQL యాంటీప్యాటర్న్‌లు: ట్రిగ్గర్‌ను దాటవేయడం ద్వారా డేటాను మార్చండి

ముందుగానే లేదా తరువాత, చాలా మంది టేబుల్ రికార్డులలో ఏదో ఒకదానిని భారీగా పరిష్కరించాల్సిన అవసరాన్ని ఎదుర్కొంటారు. నేను ఇప్పటికే దీన్ని ఎలా బాగా చేయాలో చెప్పండి, మరియు ఎలా - దీన్ని చేయకపోవడమే మంచిది. ఈ రోజు నేను మాస్ అప్‌డేట్ యొక్క రెండవ అంశం గురించి మాట్లాడతాను - ట్రిగ్గర్స్ గురించి.

ఉదాహరణకు, మీరు ఏదైనా పరిష్కరించాల్సిన టేబుల్‌పై, చెడు ట్రిగ్గర్ వేలాడుతోంది ON UPDATE, అన్ని మార్పులను కొన్ని కంకరలకు బదిలీ చేస్తుంది. మరియు మీరు అన్నింటినీ అప్‌డేట్ చేయాలి (ఉదాహరణకు, కొత్త ఫీల్డ్‌ని ప్రారంభించండి) కాబట్టి ఈ కంకరలు ప్రభావితం కావు.

ట్రిగ్గర్‌లను డిసేబుల్ చేద్దాం!

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
  UPDATE ...; -- тут долго-долго
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

నిజానికి, అంతే - ప్రతిదీ వేలాడుతోంది.

ఎందుకంటే ALTER TABLE విధిస్తుంది యాక్సెస్ ఎక్స్‌క్లూజివ్- ఎవరూ సమాంతరంగా అమలు చేయని లాక్, సాధారణమైనది కూడా SELECT, టేబుల్ నుండి ఏమీ చదవలేరు. అంటే, ఈ లావాదేవీ ముగిసే వరకు, "కేవలం చదవాలని" కోరుకునే ప్రతి ఒక్కరూ వేచి ఉంటారు. మరియు మేము దానిని గుర్తుంచుకుంటాము UPDATE మనకు చాలా కాలం ఉంది ...

దాన్ని త్వరగా ఆఫ్ చేద్దాం, ఆపై త్వరగా ఆన్ చేద్దాం!

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
COMMIT;

UPDATE ...;

BEGIN;
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

ఇక్కడ పరిస్థితి ఇప్పటికే మెరుగ్గా ఉంది, వేచి ఉండే సమయం చాలా తక్కువ. కానీ రెండు సమస్యలు మాత్రమే అందాన్ని పాడు చేస్తాయి:

  • ALTER TABLE పొడవైన వాటితో సహా టేబుల్‌పై ఉన్న అన్ని ఇతర కార్యకలాపాల కోసం కూడా వేచి ఉంటుంది SELECT
  • ట్రిగ్గర్ ఆఫ్‌లో ఉన్నప్పుడు ఏదైనా మార్పు "ఫ్లై బై" పట్టికలో, మాది కూడా కాదు. మరియు అది మొత్తాలలోకి రాదు, అయినప్పటికీ అది ఉండాలి. ఇబ్బంది!

సెషన్ వేరియబుల్స్ నిర్వహణ

కాబట్టి, మునుపటి సంస్కరణలో, మేము ఒక ప్రాథమిక పాయింట్‌పై పొరపాట్లు చేసాము - టేబుల్‌లోని “మా” మార్పులను “మాది కాదు” నుండి వేరు చేయడానికి మేము ట్రిగ్గర్‌ను ఎలాగైనా నేర్పించాలి. "మాది" స్కిప్ చేయబడింది, కానీ "మాది కాదు"లో అవి ట్రిగ్గర్ చేయబడతాయి. దీని కోసం మీరు ఉపయోగించవచ్చు సెషన్ వేరియబుల్స్.

సెషన్_రెప్లికేషన్_రోల్

చదవడానికి మాన్యువల్:

ట్రిగ్గర్ మెకానిజం కూడా కాన్ఫిగరేషన్ వేరియబుల్ ద్వారా ప్రభావితమవుతుంది సెషన్_రెప్లికేషన్_రోల్. అదనపు సూచనలు (డిఫాల్ట్) లేకుండా ప్రారంభించబడితే, ప్రతిరూపణ పాత్ర "మూలం" (డిఫాల్ట్) లేదా "స్థానికం" అయినప్పుడు ట్రిగ్గర్‌లు పని చేస్తాయి. పేర్కొనడం ద్వారా ట్రిగ్గర్‌లు ప్రారంభించబడ్డాయి ENABLE REPLICA, ఉంటే మాత్రమే పని చేస్తుంది ప్రస్తుత సెషన్ మోడ్ - "ప్రతిరూపం", మరియు ట్రిగ్గర్లు పేర్కొనడం ద్వారా ప్రారంభించబడ్డాయి ENABLE ALWAYS, ప్రస్తుత రెప్లికేషన్ మోడ్‌తో సంబంధం లేకుండా పని చేస్తుంది.

ఈ సెట్టింగ్ అందరికీ ఒకేసారి వర్తించదని నేను ప్రత్యేకంగా నొక్కిచెబుతున్నాను ALTER TABLE, కానీ మా ప్రత్యేక ప్రత్యేక కనెక్షన్‌కు మాత్రమే. మొత్తంగా, ఏ అప్లికేషన్ ట్రిగ్గర్స్ పని చేయని విధంగా:

SET session_replication_role = replica; -- выключили триггеры
UPDATE ...;
SET session_replication_role = DEFAULT; -- вернули в исходное состояние

ట్రిగ్గర్ లోపల పరిస్థితి

కానీ పై ఎంపిక అన్ని ట్రిగ్గర్‌లకు ఒకేసారి పని చేస్తుంది (లేదా మీరు డిసేబుల్ చేయకూడదనుకునే ట్రిగ్గర్‌లను ముందుగానే "ప్రత్యామ్నాయ" చేయాలి). మరియు మనకు అవసరమైతే ఒక నిర్దిష్ట ట్రిగ్గర్ "ఆపివేయి"?

ఇది మాకు సహాయం చేస్తుంది "యూజర్" సెషన్ వేరియబుల్:

పొడిగింపు పరామితి పేర్లు క్రింది విధంగా వ్రాయబడ్డాయి: పొడిగింపు పేరు తర్వాత ఒక డాట్ ఆపై పరామితి పేరు, SQLలోని పూర్తి ఆబ్జెక్ట్ పేర్లను పోలి ఉంటుంది. ఉదాహరణకు: plpgsql.variable_conflict.
తగిన పొడిగింపు మాడ్యూల్‌ను లోడ్ చేయని ప్రక్రియలలో సిస్టమ్ వెలుపల ఎంపికలను సెట్ చేయవచ్చు కాబట్టి, PostgreSQL అంగీకరిస్తుంది రెండు భాగాలతో ఏ పేర్లకైనా విలువలు.

ముందుగా, మేము ట్రిగ్గర్‌ను ఖరారు చేస్తాము, ఇలాంటివి:

BEGIN
    -- процессу конвертации можно делать все
    IF current_setting('mycfg.my_table_convert_process') = 'TRUE' THEN
        IF TG_OP IN ('INSERT', 'UPDATE') THEN
            RETURN NEW;
        ELSE
            RETURN OLD;
        END IF;
    END IF;
...

మార్గం ద్వారా, ఇది "లాభం కోసం", నిరోధించకుండా, ద్వారా చేయవచ్చు CREATE OR REPLACE ట్రిగ్గర్ ఫంక్షన్ కోసం. ఆపై ప్రత్యేక కనెక్షన్‌లో మేము "మా" వేరియబుల్‌ను కాక్ చేస్తాము:


SET mycfg.my_table_convert_process = 'TRUE';
UPDATE ...;
SET mycfg.my_table_convert_process = ''; -- вернули в исходное состояние

మీకు ఇతర మార్గాలు తెలుసా? వ్యాఖ్యలలో భాగస్వామ్యం చేయండి.

మూలం: www.habr.com

ఒక వ్యాఖ్యను జోడించండి