Эта тема на forum.dklab.ru


WingedFox: Конкурс на решение идиотской задачи
Есть удалённый "production server".
Есть дамп 500Mb.
Есть PMA.

max_upload_size = 2Mb
memory_limit = 8Mb
max_execution_time = 30sec
max_input_time = 60sec

Сервер и саппорт - в Нидерландах.
Увеличивать лимиты отказываются.
А сделать - надо...

Рассматриваются любые предложения по решению задачи.
chin:
а что если залить дамп куда-то к себе не сервер, а оттуда скриптом скачать через file_get_contents()?
WingedFox:
Не получается: заканчивается память.
Юрий Насретдинов:
WingedFox
А как насчёт использования, скажем, exec("wget ..."); ?
bæv:
Шелла, я так понимаю, нет? А ftp — тоже, что ли?
Тогда только остаётся смотреть сколько оно в архиве места займёт — и делить соответственно на части.

(Если там и zip/gzip нету — делить на 250 частей.)
Юрий Насретдинов:
WingedFox
А, блин, чего-то я туплю... Сделать кароче чтение удалённого файла по кускам... С content-range поиграться, я думаю, должно получиться. Или, если на FTP можно залить, так может вообще можно просто напрямую «промотать» файлик до предыдущего прочитанного места :)
bæv:
Или, если на FTP можно залить

Если ftp есть, то вообще проблемы не вижу — Dumper'ом всё должно залиться.
WingedFox:
Нету FTP.
Есть Plesk - аналог cPanel.
Залить на сервер - это меньшая проблема. Можно кусочками читать удалённый файл и сливать локально.

Но влить всё в базу...
Там есть записи по 1-2Mb, которые в память не влезают. 8*)
Вот думаю, как отслеживать занимаемую процессом память, чтобы не нарываться на сообщение "упс... память закончилась" 8*)

Есть желание сделать законченное решение, чтобы в таких клинических случаях (ибо человек ни от чего не застрахован) как можно качественнее автоматизировать процесс.

PS: там ещё и safe mode со всеми вытекающими =\
Миша Спларов:
Если в вашем дампе есть единичные строки с длинной больше, чем разрешено, то ничего не получится в любом случае.
Возможные решения - шелл, удалённый коннект к бд.
WingedFox:
Отдельные потерянные строки - это не беда.
Нужно чтобы было залито максимум... Ну и лог ошибок.

Дальше уже будет о чём разговаривать. А то счас мы препираемся на пальцАх.
Иероним:
А Perl на этом хостинге есть?
WingedFox:
Сие науке неизвестно.
Но хостинг на линухе, так что должен быть.
Иероним:
1) можно сделать самому себе шелл (в сети должно навалом вариантов)
2) нужно написать скрипт undumper, который будет заливать данные в базу построчно (если 1 строка = 1 запись) и писать в лог инфу о том, насколько он успешно залил запись. Так память, скорее всего, не переполнится.
Заодно в отдельный файл писать номер последней залитой строки. Чтобы следующий запуск начинать именно с нее.

При этом в перл есть функция alarm, которая позволяет послать программе SIGALARM по истечении нужного времени. Так что ставим в начале прграммы alarm(25) и обработчик $SIG{ALARM}, который будет просто корректно завершать последнюю операцию заливки и гладко выходить из программы.

А затем сделать этот скрипт CGI-скриптом, и вызывать его через браузер N раз.

В принципе, все это реализуемо и на PHP, только вместо alarm и обработки сигналов нужно будет на каждой итерации цикла проверять, сколько осталось времени.
WingedFox:
Иероним
На Перле в любом случае - не интересно, т.к. там таких ограничений нет 8*)

Если есть возможность запустить перловый скрипт, то базу можно залить вообще за один присест.
amikhailov:
Можно воспользоваться программой Mysql Front, либо EMS Mysql Manager. На сервер заливается php-файл, который играет роль HTTP-туннеля. В программе указывается способ соединения с базой "HTTP-tunneling" или что-то навроде того. Вуаля, пирог готов!
Rumata:
из обсуждения мне ясно только, что
1. дамп на сервер залить можно
2. юникс-машина
3. возможно шелл предоставлен

я бы рекомендовал смотреть в сторону шелла
WingedFox:
amikhailov
При использовании Mysql Front или EMS Mysql Manager можно контролировать размер получаемого запроса?

Rumata
Шелла нет. Фтп нет. Крона нет. Населена параноиками. 8*)

Как залить файл - уже разобрался и сделал. Просто читаю по кусочкам с удалённого сервера и сливаю эти кусочки локально.

Проблема возникает при работе с базой - иногда спокойно проходит запрос в 400Кб, а иногда спотыкается на 200Кб.
Так что, для автоматизации процесса надо как-то отлавливать момент, когда заканчивается память.....

Хотя, в следующий понедельник их самый большой босс возвращается... Возможно мучения и закончатся 8*)
amikhailov:
WingedFox
Насчет EMS Manager точно не знаю, а вот MySQL Front отсылает дамп по строчкам.
Rumata:
Шелла нет. Фтп нет. Крона нет. Населена параноиками
скорее всего перл есть что-то вроде 5.00ххх

так что о перле можно и не думать :)
WingedFox:
amikhailov
По строчкам - это хорошо.
Но строчки даже в 1Мб в память не помещаются.
Т.ч. их каким-то образом надо пропускать...
amikhailov:
А если файл почистить то больших строчек?
WingedFox:
А по какому критерию их чистить?
иногда спокойно проходит запрос в 400Кб, а иногда спотыкается на 200Кб.
amikhailov:
Методом научного тыка :))

Сначала вырезать строки размером больше 1 МБ. Потом вырезать строки > 500 КБ и т.д., пока не закачаются все строки.
WingedFox:
Дык это туча ручной работы..... Которую делать совсем не хочется. 8*)
amikhailov:
Ну отчего же ручной? Можно ведь и скриптик написать.
WingedFox:
amikhailov
Какой именно? Я пока не вижу никакой зависимости расхода памяти от размера запроса.
Можно, конечно, написать скрипт который будет читать ответы сервера, но есть проблема с тем, что время работы скрипта изменению не подлежит
т.е. придётся делать многоуровневый самовызов.....
В принципе - решение.
amikhailov:
memory_limit = 8Mb

А разве 200 Кб больше 8 МБ? Или я чего-то недопонимаю?
WingedFox:
Второе.
Как и я.
Почему mysql_query иногда падает в этом случае - науке неизвестно.

Вопль раздаётся "unable to allocate XXXXХ bytes".
amikhailov:
Какой-то долбанутый сервер. А служба поддержки отвечает на вопросы?
WingedFox:
Ага. "Спасибо что обратились. Помочь не можем" (с).
Может быть это потому, что сервера у них galadriel, mithrandir?
amikhailov:
Тогда пишите скрипт. Галадриэль с Митрандиром, safe-mode и нехватка памяти - приговор окончательный по-моему.
WingedFox:
Вот и пишу... 8*(
Ant:
На счёт памяти. В Perl, например, такая штука: хоть после использования переменной, ссылка на неё удаляется, физически же системе не возвращается. Её можно вернуть, только написав "undef $var". То биш в памяти висит самое большой значение переменной, которое встретилось до данной точки работы скрипта. Возможно, такая же "фича" присутствует и в PHP - надо разбираться.

На счёт Perl. Если он есть, почему бы его-таки не использовать? Ответы типа "так не интересно" - не принимаются. Для совсем интересной задачи можно дать условия: есть сервер и есть мой комп, но нет канала связи. Как на сервер залить инфу с моего компа? (-:
WingedFox:
Ant
Непонятно, куда можно заливать перловые скрипты.
И как заставить их работать. И где сам перл =)

Если бы была возможность запустить перловый скрипт - проблемы бы и не возникло.
Advanced Guest:
А внешний коннект к бд запрещен?
А то можно слить дамп себе на комп, mysql к удалённому хосту и в дамках.
WingedFox:
Advanced Guest
Запрещён, конечно =)
Я даже к внутреннему пароль не знаю =)
amikhailov:
Вам можно только позавидовать -) Сервер, на котором запрещено все -))
WingedFox:
Не всё. Веб-доступ разрешен 8*)
amikhailov:
То есть по сути открыт только 80 порт? Или еще 21-й?
WingedFox:
80, 21, 25, 443
Может быть что-то ещё...
Ramzes_:
Жаль сейчас мой сервер лежит, я там написал в mc один скриптик, который единственный смог перегнать дамп форума на 200мб в базу, делал он это все долго, т.к. читал по одному байту, но и память всю не сожрал. скриптик читает sql файлик, находит ;\n и отправляет мускулю. Моя 200мб база лилась около 30 минут, долго, ну а что делать когда так много всего? ;)

Эта тема на forum.dklab.ru