En vigtig faktor i databasens ydeevne er lagermotoren, der bruges af databasen, og mere specifikt dens tabeller. Forskellige lagermotorer giver bedre ydeevne i én situation frem for en anden. Til generel brug er der to kandidater, der skal tages i betragtning. Disse er MyISAM, som er standard MySQL-lagringsmotoren, eller InnoDB, som er en alternativ motor indbygget i MySQL beregnet til højtydende databaser. Før vi kan forstå forskellen mellem de to lagermotorer, skal vi forstå udtrykket "låsning."
Hvad låser MySQL?
For at beskytte integriteten af de data, der er gemt i databaser, anvender MySQL låsning. Låsning betyder ganske enkelt at beskytte data mod at blive tilgået. Når en lås anvendes, kan dataene ikke ændres, undtagen af den forespørgsel, der startede låsen. Låsning er en nødvendig komponent for at sikre nøjagtigheden af de lagrede oplysninger. Hver lagermotor har en forskellig metode til låsning. Afhængigt af dine data og forespørgselspraksis kan én motor overgå en anden. I denne serie vil vi se på de to mest almindelige typer låse, der anvendes af vores to lagermotorer.
Bordlåsning: Teknikken til at låse en hel tabel, når en eller flere celler i tabellen skal opdateres eller slettes. Tabellåsning er standardmetoden, der anvendes af standardlagermaskinen, MyISAM.
Eksempel:MyISAM-tabellåsning | Kolonne A | Kolonne B | Kolonne C | |
Forespørgsel 1 OPDATERING | Række 1 | Skriver | data | data |
Forespørgsel 2 VÆLG (Vent) | Række 2 | data | data | data |
Forespørgsel 3 OPDATERING (Vent) | Række 3 | data | data | data |
Forespørgsel 4 VÆLG (Vent) | Række 4 | data | data | data |
Forespørgsel 5 VÆLG (Vent) | Række 5 | data | data | data |
Eksemplet illustrerer, hvordan en enkelt skriveoperation låser hele tabellen, hvilket får andre forespørgsler til at vente på, at UPDATE-forespørgslen er færdig. |
Låsning på rækkeniveau: Handlingen med at låse en effektiv række af rækker i en tabel, mens en eller flere celler inden for området ændres eller slettes. Låsning på rækkeniveau er den metode, der bruges af InnoDB-lagringsmotoren og er beregnet til højtydende databaser.
Eksempel:InnoDB rækkeniveaulåsning | Kolonne A | Kolonne A | Kolonne A | |
Forespørgsel 1 OPDATERING | Række 1 | Skriver | data | data |
Forespørgsel 2 SELECT | Række 2 | Læser | data | data |
Forespørgsel 3 OPDATERING | Række 3 | data | Skriver | data |
Forespørgsel 4 VÆLG | Række 4 | Læser | Læser | Læser |
Forespørgsel 5 SELECT | Række 5 | Læser | data | Læser |
Eksemplet viser, hvordan brug af låsning på rækkeniveau giver mulighed for at køre flere forespørgsler på individuelle rækker ved kun at låse de rækker, der opdateres, i stedet for hele tabellen. |
MyISAM vs. InnoDB
Ved at sammenligne de to lagermotorer kommer vi til kernen af argumentet mellem at bruge InnoDB over MyISAM. En applikation eller et websted, der har en ofte brugt tabel, fungerer usædvanligt godt ved at bruge InnoDB-lagringsmotoren ved at løse tabellåsende flaskehalse. Spørgsmålet om at bruge den ene frem for den anden er imidlertid subjektiv, da ingen af dem er perfekte i alle situationer. Der er styrker og begrænsninger ved begge lagringsmotorer. Intim viden om databasestrukturen og forespørgselspraksis er afgørende for at vælge den bedste lagringsmotor til dine tabeller.
MyISAM vil udkonkurrere InnoDB på store tabeller, der kræver meget mere læseaktivitet i forhold til skriveaktivitet. MyISAMs læsbarhed overstråler InnoDB, fordi det er hurtigere at låse hele tabellen end at finde ud af, hvilke rækker der er låst i tabellen. Jo flere oplysninger i tabellen, jo mere tid tager det InnoDB at finde ud af, hvilke der ikke er tilgængelige. Hvis din applikation er afhængig af enorme tabeller, der ikke ændrer data ofte, så vil MyISAM overgå InnoDB. Omvendt klarer InnoDB MyISAM, når data i tabellen ændres hyppigt. Tabelændringer skriver data mere end læsning af data pr. sekund. I disse situationer kan InnoDB følge med i store mængder af anmodninger nemmere end at låse hele bordet for hver enkelt.
Skal jeg bruge InnoDB med WordPress, Magento eller Joomla Sites?
Det korte svar her er ja, i de fleste tilfælde. Liquid Webs mest hjælpsomme mennesker til at hoste supportteams er stødt på adskillige flaskehalse, når kunderne bruger nogle af dagens standard webapplikationer. De fleste brugere af populære tredjepartsapplikationer som WordPress, Magento og Joomla har begrænset kendskab til de underliggende databasekomponenter eller kode, der er involveret, for at kunne træffe en informeret beslutning om lagringsmotorer. De fleste tabellåsende flaskehalse fra disse indholdsstyringssystemer (CMS) løses generelt ved at ændre alle tabellerne for webstedet til InnoDB i stedet for standard MyISAM. Hvis du er vært for mange af disse typer CMS på din server, vil det være en fordel at ændre standardlagringsmotoren i MySQL til at bruge InnoDB til alle nye tabeller, så eventuelle nye tabelinstallationer starter med InnoDB.
Indstilling af standardlagermotoren
Indstil din standardlagermaskine til InnoDB ved at tilføje default_storage_engine=InnoDB til [mysqld] sektionen af systemkonfigurationsfilen placeret på: /etc/my.cnf. Genstart af MySQL-tjenesten er nødvendig for, at serveren kan registrere ændringer i filen.
~ $ cat /etc/my.cnf
[mysqld]
log-error=/var/lib/mysql/mysql.err
innodb_file_per_table=1
default-storage-engine=innodb
innodb_buffer_pool_size=128M
Konvertering af alle tabeller mellem MyISAM og InnoDB
Desværre har MySQL ikke i sig selv en mulighed for at konvertere tabeller, så hver tabel skal ændres individuelt. Liquid Webs supportteam har sammensat en nem at følge vedligeholdelsesplan for denne proces. Scriptet, som du kan køre på den nødvendige server via shell-adgang (SSH), vil konvertere alle tabeller mellem storage-motorer.
Bemærk Planlæg i overensstemmelse hermed, når du udfører batch-operationer af denne art, bare i tilfælde af nedetid. Bedste praksis er at sikkerhedskopiere alle dine MySQL-databaser, før du implementerer en ændring af denne størrelsesorden, hvilket giver et let gendannelsespunkt for at forhindre tab af data.Trin 1: Forberedelse
Planlæg at starte på et tidspunkt på dagen, hvor nedetid ville have minimale konsekvenser. Denne proces i sig selv kræver ingen nedetid, dog kan nedetid være nødvendig for at komme sig efter uforudsete omstændigheder.
Trin 2: Sikkerhedskopier alle databaser til en fil
Kommandoen nedenfor opretter en enkelt fil-sikkerhedskopi af alle databaser med navnet all-databases-backup.sqld og kan slettes, når konverteringen er lykkedes, og der ikke er nogen synlige problemer. mysqldump --all-databases > all-databases-backup.sql
Trin 3: Optag eksisterende tabelmotorer til en fil
Kør følgende script for at optage de eksisterende tabelmotorer til en fil med navnet table-engine-backup.sql . Du kan derefter "importere" eller "køre" denne fil senere for at konvertere tilbage til deres originale motorer, hvis det er nødvendigt.
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=",Engine,";") FROM information_schema.tables WHERE table_schema NOT IN("mysql","information_schema","performance_schema");' | tee table-engine-backup.sql
Hvis du af en eller anden grund har brug for at vende tabelmotorerne tilbage, skal du køre:mysql < table-engine-backup.sql
Trin 4a: Konverter MyISAM-tabeller til InnoDB
Kommandoen nedenfor fortsætter, selvom en tabel fejler, og fortæller dig, hvilke tabeller der ikke kunne konverteres. Outputtet gemmes i filen med navnet convert-to-innodb.log til senere gennemgangw.
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=InnoDB;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "MyISAM";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-innodb.log
Trin 4b:Konverter alle InnoDB-tabeller til MyISAM
Denne kommando fortsætter, selvom en tabel fejler, og fortæller dig, hvilke tabeller der ikke kunne konverteres. Outputtet gemmes også i filen med navnet convert-to-myisam.log til senere gennemgang.
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=MyISAM;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "InnoDB";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-myisam.log
Konvertering af en enkelt tabel mellem MyISAM og InnoDB
De følgende kommandoer illustrerer, hvordan konvertering af en enkelt tabel udføres.
Bemærk Erstat databasenavn med det korrekte databasenavn og tabelnavn med det korrekte tabelnavn. Sørg for, at du har en gyldig sikkerhedskopi af den pågældende tabel, før du fortsætter.
Sikkerhedskopier et enkelt bord til en fil mysqldump database_name table_name > backup-table_name.sql
Konverter en enkelt tabel til InnoDB
mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=InnoDB;’
Konverter en enkelt tabel til MyISAM:
mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=MyISAM;’
Se vores andre artikler i denne serie, MySQL Performance:Identifying Long Queries, for at lokalisere langsomme forespørgsler i din database. Hold øje med vores næste artikel, hvor vi vil dække caching og optimering.