LINUX.ORG.RU

Вставка новых данных в середину большого файла. Как поведет себя ФС?


0

0

Необходимо разработать свою простую БД (вообщем, файл) для хранения некоторой информации.

Данные у меня для быстроты выборки в файле должны быть отсортированны.

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

Как в этом случае поведет себя файловая система?

То есть был файл ==========================

Были новые данные +++

И я вставляю эти данные в файл ========+++===============

Получается, если у меня файл размером 1гб, а я вставляю данные в место в файле, например, примерно в 600мб, то остальные 424мб будут сдвинуты файловой системой? Или файловая система как-то выделит новый блок (не среди блоков файла) и запишет быстро данные в этот блок, но файл станет фрагментирован? То есть, как я понял, информация о том, где искать данные файла хранится в списке. Каждый элемент списка содержит адрес блока данных на ЖД, где лежит очередная порция данных файла. То есть файловая система может взять два соседних блока и вставить между ними новый блок данных (то есть мои новые данные) и связать блоки в нужную последовательность. В данном случае сдвигать 424мб не понадобится.

То есть я имею ввиду, есть два соседних блока 1 и 2 Мне надо вставить между ними новые данные, т.е. блок данных 3.

При этом есть список, где блок 1 указывает что после него идет блок 2. Но теперь берется и меняется последовательность. То есть 1 => 3 => 2

Так как поведет себя современная файловая система?

Насчет файловой системы интересует конкретно работа ext3 и ReiserFS. Ну или какую файловую систему порекомендуете для максимальной производительности в данном случае.

Выбор данных у меня производиться мгновенно. НО волнует вопрос производительности при вставке новых данных. А вставки данных будут очень часто.

Надеюсь, я смог правильно донести суть вопроса :-)

Ответ на: комментарий от Reset

я не спец, но из-за вот такой вот ситуации, топикстартеру возможно хорошо было бы изобрести велосипед, написав собственный модуль ядра и системный вызов для работы с ext2/3, который будет именно вставлять данные, а не перемещать гигантские объяемы данных. Т.е. работа должна быть в основном с метаданными, точнее с инодами.

anonymous
()

Ну в общем может лучше все-таки БД нормальную использовать?

Ну или если очень хочется файл, то необязательно все хранить в 1 файле. Разбей его на несколько десятков и объем уменьшится.

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

Интересно, а как профессиональные БД решают эту проблему? Ведь они тоже часто хранят данные в сортированном порядке.

Кстати, придумал глупое, но решение проблемы. Можно сразу создать большой файл. А потом в него уже писать данные. Надо будет просто прикинуть кол-во необходимых записей. В данном случае, просто нерационально будет использоваться место. То есть места на ЖД будет использоваться больше, чем, возможно, будет необходимо. Но проблема места, впринципе, не критична :-) А когда кол-во записей перевалит на расчитанный размер, то создавать еще один файл.

Кстати, я еще знаю, что файловые системы вида ext плохо хранят большие файлы. Точнее хранят ФС ext файлы хорошо, но доступ к концу большого файла вычисляется достаточно долго ввиду косвенной адресации.

Может кто-то может подсказать рекомендуемый размер файла при превышении которого лучше писать данные в новый файл?

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

Лучше отказаться от ФС совсем и использовать raw-разделы.

Только конечно вставлять в середину не нужно. Нужно вставлять в конец и модифицировать индексы, по которым и будет упорядочивание (которые можно держать полностью или частично в памяти, и сохранять как обычные файлы на ФС).

Вот только вступать на этот путь надо только если есть 100% уверенность, что обычные реляционные БД не подходят. Ибо объём работы достаточно большой.

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

открываешь файл, делаешь fseek до такого объема который тебе нужен, получается файл большого размера, который реально на диске занимает 0 байт.

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

А может в начале файла хранить указатели на записи? А эти указатели будут отсоритрованы по нужному критерию. Тогда данные можно просто дописывать, а в заголовок файла добавлять на нужную позицию указатель на новую запись. Если размер записей большой, то это именно то, что нужно. Так же можно хранить в двух файлах БД. В одном указатели на записи в другом. Первый файл можно mmap-нуть в память, а в памяти сдвигать данные можно намного быстрее, чем с использованием read/write в файл.

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

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

Поэтому и возник вопрос данного топика.

Но видимо, действительно, прийдется придумать создание какого-то индекса, а новые данные писать в конец файла.

И, возможно, один раз в сутки упорядочивать файл на ЖД, путем его полной перезаписи в упорядоченном формате.

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

> Подозреваю, что для указанной задачи подойдет какая-нибудь бд типа berkeley

+1

Зачем изобретать колесо?

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

> > Подозреваю, что для указанной задачи подойдет какая-нибудь бд типа berkeley

+1

> Зачем изобретать колесо?

Прозреваю, что на указанных автором типичных объемах (файл базы от 1 гига) BerkeleyDB будет сосать не нагибаясь.

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

> Прозреваю, что на указанных автором типичных объемах (файл базы от 1 гига) BerkeleyDB будет сосать не нагибаясь.

Атнють

anonymous
()

делаешь файл indexes. в нем хранятся имена файлов с блоками данных.

например data1, date2 ... datan

в файлах date1 ... хранятся собственно данные. тогда вставка будет из себя представлять создание нового date n+1 и вставка в середину файла index

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

> Интересно, а как профессиональные БД решают эту проблему?

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

Нормальные СУБД пишут всегда данные в конец таблицы, или в первую же свободную "дырку" в таблице, образовавшуюся в результате удаления строк. "Порядок строк" в свою очередь определяется такой штукой как "индекс" - то есть специальным списком, в котором хранятся значения ключевых элементов влияющих на порядок строк, и адрес строки относительно начала таблицы.

> А когда кол-во записей перевалит на расчитанный размер, то создавать еще один файл.

Не занимайтесь организацией ментального секс любей с вами (не е..те мозги людям), а возьмите нормальную СУБД в которой все эти проблемы давно решены профессионалами. Например PostgreSQL или MySQL.

Эти штуки заодно дадут вам такие штуки как "транзакция" (атомарность операции изменения данных с возможностью отката), "журналирование" (относительную гарантию целостности данных в случае например сбоя питания), "консолидация" (отбор и группировка данных по некоторым критериям с вычислением значения агрегатных функций типа "среднне арифметическое", "сумма" или "количество"), единый язык запросов a.k.a "SQL" - а не изобретенный вами велосипед функций для работы с вашей структурой файлов, а также множественные индексы и очень быстрые сортировки не только по заранее придуманному вами критерию - который неправилен изначально.

Всем тем кто предлагает решить задачу тем путем которым ее хотел решить спросивший: а вы не думали, что строки могут быть РАЗНОЙ ДЛИНЫ и тогда простым seek() вы не отделаетесь?

> но доступ к концу большого файла вычисляется достаточно долго ввиду косвенной адресации.

Может вам сходить почитайть документацию? А то уши в трубочку скручиваются. Аксиома при работе с дисковым I/O больших объемов "время доступа к данным в оперативной памяти пренебрежимо мало по сравнению с доступом к данным на диске". Точка.

no-dashi ★★★★★
()
Ответ на: комментарий от BlackSergey

>И, возможно, один раз в сутки упорядочивать файл на ЖД, путем его полной перезаписи в упорядоченном формате.

А еще есть фрагментация файла на диске. ИМХО, все БД прекрасно работают пока вся БД помещается в ОЗУ/в кеше диска. Если вам так важна скорость, добавляйте ОЗУ в сервер.

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

> ИМХО, все БД прекрасно работают пока вся БД помещается в ОЗУ/в кеше
> диска. Если вам так важна скорость, добавляйте ОЗУ в сервер.
>

И как же это БД работают с объемами в десятки и сотни GB, а то и с
терабайтами? Неужели там столько ОЗУ?

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

> Прозреваю, что на указанных автором типичных объемах (файл базы от 1 гига) BerkeleyDB будет сосать не нагибаясь.

Ну на моих задачах bdb справлялась с базами около 50Г, может и больше будет работать, я не проверял.

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

Мне нравится SQLite. Она довольно легко включается в код приложения на Си. Но ввиду реализации этой БД она полностью блокирует файл во время записи.

Может кто-то использовал эту библиотеку в своих разработках. Насколько нужно часто писать в БД, чтобы начались тормоза?

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

>Может кто-то использовал эту библиотеку в своих разработках. Насколько нужно часто писать в БД, чтобы начались тормоза?

Предварительно создана таблица:

CREATE TABLE tbl2 (one INTEGER PRIMARY KEY AUTOINCREMENT,
two VARCHAR(50), three REAL);

Есть враппер около объекта sqlite3 ( взят здесь: http://www.codenet.ru/db/other/sqlite/ )

Пробуем записать в базу подряд 1000 записей примерно так:


for(int i=0; i<1000; i++) {
char *str_q_t="insert into tbl2 values (NULL, \'value\', %f);";
char str_q[500];
sprintf(str_q, str_q_t, (double)i);
db->SQLRun(str_q);
}

... в общем, я сначала подумал, что прога подвисла и прервал ее выполнение. Полез в базу - ан нет, все пучком, записи появились. Перезапустил. Через 2 минуты 20 секунд все свершилось. Причем, выборка из таблицы происходит шустро. А на запись, получается, система туговатая. Может чего не так скомпилено... хотя вряд-ли.

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

> И как же это БД работают с объемами в десятки и сотни GB, а то и с терабайтами? Неужели там столько ОЗУ?

Ну сотня-две гигабайт памяти на серверах не редкость :)

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