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

Funzione di backup PDO MySQL

Quello script di backup è ridicolo e nessuno dovrebbe crearne un'altra versione. Ho già visto quello script, oltre a tentativi simili, e hanno molti problemi:

  • Non delimita i nomi delle tabelle nei backtick
  • Non gestisce NULL
  • Non gestisce i set di caratteri
  • Non gestisce i dati binari
  • Non esegue il backup delle VIEW
  • Non esegue il backup di TRIGGER o PROCEDURE MEMORIZZATE o FUNZIONI o EVENTI MEMORIZZATI
  • Utilizza l'obsoleta estensione mysql (ma è per questo che vuoi una versione PDO, vero?)
  • Utilizza addlashes() invece di una corretta funzione di escape di MySQL.
  • Aggiunge tutti dati per tutti tabelle in una stringa molto lunga, prima di produrre l'intero contenuto. Ciò significa che devi essere in grado di archiviare l'intero database in una stringa, il che quasi sicuramente eliminerà il limite massimo di memoria PHP.

Vedi anche la mia risposta passata sullo sfortunato script di backup di David Walsh:

Re il tuo commento:

Leggi i commenti sulla pagina a cui ti sei collegato. Molte persone hanno identificato problemi e alcuni hanno soluzioni o almeno suggerimenti.

Il fatto che questo script aggiunga tutto in una stringa è un rompicapo, penso, ma non dovrebbe essere difficile cambiare lo script per aprire il file di output prima , quindi genera i dati di ogni riga durante il ciclo, quindi chiudi il file dopo il ciclo. È una specie di gioco da ragazzi, non sono sicuro del motivo per cui la sceneggiatura non lo fa. Ma è abbastanza chiaro che lo script non è stato testato molto bene.

Ma comunque, non proverei a reinventare questa ruota. Mysqldump o mydumper fanno bene questo lavoro. FWIW, non è necessario eseguire mysqldump sullo stesso server in cui risiede il database. Mysqldump supporta un'opzione per --host quindi puoi eseguire mysqldump ovunque per eseguire il backup di un database remoto, a condizione che i firewall non blocchino la connessione del client. Fondamentalmente, se puoi connettere un'app PHP al database da qualche host client, puoi connettere mysqldump.

Se questa non è davvero un'opzione, userei la funzione di dump del database di phpmyadmin. Questi sono maturi e ben testati e scaricano tutto correttamente. Ecco un articolo che descrive come utilizzare la funzione di dump:

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

[Copiando i miei commenti dalla tua risposta:]

Questo sta entrando nella revisione del codice, che non è lo scopo di StackOverflow. Ma in breve:

  • nessun supporto adeguato per NULL (li converti in '');
  • non delimitano in modo coerente i nomi delle tabelle;
  • usando virgolette non ANSI come delimitatori di stringa;
  • l'utilizzo di query bufferizzate su tabelle enormi interromperà il limite di memoria massimo di PHP;
  • aggiungere tutte le righe per una tabella enorme interromperà il limite di memoria massimo di PHP;
  • usando addlashes() invece di PDO::quote();
  • verifica degli errori di query solo al termine della funzione;
  • non verifica la creazione di file non riuscita;
  • L'estensione gzip potrebbe non essere caricata
  • Inoltre, probabilmente non supporta ancora i dati UTF8.

Sì, è meglio della sceneggiatura originale di David Walsh. :-)

NULL non è lo stesso di '' in SQL (tranne in Oracle, ma in questo caso non sono conformi allo standard SQL). Vedi MySQL, meglio inserire NULL o vuoto stringa?

Ho letto male il codice sul problema del limite di memoria. Stai scrivendo l'output per ogni riga, quindi va bene (a meno che la riga non contenga un BLOB da 1 GB o qualcosa del genere).

Ma non dovresti semplicemente produrre una singola istruzione INSERT con un insieme di righe separate da virgole. Anche mysqldump --extended-insert restituisce una lunghezza finita di dati, quindi avvia una nuova istruzione INSERT. Il criterio è se la lunghezza dell'istruzione INSERT rientra nell'argomento dell'opzione per --net-buffer-length .

In ANSI SQL, le virgolette singole '' vengono utilizzate per delimitare valori letterali stringa o valori letterali di data. Le doppie virgolette "" vengono utilizzate per delimitare identificatori come il nome della tabella oi nomi delle colonne. Per impostazione predefinita, MySQL li tratta allo stesso modo, ma questo non è standard. Vedi Database differenti usano citazioni di nomi differenti? . Se provi a importare i tuoi dati di backup su un server MySQL dove hai SET SQL_MODE=ANSI_QUOTES , l'importazione avrà esito negativo.

Esempio:query('SELECT * FROM '.$table); e in effetti ciascuno degli altri casi in cui usi $table in una query. Hai delimitato la tabella solo una volta, nell'istruzione INSERT il tuo script restituisce.

MySQL riconosce sempre i backtick come delimitatori di identificatori e le virgolette singole per stringhe/date. Ma le doppie virgolette cambiano significato a seconda di SQL_MODE che ho menzionato. Non puoi presumere quale SQL_MODE sia attivo sull'istanza MySQL su cui esegui il ripristino, quindi è meglio se usi i back-tick per gli identificatori e le virgolette singole per le stringhe. Il motivo per cui li delimita durante la query sulla tabella è che potresti avere nomi di tabelle che sono parole riservate SQL o che contengono caratteri speciali, ecc.

È possibile inserire tutti i tipi numerici senza delimitatori. Solo le stringhe e le date necessitano di delimitatori. Vedi dev.mysql.com/doc/refman/5.6/en/literals.html