PostgreSQL Antipatterns፡ ቀስቅሴን በማለፍ መረጃን ይቀይሩ

ይዋል ይደር እንጂ ብዙዎች በሰንጠረዥ መዛግብት ውስጥ የሆነ ነገር በከፍተኛ ሁኔታ የመጠገን አስፈላጊነት ይገጥማቸዋል። አስቀድሜ አለኝ እንዴት የተሻለ ማድረግ እንዳለብኝ ንገረኝ, እና እንዴት - ላለማድረግ የተሻለ ነው. ዛሬ ስለ የጅምላ ማሻሻያ ሁለተኛው ገጽታ እናገራለሁ - ስለ ቀስቅሴዎች.

ለምሳሌ, አንድ ነገር ማስተካከል በሚያስፈልግበት ጠረጴዛ ላይ, ክፉ ቀስቅሴ ተንጠልጥሏል 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 = ''; -- вернули в исходное состояние

ሌሎች መንገዶችን ታውቃለህ? በአስተያየቶቹ ውስጥ ያካፍሉ.

ምንጭ: hab.com

አስተያየት ያክሉ