Académique Documents
Professionnel Documents
Culture Documents
Supongamos que la tabla tiene 10 filas, est alojada en 2 bloques, donde tiene un solo ITL y nada de espacio para crear
uno nuevo:
Bloque 1: filas del 1 al 5
Bloque 2: filas del 6 al 10
Ahora empezamos a trabajar con las sesiones:
Sesion 1: hace un update sobre una columna de la fila 9 (Es el bloque 2, y lo hace sin problemas)
Sesion 2: hace un update sobre una columna de la fila 10 (Es el bloque 2, y queda esperando por enq: TX - row lock
contention)
Podemos ver que se trata de 2 transacciones aplicando sobre diferentes filas del mismo bloque.
La sesion 1 tom el ITL disponible.
La sesion 2 No encuentra ningn ITL disponible, al intentar crearlo, se encuentra con que no hay espacio, por lo tanto
queda esperando.
Que pasara si tenemos INITRANS 2?
Ambas transacciones operan sin problemas concurrentemente sobre el mismo bloque, ocupando cada una uno de los ITL.
Si una tercera sesion intenta modificar una fila distinta en el mismo bloque, quedara esperando por "enq: TX - row lock
contention".
Ahora veamos que pasa si hay espacio disponible para nuevos ITL:
En este caso la sesion intenta crear un nuevo ITL (No la sesion, para eso utiliza una funcin del kernel de Oracle), y si hay
espacio disponible, lo crea y ejecuta concurrentemente.
Si no hay espacio disponible, por ms que no se haya llegado al MAXTRANS (o a 255 ITL en 10g), el bloque queda
saturado de transacciones concurrentes y el resto de las sesiones que ingresen en el bloque quedarn esperando por
nuestro evento "enq: TX - row lock contention"
Hemos visto todos los casos posibles, y si falta alguno tenemos toda la informacin necesaria para poder
deducirlo.
IMPORTANTE: El valor de INITRANS se tiene en cuenta solo al momento de formatear los bloques, o sea, cada vez que se
pide un nuevo extent, cuando se crea la tabla o cuando se hace un move del segmento, as que por ms que se cambie el
parametro a una tabla existente, los bloques ya creados seguirn con la misma cantidad de ITL hasta que se haga un
mantenimiento con un move o alguna otra tcnica para reubicar la tabla.
Los nuevos bloques utilizaran los nuevos parametros.
?
1
2
3
4
5
6
7
8
9
10
11
12
EVENT
COUNT(9)
---------------------------------------- ---------....
....
rdbms ipc message
12
buffer busy waits
29
cursor: pin S
53
latch: redo allocation
79
log file sync
92
db file sequential read
103
enq: TX - row lock contention
140
SQL*Net message from client
1174
?
1OBJECT_NAME
USERNAME
PROGRAM
COUNT(9)
2------------------------------ -------------------- ---------------------------------------- ---------USUER1
cargador@hadoopds (TNS V1-V3)
60
3TABLA_1
Script: Bloques que generan enq: TX - row lock contention modificada.
Identificamos que la tabla a la que intentan acceder es la tabla TABLA_1 y el que est mostrando estas esperas es la
aplicacin "cargador"
4) Hablando con el grupo de desarrollo de la aplicacion "cargador" nos comentan que aumentaron las ejecuciones en
paralelo de la aplicacin para ganar tiempo (no tuvieron en cuenta nuestras restricciones).
Tambin verificamos con el grupo de desarrollo que las llamadas paralelas de la aplicacin no intenten modificar la misma
ROW, porque de ser as aqui termina el estudio y es responsabilidad de la aplicacin tener en cuenta esta restriccin.
5) Nos fijamos a que OBJECT, FILE, BLOCK estn intentando acceder las sesiones que estn en espera.
?
SELECT object_name, ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW#, count(9) cant, min(seconds_in_wait) min_time,
max(seconds_in_wait) max_time
from v$session b, dba_objects o
where o.object_id=ROW_WAIT_OBJ#
and event = 'enq: TX - row lock contention'
group by object_name, ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW#
order by 1,5;
?
OBJECT_NAME
ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW#
------------------------------ -------------- --------------- ------------- ---------- ---------- ---------TABLA_1
2828
1724614
0
9
12
18
TABLA_1
2959
984830
0
61
17
574
Esto nos genera un dump file que quedar en el directorio de udump (ver segn versin su ubicacin) con el nombre:
<bdSID>_ora_<OSPID>.trc, donde dbSID es el SID de la base de datos y el OSPID es el PID de la sesion actual.
incrementando los ITL hasta que se qued sin espacio, por lo tanto no gener ms de 10 ITL, y vemos que en un
momento dado, el bloque que ms concurrencia tiene requiere 71 ITL para que las sesiones no esperen.
Luego de chequear en varias oportunidades una concurrencia de 70 transacciones aproximadamente, podemos decir que
si el bloque tuviese 80 ITL reduciramos casi a 0 el evento "enq: TX - row lock contention" (pagando esto con espacio
23 bytes*80=1840 b, ms de 1k por cada bloque), salvo picos de concurrencia que de todos modos la mejora sera ms
que notable.
11) Solucin:
Paso 1: Cambiar el parametro INITRANS de la tabla a 50 (40 de concurrencia promedio)
Paso 2: Realizar un move de la tabla para que los bloques sean reformateados.(Recomiendo evaluar el uso de
DBMS_REDEFINITION)
Paso 3: Chequear estado de objetos dependientes.
Espero que les sirva y sea clara la explicacin.
Cualquier duda, inquietud, estoy a su disposicin en los comentarios.