Här är ett mer komplett svar med avseende på InnoDB. Det är lite av en lång process, men kan vara värt ansträngningen.
Tänk på att /var/lib/mysql/ibdata1 är den mest trafikerade filen i InnoDB-infrastrukturen. Den innehåller normalt sex typer av information:
- Tabelldata
- Tabellindex
- MVCC (Multiversioning Concurrency Control)
Data
- Återställande segment
- Ångra mellanslag
- Tabellmetadata (Data Dictionary)
- Dubbel skrivbuffert (bakgrundsskrivning för att förhindra beroende av OS-cache)
- Infoga buffert (hanterar ändringar av icke-unika sekundära index)
- Se
Bildrepresentation av ibdata1
InnoDB-arkitektur

Många människor skapar flera ibdata filer som hoppas på bättre diskutrymmeshantering och prestanda, men den uppfattningen är felaktig.
Kan jag köra OPTIMERA TABELL
?
Tyvärr kör OPTIMERA TABELL
mot en InnoDB-tabell lagrad i den delade tabellutrymmesfilen ibdata1 gör två saker:
- Gör tabellens data och index sammanhängande inuti
ibdata1 - Gör
ibdata1växa eftersom de sammanhängande data- och indexsidorna läggs till tillibdata1
Du kan dock separera tabelldata och tabellindex från ibdata1 och hantera dem självständigt.
Kan jag köra OPTIMERA TABELL
med innodb_file_per_table
?
Anta att du skulle lägga till innodb_file_per_table
till /etc/my.cnf (my.ini) . Kan du då bara köra OPTIMERA TABELL
på alla InnoDB-tabeller?
Goda nyheter :När du kör OPTIMERA TABELL
med innodb_file_per_table
aktiverat, kommer detta att producera en .ibd fil för den tabellen. Till exempel, om du har tabellen mydb.mytable med en datadir för /var/lib/mysql , kommer det att producera följande:
/var/lib/mysql/mydb/mytable.frm/var/lib/mysql/mydb/mytable.ibd
.ibd kommer att innehålla datasidorna och indexsidorna för den tabellen. Bra.
Dåliga nyheter :Allt du har gjort är att extrahera datasidorna och indexsidorna för mydb.mytable från att bo i ibdata . Datadictionary-posten för varje tabell, inklusive mydb.mytable , finns fortfarande kvar i dataordboken (Se bildrepresentation av ibdata1
). DU KAN INTE BARA RADERA ibdata1 VID DENNA PUNKT !!! Observera att ibdata1 har inte krympt alls.
InnoDB Infrastructure Cleanup
För att krympa ibdata1 en gång för alla måste du göra följande:
-
Dump (t.ex. med
mysqldump) alla databaser till en.sqltextfil (SQLData.sqlanvänds nedan) -
Släpp alla databaser (förutom
mysqlochinformationsschema) VARNING :Som en försiktighetsåtgärd, kör det här skriptet för att vara helt säker på att du har alla användarbidrag på plats:mkdir /var/lib/mysql_grants cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/. chown -R mysql:mysql /var/lib/mysql_grants -
Logga in på mysql och kör
SET GLOBAL innodb_fast_shutdown =0;(Detta kommer att ta bort alla återstående transaktionsändringar frånib_logfile0ochib_logfile1) -
Stäng av MySQL
-
Lägg till följande rader i
/etc/my.cnf(ellermy.inipå Windows)[mysqld] innodb_file_per_table innodb_flush_method=O_DIRECT innodb_log_file_size=1G innodb_buffer_pool_size=4G(Sidenot:Oavsett vilken uppsättning du har för
innodb_buffer_pool_size, se till attinnodb_log_file_sizeär 25 % avinnodb_buffer_pool_size.Även:
innodb_flush_method=O_DIRECTär inte tillgängligt på Windows) -
Ta bort
ibdata*ochib_logfile*, Alternativt kan du ta bort alla mappar i/var/lib/mysql, förutom/var/lib/mysql/mysql. -
Starta MySQL (Detta kommer att återskapa
ibdata1[10 MB som standard] ochib_logfile0ochib_logfile1vid 1G vardera). -
Importera
SQLData.sql
Nu, ibdata1 kommer fortfarande att växa men bara innehålla tabellmetadata eftersom varje InnoDB-tabell kommer att existera utanför ibdata1 . ibdata1 kommer inte längre att innehålla InnoDB-data och index för andra tabeller.
Anta till exempel att du har en InnoDB-tabell som heter mydb.mytable . Om du tittar i /var/lib/mysql/mydb , kommer du att se två filer som representerar tabellen:
mytable.frm(Storage Engine Header)mytable.ibd(Tabelldata och index)
Med innodb_file_per_table alternativet i /etc/my.cnf , kan du köra OPTIMIZE TABLE mydb.mytable och filen /var/lib/mysql/mydb/mytable.ibd kommer faktiskt att krympa.
Jag har gjort detta många gånger under min karriär som MySQL DBA. Första gången jag gjorde det här krympte jag faktiskt 50 GB ibdata1 fil ner till endast 500 MB!
Ge det ett försök. Om du har ytterligare frågor om detta är det bara att fråga. Lita på mig; detta kommer att fungera på kort sikt såväl som på lång sikt.
VARNING
Vid steg 6, om mysql inte kan starta om på grund av mysql schema börjar släpptes, titta tillbaka på steg 2. Du gjorde den fysiska kopian av mysql schema. Du kan återställa den enligt följande:
mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
Gå tillbaka till steg 6 och fortsätt
UPPDATERING 2013-06-04 11:13 EDT
När det gäller inställning av innodb_log_file_size till 25 % av innodb_buffer_pool_size i steg 5 är den generella regeln ganska gammaldags.
Tillbaka den 3 juli 2006 , Percona hade en trevlig artikel varför man ska välja en riktig innodb_log_file_size a> . Senare, den 21 november 2008 , följde Percona upp med en annan artikel om hur man beräknar rätt storlek baserat på maximal arbetsbelastning och behåller en timmes ändringar
.
Jag har sedan dess skrivit inlägg i DBA StackExchange om att beräkna loggstorleken och var jag refererade till dessa två Percona-artiklar.
27 augusti 2012:Korrekt inställning för 30 GB InnoDB-tabell på server med 48 GB RAM17 januari 2013:MySQL 5.5 - Innodb - innodb_log_file_size högre än 4 GB tillsammans?
Personligen skulle jag fortfarande gå med 25%-regeln för en initial installation. Sedan, eftersom arbetsbelastningen kan bestämmas mer exakt över tiden i produktionen, kan du ändra storlek loggarna under en underhållscykel på bara några minuter.