PostgreSQL ضد نمونې: د محرک په واسطه ډاټا بدل کړئ

ژر یا وروسته، ډیری خلک د جدول ریکارډونو کې په پراخه کچه د یو څه سمولو اړتیا سره مخ دي. زه لا دمخه لرم ما ته وویل چې دا څنګه ښه کولی شم، او څنګه - دا غوره ده چې دا ونه کړئ. نن به زه د ډله ایز تازه کولو دوهم اړخ په اړه وغږیږم - د محرکاتو په اړه.

د مثال په توګه، په میز کې چې تاسو اړتیا لرئ یو څه سم کړئ، یو بد محرک دی ON UPDATE, په ځینو مجموعو کې ټول بدلونونه لیږدول. او تاسو اړتیا لرئ هرڅه تازه کړئ (د مثال په توګه یو نوی ساحه پیل کړئ) په ډیر احتیاط سره چې دا واحدونه اغیزمن نشي.

راځئ چې یوازې محرکات بند کړو!

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

په حقیقت کې، دا ټول دي - هرڅه لا دمخه ځړول شوي دي.

ځکه ALTER TABLE لګوي Exclusive- یو قفل چې لاندې هیڅوک په موازي توګه نه چلیږي، حتی یو ساده 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

Add a comment