ENQ: TX - ROW LOCK CONTENTION no Oracle RAC
Feliz ano novo (para os que consideram o início do ano após o carnaval),
Desculpem minha ausência, mas é que o tempo é curto e muitas coisas estão acontecendo ao mesmo tempo.
Preciso informar a vocês um evento em particular que ocorreu comigo em um dos ambientes em que trabalho. O ambiente é em RAC 11g e um sistema foi migrado.
Quando este foi migrado, foi percebido um alto índice de ocorrência do evento "ENQ: TX - ROW LOCK CONTENTION" que não acontecia antes. Isso parece claro, porém não foi tão fácil assim resolver. Este evento acontecia em INSERTS, UPDATES e DELETES causando um "pequeno" estresse ao utilizar a aplicação. Anteriormente o sistema funcionava normalmente em SINGLE INSTANCE, mas os problemas vieram após "virar" pro RAC.
Sabemos que falta de índices em chaves estrangeiras causam problemas de ROW LOCK, mas não era o caso, pois não acontecia anteriormente. Quando ocorre este evento em INSERTS, geralmente, é pelo fato de uma sessão estar inserindo um valor X e outra sessão estar inserindo o mesmo valor X causando a esta a espera ROW LOCK. Se a primeira sessão confirmasse (COMMIT) o erro de CONSTRAINT violada apareceria para a segunda, mas se a primeira não confirmasse (ROLLBACK) a segunda iria inserir com sucesso.
Isso também foi analisado, mas não era o caso. Algumas vezes até DEADLOCK ocorria com apenas traces e informações geradas de uma sessão.
Foi percebido que o ambiente usava MTS (Microsoft Transaction Server) que tratava as transações como distribuídas no Oracle. No caso do RAC o que acontecia era que um usuário quando entrava no sistema WEB abria várias sessões, algumas em uma instância e outras na outra instância. Notei que quando isso acontecia causava tais bloqueios.
Para resolver da melhor forma possível, criei serviços voltados para este tipo de configuração e adaptei ao ambiente do sistema com MTS.
Primeiramente o comando abaixo criou o serviço "WEB_XA1" com FAILOVER, Load Balance Goal SHORT runtime SERVICE_TIME, DTP TRUE (-x, processamento de transações distribuídas), notificações AQ TRUE (Fast Start App Failover), instância preferencial WEB1, instância disponível WEB2. Significa que quem conectar no WEB_XA1, todas suas sessões cairão somente na instância WEB1 e caso esta não esteja disponível as sessões serão transferidas/abertas na WEB2.
Depois criei outro serviço, mas com a instância preferencial e disponível trocados:
Fiz isso porque no ambiente possuem 4 servidores de aplicação, então em 2 servidores foi configurado para acessar o serviço WEB_XA1 e o outro WEB_XA2 para balancear a carga. Após isso configurado o evento de espera "ENQ: TX - ROW LOCK CONTENTION" simplesmente desapareceu.
Fica aí a dica pra quem enfrentar isto após migrações para ambiente RAC e transações distribuídas.
Até a próxima.
Desculpem minha ausência, mas é que o tempo é curto e muitas coisas estão acontecendo ao mesmo tempo.
Preciso informar a vocês um evento em particular que ocorreu comigo em um dos ambientes em que trabalho. O ambiente é em RAC 11g e um sistema foi migrado.
Quando este foi migrado, foi percebido um alto índice de ocorrência do evento "ENQ: TX - ROW LOCK CONTENTION" que não acontecia antes. Isso parece claro, porém não foi tão fácil assim resolver. Este evento acontecia em INSERTS, UPDATES e DELETES causando um "pequeno" estresse ao utilizar a aplicação. Anteriormente o sistema funcionava normalmente em SINGLE INSTANCE, mas os problemas vieram após "virar" pro RAC.
Sabemos que falta de índices em chaves estrangeiras causam problemas de ROW LOCK, mas não era o caso, pois não acontecia anteriormente. Quando ocorre este evento em INSERTS, geralmente, é pelo fato de uma sessão estar inserindo um valor X e outra sessão estar inserindo o mesmo valor X causando a esta a espera ROW LOCK. Se a primeira sessão confirmasse (COMMIT) o erro de CONSTRAINT violada apareceria para a segunda, mas se a primeira não confirmasse (ROLLBACK) a segunda iria inserir com sucesso.
Isso também foi analisado, mas não era o caso. Algumas vezes até DEADLOCK ocorria com apenas traces e informações geradas de uma sessão.
Foi percebido que o ambiente usava MTS (Microsoft Transaction Server) que tratava as transações como distribuídas no Oracle. No caso do RAC o que acontecia era que um usuário quando entrava no sistema WEB abria várias sessões, algumas em uma instância e outras na outra instância. Notei que quando isso acontecia causava tais bloqueios.
Para resolver da melhor forma possível, criei serviços voltados para este tipo de configuração e adaptei ao ambiente do sistema com MTS.
Primeiramente o comando abaixo criou o serviço "WEB_XA1" com FAILOVER, Load Balance Goal SHORT runtime SERVICE_TIME, DTP TRUE (-x, processamento de transações distribuídas), notificações AQ TRUE (Fast Start App Failover), instância preferencial WEB1, instância disponível WEB2. Significa que quem conectar no WEB_XA1, todas suas sessões cairão somente na instância WEB1 e caso esta não esteja disponível as sessões serão transferidas/abertas na WEB2.
$ srvctl add service -d WEB -s WEB_XA1 -P BASIC -e SELECT -m BASIC -j SHORT -B SERVICE_TIME -x TRUE -q TRUE -r WEB1 -a WEB2
Depois criei outro serviço, mas com a instância preferencial e disponível trocados:
$ srvctl add service -d WEB -s WEB_XA2 -P BASIC -e SELECT -m BASIC -j SHORT -B SERVICE_TIME -x TRUE -q TRUE -r WEB2 -a WEB1
Fiz isso porque no ambiente possuem 4 servidores de aplicação, então em 2 servidores foi configurado para acessar o serviço WEB_XA1 e o outro WEB_XA2 para balancear a carga. Após isso configurado o evento de espera "ENQ: TX - ROW LOCK CONTENTION" simplesmente desapareceu.
Fica aí a dica pra quem enfrentar isto após migrações para ambiente RAC e transações distribuídas.
Até a próxima.
Em minha empresa, também está ocorrendo isso. Mudei o schema RM do oracle 9 para o 10.2.0.5 e atualizei a aplicação. Começou a dar esses problemas de lock.
ResponderExcluir