I diversi tipi di blocchi e quando vengono utilizzati sono menzionati nel documento in Table-level Locks. A proposito di ALTER TABLE
, si dice solo che può acquisire un blocco SHARE UPDATE EXCLUSIVE
o ACCESS EXCLUSIVE
.
Ma in realtà, le versioni correnti di postgres accettano Access Exclusive Locks per tutte le varianti di questo comando, quindi non è vero che letture contemporanee possono accadere contemporaneamente in certi casi.
È facile controllare il codice sorgente perché in vari casi è prevista una funzione dedicata a stabilire il livello di blocco necessario per questo comando. Si vedano i commenti in src/backend/commands/tablecmds.c:
/*
* AlterTableGetLockLevel
*
* Sets the overall lock level required for the supplied list of subcommands.
* Policy for doing this set according to needs of AlterTable(), see
* comments there for overall explanation.
*
* Function is called before and after parsing, so it must give same
* answer each time it is called. Some subcommands are transformed
* into other subcommand types, so the transform must never be made to a
* lower lock level than previously assigned. All transforms are noted below.
*
* Since this is called before we lock the table we cannot use table metadata
* to influence the type of lock we acquire.
*
* There should be no lockmodes hardcoded into the subcommand functions. All
* lockmode decisions for ALTER TABLE are made here only. The one exception is
* ALTER TABLE RENAME which is treated as a different statement type T_RenameStmt
* and does not travel through this section of code and cannot be combined with
* any of the subcommands given here.
*/
LOCKMODE
AlterTableGetLockLevel(List *cmds)
{
/*
* Late in 9.1 dev cycle a number of issues were uncovered with access to
* catalog relations, leading to the decision to re-enforce all DDL at
* AccessExclusiveLock level by default.
La funzione ha una certa logica per prendere le serrature più deboli ma è disabilitata nella sua forma attuale per tornare AccessExclusiveLock
in tutti i casi.
fonte
2013-10-22 20:02:50
Questo è fantastico - non mi è mai venuto in mente di guardare la fonte, e se avesse avuto, non avrei saputo dove guardare. Sorprendentemente leggibile. Sto guardando attraverso di esso per vedere se riesco a trovare prove che è solo un breve blocco per l'aggiunta di colonne nullable, ma non so abbastanza per dirlo con certezza. Forse qualcosa in ATExecAddColumn? https://github.com/postgres/postgres/blob/master/src/backend/commands/tablecmds.c#L4383 – jpadvo
@jpadvo: l'aggiunta di colonne nullable o non annullabili richiede lo stesso tipo di blocco. Se viene fornito un valore predefinito, è sempre lo stesso blocco ma è trattenuto più a lungo perché deve effettivamente scrivere il valore in ogni riga della tabella. –