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

Biblioteca IBSurgeon

Banco de dados Firebird de 1 Tb: relatório preliminar

Dmitry Kuzmenko, última atualização 31-03-2014

Traduções deste documento: Português Russo Chinês

Leia nosso artigo sobre um banco de dados ainda maior (1,7 Terabyte): Mais Detalhes Sobre o banco de dados de 1,7 Terabyte.

Por que criar um banco de dados Firebird de um terabyte?

Muitas empresas trabalham com grandes bancos de dados Firebird e dependem deles para sustentar operações de negócio importantes. Alguns dos bancos de dados Firebird já têm centenas de gigabytes de tamanho e continuam a crescer (veja a seção “Quem é grande?”), e é fácil prever o momento em que eles se tornarão 2, 3 ou 5 vezes maiores. Assim, administradores de banco de dados e fornecedores têm interesse em investigar o comportamento do Firebird com grandes bancos de dados e obter algumas recomendações sobre como gerenciá-los.

Também a razão importante que tínhamos em mente ao criar o banco de dados Firebird de 1Tb foi a eliminação definitiva da percepção predominante do Firebird como um mecanismo de banco de dados para “bancos de dados pequenos”. Esse mito parece estar morto agora, mas alguns analistas e jornalistas o ressuscitam regularmente, e esperamos acabar de uma vez por todas com essa percepção ridícula.

## Hardware

O Firebird é bem conhecido por sua incrível escalabilidade e esta investigação confirmou isso mais uma vez. O propósito inicial deste experimento era apenas a criação de um banco de dados Firebird de 1Tb de tamanho, então usamos um computador desktop comum:

Tabela 1: Hardware

Componente Parâmetros
CPU AMDAthlon 64 x2 5200
RAM 4GB
Placa-mãe MSI K9N Platinum
HDD1 (sistema operacional e temp) ST3160815AS, 160GB, SATA II
HDD2 (auxiliar) HDT721064SLA360, 640GB,SATAII
HDD2 (auxiliar) HDS728080PLA380, 80GB, SATA I
HDD3 (banco de dados) ST31500341AS, 1.5TB, SATA II (Firmware CC1H)

Em essência, colocamos o HDD de 1,5Tb em um dos nossos desktops de escritório, sem quaisquer outras modificações. Este HDD foi formatado com tamanho de cluster de 16Kb (o mesmo que o tamanho de página do banco de dados, como você pode ver abaixo).

Software

Como é um computador desktop, o sistema operacional é Windows XP Professional SP3, 32bit. Para realmente executar o teste, usamos o carregador do kit de ferramentas baseado em TPC (baixe-o em http://ibdeveloper.com/tests/tpc-c/, tanto binários quanto fontes estão disponíveis).

Gostaríamos de enfatizar que o carregador insere dados como seriam inseridos em um cenário da vida real: os registros são inseridos e situados dentro do banco de dados (e em áreas físicas do disco) em várias tabelas master-detail-subdetail, não tabela por tabela.

Tabela 2: Software

Software Versão
Sistema operacional Windows XP Professional SP3, 32bit
Firebird 2.1.3 SuperServer (snapshot)
Carregador Carregador personalizado do teste baseado em tpc

Plano

Tínhamos um plano muito direto para este experimento:

  1. Criar o banco de dados e carregá-lo com 1Tb de dados, sem índices
  2. Criar chaves primárias e índices apropriados (então, na verdade, o tamanho do banco de dados é superior a 1Tb)
  3. Coletar estatísticas do banco de dados
  4. Executar várias consultas SQL e estimar o desempenho do banco de dados

Configuração do banco de dados e do servidor Firebird

O banco de dados tem tamanho de página de 16384 bytes, o mesmo que o cluster do HDD, para maximizar o desempenho de disco (ler/gravar 1 página em um ciclo de I/O).

Na configuração do Firebird, configuramos um diretório adicional para espaço temporário e o apontamos para o disco de 640Gb (onde ~300Gb estavam livres).

Etapa de carregamento

Os dados foram carregados neste banco de dados em várias etapas. O computador foi usado durante as operações de carregamento como um desktop comum (temos MS Office, Firefox, IBAnalyst, etc - cerca de 8-12 programas rodando ao mesmo tempo). Se tivéssemos dedicado o hardware apenas para esta tarefa, provavelmente seria mais rápido, então considere esses valores apenas como um exemplo de baixo custo; eles definitivamente não são os melhores resultados.

Tabela 3: Operações de carregamento

| |

Descrição Valor
Tempo de carregamento ~70 horas
Total de registros inseridos 6,2 bilhões
Velocidade média de inserção 24500 registros/segundo
Tamanho médio do registro 146 bytes (mín 13 bytes, máx - 600 bytes)
Transações 646489

Passamos ~4 dias carregando, e depois disso tínhamos um banco de dados Firebird com exatamente 1Tb de tamanho (ou seja, 1 099 900 125 184 bytes).

Abaixo você pode ver o crescimento do banco de dados e a dinâmica das transações no FBDataGuard Viewer:

Índices

Criamos os índices um a um e contamos o tempo de criação e o tamanho apropriado do arquivo temporário usado para ordenação.

O maior índice foi criado para a tabela ORDER_LINE. Sua chave primária contém quatro campos (Smallint, Smallint, Integer e Smallint). O arquivo temporário para este índice de ordenação foi de 182Gb, e o tamanho final do índice no banco de dados é de 29,3Gb.

É interessante ver que mesmo o índice para uma tabela com 3,8 bilhões de registros tem profundidade = 3, porque o tamanho de página era de 16384 bytes, então não há overhead ao buscar dados usando a chave primária para esta tabela.

Estatísticas

Depois disso, coletamos as estatísticas do banco de dados. Levou 7 horas 32 minutos e 45 segundos.

Colocamos as principais informações estatísticas em uma única tabela e incluímos algumas consultas e medições de tempo:

Tabela 4: Estatísticas consolidadas para o banco de dados de 1Tb

Nome da tabela Contagem de registros Tamanho, gb Tempo de execução de select count(*) Tempo de criação do índice Tamanho do arquivo tmp, Gb Tamanho do índice, Gb
WAREHOUSE 1240 0.002 0s 0 0 0.0
ITEM 100000 0.012 0.7s - - 0.0
DISTRICT 124000 0.017 0.7s 6 - 0.0
NEW_ORDER 111600000 32 20m 00s 23m 00s 4.56 0.8
CUSTOMER 372000000 224 - 41m 00s - 2.6
customer_last 1h 52m 32s 12.4 2.3
fk_cust_ware 2h 10m 51s - 2.3
HISTORY 372000000 32 - - - -
ORDERS 372000000 25 32m 00s 45m 41s 15.2 2.5
STOCK 1240000000 404 - 3h 34m 44s 41.5 9.2
ORDER_LINE 3720051796 359 - 12h 6m 18s 182.0 29.3

As estatísticas do banco de dados podem ser baixadas aqui.

Você pode usar o FBDataGuard Community Edition Viewer gratuito para interpretar os dados de texto e ver não apenas as métricas de desempenho do banco de dados, mas também o consumo de CPU e memória.

Consultas

Em primeiro lugar, executamos consultas select count(*) em várias tabelas (veja a 4ª coluna na Tabela 4 acima). Como você sabe, devido à natureza multiversão do Firebird, select count(*) para a tabela inteira é uma operação cara para o servidor porque requer visitar cada página, e desenvolvedores Firebird experientes não usam select count(*), mas nós o usamos para demonstrar a proporção geral de desempenho do banco de dados e do hardware.

Após as consultas select count, executamos consultas de um cenário da vida real e, para ser honesto, ficamos impressionados com resultados tão bons. Veja por si mesmo:

Consulta Estatísticas Descrição
select w_id, w_name, c_id, c_last
from WAREHOUSE, customer
where c_w_id = w_id
PLAN JOIN (WAREHOUSE NATURAL, CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 15ms
Execute time = 79ms
Avg fetch time = 6.08 ms
Current memory = 272 264 476
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 82
Writes from cache to disk = 0
Fetches from cache = 3 648
Junção simples de tabelas com 12400 e 372000000 registros, sem condições WHERE. “Avg fetch time = 6.08 ms” é para buscar a primeira linha.
select w_id, w_name, c_id, c_last
from WAREHOUSE, customer
where c_w_id = w_id and c_w_id = 10000
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 16ms
Execute time = 78ms
Avg fetch time = 6.00 ms
Current memory = 272 266 148
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 88
Writes from cache to disk = 0
Fetches from cache = 3 656
Junção das mesmas tabelas com condição que força a seleção de registros recentes. “Avg fetch time = 6.00 ms” é para buscar a primeira linha.
select count(*)
from WAREHOUSE, customer
where c_w_id = w_id and c_w_id = 10000
Result = 30000
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 0ms
Execute time = 453ms
Avg fetch time = 453.00 ms
Current memory = 272 263 844
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 1 048
Writes from cache to disk = 0
Fetches from cache = 60 024
Contagem de registros para a consulta anterior
SELECT * FROM ORDER_LINE
WHERE OL_W_ID = 500
Plan
PLAN (ORDER_LINE INDEX (ORDER_LINE_PK))
------ Performance info ——
Prepare time = 0ms
Execute time = 94ms
Avg fetch time = 7.23 ms
Current memory = 136 445 536
Max memory = 136 592 176
Memory buffers = 8 192
Reads from disk to cache = 150
Writes from cache to disk = 0
Fetches from cache = 2 402
Consulta à maior tabela (3,8B registros). “Avg fetch time = 7.23 ms” é para buscar a primeira linha.
<br>Plan<br>
<br>PLAN (ORDER_LINE INDEX (ORDER_LINE_PK))<br>
<br> <br>
<br>------ Performance info ------<br>
<br>Prepare time = 0ms<br>
<br>Execute time = 3s 438ms<br>
<br>Avg fetch time = 0.01 ms<br>
<br>Current memory = 136 445 496<br>
<br>Max memory = 136 592 176<br>
<br>Memory buffers = 8 192<br>
<br>Reads from disk to cache = 1 840<br>
<br>Writes from cache to disk = 0<br>
<br>Fetches from cache = 598 636<br>

| SELECT * FROM ORDER_LINE
WHERE OL_W_ID = 500 | A mesma consulta na maior tabela (3,8B de registros), mas desta vez buscamos todos os registros (299245 registros buscados). | | | | | select w_id, w_name, c_id, c_last
from WAREHOUSE, customer
where c_w_id = w_id and (c_w_id > 8000) and (c_w_id < 10000) | Plano
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Informações de desempenho ——
Prepare time = 0ms
Execute time = 125ms
Avg fetch time = 9.62 ms
Current memory = 272 270 824
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 91
Writes from cache to disk = 0
Fetches from cache = 3 659 | Junção de tabelas com 1240 registros e 372M de registros. | | select count(*)
from WAREHOUSE, customer
where c_w_id = w_id and (c_w_id > 8000) and (c_w_id < 10000)
Result = 59 970 000 | Plano
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Informações de desempenho ——
Prepare time = 0ms
Execute time = 13m 4s 718ms
Avg fetch time = 784 718.00 ms
Current memory = 272 268 532
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 2 332 583
Writes from cache to disk = 0
Fetches from cache = 119 977 902 | Contagem de registros da consulta anterior |

Resumo

Neste experimento o Firebird apresenta os seguintes resultados

  1. Capacidade indiscutível de lidar com grandes bancos de dados. Temos bastante certeza de que é possível criar e usar um banco de dados de 32 Tb em hardware apropriado, e o Firebird apresentará o mesmo alto desempenho que apresenta para bancos de dados menores (ou seja, 1Tb e abaixo).

  2. Boa escalabilidade e footprint surpreendentemente pequeno. O banco de dados de 1Tb foi criado em um computador desktop comum e, mais importante, pode ser usado para executar consultas gerais: se você não buscar milhões de registros, a velocidade da consulta é a mesma que para bancos de dados de tamanho moderado (10-15Gb).

Este não é o fim deste experimento: pretendemos executar algumas consultas, coletar estatísticas adicionais e publicar um relatório mais detalhado em breve. Fique ligado.

Contatos

Envie todas as suas dúvidas e perguntas para [email protected]