Hier is een vollediger antwoord met betrekking tot InnoDB. Het is een beetje een langdurig proces, maar het kan de moeite waard zijn.
Houd er rekening mee dat /var/lib/mysql/ibdata1
is het drukste bestand in de InnoDB-infrastructuur. Het bevat normaal gesproken zes soorten informatie:
- Tabelgegevens
- Tabelindexen
- MVCC (Multiversioning Concurrency Control)
Gegevens
- Segmenten terugdraaien
- Spatie ongedaan maken
- Tabelmetadata (Data Dictionary)
- Dubbele schrijfbuffer (schrijven op de achtergrond om afhankelijkheid van OS-caching te voorkomen)
- Buffer invoegen (beheer van wijzigingen in niet-unieke secundaire indexen)
- Zie de
Geïllustreerde weergave van ibdata1
InnoDB-architectuur
Veel mensen maken meerdere ibdata
bestanden in de hoop op beter schijfruimtebeheer en betere prestaties, maar die overtuiging is onjuist.
Kan ik OPTIMALISEREN uitvoeren TABEL
?
Helaas draait OPTIMIZE TABLE
tegen een InnoDB-tabel die is opgeslagen in het gedeelde tabelruimtebestand ibdata1
doet twee dingen:
- Maakt de gegevens en indexen van de tabel aaneengesloten binnen
ibdata1
- Maakt
ibdata1
groeien omdat de aangrenzende gegevens- en indexpagina's worden toegevoegd naaribdata1
U kunt echter tabelgegevens en tabelindexen scheiden van ibdata1
en beheer ze onafhankelijk.
Kan ik OPTIMALISEREN uitvoeren TABEL
met innodb_file_per_table
?
Stel dat u innodb_file_per_table
naar /etc/my.cnf (my.ini)
. Kun je dan gewoon OPTIMALISEERTABEL uitvoeren
op alle InnoDB-tafels?
Goed nieuws :Wanneer u OPTIMIZE TABLE
met innodb_file_per_table
ingeschakeld, zal dit een .ibd
. opleveren bestand voor die tabel. Als u bijvoorbeeld tabel mydb.mytable
. heeft met een datadir van /var/lib/mysql
, zal het het volgende produceren:
/var/lib/mysql/mydb/mytable.frm
/var/lib/mysql/mydb/mytable.ibd
De .ibd
bevat de gegevenspagina's en indexpagina's voor die tabel. Geweldig.
Slecht nieuws :Het enige dat u hebt gedaan, is de gegevenspagina's en indexpagina's van mydb.mytable
extraheren van het leven in ibdata
. Het gegevenswoordenboekitem voor elke tabel, inclusief mydb.mytable
, staat nog steeds in de datadictionary (zie de Geïllustreerde weergave van ibdata1
). JE KUNT NIET ALLEEN EENVOUDIG VERWIJDEREN ibdata1
OP DIT PUNT!!! Houd er rekening mee dat ibdata1
is helemaal niet gekrompen.
InnoDB Infrastructuur opschonen
ibdata1
verkleinen eens en voor altijd moet u het volgende doen:
-
Dump (bijv. met
mysqldump
) alle databases in een.sql
tekstbestand (SQLData.sql
wordt hieronder gebruikt) -
Verwijder alle databases (behalve
mysql
eninformation_schema
) WAARSCHUWING :Voer als voorzorgsmaatregel dit script uit om er absoluut zeker van te zijn dat alle gebruikerstoelagen aanwezig zijn:mkdir /var/lib/mysql_grants cp /var/lib/mysql/mysql/* /var/lib/mysql_grants/. chown -R mysql:mysql /var/lib/mysql_grants
-
Log in op mysql en voer
SET GLOBAL innodb_fast_shutdown =0;
uit (Hierdoor worden alle resterende transactiewijzigingen vanib_logfile0
volledig gewist enib_logfile1
) -
MySQL afsluiten
-
Voeg de volgende regels toe aan
/etc/my.cnf
(ofmijn.ini
op Windows)[mysqld] innodb_file_per_table innodb_flush_method=O_DIRECT innodb_log_file_size=1G innodb_buffer_pool_size=4G
(Sidenote:wat je set ook is voor
innodb_buffer_pool_size
, zorg ervoor datinnodb_log_file_size
is 25% vaninnodb_buffer_pool_size
.Ook:
innodb_flush_method=O_DIRECT
is niet beschikbaar op Windows) -
Verwijder
ibdata*
enib_logfile*
, Optioneel kunt u alle mappen verwijderen in/var/lib/mysql
, behalve/var/lib/mysql/mysql
. -
Start MySQL (hiermee wordt
ibdata1
opnieuw gemaakt) [standaard 10 MB] enib_logfile0
enib_logfile1
met elk 1G). -
Importeer
SQLData.sql
Nu, ibdata1
zal nog steeds groeien maar alleen tabelmetadata bevatten omdat elke InnoDB-tabel buiten ibdata1
zal bestaan . ibdata1
zal niet langer InnoDB-gegevens en indexen voor andere tabellen bevatten.
Stel dat u bijvoorbeeld een InnoDB-tabel heeft met de naam mydb.mytable
. Als je kijkt in /var/lib/mysql/mydb
, ziet u twee bestanden die de tabel vertegenwoordigen:
mijntabel.frm
(Storage Engine Header)mijntabel.ibd
(Tabelgegevens en indexen)
Met de innodb_file_per_table
optie in /etc/my.cnf
, kunt u OPTIMIZE TABLE mydb.mytable
. uitvoeren en het bestand /var/lib/mysql/mydb/mytable.ibd
zal zelfs krimpen.
Ik heb dit vele malen gedaan in mijn carrière als MySQL DBA. De eerste keer dat ik dit deed, kromp ik zelfs een 50GB ibdata1
bestand tot slechts 500 MB!
Probeer het eens. Als je hier nog vragen over hebt, stel ze gerust. Geloof me; dit werkt zowel op korte als op lange termijn.
WAARSCHUWING
Bij stap 6, als mysql niet opnieuw kan opstarten vanwege de mysql
schema begin verwijderd, kijk terug naar stap 2. U hebt de fysieke kopie gemaakt van de mysql
schema. U kunt het als volgt herstellen:
mkdir /var/lib/mysql/mysql
cp /var/lib/mysql_grants/* /var/lib/mysql/mysql
chown -R mysql:mysql /var/lib/mysql/mysql
Ga terug naar stap 6 en ga verder
UPDATE 2013-06-04 11:13 EDT
Met betrekking tot het instellen van innodb_log_file_size tot 25% van innodb_buffer_pool_size in stap 5 is die algemene regel nogal ouderwets.
Terug op 03 juli 2006
, had Percona een mooi artikel waarom je een goede innodb_log_file_size moet kiezen . Later, op 21 november 2008
, volgde Percona een ander artikel op hoe de juiste grootte te berekenen op basis van piekwerkbelasting en een uur aan wijzigingen te behouden
.
Sindsdien heb ik berichten in de DBA StackExchange geschreven over het berekenen van de loggrootte en waar ik naar die twee Percona-artikelen heb verwezen.
27 aug. 2012
:Juiste afstemming voor 30GB InnoDB-tabel op server met 48GB RAM17 januari 2013
:MySQL 5.5 - Innodb - innodb_log_file_size groter dan 4GB gecombineerd?
Persoonlijk zou ik nog steeds gaan voor de 25%-regel voor een eerste installatie. Omdat de werklast in de loop van de tijd in productie nauwkeuriger kan worden bepaald, kunt u het formaat wijzigen de logboeken tijdens een onderhoudscyclus in slechts enkele minuten.