sql >> Base de Datos >  >> RDS >> PostgreSQL

Interbloqueos en PostgreSQL al ejecutar UPDATE

En PostgreSQL, las filas se bloquearán a medida que se actualicen; de hecho, la forma en que esto funciona es que cada tupla (versión de una fila) tiene un campo de sistema llamado xmin para indicar qué transacción hizo que esa tupla fuera actual (por inserción o actualización) y un campo de sistema llamado xmax para indicar qué transacción caducó esa tupla (por actualización o eliminación). Cuando accede a los datos, verifica cada tupla para determinar si es visible para su transacción, comparando su "instantánea" activa con estos valores.

Si está ejecutando una ACTUALIZACIÓN y una tupla que coincide con sus condiciones de búsqueda tiene un xmin que lo haría visible para su instantánea y un xmax de una transacción activa, se bloquea, esperando que se complete esa transacción. Si la transacción que primero actualizó la tupla retrocede, su transacción se activa y procesa la fila; si se confirma la primera transacción, su transacción se activa y toma medidas según el nivel de aislamiento de la transacción actual.

Obviamente, un interbloqueo es el resultado de que esto suceda en filas en diferente orden. No hay un bloqueo de nivel de fila en la RAM que se pueda obtener para todas las filas al mismo tiempo, pero si las filas se actualizan en el mismo orden, no puede tener el bloqueo circular. Desafortunadamente, el IN(1, 2) sugerido la sintaxis no garantiza eso. Diferentes sesiones pueden tener diferentes factores de costos activos, una tarea de "análisis" en segundo plano puede cambiar las estadísticas de la tabla entre la generación de un plan y el otro, o puede estar usando un escaneo de secuencias y verse afectado por la optimización de PostgreSQL que provoca una nueva escaneo de secuencias. para unirse a uno que ya está en curso y "recorrer" para reducir la E/S del disco.

Si realiza las actualizaciones una a la vez en el mismo orden, en el código de la aplicación o usando un cursor, solo tendrá un bloqueo simple, no interbloqueos. Sin embargo, en general, las bases de datos relacionales son propensas a fallas de serialización y es mejor acceder a ellas a través de un marco que las reconozca en base a SQLSTATE y vuelva a intentar automáticamente toda la transacción desde el principio. En PostgreSQL, una falla de serialización siempre tendrá un SQLSTATE de 40001 o 40P01.

http://www.postgresql.org/docs/current/interactive/mvcc-intro.html