sql >> Databasteknik >  >> RDS >> Mysql

Hur återställer man en enda MySQL-tabell med mysqldump?

Mysqldump är det mest populära logiska säkerhetskopieringsverktyget för MySQL. Den ingår i MySQL-distributionen, så den är redo att användas på alla MySQL-instanser.

Logiska säkerhetskopior är dock inte det snabbaste eller mest utrymmeseffektiva sättet att säkerhetskopiera MySQL-databaser, men de har en enorm fördel jämfört med fysiska säkerhetskopior.

Fysiska säkerhetskopior är vanligtvis allt eller inget typ av säkerhetskopior. Även om det kan vara möjligt att skapa partiell backup med Xtrabackup (vi beskrev detta i ett av våra tidigare blogginlägg), är det svårt och tidskrävande att återställa sådan backup.

I grund och botten, om vi vill återställa en enda tabell, måste vi stoppa hela replikeringskedjan och utföra återställningen på alla noder samtidigt. Detta är ett stort problem - nuförtiden har du sällan råd att stoppa alla databaser.

Ett annat problem är att tabellnivån är den lägsta granularitetsnivån du kan uppnå med Xtrabackup:du kan återställa en enskild tabell men du kan inte återställa en del av den. Logisk säkerhetskopiering kan dock återställas i form av att köra SQL-satser, därför kan den enkelt utföras på ett körande kluster och du kan (vi skulle inte kalla det lätt, men ändå) välja vilka SQL-satser som ska köras så att du kan gör en partiell återställning av en tabell.

Låt oss ta en titt på hur detta kan göras i den verkliga världen.

Återställa en enda MySQL-tabell med mysqldump

Tänk i början på att partiella säkerhetskopior inte ger en konsekvent bild av data. När du tar säkerhetskopior av separata tabeller kan du inte återställa sådan säkerhetskopia till en känd position i tid (till exempel för att tillhandahålla replikeringsslaven) även om du skulle återställa all data från säkerhetskopian. Med det här bakom oss, låt oss fortsätta.

Vi har en herre och en slav:

Datauppsättningen innehåller ett schema och flera tabeller:

mysql> SHOW SCHEMAS;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| performance_schema |

| sbtest             |

| sys                |

+--------------------+

5 rows in set (0.01 sec)



mysql> SHOW TABLES FROM sbtest;

+------------------+

| Tables_in_sbtest |

+------------------+

| sbtest1          |

| sbtest10         |

| sbtest11         |

| sbtest12         |

| sbtest13         |

| sbtest14         |

| sbtest15         |

| sbtest16         |

| sbtest17         |

| sbtest18         |

| sbtest19         |

| sbtest2          |

| sbtest20         |

| sbtest21         |

| sbtest22         |

| sbtest23         |

| sbtest24         |

| sbtest25         |

| sbtest26         |

| sbtest27         |

| sbtest28         |

| sbtest29         |

| sbtest3          |

| sbtest30         |

| sbtest31         |

| sbtest32         |

| sbtest4          |

| sbtest5          |

| sbtest6          |

| sbtest7          |

| sbtest8          |

| sbtest9          |

+------------------+

32 rows in set (0.00 sec)

Nu måste vi ta en säkerhetskopia. Det finns flera sätt på vilka vi kan närma oss denna fråga. Vi kan bara ta en konsekvent säkerhetskopia av hela datamängden men detta kommer att generera en stor, enda fil med all data. För att återställa den enskilda tabellen måste vi extrahera data för tabellen från den filen. Det är givetvis möjligt, men det är ganska tidskrävande och det är ganska mycket manuell drift som kan skriptas men om du inte har ordentliga skript på plats är det att skriva ad hoc-kod när din databas är nere och du är under hårt tryck. inte nödvändigtvis den säkraste idén.

Istället för det kan vi förbereda säkerhetskopiering på ett sätt så att varje tabell kommer att lagras i en separat fil:

[email protected]:~/backup# d=$(date +%Y%m%d) ; db='sbtest'; for tab in $(mysql -uroot -ppass -h127.0.0.1 -e "SHOW TABLES FROM ${db}" | grep -v Tables_in_${db}) ; do mysqldump --set-gtid-purged=OFF --routines --events --triggers ${db} ${tab} > ${d}_${db}.${tab}.sql ; done

Observera att vi ställer in --set-gtid-purged=AV. Vi behöver det om vi skulle ladda dessa data senare till databasen. Annars kommer MySQL att försöka ställa in @@GLOBAL.GTID_PURGED, vilket med största sannolikhet kommer att misslyckas. MySQL skulle också ställa in SET @@SESSION.SQL_LOG_BIN=0; vilket definitivt inte är vad vi vill. Dessa inställningar krävs om vi skulle göra en konsekvent säkerhetskopia av hela datamängden och vi skulle vilja använda den för att tillhandahålla en ny nod. I vårt fall vet vi att det inte är en konsekvent säkerhetskopia och att det inte finns något sätt att bygga om något från den. Allt vi vill är att skapa en dump som vi kan ladda på mastern och låta den replikera till slavar.

Det kommandot genererade en trevlig lista med sql-filer som kan laddas upp till produktionsklustret:

[email protected]:~/backup# ls -alh

total 605M

drwxr-xr-x 2 root root 4.0K Mar 18 14:10 .

drwx------ 9 root root 4.0K Mar 18 14:08 ..

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest10.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest11.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest12.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest13.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest14.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest15.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest16.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest17.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest18.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest19.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest1.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest20.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest21.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest22.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest23.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest24.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest25.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest26.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest27.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest28.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest29.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest2.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest30.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest31.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest32.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest3.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest4.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest5.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest6.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest7.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest8.sql

-rw-r--r-- 1 root root  19M Mar 18 14:10 20200318_sbtest.sbtest9.sql

När du vill återställa data behöver du bara ladda SQL-filen till masternoden:

[email protected]:~/backup# mysql -uroot -ppass sbtest < 20200318_sbtest.sbtest11.sql

Data kommer att laddas in i databasen och replikeras till alla slavar.

Hur återställer man en enskild MySQL-tabell med ClusterControl?

För närvarande erbjuder ClusterControl inte ett enkelt sätt att återställa en enda tabell, men det är fortfarande möjligt att göra det med bara några manuella åtgärder. Det finns två alternativ du kan använda. För det första, lämpligt för ett litet antal tabeller, kan du i princip skapa ett schema där du utför partiella säkerhetskopieringar av en separat tabell en efter en:

Här tar vi en säkerhetskopia av tabellen sbtest.sbtest1. Vi kan enkelt schemalägga ytterligare en säkerhetskopia för sbtest2 table:

Alternativt kan vi göra en säkerhetskopiering och lägga in data från ett enda schema i ett separat fil:

Nu kan du antingen hitta de saknade uppgifterna för hand i filen, återställa denna säkerhetskopia till en separat server eller låt ClusterControl göra det:

Du håller servern igång och du kan extrahera data som du ville återställa med antingen mysqldump eller SELECT ... INTO OUTFILE. Sådan extraherad data kommer att vara redo att appliceras på produktionsklustret.


  1. Det gick inte att hitta en ingångspunkt med namnet "InterlockedIncrement" i DLL:n "kernel32.dll" - [e-postskyddad] 64 bitar

  2. Migrera från MSSQL till PostgreSQL - Vad du bör veta

  3. Oracle DB:Hur kan jag skriva fråga som ignorerar skiftläge?

  4. Det gick inte att få spring boot för att automatiskt skapa databasschema