![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Кто руками трогал 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
Как они реагируют на такое: в таблице ~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
no subject
Date: 2015-05-04 01:42 pm (UTC)no subject
Date: 2015-05-04 01:56 pm (UTC)Далее, надо глянуть - где именно косяки - i/o, проц сервера, задержки сети, проц клиента - обычно это легко различимо. Ну и дальше по обстоятельствам - крутить кэш FB, ставить SSD, искать плохие индексы и прочее такое.
no subject
Date: 2015-05-04 02:04 pm (UTC)no subject
Date: 2015-05-04 02:09 pm (UTC)Жрет проц - это значит или они в FB вычисления массово делают, или же база целиком в кэше но на каждый чих сканируется целиком. Проверяется запуском process explorer и втыканием в i/o статистику.
Еще можно попробовать запустить на новой версии с мониторингом, хотя неадекватные люди вполне способны прибить клиентский софт к определенной версии сервера (что, теоретически, можно отлечить, похачив fbclient.dll чтобы возвращала всегда правильную версию).
no subject
Date: 2015-05-04 02:55 pm (UTC)http://momjian.us/main/writings/pgsql/mvcc.pdf
no subject
Date: 2015-05-04 03:11 pm (UTC)no subject
Date: 2015-05-04 03:30 pm (UTC)no subject
Date: 2015-05-04 04:26 pm (UTC)no subject
Date: 2015-05-04 03:32 pm (UTC)копирование таблицы эквивалентно ее чтению со сборкой мусора, если не указать в подключении спецфлаг "без сборки мусора"
Т.е. обходных путей против транзакций в стиле "грохаем таблицу под ноль" вообще нету.
no subject
Date: 2015-05-04 04:33 pm (UTC)no subject
Date: 2015-05-04 05:32 pm (UTC)Есть альтернативный вариант реализации: вместо удаления сохраняется текущее значение ID и далее обрабатываются записи после него. Оно в принципе подвержено тем проблемам, которые ты описывал для оракл-кластера (генерация сиквенсов пачкой) но мне некритично, т.к. не оракл, и ID генерятся локально.
А вот что в этом плохого: бэкап БД будет линейно замедлятся, а удаление старых записей создает те же проблемы, только перенося их в обслуживающий процесс (т.е. вместо 100 раз удалить по 100 записей - 1 раз удалять 10000).
Поэтому я пытаюсь осмыслить, это проблема Firebird или принципиальная проблема реализации очередей с транзакциями поверх MVCC.
no subject
Date: 2015-05-04 06:45 pm (UTC)no subject
Date: 2015-05-04 06:49 pm (UTC)Идея прогнать эту же нагрузку на Postgresql мне не пришла в голову вообще, хотя там работы на 2-3 дня вообще.
no subject
Date: 2015-05-04 06:54 pm (UTC)всегда ваш,
К.О.
no subject
Date: 2015-05-04 09:56 pm (UTC)Я конечно не знаю, какая там задача, но может быть имеет смысл вообще избегать удалений и добавлений, или хотя бы свести их к минимуму? Апдейты, пусть это и реплейс значений всех колонок, намного быстрее же (возможно, в несколько раз быстрее), меньше расход памяти, меньше "мусора", да и фрагментация будет меньше. Например, если нужно одну запись удалить, и одну добавить, то один апдейт полюбому лучше делита и инсерта. Прошу прощения, если не в тему.
no subject
Date: 2015-05-05 01:17 am (UTC)Вместо удаления помечай записи как "удаленные", а по ночам или когда нагрузка минимальна проводи реальное удаление?
no subject
Date: 2015-05-05 01:35 am (UTC)no subject
Date: 2015-05-05 02:53 am (UTC)no subject
Date: 2015-05-05 04:47 am (UTC)no subject
Date: 2015-05-05 05:23 am (UTC)http://sql.ru/forum/actualtopics.aspx?bid=2
no subject
Date: 2015-05-05 06:07 am (UTC)Но меня больше интересует ситуация в других СУБД.