sql >> Database >  >> RDS >> Mysql

Howto:een mysql InnoDB-opslagengine reinigen?

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:

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 naar ibdata1

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:

  1. Dump (bijv. met mysqldump ) alle databases in een .sql tekstbestand (SQLData.sql wordt hieronder gebruikt)

  2. Verwijder alle databases (behalve mysql en information_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
    
  3. Log in op mysql en voer SET GLOBAL innodb_fast_shutdown =0; uit (Hierdoor worden alle resterende transactiewijzigingen van ib_logfile0 volledig gewist en ib_logfile1 )

  4. MySQL afsluiten

  5. Voeg de volgende regels toe aan /etc/my.cnf (of mijn.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 dat innodb_log_file_size is 25% van innodb_buffer_pool_size .

    Ook:innodb_flush_method=O_DIRECT is niet beschikbaar op Windows)

  6. Verwijder ibdata* en ib_logfile* , Optioneel kunt u alle mappen verwijderen in /var/lib/mysql , behalve /var/lib/mysql/mysql .

  7. Start MySQL (hiermee wordt ibdata1 opnieuw gemaakt) [standaard 10 MB] en ib_logfile0 en ib_logfile1 met elk 1G).

  8. 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.

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.



  1. Gegevens invoegen en verwijderen in PostgreSQL

  2. Android met Room - Hoe een externe sleutel nullable in te stellen

  3. Kunnen we meerdere WITH AS hebben in één sql - Oracle SQL?

  4. Oracle instantclient DYLD_LIBRARY_PATH fout