Vergrendeling begrijpen
MvCC (Multi-Version Concurrency Control) biedt de juiste gelijktijdigheidsinstellingen voor de meeste scenario's. Als voor een toepassing echter specifieke vergrendelingen nodig zijn waarmee precies wordt bepaald welke rijen worden beïnvloed en met een specifiek vergrendelingsniveau, schakelt u deze verfijnde controle in met expliciete vergrendelingsmodi.
In Azure Database for PostgreSQL zijn er drie typen expliciete vergrendelingen, vergrendelingen op tabelniveau, vergrendelingen op rijniveau en vergrendelingen op paginaniveau. De eerste transactie vraagt om een vergrendeling en, indien geaccepteerd, wordt de aangevraagde vergrendeling de bestaande vergrendeling. Als een andere transactie probeert een vergrendeling op dezelfde gegevens uit te schakelen, wordt de vergrendeling verleend als deze niet conflicteert met de oorspronkelijke transactie.
Twee transacties kunnen bijvoorbeeld op dezelfde gegevens tegelijk query's uitvoeren met een SELECT-instructie. Voor deze aanvragen wordt een ACCESS SHARE-vergrendeling gebruikt en beide zijn toegestaan. In een ander scenario voert een transactie een query uit op gegevens met een SELECT-instructie en een ACCESS SHARE-vergrendeling, maar tegelijkertijd probeert een andere transactie dezelfde tabel te verwijderen. Voor het verwijderen van een tabel is een ACCESS EXCLUSIVE-vergrendeling vereist, die in dit scenario niet zou worden verleend.
Vergrendelingen op tabelniveau
Vergrendelingen op tabelniveau krijgen vergrendelingen voor een hele tabel, zelfs als ze RIJ in hun naam hebben. Het vergrendelen van een hele tabel is mogelijk vereist als de tabel zelf wordt gewijzigd of efficiënter is dan het verwijderen van veel vergrendelingen op rijniveau.
Er zijn acht typen vergrendeling op tabelniveau in Azure Database for PostgreSQL en de SQL-opdrachten die deze typen vergrendelingen verkrijgen zijn:
Vergrendelingsmodus | Overgenomen door |
---|---|
ACCESS SHARE | SELECT-opdracht |
RIJSHARE | SELECT FOR UPDATE and SELECT FOR SHARE commands |
RIJ EXCLUSIEF | Opdrachten BIJWERKEN, VERWIJDEREN en INVOEGEN |
EXCLUSIEF DELEN | ANALYSEREN, INDEX GELIJKTIJDIG MAKEN, STATISTIEKEN MAKEN, OPMERKINGEN MAKEN, GELIJKTIJDIG INDEXEREN, GELIJKTIJDIG INDEXEREN, sommige ALTER INDEX- en ALTER TABLE-opdrachten, en VACUUM (niet VOLLEDIG) |
DELEN | OPDRACHT CREATE INDEX (niet GELIJKTIJDIG) |
EXCLUSIEF RIJ DELEN | CREATE TRIGGER-opdracht en enkele ALTER TABLE-opdrachten |
EXCLUSIEVE | OPDRACHT GEREALISEERDE WEERGAVE GELIJKTIJDIG VERNIEUWEN |
EXCLUSIEVE TOEGANG | DROP TABLE, REINDEX, TRUNCATE, CLUSTER, REFRESH MATERIALIZED VIEW (niet GELIJKTIJDIG) opdrachten, de meeste ALTER INDEX- en ALTER TABLE-opdrachten, en VACUUM FULL |
Elk type bestaande vergrendeling blokkeert andere aangevraagde vergrendelingen die worden verkregen. In de volgende tabel ziet u welke vergrendelingen voorkomen dat andere vergrendelingen worden verkregen:
-- | Bestaande ACCESS SHARE | Bestaande RIJSHARE | Bestaande RIJ EXCLUSIEF | Bestaande SHARE UPDATE EXCLUSIEF | Bestaande SHARE | Bestaande SHARE ROW EXCL | Bestaande EXCLUSIVE | Bestaande ACCESS EXCLUSIVE |
---|---|---|---|---|---|---|---|---|
Aangevraagde ACCESS SHARE | Geblokkeerd | |||||||
Aangevraagde RIJSHARE | Geblokkeerd | Geblokkeerd | ||||||
AangevraagdE RIJ-EXCLUSIEF | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | ||||
EXCLUSIEVE SHARE-UPDATE aangevraagd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | |||
Aangevraagde SHARE | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | |||
AANGEVRAAGDE EXCLUSIEVE SHARE-RIJ | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | ||
Exclusief aangevraagd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | |
AANGEVRAAGDE EXCLUSIEVE TOEGANG | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd |
Vergrendelingen op rijniveau
Vergrendelingen op rijniveau zijn gedetailleerder en hebben alleen invloed op een andere transactie die toegang heeft tot dezelfde rij. Dit vergrendelingstype verbetert gelijktijdigheid, maar het verkrijgen en verwijderen van veel vergrendelingen heeft een negatieve invloed op de prestaties. Vergrendelingen op rijniveau worden automatisch verkregen door PostgreSQL en worden niet handmatig toegepast.
Er zijn vier typen vergrendeling op rijniveau in Azure Database for PostgreSQL en deze worden verkregen, afhankelijk van welke andere vergrendelingstypen moeten worden geblokkeerd:
-- | Bestaande FOR KEY SHARE | Bestaande FOR SHARE | Bestaande VOOR GEEN SLEUTELUPDATE | Bestaand VOOR UPDATE |
---|---|---|---|---|
Aangevraagd VOOR SLEUTELSHARE | Geblokkeerd | |||
Aangevraagd VOOR SHARE | Geblokkeerd | Geblokkeerd | ||
Aangevraagd VOOR GEEN SLEUTELUPDATE | Geblokkeerd | Geblokkeerd | Geblokkeerd | |
Aangevraagd VOOR UPDATE | Geblokkeerd | Geblokkeerd | Geblokkeerd | Geblokkeerd |
Vergrendelingen op paginaniveau
Vergrendelingen op paginaniveau zijn van invloed op een pagina met gegevens, die doorgaans uit meerdere rijen bestaan. Hoewel PostgreSQL-processen gebruikmaken van vergrendelingen op paginaniveau, vereisen toepassingsontwikkelaars dit type vergrendeling doorgaans niet.
Vergrendelingen handmatig toepassen en huidige vergrendelingen weergeven
Als u handmatig een vergrendeling op tabelniveau wilt toepassen, kunt u de opdracht LOCK gebruiken met de vereiste vergrendelingsmodus. De opdracht LOCK moet zich binnen een transactie bevinden en de vergrendelingen worden vrijgegeven wanneer de transactie is voltooid. Voorbeeld:
BEGIN TRANSACTION;
LOCK TABLE humanresources.department IN ROW EXCLUSIVE MODE;
COMMIT;
Gebruik pg_locks om vergrendelingen weer te geven die momenteel in de database zijn opgeslagen. Als u bijvoorbeeld alle huidige vergrendelingen wilt weergeven, gebruikt u de volgende opdracht:
SELECT * FROM pg_locks;