Servertillverkare och molnleverantörer erbjuder olika typer av lagringslösningar för att tillgodose dina databasbehov. När vi köper en ny server eller väljer en molninstans för att köra vår databas frågar vi oss ofta – hur mycket diskutrymme ska vi allokera? Som vi kommer att ta reda på är svaret inte trivialt eftersom det finns ett antal aspekter att ta hänsyn till. Diskutrymme är något som måste tänkas på i förväg, eftersom att krympa och utöka diskutrymmet kan vara en riskabel operation för en diskbaserad databas.
I det här blogginlägget kommer vi att undersöka hur du initialt storleksanpassar ditt lagringsutrymme och sedan planerar för kapacitet för att stödja tillväxten av din MySQL- eller MariaDB-databas.
Hur MySQL använder diskutrymme
MySQL lagrar data i filer på hårddisken under en specifik katalog som har systemvariabeln "datadir". Innehållet i datadir kommer att bero på MySQL-serverversionen och de inlästa konfigurationsparametrarna och servervariablerna (t.ex. general_log, slow_query_log, binär logg).
Den faktiska lagrings- och hämtningsinformationen beror på lagringsmotorerna. För MyISAM-motorn lagras en tabells index i .MYI-filen, i datakatalogen, tillsammans med .MYD- och .frm-filerna för tabellen. För InnoDB-motorn lagras indexen i tabellutrymmet, tillsammans med tabellen. Om innodb_file_per_table alternativet är inställt, kommer indexen att finnas i tabellens .ibd-fil tillsammans med .frm-filen. För minnesmotorn lagras data i minnet (högen) medan strukturen lagras i .frm-filen på disken. I den kommande MySQL 8.0 tas metadatafilerna (.frm, .par, dp.opt) bort i och med introduktionen av det nya dataordboksschemat.
Det är viktigt att notera att om du använder InnoDB delat tabellutrymme för att lagra tabelldata (innodb_file_per_table=OFF ), förväntas din MySQL fysiska datastorlek växa kontinuerligt även efter att du har trunkerat eller raderat stora rader med data. Det enda sättet att återta det lediga utrymmet i den här konfigurationen är att exportera, ta bort de aktuella databaserna och återimportera tillbaka dem via mysqldump. Därför är det viktigt att ställa in innodb_file_per_table=ON om du är orolig för diskutrymmet, så när du trunkerar en tabell kan utrymmet återtas. Med den här konfigurationen kommer en enorm DELETE-operation inte att frigöra diskutrymme om inte OPTIMIZE TABLE exekveras efteråt.
MySQL lagrar varje databas i sin egen katalog under "datadir"-sökvägen. Dessutom kommer loggfiler och andra relaterade MySQL-filer som socket- och PID-filer, som standard, också att skapas under datadir. Av prestanda- och tillförlitlighetsskäl rekommenderas det att lagra MySQL-loggfiler på en separat disk eller partition - speciellt MySQL-felloggen och binära loggar.
Uppskattning av databasstorlek
Det grundläggande sättet att uppskatta storlek är att hitta tillväxtförhållandet mellan två olika tidpunkter och sedan multiplicera det med den aktuella databasstorleken. Att mäta din databastrafik under rusningstid för detta ändamål är inte den bästa praxis och representerar inte din databasanvändning som helhet. Tänk på en batchoperation eller en lagrad procedur som körs vid midnatt, eller en gång i veckan. Din databas kan potentiellt växa avsevärt på morgonen, innan den eventuellt krymps av en hushållsoperation vid midnatt.
Ett möjligt sätt är att använda våra säkerhetskopior som baselement för denna mätning. Fysisk säkerhetskopiering som Percona Xtrabackup, MariaDB Backup och ögonblicksbild av filsystemet skulle ge en mer exakt representation av din databasstorlek jämfört med logisk säkerhetskopiering, eftersom den innehåller den binära kopian av databasen och index. Logisk säkerhetskopiering som mysqldump lagrar bara SQL-satser som kan köras för att återskapa de ursprungliga databasobjektdefinitionerna och tabelldata. Ändå kan du fortfarande få ett bra tillväxtförhållande genom att jämföra mysqldump-säkerhetskopior.
Vi kan använda följande formel för att uppskatta databasstorleken:
Var,
- B - Aktuell veckas fullständiga backupstorlek,
- B - Föregående vecka full storlek för säkerhetskopiering,
- Dbdata - Total databasdatastorlek,
- Dbindex - Total databasindexstorlek,
- 52 - Antal veckor på ett år,
- Y - År.
Den totala databasstorleken (data och index) i MB kan beräknas genom att använda följande satser:
mysql> SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) "DB Size in MB" FROM information_schema.tables;
+---------------+
| DB Size in MB |
+---------------+
| 2013.41 |
+---------------+
Ovanstående ekvation kan ändras om du istället vill använda månatliga säkerhetskopior. Ändra det konstanta värdet på 52 till 12 (12 månader på ett år) och du är bra att gå.
Glöm inte heller att ta hänsyn till innodb_log_file_size x 2, innodb_data_file_path och för Galera Cluster, lägg till gcache.size värde.
Storleksuppskattning av binära loggar
Binära loggar genereras av MySQL-mastern för replikering och punkt-i-tid återställning. Det är en uppsättning loggfiler som innehåller information om dataändringar gjorda på MySQL-servern. Storleken på de binära loggarna beror på antalet skrivoperationer och det binära loggformatet - STATEMENT, ROW eller MIXED. Uttalandebaserad binär logg är vanligtvis mycket mindre jämfört med radbaserad binär logg, eftersom den bara består av skrivsatser medan den radbaserade består av modifierad radinformation.
Det bästa sättet att uppskatta den maximala diskanvändningen av binära loggar är att mäta den binära loggstorleken för en dag och multiplicera den med expire_logs_days värde (standard är 0 - ingen automatisk borttagning). Det är viktigt att ställa in expire_logs_days så att du kan uppskatta storleken korrekt. Som standard är varje binär logg begränsad till cirka 1 GB innan MySQL roterar den binära loggfilen. Vi kan använda en MySQL-händelse för att helt enkelt tömma den binära loggen för denna uppskattning.
Se först till att variabeln event_scheduler är aktiverad:
mysql> SET GLOBAL event_scheduler = ON;
Sedan, som en privilegierad användare (med EVENT- och RELOAD-privilegier), skapa följande händelse:
mysql> USE mysql;
mysql> CREATE EVENT flush_binlog
ON SCHEDULE EVERY 1 HOUR STARTS CURRENT_TIMESTAMP ENDS CURRENT_TIMESTAMP + INTERVAL 2 HOUR
COMMENT 'Flush binlogs per hour for the next 2 hours'
DO FLUSH BINARY LOGS;
För en skrivintensiv arbetsbelastning behöver du antagligen förkorta intervallet till 30 minuter eller 10 minuter innan den binära loggen når 1 GB maximal storlek, och sedan avrunda utmatningen upp till en timme. Verifiera sedan händelsens status genom att använda följande sats och titta på kolumnen LAST_EXECUTED:
mysql> SELECT * FROM information_schema.events WHERE event_name='flush_binlog'\G
...
LAST_EXECUTED: 2018-04-05 13:44:25
...
Ta sedan en titt på de binära loggarna vi har nu:
mysql> SHOW BINARY LOGS;
+---------------+------------+
| Log_name | File_size |
+---------------+------------+
| binlog.000001 | 146 |
| binlog.000002 | 1073742058 |
| binlog.000003 | 1073742302 |
| binlog.000004 | 1070551371 |
| binlog.000005 | 1070254293 |
| binlog.000006 | 562350055 | <- hour #1
| binlog.000007 | 561754360 | <- hour #2
| binlog.000008 | 434015678 |
+---------------+------------+
Vi kan sedan beräkna genomsnittet av tillväxten av våra binära loggar som är cirka ~562 MB per timme under rusningstid. Multiplicera detta värde med 24 timmar och expire_logs_days värde:
mysql> SELECT (562 * 24 * @@expire_logs_days);
+---------------------------------+
| (562 * 24 * @@expire_logs_days) |
+---------------------------------+
| 94416 |
+---------------------------------+
Vi kommer att få 94416 MB vilket är runt ~95 GB diskutrymme för våra binära loggar. Slavens reläloggar är i princip desamma som masterns binära loggar, förutom att de lagras på slavsidan. Därför gäller denna beräkning även för slavreläloggarna.
Spindelskiva eller Solid State?
Det finns två typer av I/O-operationer på MySQL-filer:
- Sekventiella I/O-orienterade filer:
- InnoDB-systemtabellutrymme (ibdata)
- MySQL-loggfiler:
- Binära loggar (binlog.xxxx)
- REDO-loggar (ib_logfile*)
- Allmänna loggar
- Långsamma frågeloggar
- Fellogg
- Slumpmässiga I/O-orienterade filer:
- InnoDB fil-per-tabell-datafil (*.ibd) med innodb_file_per_table=ON (standard).
Överväg att placera slumpmässiga I/O-orienterade filer i ett diskundersystem med hög kapacitet för bästa prestanda. Detta kan vara en flash-enhet - antingen SSD eller NVRAM-kort, eller höga RPM-spindelskivor som SAS 15K eller 10K, med hårdvaru-RAID-kontroller och batteristödd enhet. För sekventiella I/O-orienterade filer bör lagring på hårddisk med batteristödd skrivcache vara tillräckligt bra för MySQL. Observera att prestandaförsämring är sannolikt om batteriet är urladdat.
Vi kommer att täcka detta område (uppskattning av diskgenomströmning och filallokering) i ett separat inlägg.
Kapacitetsplanering och dimensionering
Kapacitetsplanering kan hjälpa oss att bygga en produktionsdatabasserver med tillräckligt med resurser för att överleva daglig verksamhet. Vi måste också ta hänsyn till oväntade behov, ta hänsyn till framtida lagrings- och diskkapacitetsbehov. Därför är kapacitetsplanering viktig för att säkerställa att databasen har tillräckligt med utrymme att andas tills nästa maskinvaruuppdateringscykel.
Det är bäst att illustrera detta med ett exempel. Med tanke på följande scenario:
- Nästa maskinvarucykel:3 år
- Aktuell databasstorlek:2013 MB
- Aktuell full backupstorlek (vecka N):1177 MB
- Tidigare fullständig säkerhetskopieringsstorlek (vecka N-1):936 MB
- Deltastorlek:241 MB per vecka
- Deltaförhållande:25,7 % ökning per vecka
- Totalt antal veckor på 3 år:156 veckor
- Uppskattning av total databasstorlek:((1177 - 936) x 2013 x 156)/936 =80856 MB ~ 81 GB efter 3 år
Om du använder binära loggar, summera det från värdet vi fick i föregående avsnitt:
- 81 + 95 =176 GB lagringsutrymme för databas och binära loggar.
Lägg till minst 100 % mer utrymme för drift- och underhållsuppgifter (lokal säkerhetskopiering, datalagring, fellogg, operativsystemfiler, etc):
- 176 + 176 =352 GB totalt diskutrymme.
Baserat på denna uppskattning kan vi dra slutsatsen att vi skulle behöva minst 352 GB diskutrymme för vår databas i 3 år. Du kan använda detta värde för att motivera ditt nya maskinvaruköp. Om du till exempel vill köpa en ny dedikerad server kan du välja 6 x 128 SSD RAID 10 med batteristödd RAID-kontroller som ger dig cirka 384 GB totalt diskutrymme. Eller, om du föredrar moln, kan du få 100 GB blocklagring med förberedd IOPS för vår databasanvändning på 81 GB och använda standardbeständig blocklagring för våra 95 GB binära loggar och annan operativ användning.
Lycka till med dimensioneringen!