metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2015-05-04 04:14 pm

Firebird vs Postgres vs Oracle, MVCC и очереди

Кто руками трогал Postgres или Oracle (или прочие MVCC СУБД)?

Как они реагируют на такое: в таблице ~1 млн записей, в нее долбятся 2-3-5-10 клиентов, каждый над своим подмножеством записей делает что-то вроде "3/4 записей делаем update, 1/4 удаляем, добавляем еще столько же" и повторять это 24/7. Т.е. антипаттерн "очередь поверх MVCC БД, да еще сделанная через пень-колоду".

Firebird с его реализацией MVCC на такое реагирует нехорошо - накапливается мусор в БД и если, не дай бог, рядом будет длинная транзакция (например бэкап) - то мусора будет охрененно много, после чего какая-то из рабочих транзакций станет собирать мусор, и тоже станет длинной, в результате чего есть шансы поиметь бесконечное накопление мусора и нужно будет отключать рабочие процессы и собирать мусор или же базе будет проще сделать backup-restore (с ключиком -g - отключенной сборкой мусора), чем ждать.

Т.е. при определенном проценте версий записей, сборка мусора в Firebird становится настолько тяжелой по i/o, что прочитать базу целиком один раз без сборки мусора для бэкапа и потом восстановить намного быстрее, чем ждать сборки мусора стандартными механизмами.

Что больше всего смущает в этом - то что сборка мусора на ходу читает базу по кругу какое-то неимоверное количество раз (судя по i/o), т.е. для 100 мб базы может быть прочитано-записано 10-100 гб.

Каждый раз это вызывает желание залезть в кишки сервера и поискать там какой-нибудь неявно окопавшийся алгоритм маляра шлемиеля, потому что оно имеет явно нелинейную зависимость от количества записей в целевой таблице. Или же там что-то вроде нелокальности данных - там не кластерный индекс, соответственно версии записей могут лежать по всему файлу БД как попало, а оно их пытается сканировать линейно.

Еще меня посещает мысль сымитировать MVCC руками, загнать поверх такую же нагрузку и посмотреть, не является ли она принципиально несовместимой с MVCC без втаскивания туда какого-нибудь окасаки или LSM.

PS: Вот собственно описание аналогичной проблемы и ответы на нее http://osdir.com/ml/firebird-db/2013-01
/msg00003.html

[identity profile] dennis_chikin.livejournal.com 2015-05-04 01:42 pm (UTC)(link)
Лучше б кто-нибудь сказал, как можно сделать так, чтобы база о 5000 записей (ну правда объем - около сотни мег), перетащенная с access на FB при работе с одним клиентом дает адское слайд-шоу, и, главное, нельзя-ли это сладшоу как-то "разделать" обратно, при условии, что показывалка - вся из себя проприетарная. Ну вот просто с очередной версии стал fb вместо ацесса, и началось. Версия привязана к железу.

[identity profile] norguhtar.livejournal.com 2015-05-04 02:55 pm (UTC)(link)

[identity profile] vit-r.livejournal.com 2015-05-04 03:11 pm (UTC)(link)
А можно в одной транзакции копировать старую таблицу в новую копию, сделать VACUUM и переименовать новую в старую?

[identity profile] falcrum.livejournal.com 2015-05-04 04:33 pm (UTC)(link)
Как-то странно выглядит "1/4 удаляем" - не отсюда проблемы?

[identity profile] http://users.livejournal.com/_slw/ 2015-05-04 06:45 pm (UTC)(link)
возьми да проверь, постгрес поставить несложно

[identity profile] thetvv.livejournal.com 2015-05-04 09:56 pm (UTC)(link)
ME> 1/4 удаляем, добавляем еще столько же

Я конечно не знаю, какая там задача, но может быть имеет смысл вообще избегать удалений и добавлений, или хотя бы свести их к минимуму? Апдейты, пусть это и реплейс значений всех колонок, намного быстрее же (возможно, в несколько раз быстрее), меньше расход памяти, меньше "мусора", да и фрагментация будет меньше. Например, если нужно одну запись удалить, и одну добавить, то один апдейт полюбому лучше делита и инсерта. Прошу прощения, если не в тему.

[identity profile] kuaw26.livejournal.com 2015-05-05 01:17 am (UTC)(link)
Не в курсе че да как там у вас, но может вам поможет "отложенное" удаление?
Вместо удаления помечай записи как "удаленные", а по ночам или когда нагрузка минимальна проводи реальное удаление?

[identity profile] jdevelop.livejournal.com 2015-05-05 02:53 am (UTC)(link)
в поцтгрессе есть замечательная штука - партишнинг. При удачном стечении обстоятельств каждый клиент может работать на записи со своим шардом, а чтение делается агрегатно по всей таблице. И все в принципе счастливы.

[identity profile] kranov.livejournal.com 2015-05-05 04:47 am (UTC)(link)
oracle хранит старые версии в отдельном пространстве undo (rollback segment(in-memory-undo)), поэтому пухнуть таблица будет если только из-за апдейтов, строка при апдейте не влезает в зарезервированное место в блоке и сплитится, ну и индексы будут разбалансироваться постепенно из-за делитов (раз в n-лет можно поребилдить (онлайн)), т.е. надо настроить заранее резерв (pctfree/pctused). В общем-то что-то похожее у меня было (объемы правда в 10раз побольше), транзакции (транзакция 2-5 строк) банкоматов и посов пишутся в таблицу (апдейтятся), и в течении месяца удаляются (перетекают в бэкофис).

[identity profile] fraks-nsk.livejournal.com 2015-05-05 05:23 am (UTC)(link)
А что мешает спросить про Firebird у непосредственно разработчиков?
http://sql.ru/forum/actualtopics.aspx?bid=2