Erro ORA-27090: Unable to reserve kernel resources for asynchronous disk I/O no Oracle 12c

 

Introdução

Hoje, ao executar uma query em um ambiente de testes rodando Oracle 12c (12.2.0.1 EE) recebi o erro ORA-27090: Unable to reserve kernel resources for asynchronous disk I/O e Linux-x86_64 Error: 11: Resource temporarily unavailable. O motivo do erro foi rodar uma query com paralelismo com um servidor que tinha recursos de sobra e tomei o erro. Acontece que o Oracle esbarrou em uma limitação de parametrização imposta pelo Sistema Operacional Linux através do parâmetro fs.aio-max-nr.

 

Problema

   Quando fui executar uma query com paralelismo habilitado no test.sql conforme o script abaixo:

[oracle@localhost ]$ cat test.sql

select /*+ PARALLEL(c,32) */ count(1)
from mufalani.TESTE C;

O script retornou o erro abaixo, e eu já havia usado paralelismo nesse ambiente sem maiores problemas, então isso me alertou que eu estava atingindo um limite, provavelmente do Kernel de alguma configuração que eu havia feito inadequadamente para a carga de trabalho do ambiente.

[oracle@localhost ]$ sqlplus “/as sysdba” @test.sql

SQL*Plus: Release 12.2.0.1.0 Production on Fri May 25 11:58:38 2018

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Connected to:

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 – 64bit Production

FROM mufalani.TESTE C

*

ERROR at line 2:

ORA-27090: Unable to reserve kernel resources for asynchronous disk I/O

Linux-x86_64 Error: 11: Resource temporarily unavailable

Additional information: 3

Additional information: 128

Additional information: 243124944454

 

Solução

Consultando a nota What value should kernel parameter AIO-MAX-NR be set to ? (Doc ID 2229798.1), confirmei o que era minha suspeita inicial quando esbarrei no erro. Recomendo a leitura da nota para maiores detalhes de como calcular o valor para o ambiente, e lá diz que não tem relatos de problemas de performance para valores superestimados, mesmo assim, tem a conta de como calcular esse parâmetro na nota citada.

Consultando o site Kernel.org (https://www.kernel.org/doc/Documentation/sysctl/fs.txt)

==============================================================

aio-nr & aio-max-nr:

aio-nr is the running total of the number of events specified on the

io_setup system call for all currently active aio contexts.  If aio-nr

reaches aio-max-nr then io_setup will fail with EAGAIN.  Note that

raising aio-max-nr does not result in the pre-allocation or re-sizing

of any kernel data structures.

==============================================================

 

Isso confirmou minhas suspeitas de quando o erro foi mostrado na minha tela, sinal que esgotei a quantidade I/O assíncrono que poderia fazer em uma system call io_setup().  Consultando o site man7.org sobre essa função:

DESCRIPTION

The io_setup() system call creates an asynchronous I/O context suitable for concurrently processing nr_events operations.  The ctx_idp argument must not point to an AIO context that already exists, and must be initialized to 0 prior to the call.  On successful creation of the AIO context, *ctx_idp is filled in with the resulting handle.

  RETURN VALUE

On success, io_setup() returns 0.  For the failure return, see NOTES.

ERRORS

EAGAIN The specified nr_events exceeds the user’s limit of available

events, as defined in /proc/sys/fs/aio-max-nr.

EFAULT An invalid pointer is passed for ctx_idp.

EINVAL ctx_idp is not initialized, or the specified nr_events exceeds

internal limits.  nr_events should be greater than 0.

ENOMEM Insufficient kernel resources are available.

ENOSYS io_setup() is not implemented on this architecture.

Solução 

Nesse caso, a solução foi simples, aumentar o valor do parâmetro fs.aio-nr-max para 3145728, para isso, tivemos que fazer os seguintes passos como root.

[root@localhost ]# vi /etc/sysctl.conf

Adicionar a linha ao arquivo e salvar

# Doc ID 2229798.1

fs.aio-max-nr = 3145728

Obs.: Eu gosto de manter documentado, se possível informando a nota do MOSC que usei para definir determinado parâmetro do Kernel

Depois de salvar, você pode, ou reiniciar o ambiente ou usar o commando sysctl -w para tornar o ajuste permanente.

[root@localhost ]# sysctl -w

Para conferir o valor, basta usar também o systcl, mas agora com a opção -a

[root@localhost ]# sysctl -a | grep aio

fs.aio-nr = 65536
fs.aio-max-nr = 3145728

Depois disso, vamos testar a query novamente, agora com o S.O ajustado:

[oracle@localhost ]$ sqlplus “/as sysdba” @test.sql

SQL*Plus: Release 12.2.0.1.0 Production on Fri May 25 11:58:38 2018

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Connected to:

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 – 64bit Production

COUNT(*)
————-
67999978015

Como o esperado, agora a query funcionou com o paralelismo que eu desejava e muito provável que esse valor esteja mais de acordo com o meu ambiente de testes.

Conclusão

Durante a instalação, você pode optar por seguir a documentação oficial da Oracle copiado os valores mínimos indicados para a pre-configuração manual do produto ou até mesmo usado o pacote de pre-install via yum para fazer uma instalação mais automatizada, e isso nem sempre satisfaz as necessidades do seu ambiente de produção, nesse caso, dê uma olhada na documentação oficial e ajuste cada parâmetro de acordo com as necessidades do seu ambiente.

https://docs.oracle.com/en/database/oracle/oracle-database/12.2/cwlin/changing-kernel-parameter-values.html#GUID-FB0CC366-61C9-4AA2-9BE7-233EB6810A31

Se usou o pacote de pré-instalação, esses são os valores do Kernel que vai obter no ambiente:

fs.aio-max-nr = 1048576
fs.file-max = 6815744
kernel.shmall = 2097152
kernel.shmmax = 4294967295
kernel.shmmni = 4096
kernel.sem = 250 32000 100 128
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576

Tendo em mente que a documentação da Oracle é o melhor caminho para verificação de problemas, implementar soluções, adicionalmente, o MOSC fornece o apoio necessário para suporte aos seus ambientes de produção. Mesmo assim, o Oracle Database é um produto extremante parametrizável e flexível, com isso é muito recomendado que ajuste o produto de acordo com seu ambiente e conte com os recursos como a documentação oficial e o MOSC.

Rodrigo Mufalani é um Oracle ACE e Oracle Certified Master (OCM) com mais de 14 anos de experiência, começou com o Oracle 8i, mas teve a oportunidade de dar suporte a Oracle 7.3.4 em diante. É especialista em banco de dados Oracle com foco principal em Performance & Tuning e RAC. É palestrante em eventos de Oracle como: OTN LAD TOUR e outros. Atualmente trabalha como consultor diversas empresas no segmento de variados ramos como: Educação, Saúde, Tecnologia, Seguros e etc. Foi o terceiro Oracle ACE a ser nomeado no Brasil e é OCP nas versões 10g, 11g e 12c

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios são marcados com *