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 = ''; -- ╨▓╨╡╤А╨╜╤Г╨╗╨╕ ╨▓ ╨╕╤Б╤Е╨╛╨┤╨╜╨╛╨╡ ╤Б╨╛╤Б╤В╨╛╤П╨╜╨╕╨╡

рдЕрдиреНрдп рддрд░рд┐рдХрд╛рд╣рд░реВ рдерд╛рд╣рд╛ рдЫ? рдЯрд┐рдкреНрдкрдгреАрд╣рд░реВрдорд╛ рд╕рд╛рдЭрд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реНред

рд╕реНрд░реЛрдд: www.habr.com

DDoS рд╕реБрд░рдХреНрд╖рд╛, VPS VDS рд╕рд░реНрднрд░рд╣рд░реВ рднрдПрдХрд╛ рд╕рд╛рдЗрдЯрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рднрд░рдкрд░реНрджреЛ рд╣реЛрд╕реНрдЯрд┐рдЩ рдЦрд░рд┐рдж рдЧрд░реНрдиреБрд╣реЛрд╕реН ЁЯФе DDoS рд╕реБрд░рдХреНрд╖рд╛, VPS VDS рд╕рд░реНрднрд░рд╣рд░реВ рд╕рд╣рд┐рддрдХреЛ рднрд░рдкрд░реНрджреЛ рд╡реЗрдмрд╕рд╛рдЗрдЯ рд╣реЛрд╕реНрдЯрд┐рдЩ рдХрд┐рдиреНрдиреБрд╣реЛрд╕реН | ProHoster