Practica4 2019-1
Practica4 2019-1
de Bases
de Datos
Práctica 4
Control de la concurrencia en
Oracle
Profesores: Laura Mota y Mª José Vicent
1
Práctica 4.
Objetivos:
Conocer la estrategia seguida en Oracle para el control de la
ejecución concurrente de transacciones.
Conocer los niveles de aislamiento estándar que a nivel de
transacción pueden especificarse en Oracle.
Comprobar experimentalmente la aplicación de esta
estrategia en distintas situaciones.
2
Práctica 4.
Niveles de aislamiento en SQL estándar:
SET TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED
READ COMMITTED
REPETEABLE READ
SERIALIZABLE }
READ UNCOMMITTED: lectura no confirmada.
READ COMMITTED: lectura confirmada.
REPETEABLE READ: lectura repetible
SERIALIZABLE: lectura serializable.
En el Tema 4, se estudia la propuesta que el SQL estándar hace relativa al control de la
concurrencia. El SQL propone que el protocolo, utilizado por el SGBD, permita trabajar con
distintos niveles de control de la concurrencia: niveles de aislamiento.
El nivel de aislamiento lo establece el usuario al inicio de la transacción, con la instrucción SQL:
SET TRANSACTION ISOLATION LEVEL
{READ UNCOMMITTED READ COMMITTED REPETEABLE READ SERIALIZABLE }
(el alcance es la transacción)
O en la sesión de usuario, con la instrucción SQL:
ALTER SESSION SET ISOLATION LEVEL
{READ UNCOMMITTED READ COMMITTED REPETEABLE READ SERIALIZABLE }
(el alcance es la sesión)
La elección del nivel de aislamiento debe estar en función del tipo de actividad que se vaya a
realizar.
SQL propone cuatro niveles de aislamiento que significan distintos grados de exigencia en el
control de la concurrencia.
3
Práctica 4.
Niveles de aislamiento en Oracle:
SET TRANSACTION ISOLATION LEVEL { READ COMMITTED
SERIALIZABLE }
READ COMMITTED: lectura de datos confirmados al inicio de
la instrucción SQL.
SERIALIZABLE: lectura de datos confirmados al inicio de la
transacción.
El valor por defecto cuando no se usa la instrucción es READ
COMMITED.
Oracle simplifica la propuesta de SQL, y elimina dos niveles de aislamiento.
El efecto es que en Oracle, el nivel mínimo de aislamiento en el que se puede trabajar es READ
COMMITED, es decir las transacciones siempre leen versiones de los datos ya confirmados en el
instante de la operación de lectura. Por otro lado, desaparece un nivel intermedio, REPETEABLE
READ, que queda incluido en el siguiente nivel, SERIALIZABLE, en el que las transacciones leen
versiones de los datos confirmados al inicio de la transacción.
4
Práctica 4.
Control del procesamiento de transacciones en SQL estándar:
Anomalía
Lectura no Lectura de Pérdida de
Nivel de aislamiento Lectura sucia
repetible fantasmas actualizaciones
READ UNCOMMITED SÍ SÍ SÍ SÍ
READ COMMITED NO SÍ SÍ SÍ
REPETIBLE READ NO NO SÍ SÍ
SERIALIZABLE NO NO NO NO
5
Práctica 4.
Control del procesamiento de transacciones en Oracle:
Anomalía
Lectura no Lectura de Pérdida de
Nivel de aislamiento Lectura sucia
repetible fantasmas actualizaciones
READ COMMITED NO SÍ SÍ SÍ
SERIALIZABLE NO NO NO NO
6
Práctica 4.
Control de la concurrencia en Oracle:
El control de la concurrencia en Oracle se basa en tres recursos:
Un protocolo de bloqueo de elementos de datos.
Las versiones antiguas de los elementos de datos (anteriores
a una actualización), guardadas en el servidor con fines de
recuperación.
Las marcas de tiempo (número secuencial del sistema): SCN
(System Change Number).
Estos tres recursos se explican a continuación.
7
Práctica 4. Recurso 1 para control concurrencia en Oracle:
Protocolo de bloqueo de Oracle:
El sistema Oracle utiliza un protocolo de bloqueo en el que un
elemento de datos puede estar en dos estados: ‘bloqueado’,
‘desbloqueado’:
Si bloqueo(X) = ‘bloqueado’, otras transacciones distintas a la
que provocó el bloqueo pueden leer el elemento de datos X, pero
ninguna otra transacción distinta a la que provocó el bloqueo
puede escribir el elemento X. Bloqueo exclusivo en escritura.
Si bloqueo(X) = ‘desbloqueado’, cualquier transacción puede leer
o escribir el elemento de datos X.
En el Tema 4, se estudia la familia de protocolos de bloqueo de elementos de datos.
Se presentaron dos protocolos de bloqueo, el protocolo de bloqueo binario (impide el acceso
concurrente a un elemento de datos), y el protocolo de bloqueo B2F (permite un acceso
concurrente en lectura y un acceso exclusivo en escritura).
Los protocolos de bloqueo de elementos de datos se basan en la idea de restringir el acceso al
mismo elemento de datos por varias transacciones.
Bloqueo: estado de un elemento de datos con respecto a las operaciones que las transacciones
pueden realizar sobre él.
El protocolo de bloqueo propuesto por Oracle no coincide exactamente con ninguno de los
vistos en teoría.
8
Práctica 4. Recurso 1 para control concurrencia en Oracle:
Protocolo de bloqueo de Oracle:
Los bloqueos son implícitos(1):
El estado de bloqueo lo provoca una operación de escritura
SQL.
El desbloqueo de un elemento de datos se produce cuando
finaliza la transacción que lo tenía bloqueado (con
confirmación o con anulación).
La granularidad (por defecto) del bloqueo es a nivel de fila(2).
(1) El usuario puede definir bloqueos manuales (explícitos).
(2) La granularidad puede ser también a nivel de tabla. 9
En Oracle, como en otros SGBD, el bloqueo y el desbloqueo son implícitos, es decir no existen
operaciones específicas para bloquear y desbloquear elementos de datos. El estado de bloqueo
de un elemento de datos lo provoca una operación de escritura sobre el elemento. El
desbloqueo de los elementos de datos, bloqueados durante una transacción, se produce cuando
la transacción termina.
Existen bloqueos explícitos (SELECT … FOR UPDATE) que permiten bloquear conjuntos de filas,
para realizar ciertas operaciones. Este tipo de bloqueos no serán estudiados en esta práctica.
En Oracle, como en otros SGBD, el bloqueo es a nivel de fila.
En algunas ocasiones el bloqueo se produce a nivel de tabla, esto sucede cuando concurren una
operación de DML (actualización) y una operación de DDL (definición de datos (CREATE)). Este
tipo de bloqueos tampoco serán estudiados en esta práctica.
9
Práctica 4. Recurso 1 para control concurrencia en Oracle:
Protocolo de bloqueo de Oracle:
Conclusiones:
Una operación de lectura siempre se satisface. Los lectores
nunca esperan (aunque esté bloqueado).
Sólo una transacción activa puede actualizar un elemento de
datos (bloqueo exclusivo en escritura).
10
De acuerdo con la definición del protocolo de bloqueo que se sigue en Oracle, se puede concluir
que las operaciones de lectura de las transacciones siempre se satisfacen, y que sólo una
transacción puede acceder a un elemento de datos para actualizarlo.
Observad que este protocolo no coincide con el protocolo B2F estudiado en el Tema 4, el
protocolo B2F es más estricto.
Observad que no coincide tampoco con el Protocolo Multiversión (Tema 4), ya que, aunque
siempre se permite la lectura de un elemento de datos, no se permite que varias transacciones
actualicen un elemento de datos a la vez.
10
Práctica 4. Recurso 1 para control concurrencia en Oracle:
Protocolo de bloqueo de Oracle:
Bloqueo mortal en Oracle: el SGBD detecta la situación de
bloqueo mortal y la resuelve rechazando una de las operaciones
que provocan el problema, informando a la correspondiente
transacción. No anula la transacción.
11
11
Práctica 4. Recurso 1 para control concurrencia en Oracle:
12
Para ver los bloqueos que hay en un momento determinado se puede utilizar la herramienta de
informes del SQL Developer (Menú: Ver‐Informes) con el usuario sys o system.
12
Práctica 4. Recurso 2 para control concurrencia en Oracle:
Versiones antiguas de los elementos de datos:
Las versiones de un elemento de datos que mantiene el sistema
son los valores (confirmados) anteriores a las actualizaciones de
las transacciones, que se almacenan con fines de recuperación
de la base de datos.
En Oracle la información para la recuperación de la base de
datos se almacena en dos repositorios distintos:
El fichero de diario (Redo Log) y
El espacio de deshacer (Undo Tablespace).
13
Anteriormente se ha dicho que Oracle utiliza tres recursos para el control de la concurrencia:
bloqueo de elementos de datos, versiones de los elementos de datos y marcas de tiempo. Esto
significa que ninguno de estos recursos por sí sólo es suficiente para asegurar los niveles de
aislamiento que permite Oracle.
Respecto a las versiones de los elementos de datos, Oracle mantiene versiones antiguas de los
elementos de datos (valores confirmados anteriores a las actualizaciones de las transacciones)
con fines de recuperación de la base de datos. Este uso se vio en la práctica 3, pero como se verá
en las trasparencias siguientes, Oracle va a hacer también uso de las versiones de los elementos
de datos para el control de la concurrencia.
Usualmente (ver Tema 4), los SGBD almacenan los valores de los datos anterior (valor_antes) y
posterior (valor_después) a una actualización en el fichero de diario del sistema. Oracle, por
razones de rendimiento, almacena esta información en dos repositorios distintos, de la forma
que se va a exponer a continuación. Básicamente la idea del uso de un diario, donde se registra
todo lo que sucede en las transacciones, es la misma, pero la implementación que hace Oracle
de esta idea es distinta.
13
Práctica 4. Recurso 2 para control concurrencia en Oracle:
Versiones antiguas de los elementos de datos:
Bloques Bloques de Bloques
de datos deshacer de diario
Ficheros de
Instancia control
Área compartida
Buffers datos Buffer diario
Ficheros de Ficheros de
datos diario
14
Como se ha presenta en el Tema 4, en un fichero de diario se registran todas las operaciones
que realizan las transacciones, con fines de recuperación de la BD: deshacer una transacción
anulada o interrumpida, o rehacer una transacción confirmada.
Para poder deshacer o rehacer una actualización de una transacción es necesario guardar en el
diario el valor anterior y el valor posterior a dicha actualización, como se indica en la entrada de
tipo [escribir, T, X, valor_antes, valor_después]
La particularidad de Oracle reside en que estas dos informaciones (valores de X) se almacenan
en dos repositorios distintos: en un fichero de datos del servidor y en el fichero de diario del
servidor.
Como se presentará en la práctica 6, Oracle utiliza para gestionar el espacio disponible en disco
(los ficheros de datos) una organización particular. El espacio en disco destinado a datos se
organiza en espacios de distinto tamaño (tablespaces en la terminología de Oracle), gestionados
por el servidor. Uno de estos espacios se destina a almacenar las anotaciones con los valores
anteriores de los datos actualizados, para poder deshacer transacciones durante la recuperación
de la BD. Por este motivo se habla de Espacio de Deshacer (Undo Tablespace).
En el fichero de diario se almacenan las anotaciones con el valor posterior de los datos
actualizados para poder rehacer transacciones durante la recuperación de la BD.
En la transparencia se indica el destino final de estos dos valores del dato actualizado
(valor_antes y valor_después). En las transparencias siguientes se presentará con más detalle el
uso de estos dos repositorios.
14
Práctica 4. Recurso 2 para control concurrencia en Oracle:
Versiones antiguas de los elementos de datos:
Espacio de
deshacer
2
Buffer de
Fichero
datos
de datos
Buffer de
[escribir, T, X, valor_antes, valor_después ] Objeto de
diario
datos
En la actualización de un elemento de datos (X):
3 1
El valor_después se escribe en el objeto de datos
El valor_antes se escribe en el espacio de deshacer
Ambos modificaciones (escrituras) son registradas antes en el Fichero
fichero de diario con fines de recuperación. de diario
15
Debido a la forma particular, en Oracle, de almacenar la información relativa a una actualización,
es importante entender el destino de cada información:
• El valor del dato después de la actualización (valor_después) se escribe en el correspondiente
bloque de datos (bloque del objeto de datos) residente temporalmente en el buffer de datos.
Una anotación con ese valor actualizado (valor_después) es registrada previamente en el
buffer de diario.
• El valor del dato antes de la actualización (valor_antes) se escribe en el correspondiente
bloque del espacio de deshacer residente temporalmente en el buffer de datos. Una
anotación con la actualización realizada sobre el espacio de deshacer (valor_antes) es
también registrada previamente en el buffer de diario.
Los bloques de datos y de deshacer en los que se han hecho actualizaciones, en el buffer de
datos, serán devueltos a su posición en el disco en algún momento posterior (Práctica 3).
El contenido del buffer de diario será grabado en el fichero de diario en disco siguiendo una
política que asegura tener en el diario en disco toda la información necesaria para la
recuperación de la base de datos en caso de fallo. (Práctica 3)
Es importante observar que las actualizaciones realizadas en el espacio de deshacer
(valor_antes) reciben el mismo tratamiento, respecto a la política de recuperación, que las
actualizaciones de los objetos de datos (valor_después), es decir son anotadas en el fichero de
diario.
15
Práctica 4. Recurso 3 para control concurrencia en Oracle:
Marcas de tiempo: System Change Number (SCN)
SCN: número secuencial asignado por el sistema (representa un
instante de tiempo y permite la ordenación temporal).
Cada transacción lleva asociado un SCN de inicio y un SCN de
terminación. Si una transacción T tiene un SCN de inicio menor que el SCN
de inicio de otra transacción T’, entonces T es anterior a T’.
Los bloques de datos tienen, en la cabecera del bloque, ranuras
transaccionales donde el sistema registra, entre otra
información, el SCN de las transacciones confirmadas que han
actualizado filas del bloque.
16
16
Práctica 4. Recurso 3 para control concurrencia en Oracle:
Marcas de tiempo: System Change Number (SCN)
• Directorio de filas en el bloque.
• Directorio de tablas que usan el
Cabecera
bloque.
• Slots de transacciones: SCN de
Espacio Libre
confirmación de las transacciones
Bloque que han modificado las filas del
bloque.
Datos
17
17
Práctica 4.
Estudio de las anomalías en Oracle:
Lectura sucia.
Lectura no repetible. Lectura de fantasmas.
Pérdida de actualizaciones.
18
Una vez presentados los tres recursos que utiliza Oracle para el control de la concurrencia, se va
a hacer una revisión de las anomalías tipificadas (lectura sucia, lectura no repetible, y pérdida de
actualizaciones) para analizar cómo Oracle las evita con su estrategia de control de la
concurrencia. Dado que la lectura de fantasmas es un caso específico de lectura no repetible, no
se estudia su caso.
18
Práctica 4. READ COMMITED
Lectura sucia en Oracle:
Buffers de datos
T1 T2 bloques de datos bloques de deshacer
t1 inicio X
t2 r(X) X=10 10
t3 w(X)
bloqueo (exclusivo
20 T1 t3 X 10
…
en escritura)
ti inicio
… r(X) X=10
lectura permitida
El sistema necesita mantener información sobre las transacciones confirmadas, y el instante de
inicio y de finalización de las transacciones.
En los slots transaccionales de la cabecera de los bloques, el sistema guarda el SCN de las
transacciones que han actualizado filas del bloque.
Procedimiento:
a) Si la última transacción* que ha actualizado X (cabecera de bloque) es una transacción
confirmada**, entonces, el valor de X en el bloque de datos es un valor confirmado.
b) Si la última transacción que ha actualizado X (cabecera de bloque) no es transacción
confirmada, entonces, el sistema deberá buscar en el espacio de deshacer la primera
actualización de X de esa transacción, y usar el valor_antes.
En Oracle NO hay lectura sucia.
* La última transacción que ha actualizado X será la de mayor SCN (slots transaccionales)
** No se entra en cómo el servidor mantiene información sobre las transacciones: inicio, fin,
confirmación.
19
Práctica 4.
Lectura sucia en Oracle:
Para cada elemento de datos actualizado por una transacción, el
sistema mantiene la siguiente información en el espacio de
deshacer: el identificador de la transacción, una marca de
tiempo y el valor antes de la actualización.
Con esta información el SGBD puede proporcionar a cada
transacción que requiere la lectura de un elemento de datos el
último valor confirmado del mismo antes del inicio de la
instrucción.
Se asegura el nivel de aislamiento READ COMMITED: las operaciones de
lectura de las transacciones leen datos ya confirmados en el momento de la
lectura (o bien las actualizaciones realizadas por la propia transacción).
Se evita la anomalía de la lectura sucia. 20
Para asegura el nivel de aislamiento READ COMMITED (valor por defecto) en el que no se
produce la anomalía de la lectura sucia, Oracle utiliza las versiones anteriores de los elementos
de datos y proporciona a las transacciones, en sus operaciones de lectura, el último valor
confirmado del dato, existente al inicio de la operación.
En Oracle NO hay lectura sucia.
20
Práctica 4.
Estudio de las anomalías en Oracle:
Lectura sucia.
Lectura no repetible. Lectura de fantasmas.
Pérdida de actualizaciones.
21
21
Práctica 4.
Lectura no repetible en Oracle:
El valor mínimo y por defecto de aislamiento de Oracle es
read commited por lo que en este nivel se leerán siempre
datos confirmados antes de la operación de lectura.
Si entre dos lecturas del mismo dato en una transacción otra
transacción modifica el dato y confirma la modificación, cada
lectura devolverá un valor.
22
22
Práctica 4. READ COMMITED
Lectura no repetible en Oracle:
Buffers de datos
T1 T2 bloques de datos bloques de deshacer
t1 inicio X
t2 r(X) X=10 10
t3 inicio bloqueo
50 T2 t4 X 10
t4 w(X)
… c liberación
ti r(X) X=50
…
lectura permitida
Como se puede observar, el uso del protocolo de bloqueo de Oracle y la lectura del último valor
confirmado del dato (al inicio de la operación), no son suficientes para evitar la anomalía.
23
Práctica 4. SERIALIZABLE
Lectura no repetible en Oracle:
Buffers de datos
T1 T2 bloques de datos bloques de deshacer
t1 inicio X
t2 r(X) X=10 10
t3 inicio bloqueo
50 T2 t4 X 10
t4 w(X)
… c liberación
ti r(X) X=10
…
lectura permitida
24
Práctica 4. SERIALIZABLE
Lectura no repetible en Oracle:
T1 T2 T3 bloques de datos bloques de deshacer
X T0 ti X 4
t1 inicio
t2 r(X) X=10 10
t3 inicio
t4 r(X) X=10 50 T2 t4 X 10
t5 w(X)
t6 c
t7 inicio X=50 80 T3 t9 X 50
t8 r(X)
t9 w(X)
t10 c
t11 r(X) X=10
… …
En la transparencia se muestra un ejemplo con 3 transacciones.
SERIALIZABLE: Se busca en el espacio de deshacer las entradas de la última transacción, que ha
actualizado X, y que ha sido confirmada, antes del inicio de la transacción que ahora quiere leer.
Procedimiento:
a) Si la última transacción que ha actualizado X (cabecera de bloque) es una transacción
confirmada, antes del inicio de la transacción que ahora quiere leer, entonces se lee el valor
de X en el bloque de datos.
b) Si la última transacción que ha actualizado X (cabecera de bloque) es una transacción
confirmada, después del inicio de la transacción que ahora quiere leer, o no es una
transacción confirmada, entonces, el sistema deberá buscar dos transacciones consecutivas,
Ti, Ti+1 (que han actualizado X), tales que Ti sea la última transacción confirmada antes del
inicio de la transacción que ahora quiere leer, y en el espacio de deshacer se debe leer el
valor_antes de la primera actualización de Ti+1.
25
Práctica 4.
Lectura no repetible en Oracle:
Para cada elemento de datos actualizado por una transacción, el
sistema mantiene la siguiente información en el espacio de
deshacer: el identificador de la transacción, una marca de
tiempo y el valor antes de la actualización.
Con esta información el SGBD puede proporcionar a cada
transacción que requiere la lectura de un elemento de datos el
último valor confirmado del mismo antes del inicio de la
transacción.
Se asegura el nivel de aislamiento SERIALIZABLE: las operaciones de lectura
de las transacciones leen datos confirmados antes del inicio de la
transacción (o bien las actualizaciones realizadas por la propia transacción).
Se evita la anomalía de la lectura no repetible. 26
Para asegura el nivel de aislamiento SERIALIZABLE en el que no se produce la anomalía de la
lectura no repetible, Oracle usa las versiones anteriores del elemento de datos, y proporciona a
las transacciones, en sus operaciones de lectura, el último valor confirmado del dato, existente al
inicio de la transacción.
26
Práctica 4.
Estudio de las anomalías en Oracle:
Lectura sucia.
Lectura no repetible. Lectura de fantasmas.
Pérdida de actualizaciones.
27
27
Práctica 4. READ COMMITED
Pérdida de actualizaciones en Oracle:
Buffers de datos
T1 T2 bloques de datos
t1 inicio X
t2 r(X) X=10 10
t3 inicio
X=10
t4 r(X)
t5 XX2 8
bloqueo
t4 w(X)
t6 c liberación
7
t7 XX3
t8 w(X) bloqueo
t9 c liberación Sí se da la
anomalía 28
Como se puede observar, el uso del protocolo de bloqueo de Oracle y la lectura del último valor
confirmado del dato (al inicio de la transacción), no son suficientes para evitar la anomalía. Por
lo tanto va a ser necesario utilizar otros recursos.
28
Práctica 4. SERIALIZABLE
Pérdida de actualizaciones en Oracle:
Buffers de datos
T1 T2 bloques de datos
t1 inicio X
t2 r(X) X=10 10
t3 inicio
X=10
t4 r(X)
t5 XX2 8
bloqueo
t4 w(X)
t6 c liberación ORA 08177, “Cannot serialize access for this
t7 XX3 transaction”
t8 w(X) Cause: Encountered data changed by an operation that
occurred after the start of this serializable transaction.
t9 No se da la
anomalía 29
29
Práctica 4.
Pérdida de actualizaciones en Oracle:
Oracle utiliza la información de las marcas de tiempo (SCN) en
los slots transaccionales de la cabecera de los bloques para
saber qué transacciones han actualizado alguna fila del bloque.
En el nivel de aislamiento SERIALIZABLE, una transacción T
puede actualizar una fila sólo si el sistema puede garantizar que
la última actualización de la fila fue hecha por una transacción
que fue confirmada antes del inicio de T.
Error generado cuando una transacción T (ejecutada en el nivel
SERIALIZABLE) intenta actualizar una fila residente en un bloque
que ha sido actualizada por otra transacción que fue confirmada
después de que la transacción T se iniciase: ORA 08177, “Cannot
serialize access for this transaction”.
Anula la instrucción de escritura 30
Oracle utiliza para el control de la anomalía de la pérdida de actualizaciones, el recurso de las
marcas de tiempo en los slots transaccionales de las cabeceras de bloque.
30