Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Funkcja kopii zapasowych PDO MySQL

Ten skrypt kopii zapasowej jest niedorzeczny i nikt nie powinien tworzyć jego innej wersji. Widziałem ten skrypt już wcześniej, podobnie jak podobne próby, i mają wiele problemów:

  • Nie rozgranicza nazw tabel w back-ticks
  • Nie obsługuje wartości NULL
  • Nie obsługuje zestawów znaków
  • Nie obsługuje danych binarnych
  • Nie tworzy kopii zapasowych WIDOKÓW
  • Nie tworzy kopii zapasowych WYZWALACÓW, PRZECHOWYWANYCH PROCEDUR, PRZECHOWYWANYCH FUNKCJI lub ZDARZEŃ
  • Używa przestarzałego rozszerzenia mysql (ale właśnie dlatego chcesz wersję PDO, prawda?)
  • Używa addslashes() zamiast właściwej funkcji ucieczki MySQL.
  • Dołącza wszystkie dane dla wszystkich tabele w jeden naprawdę długi ciąg, przed wyświetleniem całej zawartości. Oznacza to, że musisz być w stanie przechowywać całą bazę danych w jednym ciągu, co prawie na pewno rozwali Twój maksymalny limit pamięci PHP.

Zobacz także moją poprzednią odpowiedź na temat niefortunnego skryptu kopii zapasowej Davida Walsha:

Odpowiedz na swój komentarz:

Przeczytaj komentarze na stronie, do której prowadziłeś link. Wiele osób zidentyfikowało problemy, a niektórzy mają poprawki lub przynajmniej sugestie.

Myślę, że fakt, że ten skrypt dołącza wszystko do jednego ciągu znaków, jest przełomem, ale zmiana skryptu w celu otwarcia pliku wyjściowego najpierw nie powinna być trudna. , a następnie wypisz dane każdego wiersza podczas pętli, a następnie zamknij plik po pętli. To trochę oczywiste, nie jestem pewien, dlaczego skrypt tego nie robi. Ale jest całkiem jasne, że skrypt nie został zbyt dobrze przetestowany.

Ale i tak nie próbowałbym wymyślać tego koła na nowo. Mysqldump lub mydumper wykonują tę pracę dobrze. FWIW, nie musisz uruchamiać mysqldump na tym samym serwerze, na którym znajduje się baza danych. Mysqldump obsługuje opcję dla --host więc możesz uruchomić mysqldump w dowolnym miejscu, aby wykonać kopię zapasową zdalnej bazy danych, o ile zapory nie blokują połączenia twojego klienta. Zasadniczo, jeśli możesz podłączyć aplikację PHP do bazy danych z jakiegoś hosta klienta, możesz podłączyć mysqldump.

Jeśli to naprawdę nie jest opcja, skorzystałbym z funkcji zrzutu bazy danych w phpmyadmin. Są dojrzałe, dobrze przetestowane i wszystko poprawnie zrzucają. Oto artykuł opisujący, jak korzystać z funkcji zrzutu:

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

[Kopiowanie moich komentarzy z Twojej odpowiedzi:]

To wchodzi w przegląd kodu, który nie jest celem StackOverflow. Ale krótko:

  • brak odpowiedniej obsługi NULL (konwertujesz je na '');
  • niespójne rozdzielanie nazw tabel;
  • używając podwójnych cudzysłowów innych niż ANSI jako ograniczników łańcucha;
  • używanie buforowanych zapytań na dużych tabelach spowoduje przekroczenie maksymalnego limitu pamięci PHP;
  • dołączenie wszystkich wierszy do ogromnej tabeli złamie maksymalny limit pamięci PHP;
  • używając addslashes() zamiast PDO::quote();
  • sprawdzanie błędów zapytań tylko na końcu funkcji;
  • nie sprawdzanie, czy tworzenie pliku nie powiodło się;
  • Rozszerzenie gzip nie może być załadowane
  • Ponadto prawdopodobnie nadal nie obsługuje danych UTF8.

Tak, to jest lepsze niż oryginalny scenariusz Davida Walsha. :-)

NULL to nie to samo co '' w SQL (z wyjątkiem Oracle, ale w tym przypadku nie są one zgodne ze standardem SQL). Zobacz MySQL, lepiej wstawić NULL lub pusty ciąg?

Błędnie odczytałem kod dotyczący problemu z limitem pamięci. Piszesz dane wyjściowe dla każdego wiersza, więc to jest w porządku (chyba że wiersz zawiera blob 1 GB lub coś takiego).

Ale nie powinieneś wyprowadzać pojedynczej instrukcji INSERT z zestawem wierszy oddzielonych przecinkami. Nawet mysqldump --extended-insert wypisuje skończoną długość danych, a następnie uruchamia nową instrukcję INSERT. Kryterium jest to, czy długość instrukcji INSERT mieści się w argumencie opcji dla --net-buffer-length .

W ANSI SQL pojedyncze cudzysłowy '' są używane do oddzielania literałów łańcuchowych lub literałów dat. Podwójne cudzysłowy „” służą do oddzielania identyfikatorów, takich jak nazwa tabeli lub nazwy kolumn. Domyślnie MySQL traktuje je tak samo, ale jest to niestandardowe. Zobacz Czy różne bazy danych używają różnych cytatów nazw? . Jeśli próbujesz zaimportować dane kopii zapasowej na serwer MySQL, na którym masz SET SQL_MODE=ANSI_QUOTES , import się nie powiedzie.

Przykład:query('SELECT * FROM '.$table); iw rzeczywistości każdy z pozostałych przypadków, w których w zapytaniu używasz $table. Ograniczyłeś tabelę tylko raz, w instrukcji INSERT, którą wyprowadza twój skrypt.

MySQL zawsze rozpoznaje znaki wsteczne jako ograniczniki identyfikatorów i pojedyncze cudzysłowy dla ciągów/dat. Ale podwójne cudzysłowy zmieniają znaczenie w zależności od wspomnianego przeze mnie trybu SQL_MODE. Nie można założyć, który tryb SQL_MODE działa w instancji MySQL, w której przywracasz, więc najlepiej jest użyć tylnych znaczników dla identyfikatorów i pojedynczych cudzysłowów dla ciągów. Powodem, dla którego należy je rozgraniczać podczas wysyłania zapytań do tabeli, jest to, że możesz mieć nazwy tabel będące słowami zastrzeżonymi SQL lub zawierające znaki specjalne itp.

Możesz wstawić wszystkie typy liczbowe bez ograniczników. Tylko ciągi i daty wymagają ograniczników. Zobacz dev.mysql.com/doc/refman/5.6/en/literals.html



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wyszukiwanie wielu słów kluczowych

  2. Jak korzystać z mysql JOIN bez warunku ON?

  3. Jak zmienić strefę czasową MySQL w połączeniu z bazą danych za pomocą Javy?

  4. Użyj relacyjnych baz danych MySQL na Ubuntu 9.04 (Jaunty)

  5. Usuwanie powrotu karetki w Mysql DB