У меня есть консольный скрипт PHP, который вызывается через cron, который сам, помимо прочего, создает tar-файл каталога.
При вызове скрипта PHP через cron файл tar создается неправильно. Следующая ошибка выдается при просмотре tar-файла:
gzip: stdin: unexpected end of file
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now
При вызове PHP-скрипта вручную через консоль файл tar создается правильно. Вывод журнала cron не показывает ошибок.
Здесь вызов tar формирует скрипт PHP.
exec("cd $this->backupTempFolderName/$id; tar -czf ../../$this->backupFolderName/$tarFileName $dbDumpFileName documents");
У кого-нибудь есть идея, почему tar создается правильно, когда вызывается вручную, и не работает при вызове через cron?
Обновить: Ошибка при создании файла tar через cron:
tar: ../../backup/20150819-060003.tar.gz: Wrote only 4096 of 10240 bytes
tar: Error is not recoverable: exiting now
Иногда ошибка:
tar: ../../backup/20150819-054002.tar.gz: Cannot write: Broken pipe
tar: Error is not recoverable: exiting now
Как было сказано ранее, при выполнении через cron файл tar создается, но всегда на 50% правильного размера (при выполнении сценария вручную):
-rw-r--r-- 1 gtz gtz 1596099468 Aug 19 06:25 20150819-042330.tar.gz <- Manually called skript, working tar
-rw-r--r-- 1 gtz gtz 858570752 Aug 19 07:21 20150819-052002.tar.gz <- Script called via cron, broken tar
Обновление 2
После некоторых дальнейших исследований, основанных на вводимых здесь данных, можно добавить, что cron с именем script работает на виртуальном частном сервере — я подозреваю, что могут существовать некоторые ограничения для заданий cron, которые не задокументированы хостером (только ограничение по минимуму) Время повторения указано в документации).
Эта ошибка обычно возникает из-за недостатка места на диске.
Я хотел бы еще немного изучить эту тему, добавив несколько журналов до и после выполнения tar.
Также проверьте, какой пользователь использует ваша конфигурация для задания cron, в котором вы выполняете резервное копирование. Для этого пользователя также может быть установлен некоторый лимит квоты, чего не происходит, когда вы запускаете консоль вне cron.
Спросите у своего провайдера о квотах на VPS для пользователей и для процессов … Вот что здесь звучит.
Я думаю, что у вас есть ограничение ресурса
Как сказал М. Иванов, добавьте эту команду в ваш PHP-скрипт:
shell_exec("php -info");
и проверьте этот параметр как при запуске скрипта из командной строки, так и из задания cron
memory_limit => ???
Вы также можете попробовать запустить свой cron, увеличив предел памяти до 1600M
php -d memory_limit=1600M scriptCompressor.php
Надеюсь, это поможет 🙂
Вы можете попробовать создать тарбол непосредственно из PHP, чтобы избежать exec
вызов. Смотрите этот ответ: https://stackoverflow.com/a/20062628/5260945.
Кроме того, если смотреть на запись в cron, в вашем примере нет косой черты. Я знаю, что это может быть просто опечатка для комментария, но убедитесь, что у вас есть абсолютный путь для cd
команда. Среда по умолчанию для задания cron отличается от среды входа в систему.
у cronjobs сами по себе обычно нет границ. Если вы используете общий хостинг, возможно, они установили некоторые принудительные сценарии, но я подозреваю, что они также повредят резервные копии вашей консоли.
Если вы запускаете cronjobs из какого-либо контейнера, например, Drupal, у них есть особые ограничения.
Также проверьте пределы bash с:
ulimit -a
Сообщите о месте на диске до начала резервного копирования и на всякий случай. Обычно это очень мало на VPS.
Я уверен, что проблема с памятью или временем выполнения.
Выполните одно и то же, запустите тот же сценарий для каталога, который содержит только один тестовый файл, и проверьте выходные данные. Если ваш сценарий работает в этом сценарии, то он на 100% уверен в своей проблеме с памятью.
попробуйте настроить параметры памяти и выполнить ваш скрипт.
Я надеюсь, что это поможет вам.
Спасибо
Глядя на следующую ошибку.
tar: ../../backup/20150819-054002.tar.gz: Cannot write: Broken pipe
tar: Error is not recoverable: exiting now
Я вижу, что функция exec в сценарии PHP не блокирует и не вызывает ошибку преждевременно. Таким образом, сеанс PHP, который вызывается во время задания Cron, завершается до завершения команды. Это всего лишь предположение, но вы можете попытаться отправить его в фоновый режим при запуске из Cron.
exec("cd $this->backupTempFolderName/$id; tar -czf ../../$this->backupFolderName/$tarFileName $dbDumpFileName documents &");
Эта команда должна блокировать, так что это просто выстрел в темноте.
Ошибка возникает при попытке выполнить файл php и выдает ошибку EOF. Это означает, что где-то в вашем php-файле вы должны проверить код вашего cron-файла, может случиться так, что вы забудете завершить скобки условия или класса и т. Д …
Удачи [‘}
Для записи ошибок в журнал при выполнении через cron replace >/paht/to/application/app/logs/backup-output.log
в строке cron 2>&1 >/path/to/application/app/logs/backup-output.log
Также проверьте путь в строке cron .. возможно, каталог изменений не работает, как вы думаете. Попробуйте распечатать getcwd()
в журнал или что-то, при запуске сценария php из cron.
Редактировать: интересно, почему за это проголосовали not useful
, Спрашивающий упомянул, что ошибки не выводятся в журнал, когда cron выполняет скрипт. Это не трудно представить, как >
просто перенаправляет STDOUT, а не STDERR (на котором будут напечатаны ошибки php) в журнал. Итак, добавление 2>&1
может раскрыть некоторую новую информацию.