Skip to content
Snippets Groups Projects
Select Git revision
  • benchmark-tools
  • postgres-lambda
  • master default
  • REL9_4_25
  • REL9_5_20
  • REL9_6_16
  • REL_10_11
  • REL_11_6
  • REL_12_1
  • REL_12_0
  • REL_12_RC1
  • REL_12_BETA4
  • REL9_4_24
  • REL9_5_19
  • REL9_6_15
  • REL_10_10
  • REL_11_5
  • REL_12_BETA3
  • REL9_4_23
  • REL9_5_18
  • REL9_6_14
  • REL_10_9
  • REL_11_4
23 results

postinit.c

Blame
    • Tom Lane's avatar
      ac23b711
      Fix incorrect order of database-locking operations in InitPostgres(). · ac23b711
      Tom Lane authored
      We should set MyProc->databaseId after acquiring the per-database lock,
      not beforehand.  The old way risked deadlock against processes trying to
      copy or delete the target database, since they would first acquire the lock
      and then wait for processes with matching databaseId to exit; that left a
      window wherein an incoming process could set its databaseId and then block
      on the lock, while the other process had the lock and waited in vain for
      the incoming process to exit.
      
      CountOtherDBBackends() would time out and fail after 5 seconds, so this
      just resulted in an unexpected failure not a permanent lockup, but it's
      still annoying when it happens.  A real-world example of a use-case is that
      short-duration connections to a template database should not cause CREATE
      DATABASE to fail.
      
      Doing it in the other order should be fine since the contract has always
      been that processes searching the ProcArray for a database ID must hold the
      relevant per-database lock while searching.  Thus, this actually removes
      the former race condition that required an assumption that storing to
      MyProc->databaseId is atomic.
      
      It's been like this for a long time, so back-patch to all active branches.
      ac23b711
      History
      Fix incorrect order of database-locking operations in InitPostgres().
      Tom Lane authored
      We should set MyProc->databaseId after acquiring the per-database lock,
      not beforehand.  The old way risked deadlock against processes trying to
      copy or delete the target database, since they would first acquire the lock
      and then wait for processes with matching databaseId to exit; that left a
      window wherein an incoming process could set its databaseId and then block
      on the lock, while the other process had the lock and waited in vain for
      the incoming process to exit.
      
      CountOtherDBBackends() would time out and fail after 5 seconds, so this
      just resulted in an unexpected failure not a permanent lockup, but it's
      still annoying when it happens.  A real-world example of a use-case is that
      short-duration connections to a template database should not cause CREATE
      DATABASE to fail.
      
      Doing it in the other order should be fine since the contract has always
      been that processes searching the ProcArray for a database ID must hold the
      relevant per-database lock while searching.  Thus, this actually removes
      the former race condition that required an assumption that storing to
      MyProc->databaseId is atomic.
      
      It's been like this for a long time, so back-patch to all active branches.