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 creëren?
Veel bedrijven werken met grote Firebird-databases en vertrouwen erop om belangrijke bedrijfsprocessen te ondersteunen. Sommige Firebird-databases zijn al honderden gigabytes groot en blijven groeien (zie de sectie “Wie is groot?”), en het is gemakkelijk om het moment te voorspellen waarop ze 2, 3 of 5 keer groter worden. Databasebeheerders en leveranciers zijn daarom geïnteresseerd om het gedrag van Firebird met grote databases te onderzoeken en aanbevelingen te krijgen over hoe ze deze moeten beheren.
Ook de belangrijke reden die we in gedachten hadden bij het creëren van een 1Tb Firebird-database was de definitieve eliminatie van de heersende perceptie van Firebird als database-engine voor “kleine databases”. Deze mythe lijkt nu dood te zijn, maar sommige analisten en journalisten halen hem regelmatig uit het graf, en we hopen eindelijk af te rekenen met deze belachelijke perceptie.
| ## Hardware |
Firebird staat bekend om zijn ongelooflijke schaalbaarheid en dit onderzoek heeft dat opnieuw bevestigd. Het oorspronkelijke doel van dit experiment was alleen het creëren 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 tijdelijk) | 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 essentie hebben we de 1.5Tb HDD in een van onze kantoor-desktops geplaatst, zonder andere wijzigingen. Deze HDD was geformatteerd met een clustergrootte van 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 van een op TPC gebaseerde toolkit (download het 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 van tpc-based test |
Plan
We hadden een zeer eenvoudig plan voor dit experiment:
- Database creëren en vullen met 1Tb gegevens, zonder indexen
- Primaire sleutels en passende indexen creëren (dus de werkelijke databasegrootte is meer dan 1Tb)
- Databasestatistieken verzamelen
- Verschillende SQL-query’s uitvoeren en de databaseprestaties inschatten
Database- en Firebird-serverconfiguratie
De database heeft een paginagrootte van 16384 bytes, hetzelfde als de HDD-cluster, om de schijfdoorvoerprestaties te maximaliseren (om 1 pagina in één I/O-cyclus te lezen/schrijven).
In de Firebird-configuratie hebben we een extra directory geconfigureerd voor tijdelijke ruimte en deze naar de schijf met 640Gb verwezen (waar ~300Gb vrij was).
Laadstap
Gegevens werden in verschillende stappen in deze database geladen. De computer werd tijdens laadoperaties gebruikt als gewone desktop (we hadden MS Office, Firefox, IBAnalyst, enz. - ongeveer 8-12 programma’s draaiden tegelijkertijd). Als we de hardware alleen voor deze taak zouden hebben toegewijd, zou het waarschijnlijk sneller zijn geweest, dus beschouw deze waarden alleen als een low-end voorbeeld; ze zijn zeker 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 exact 1Tb grootte (d.w.z. 1 099 900 125 184 bytes).
Hieronder zie je de databasegroei en transactiedynamiek in FBDataGuard Viewer:

Indexen
We hebben indexen één voor één gecreëerd en de tijd van hun creatie en de juiste grootte van het tijdelijke bestand dat voor sorteren werd gebruikt, geteld.
De grootste index werd gecreëerd voor de tabel ORDER_LINE. De primaire sleutel bevat vier velden (Smallint, Smallint, Integer en Smallint). Het tijdelijke bestand voor deze sorteerindex 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 van gegevens met behulp van de primaire sleutel voor deze tabel.
Statistieken
Daarna hebben we databasestatistieken verzameld. Het duurde 7 uur 32 min 45 sec.
We hebben de belangrijkste statistische informatie in één tabel geplaatst en enkele query’s en tijdmetingen opgenomen:
Tabel 4: Geconsolideerde statistieken voor 1Tb database
| Tabelnaam | Recordtellingen | Grootte, gb | Uitvoeringstijd van select count(*) | Indexcreatietijd | Tmp bestandsgrootte, 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 hier worden gedownload.
Je kunt de gratis FBDataGuard Community Edition Viewer gebruiken om tekstgegevens te interpreteren en niet alleen databaseprestatiemetingen te zien, maar ook CPU- en geheugengebruik.
Query’s
Allereerst hebben we select count(*)-query’s uitgevoerd op verschillende tabellen (zie 4e kolom in Tabel 4 hierboven). Zoals je weet, is select count(*) voor de hele tabel vanwege de multi-version aard van Firebird 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 select count-query’s hebben we query’s uit een realistisch scenario uitgevoerd en, om eerlijk te zijn, we waren verbaasd over zulke goede resultaten. Zie 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)) ------ Prestatie-info —— Voorbereidingstijd = 15ms Uitvoeringstijd = 79ms Gemiddelde ophaaltijd = 6.08 ms Huidig geheugen = 272 264 476 Max geheugen = 272 514 048 Geheugenbuffers = 16 384 Leest van schijf naar cache = 82 Schrijft van cache naar schijf = 0 Ophaalt uit cache = 3 648 |
Eenvoudige join van tabellen met 12400 en 372000000 records, geen WHERE-voorwaarden. “Gemiddelde ophaaltijd = 6.08 ms” is 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)) ------ Prestatie-info —— Voorbereidingstijd = 16ms Uitvoeringstijd = 78ms Gemiddelde ophaaltijd = 6.00 ms Huidig geheugen = 272 266 148 Max geheugen = 272 514 048 Geheugenbuffers = 16 384 Leest van schijf naar cache = 88 Schrijft van cache naar schijf = 0 Ophaalt uit cache = 3 656 |
Join van dezelfde tabellen met een voorwaarde die selectie van recente records forceert. “Gemiddelde ophaaltijd = 6.00 ms” is voor het ophalen van de eerste rij. |
| select count(*) from WAREHOUSE, customer where c_w_id = w_id and c_w_id = 10000 Resultaat = 30000 |
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE)) ------ Prestatie-info —— Voorbereidingstijd = 0ms Uitvoeringstijd = 453ms Gemiddelde ophaaltijd = 453.00 ms Huidig geheugen = 272 263 844 Max geheugen = 272 514 048 Geheugenbuffers = 16 384 Leest van schijf naar cache = 1 048 Schrijft van cache naar schijf = 0 Ophaalt uit cache = 60 024 |
Tel records voor vorige query |
| SELECT * FROM ORDER_LINE WHERE OL_W_ID = 500 |
Plan PLAN (ORDER_LINE INDEX (ORDER_LINE_PK)) ------ Prestatie-info —— Voorbereidingstijd = 0ms Uitvoeringstijd = 94ms Gemiddelde ophaaltijd = 7.23 ms Huidig geheugen = 136 445 536 Max geheugen = 136 592 176 Geheugenbuffers = 8 192 Leest van schijf naar cache = 150 Schrijft van cache naar schijf = 0 Ophaalt uit cache = 2 402 |
Query naar de grootste tabel (3.8B records). “Gemiddelde ophaaltijd = 7.23 ms” is voor het ophalen van de eerste rij. |
<br>Plan<br><br>PLAN (ORDER_LINE INDEX (ORDER_LINE_PK))<br><br> <br><br>------ Prestatie-info ------<br><br>Voorbereidingstijd = 0ms<br><br>Uitvoeringstijd = 3s 438ms<br><br>Gemiddelde ophaaltijd = 0.01 ms<br><br>Huidig geheugen = 136 445 496<br><br>Max geheugen = 136 592 176<br><br>Geheugenbuffers = 8 192<br><br>Leest van schijf naar cache = 1 840<br><br>Schrijft van cache naar schijf = 0<br><br>Ophaalt uit 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))
------ Prestatie-info ——
Voorbereidingstijd = 0ms
Uitvoeringstijd = 125ms
Gemiddelde ophaaltijd = 9,62 ms
Huidig geheugen = 272 270 824
Maximaal geheugen = 272 514 048
Geheugenbuffers = 16 384
Leesbewerkingen van schijf naar cache = 91
Schrijfbewerkingen van cache naar schijf = 0
Ophaalbewerkingen uit cache = 3 659 | Tabellen samenvoegen met 1240 records en 372M records. |
| select count(*)
from WAREHOUSE, customer
where c_w_id = w_id and (c_w_id > 8000) and (c_w_id < 10000)
Resultaat = 59 970 000 | Plan
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Prestatie-info ——
Voorbereidingstijd = 0ms
Uitvoeringstijd = 13m 4s 718ms
Gemiddelde ophaaltijd = 784 718,00 ms
Huidig geheugen = 272 268 532
Maximaal geheugen = 272 514 048
Geheugenbuffers = 16 384
Leesbewerkingen van schijf naar cache = 2 332 583
Schrijfbewerkingen van cache naar schijf = 0
Ophaalbewerkingen uit cache = 119 977 902 | Records tellen voor de vorige query |
Samenvatting
In dit experiment toont Firebird de volgende resultaten
-
Onmiskenbaar vermogen 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 Firebird zal dezelfde hoge prestaties tonen als bij kleinere databases (d.w.z. 1Tb en lager).
-
Goede schaalbaarheid en verbazingwekkend kleine voetafdruk. Een database van 1Tb is gecreëerd op een gewone desktopcomputer en, belangrijker nog, deze kan worden gebruikt om algemene queries uit te voeren: als je geen miljoenen records ophaalt, is de snelheid van de query hetzelfde als bij databases van gemiddelde omvang (10-15Gb).
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. Blijf op de hoogte.
Contact
Stuur al je vragen en verzoeken naar [email protected]