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 данные вытаскиваются в цикле и обрабатываются.

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

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



Последнее исправление: marcuzy (всего исправлений: 1)

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

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

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

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

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

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

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

Хотя, я видимо неправильно создал своп..

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 ★★★★★
()
Ответ на: комментарий от AndreyKl

А что тебе не ясно? Тут вроде все просто..

marcuzy
() автор топика

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

Deleted
()

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

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