Articulo de referencia

Control de concurrencia basado en marcas de tiempo

En informática , un algoritmo de control de concurrencia basado en marcas de tiempo es un método de control de concurrencia optimista . Se utiliza en algunas bases de datos para...

En informática , un algoritmo de control de concurrencia basado en marcas de tiempo es un método de control de concurrencia optimista . Se utiliza en algunas bases de datos para gestionar de forma segura las transacciones utilizando marcas de tiempo para la sincronización en lugar de bloqueos. [ 1 ]

Operación

Supuestos

  • Cada valor de marca de tiempo es único y representa con precisión un instante en el tiempo.
  • Una marca de tiempo de mayor valor se produce más tarde en el tiempo que una marca de tiempo de menor valor.

Generando una marca de tiempo

Existen varios métodos diferentes para generar marcas de tiempo.

  • Utilizar el valor del reloj del sistema al inicio de una transacción como marca de tiempo.
  • Utilizar un contador compartido seguro para subprocesos que se incrementa al inicio de una transacción como marca de tiempo.
  • Una combinación de los dos métodos anteriores.

Definición formal

Cada transacción (Ti{\displaystyle T_{i}}) es una lista ordenada de acciones (Aiincógnita{\displaystyle A_{ix}}). Antes de que la transacción realice su primera acción (Ai1{\displaystyle A_{i1}}), se marca con la marca de tiempo actual , o cualquier otra secuencia estrictamente ordenada :TS(Ti)=norteOW(){\displaystyle TS(T_{i})=NOW()}A cada transacción también se le proporciona un conjunto inicialmente vacío de transacciones de las que depende,DmiPAG(Ti)=[]{\displaystyle DEP(T_{i})=[]}y un conjunto inicialmente vacío de objetos antiguos que actualizó,OLD(Ti)=[]{\displaystyle OLD(T_{i})=[]}.

Cada objeto(Oj){\displaystyle (O_{j})}En la base de datos se proporcionan dos campos de marca de tiempo que no se utilizan para nada más que para el control de concurrencia:

  • RT(Oj){\displaystyle RT(O_{j})}es la marca de tiempo de la última transacción que leyó el valor del objeto (TS(Tr){\displaystyle TS(T_{r})}, dóndeTr{\displaystyle T_{r}}es la última transacción que leyó el valor del objeto).
  • WT(Oj){\displaystyle WT(O_{j})}es la marca de tiempo de la última transacción que actualizó el valor del objeto (TS(Tw){\displaystyle TS(T_{w})}, dóndeTw{\displaystyle T_{w}}es la última transacción que actualizó el valor del objeto).

A pesar deTi{\displaystyle T_{i}}:

Por cada acciónAiincógnita{\displaystyle A_{ix}}:
SiAiincógnita{\displaystyle A_{ix}}desea leer el valor deOj{\displaystyle O_{j}}:
SiWT(Oj)>TS(Ti){\displaystyle WT(O_{j})>TS(T_{i})}entonces abortar (un hilo más reciente ha sobrescrito el valor),
De lo contrario, actualice el conjunto de dependencias.DmiPAG(Ti).add(WT(Oj)){\displaystyle DEP(T_{i}).\mathrm {add} (WT(O_{j}))}y establecerRT(Oj)=máximo(RT(Oj),TS(Ti)){\displaystyle RT(O_{j})=\max(RT(O_{j}),TS(T_{i}))};
SiAiincógnita{\displaystyle A_{ix}}desea actualizar el valor deOj{\displaystyle O_{j}}:
SiRT(Oj)>TS(Ti){\displaystyle RT(O_{j})>TS(T_{i})}entonces abortar (un hilo más reciente ya está dependiendo del valor anterior),
SiWT(Oj)>TS(Ti){\displaystyle WT(O_{j})>TS(T_{i})}entonces omitir (la regla de Thomas Write ),
De lo contrario, guarde los valores anteriores.OLD(Ti).add(Oj,WT(Oj)){\displaystyle OLD(T_{i}).\mathrm {add} (O_{j},WT(O_{j}))}, colocarWT(Oj)=TS(Ti){\displaystyle WT(O_{j})=TS(T_{i})}y actualizar el valor deOj{\displaystyle O_{j}}.
Si bien hay una transacción enDmiPAG(Ti){\displaystyle DEP(T_{i})}Eso no ha terminado: espera
Si hay una transacción enDmiPAG(Ti){\displaystyle DEP(T_{i})}que abortó entonces abortar
De lo contrario: confirmar .

Para abortar :

Para cada(oldOj,oldWT(Oj)){\displaystyle (\mathrm {antiguo} O_{j},\mathrm {antiguo} WT(O_{j}))}enOLD(Ti){\displaystyle OLD(T_{i})}
SiWT(Oj){\displaystyle WT(O_{j})}igualTS(Ti){\displaystyle TS(T_{i})}luego restaurarOj=oldOj{\displaystyle O_{j}=\mathrm {antiguo} O_{j}}yWT(Oj)=oldWT(Oj){\displaystyle WT(O_{j})=\mathrm {old} WT(O_{j})}

Definición informal

Cada vez que se inicia una transacción, se le asigna una marca de tiempo. Esta marca indica cuándo se inició la transacción. Estas marcas de tiempo garantizan que las transacciones afecten a cada objeto en el orden en que aparecen sus respectivas marcas de tiempo. Por lo tanto, si dos operaciones de transacciones diferentes afectan al mismo objeto, la operación de la transacción con la marca de tiempo más antigua debe ejecutarse antes que la operación de la transacción con la marca de tiempo más reciente. Sin embargo, si la operación de la transacción incorrecta se ejecuta primero, se cancela y la transacción debe reiniciarse.

Cada objeto en la base de datos tiene una marca de tiempo de lectura , que se actualiza cada vez que se leen los datos del objeto, y una marca de tiempo de escritura , que se actualiza cada vez que se modifican los datos del objeto.

Si una transacción quiere leer un objeto,

  • Pero si la transacción se inició antes de la marca de tiempo de escritura del objeto, significa que algo modificó los datos del objeto después de que se iniciara la transacción. En este caso, la transacción se cancela y debe reiniciarse.
  • Si la transacción se inició después de la marca de tiempo de escritura del objeto, significa que es seguro leerlo. En este caso, si la marca de tiempo de la transacción es posterior a la marca de tiempo de lectura del objeto, la marca de tiempo de lectura se establece a la marca de tiempo de la transacción.

Si una transacción quiere escribir en un objeto,

  • Pero como la transacción se inició antes de la marca de tiempo de lectura del objeto, significa que alguien ha accedido a él y suponemos que ha copiado sus datos. Por lo tanto, no podemos escribir en el objeto, ya que eso invalidaría cualquier dato copiado; así que la transacción se cancela y debe reiniciarse.
  • Si la transacción se inició antes de la marca de tiempo de escritura del objeto, significa que algo ha cambiado en el objeto desde que iniciamos nuestra transacción. En este caso, utilizamos la regla de escritura de Thomas y simplemente omitimos nuestra operación de escritura y continuamos con normalidad; no es necesario abortar ni reiniciar la transacción.
  • De lo contrario, la transacción escribe en el objeto y la marca de tiempo de escritura del objeto se establece con la marca de tiempo de la transacción.

Físicamente irrealizable

El comportamiento es físicamente irrealizable si los resultados de las transacciones no hubieran podido ocurrir si estas fueran instantáneas. Las siguientes son las únicas dos situaciones que dan lugar a un comportamiento físicamente irrealizable:

  1. La transacción T intenta leer X, pero TS(T) < WT(X). Motivo: Significa que otra transacción ha escrito en X después de que T comenzara.
  2. La transacción T intenta escribir X, pero TS(T) < RT(X). Razón: Significa que una transacción posterior leyó X antes de que T lo escribiera.

Recuperabilidad

Tenga en cuenta que la ordenación por marcas de tiempo en su forma básica no produce historiales recuperables. Considere, por ejemplo, el siguiente historial con transacciones.T1{\displaystyle T_{1}}yT2{\displaystyle T_{2}}:

W1(incógnita)R2(incógnita)W2(y)do2R1(z)do1{\displaystyle W_{1}(x)\;R_{2}(x)\;W_{2}(y)\;C_{2}\;R_{1}(z)\;C_{1}}

Esto podría ser producido por un planificador TO, pero no es recuperable, ya queT2{\displaystyle T_{2}}confirma incluso aunque haya leído de una transacción no confirmada. Para asegurar que genere historiales recuperables, un planificador puede mantener una lista de otras transacciones de las que cada transacción ha leído y no permitir que una transacción se confirme antes de que esta lista consista únicamente en transacciones confirmadas. Para evitar abortos en cascada, el planificador podría etiquetar los datos escritos por transacciones no confirmadas como sucios y nunca permitir que se inicie una operación de lectura en dicho elemento de datos antes de que se elimine la etiqueta. Para obtener un historial estricto, el planificador no debería permitir ninguna operación en elementos sucios.

Problemas de implementación

Resolución de marca de tiempo

Este es el tiempo mínimo transcurrido entre dos marcas de tiempo consecutivas. Si la resolución de la marca de tiempo es demasiado grande (gruesa), aumenta la posibilidad de que dos o más marcas de tiempo sean iguales, lo que permite que algunas transacciones se confirmen en un orden incorrecto. Por ejemplo, en un sistema que crea cien marcas de tiempo únicas por segundo, dos eventos que ocurren con 2 milisegundos de diferencia pueden recibir la misma marca de tiempo, aunque hayan ocurrido en momentos distintos.

Bloqueo de marca de tiempo

Si bien esta técnica no requiere bloqueo, ya que el objeto no se bloquea para evitar el acceso concurrente durante la duración de una transacción, el acto de registrar cada marca de tiempo en el objeto requiere un bloqueo de duración extremadamente corta en el objeto o en su proxy.

Véase también

Referencias

  1. Wolf, Stephan; Mühe, Henrik; Kemper, Alfons; Neumann, Thomas (2013). "Una evaluación del control de concurrencia de ordenación estricta de marcas de tiempo para sistemas de bases de datos en memoria principal". Actas del Taller Internacional sobre Gestión y Análisis de Datos en Memoria . Springer Publishing . págs. 82–93 . doi : 10.1007/978-3-319-13960-9_7 .