sql >> Database teknologi >  >> RDS >> Mysql

PDO MySQL backup funktion

Det backup-script er latterligt, og ingen bør lave en anden version af det. Jeg har set det script før, såvel som lignende forsøg, og de har mange problemer:

  • Afgrænser ikke tabelnavne i back-ticks
  • Handterer ikke NULLs
  • Handterer ikke tegnsæt
  • Handterer ikke binære data
  • Sikkerhedskopierer ikke VIEWS
  • Sikkerhedskopierer ikke TRIGGERE eller GEMMEDE PROCEDURER eller GEMTE FUNKTIONER eller BEGIVENHEDER
  • Bruger forældet mysql-udvidelse (men det er derfor, du vil have en PDO-version, ikke?)
  • Bruger addslashes() i stedet for en ordentlig MySQL escape-funktion.
  • Tilføjer alle data for alle tabeller i en rigtig lang streng, før hele indholdet udlæses. Det betyder, at du skal være i stand til at gemme hele din database i én streng, hvilket næsten helt sikkert vil sprænge din PHP max hukommelsesgrænse.

Se også mit tidligere svar om det uheldige David Walsh backup-script:

Om din kommentar:

Læs kommentarerne på den side, du linkede til. Mange mennesker har identificeret problemer, og nogle har rettelser eller i det mindste forslag.

Det faktum, at dette script tilføjer alt i én streng, er en deal-breaker, synes jeg, men det burde ikke være svært at ændre scriptet for at åbne outputfilen først , udlæs derefter hver rækkes data under løkken, og luk derefter filen efter løkken. Det er en slags no-brainer, jeg er ikke sikker på, hvorfor scriptet ikke gør det. Men det er ret tydeligt, at manuskriptet ikke blev testet særlig godt.

Men alligevel ville jeg ikke forsøge at genopfinde dette hjul. Mysqldump eller mydumper klarer dette job fint. FWIW, du behøver ikke at køre mysqldump på den samme server, hvor databasen ligger. Mysqldump understøtter en mulighed for --host så du kan køre mysqldump hvor som helst for at sikkerhedskopiere en ekstern database, så længe firewalls ikke blokerer din klient i at oprette forbindelse. Grundlæggende, hvis du kan forbinde en PHP-app til databasen fra en klientvært, kan du forbinde mysqldump.

Hvis det virkelig ikke er en mulighed, så ville jeg bruge database dump-funktionen i phpmyadmin. Disse er modne og gennemtestede, og de dumper alt korrekt. Her er en artikel, der beskriver, hvordan du bruger dump-funktionen:

http://www.techrepublic. com/blog/smb-technologist/import-and-export-databases-using-phpmyadmin/

[Kopierer mine kommentarer fra dit svar:]

Dette kommer ind i kodegennemgang, hvilket ikke er formålet med StackOverflow. Men kort:

  • ingen ordentlig understøttelse af NULL (du konverterer dem til '');
  • ikke konsekvent afgrænsende tabelnavne;
  • brug af ikke-ANSI dobbelte anførselstegn som strengeafgrænsere;
  • brug af bufferforespørgsler på store tabeller vil bryde PHP max hukommelsesgrænse;
  • at tilføje alle rækker til en stor tabel vil bryde PHP max hukommelsesgrænsen;
  • ved at bruge addslashes() i stedet for PDO::quote();
  • kontrollerer kun for forespørgselsfejl i slutningen af ​​funktionen;
  • kontrollerer ikke for mislykket filoprettelse;
  • gzip-udvidelsen er muligvis ikke indlæst
  • Understøtter sandsynligvis stadig ikke UTF8-data.

Ja, dette er bedre end det originale David Walsh-manuskript. :-)

NULL er ikke det samme som '' i SQL (undtagen i Oracle, men de overholder ikke SQL-standarden i dette tilfælde). Se MySQL, bedre at indsætte NULL eller tom streng?

Jeg læste forkert koden på problemet med hukommelsesgrænsen. Du skriver output for hver række, så det er okay (medmindre rækken indeholder en 1 GB klat eller noget).

Men du skal ikke bare udskrive en enkelt INSERT-sætning med et kommasepareret sæt rækker. Selv mysqldump --extended-insert udlæser en endelig længde af data og starter derefter en ny INSERT-sætning. Kriteriet er, om længden af ​​INSERT-sætningen passer inden for option-argumentet for --net-buffer-length .

I ANSI SQL bruges enkelte anførselstegn '' til at afgrænse strengliteraler eller datoliteraler. Dobbelte anførselstegn "" bruges til at afgrænse identifikatorer som tabelnavn eller kolonnenavne. Som standard behandler MySQL dem på samme måde, men dette er ikke-standard. Se Bruger forskellige databaser forskellige navnecitater? . Hvis du forsøger at importere dine backupdata til en MySQL-server, hvor du har SET SQL_MODE=ANSI_QUOTES , vil importen mislykkes.

Eksempel:query('SELECT * FROM '.$table); og faktisk hvert af de andre tilfælde, hvor du bruger $table i en forespørgsel. Du afgrænsede kun tabellen én gang, i INSERT-sætningen udsender dine scripts.

MySQL genkender altid back-ticks som identifikatorafgrænsere og enkelte anførselstegn for strenge/datoer. Men dobbelte anførselstegn ændrer betydning afhængigt af den SQL_MODE, jeg nævnte. Du kan ikke antage, hvilken SQL_MODE der er i kraft på den MySQL-instans, du gendanner på, så det er bedst, hvis du bruger back-ticks for identifikatorer og enkelte anførselstegn for strenge. Grunden til, at du afgrænser dem, mens du forespørger i din tabel, er, at du muligvis har tabelnavne, der er reserverede SQL-ord, eller som indeholder specialtegn osv.

Du kan indsætte alle numeriske typer uden skilletegn. Kun strenge og datoer skal bruge afgrænsninger. Se dev.mysql.com/doc/refman/5.6/en/literals.html



  1. MySQL-forespørgsel, der skelner mellem store og små bogstaver

  2. MySQL 5.7.12-import kan ikke oprette en JSON-værdi fra en streng med CHARACTER SET 'binary'

  3. Forespørgsel for at kontrollere, om feltet eksisterer, og returner derefter resultatsættet

  4. MySQL-bruger angivet som definerer eksisterer ikke