DBA: рдлреНрд▓рд╛рдЗрдВрдЧ рд▓реЙрдХ рдХреА рдЦреЛрдЬ рдореЗрдВ

рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ, рдЬрд╣рд╛рдБ рдореИрдВрдиреЗ PostgreSQL рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХреА рдереА , рд╡рд╣рд╛рдБ рдЗрд╕ рддрд░рд╣ рдХрд╛ рдПрдХ рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдерд╛:
рдмрдврд╝реЛ wait- рдЖрд╡реЗрджрди рдХрд┐рд╕реА рдХреЗ рддрд╛рд▓реЗ рдкрд░ "рдЖрд░рд╛рдо" рд╣реИ ред рдпрджрд┐ рдпрд╣ рдкрд┐рдЫрд▓реЗ рдПрдХ рд╕рдордп рдХреА рд╡рд┐рд╕рдВрдЧрддрд┐ рд╣реИ - рдореВрд▓ рдХрд╛рд░рдг рдХреЛ рд╕рдордЭрдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ред
рдпрд╣ рд╕реНрдерд┐рддрд┐ рдбреАрдмреАрдП рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдкреНрд░рд┐рдп рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ:

  • рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ, рдЖрдзрд╛рд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ
  • рдХреЛрдИ рд╕рд░реНрд╡рд░ рд╕рдВрд╕рд╛рдзрди рд╕рдорд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВ
  • ... рд▓реЗрдХрд┐рди рдХреБрдЫ рдЕрдиреБрд░реЛрдз "рдзреАрдорд╛"

"рдХреНрд╖рдг рдореЗрдВ" рддрд╛рд▓реЗ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдмрд╣реБрдд рдХрдо рд╣реИ, рдФрд░ рд╡реЗ рдХреЗрд╡рд▓ рдХреБрдЫ рд╕реЗрдХрдВрдб рддрдХ рд░рд╣ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрдиреБрд░реЛрдз рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХреЛ рджрд╕рд┐рдпреЛрдВ рдмрд╛рд░ рдЦрд░рд╛рдм рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдЖрдк рдмрд╕ рдмреИрдардирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдФрд░ рдСрдирд▓рд╛рдЗрди рдЬреЛ рд╣реЛ рд░рд╣рд╛ рд╣реИ рдЙрд╕реЗ рдкрдХрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╢рд╛рдВрдд рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреМрди рд╕реЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпрд╛ рд╕рдорд╕реНрдпрд╛ рд╣реИ - рдХреМрди, рдХрд┐рд╕рдХреЗ рд╕рд╛рде рдФрд░ рдХрд┐рд╕ рд╡рдЬрд╣ рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рдВрд╕рд╛рдзрди рд╕рдВрдШрд░реНрд╖ рдореЗрдВ рдЖрдПред

рдкрд░ рдХреИрд╕реЗ? рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕рдХреА рдпреЛрдЬрдирд╛ рдХреЗ рдЕрдиреБрд░реЛрдз рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЬреЛ рдЖрдкрдХреЛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╕рдордЭрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдЧрдпрд╛ рдФрд░ рдХрд┐рддрдирд╛ рд╕рдордп рд▓рдЧрд╛, рддрд╛рд▓рд╛ рдРрд╕реЗ рд╕реНрдкрд╖реНрдЯ рдирд┐рд╢рд╛рди рдирд╣реАрдВ рдЫреЛрдбрд╝рддрд╛ рд╣реИ ...

рдЬрдм рддрдХ рдХрд┐ рдПрдХ рд▓рдШреБ рдкреНрд░рд╡реЗрд╢ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдирд╣реАрдВ рд╣реИ: рд▓реЗрдХрд┐рди рдЪрд▓реЛ рдЗрд╕реЗ рдкрдХрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ!
process ... still waiting for ...


рд╣рдо рд▓реЙрдЧ рдореЗрдВ рд▓реЙрдХ рдХреЛ рдкрдХрдбрд╝рддреЗ рд╣реИрдВ


рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдХрдо рд╕реЗ рдХрдо рдЗрд╕ рд▓рд╛рдЗрди рдХреЗ рд▓реЙрдЧ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рд░реНрд╡рд░ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
log_lock_waits = 'on'
... рдФрд░ рд╣рдорд╛рд░реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдиреНрдпреВрдирддрдо рд╕реАрдорд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ:
deadlock_timeout = '100ms'

рдЬрдм рдкреИрд░рд╛рдореАрдЯрд░ рд╕рдХреНрд╖рдо рд╣реЛрддрд╛ рд╣реИ log_lock_waits, рддреЛ рдпрд╣ рдкреИрд░рд╛рдореАрдЯрд░ рдпрд╣ рднреА рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕ рд╕рдордп рдЕрд╡рд░реБрджреНрдз рд╣реЛрдиреЗ рдХреЗ рдЗрдВрддрдЬрд╛рд░ рдХреЗ рд╕рдВрджреЗрд╢ рд╕рд░реНрд╡рд░ рд▓реЙрдЧ рдореЗрдВ рд▓рд┐рдЦреЗ рдЬрд╛рдПрдВрдЧреЗред рдпрджрд┐ рдЖрдк рддрд╛рд▓реЗ рдХреЗ рдХрд╛рд░рдг рд╣реЛрдиреЗ рд╡рд╛рд▓реА рджреЗрд░реА рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рдореВрд▓реНрдп рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЗрд╕реЗ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ deadlock_timeoutред
рдЗрд╕ рд╕рдордп рдХреЗ рджреМрд░рд╛рди "рдЕрдирдЯреЗрд▓реА" рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рдЧрддрд┐рд░реЛрдзреЛрдВ рдХреЛ рдлрд╛рдбрд╝рд╛ рдирд╣реАрдВ рдЬрд╛рдПрдЧрд╛ред рдФрд░ рдпрд╣рд╛рдВ "рд╕рд╛рдорд╛рдиреНрдп" рддрд╛рд▓реЗ рд╣реИрдВ - рд▓реЙрдЧ рдореЗрдВ рдХрдИ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рдбрдВрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
2019-03-27 00:06:46.026 MSK [38162:84/166010018] [inside.tensor.ru] [local] csr-inside-bl10:10081: MergeRequest LOG: process 38162 still waiting for ExclusiveLock on advisory lock [225382138,225386226,141586103,2] after 100.047 ms

2019-03-27 00:06:46.026 MSK [38162:84/166010018] [inside.tensor.ru] [local] csr-inside-bl10:10081: MergeRequest DETAIL: Process holding the lock: 38154. Wait queue: 38162.

2019-03-27 00:06:46.026 MSK [38162:84/166010018] [inside.tensor.ru] [local] csr-inside-bl10:10081: MergeRequest CONTEXT: SQL statement "SELECT pg_advisory_xact_lock( '""'::regclass::oid::integer, 141586103::integer )"
PL/pgSQL function inline_code_block line 2 at PERFORM


2019-03-27 00:06:46.026 MSK [38162:84/166010018] [inside.tensor.ru] [local] csr-inside-bl10:10081: MergeRequest STATEMENT: DO $$ BEGIN
PERFORM pg_advisory_xact_lock( '""'::regclass::oid::integer, 141586103::integer );
EXCEPTION
WHEN query_canceled THEN RETURN;
END; $$;

тАж

2019-03-27 00:06:46.077 MSK [38162:84/166010018] [inside.tensor.ru] [local] csr-inside-bl10:10081: MergeRequest LOG: process 38162 acquired ExclusiveLock on advisory lock [225382138,225386226,141586103,2] after 150.741 ms
рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓реЙрдЧ рдХреЗ рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рдХреЗ рдХреНрд╖рдг рд╕реЗ рдХреЗрд╡рд▓ 50ms рд╣реА рдерд╛ ред рдХреЗрд╡рд▓ рдЗрд╕ рдЕрдВрддрд░рд╛рд▓ рдореЗрдВ рд╣рдо рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХрдо рд╕реЗ рдХрдо рдХреБрдЫ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЬрд┐рддрдиреА рддреЗрдЬреА рд╕реЗ рд╣рдо рдРрд╕рд╛ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИрдВ, рдЙрддрдиреЗ рд╣реА рдЕрдзрд┐рдХ рддрд╛рд▓реЗ рд╣рдо рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣рд╛рдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЬрд╛рдирдХрд╛рд░реА рдЙрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдкреАрдЖрдИрдбреА тАЛтАЛрд╣реИ рдЬреЛ рд▓реЙрдХ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реА рд╣реИред рдпрд╣ рдЗрд╕ рдкрд░ рд╣реИ рдХрд┐ рд╣рдо рд▓реЙрдЧ рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рдмреАрдЪ рдЬрд╛рдирдХрд╛рд░реА рдХреА рддреБрд▓рдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдПрдХ рд╡рд┐рд╢реЗрд╖ рддрд╛рд▓рд╛ рдХрд┐рддрдирд╛ рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рдерд╛ - рдЕрд░реНрдерд╛рдд, рдпрд╣ "рд▓рдЯрдХрд╛" рдХрдм рддрдХред

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдХреЗрд╡рд▓ рд╕рд╛рдордЧреНрд░реА LOGрд░рд┐рдХреЙрд░реНрдб рдкрд░ RegExp рдХреЗ рдПрдХ рдЬреЛрдбрд╝реЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ :

const RE_lock_detect = /^process (\d+) still waiting for (.*) on (.*) after (\d+\.\d{3}) ms(?: at character \d+)?$/; //    
const RE_lock_acquire = /^process (\d+) acquired (.*) on (.*) after (\d+\.\d{3}) ms(?: at character \d+)?$/; //   

рд╣рдо рд▓реЙрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд┐рд▓рддрд╛ рд╣реИ


рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдереЛрдбрд╝рд╛ рд░рд╣рддрд╛ рд╣реИ - рд▓реЙрдЧ рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рдирд╛ рдФрд░ рддрджрдиреБрд╕рд╛рд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рдирд╛ рд╕реАрдЦреЗрдВред

рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдм рдХреБрдЫ рд╣реИ - рдПрдХ рдСрдирд▓рд╛рдЗрди рд▓реЙрдЧ рдкрд╛рд░реНрд╕рд░ рдФрд░ рдПрдХ рдкреВрд░реНрд╡-рд╕рдХреНрд░рд┐рдп рдбреЗрдЯрд╛рдмреЗрд╕ рдХрдиреЗрдХреНрд╢рди, рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдХреНрдпреВрдПрд▓ рдореЙрдирд┐рдЯрд░рд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд▓реЗрдЦ рдореЗрдВ рдмрд╛рдд рдХреА рдереА :


рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХреЛрдИ рд╕рдорд╛рди рд╕рд┐рд╕реНрдЯрдо рддреИрдирд╛рдд рдирд╣реАрдВ рд╣реИ, рддреЛ рдпрд╣ рдареАрдХ рд╣реИ, рд╣рдо рд╕рдм рдХреБрдЫ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред "рдХрдВрд╕реЛрд▓ рд╕реЗ рд░рд╛рдЗрдЯ"!

рдпрджрд┐ PostgreSQL 10 рдФрд░ рдЙрдЪреНрдЪрддрд░ рдХрд╛ рд╕реНрдерд╛рдкрд┐рдд рд╕рдВрд╕реНрдХрд░рдг рднрд╛рдЧреНрдпрд╢рд╛рд▓реА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдлрд╝рдВрдХреНрд╢рди pg_current_logfile () рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ , рдЬреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд░реНрддрдорд╛рди рд▓реЙрдЧ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдирд╛рдо рджреЗрддрд╛ рд╣реИред рдХрдВрд╕реЛрд▓ рд╕реЗ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдХрд╛рдлреА рдЖрд╕рд╛рди рд╣реЛрдЧрд╛:

psql -U postgres postgres -t -A -c "SELECT CASE WHEN substr(current_setting('log_directory'), 1, 1) <> '/' THEN current_setting('data_directory') ELSE '' END || '/' || pg_current_logfile()"

рдпрджрд┐ рд╕рдВрд╕реНрдХрд░рдг рдЕрдЪрд╛рдирдХ рдЫреЛрдЯрд╛ рд╣реИ - рд╕рдм рдХреБрдЫ рдмрд╛рд╣рд░ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓:

ps uw -U postgres \
  | grep [l]ogger \
  | awk '{print "/proc/"$2"/fd"}' \
  | xargs ls -l \
  | grep `cd; psql -U postgres postgres -t -A -c "SELECT CASE WHEN substr(current_setting('log_directory'), 1, 1) = '/' THEN current_setting('log_directory') ELSE current_setting('data_directory') || '/' || current_setting('log_directory') END"` \
  | awk '{print $NF}'

рд╣рдореЗрдВ рдкреВрд░реНрдг рдлрд╝рд╛рдЗрд▓ рдирд╛рдо tail -fрдорд┐рд▓рддрд╛ рд╣реИ , рдЬрд┐рд╕реЗ рд╣рдо рджреЗрддреЗ рд╣реИрдВ рдФрд░ рд╡рд╣рд╛рдВ рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЛ рдкрдХрдбрд╝реЗрдВрдЧреЗ 'still waiting for'ред

рдЦреИрд░, рдЬреИрд╕реЗ рд╣реА рдЗрд╕ рдзрд╛рдЧреЗ рдореЗрдВ рдХреБрдЫ рдЙрддреНрдкрдиреНрди рд╣реБрдЖ, рд╣рдо рдХрд╣рддреЗ рд╣реИрдВ ...

рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдЕрдиреБрд░реЛрдз


рдХрд╛рд╢, рд▓реЙрдЧ рдореЗрдВ рдЕрд╡рд░реБрджреНрдз рдХрд░рдиреЗ рдХрд╛ рдЙрджреНрджреЗрд╢реНрдп рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рд╣рдореЗрд╢рд╛ рд╕рдВрд╕рд╛рдзрди рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рд╕рдВрдШрд░реНрд╖ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рд╕рдорд╛рдирд╛рдВрддрд░ рдореЗрдВ рд╕рдорд╛рди рдирд╛рдо рдХрд╛ рдПрдХ рдЗрдВрдбреЗрдХреНрд╕ рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд▓реЙрдЧ рдореЗрдВ рдХреЗрд╡рд▓ рдХреБрдЫ рдРрд╕рд╛ рд╣реА рд╣реЛрдЧрд╛ still waiting for ExclusiveLock on transaction 12345ред

рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрдкрдиреА рд░реБрдЪрд┐ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд╕рднреА рддрд╛рд▓реЛрдВ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рджреВрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ ред рдФрд░ рдХреЗрд╡рд▓ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА (рдЬреЛ рддрд╛рд▓рд╛ рд▓рдЧрд╛рддрд╛ рд╣реИ / рдЬреЛ рдЙрдореНрдореАрдж рдХрд░рддрд╛ рд╣реИ) рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдХреНрд╕рд░ рд▓реЗрдирджреЗрди рдХреЗ рдмреАрдЪ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдЕрдкреЗрдХреНрд╖рд╛рдУрдВ рдХреА рдПрдХ "рд╢реНрд░реГрдВрдЦрд▓рд╛" рд╣реЛрддреА рд╣реИ:

tx1 [resA] -> tx2 [resA]
tx2 [resB] -> tx3 [resB]
...

рдХреНрд▓рд╛рд╕рд┐рдХ: "рд╢рд▓рдЬрдо рдХреЗ рд▓рд┐рдП рджрд╛рджрд╛, рджрд╛рджрд╛ рдХреЗ рд▓рд┐рдП рджрд╛рджреА, рджрд╛рджреА рдХреЗ рд▓рд┐рдП рдкреЛрддреА, ..."

рдЗрд╕рд▓рд┐рдП, рд╣рдо рдПрдХ рдЕрдиреБрд░реЛрдз рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рд╣рдореЗрдВ рдмрддрд╛рдПрдЧрд╛ рдХрд┐ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдПрд╕рдЖрдИрдбреА рдХреЗ рд▓рд┐рдП рдкреВрд░реА рдЕрд╡рд░реБрджреНрдз рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд╕рд╛рде рдореБрд╕реАрдмрддреЛрдВ рдХрд╛ рдореВрд▓ рдХрд╛рд░рдг рдХреМрди рдмрди рдЧрдпрд╛ред

WITH RECURSIVE lm AS (
-- lock modes
  SELECT
    rn
  , CASE
      WHEN lm <> 'Share' THEN row_number() OVER(PARTITION BY lm <> 'Share' ORDER BY rn)
    END rx
  , lm || 'Lock' lm
  FROM (
    SELECT
      row_number() OVER() rn
    , lm
    FROM
      unnest(
        ARRAY[
          'AccessShare'
        , 'RowShare'
        , 'RowExclusive'
        , 'ShareUpdateExclusive'
        , 'Share'
        , 'ShareRowExclusive'
        , 'Exclusive'
        , 'AccessExclusive'
        ]
      ) T(lm)
  ) T
)
-- lock types
, lt AS (
  SELECT
    row_number() OVER() rn
  , lt
  FROM
    unnest(
      ARRAY[
        'relation'
      , 'extend'
      , 'page'
      , 'tuple'
      , 'transactionid'
      , 'virtualxid'
      , 'object'
      , 'userlock'
      , 'advisory'
      , ''
      ]
    ) T(lt)
)
-- lock modes conflicts
, lmx AS (
  SELECT
    lr.rn lrn
  , lr.rx lrx
  , lr.lm lr
  , ld.rn ldn
  , ld.rx ldx
  , ld.lm ld
  FROM
    lm lr
  JOIN
    lm ld ON
      ld.rx > (SELECT max(rx) FROM lm) - lr.rx OR
      (
        (lr.rx = ld.rx) IS NULL AND
        (lr.rx, ld.rx) IS DISTINCT FROM (NULL, NULL) AND
        ld.rn >= (SELECT max(rn) FROM lm) - lr.rn
      )
)
-- locked targets/pids
, lcx AS (
  SELECT DISTINCT
    (lr.locktype, lr.database, lr.relation, lr.page, lr.tuple, lr.virtualxid, lr.transactionid::text::bigint, lr.classid, lr.objid, lr.objsubid) target
  , ld.pid  ldp
  , ld.mode ldm
  , lr.pid  lrp
  , lr.mode lrm
  FROM
    pg_locks ld
  JOIN
    pg_locks lr ON
      lr.pid <> ld.pid AND
      (lr.locktype, lr.database, lr.relation, lr.page, lr.tuple, lr.virtualxid, lr.transactionid::text::bigint, lr.classid, lr.objid, lr.objsubid) IS NOT DISTINCT FROM (ld.locktype, ld.database, ld.relation, ld.page, ld.tuple, ld.virtualxid, ld.transactionid::text::bigint, ld.classid, ld.objid, ld.objsubid) AND
      (lr.granted, ld.granted) = (TRUE, FALSE)
  JOIN
    lmx ON
      (lmx.lr, lmx.ld) = (lr.mode, ld.mode)
  WHERE
    (ld.pid, ld.granted) = ($1::integer, FALSE) -- PID
)
SELECT
  lc.locktype "type"
, CASE lc.locktype
    WHEN 'relation'      THEN ARRAY[relation::text]
    WHEN 'extend'        THEN ARRAY[relation::text]
    WHEN 'page'          THEN ARRAY[relation, page]::text[]
    WHEN 'tuple'         THEN ARRAY[relation, page, tuple]::text[]
    WHEN 'transactionid' THEN ARRAY[transactionid::text]
    WHEN 'virtualxid'    THEN regexp_split_to_array(virtualxid::text, '/')
    WHEN 'object'        THEN ARRAY[classid, objid, objsubid]::text[]
    WHEN 'userlock'      THEN ARRAY[classid::text]
    WHEN 'advisory'      THEN ARRAY[classid, objid, objsubid]::text[]
  END target
, lc.pid = lcx.ldp "locked"
, lc.pid
, regexp_replace(lc.mode, 'Lock$', '') "mode"
, lc.granted
, (lc.locktype, lc.database, lc.relation, lc.page, lc.tuple, lc.virtualxid, lc.transactionid::text::bigint, lc.classid, lc.objid, lc.objsubid) IS NOT DISTINCT FROM lcx.target "conflict"
FROM
  lcx
JOIN
  pg_locks lc ON
    lc.pid IN (lcx.ldp, lcx.lrp);

рд╕рдорд╕реНрдпрд╛ # 1 - рдзреАрдореА рд╢реБрд░реБрдЖрдд


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рд▓реЙрдЧ рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдПрдХ рд▓реЙрдХ ( LOG) рдХреА рдШрдЯрдирд╛ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓реА рд░реЗрдЦрд╛ рдХреЗ рдмрдЧрд▓ рдореЗрдВ , 3 рдФрд░ рд▓рд╛рдЗрдиреЗрдВ ( DETAIL, CONTEXT, STATEMENT) рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдЬрд╛рдирдХрд╛рд░реА рдХреА рд░рд┐рдкреЛрд░реНрдЯрд┐рдВрдЧ рдХрд░ рд░рд╣реА рд╣реИрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдордиреЗ рд╕рднреА 4 рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЗ рдкреВрд░реНрдг "рдкреИрдХреЗрдЬ" рдХреЗ рдЧрдарди рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд┐рдпрд╛ рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рд╣рдордиреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рд░реБрдЦ рдХрд┐рдпрд╛ред рд▓реЗрдХрд┐рди рд╣рдо рдкреИрдХреЗрдЬ рдХреЗ рдЧрдарди рдХреЛ рдХреЗрд╡рд▓ рддрднреА рдкреВрд░рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рдЕрдЧрд▓рд╛ (рдкрд╣рд▓реЗ рд╕реЗ рд╣реА 5 рд╡рд╛рдВ!) рд░рд┐рдХреЙрд░реНрдб рдЖрддрд╛ рд╣реИ, рдПрдХ рдЕрдиреНрдп рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде, рдпрд╛ рдЯрд╛рдЗрдордЖрдЙрдЯ рдХреЗ рд╕рд╛рдеред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рджреЛрдиреЛрдВ рд╡рд┐рдХрд▓реНрдк рдЕрдирд╛рд╡рд╢реНрдпрдХ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХреЛ рдЙрддреНрддреЗрдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВред

рдЗрди рджреЗрд░реА рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рд▓реЙрдХ рд░рд┐рдХреЙрд░реНрдб рдХреА рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЛ рд╕реНрдЯреНрд░реАрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рд┐рдЪ рдХрд┐рдпрд╛ ред рдпрд╣реА рд╣реИ, рдЕрдм рд╣рдо рд▓рдХреНрд╖реНрдп рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЬрд╛рддреЗ рд╣реИрдВ рдЬреИрд╕реЗ рд╣реА рд╣рдордиреЗ рдкрд╣рд▓рд╛ рд░рд┐рдХреЙрд░реНрдб рд╕реЙрд░реНрдЯ рдХрд┐рдпрд╛, рдФрд░ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ рдпрд╣ рд╡рд╣рд╛рдВ рд╡рд░реНрдгрд┐рдд рд▓реЙрдХ рдерд╛ред

рд╕рдорд╕реНрдпрд╛ # 2 - рдзреАрдореА рдЧрддрд┐ рд╕реЗ рдЕрдиреБрд░реЛрдз


рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рдХреБрдЫ рддрд╛рд▓реЛрдВ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рдирд╣реАрдВ рдерд╛ред рдЙрдиреНрд╣реЛрдВрдиреЗ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЦреБрджрд╛рдИ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ - рдФрд░ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдХреБрдЫ рд╕рд░реНрд╡рд░реЛрдВ рдкрд░ рд╣рдорд╛рд░реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдЕрдиреБрд░реЛрдз рдХреЛ 15-20ms рдХреЗ рд▓рд┐рдП рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ !

рдХрд╛рд░рдг рдЖрдо рд╣реЛ рдЧрдпрд╛ - рдЖрдзрд╛рд░ рдкрд░ рд╕рдХреНрд░рд┐рдп рддрд╛рд▓реЗ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛, рдХрдИ рд╣рдЬрд╛рд░ рддрдХ рдкрд╣реБрдВрдЪ рдЧрдИ:



pg_locks


рдпрд╣рд╛рдВ рдпрд╣ рдзреНрдпрд╛рди рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ PostgreSQL рдореЗрдВ рддрд╛рд▓реЗ рдХрд╣реАрдВ рднреА "рд╕рдВрдЧреНрд░рд╣реАрдд" рдирд╣реАрдВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рд╕рд┐рд╕реНрдЯрдо рд╡реНрдпреВ pg_locks рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ , рдЬреЛ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдкреНрд░рддреНрдпрдХреНрд╖ рдкреНрд░рддрд┐рдмрд┐рдВрдм рд╣реИ pg_lock_statusред рдФрд░ рд╣рдорд╛рд░реЗ рдЕрдиреБрд░реЛрдз рдореЗрдВ рд╣рдо рдЗрд╕реЗ рддреАрди рдмрд╛рд░ рд╕реЗ рдкрдврд╝рддреЗ рд╣реИрдВ ! рдЗрд╕ рдмреАрдЪ, рд╣рдо рдЗрди рд╣рдЬрд╛рд░реЛрдВ рд▓реЙрдХ рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХреЛ рдкрдврд╝рддреЗ рд╣реИрдВ, рдФрд░ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ рдЬреЛ рд╣рдорд╛рд░реЗ рдкреАрдЖрдИрдбреА тАЛтАЛрд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рд▓реЙрдХ рд╣реА "рд╣рд▓" рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗ ...

рд╕рдорд╛рдзрд╛рди рд╕реАрдЯреАрдИ рдореЗрдВ pg_locks рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ "рднреМрддрд┐рдХ" рдХрд░рдирд╛ рдерд╛ - рдЗрд╕рдХреЗ рдмрд╛рдж, рдЖрдк рдЗрд╕реЗ рдЬрд┐рддрдиреА рдмрд╛рд░ рдЪрд╛рд╣реЗрдВ рдЙрддрдиреА рдмрд╛рд░ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣реИред рдирд╣реАрдВ рдмрджрд▓рддрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдкрд░ рдмреИрдардиреЗ рдХреЗ рдмрд╛рдж, рдЗрд╕рдХреЗ рджреЛ рд╕реНрдХреИрди рддрдХ рд╕рдм рдХреБрдЫ рдХрдо рдХрд░рдирд╛ рд╕рдВрднрд╡ рдерд╛ред

рдЕрддреНрдпрдзрд┐рдХ рдЧрддрд┐рд╢реАрд▓рддрд╛


рдФрд░ рдЕрдЧрд░ рдКрдкрд░ рдХреА рдХреНрд╡реЗрд░реА рдХреЛ рдереЛрдбрд╝рд╛ рдХрд░реАрдм рд╕реЗ рджреЗрдЦреЗрдВ, рддреЛ рд╣рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕реАрдЯреАрдИ lmрдФрд░ lmxрдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдбреЗрдЯрд╛ рд╕реЗ рдмрдВрдзрд╛ рд╣реБрдЖ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдореЛрдб рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░рдиреЗ рдХреЗ рдмреАрдЪ рд╕рдВрдШрд░реНрд╖ рдХреА рд╣рдореЗрд╢рд╛ рд╕рдорд╛рди "рд╕реНрдерд┐рд░" рдореИрдЯреНрд░рд┐рдХреНрд╕ рдкрд░рд┐рднрд╛рд╖рд╛ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ ред рддреЛ рдЪрд▓рд┐рдП рдЗрд╕реЗ рдЧреБрдгрд╡рддреНрддрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ VALUESред

рд╕рдорд╕реНрдпрд╛ # 3 - рдкрдбрд╝реЛрд╕реА


рд▓реЗрдХрд┐рди рддрд╛рд▓реЛрдВ рдХрд╛ рдХреБрдЫ рд╣рд┐рд╕реНрд╕рд╛ рдЕрднреА рднреА рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЖрдорддреМрд░ рдкрд░ рдпрд╣ рдирд┐рдореНрди рдпреЛрдЬрдирд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╣реЛрддрд╛ рд╣реИ - рдХрд┐рд╕реА рдиреЗ рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп рд╕рдВрд╕рд╛рдзрди рдХреЛ рдЕрд╡рд░реБрджреНрдз рдХрд░ рджрд┐рдпрд╛, рдФрд░ рдХрдИ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдПрдВ рдЬрд▓реНрджреА рдФрд░ рдЬрд▓реНрджреА рд╕реЗ рдЗрд╕рдореЗрдВ рдпрд╛ рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдмрдврд╝реАрдВ ред

рдирддреАрдЬрддрди, рд╣рдордиреЗ рдкрд╣рд▓реЗ рдкреАрдЖрдИрдбреА тАЛтАЛрдХреЛ рдкрдХрдбрд╝рд╛, рд▓рдХреНрд╖реНрдп рдмреЗрд╕ рдкрд░ рдЧрдпрд╛ (рдФрд░ рдЗрд╕реЗ рдЕрдзрд┐рднрд╛рд░ рдирд╣реАрдВ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рдХрдиреЗрдХреНрд╢рди рд░рдЦрддреЗ рд╣реИрдВ), рдХреНрдпрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд┐рдпрд╛, рдкрд░рд┐рдгрд╛рдо рдХреЗ рд╕рд╛рде рд▓реМрдЯрд╛, рдЕрдЧрд▓рд╛ рдкреАрдЖрдИрдбреА тАЛтАЛрд▓реЗ рд▓рд┐рдпрд╛ ... рд▓реЗрдХрд┐рди рдЖрдзрд╛рд░ рдкрд░ рдЬреАрд╡рди рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рдирд╣реАрдВ рд╣реИ, рдФрд░ рдкреАрдЖрдИрдбреА тАЛтАЛрд▓реЙрдХ # 2 рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЪрд▓рд╛ рдЧрдпрд╛ рд╣реИ!

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдкреАрдЖрдИрдбреА тАЛтАЛрдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ, рдЕрдЧрд░ рд╣рдо рдЕрднреА рднреА рдЕрдиреБрд░реЛрдз рдореЗрдВ рд╕рд╛рдорд╛рдиреНрдп рд╕реВрдЪреА рд╕реЗ рддрд╛рд▓реЗ рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рддреЗ рд╣реИрдВ? рдЖрдЗрдП рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рд╕реАрдзреЗ рдкрд░рд╕реНрдкрд░ рд╡рд┐рд░реЛрдзреА рдкреНрд░рдХреНрд░рд┐рдпрд╛рдУрдВ рдХреА рдкреВрд░реА рд╕реВрдЪреА рдХреЛ рддреБрд░рдВрдд рд▓реЗ рд▓реЗрдВ рдФрд░ рдЕрдиреБрд░реЛрдз рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рджреМрд░рд╛рди рдЧрд┐рд░рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдкреАрдЖрдИрдбреА тАЛтАЛрдкрд░ рдЕрдкрдиреЗ рддрд╛рд▓реЗ рд╡рд┐рддрд░рд┐рдд рдХрд░реЗрдВ:

WITH lm(ld, lr) AS (
  VALUES
    ('AccessShareLock', '{AccessExclusiveLock}'::text[])
  , ('RowShareLock', '{ExclusiveLock,AccessExclusiveLock}'::text[])
  , ('RowExclusiveLock', '{ShareLock,ShareRowExclusiveLock,ExclusiveLock,AccessExclusiveLock}'::text[])
  , ('ShareUpdateExclusiveLock', '{ShareUpdateExclusiveLock,ShareLock,ShareRowExclusiveLock,ExclusiveLock,AccessExclusiveLock}'::text[])
  , ('ShareLock', '{RowExclusiveLock,ShareUpdateExclusiveLock,ShareRowExclusiveLock,ExclusiveLock,AccessExclusiveLock}'::text[])
  , ('ShareRowExclusiveLock', '{RowExclusiveLock,ShareUpdateExclusiveLock,ShareLock,ShareRowExclusiveLock,ExclusiveLock,AccessExclusiveLock}'::text[])
  , ('ExclusiveLock', '{RowShareLock,RowExclusiveLock,ShareUpdateExclusiveLock,ShareLock,ShareRowExclusiveLock,ExclusiveLock,AccessExclusiveLock}'::text[])
  , ('AccessExclusiveLock', '{AccessShareLock,RowShareLock,RowExclusiveLock,ShareUpdateExclusiveLock,ShareLock,ShareRowExclusiveLock,ExclusiveLock,AccessExclusiveLock}'::text[])
)
, locks AS (
  SELECT
    (
      locktype
    , database
    , relation
    , page
    , tuple
    , virtualxid
    , transactionid::text::bigint
    , classid
    , objid
    , objsubid
    ) target
  , *
  FROM
    pg_locks
)
, ld AS (
  SELECT
    *
  FROM
    locks
  WHERE
    NOT granted
)
, lr AS (
  SELECT
    *
  FROM
    locks
  WHERE
    target::text = ANY(ARRAY(
      SELECT DISTINCT
        target::text
      FROM
        ld
    )) AND
    granted
)
, lcx AS (
  SELECT DISTINCT
    lr.target
  , ld.pid ldp
  , ld.mode ldm
  , lr.pid lrp
  , lr.mode lrm
  FROM
    ld
  JOIN
    lr
      ON lr.pid <> ld.pid AND
        lr.target IS NOT DISTINCT FROM ld.target
)
SELECT
  lc.locktype "type"
, CASE lc.locktype
    WHEN 'relation' THEN
      ARRAY[relation::text]
    WHEN 'extend' THEN
      ARRAY[relation::text]
    WHEN 'page' THEN
      ARRAY[relation, page]::text[]
    WHEN 'tuple' THEN
      ARRAY[relation, page, tuple]::text[]
    WHEN 'transactionid' THEN
      ARRAY[transactionid::text]
    WHEN 'virtualxid' THEN
      regexp_split_to_array(virtualxid::text, '/')
    WHEN 'object' THEN
      ARRAY[classid, objid, objsubid]::text[]
    WHEN 'userlock' THEN
      ARRAY[classid::text]
    WHEN 'advisory' THEN
      ARRAY[classid, objid, objsubid]::text[]
  END target
, lc.pid = lcx.ldp as locked
, lc.pid
, regexp_replace(lc.mode, 'Lock$', '') "mode"
, lc.granted
, lc.target IS NOT DISTINCT FROM lcx.target as conflict
FROM
  lcx
JOIN
  locks lc
    ON lc.pid IN (lcx.ldp, lcx.lrp);

рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд▓реЙрдЧ рдореЗрдВ рдЖрдиреЗ рдХреЗ рдмрд╛рдж рдХреЗрд╡рд▓ 1-2 рдПрдордПрд╕ рдореЗрдВ рдореМрдЬреВрдж рддрд╛рд▓реЗ рдХрд╛ рднреА рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ ред

рдЗрд╕рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВ


рджрд░рдЕрд╕рд▓, рд╣рдордиреЗ рдЗрддрдиреА рд▓рдВрдмреА рдХреЛрд╢рд┐рд╢ рдХреНрдпреЛрдВ рдХреА? рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рд╣рдореЗрдВ рдХреНрдпрд╛ рдорд┐рд▓рддрд╛ рд╣реИ?

type     | target                  | locked | pid    | mode        | granted | conflict
---------------------------------------------------------------------------------------
relation | {225388639}             | f      | 216547 | AccessShare | t       | f
relation | {423576026}             | f      | 216547 | AccessShare | t       | f
advisory | {225386226,194303167,2} | t      |  24964 | Exclusive   | f       | t
relation | {341894815}             | t      |  24964 | AccessShare | t       | f
relation | {416441672}             | f      | 216547 | AccessShare | t       | f
relation | {225964322}             | f      | 216547 | AccessShare | t       | f
...

рдЗрд╕ рдкреНрд▓реЗрдЯ рдореЗрдВ, targetрдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рди рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИрдВ relation, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдРрд╕рд╛ рдорд╛рди рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдпрд╛ рд╕реВрдЪрдХрд╛рдВрдХ рдХрд╛ рдПрдХ OID рд╣реИ ред рдЕрдм рдмрд╣реБрдд рдХрдо рдмрдЪрд╛ рд╣реИ - рдорд╛рдирд╡-рдкрдардиреАрдп рд░реВрдк рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЕрднреА рднреА рдЕрдЬреНрдЮрд╛рдд рдУрдЖрдИрдбреА рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдкреВрдЫрддрд╛рдЫ рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП:

SELECT $1::oid::regclass;

рдЕрдм, рддрд╛рд▓реЗ рдХреЗ рд╕рднреА "рдореИрдЯреНрд░рд┐рдХреНрд╕" рдФрд░ рдЙрди рд╕рднреА рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдЬрд╛рдирдирд╛, рдЬрд┐рди рдкрд░ рд╡реЗ рд▓реЗрдирджреЗрди рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рджреНрд╡рд╛рд░рд╛ рдЖрд░реЛрдкрд┐рдд рдереЗ, рд╣рдо рдирд┐рд╖реНрдХрд░реНрд╖ рдирд┐рдХрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ "рдХреНрдпрд╛ рд╣реБрдЖ" , рдФрд░ рдХрд┐рд╕ рд╕рдВрд╕рд╛рдзрди рдиреЗ рд╕рдВрдШрд░реНрд╖ рдХреЛ рд░реЛрдХ рджрд┐рдпрд╛, рднрд▓реЗ рд╣реА рдЕрдиреБрд░реЛрдз рдЕрд╡рд░реБрджреНрдз рд╣реЛ рдЧрдпрд╛ рд╣реЛ, рд╣рдо рдЕрдЬреНрдЮрд╛рдд рдереЗред рдпрд╣ рдЖрд╕рд╛рдиреА рд╕реЗ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рд▓реЙрдЧ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд╡рд░реБрджреНрдз рдЕрдиреБрд░реЛрдз рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХрд╛рдлреА рд▓рдВрдмрд╛ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд▓реЗрдирджреЗрди рдЗрд╕рдХреЗ рдкреВрд░рд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рд╕рдХреНрд░рд┐рдп рдерд╛ рдФрд░ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рд╕рдорд╕реНрдпрд╛рдПрдВ рдкреИрджрд╛ рдХрд░рддрд╛ рдерд╛ред



рд▓реЗрдХрд┐рди рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ - рдПрдХ рдЕрдиреНрдп рд▓реЗрдЦ рдореЗрдВред

"рд╕рдм рдЕрдкрдиреЗ рдЖрдк рд╕реЗ"


рдЗрд╕ рдмреАрдЪ, рд╣рдо "рдирд┐рдЧрд░рд╛рдиреА" рдХрд╛ рдкреВрд░рд╛ рд╕рдВрд╕реНрдХрд░рдг рдПрдХрддреНрд░ рдХрд░реЗрдВрдЧреЗ, рдЬреЛ рд▓реЙрдЧ рдореЗрдВ рдХреБрдЫ рд╕рдВрджрд┐рдЧреНрдз рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реА рдЕрдкрдиреЗ рд╕рдВрдЧреНрд░рд╣ рдХреЗ рд▓рд┐рдП рддрд╛рд▓реЗ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╣рдЯрд╛ рджреЗрдЧрд╛ред

ps uw -U postgres \
  | grep [l]ogger \
  | awk '{print "/proc/"$2"/fd"}' \
  | xargs ls -l \
  | grep `cd; psql -U postgres postgres -t -A -c "SELECT CASE WHEN substr(current_setting('log_directory'), 1, 1) = '/' THEN current_setting('log_directory') ELSE current_setting('data_directory') || '/' || current_setting('log_directory') END"` \
  | awk '{print $NF}' \
  | xargs -l -I{} tail -f {} \
  | stdbuf -o0 grep 'still waiting for' \
  | xargs -l -I{} date '+%Y%m%d-%H%M%S.%N' \
  | xargs -l -I{} psql -U postgres postgres -f detect-lock.sql -o {}-lock.log

рдФрд░ detect-lock.sqlрдЖрдЦрд┐рд░реА рдирд┐рд╡реЗрджрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЧрд▓рд╛ ред рднрд╛рдЧреЛ - рдФрд░ рд╡рд╛рдВрдЫрд┐рдд рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рд╛рде рдлрд╝рд╛рдЗрд▓реЛрдВ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ:

# cat 20200526-181433.331839375-lock.log
     type      |     target     | locked |  pid   |     mode     | granted | conflict
---------------+----------------+--------+--------+--------------+---------+----------
 relation      | {279588430}    | t      | 136325 | RowExclusive | t       | f
 relation      | {279588422}    | t      | 136325 | RowExclusive | t       | f
 relation      | {17157}        | t      | 136325 | RowExclusive | t       | f
 virtualxid    | {110,12171420} | t      | 136325 | Exclusive    | t       | f
 relation      | {279588430}    | f      |  39339 | RowExclusive | t       | f
 relation      | {279588422}    | f      |  39339 | RowExclusive | t       | f
 relation      | {17157}        | f      |  39339 | RowExclusive | t       | f
 virtualxid    | {360,11744113} | f      |  39339 | Exclusive    | t       | f
 virtualxid    | {638,4806358}  | t      |  80553 | Exclusive    | t       | f
 advisory      | {1,1,2}        | t      |  80553 | Exclusive    | f       | t
 advisory      | {1,1,2}        | f      |  80258 | Exclusive    | t       | t
 transactionid | {3852607686}   | t      | 136325 | Exclusive    | t       | f
 extend        | {279588422}    | t      | 136325 | Exclusive    | f       | t
 extend        | {279588422}    | f      |  39339 | Exclusive    | t       | t
 transactionid | {3852607712}   | f      |  39339 | Exclusive    | t       | f
(15 rows)

рдЦреИрд░, рдлрд┐рд░ - рдмреИрдареЛ рдФрд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЛ ...

All Articles