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.
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