Nogen slettede ved et uheld en del af databasen. Nogen har glemt at inkludere en WHERE-sætning i en DELETE-forespørgsel, eller de har droppet den forkerte tabel. Sådanne ting kan og vil ske, det er uundgåeligt og menneskeligt. Men virkningen kan være katastrofal. Hvad kan du gøre for at beskytte dig mod sådanne situationer, og hvordan kan du gendanne dine data? I dette blogindlæg vil vi dække nogle af de mest typiske tilfælde af datatab, og hvordan du kan forberede dig, så du kan komme dig fra dem.
Forberedelser
Der er ting, du bør gøre for at sikre en jævn bedring. Lad os gennemgå dem. Husk, at det ikke er en "vælg én"-situation - ideelt set vil du implementere alle de foranstaltninger, vi vil diskutere nedenfor.
Sikkerhedskopi
Du skal have en backup, det er der ingen mulighed for at komme væk fra. Du bør få testet dine backupfiler - medmindre du tester dine backups, kan du ikke være sikker på, om de er gode, og om du nogensinde vil være i stand til at gendanne dem. Til katastrofegendannelse bør du opbevare en kopi af din sikkerhedskopi et sted uden for dit datacenter - bare hvis hele datacentret bliver utilgængeligt. For at fremskynde gendannelsen er det meget nyttigt at opbevare en kopi af sikkerhedskopien også på databasenoderne. Hvis dit datasæt er stort, kan det tage betydelig tid at kopiere det over netværket fra en backup-server til databasenoden, som du vil gendanne. Bevaring af den seneste sikkerhedskopi lokalt kan forbedre gendannelsestiden betydeligt.
Logisk sikkerhedskopiering
Din første backup vil højst sandsynligt være en fysisk backup. For MySQL eller MariaDB vil det enten være noget som xtrabackup eller en slags filsystem-øjebliksbillede. Sådanne sikkerhedskopier er gode til at gendanne et helt datasæt eller til at klargøre nye noder. Men i tilfælde af sletning af en delmængde af data, lider de af betydelige omkostninger. Først og fremmest er du ikke i stand til at gendanne alle data, ellers vil du overskrive alle ændringer, der skete efter sikkerhedskopieringen blev oprettet. Det, du leder efter, er muligheden for kun at gendanne en delmængde af data, kun de rækker, der ved et uheld blev fjernet. For at gøre det med en fysisk backup skal du gendanne den på en separat vært, finde fjernede rækker, dumpe dem og derefter gendanne dem på produktionsklyngen. Kopiering og gendannelse af hundredvis af gigabyte data bare for at gendanne en håndfuld rækker er noget, vi helt sikkert ville kalde en betydelig overhead. For at undgå det kan du bruge logiske sikkerhedskopier - i stedet for at gemme fysiske data, gemmer sådanne sikkerhedskopier data i et tekstformat. Dette gør det nemmere at finde de nøjagtige data, som blev fjernet, som derefter kan gendannes direkte på produktionsklyngen. For at gøre det endnu nemmere kan du også opdele en sådan logisk backup i dele og sikkerhedskopiere hver eneste tabel til en separat fil. Hvis dit datasæt er stort, vil det give mening at opdele en stor tekstfil så meget som muligt. Dette vil gøre sikkerhedskopieringen inkonsekvent, men for de fleste tilfælde er dette ikke noget problem - hvis du skal gendanne hele datasættet til en konsistent tilstand, vil du bruge fysisk backup, hvilket er meget hurtigere i denne henseende. Hvis du kun skal gendanne en delmængde af data, er kravene til konsistens mindre strenge.
Point-in-Time-gendannelse
Sikkerhedskopiering er kun en begyndelse - du vil være i stand til at gendanne dine data til det punkt, hvor sikkerhedskopien blev taget, men højst sandsynligt blev data fjernet efter det tidspunkt. Bare ved at gendanne manglende data fra den seneste sikkerhedskopi, kan du miste alle data, der blev ændret efter sikkerhedskopieringen. For at undgå dette bør du implementere Point-In-Time Recovery. For MySQL betyder det dybest set, at du bliver nødt til at bruge binære logfiler til at afspille alle de ændringer, der skete mellem tidspunktet for sikkerhedskopieringen og datatabshændelsen. Nedenstående skærmbillede viser, hvordan ClusterControl kan hjælpe med det.
Det, du skal gøre, er at gendanne denne sikkerhedskopi indtil det øjeblik, lige før datatabet. Du bliver nødt til at gendanne den på en separat vært for ikke at foretage ændringer på produktionsklyngen. Når du har gendannet sikkerhedskopien, kan du logge ind på værten, finde de manglende data, dumpe dem og gendanne på produktionsklyngen.
Forsinket slave
Alle de metoder, vi diskuterede ovenfor, har ét fælles smertepunkt – det tager tid at gendanne dataene. Det kan tage længere tid, når du gendanner alle data og derefter prøver kun at dumpe den interessante del. Det kan tage kortere tid, hvis du har logisk backup, og du hurtigt kan bore ned til de data, du vil gendanne, men det er på ingen måde en hurtig opgave. Du skal stadig finde et par rækker i en stor tekstfil. Jo større den er, jo mere kompliceret bliver opgaven - nogle gange bremser filens størrelse alle handlinger. En metode til at undgå disse problemer er at have en forsinket slave. Slaver forsøger typisk at holde sig ajour med masteren, men det er også muligt at konfigurere dem, så de holder afstand til deres master. På nedenstående skærmbillede kan du se, hvordan du bruger ClusterControl til at implementere en sådan slave:
Kort sagt har vi her en mulighed for at tilføje en replikeringsslave til databaseopsætningen og konfigurere den til at blive forsinket. I skærmbilledet ovenfor vil slaven blive forsinket med 3600 sekunder, hvilket er en time. Dette giver dig mulighed for at bruge denne slave til at gendanne de fjernede data op til en time efter datasletningen. Du behøver ikke at gendanne en sikkerhedskopi, det vil være nok at køre mysqldump eller SELECT ... INTO OUTFILE for de manglende data, og du vil få dataene til at gendanne på din produktionsklynge.
Gendannelse af data
I dette afsnit vil vi gennemgå et par eksempler på utilsigtet sletning af data, og hvordan du kan gendanne dem. Vi vil gennemgå gendannelse fra et fuldstændigt datatab, vi vil også vise, hvordan du genopretter fra et delvist datatab, når du bruger fysiske og logiske sikkerhedskopier. Vi vil endelig vise dig, hvordan du gendanner utilsigtet slettede rækker, hvis du har en forsinket slave i din opsætning.
Fuldt datatab
Utilsigtet "rm -rf" eller "DROP SCHEMA myonlyschema;" er blevet udført, og du endte med slet ingen data. Hvis du tilfældigvis også har fjernet andre filer end fra MySQL-datamappen, skal du muligvis omprovisionere værten. For at gøre tingene enklere vil vi antage, at kun MySQL er blevet påvirket. Lad os overveje to tilfælde, med en forsinket slave og uden en.
Ingen forsinket slave
I dette tilfælde er det eneste, vi kan gøre, at gendanne den sidste fysiske backup. Da alle vores data er blevet fjernet, behøver vi ikke at være bekymrede for aktivitet, der skete efter datatabet, for uden data er der ingen aktivitet. Vi burde være bekymrede over den aktivitet, der skete efter sikkerhedskopieringen fandt sted. Det betyder, at vi er nødt til at lave en punkt-i-tidsgendannelse. Det vil selvfølgelig tage længere tid end blot at gendanne data fra sikkerhedskopien. Hvis det er mere afgørende at få din database op hurtigt end at få alle data gendannet, kan du lige så godt bare gendanne en sikkerhedskopi og have det fint med det.
Først og fremmest, hvis du stadig har adgang til binære logfiler på den server, du vil gendanne, kan du bruge dem til PITR. Først ønsker vi at konvertere den relevante del af de binære logfiler til en tekstfil for yderligere undersøgelse. Vi ved, at datatab skete efter kl. 13:00. Lad os først tjekke, hvilken binlog-fil vi skal undersøge:
[email protected]:~# ls -alh /var/lib/mysql/binlog.*-rw-r----- 1 mysql mysql 1.1G 23. april 10:32 /var/lib /mysql/binlog.000001-rw-r----- 1 mysql mysql 1.1G 23. apr 10:33 /var/lib/mysql/binlog.000002-rw-r----- 1 mysql mysql 1.1G apr. 23 10:35 /var/lib/mysql/binlog.000003-rw-r----- 1 mysql mysql 1.1G 23. april 10:38 /var/lib/mysql/binlog.000004-rw-r--- -- 1 mysql mysql 1.1G 23. apr 10:39 /var/lib/mysql/binlog.000005-rw-r----- 1 mysql mysql 1.1G 23. apr 10:41 /var/lib/mysql/binlog. 000006-rw-r----- 1 mysql mysql 1.1G 23. apr 10:43 /var/lib/mysql/binlog.000007-rw-r----- 1 mysql mysql 1.1G 23. apr / 10:43 var/lib/mysql/binlog.000008-rw-r----- 1 mysql mysql 1.1G 23. apr 10:47 /var/lib/mysql/binlog.000009-rw-r----- 1 mysql mysql 1.1G 23. apr. 10:49 /var/lib/mysql/binlog.000010-rw-r----- 1 mysql mysql 1.1G 23. apr. 10:51 /var/lib/mysql/binlog.000011-rw-r ----- 1 mysql mysql 1.1G 23. apr. 10:53 /var/lib/mysql/binlog.000012-rw-r----- 1 mysql mysql 1.1G 23. apr. 10:55 /var/lib/mysql /binlog.000013-rw-r----- 1 mysql mysql 1.1G Apr 23 10:57 /var/lib/mysql/binlog.000014-rw-r----- 1 mysql mysql 1.1G Apr 23 10:59 /var/lib/mysql/binlog.0001 -r----- 1 mysql mysql 306M 23. apr 13:18 /var/lib/mysql/binlog.000016
Som det kan ses, er vi interesserede i den sidste binlog-fil.
[email protected]:~# mysqlbinlog --start-datetime='2018-04-23 13:00:00' --verbose /var/lib/mysql/binlog.000016> sql.out
Når det er gjort, lad os tage et kig på indholdet af denne fil. Vi vil søge efter 'drop schema' i vim. Her er en relevant del af filen:
meget 443415'/*!*/;# at 320358850#180423 13:18:58 server id 1 end_log_pos 320358946 CRC32 0x487ab38e Forespørgsel thread_id=55 exec_time=1 error_4/STAMP=01*8 TIME*82TID/STAMP=01*8*8 TIME/1 error_4/STAMP! *//*!*/;SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;drop schema sbtest/*!*/;Som vi kan se, ønsker vi at gendanne op til position 320358785. Vi kan videregive disse data til ClusterControl UI:
Forsinket slave
Hvis vi har en forsinket slave, og den vært er nok til at håndtere al trafikken, kan vi bruge den og fremme den til at mestre. Først skal vi dog sikre os, at den indhentede den gamle master indtil datatabet. Vi vil bruge noget CLI her for at få det til at ske. Først skal vi finde ud af, på hvilken position datatabet skete. Så stopper vi slaven og lader den køre op til datatabshændelsen. Vi viste, hvordan man får den korrekte position i det foregående afsnit - ved at undersøge binære logfiler. Vi kan enten bruge denne position (binlog.000016, position 320358785) eller, hvis vi bruger en multithreaded slave, skal vi bruge GTID for datatabshændelsen (52d08e9d-46d2-11e8-aa17-080027e8bf1b:443415 forespørgsler) det GTID.
Lad os først stoppe slaven og deaktivere forsinkelse:
mysql> STOP SLAVE;Forespørgsel OK, 0 rækker påvirket (0,01 sek)mysql> SKIFT MASTER TIL MASTER_DELAY =0;Forespørgsel OK, 0 rækker påvirket (0,02 sek.)
Så kan vi starte den op til en given binær logposition.
mysql> START SLAVE TIL MASTER_LOG_FILE='binlog.000016', MASTER_LOG_POS=320358785;Forespørgsel OK, 0 rækker påvirket (0,01 sek.)
Hvis vi gerne vil bruge GTID, vil kommandoen se anderledes ud:
mysql> START SLAVE INDTIL SQL_BEFORE_GTIDS =‘52d08e9d-46d2-11e8-aa17-080027e8bf1b:443415’;Forespørgsel OK, 0 rækker påvirket (0,01 sek.)
Når replikeringen stoppede (hvilket betyder, at alle de hændelser, vi bad om, er blevet udført), bør vi bekræfte, at værten indeholder de manglende data. Hvis det er tilfældet, kan du promovere det til master og derefter genopbygge andre værter ved at bruge en ny master som datakilde.
Dette er ikke altid den bedste mulighed. Alt afhænger af, hvor forsinket din slave er - hvis den er forsinket med et par timer, giver det måske ikke mening at vente på, at den indhenter det, især hvis skrivetrafikken er stor i dit miljø. I sådanne tilfælde er det højst sandsynligt hurtigere at genopbygge værter ved hjælp af fysisk backup. På den anden side, hvis du har en ret lille mængde trafik, kan dette være en god måde at faktisk hurtigt løse problemet, promovere en ny master og komme videre med at betjene trafik, mens resten af noderne bliver genopbygget i baggrunden .
Delvist tab af data - fysisk sikkerhedskopiering
I tilfælde af delvist datatab kan fysiske sikkerhedskopier være ineffektive, men da det er den mest almindelige type sikkerhedskopiering, er det meget vigtigt at vide, hvordan man bruger dem til delvis gendannelse. Første skridt vil altid være at gendanne en sikkerhedskopi op til et tidspunkt før datatabshændelsen. Det er også meget vigtigt at gendanne det på en separat vært. ClusterControl bruger xtrabackup til fysiske sikkerhedskopier, så vi vil vise, hvordan man bruger det. Lad os antage, at vi kørte følgende forkerte forespørgsel:
SLET FRA sbtest1 WHERE id <23146;
Vi ønskede kun at slette en enkelt række ('=' i WHERE-sætning), i stedet slettede vi en masse af dem ( mysqlbinlog --verbose /var/lib/mysql/binlog.000003> bin.out
Lad os nu se på outputfilen og se, hvad vi kan finde der. Vi bruger rækkebaseret replikering, derfor vil vi ikke se den nøjagtige SQL, der blev udført. I stedet (så længe vi bruger --verbose flag til mysqlbinlog) vil vi se begivenheder som nedenfor:
### SLET FRA `sbtest`.`sbtest1`### WHERE### @1=999296### @2=1009782### @3='96260841950-70557543083-97211113891824-3869824-386582 -52320653831-03705501677-77169427072-31113899105-45148058587-70555151875'### @4='84527471555-75554439500-82168020167-12926542460-82869925404'
Som det kan ses, identificerer MySQL rækker, der skal slettes ved hjælp af en meget præcis WHERE-tilstand. Mystiske tegn i den menneskelæselige kommentar, "@1", "@2", betyder "første kolonne", "anden kolonne". Vi ved, at den første kolonne er 'id', hvilket er noget, vi er interesserede i. Vi skal finde en stor DELETE-begivenhed på en 'sbtest1'-tabel. Kommentarer, der følger, skal nævne id på 1, derefter id på '2', derefter '3' og så videre - alt sammen op til id på '23145'. Alle skal udføres i en enkelt transaktion (enkelt hændelse i en binær log). Efter at have analyseret outputtet med 'mindre' fandt vi:
### SLET FRA `sbtest`.`sbtest1`### WHERE### @1=1### @2=1006036### @3='123'### @4 ='43683718329-48150560094-43449649167-51455516141-06448225399'### SLET FRA `sbtest`.`sbtest1`### @HER####8 @8=01###3=01### @8=12## '### @4='05603373460-16140454933-50476449060-04937808333-32421752305'
Arrangementet, som disse kommentarer er knyttet til, startede på:
#180427 8:09:21 server-id 1 end_log_pos 29600687 CRC32 0x8cfdd6ae Xid =307686COMMIT/*!*/;# at 29600687#180427 8:09:201 end 8:09:201 Clog_09:129 end 8:09:201 Clog_09:201 sequence_number=42845 rbr_only=yes/*!50718 INDSTIL TRANSAKSIONSISOLATIONSNIVEAU LÆS KOMMITTERET*//*!*/;SET @@SESSION.GTID_NEXT='0c695e13-4931-11e8-9f2f-08891b/e8801b/e5801b/e8801b/5801b:e8801b:e5801b/e8801b/58002b/5801b:e8801b/5801b/5801b/5801b/5801b/5801b/58012b/5801b/58012b/58012b/ # at 29600752#180427 8:09:21 server-id 1 end_log_pos 29600826 CRC32 0xc7b71da5 Forespørgsel thread_id=44 exec_time=0 error_code=0SET TIMESTAMP=1524816561/8*! ut*!/*/C/C/*! SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=8/*!*/;BEGIN/*!*/;# på 29600826
Så vi ønsker at gendanne sikkerhedskopien op til den tidligere commit i position 29600687. Lad os gøre det nu. Vi bruger ekstern server til det. Vi vil gendanne backup op til den position, og vi vil holde gendannelsesserveren oppe og køre, så vi senere kan udtrække de manglende data.
Når gendannelsen er fuldført, lad os sørge for, at vores data er blevet gendannet:
mysql> VÆLG ANTAL(*) FRA sbtest.sbtest1 WHERE id <23146;+----------+| COUNT(*) |+----------+| 23145 |+----------+1 række i sæt (0,03 sek.)
Ser godt ud. Nu kan vi udtrække disse data til en fil, som vi vil indlæse tilbage på masteren.
mysql> VÆLG * FRA sbtest.sbtest1 WHERE id <23146 INTO OUTFILE 'missing.sql';FEJL 1290 (HY000):MySQL-serveren kører med --secure-file-priv indstillingen, så den kan ikke udfør denne sætning
Noget er ikke rigtigt - det er fordi serveren er konfigureret til kun at kunne skrive filer på en bestemt placering - det handler om sikkerhed, vi ønsker ikke at lade brugerne gemme indhold hvor som helst de vil. Lad os tjekke, hvor vi kan gemme vores fil:
mysql> VIS VARIABLER SOM "secure_file_priv";+------------------+--------------- --------+| Variabelnavn | Værdi |+-------------------+-----------------------+| sikker_fil_privat | /var/lib/mysql-files/ |+------------------------+------------------------ ---+1 række i sæt (0,13 sek.)
Ok, lad os prøve en gang til:
mysql> VÆLG * FRA sbtest.sbtest1 WHERE id <23146 INTO OUTFILE '/var/lib/mysql-files/missing.sql';Forespørgsel OK, 23145 rækker påvirket (0,05 sek.)
Nu ser det meget bedre ud. Lad os kopiere dataene til masteren:
[email protected]:~# scp /var/lib/mysql-files/missing.sql 10.0.0.101:/var/lib/mysql-files/missing.sql 100% 1744KB 1,7MB/s 00:00
Nu er det tid til at indlæse de manglende rækker på masteren og teste, om det lykkedes:
mysql> INDLÆS DATAINFIL '/var/lib/mysql-files/missing.sql' I TABEL sbtest.sbtest1;Forespørgsel OK, 23145 rækker påvirket (2,22 sek.)Records:23145 Slettet:0 Sprang over:0 Advarsler:0mysql> VÆLG COUNT(*) FRA sbtest.sbtest1 WHERE id <23146;+----------+| COUNT(*) |+----------+| 23145 |+----------+1 række i sæt (0,00 sek.)
Det er alt, vi gendannede vores manglende data.
Delvist tab af data - logisk sikkerhedskopiering
I det foregående afsnit gendannede vi tabte data ved hjælp af fysisk backup og en ekstern server. Hvad hvis vi fik lavet logisk backup? Lad os se. Lad os først kontrollere, at vi har en logisk backup:
[email protected]:~# ls -alh /root/backups/BACKUP-13/total 5.8Gdrwx------ 2 root root 4.0K 27. april 07:35 .drwxr-x- -- 5 root root 4.0K apr 27 07:14 ..-rw-r--r-- 1 root root 2.4K Apr 27 07:35 cmon_backup.metadata-rw------- 1 root root 5.8G 27. apr 07:35 mysqldump_2018-04-27_071434_complete.sql.gz
Ja, det er der. Nu er det tid til at dekomprimere det.
[email protected]:~# mkdir /root/[email protected]:~# zcat /root/backups/BACKUP-13/mysqldump_2018-04-27_071434_complete.sql.gz> /root/restore /backup.sql
Når du ser på det, vil du se, at dataene er gemt i INSERT-format med flere værdier. For eksempel:
INSERT INTO `sbtest1` VALUES (1,1006036,'18034632456-32298647298-82351096178-60420120042-90070228681-93395382793-96740777141-18710455882-88896678134-41810932745','43683718329-48150560094-43449649167-51455516141-06448225399' ),(2,1008980,'69708345057-48265944193-91002879830-11554672482-35576538285-03657113365-90301319612-18462263634-56608104414-27254248188','05603373460-16140454933-50476449060-04937808333-32421752305')
Alt, hvad vi skal gøre nu, er at finde ud af, hvor vores tabel er placeret, og derefter hvor rækkerne, som er af interesse for os, er gemt. Først, ved at kende mysqldump-mønstre (slip tabel, opret en ny, deaktiver indekser, indsæt data), lad os finde ud af, hvilken linje der indeholder CREATE TABLE-sætningen for 'sbtest1'-tabellen:
[email protected]:~/restore# grep -n "CREATE TABLE \`sbtest1\`" backup.sql> [email protected]:~/restore# cat out971:CREATE TABEL `sbtest1` (
Nu, ved at bruge en metode med forsøg og fejl, skal vi finde ud af, hvor vi skal lede efter vores rækker. Vi viser dig den sidste kommando, vi kom med. Hele tricket er at prøve at udskrive forskellige rækker af linjer ved hjælp af sed og derefter kontrollere, om den seneste linje indeholder rækker tæt på, men senere end det, vi søger efter. I kommandoen nedenfor leder vi efter linjer mellem 971 (CREATE TABLE) og 993. Vi beder også sed om at afslutte, når den når linje 994, da resten af filen ikke er af interesse for os:
[email protected]:~/restore# sed -n '971,993p; 994q' backup.sql> [email protected]:~/restore# tail -n 1 1.sql | mindre
Outputtet ser ud som nedenfor:
INSERT INTO `sbtest1` VALUES (31351,1007187,'23938390896-69688180281-37975364313-05234865797-89299459691-74476188805-03642252162-40036598389-45190639324-97494758464','60596247401-06173974673-08009930825-94560626453-54686757363' ),
Det betyder, at vores rækkevidde (op til række med id 23145) er tæt på. Dernæst handler det om manuel rensning af filen. Vi vil have det til at starte med den første række, vi skal gendanne:
INSERT INTO `sbtest1` VALUES (1,1006036,'18034632456-32298647298-82351096178-60420120042-90070228681-93395382793-96740777141-18710455882-88896678134-41810932745','43683718329-48150560094-43449649167-51455516141-06448225399' )
Og ender med den sidste række at gendanne:
(23145,1001595,'37250617862-83193638873-99290491872-89366212365-12327992016-32030298805-08821519929-92162259650-88126148247-75122945670','60801103752-29862888956-47063830789-71811451101-27773551230');
Vi var nødt til at trimme nogle af de unødvendige data (det er multiline insert), men efter alt dette har vi en fil, som vi kan indlæse tilbage på masteren.
[email protected]:~/restore# cat 1.sql | mysql -usbtest -psbtest -h10.0.0.101 sbtestmysql:[Advarsel] Brug af en adgangskode på kommandolinjegrænsefladen kan være usikker.
Til sidst, sidste kontrol:
mysql> VÆLG ANTAL(*) FRA sbtest.sbtest1 WHERE id <23146;+----------+| COUNT(*) |+----------+| 23145 |+----------+1 række i sæt (0,00 sek.)
Alt er i orden, data er blevet gendannet.
Delvis datatab, forsinket slave
I dette tilfælde vil vi ikke gennemgå hele processen. Vi har allerede beskrevet, hvordan man identificerer positionen for en datatabshændelse i de binære logfiler. Vi beskrev også, hvordan man stopper en forsinket slave og starter replikeringen igen, op til et punkt før datatabshændelsen. Vi forklarede også, hvordan man bruger SELECT INTO OUTFILE og LOAD DATA INFILE til at eksportere data fra ekstern server og indlæse dem på masteren. Det er alt hvad du behøver. Så længe dataene stadig er på den forsinkede slave, skal du stoppe den. Så skal du lokalisere positionen før datatabshændelsen, starte slaven op til det punkt og, når dette er gjort, skal du bruge den forsinkede slave til at udtrække data, der blev slettet, kopiere filen til master og indlæse den for at gendanne dataene .
Konklusion
Det er ikke sjovt at gendanne tabte data, men hvis du følger de trin, vi har gennemgået i denne blog, har du en god chance for at gendanne det, du har mistet.