sql >> Databasteknik >  >> RDS >> Mysql

Hur gör man:Rengör en mysql InnoDB-lagringsmotor?

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:

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 ibdata1 växa eftersom de sammanhängande data- och indexsidorna läggs till till ibdata1

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:

  1. Dump (t.ex. med mysqldump ) alla databaser till en .sql textfil (SQLData.sql används nedan)

  2. Släpp alla databaser (förutom mysql och informationsschema ) 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
    
  3. Logga in på mysql och kör SET GLOBAL innodb_fast_shutdown =0; (Detta kommer att ta bort alla återstående transaktionsändringar från ib_logfile0 och ib_logfile1 )

  4. Stäng av MySQL

  5. Lägg till följande rader i /etc/my.cnf (eller my.ini på 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 att innodb_log_file_size är 25 % av innodb_buffer_pool_size .

    Även:innodb_flush_method=O_DIRECT är inte tillgängligt på Windows)

  6. Ta bort ibdata* och ib_logfile* , Alternativt kan du ta bort alla mappar i /var/lib/mysql , förutom /var/lib/mysql/mysql .

  7. Starta MySQL (Detta kommer att återskapa ibdata1 [10 MB som standard] och ib_logfile0 och ib_logfile1 vid 1G vardera).

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

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.



  1. Python psycopg2 infogas inte i postgresql-tabellen

  2. Hur man ansluter till Oracle med hjälp av Service Name istället för SID

  3. Bygg en offline-först applikation med Node.js och SQLite

  4. Hur ringer man upp Oracle Stored Procedure i Python?