PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Избягвайте ексклузивни заключвания за достъп на референтни таблици, когато DROPping в PostgreSQL

За всеки, който търси в Google и се опитва да разбере защо тяхната таблица за премахване (или премахване на външен ключ или добавяне на външен ключ) е блокирала за дълго време:

PostgreSQL (Разгледах версии от 9.4 до 13) ограниченията на външния ключ всъщност се прилагат с помощта на тригери в двата края на външния ключ .

Ако имате таблица company (id като първичен ключ) и таблица bank_account (id като първичен ключ, company_id като външен ключ, сочещ към company.id), тогава всъщност има 2 тригера на таблицата bank_account и също 2 тригера на company таблица.

име_на_таблица време trigger_name име_на_функция
банкова_сметка СЛЕД АКТУАЛИЗАЦИЯ RI_ConstraintTrigger_c_1515961 RI_FKey_check_upd
банкова_сметка СЛЕД ВМЪКВАНЕ RI_ConstraintTrigger_c_1515960 RI_FKey_check_ins
компания СЛЕД АКТУАЛИЗАЦИЯ RI_ConstraintTrigger_a_1515959 RI_FKey_noaction_upd
компания СЛЕД ИЗТРИВАНЕ RI_ConstraintTrigger_a_1515958 RI_FKey_noaction_del

Първоначалното създаване на тези тригери (когато се създава външният ключ) изисква SHARE ROW EXCLUSIVE заключване на тези таблици (преди беше ACCESS EXCLUSIVE заключване във версия 9.4 и по-стари). Това заключване не е в конфликт с „заключвания за четене на данни“, но ще бъде в конфликт с всички други заключвания, например просто INSERT/UPDATE/DELETE в таблицата на компанията.

Изтриването на тези тригери (при изпускане на външния ключ или цялата таблица) изисква заключване ИЗКЛЮЧИТЕЛЕН ДОСТЪП на тези таблици. Тази ключалка е в конфликт с всяка друга ключалка!

Така че си представете сценарий, при който имате изпълнявана транзакция A, която първо е направила прост SELECT от таблицата на компанията (което я кара да задържи заключване на ACCESS SHARE за таблицата на компанията, докато транзакцията бъде ангажирана или върната назад) и сега върши друга работа за 3 минути. Опитвате се да премахнете таблицата bank_account в транзакция B. Това изисква заключване ACCESS EXCLUSIVE, което ще трябва да изчака, докато заключването ACCESS SHARE бъде освободено първо. В допълнение към това всички други транзакции, които искат достъп до таблицата на компанията (просто ИЗБЕРЕТЕ, или може би INSERT/UPDATE/DELETE), ще бъдат поставени на опашка за изчакване на ключалката ACCESS EXCLUSIVE, която чака заключването на ACCESS SHARE.

Продължителните транзакции и DDL промените изискват деликатно боравене.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Добавяне на име на таблица към всяка колона в набор от резултати в SQL? (По-специално Postgres)

  2. как да събера множество стойности като един низ в postgres?

  3. Не се поддържа квадратна скоба в името на таблица/колона?

  4. Как да се направи заявка за стойности, които имат най-висок брой гласове и без флагове в PostgreSQL?

  5. Как да изброя всички потребители в PostgreSQL