Deze pagina is automatisch vertaald. Lees het Engelse origineel. English

IBSurgeon-bibliotheek

1 Tb Firebird-database: voorlopig rapport

Dmitry Kuzmenko, laatste update 31-03-2014

Vertalingen van dit document: Portugees Russisch Chinees

Lees ons artikel over een nog grotere (1,7 Terabyte) database: Meer details over 1,7 Terabyte database.

Waarom een terabyte Firebird-database aanmaken?

Veel bedrijven werken met grote Firebird-databases en vertrouwen erop voor het ondersteunen van belangrijke bedrijfsprocessen. Sommige Firebird-databases zijn al honderden gigabytes groot en blijven groeien (zie het gedeelte “Wie is groot?”), en het is gemakkelijk te voorspellen wanneer ze 2, 3 of 5 keer zo groot worden. Databasebeheerders en leveranciers zijn er dus in geïnteresseerd om het gedrag van Firebird met grote databases te onderzoeken en aanbevelingen te krijgen over hoe ze te beheren.

Een andere belangrijke reden die we in gedachten hadden bij het aanmaken van de 1Tb Firebird-database was het definitief uitbannen van de wijdverbreide opvatting dat Firebird een database-engine is voor “kleine databases”. Deze mythe lijkt nu dood te zijn, maar sommige analisten en journalisten halen hem regelmatig weer uit de kast, en we hopen deze belachelijke opvatting eindelijk de wereld uit te helpen.

## Hardware

Firebird staat bekend om zijn ongelooflijke schaalbaarheid en dit onderzoek heeft dat nogmaals bevestigd. Het oorspronkelijke doel van dit experiment was alleen het aanmaken van een Firebird-database van 1Tb, dus gebruikten we een gewone desktopcomputer:

Tabel 1: Hardware

Component Parameters
CPU AMDAthlon 64 x2 5200
RAM 4GB
Moederbord MSI K9N Platinum
HDD1 (besturingssysteem en temp) ST3160815AS, 160GB, SATA II
HDD2 (hulp) HDT721064SLA360, 640GB,SATAII
HDD2 (hulp) HDS728080PLA380, 80GB, SATA I
HDD3 (database) ST31500341AS, 1.5TB, SATA II (Firmware CC1H)

In wezen hebben we de 1,5Tb HDD in een van onze kantoor-desktops geplaatst, zonder enige andere aanpassingen. Deze HDD werd geformatteerd met clustergrootte 16Kb (hetzelfde als de paginagrootte van de database, zoals je hieronder kunt zien).

Software

Omdat het een desktopcomputer is, is het besturingssysteem Windows XP Professional SP3, 32bit. Om de test daadwerkelijk uit te voeren gebruikten we de loader uit de op TPC gebaseerde toolkit (download deze van http://ibdeveloper.com/tests/tpc-c/, zowel binaries als broncode zijn beschikbaar).

We willen benadrukken dat de loader gegevens invoegt zoals ze in een realistisch scenario zouden worden ingevoegd: records worden ingevoegd en bevinden zich in de database (en op fysieke schijfgebieden) in verschillende master-detail-subdetail-tabellen, niet tabel voor tabel.

Tabel 2: Software

Software Versie
Besturingssysteem Windows XP Professional SP3, 32bit
Firebird 2.1.3 SuperServer (snapshot)
Loader Aangepaste loader uit op tpc gebaseerde test

Plan

We hadden een heel eenvoudig plan voor dit experiment:

  1. Database aanmaken en vullen met 1Tb aan gegevens, zonder indices
  2. Primaire sleutels en bijbehorende indices aanmaken (dus eigenlijk is de database groter dan 1Tb)
  3. Databasestatistieken verzamelen
  4. Verschillende SQL-query’s uitvoeren en de databaseprestaties inschatten

Database- en Firebird-serverconfiguratie

De database heeft paginagrootte 16384 bytes, hetzelfde als de HDD-cluster, om de schijfdoorvoerprestaties te maximaliseren (om 1 pagina per I/O-cyclus te lezen/schrijven).

In de Firebird-configuratie hebben we een extra map voor temp-ruimte geconfigureerd en deze naar de schijf van 640Gb verwezen (waar ~300Gb vrij was).

Laadstap

Gegevens werden in deze database geladen in verschillende stappen. De computer werd tijdens de laadoperaties gebruikt als gewone desktop (we hebben MS Office, Firefox, IBAnalyst, enz. - ongeveer 8-12 programma’s draaiden tegelijkertijd). Als we de hardware alleen voor deze taak zouden hebben gereserveerd, zou het waarschijnlijk sneller zijn geweest, dus beschouw deze waarden alleen als een low-end voorbeeld; het zijn beslist niet de topresultaten.

Tabel 3: Laadoperaties

| |

Beschrijving Waarde
Tijd om te laden ~70 uur
Totaal ingevoegde records 6,2 miljard
Gemiddelde invoegsnelheid 24500 records/seconde
Gemiddelde recordgrootte 146 bytes (min 13 bytes, max - 600 bytes)
Transacties 646489

We hebben ~4 dagen besteed aan het laden, en daarna hadden we een Firebird-database met precies 1Tb grootte (d.w.z. 1 099 900 125 184 bytes).

Hieronder kun je de databasegroei en transactiedynamiek zien in FBDataGuard Viewer:

Indices

We hebben indices één voor één aangemaakt en de aanmaaktijd en de bijbehorende grootte van het tijdelijke bestand dat voor sorteren werd gebruikt, bijgehouden.

De grootste index werd aangemaakt voor tabel ORDER_LINE. De primaire sleutel bevat vier velden (Smallint, Smallint, Integer en Smallint). Het tijdelijke bestand voor deze sorteersindex was 182Gb, en de uiteindelijke indexgrootte in de database is 29,3Gb.

Het is interessant om te zien dat zelfs de index voor een tabel met 3,8 miljard records diepte = 3 heeft, omdat de paginagrootte 16384 bytes was, dus er is geen overhead bij het zoeken naar gegevens met behulp van de primaire sleutel voor deze tabel.

Statistieken

Daarna hebben we databasestatistieken verzameld. Dit duurde 7 uur 32 min 45 sec.

We hebben de belangrijkste statistische informatie in één tabel gezet en enkele query’s en tijdmetingen opgenomen:

Tabel 4: Geconsolideerde statistieken voor 1Tb-database

Tabelnaam Recordaantallen Grootte, gb Uitvoeringstijd van select count(*) Aanmaaktijd index Grootte tmp-bestand, Gb Indexgrootte, 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

Databasestatistieken kunnen worden gedownload van hier.

Je kunt de gratis FBDataGuard Community Edition Viewer gebruiken om tekstgegevens te interpreteren en niet alleen databaseprestatiemetingen te zien, maar ook CPU- en geheugenverbruik.

Query’s

Allereerst hebben we select count(*)-query’s uitgevoerd op verschillende tabellen (zie de 4e kolom in Tabel 4 hierboven). Zoals je weet is vanwege de multi-versie-aard van Firebird select count(*) voor een hele tabel een dure operatie voor de server, omdat het bezoeken van elke pagina vereist, en ervaren Firebird-ontwikkelaars gebruiken geen select count(*), maar we gebruikten het om de algehele prestatieverhouding van database en hardware te demonstreren.

Na de select count-query’s hebben we query’s uit een realistisch scenario uitgevoerd en, om eerlijk te zijn, waren we verbaasd over zulke goede resultaten. Oordeel zelf:

Query Statistieken Beschrijving
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
Eenvoudige join van tabellen met 12400 en 372000000 records, geen WHERE-voorwaarden. “Avg fetch time = 6.08 ms” geldt voor het ophalen van de eerste rij.
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
Join van dezelfde tabellen met een voorwaarde die selectie van recente records afdwingt. “Avg fetch time = 6.00 ms” geldt voor het ophalen van de eerste rij.
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
Records tellen voor de vorige query
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
Query op de grootste tabel (3,8 miljard records). “Avg fetch time = 7.23 ms” geldt voor het ophalen van de eerste rij.
<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 | Dezelfde query op de grootste tabel (3,8 miljard records), maar dit keer hebben we alle records opgehaald (299245 records opgehaald). | | | | | 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 | Tabellen joinen met 1240 records en 372 miljoen records. | | 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 | Records tellen voor de vorige query |

Samenvatting

In dit experiment laat Firebird de volgende resultaten zien

  1. Een onbetwiste capaciteit om grote databases te verwerken. We zijn er vrij zeker van dat het mogelijk is om een database van 32 Tb te creëren en te gebruiken op geschikte hardware, en dat Firebird dezelfde hoge prestaties zal laten zien als bij kleinere databases (dat wil zeggen 1 Tb en kleiner).

  2. Goede schaalbaarheid en een verbazingwekkend kleine footprint. Een database van 1 Tb werd gecreëerd op een gewone desktopcomputer en, belangrijker nog, kan worden gebruikt om algemene queries uit te voeren: als je niet miljoenen records ophaalt, is de snelheid van de query dezelfde als bij databases van gemiddelde grootte (10-15 Gb).

Dit is niet het einde van dit experiment: we zijn van plan om enkele queries uit te voeren, aanvullende statistieken te verzamelen en binnenkort een gedetailleerder rapport te publiceren. Houd ons in de gaten.

Contacten

Stuur al je vragen en verzoeken naar [email protected]