Her er et mere komplet svar med hensyn til InnoDB. Det er lidt af en langvarig proces, men kan være besværet værd.
Husk at /var/lib/mysql/ibdata1
er den travleste fil i InnoDB-infrastrukturen. Det rummer normalt seks typer information:
- Tabeldata
- Tabelindekser
- MVCC (Multiversioning Concurrency Control)
Data
- Tilbageføringssegmenter
- Fortryd mellemrum
- Tabelmetadata (Data Dictionary)
- Dobbelt skrivebuffer (baggrundsskrivning for at forhindre afhængighed af OS-cache)
- Indsæt buffer (håndtering af ændringer til ikke-unikke sekundære indekser)
- Se
Billedfremstilling af ibdata1
InnoDB-arkitektur
Mange mennesker opretter flere ibdata
filer, der håber på bedre styring af diskplads og ydeevne, men den tro er forkert.
Kan jeg køre OPTIMER TABEL
?
Desværre kører OPTIMER TABEL
mod en InnoDB-tabel, der er gemt i den delte tablespace-fil ibdata1
gør to ting:
- Gør tabellens data og indekser sammenhængende inde i
ibdata1
- Laver
ibdata1
vokse, fordi de sammenhængende data- og indekssider er tilføjet tilibdata1
Du kan dog adskille tabeldata og tabelindekser fra ibdata1
og administrere dem uafhængigt.
Kan jeg køre OPTIMER TABEL
med innodb_file_per_table
?
Antag, at du skulle tilføje innodb_file_per_table
til /etc/my.cnf (my.ini)
. Kan du så bare køre OPTIMER TABEL
på alle InnoDB-tabellerne?
Gode nyheder :Når du kører OPTIMER TABEL
med innodb_file_per_table
aktiveret, vil dette producere en .ibd
fil til den tabel. For eksempel, hvis du har tabellen mydb.mytable
med en datadir på /var/lib/mysql
, vil det producere følgende:
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
.ibd
vil indeholde datasider og indekssider for den tabel. Fantastisk.
Dårlige nyheder :Alt du har gjort er at udtrække datasiderne og indekssiderne for mydb.mytable
fra at bo i ibdata
. Dataordbogsindgangen for hver tabel, inklusive mydb.mytable
, er stadig tilbage i dataordbogen (se billedrepræsentationen af ibdata1
). DU KAN IKKE BARE SLETTE ibdata1
PÅ DET PUNKT !!! Bemærk venligst, at ibdata1
er slet ikke krympet.
InnoDB Infrastructure Cleanup
For at formindske ibdata1
én gang for alle skal du gøre følgende:
-
Dump (f.eks. med
mysqldump
) alle databaser til en.sql
tekstfil (SQLData.sql
bruges nedenfor) -
Slip alle databaser (undtagen
mysql
oginformationsskema
) ADVARSEL :Som en sikkerhedsforanstaltning skal du køre dette script for at sikre dig, at du har alle brugerbevillinger på plads:mkdir /var/lib/mysql_grants cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/. chown -R mysql:mysql /var/lib/mysql_grants
-
Log ind på mysql og kør
SET GLOBAL innodb_fast_shutdown =0;
(Dette vil fuldstændig fjerne alle resterende transaktionsændringer fraib_logfile0
ogib_logfile1
) -
Luk MySQL
-
Tilføj følgende linjer til
/etc/my.cnf
(ellermy.ini
på Windows)[mysqld] innodb_file_per_table innodb_flush_method=O_DIRECT innodb_log_file_size=1G innodb_buffer_pool_size=4G
(Sidenote:Uanset dit sæt til
innodb_buffer_pool_size
, sørg forinnodb_log_file_size
er 25 % afinnodb_buffer_pool_size
.Også:
innodb_flush_method=O_DIRECT
er ikke tilgængelig på Windows) -
Slet
ibdata*
ogib_logfile*
, Du kan eventuelt fjerne alle mapper i/var/lib/mysql
, undtagen/var/lib/mysql/mysql
. -
Start MySQL (Dette vil genskabe
ibdata1
[10 MB som standard] ogib_logfile0
ogib_logfile1
ved 1G hver). -
Importer
SQLData.sql
Nu, ibdata1
vil stadig vokse, men kun indeholde tabelmetadata, fordi hver InnoDB-tabel vil eksistere uden for ibdata1
. ibdata1
vil ikke længere indeholde InnoDB-data og indekser for andre tabeller.
Antag for eksempel, at du har en InnoDB-tabel med navnet mydb.mytable
. Hvis du kigger i /var/lib/mysql/mydb
, vil du se to filer, der repræsenterer tabellen:
mytable.frm
(Storage Engine Header)mytable.ibd
(Tabeldata og indekser)
Med innodb_file_per_table
mulighed i /etc/my.cnf
, kan du køre OPTIMIZE TABLE mydb.mytable
og filen /var/lib/mysql/mydb/mytable.ibd
vil faktisk krympe.
Det har jeg gjort mange gange i min karriere som MySQL DBA. Faktisk, første gang jeg gjorde dette, krympede jeg 50 GB ibdata1
fil ned til kun 500 MB!
Giv det en chance. Hvis du har yderligere spørgsmål til dette, så bare spørg. Stol på mig; dette vil virke på kort sigt såvel som på lang sigt.
ADVARSEL
Ved trin 6, hvis mysql ikke kan genstarte på grund af mysql
skema start droppet, se tilbage på trin 2. Du har lavet den fysiske kopi af mysql
skema. Du kan gendanne den som følger:
mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
Gå tilbage til trin 6 og fortsæt
OPDATERING 2013-06-04 11:13 EDT
Med hensyn til indstilling af innodb_log_file_size til 25 % af innodb_buffer_pool_size i trin 5 er den generelle regel ret gammeldags.
Tilbage den 03. juli 2006
, Percona havde en god artikel hvorfor man skal vælge en ordentlig innodb_log_file_size a> . Senere, den 21. november 2008
, fulgte Percona op med endnu en artikel om hvordan man beregner den korrekte størrelse baseret på den maksimale arbejdsbelastning og holder en times ændringer
.
Jeg har siden skrevet indlæg i DBA StackExchange om beregning af logstørrelsen, og hvor jeg refererede til de to Percona-artikler.
27. august 2012
:Korrekt tuning til 30 GB InnoDB-tabel på server med 48 GB RAM17. januar 2013
:MySQL 5.5 - Innodb - innodb_log_file_size højere end 4 GB tilsammen?
Personligt ville jeg stadig gå med 25%-reglen for en indledende opsætning. Da arbejdsbyrden derefter kan bestemmes mere nøjagtigt over tid i produktionen, kan du ændre størrelsen logfilerne under en vedligeholdelsescyklus på få minutter.