Questa pagina è stata tradotta automaticamente. Leggi l'originale in inglese. English

Libreria IBSurgeon

1 Tb database Firebird: rapporto preliminare

Dmitry Kuzmenko, ultimo aggiornamento 31-03-2014

Traduzioni di questo documento: Portoghese Russo Cinese

Leggi il nostro articolo su un database ancora più grande (1,7 Terabyte): Maggiori dettagli sul database di 1,7 Terabyte.

Perché creare un database Firebird da un terabyte?

Molte aziende lavorano con grandi database Firebird e fanno affidamento su di essi per supportare importanti operazioni commerciali. Alcuni database Firebird hanno già dimensioni di centinaia di gigabyte e continuano a crescere (vedi sezione “Chi è grande?”), ed è facile prevedere il momento in cui diventeranno 2, 3 o 5 volte più grandi. Pertanto, gli amministratori di database e i fornitori sono interessati a studiare il comportamento di Firebird con database di grandi dimensioni e a ottenere raccomandazioni su come gestirli.

Inoltre, la ragione importante che avevamo in mente durante la creazione del database Firebird da 1Tb era l’eliminazione definitiva della percezione prevalente di Firebird come motore di database per “database piccoli”. Questo mito sembra ormai morto, ma alcuni analisti e giornalisti lo risollevano regolarmente dalla tomba, e speriamo di porre fine a questa percezione ridicola una volta per tutte.

## Hardware

Firebird è noto per la sua incredibile scalabilità e questa indagine lo ha confermato ancora una volta. Lo scopo iniziale di questo esperimento era solo la creazione di un database Firebird di 1Tb, quindi abbiamo usato un normale computer desktop:

Tabella 1: Hardware

Componente Parametri
CPU AMDAthlon 64 x2 5200
RAM 4GB
Scheda madre MSI K9N Platinum
HDD1 (sistema operativo e temp) ST3160815AS, 160GB, SATA II
HDD2 (ausiliario) HDT721064SLA360, 640GB, SATAII
HDD2 (ausiliario) HDS728080PLA380, 80GB, SATA I
HDD3 (database) ST31500341AS, 1.5TB, SATA II (Firmware CC1H)

In sostanza, abbiamo inserito l’HDD da 1.5Tb in uno dei nostri desktop da ufficio, senza altre modifiche. Questo HDD è stato formattato con dimensione del cluster di 16Kb (la stessa della dimensione di pagina del database, come vedrai sotto).

Software

Trattandosi di un computer desktop, il sistema operativo è Windows XP Professional SP3, 32bit. Per eseguire effettivamente il test abbiamo usato il loader del toolkit basato su TPC (scaricabile da http://ibdeveloper.com/tests/tpc-c/, sia i binari che i sorgenti sono disponibili).

Vorremmo sottolineare che il loader inserisce i dati come verrebbero inseriti in uno scenario reale: i record vengono inseriti e posizionati all’interno del database (e nelle aree fisiche del disco) in diverse tabelle master-detail-subdetail, non tabella per tabella.

Tabella 2: Software

Software Versione
Sistema operativo Windows XP Professional SP3, 32bit
Firebird 2.1.3 SuperServer (snapshot)
Loader Loader personalizzato dal test basato su tpc

Piano

Avevamo un piano molto semplice per questo esperimento:

  1. Creare il database e caricarlo con 1Tb di dati, senza indici
  2. Creare le chiavi primarie e gli indici appropriati (quindi la dimensione effettiva del database è superiore a 1Tb)
  3. Raccogliere le statistiche del database
  4. Eseguire diverse query SQL e valutare le prestazioni del database

Configurazione del database e del server Firebird

Il database ha una dimensione di pagina di 16384 byte, la stessa del cluster HDD, per massimizzare le prestazioni del disco (leggere/scrivere 1 pagina in un ciclo di I/O).

Nella configurazione di Firebird abbiamo configurato una directory aggiuntiva per lo spazio temporaneo e l’abbiamo puntata al disco da 640Gb (dove erano disponibili ~300Gb).

Fase di caricamento

I dati sono stati caricati in questo database in più fasi. Il computer è stato usato durante le operazioni di caricamento come normale desktop (avevamo MS Office, Firefox, IBAnalyst, ecc. - circa 8-12 programmi eseguiti contemporaneamente). Se avessimo dedicato l’hardware solo a questo compito, probabilmente sarebbe stato più veloce, quindi considera questi valori solo come un esempio di fascia bassa; non sono sicuramente i risultati migliori.

Tabella 3: Operazioni di caricamento

| |

Descrizione Valore
Tempo di caricamento ~70 ore
Record totali inseriti 6,2 miliardi
Velocità media di inserimento 24500 record/secondo
Dimensione media del record 146 byte (min 13 byte, max - 600 byte)
Transazioni 646489

Abbiamo impiegato ~4 giorni per il caricamento, e dopo avevamo un database Firebird con esattamente 1Tb di dimensione (cioè 1 099 900 125 184 byte).

Sotto puoi vedere la crescita del database e le dinamiche delle transazioni nel Visualizzatore FBDataGuard:

Indici

Abbiamo creato gli indici uno per uno e calcolato il tempo di creazione e la dimensione appropriata del file temporaneo usato per l’ordinamento.

L’indice più grande è stato creato per la tabella ORDER_LINE. La sua chiave primaria contiene quattro campi (Smallint, Smallint, Integer e Smallint). Il file temporaneo per questo indice di ordinamento era di 182Gb, e la dimensione finale dell’indice nel database è di 29.3Gb.

È interessante vedere che anche l’indice per una tabella con 3,8 miliardi di record ha profondità = 3, perché la dimensione di pagina era di 16384 byte, quindi non c’è overhead durante la ricerca dei dati usando la chiave primaria per questa tabella.

Statistiche

Dopo abbiamo raccolto le statistiche del database. Ci sono volute 7 ore 32 minuti 45 secondi.

Abbiamo inserito le informazioni statistiche chiave in una tabella e incluso alcune query e misurazioni dei tempi:

Tabella 4: Statistiche consolidate per il database da 1Tb

Nome tabella Conteggio record Dimensione, gb Tempo di esecuzione di select count(*) Tempo di creazione indice Dimensione file tmp, Gb Dimensione indice, 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

Le statistiche del database possono essere scaricate da qui.

Puoi usare il Visualizzatore gratuito FBDataGuard Community Edition per interpretare i dati testuali e vedere non solo le metriche delle prestazioni del database, ma anche il consumo di CPU e memoria.

Query

Prima di tutto, abbiamo eseguito select count(*) su diverse tabelle (vedi 4ª colonna nella Tabella 4 sopra). Come sai, a causa della natura multi-versione di Firebird, select count(*) per l’intera tabella è un’operazione costosa per il server perché richiede la visita di ogni pagina, e gli sviluppatori Firebird esperti non usano select count(*), ma l’abbiamo usata per dimostrare il rapporto complessivo di prestazioni tra database e hardware.

Dopo le query select count, abbiamo eseguito query da uno scenario reale e, a essere onesti, siamo rimasti stupiti da risultati così buoni. Giudica tu stesso:

Query Statistiche Descrizione
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))
------ Informazioni sulle prestazioni ——
Tempo di preparazione = 15ms
Tempo di esecuzione = 79ms
Tempo medio di fetch = 6.08 ms
Memoria corrente = 272 264 476
Memoria massima = 272 514 048
Buffer di memoria = 16 384
Letture da disco a cache = 82
Scritture da cache a disco = 0
Fetch dalla cache = 3 648
Join semplice di tabelle con 12400 e 372000000 record, nessuna condizione WHERE. “Tempo medio di fetch = 6.08 ms” è per il recupero della prima riga.
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))
------ Informazioni sulle prestazioni ——
Tempo di preparazione = 16ms
Tempo di esecuzione = 78ms
Tempo medio di fetch = 6.00 ms
Memoria corrente = 272 266 148
Memoria massima = 272 514 048
Buffer di memoria = 16 384
Letture da disco a cache = 88
Scritture da cache a disco = 0
Fetch dalla cache = 3 656
Join delle stesse tabelle con condizione che forza la selezione di record recenti. “Tempo medio di fetch = 6.00 ms” è per il recupero della prima riga.
select count(*)
from WAREHOUSE, customer
where c_w_id = w_id and c_w_id = 10000
Risultato = 30000
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Informazioni sulle prestazioni ——
Tempo di preparazione = 0ms
Tempo di esecuzione = 453ms
Tempo medio di fetch = 453.00 ms
Memoria corrente = 272 263 844
Memoria massima = 272 514 048
Buffer di memoria = 16 384
Letture da disco a cache = 1 048
Scritture da cache a disco = 0
Fetch dalla cache = 60 024
Conteggio record per la query precedente
SELECT * FROM ORDER_LINE
WHERE OL_W_ID = 500
Plan
PLAN (ORDER_LINE INDEX (ORDER_LINE_PK))
------ Informazioni sulle prestazioni ——
Tempo di preparazione = 0ms
Tempo di esecuzione = 94ms
Tempo medio di fetch = 7.23 ms
Memoria corrente = 136 445 536
Memoria massima = 136 592 176
Buffer di memoria = 8 192
Letture da disco a cache = 150
Scritture da cache a disco = 0
Fetch dalla cache = 2 402
Query alla tabella più grande (3.8B record). “Tempo medio di fetch = 7.23 ms” è per il recupero della prima riga.
<br>Plan<br>
<br>PLAN (ORDER_LINE INDEX (ORDER_LINE_PK))<br>
<br> <br>
<br>------ Informazioni sulle prestazioni ------<br>
<br>Tempo di preparazione = 0ms<br>
<br>Tempo di esecuzione = 3s 438ms<br>
<br>Tempo medio di fetch = 0.01 ms<br>
<br>Memoria corrente = 136 445 496<br>
<br>Memoria massima = 136 592 176<br>
<br>Buffer di memoria = 8 192<br>
<br>Letture da disco a cache = 1 840<br>
<br>Scritture da cache a disco = 0<br>
<br>Fetch dalla cache = 598 636<br>

| SELECT * FROM ORDER_LINE
WHERE OL_W_ID = 500 | La stessa query sulla tabella più grande (3.8 miliardi di record), ma questa volta abbiamo recuperato tutti i record (299245 record recuperati). | | | | | 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) | Plan
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
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 | Join di tabelle con 1240 record e 372M record. | | 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 | Plan
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
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 | Conteggio dei record per la query precedente |

Riepilogo

In questo esperimento Firebird mostra i seguenti risultati

  1. Indubbia capacità di gestire database di grandi dimensioni. Siamo abbastanza sicuri che sia possibile creare e utilizzare un database da 32 Tb su hardware appropriato, e Firebird mostrerà le stesse prestazioni elevate che mostra per database più piccoli (cioè 1Tb e inferiori).

  2. Buona scalabilità e footprint sorprendentemente ridotto. Un database da 1Tb è stato creato su un normale computer desktop e, cosa più importante, può essere utilizzato per eseguire query generali: se non si recuperano milioni di record, la velocità delle query è la stessa di quella per database di dimensioni moderate (10-15Gb).

Questo non è la fine di questo esperimento: intendiamo eseguire alcune query, raccogliere statistiche aggiuntive e pubblicare un report più dettagliato a breve. Restate sintonizzati.

Contatti

Inviate tutte le vostre domande e richieste a [email protected]