Немного мистики при чтении и записи в фаил

12
D
На сайте с 05.06.2007
Offline
155
1106

Вообщем сайт находился на одном сервере с раид1, есть скрипт который примерно до 5 раз(обычно 1-2 раза) в секунду обновляет фаил размером в 50 кб, т.е. перезаписывает его, паралельная запись исключена, так же есть другие скрипты которые не реже читают этот фаил и пишут инфу в статистику, так вот на старом сервере никаких проблем не возникало!

На новом же, в день пару раз фаил читается как пустой, либо лишь часть его. На что валить? На то что жёсткий тупит или на то что Раид отсутствует?

Я знаю что проблему можно решить правильным LOCK_EX, но всё же волнует тот факт что на старом сервере такого никогда небыло! Активность сервера таже, конфигурация nginx+php таже, нагрузка на новый сервер намного меньше, ресурсов предостаточно, ибо он мощнее, и всё же такой баг возникает.

PS. старый сервер был Suse9, новый debian4.0.

Написал не мало шедевров ;)
DyaDya
На сайте с 11.04.2007
Offline
147
#1

1. Может проблема в этом?

http://ru2.php.net/manual/ru/function.stat.php

Замечание: Результаты этой функции кэшируются. Более подробную информацию смотрите в разделе clearstatcache().

2. Тем более, если знаете, что проблему можно решить: Я знаю что проблему можно решить правильным LOCK_EX

Так лучше решайте.

Выбирайте качественный хостинг (http://vashmaster.ru/informaciya/o_poleznyh_programmah/news83.php) и продвигайте сайты в СЕОПУЛЬТ (http://seopult.ru/ref.php?ref=72b5ed9561fe66a1). А на «SAPE» я в обиде :) Не упрекайте за очепятки, пишу вслепую (http://ergosolo.ru/) и также делаю сайты (http://www.vashmaster.ru/) ;)
Andreyka
На сайте с 19.02.2005
Offline
822
#2

sendfile в nginx включен?

Не стоит плодить сущности без необходимости
N
На сайте с 06.05.2007
Offline
419
#3

Так чем мощнее сервер, тем больше шансов, что второй процесс влезет во время записи.

Короче ошибка у вас была изначально и ее надо исправлять.

А кстати, почему вы не пишете в новый временный файл и не переименовываете ?

просто эта операция атомарна и не потребует переписывать весь читающий код.

Кнопка вызова админа ()
D
На сайте с 05.06.2007
Offline
155
#4

Запись уже с LOCK_EX

if (file5 = fopen (all_f, "w")) {

flock(fileno(file5), LOCK_EX);

fseek(file5, 0, SEEK_SET);

fputs (towrite , file5);

fflush(file5);

flock(fileno(file5),LOCK_UN);

fclose (file5);

}

DyaDya, в основном читает фаил как пустой..

sendfile on; - как и на старом, вот только что это даёт..

Так чем мощнее сервер, тем больше шансов, что второй процесс влезет во время записи.

вот это уже интересно, процессор был 2гх, а сейчас 2 по 2.5 ..

идея с переименованием файла мне ранее не приходила в голову, это конечно быстрее, но мне кажется может быть такое что фаил переименуется в момент чтения и опять получим не то что нужно )

Andreyka
На сайте с 19.02.2005
Offline
822
#5

Попробуйте на время отключить sendfile, иногда бывает что рвет страницы из-за него, но редко

А код - выглядит ужасно

Я бы подумал над memcache, pipe или fifo

N
На сайте с 06.05.2007
Offline
419
#6

Dimanych, да операция переименования атомарная ! не успеет никто вклиниться.

блокировка в коде обновления файла вам НИЧЕГО не даст, если остальной код чтения файла не делает flock.

а андрейка это бот. он на знакомые фразы реагирует ;)

Andreyka
На сайте с 19.02.2005
Offline
822
#7

Смерть человекам!

N
На сайте с 06.05.2007
Offline
419
#8

нет ну реально причем бы тут nginx и sendfile? проблема чисто программистская.

в линуксе man rename(2) четко написано :

If newpath already exists it will be atomically replaced (subject to a

few conditions; see ERRORS below)

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

почему это не должно работать? обновлять тот же файл и молиться на таненбаумов совершенно не обязательно.

D
На сайте с 05.06.2007
Offline
155
#9

>А код - выглядит ужасно

нормальный код, обычно мой алгор. код вообще не читаем программистами, и zend не нужен ;)

>Я бы подумал над memcache, pipe или fifo

да тоже не раз подумывал засунуть это дело в shared, но пока это не являлось узким местом в системе..

>если остальной код чтения файла не делает flock

уже сделал для чтения, посмотрим результат

> а андрейка это бот. он на знакомые фразы реагирует

иногда очень похоже, но может быть там просто двойной смысл =)))

Почитал про атомарность переименовывания, но разве не может быть тот случай когда фаил переименовывается во время чтения... что произойдёт?

скрипт дочитает старый фаил? (былоб супер)

скрипт подумает что файла нет и остановит чтение? (баг)

скрипт продолжит чтение но уже нового файла? (ужас)

PS. появление бага приходится сваливать на быстроту процессора и отсутствие раид

N
На сайте с 06.05.2007
Offline
419
#10

подразумевается атомарность на уровне системных вызовов.

(в лучшем случае там те же блокировки на уровне inode. в худшем - одна блокировка на все ядро)

файлы с диска не удаляются пока последний процесс не освободит файл.

поэтому из трех вариантов случится первый - скрипт дочитает старый файл.

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий