LINUX.ORG.RU

PHP потеря данных.


0

1

Всем привет. Есть VPS 1гГц 512мб, ubuntu 10.10. В работе 20 php скриптов, которые прилично кушают память, судя по информации из top, свопа нет (total: 0кб), зато ОЗУ загружена на все 100%, ни одного свободного кб, скрипты работают, но данных много, а результат странный. Из более чем трех миллионов записей, после обработки должно остаться примерно 1-1.5к (а получается 150штук). Скрипты работают «немного» глупо (на самом деле очень глупо), берут из базы примерно по 172к строк за один запрос, а потом обрабатывают. Допустим примерно так:

SELECT bla, blaa FROM table WHERE id>=234 LIMIT 170000
потом используя указатель на ресурс запроса, через mysql_result данные вытаскиваются в цикле и обрабатываются.

Скрипты, конечно, поправлю, но Вопрос: могут ли пропадать данные просто так, точнее при нехватки ОЗУ? При этом скрипты продолжают работать. И как правильно настроить своп?

Заранее благодарен.

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

своп можно настроить так: выделяешь раздел, делаешь на него mkswap, делаешь swapon /dev/раздел_своп, так же желательно внести в /etc/fstab строчку типа такой

/dev/раздел_своп swap swap sw 0 0

чтобы своп подключалася автоматически при загрузке системы.

AndreyKl ★★★★★ ()
Ответ на: комментарий от AndreyKl

Добавил своп на 1024мб, но он не отображается в top, там по-прежнему 0кб. Изменил скрипт, в результате сейчас в запасе 15-30 мб, но видимо какие-то утечки или что еще, но кол-во памяти успешно падает с каждым часом. Перезагружать серв не желательно. Боюсь как бы за ночь память совсем не кончилась, кстати, сейчас скрипт дает более правдоподобный результат, так что проблема с памятью действительно сильно влияла. Я не знаю как устроен курсор mysql в php, но видно он не генерирует исключений при нехватке памяти, + все скрипты запускались практически одновременно и часть времени уходила только на получение результата от mysql, возможно еще на том этапе данные «побились».

marcuzy ()
Ответ на: комментарий от marcuzy

хм. возможно я слишком категоричен.

вообще, теоретически, данные при нехватке памяти теряться могут, конечно. дургой вопрос - как это будет в случае с mysql + php. как я себе представляю, вряд ли там что-то может потеряться. но, конечно зависит от схемы. если у Вас схема к примеру, такая:

  • цикл:
    • достаём из майскюэль строку
    • делаем с ней вещи
    • складываем в php-массив результат
  • конец цикла
  • кладём результат в mysql

то конечно же все данные из массива потеряются если память закончиться внутри цикла к примеру.

AndreyKl ★★★★★ ()

Для больших результатов нужно использовать mysql_fetch_[row|array|assoc|object], а после обработки блока данных нужно освобождать результат запроса.

RR ()
Ответ на: комментарий от Sosiska

согласен, почему то все пхписты считают что документацию читать не нужно.

RR ()

Ничего не понял: после обработки должно остаться 1-1.5к необработанных записей (т.е. 3млн записей всё равно остаются в базе, но из низ 1.5к необработанные), или должно остаться всего 1-1.5к, т.е. в процессе обработки ты их удаляешь? Все твои скрипты одновременно делают SELECT bla, blaa FROM table WHERE id>=234 LIMIT 170000 без всякого ORDER? Распиши подробнее, что происходит.

SOmni ★★ ()
Ответ на: комментарий от SOmni

Все 3.4 млн. записей условно делятся на куски для разных экземпляров (эта конфигурация в отдельной таблице), скрипт запускается со своим идентификатором, который указывает на конфигурацию. На счет запроса, было так: каждый скрипт забирал определенную порцию данных из БД

 $res = mysql_query('SELECT bla, blaa FROM table LIMIT xxx, 172000 ORDER BY id'); //где ххх некое число

/*далее в цикле указатель на ресурс запроса (переменная $res) использовался в цикле, например:*/
for ($i=$last; $i<172000;$i++){
$bla = mysql_result($res, $i, 0);
....
}

Согласен всё это не оптимально, включая запрос в базу, но то было просто спонтанное решение, даже экспериментальное.

Для больших результатов нужно использовать mysql_fetch_[row|array|assoc|object]

Да, действительно, для скорости прирост, но разве с точки зрения расхода памяти это что-то изменит?

marcuzy ()
Ответ на: комментарий от AndreyKl

>то конечно же все данные из массива потеряются если память закончиться внутри цикла к примеру.

В этом случае вылетит фатальная ошибка и до никакой «потери данных» дело просто не дойдёт.

KRoN73 ★★★★★ ()
Ответ на: комментарий от marcuzy

>mysql_query(...)

Где идентификатор БД? Работа с идентификатором по умолчанию при смешанных запросах может приводить к смене контекста ресурса. _Всегда_ используйте прямое указание соединения.

KRoN73 ★★★★★ ()
Ответ на: комментарий от KRoN73

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

marcuzy ()
Ответ на: комментарий от marcuzy

Да и забыл, записи обрабатываются, удовлетворяющие условиям попадают в отдельную таблицу.

Так, и что, в отдельную таблицу попадает меньше записей, чем надо? Вместо 1.5к всего 150 или что? И что это ещё за $last в

for ($i=$last;...
, если все записи должны обработаться?

SOmni ★★ ()
Ответ на: комментарий от SOmni

Да, попадало меньше, чем рассчитывалось. И данные действительно пропадали, другого объяснения нет.

$last - описочка, там 0. Алгоритм я переделал на более рациональный, и работает он с успехом.

marcuzy ()
Ответ на: комментарий от KRoN73

гм. ты прям как маленький. прям если я не написал явно - сам как будто додумать не можешь. НЕ ВЕРЮ ! :) добавь mysql delete в цикл. вот тебе и потеря данных.

AndreyKl ★★★★★ ()

При чём тут вообще оперативная память?! Top может показать, что занято всё, потому что всё свободное занято кешами. Запустите один скрипт на своей системе и посмотрите время выполнения. потом время выполнения, когда они выполняются пачкой. Если существенно выше — пробуем увеличить. Своп на VPS? Мне кажется странным, не могу скаать за виртуалки, которые используются у вас на сервере, но я б на вашем месте о нём не думал, а дебажил и чинил скрипты.

Deleted ()

т. е. у тебя сначала удаляется оригинальная запись, а потом добавляется обработанная? А ты не пробовал использовать транзакции? Тогда в случае падения скрипта в процессе выполнения все изменения просто откатятся, и можно будет позже попробовать их обработать ещё раз.

INFOMAN ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.