Страница 1 из 1
Падение производительности
Добавлено: 13 апр 2005, 14:47
teamforce
Добрый день,
Столкнулся с проблемой падения производительности сервера при большом количестве изменений в базе. На сервер баз данных с 10 application серверов складываются данные. До того как положить данные в базу делается проверка, а не положил ли их уже другой application сервер. Количество update'ов 100-150 тысяч в сутки. Раз в сутки вся эта таблица вычищается. В результате этой бурной деятельности через неделю производительность сервера падает, вырастает количество ждущих процессов и вся система нагибается. Лечится backup/restore, но это плохой вариант поскольку приходится останавливать все application сервера. Сервер баз данных Firebird 1.5.2. Железо - Dual Xeon и 4 гигабайта памяти. Размер базы практически не меняется и составляет 500 мегабайт.
Пока придумал только использовать еще один in-memory SQL сервер для хранения update'ов. Может есть более здравые идеи? Внедрять второе соединение с базой данных в работающее приложение немного тяжко будет...
Заранее благодарен за совет,
Данис
Re: Падение производительности
Добавлено: 13 апр 2005, 15:21
Merlin
teamforce писал(а):Добрый день,
Количество update'ов 100-150 тысяч в сутки. Раз в сутки вся эта таблица вычищается.
Если нет зависимостей с этой таблицей в самой базе, оптимально будет вычищать радикальным способом - drop/create.
teamforce писал(а):
В результате этой бурной деятельности через неделю производительность сервера падает, вырастает количество ждущих процессов и вся система нагибается.
Что наводит на размышления о наличии в приложениях долгоиграющих write транзакций. Особенно вредоносны в этом плане транзакции с уровнем изоляции concurrency.
teamforce писал(а):
Лечится backup/restore, но это плохой вариант поскольку приходится останавливать все application сервера.
Это в хорошо спроектированной системе должно неплохо лечиться и при помощи sweep, но, на фоне упомянутых write транзакций-долгожителей особо на него надеяться без остановки приложений на время его работы не приходится.
teamforce писал(а):
придумал только использовать еще один in-memory SQL сервер для хранения update'ов. Может есть более здравые идеи?
Проконтролировать управление транзакциями и прмвести его в божеский вид (длинные читающие, если вообще таковые необходимы, read_commited read, пишущие короткие) и наладить регулярный sweep.
teamforce писал(а):
Внедрять второе соединение с базой данных в работающее приложение немного тяжко будет...
Ни пониль.
Добавлено: 13 апр 2005, 15:42
kdv
базу IBAnalyst-ом смотрел, когда тормозит?
Добавлено: 13 апр 2005, 15:47
teamforce
Я про IBAnalyst только сегодня узнал когда форум почитал.

Обязательно посмотрю в следующий раз.
За идеи большое спасибо. Вычистку с помощью drop/create сделаю прямой сейчас.

Sweep повешу на cron вместе с удалением таблицы.
К вопросу о долгоиграющих write'ах - действительно на insert'е еще trigger висит и сразу после хранимая процедурка еще вызывается из нескольких запросов. Посмотрю что можно сделать чтобы их время выполнения уменьшить.
Второе соедение к базе данных я планировал вводить для того чтобы разделить на 2 базы - оперативную на каком-нибудь in-memory SQL сервере и аналитическую оставлю на Firebird'е. Надеюсь после того как все подправлю этого уже не потребуется.
Добавлено: 13 апр 2005, 18:24
Merlin
teamforce писал(а):
К вопросу о долгоиграющих write'ах - действительно на insert'е еще trigger висит и сразу после хранимая процедурка еще вызывается из нескольких запросов. Посмотрю что можно сделать чтобы их время выполнения уменьшить.
Не, это последнее о чём следует думать. В транзакции должно выполняться столько действий, сколько диктует логика предметной области и их сложность должна быть такой, какой нужно. Но не больше - выполнены действия, которые могут быть валидны только все вместе - коммит немедленно. Фатальный сценарий такой - утром юзер Вася запустил задачу, открыл форму с гридом, активизировал запрос (читай транзакцию, причём она write) и весь день то полистает, то запостит чего-нибудь, то просто в носе поковыряет. А может и не постить, но write-транзакция висит. Если это снапшот (concurrency), то он должен видеть _всю_ базу в таком состоянии, в котором она была на момент его старта по определению. То есть, в течение дня юзера Петя и Маша могли пол-базы три раза проапдейтить и четверть потом удалить, но Васин снапшот держит все версии всех записей по всей базе, которые без него давно признали бы мусором и снесли к чёртовой матери. По данным последних исследований, read_commited write транзакции тоже могут приводить к такому эффекту, хоть и не должны. А ещё есть такой враг народа, как rollback. Если с утра юзер Коля изменил одну запись, потом почесал репу и сказал - а ну его - его отроллбаченная транзакция становится точкой отсчёта, начиная с которой остальные транзакции грузят информацию о других транзакциях в память для собственных нужд, с целью опознания мусора и определения какие версии они должны видеть, какие нет. Мусор он (rollback) не удерживает, но память под Transaction Inventory Pages дуется, дуется, пока не приходит к тому, что скоро лопнет. А это тоже отнюдь не способствует быстрдействию. Вот свип-то и ликвидирует последствия роллбака и заодно прибирает мусор. Последнее с успехом, правда, делает и любая другая транзакция, когда на мусор натыкается. Но при одном условии - если этот мусор уже можно признать мусором (см. юзера Васю). А зловредный Вася и свипу не даст мусор собрать, то есть, если такие возможности у Васи есть, то, пока у него их не отобрали путём пересмотра управления транзакциями в программе, перед свипом его надобно из базы выгнать.
Добавлено: 14 апр 2005, 09:20
teamforce
Неее... Таких клинических случаев быть не должно. Dataaware компоненты вообще не используется. Все операции проводятся через классы предметной области, а там все очень просто - методы работы с базой сводятся к Load, Create, Update. Rollback'и тоже не используются, вообще у JDBC connector'а AutoCommit стоит после каждого запроса.
Еще раз спасибо за идеи. Я их уже реализовал. Если не поможет, буду внимательно глядеть на базу с помощью IBAnalyst'а.