Этот сценарий резервного копирования нелеп, и никто не должен делать его другую версию. Я видел этот сценарий раньше, а также подобные попытки, и у них много проблем:
- Не разделяет имена таблиц в обратных тиках
- Не обрабатывает NULL
- Не обрабатывает наборы символов
- Не обрабатывает двоичные данные
- Не выполняет резервное копирование ПРОСМОТРОВ
- Не выполняет резервное копирование ТРИГГЕРОВ, СОХРАНЕННЫХ ПРОЦЕДУР, СОХРАНЕННЫХ ФУНКЦИЙ или СОБЫТИЙ
- Использует устаревшее расширение mysql (но именно поэтому вам нужна версия PDO, не так ли?)
- Использует addlashes () вместо соответствующей функции экранирования MySQL.
- Добавляет все данные для всех таблиц в одну очень длинную строку перед выводом всего содержимого. Это означает, что вы должны иметь возможность хранить всю свою базу данных в одной строке, что почти наверняка приведет к превышению максимального лимита памяти PHP.
См. Также мой предыдущий ответ о неудачном сценарии резервного копирования Дэвида Уолша:
Повторите свой комментарий:
Прочтите комментарии на странице, на которую вы указали. Многие люди выявили проблемы, а у некоторых есть исправления или, по крайней мере, предложения.
Я думаю, что тот факт, что этот скрипт добавляет все в одну строку, является препятствием, но не должно быть сложно изменить скрипт, чтобы открыть выходной файл сначала, а затем выводить данные каждой строки во время цикл, затем закройте файл после цикла. Это своего рода легкая задача, я не уверен, почему сценарий этого не делает. Но совершенно очевидно, что сценарий не очень хорошо тестировался.
Но в любом случае я бы не стал изобретать это колесо. Mysqldump или mydumper отлично справляются с этой задачей. FWIW, вам не нужно запускать mysqldump на том же сервере, где находится база данных. Mysqldump поддерживает параметр --host
, поэтому вы можете запускать mysqldump где угодно для резервного копирования удаленной базы данных, если брандмауэры не блокируют подключение вашего клиента. По сути, если вы можете подключить приложение PHP к базе данных с некоторого клиентского хоста, вы можете подключить mysqldump.
Если это действительно не вариант, я бы использовал функцию дампа базы данных phpmyadmin. Они зрелые, проверенные и все правильно сбрасывают. Вот статья, в которой описывается, как использовать функцию дампа:
http://www.techrepublic.com/blog/smb-technologist/import-and-export-databases-using-phpmyadmin/
[Копирование моих комментариев из вашего ответа:]
Это касается обзора кода, который не является целью StackOverflow. Но вкратце:
- нет надлежащей поддержки NULL (вы конвертируете их в '');
- непоследовательное разделение имен таблиц;
- использование двойных кавычек, отличных от ANSI, в качестве разделителей строк;
- использование буферизованных запросов к огромным таблицам нарушит максимальный предел памяти PHP;
- добавление всех строк для огромной таблицы нарушит ограничение максимальной памяти PHP;
- использование addlashes () вместо PDO :: quote ();
- проверка на наличие ошибок запроса только в конце функции;
- не проверять наличие неудачного создания файла;
- расширение gzip не может быть загружено
- Кроме того, вероятно, все еще не поддерживаются данные UTF8.
но он там доходит, не так ли?
Да, это лучше, чем оригинальный сценарий Дэвида Уолша. :-)
что не так с NULL для ''?
NULL - это не то же самое, что '' в SQL (кроме Oracle, но в этом случае они не соответствуют стандарту SQL). См. MySQL, лучше вставить NULL или пустую строку?
структура таблицы должна быть очень большой для максимального объема памяти. каждая вставляемая строка записывается в файл индивидуально, поэтому, опять же, строка должна быть очень большой для максимального объема памяти.
Я неправильно прочитал код проблемы ограничения памяти. Вы пишете вывод для каждой строки, так что это нормально (если строка не содержит капли размером 1 ГБ или что-то в этом роде).
Но вы не должны просто выводить один оператор INSERT с набором строк, разделенных запятыми. Даже mysqldump --extended-insert
выводит данные конечной длины, а затем запускает новый оператор INSERT. Критерий состоит в том, соответствует ли длина оператора INSERT параметру параметра --net-buffer-length
.
что не так с "" разделителями строк? как мне получить ANSI?
В ANSI SQL одинарные кавычки '' используются для разделения строковых литералов или литералов даты. Двойные кавычки «» используются для разделения идентификаторов, таких как имя таблицы или имена столбцов. По умолчанию MySQL обрабатывает их одинаково, но это нестандартно. См. Используют ли разные базы данных разные цитаты имен?. Если вы попытаетесь импортировать данные резервной копии на сервер MySQL, где у вас есть SET SQL_MODE=ANSI_QUOTES
, импорт завершится неудачно.
а какие таблицы не разграничены?
Пример: query('SELECT * FROM '.$table);
и фактически каждый из других случаев, когда вы используете $ table в запросе. Вы ограничили таблицу только один раз, в операторе INSERT, который выводит ваш скрипт.
все таблицы $ не разделены, все ли они должны быть с ""?
MySQL всегда распознает обратные тики как разделители идентификаторов и одинарные кавычки для строк / дат. Но двойные кавычки меняют значение в зависимости от упомянутого мной SQL_MODE. Вы не можете предположить, какой SQL_MODE действует на экземпляр MySQL, который вы восстанавливаете, поэтому лучше всего использовать обратные тики для идентификаторов и одинарные кавычки для строк. Причина, по которой вы должны разделять их при запросе таблицы, заключается в том, что имена таблиц могут быть зарезервированными словами SQL или содержать специальные символы и т. Д.
вы можете вставлять числа с плавающей запятой без разделителей в mysql, или вам нужен ''? Благодарность
Вы можете вставлять все числовые типы без разделителей. В разделителях нужны только строки и даты. См. Dev.mysql.com/doc/refman/5.6/en/literals.html
person
Bill Karwin
schedule
16.08.2013