powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
25 сообщений из 33, страница 1 из 2
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847493
eltim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Есть база под Firebird 3.0.4, в которой хранятся таблицы-справочники.
К базе постоянно делается множество запросов из других баз, хранящих идентификаторы записей нужных таблиц, на чтение доп.информации о соответствующей записи справочника.
Запросы выполняются посредством JDBC-драйвера Jaybird 3.0.5 отдельными Java-потоками, самостоятельно устанавливающими соединение с БД (conn) и закрывающими его перед завершением своей работы.
При организации подключения задаётся
Код: java
1.
2.
3.
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
conn.setAutoCommit(false);
conn.setReadOnly(false);

, т.к., несмотря на то, что, в основном, это SELECT-запросы, логикой приложения допускается делать изменения в справочники.

Каждый запрос выполняется в блоке
Код: java
1.
2.
3.
4.
5.
6.
try (PreparedStatement pstat = conn.prepareStatement(querySelect, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
...
}
catch {
...
}

,
гарантирующем закрытие PreparedStatement и связанных с ним ресурсов (ResultSet).

Одна из таблиц этой базы - ORD.
После backup/restore базы (при переносе её из FB 2.5) и краткого периода работы в ней её размер был 64 Мб, gstat -a -i выдал следующую информацию:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
Database header page information:
	Flags			0
	Generation		30122
	System Change Number	0
	Page size		8192
	ODS version		12.0
	Oldest transaction	30100
	Oldest active		30101
	Oldest snapshot		30101
	Next transaction	30108
	Sequence number		0
	Next attachment ID	1189
	Implementation		HW=AMD/Intel/x64 little-endian OS=Windows CC=MSVC
	Shadow count		0
	Page buffers		0
	Next header page	0
	Database dialect	3
	Creation date		Jun 13, 2019 19:20:30
	Attributes		force write

    Variable header data:
	Sweep interval:		20000
	*END*
...

Analyzing database pages ...
...

ORD (141)
    Primary pointer page: 220, Index root page: 221
    Pointer pages: 1, data page slots: 16
    Data pages: 16, average fill: 71%
    Primary pages: 16, secondary pages: 0, swept pages: 0
    Empty pages: 2, full pages: 13
    Fill distribution:
	 0 - 19% = 3
	20 - 39% = 0
	40 - 59% = 0
	60 - 79% = 0
	80 - 99% = 13
...



Затем с базой шла работа примерно месяц. В результате её размер раздулся до 214 Мб, при том, что кол-во записей ни в одной из таблиц не изменилось.
gstat выдал для неё:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
Database header page information:
	Flags			0
	Generation		28811520
	System Change Number	0
	Page size		8192
	ODS version		12.0
	Oldest transaction	28808999
	Oldest active		28809000
	Oldest snapshot		28809000
	Next transaction	28809062
	Sequence number		0
	Next attachment ID	725831
	Implementation		HW=AMD/Intel/x64 little-endian OS=Windows CC=MSVC
	Shadow count		0
	Page buffers		0
	Next header page	0
	Database dialect	3
	Creation date		Jun 13, 2019 19:20:30
	Attributes		force write

    Variable header data:
	Sweep interval:		20000
	*END*

...

ORD (141)
    Primary pointer page: 220, Index root page: 221
    Pointer pages: 11, data page slots: 14784
    Data pages: 14784, average fill: 6%
    Primary pages: 14, secondary pages: 14770, swept pages: 0
    Empty pages: 4989, full pages: 13
    Fill distribution:
	 0 - 19% = 14771
	20 - 39% = 0
	40 - 59% = 0
	60 - 79% = 0
	80 - 99% = 13
...


Известно, что к ней было примерно 40 запросов на создание записей в таблице ORD, и все они окончились неудачей из-за violation of PRIMARY or UNIQUE KEY constraint.
Остальные запросы были SELECT, commit() после которых не делался.

Заметно ухудшение производительности.

Мои предположения:
1. В базе почему-то не ведётся сборка мусора, из-за чего её размер растёт.
2. Сборка мусора не ведётся, т.к. SELECT-транзакции оформлены как read/write и являются "длинными".
3. "Длинными" транзакции являются, т.к. нет явного commit() после SELECT.

Хотя в FB работаю с версии 2.0, изучал её поверхностно.
Перед тем, как обратиться за помощью, читал http://www.ibase.ru/transactions/ и https://firebirdsql.org/file/documentation/drivers_documentation/Jaybird_2_1_JDBC_driver_manual.pdf (для jaybird 3 такого не нашёл).

Хотел бы, чтобы база не росла в размерах, если её таблицы только читаются, и не было снижения быстродействия при работе с ней.
Прошу помочь, желательно максимально доступным языком. Сокращения, которые я периодически встречал на форуме, пока пытался найти что-то похожее на мою проблему, мне большей частью не понятны.

4. Если не менять тип соединения на read-only, поможет ли в моей ситуации явный commit() для SELECT-запросов?
5. Если не менять тип соединения на read-only, поможет ли в моей ситуации setAutoCommit(true) для SELECT-запросов?
6. Если поменять тип соединения на read-only для SELECT-запросов, поможет ли это в моей ситуации?
7. Если поменять тип соединения на read-only, можно ли не делать явный commit() для SELECT-запросов?
8. Как делать правильно, на Ваш взгляд (Ваш рецепт)?

Спасибо за корректные, доброжелательные ответы.
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847494
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
БЛОБ'ы ?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847495
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
eltim,

gstat -a не дает информацию по версиям. Поэтому надо делать gstat -r
только так будет видно, есть там версии, или нет.
По идее, судя по маркерам транзакций (oit, oat, ost, next) никакого мусора или версий в базе нет.
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847503
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
eltim,

либо управляйте транзакциями явно, либо не ставьте conn.setAutoCommit(false);

eltimPrimary pages: 14, secondary pages: 14770

охренеть. Ваша таблица сильно фрагментирована. Походу вы там одной записи 100500 версий создали. Статистику надо было показать с выводом средней длины цепочки версий (переключатель -r)

Есть ли блобы? Небось конкатенацией блобов занимаетесь
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847507
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv,

у него таблица через чур сильно фрагментирована. Вторичных страниц в 1000 раз больше первичных. Как известно на вторичных страницах помещаются либо фрагменты, либо версии.
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847590
eltim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимопроходящий,

в базе BLOB-ы есть, но в других таблицах. В этой (ORD) BLOB-ов нет, только поля CHAR, VARCHAR, SMALLINT, INT, BIGINT.


gstat -r сначала:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
...
ORD (141)
    Primary pointer page: 220, Index root page: 221
    Total formats: 1, used formats: 1
    Average record length: 130.47, total records: 625
    Average version length: 0.00, total versions: 0, max versions: 0
    Average fragment length: 0.00, total fragments: 0, max fragments: 0
    Average unpacked length: 1868.00, compression ratio: 14.32
    Pointer pages: 1, data page slots: 16
    Data pages: 16, average fill: 71%
    Primary pages: 16, secondary pages: 0, swept pages: 0
    Empty pages: 2, full pages: 13
    Fill distribution:
	 0 - 19% = 3
	20 - 39% = 0
	40 - 59% = 0
	60 - 79% = 0
	80 - 99% = 13
...



потом:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
...
ORD (141)
    Primary pointer page: 220, Index root page: 221
    Total formats: 1, used formats: 1
    Average record length: 130.48, total records: 625
    Average version length: 0.00, total versions: 0, max versions: 0
    Average fragment length: 0.00, total fragments: 0, max fragments: 0
    Average unpacked length: 1868.00, compression ratio: 14.32
    Pointer pages: 11, data page slots: 14784
    Data pages: 14784, average fill: 6%
    Primary pages: 14, secondary pages: 14770, swept pages: 0
    Empty pages: 4989, full pages: 13
    Fill distribution:
	 0 - 19% = 14771
	20 - 39% = 0
	40 - 59% = 0
	60 - 79% = 0
	80 - 99% = 13
...


Существенное дополнение :
Проанализировав код, выяснил (вспомнил), что приложение в отдельном потоке через каждый заданный интервал времени (~ 60 мин.) делает UPDATE всех записей ORD (обновляет поле-флаг актуальной информацией с сервера):
Код: java
1.
int rowsUpdated = pstat.executeUpdate();


commit() делается, только если rowsUpdated != 0.
Потом соединение закрывается, поток завершается.
Насколько я помню, если поле до обновления содержало то же самое значение, что и указываемое при обновлении, FB UPDATE не делает, стало быть, rowsUpdated = 0.. Получается множество неподтверждённых транзакций?
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847592
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
09.08.2019 16:32, eltim пишет:
> через каждый заданный интервал времени (~ 60 мин.) делает UPDATE всех записей ORD (обновляет поле-флаг актуальной информацией с сервера)

зачем?
какую задачу вы таким способом решаете?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847594
eltim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимопроходящий,

..с LDAP-сервера. Чтобы хранить её [информацию] у себя локально, т.к. он м.б. периодически недоступен.
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847597
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
09.08.2019 16:42, eltim пишет:
> ..с LDAP-сервера. Чтобы хранить её [информацию] у себя локально, т.к. он м.б. периодически недоступен.

зачем апдейтить то, что не менялось?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847598
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
eltimприложение в отдельном потоке через каждый заданный интервал времени (~ 60 мин.) делает UPDATE всех записей ORDНу так сервер и выполняет то, что просили. Это занимает место. Мусор собирается не сразу. Но в данный момент он собран. А место осталось зарезервировано.

eltimНасколько я помню, если поле до обновления содержало то же самое значение, что и указываемое при обновлении, FB UPDATE не делаетКонечно делает
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847602
eltim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денислибо управляйте транзакциями явно, либо не ставьте conn.setAutoCommit(false);

Идеология в том, чтобы управлять явно, т.к. используется универсальный класс работы с БД, поддерживающий, в т.ч., запись сразу в несколько таблиц как единую операцию.
Что не так здесь в явном управлении?
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847607
eltim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvladКонечно делает
В то же самое время статистика по другой таблице:
сначала
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
...
FTBP (130)
    Primary pointer page: 189, Index root page: 190
    Total formats: 2, used formats: 1
    Average record length: 154.96, total records: 9308
    Average version length: 0.00, total versions: 0, max versions: 0
    Average fragment length: 0.00, total fragments: 0, max fragments: 0
    Average unpacked length: 5056.00, compression ratio: 32.63
    Pointer pages: 1, data page slots: 224
    Data pages: 224, average fill: 87%
    Primary pages: 224, secondary pages: 0, swept pages: 0
    Empty pages: 2, full pages: 221
    Fill distribution:
	 0 - 19% = 2
	20 - 39% = 0
	40 - 59% = 1
	60 - 79% = 0
	80 - 99% = 221
...



потом
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
FTBP (130)
    Primary pointer page: 189, Index root page: 190
    Total formats: 2, used formats: 1
    Average record length: 154.96, total records: 9308
    Average version length: 0.00, total versions: 0, max versions: 0
    Average fragment length: 0.00, total fragments: 0, max fragments: 0
    Average unpacked length: 5056.00, compression ratio: 32.63
    Pointer pages: 1, data page slots: 224
    Data pages: 224, average fill: 87%
    Primary pages: 224, secondary pages: 0, swept pages: 222
    Empty pages: 2, full pages: 221
    Fill distribution:
	 0 - 19% = 2
	20 - 39% = 0
	40 - 59% = 1
	60 - 79% = 0
	80 - 99% = 221
...


Отличие только в swept pages. Стало быть, мусор собирался, но таблицы ORD это не коснулось?
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847610
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
09.08.2019 17:00, eltim пишет:

> Отличие только в swept pages. Стало быть, мусор собирался, но таблицы ORD это не коснулось?

коснулось.
мусор собран.
но каждый твой апдейт создаёт новую версию записи.
под неё выделяется место на страницах данных.
после сборки мусора это место помечается как свободное.
но оно то уже выделено и размер базы вырос.
посмотри на average fill таблицы ORD.
у тебя было 71%, а стало 6%.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847615
eltim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимопроходящийзачем апдейтить то, что не менялось?

Это лучший вариант с т.зрения БД.
Но он связан накладными расходами - сверкой значений каждого обновляемого поля.
Предположим, каждый раз будут новые данные.
Мимопроходящийкоснулось.
мусор собран.
но каждый твой апдейт создаёт новую версию записи.
под неё выделяется место на страницах данных.
после сборки мусора это место помечается как свободное.
но оно то уже выделено и размер базы вырос.
UPDATE всегда создаёт новую версию записи? Можно ли избежать роста БД при UPDATE?
Ведь свободного места-то уже много, зачем выделять новое?
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847619
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
09.08.2019 17:17, eltim пишет:
> Это лучший вариант с т.зрения БД.
> Но он связан накладными расходами - сверкой значений каждого обновляемого поля.

сервер железный, он справится.

> UPDATE всегда создаёт новую версию записи?

да.

> Можно ли избежать роста БД при UPDATE?

нет.

> Ведь свободного места-то уже много, зачем выделять новое?

всё зависит от того, как у тебя организовано управление транзакциями.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847621
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
eltimЭто лучший вариант с т.зрения БД.

Это полный бред с любой точки зрения. Если у вас сервер временами недоступен - подымайте
его локальное зеркало, которое будет доступно всегда.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847627
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
eltimМожно ли избежать роста БД при UPDATE?
вы считаете, что 214 мб база это какой-то адский размер? По сравнению с 214 гиг, например, это ноль, ничто.
Которое полностью помещается в кэше файловой системы.

Тем не менее, в таблице ORD 625 записей. А вот фрагментирована она на 14784 страницы, куда (при 8к странице) помещается почти МИЛЛИОН записей.
Вопрос - сколько времени надо было держать какую-то транзакцию открытой, чтобы нагенерить миллион версий, если каждый час их количество увеличивается на 625?
Если вы сделаете приложение с одной транзакцией, которая будет делать update/commit, то убедитесь, что никакого миллиона версий там не будет, соответственно, не распухнет база, и не будет такой фрагментации.

Либо, как вариант, такое количество версий - это просто случайность, типа IBExpert с активной транзакцией, оставленного на несколько дней.
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847629
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не нравится мне эта статистика... Я бы сделал валидацию (gfix -v -full) для начала
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847634
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
eltimНасколько я помню, если поле до обновления содержало то же самое значение, что и указываемое при обновлении, FB UPDATE не делает

у UPDATE могут быть косвенные эффекты, даже update T set F = F может, навскидку
1) изменить формат записи, после ALTER TABLE
2) просто попытаться прочитать данные, если БД частично разрушена
3) запустить триггеры

Если не хочется "холостого пробега", то и делай явно UPDATE T SET F = V WHERE F IS DISTINCT FROM V (ну или ...WHERE F <> V - но это на NULLах не сработает)
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847636
eltim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мимопроходящийкоснулось.
мусор собран.

Мусор собран, но swept pages для ORD были и остались = 0. Что тогда это значит?
kdvсколько времени надо было держать какую-то транзакцию открытой, чтобы нагенерить миллион версий, если каждый час их количество увеличивается на 625?

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

Я вроде написал, как. Что нужно/можно добавить?
Dimitry SibiryakovЭто полный бред с любой точки зрения.

Dimitry, здесь я согласился с Мимопроходящим:
Мимопроходящийзачем апдейтить то, что не менялось?

Dimitry SibiryakovЕсли у вас сервер временами недоступен - подымайте
его локальное зеркало, которое будет доступно всегда.

Мысль понятна (в данной задаче это неприменимо), но не хотелось бы отвлекаться от темы вопроса.

И всё-таки, нужно ли делать commit после SELECT-а и commit после UPDATE-а, не обновившего ни одной записи (при autoCommit = false)?
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847638
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
COMMIT нужно делать всегда,
за исключением тех случаев,
когда удержание транзакции делается ОСОЗНАННО.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847639
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
eltimМусор собран, но swept pages для ORD были и остались = 0. Что тогда это значит?Мусор собран не свипом\сборщиком мусора

eltimcommit после UPDATE-а, не обновившего ни одной записиОткуда известно, про "ни одной записи" ?
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847640
eltim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvladНе нравится мне эта статистика... Я бы сделал валидацию (gfix -v -full) для начала
gfix -v -full выдал:
Код: sql
1.
2.
Summary of validation errors
	Number of record level warnings	: 2
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847643
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
eltim,

firebird.log содержит детали
...
Рейтинг: 0 / 0
FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
    #39847646
eltim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvladОткуда известно, про "ни одной записи" ?

Код: java
1.
int rowsUpdated = pstat.executeUpdate();


rowsUpdated в данном случае - это "the row count for SQL Data Manipulation Language (DML) statements"
Если rowsUpdated = 0, значит, подходящие записи для обновления отсутствовали.
...
Рейтинг: 0 / 0
25 сообщений из 33, страница 1 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / FB 3.0.4 + Jaybird 3.0.5 - Рост размера базы при SELECT
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]