Esta página foi traduzida por máquina. Leia o original em inglês. English

Biblioteca IBSurgeon

23 maneiras adicionais de acelerar o Firebird

Alexey Kovyazin, IBSurgeon, [email protected], 08-Jan-2019

Traduções: Português

Por que “mais 23”?

Alguns de vocês lembram do artigo « 45 Maneiras de Acelerar o Firebird», publicado em maio de 2016. Agora é hora de publicar a próxima série de dicas e truques, baseados principalmente na experiência de otimização e manutenção de bancos de dados Firebird e servidores com um alto número de conexões (1000+).

1. Defina as Opções de Energia como Alto Desempenho no Windows Server 2016 e 2019

Por padrão, o Windows Server tem um plano de energia definido como “Equilibrado”, que não é adequado para servidores de banco de dados. Defina-o como “Alto Desempenho” e ganhe aproximadamente +20% de desempenho para operações intensivas de CPU. Isso pode ser definido online, sem reinicialização ou reboot. A imagem abaixo mostra o gráfico de CPU, que demonstra a vantagem do plano de energia “Alto Desempenho”:

Mais detalhes sobre nossos testes com planos de energia do Windows podem ser encontrados aqui.

2. Habilite «Interagir com a área de trabalho» no Classic para Windows

Se você estiver usando Firebird com arquitetura Classic no Windows, habilite a marcação «Permitir que o serviço interaja com a área de trabalho». Sem essa configuração, o recurso «desktop heap» é limitado pelo Windows, e o Firebird não consegue abrir mais de 250-300 conexões (depende dos metadados do banco de dados e do consumo de memória relacionado) - ocorrerá erro de falta de memória (Out Of Memory).

3. Cuidado: Controlador de Domínio

O problema é que o Windows com a função de Controlador de Domínio desabilita o cache de gravação no disco com o banco de dados do Active Directory.

Isso afeta o Firebird de várias maneiras (assim como outros aplicativos, é claro), e demonstra um desempenho significativamente pior do que em servidores sem as funções do Active Directory.

Observe que esse problema afeta versões populares do Windows, como o Windows Small Business Server 2011, bem como outras versões com DC.

4. Aumente o limite de «max open files» no Linux

Se você estiver usando Linux como servidor de banco de dados, não se esqueça de ajustar os limites para o Firebird. Verifique os limites do seu processo Firebird (SuperServer ou SuperClassic) com o seguinte comando:

Code
cat /proc//limits

e preste atenção na linha com o número máximo de arquivos abertos.

O Firebird pode usar até 4 handles por conexão, e se você tiver algo assim:

Code
Max open files 4096 4096 files

isso significa que o número total de conexões atendidas pelo processo Firebird será limitado a algo em torno de 1000.

Observe - se você tiver 4 bancos de dados no servidor, a conexão para cada banco de dados é contada.

Defina mais - recomendo 65535.

Não se esqueça de verificar novamente após reiniciar o processo Firebird: se foi aplicado ou não.

Para arquitetura Classic, é necessário verificar e aumentar os limites para o usuário «firebird».

5. Use Linux moderno

Sim, entendo que esse conselho é trivial, mas vi muitas vezes uma boa melhoria de desempenho após a migração do CentOS 6 para 7, Ubuntu 12 para 16 (no mesmo hardware!), então agora é uma recomendação obrigatória para servidores de banco de dados com mais de 250-300 conexões. O Linux moderno é um pré-requisito antes de etapas adicionais de otimização.

Versões recomendadas de Linux: CentOS 7.x e Ubuntu 16, 18.

6. Reserve 40% da RAM para cache de arquivos no Windows

O Gerenciador de Memória do SO tem implicações em relação à alocação de memória e, por padrão, o Windows exige 40% da RAM para cache de arquivos.

Infelizmente, a ferramenta limitada Gerenciador de Tarefas do Windows mostra a memória usada para cache de arquivos como «livre», e alguns administradores tentam fazer o Firebird consumir toda essa memória livre, então definem o parâmetro DefaultDBCachePage no firebird.conf com valores muito altos, o que geralmente leva a swapping.

Sempre use a ferramenta RAMMap para ver o uso real de memória no Windows.

A regra empírica para Windows Server (dedicado para uso como servidor Firebird) é a seguinte: a memória do Firebird (Working Set) deve ser menor que 40% da RAM total. Se o tamanho total dos working sets para todos os processos for superior a 50%, o swap pode ser iniciado pelo Windows.

Observe: “reservar” aqui significa não apenas “não definir muitos page buffers no Firebird”, mas também, igualmente importante, restringir o uso de memória de outros softwares. Por exemplo, se você tiver MS Exchange ou MSSQL no mesmo servidor com Firebird, certifique-se de restringir seus apetites de memória.

Se você tiver interesse em saber detalhes, gravei um webinar dedicado ao gerenciamento de memória no Firebird:

7. Reserve 30% da RAM para cache de arquivos no Linux

O Linux trabalha com cache de arquivos de outra forma que o Windows e, em geral, a quantidade de RAM usada para cache de arquivos pode ser significativamente menor do que no Windows, sem degradação perceptível de desempenho do Firebird. No entanto, para garantir alto desempenho do sistema com alto número de conexões, especialmente em Classic e SuperClassic, uma boa ideia será reservar 30% da RAM para cache de arquivos.

8. Use irqbalance no Linux

O irqbalance frequentemente melhora o desempenho do Firebird e o balanceamento de carga da CPU em servidores com alto número de núcleos.

9. Para Máquinas Virtuais - cuidado com Memory Overcommit

Uma Máquina Virtual pode ser configurada para ter mais memória do que existe fisicamente na máquina host - com um recurso conhecido como Memory Overcommit (o nome pode ser diferente em diferentes sistemas de virtualização). Isso significa que, no caso de um pico de consumo de memória (na VM com o servidor de banco de dados ou na VM vizinha), o swap pode começar, o que levará a atrasos significativos. Para uma VM de alto desempenho destinada a um servidor de banco de dados, toda a memória deve ser estática.

10. Para Máquinas Virtuais - verifique os limites da VM

Frequentemente, as VMs são criadas com limites padrão de CPU e IO, que podem ser muito baixos, como 50 IOPS e 10% de CPU. Verifique as configurações da VM do seu servidor e remova quaisquer limites - um servidor de banco de dados de alto desempenho deve ter toda a CPU, largura de banda e IO possíveis.

11. Limpe os arquivos temporários do Firebird

O Firebird cria muitos arquivos temporários para várias operações: classificação, processamento de BLOBs, rastreamento. Esses arquivos são armazenados nos seguintes locais: no Windows C:\ProgramData\firebird, no Linux / tmp / firebird

Normalmente, esses arquivos devem ser limpos automaticamente, no entanto, às vezes isso não acontece (por exemplo, no caso de reinicialização do servidor).

Verifique essas pastas periodicamente e limpe arquivos antigos - pode haver muitos GBs de arquivos desatualizados fb_NNN, e limpá-los liberará espaço na unidade do sistema.

12. Não se esqueça de habilitar o cache de arquivos com cache grande do Firebird

Como você sabe, o cache do Firebird (também chamado de «page buffers») é especificado pelo parâmetro DefaultDBCachePages no firebird.conf/databases.conf, ou diretamente no cabeçalho do banco de dados.

No Firebird 3 SuperServer, o tamanho desse cache pode ser definido muito alto, mas é importante lembrar de outro parâmetro: FileSystemCacheThreshold.

Se FileSystemCacheThreshold for menor que DefaultDBCachePages ou page buffers, o cache de arquivos do sistema operacional não será usado, o que pode levar a problemas de desempenho.

Em 99% dos casos, é melhor ter o cache de arquivos habilitado.

Para garantir isso, sempre defina os parâmetros de acordo com a seguinte regra:

  • DefaultDBCachePages = X
  • FileSystemCacheThreshold = X+ N, N>1

Existem casos raros em que desabilitar o cache de arquivos melhora o desempenho - se você tiver esse exemplo, entre em contato comigo - [email protected]!

13. Acelere o banco de dados de segurança

Toda conexão ao banco de dados Firebird estabelece uma conexão com o banco de dados de segurança (security3.fdb no caso do Firebird 3) e realiza várias leituras e gravações (páginas de transação, página de cabeçalho). Se você tiver conexões frequentes, o desempenho do seu banco de dados de segurança pode se tornar um problema.

No mínimo, você pode fazer o seguinte:

  • Aumente os page buffers para securityN.fdb (o ótimo empírico é 256 buffers)
  • Mova security3.fdb para uma unidade rápida (é um recurso padrão no Firebird 3, no 2.5 exigirá reinstalação)

Em seguida, você pode definir Forced Writes OFF para o banco de dados de segurança - a pequena chance de corrupção não é um problema neste caso.

A maneira mais radical é tornar o banco de dados de segurança somente leitura - isso eliminará todas as gravações nele.

Se você não altera frequentemente os usuários no banco de dados de segurança, é a melhor solução.

14. Experimente SuperClassic no Firebird 3

No Firebird 3, a arquitetura SuperServer foi amplamente divulgada como a solução definitiva de desempenho, mas existem alguns tipos de carga que demonstram melhor desempenho com SuperClassic (mas não Classic - sempre funciona mais lento que SuperServer/SuperClassic).

Como realizar esse experimento de forma segura? Siga os passos abaixo:

Para experimentar SuperClassic

  1. Defina no firebird.conf
  2. ServerMode=SuperClassic
  3. DefaultDbCachePages=1024
  4. gfix -buff 0
  5. Reinicie o Firebird

Para reverter para SuperServer

  1. Defina no firebird.conf
  2. ServerMode=SuperServer
  3. DefaultDbCachePages=N # N*page size*databases_count < 25% RAM
  4. FileSystemCacheThreshold = N+1
  5. gfix -buff 0
  6. Reinicie o Firebird

Por favor, escreva para mim ([email protected]) sobre os resultados do experimento, estou interessado em ver os resultados.

15. Banco de dados grande? Aumente o tamanho da página

Por padrão, os bancos de dados Firebird têm os seguintes tamanhos de página:

  • 2.5 - 4096 bytes
  • 3.0 - 8192 bytes

No entanto, o tamanho máximo de página é 16K (no 4.0 - 32K).

Para bancos de dados com mais de 100Gb, em 95% dos casos, é melhor ter o maior tamanho de página disponível, para:

  • Diminuir a profundidade dos índices. Recomenda-se ter índices com profundidade menor ou igual a 3. Índices com profundidade 4 e 5 serão muito mais lentos
  • Aumentar a utilização da RAM. O cache do Firebird é especificado em páginas, 1000 páginas com tamanho de página 8K serão 8Mb de memória real, e com 16K - 16Mb.
  • Diminuir o número de páginas do sistema. Isso acelerará o acesso aos registros das tabelas grandes (menos saltos ponteiro-ponteiro-página de dados) e ajuda na preparação de consultas SQL grandes. Para aumentar o tamanho da página do banco de dados, o banco de dados deve ser copiado com a ferramenta gbak e depois restaurado com o parâmetro -page ( gbak -c -page 16384).

Observe: se você tiver um banco de dados com muitos blobs pequenos, aumentar o tamanho da página pode diminuir a fragmentação ou aumentá-la, e é difícil prever se aumentará ou diminuirá o desempenho.

16. Não use o flag no_reserve

O flag no_reserve faz o Firebird não reservar espaço livre (30%) nas páginas de dados para possíveis versões de registros, que ocorrem após UPDATE ou DELETE. Esse flag permite que os dados sejam armazenados de forma mais compacta (e o tamanho do banco de dados também é menor), mas no caso de UPDATE/DELETE todas as alterações vão para a nova página de dados. Como resultado, no banco de dados com o flag no_reserve, as operações UPDATE/DELETE são mais lentas.

Então, se o seu banco de dados não for somente leitura, recomendo remover o flag no_reserve.

Como verificar se está definido ou não - veja a linha Attributes na saída de

Code
gstat -h database

Como desabilitar:

Code
gfix -use reserve database

Após este comando, as novas páginas de dados serão criadas com espaço reservado.

No entanto, para alcançar o efeito completo, é necessário fazer backup do banco de dados com gbak e depois restaurar; neste caso, todas as páginas de dados ficarão com espaço reservado.

Observe: o tamanho do banco de dados aumentará após a remoção do flag no_reserve e backup/restauração.

17. Defina um tamanho inicial alto para a tabela de locks do Firebird

A tabela de locks é o mecanismo do Firebird usado para sincronizar o acesso aos objetos internos do motor.

A tabela de locks do Firebird pode crescer automaticamente, mas seu aumento é uma operação lenta, que pode levar a micro-congelamentos. A tabela de locks só pode crescer, a partir do tamanho inicial (que é definido no firebird.conf).

Para evitar múltiplas rodadas de aumento da tabela de locks, uma boa ideia é monitorar o tamanho da tabela de locks ao final do período de trabalho (dia, semana, etc), e então defini-lo como tamanho inicial no firebird.conf.

LockMemSize=99999999

Para sua referência: LockMemSize em sistemas de alta carga com ~1000 usuários geralmente fica abaixo de 200Mb.

18. Use fb_lock_print para contar o número de conexões ao banco de dados

Obter o número de conexões ao banco de dados é uma tarefa frequente para os desenvolvedores de banco de dados: pode ser necessário para fins de licenciamento, por exemplo.

Frequentemente, os desenvolvedores usam a consulta SELECT count(*) FROM MON$ATTACHMENTS para obter esse valor, mas não é a forma ideal: consultas frequentes às tabelas MON$ podem ser um fardo para o banco de dados, então é melhor usar a alternativa:

Execute

fb_lock_print -d nome_do_banco | alias

e verifique o valor Owners - ele mostrará o número atual de conexões ao banco de dados.

19. Evite LEFT JOINs desnecessários

Frequentemente vejo consultas com a construção como esta:

T1 LEFT JOIN T2 ON (…) WHERE T2.Field_condition

Essencialmente, a condição em T2 exclui NULLs da saída do LEFT JOIN T2, então é possível mudar LEFT JOIN para INNER JOIN - isso não afetará o resultado da consulta.

INNER JOIN dá mais liberdade para o otimizador do Firebird, e nas versões modernas do Firebird, é otimizado muito melhor que LEFT.

Especialmente faz sentido nos seguintes casos:

  • Sem condição para T1 na cláusula WHERE
  • T2 é uma tabela pequena

20. Evite contagens de registros desnecessárias

Outro erro comum em consultas complexas de banco de dados e procedimentos armazenados é usar select count() apenas para verificar a existência do registro.

A seguinte consulta lerá todos os registros de acordo com a condição1:

Code
(select count(*)…. where condition11) >0

Melhor usar esta construção alternativa

Code
Exists(select first 1 id where condition1)

Se a condição1 retornar mais de 1 registro, a opção proposta será muito mais rápida, porque ela não lê todos os registros, ela para após o primeiro registro buscado.

21. Evite ordenações desnecessárias em procedimentos armazenados

A ordenação dos resultados da consulta dentro do procedimento armazenado deve ser justificada pela lógica de negócio.

Por exemplo, no exemplo do procedimento armazenado abaixo, a cláusula ORDER BY é inútil do ponto de vista da lógica de negócio, mas adiciona uma operação de ordenação desnecessária.

Code
create or alter procedure NEW_PROCEDURE
returns (
    SUMX double precision)
as
declare variable _amount double precision;
begin
for select T1.amount from Table1 t1 where ....
    order by id
    into :_amount
    do
    begin
     sumx=sumx+_amount
    end;
  suspend;
end

Verifique seu código PSQL para situações semelhantes e remova ORDER BY inúteis (assim como distinct e UNION).

22. Não mantenha consultas no estado preparado sem necessidade

Frequentemente vemos 500-1000 statements preparados em cada conexão (isso pode ser verificado com consultas MON$).

A grande maioria deles é executada apenas uma vez, e então ficam apenas na RAM, aumentando o working set do Firebird, e desacelerando as consultas MON$.

A recomendação é manter consultas SQL no estado preparado apenas se elas forem destinadas a serem executadas muitas vezes, ou se o tempo de preparação for grande (pode ser o caso de consultas muito grandes com muitos joins e acesso a tabelas enormes).

23. Sempre feche consultas com ordenação grande

Até que a consulta SQL com ordenação (ORDER BY, GROUP BY, UNION, distinct) não seja fechada, o Firebird retém os registros ordenados na memória. O tamanho da memória alocada para ordenação é definido pelo parâmetro TempCacheLimit no firebird.conf, por padrão é 64Mb.

Mesmo com TempCacheLimit aumentado, consultas de longa duração com um grande número de registros ordenados consumirão todo o montante alocado eventualmente, e como resultado, a ordenação irá para os arquivos temporários (ou seja, disco). Como resultado, isso pode levar a uma lentidão significativa.

A recomendação é fechar todas essas consultas em tempo hábil.

Perguntas?

Sinta-se à vontade para entrar em contato comigo para qualquer pergunta: [email protected]!