Начало » Использование СУБД » Firebird, HQbird, InterBase » Очищение старых данных в мультифайловой БД
Очищение старых данных в мультифайловой БД [сообщение #5031] |
Tue, 14 May 2024 13:04 |
TheKeeper
Сообщений: 1 Зарегистрирован: May 2024
|
Junior Member |
|
|
Здравствуйте. У меня возникла такая проблема, не могу найти решение.
Мы используем Firebird с ALTER DATABASE ADD FILE. У меня возникла проблема, что я не вижу способа оперативно освободить место на жёстком диске. Я могу удалить старые данные, но физически место не очищается. gfix sweep тоже не решает проблему. Через некоторое время я просто упрусь в потолок места на жёстком диске.
Можно решить проблему через gbak backup/gbak restore, но это требует остановки работы базы данных на долгий период времени, что может быть неприемлимым.
Есть ли возможность:
* Очистить место из БД на горячую, во время работы, удалив какие-то старые данные?
* Если нет, то хотя бы остановить БД лишь на небольшой промежуток времени, чтобы быстренько переформатировать не всю БД, а лишь файл с удалёнными данными?
|
|
|
|
|
|
Re: Очищение старых данных в мультифайловой БД [сообщение #5035 является ответом на сообщение #5031] |
Tue, 14 May 2024 14:07 |
neozx1984
Сообщений: 27 Зарегистрирован: June 2022
|
Junior Member |
|
|
TheKeeper писал(а) Tue, 14 May 2024 13:04Есть ли возможность:
* Очистить место из БД на горячую, во время работы, удалив какие-то старые данные?
* Если нет, то хотя бы остановить БД лишь на небольшой промежуток времени, чтобы быстренько переформатировать не всю БД, а лишь файл с удалёнными данными?
Можно используя утилиту pluck.
Вот статья на Хабре о ней Уменьшение размера файла в СУБД Ред База Данных / Firebird без операции backup & restore
Но есть ряд подводных камней:
* Файл СУБД должен быть на SSD.
* Есть баги на старых версиях XFS, нужно обновлять ядро.
* Желательно, что бы файловая система была заполнена не более чем на 80-90%.
P.S. pluck не поддерживает многофайловые БД. Не думал, что их ещё кто-то использует. В принципе можно сделать поддержку.
P.P.S. pluck работает только под ОС Linux. Можно сделать версию для Windows при необходимости.
|
|
|
|
|
|
|
|
|
Re: Очищение старых данных в мультифайловой БД [сообщение #5045 является ответом на сообщение #5031] |
Wed, 15 May 2024 07:55 |
fraks
Сообщений: 139 Зарегистрирован: June 2022 Географическое положение: Новосибирск
|
Senior Member |
|
|
TheKeeper писал(а) Tue, 14 May 2024 17:04Здравствуйте. У меня возникла такая проблема, не могу найти решение.
Мы используем Firebird с ALTER DATABASE ADD FILE. У меня возникла проблема, что я не вижу способа оперативно освободить место на жёстком диске. Я могу удалить старые данные, но физически место не очищается. gfix sweep тоже не решает проблему. Через некоторое время я просто упрусь в потолок места на жёстком диске.
Можно решить проблему через gbak backup/gbak restore, но это требует остановки работы базы данных на долгий период времени, что может быть неприемлимым.
Есть ли возможность:
* Очистить место из БД на горячую, во время работы, удалив какие-то старые данные?
* Если нет, то хотя бы остановить БД лишь на небольшой промежуток времени, чтобы быстренько переформатировать не всю БД, а лишь файл с удалёнными данными?
ИМХО ты не там видишь проблему и борешься не с тем с чем надо.
Непонятно зачем тебе ALTER DATABASE ADD FILE. У вас такая база что на один раздел не влазит?
Файл базы может только расти, уменьшаться не может, кроме как пересоздать базу через Backup/Restore посредством gbak.
При ADD FILE, насколько я помню, сам не пользовался, нужно сразу задавать размер файла, и он не будет меняться.
Вобщем, смысл в следующем. Когда ты удаляешь данные в базе, командой DELETE FROM, то фактически данные не удаляются а помечаются как удаленные.
Место от этих данных базой будет использовано для новых данных, если эти помеченные кто-то или что-то проверит на никомуненужность
Обычно, для того что бы сразу после удаления освободить место, нужно прочитать только что удаленное.
Я делаю примерно так:
DELETE FROM TABLE WHERE (УСЛОВИЕ);
COMMIT;
SELECT COUNT(*) FROM TABLE WHERE (УСЛОВИЕ);
COMMIT;
Count(*) естественно выдаст 0, на подсчет уйдет какое-то то время, т.к. сервер будет проверять каждую найденную (удаленную) версию записи на предмет нужна ли она кому-нибудь, и если обнаружит что не нужна - удалит ее, освободит место для дальнейшего использования.
Естественно, тут еще может быть масса всяких тонкостей, например транзакция может быть запущена "без сборки мусора" - тогда count(*) так же выдаст 0 но место не свободится.
Или у кого-то запущена длинная транзакция в которой он читает эти удаленные записи, и пока та транзакция не завершится, эти данные будут для нее хранится. Опять же, это зависит от уровня изоляции транзакции и т.п.
Вобщем, тебе нужно читать на ibase.ru статьи про версионность и транзакции.
И, возможно, придется переделать приложение что бы работало корректно с транзакциями.
|
|
|
|
Переход к форуму:
Текущее время: Thu Nov 21 18:10:05 GMT+3 2024
Общее время, затраченное на создание страницы: 0.00785 секунд
|