Firebird 1.5 и кеширование данных
Firebird 1.5 и кеширование данных
Разрабатываю БД - реестр населения и юрлиц, работаю с Firebird 1.5 через ODBC из программы, написанной на VC.
Структура БД примерно такая:
1. таблица граждан
2. таблица фирм
3. таблица адресов
таблицы связей
4. граждане-телефоны
5. граждане-адреса
6. граждане-фирмы
7. фирмы-телефоны
8. фирмы-адреса
9. адреса-телефоны
10,11,12 - словари для таблиц 1-3 (города, улицы, имена, фамилии, отчества), доп информация
размер таблиц - миллионы и десятки миллионов записей.
процесс разработки включает в себя в т.ч. и конвертацию десятков БД, собранных в разное время разными ведомствами разных городов в единый формат (с проверкой всех добавляемых данных и связей на присуствие в БД). Все это происходит на скромной машинке - P4/3GHz, 1G памяти, XP
до определенного момента все было отлично, и конвертация происходила с отличной скоростью - сотни записей в секунду на уже заполненной БД. Однако при конвертации одной таблицы, в которой были смешаны данные всех итспользуемых в БД типов, скорость упала неадекватно сложности процесса - больше чем на порядок относительно чуть более простого варианта. Проверил индексы, сделал измерение времени работы всех запросов, по итпам. Выяснилось следующее: стали тормозить все запросы без исключения. Путем несложного медитирования догадался, что птице перестало хватать паимяти для кеширования индексов.
Покопался в конфигах. Увеличил DefaultDbCachePages, один из тормозивших процессов стал работать нормально, Самый тяжелый - фиг. Никакое увеличение DefaultDbCachePages не могло заставить птицу отожрать больше 280М у системы.
Поставил беты вторрой версии птицы. Она отреагировала на увеличение параметра и ее удалось заставить сожрать 550М. Дальше и она отказалась увеличивать кеш, хотя в 1Г памяти приложение может спокойно выделить и 750М без свопа.
Отсюда вопрос - что делать дальше? Очевидный путь - переделать конвертацию, сделав ее многопроходной, так, чтобы на каждом проходе обрабатывалась только часть исходной строки и не задействовались все имеющиеся табилцы - понятен. Но хочется просто поставить побольше памяти в компьютер и не париться. Но упрямая птица отказывается использовать даже тот гиг, что есть, куда уж больше добавлять-то?
Структура БД примерно такая:
1. таблица граждан
2. таблица фирм
3. таблица адресов
таблицы связей
4. граждане-телефоны
5. граждане-адреса
6. граждане-фирмы
7. фирмы-телефоны
8. фирмы-адреса
9. адреса-телефоны
10,11,12 - словари для таблиц 1-3 (города, улицы, имена, фамилии, отчества), доп информация
размер таблиц - миллионы и десятки миллионов записей.
процесс разработки включает в себя в т.ч. и конвертацию десятков БД, собранных в разное время разными ведомствами разных городов в единый формат (с проверкой всех добавляемых данных и связей на присуствие в БД). Все это происходит на скромной машинке - P4/3GHz, 1G памяти, XP
до определенного момента все было отлично, и конвертация происходила с отличной скоростью - сотни записей в секунду на уже заполненной БД. Однако при конвертации одной таблицы, в которой были смешаны данные всех итспользуемых в БД типов, скорость упала неадекватно сложности процесса - больше чем на порядок относительно чуть более простого варианта. Проверил индексы, сделал измерение времени работы всех запросов, по итпам. Выяснилось следующее: стали тормозить все запросы без исключения. Путем несложного медитирования догадался, что птице перестало хватать паимяти для кеширования индексов.
Покопался в конфигах. Увеличил DefaultDbCachePages, один из тормозивших процессов стал работать нормально, Самый тяжелый - фиг. Никакое увеличение DefaultDbCachePages не могло заставить птицу отожрать больше 280М у системы.
Поставил беты вторрой версии птицы. Она отреагировала на увеличение параметра и ее удалось заставить сожрать 550М. Дальше и она отказалась увеличивать кеш, хотя в 1Г памяти приложение может спокойно выделить и 750М без свопа.
Отсюда вопрос - что делать дальше? Очевидный путь - переделать конвертацию, сделав ее многопроходной, так, чтобы на каждом проходе обрабатывалась только часть исходной строки и не задействовались все имеющиеся табилцы - понятен. Но хочется просто поставить побольше памяти в компьютер и не париться. Но упрямая птица отказывается использовать даже тот гиг, что есть, куда уж больше добавлять-то?
А двойка позволяет на лету менять размер? Хотя, конечно, я и перегнать данные из одной БД в другую могу. нО двойку я ставил только посмотреть. В бетатестеры не рвусь.hvlad писал(а):Если уж 2-ку взял, попробуй увеличить р-р страницы. И убедись, что БД в ОДС11
Но мысль вообще интересная, посмотреть, а не повлияет ли изменение размера страницы на выделение памяти. Вдруг там ограничение не на объем, а на количество страниц? Кто-нибудь с этим экспериментировал?
А что такое ОДС11?
Как обычно - бекап\ресторpticelov писал(а):А двойка позволяет на лету менять размер?hvlad писал(а):Если уж 2-ку взял, попробуй увеличить р-р страницы. И убедись, что БД в ОДС11
Дело твоё :pticelov писал(а):Хотя, конечно, я и перегнать данные из одной БД в другую могу. нО двойку я ставил только посмотреть. В бетатестеры не рвусь.
1. 2-ка будет быстрее искать ключ в индексе, особенно на большой странице.
2. 2-ка позволяет задать в 2 раза больше кеш
3. 2-ка нормально работает на запись с большим кешем
Ограничение на кол-во страницpticelov писал(а):Но мысль вообще интересная, посмотреть, а не повлияет ли изменение размера страницы на выделение памяти. Вдруг там ограничение не на объем, а на количество страниц? Кто-нибудь с этим экспериментировал?
Это следующая ОДС, после 10-ойpticelov писал(а):А что такое ОДС11?
Ох уж эти птицы
Двойку ставить не хочется. То, что глюки будут - понятно (правда мне не так страшны глюки при конвертации - а для работы потом я БД могу и в 1.5 перенести), но при первом же запуске моего импортера данных оно где-то молча зависло минут через 15 работы. Разбюираться было лень
В принципе, я могу поменять дефолтовые 4К размера страницы на что-нибудь побольше и в 1.5, раз уж там ограничение именно по количеству страниц. А может просто ограничение изменить? Это связано с чем-то разумным? А то странно как-то: память есть, а использовать - хрен! А в 2 версии лимит увеличили в 2 раза.
А насколько она быстрее ключ ищет? В принципе, я доволен скоростью - у меня все запросы выполняются пренебрежимо малое время, если кеша хватает. Правда я был доволен и jet'ом, пока на ограничение в 2M не напоролся - мне не так много надо.
А что за проблемы у 1.5 при записи с большим кешем?
Если бы я знал, Что такое ОДС, я бы ен спрашивал. Как я поинмаю, это номер формата файла БД? А если ен менять, то что будет? Хотелось бы (если уж экспериментировать) иметь максимальную совместимость взад.
В принципе, я могу поменять дефолтовые 4К размера страницы на что-нибудь побольше и в 1.5, раз уж там ограничение именно по количеству страниц. А может просто ограничение изменить? Это связано с чем-то разумным? А то странно как-то: память есть, а использовать - хрен! А в 2 версии лимит увеличили в 2 раза.
А насколько она быстрее ключ ищет? В принципе, я доволен скоростью - у меня все запросы выполняются пренебрежимо малое время, если кеша хватает. Правда я был доволен и jet'ом, пока на ограничение в 2M не напоролся - мне не так много надо.
А что за проблемы у 1.5 при записи с большим кешем?
Если бы я знал, Что такое ОДС, я бы ен спрашивал. Как я поинмаю, это номер формата файла БД? А если ен менять, то что будет? Хотелось бы (если уж экспериментировать) иметь максимальную совместимость взад.
Приручил я птичку
Поставил я страничку 16К, обнаружились 2 смешных эффекта, кроме ожидаемого (работать стало хорошо, выигрыш раз так в 5-6 по скорости при потреблении памяти около 700М)
1. Ставлю лимит кеша 62000 страниц - все работает, как ожидается, коннектятся 3 клиента без проблем, ставлю 62500 - второй клиент не коннектится к той же БД (к другой - легко). Ошибка
internal gds software consistency check (cannot start thread)
не то, чтобы очень напрягало, но эффект забавный
2. Ставил 70 тысяч кеш (где-то возле предела). Сервер пытался использовать 1050 метров, а у меня всего 1G, причем часть жрет XPя. Запускаю конвертор. Процесс стартует с 30 записей в секунду, потихоньку скорость начинает расти (по мерере засасывания страниц в кеш), параллельно в таскменеджере наблюдаю за ростом используемой физической памяти fbserver'ом, сокращением объема доступной и (когда доступная память упала до 10М) - системного кеша. fbserver дорос до 650M а скорость - до 100 записей в секунду. В этот момент мне приспичило запустить еще одну программу.
fbserver'а выкидывают в своп, размер используемой физической памяти падает до 400М. Скорость на пару секунд падает (работает другая программа) после чего восстанавливается, хотя система больше 450М отдавать птице не хочет, а ее прастущие потребности удовлетворяются виртуальной памятью. При этом скорость потихонечку продолжает расти и доходит до 150 записей в секунду.
Эксперимент повторялся дважды. Потом размер кеша был понижен, чтобы виртуальаня память не задействовалась - процесс разгонлся только до 100 с мелочью записей в секунду.
Вывод:
собстенный кеш огненной птицы не сишком эффективен, и для повышения его эффективности, как то ни странно, можно позволить серверу сваливаться в своп - винда по необходимости из свопа подкачивает данные быстрее, чем fbserver из файла БД.
1. Ставлю лимит кеша 62000 страниц - все работает, как ожидается, коннектятся 3 клиента без проблем, ставлю 62500 - второй клиент не коннектится к той же БД (к другой - легко). Ошибка
internal gds software consistency check (cannot start thread)
не то, чтобы очень напрягало, но эффект забавный
2. Ставил 70 тысяч кеш (где-то возле предела). Сервер пытался использовать 1050 метров, а у меня всего 1G, причем часть жрет XPя. Запускаю конвертор. Процесс стартует с 30 записей в секунду, потихоньку скорость начинает расти (по мерере засасывания страниц в кеш), параллельно в таскменеджере наблюдаю за ростом используемой физической памяти fbserver'ом, сокращением объема доступной и (когда доступная память упала до 10М) - системного кеша. fbserver дорос до 650M а скорость - до 100 записей в секунду. В этот момент мне приспичило запустить еще одну программу.
fbserver'а выкидывают в своп, размер используемой физической памяти падает до 400М. Скорость на пару секунд падает (работает другая программа) после чего восстанавливается, хотя система больше 450М отдавать птице не хочет, а ее прастущие потребности удовлетворяются виртуальной памятью. При этом скорость потихонечку продолжает расти и доходит до 150 записей в секунду.
Эксперимент повторялся дважды. Потом размер кеша был понижен, чтобы виртуальаня память не задействовалась - процесс разгонлся только до 100 с мелочью записей в секунду.
Вывод:
собстенный кеш огненной птицы не сишком эффективен, и для повышения его эффективности, как то ни странно, можно позволить серверу сваливаться в своп - винда по необходимости из свопа подкачивает данные быстрее, чем fbserver из файла БД.
-
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
Re: Приручил я птичку
Что забавного в исчерпании памяти настолько, что система не может даже создать поток ?pticelov писал(а):1. Ставлю лимит кеша 62000 страниц - все работает, как ожидается, коннектятся 3 клиента без проблем, ставлю 62500 - второй клиент не коннектится к той же БД (к другой - легко). Ошибка
internal gds software consistency check (cannot start thread)
не то, чтобы очень напрягало, но эффект забавный
2 hvlad:
Какое исчерпание памяти? Ее полно - и виртуальной и физической. В момент коннекта к БД (если это первый коннект к данной БД) птица выделяет память под кеш в полном объеме, но еще не использует ее. Прсото скачет размер выделенной памяти у процесса и все. Виртуальной памяти - еще несколько гигов (у меня минимальынй размер свопа - 4Г). Физической - тем более, ее вообще в момент коненкта не пользуют - она начинает заполняться по мере занесения данных в кеш.
Вероятно, какое-то магическое число общего размера памяти на процесс или переполнение какого-то сетчика размера памяти у самой птицы. 62500 стариниц по 16К - это ровно 1000000К памяти, т.е. 977M. 2 таких комплекта за 2Г не выходят. Но опасно близко.
Похоже, верный вывод такой - хоть тресни, но больше 2Г птица использвоать не сможет, пока на 64 бита не перейдет. Обидно, потому что в свете "глюка 2" (то, что виртуальная память винды дает более эффективное кеширование, чем кеш птицы), чем больше используешь - тем лучше.
2 Dmity:
Конечно, я прекрасно понимаю, что у него на каждую БД свой кеш, поэтому после обнаружения своей ошибки (что не проходили коннекты к разным БД) глюк и перестал быть столь мистическим.
Какое исчерпание памяти? Ее полно - и виртуальной и физической. В момент коннекта к БД (если это первый коннект к данной БД) птица выделяет память под кеш в полном объеме, но еще не использует ее. Прсото скачет размер выделенной памяти у процесса и все. Виртуальной памяти - еще несколько гигов (у меня минимальынй размер свопа - 4Г). Физической - тем более, ее вообще в момент коненкта не пользуют - она начинает заполняться по мере занесения данных в кеш.
Вероятно, какое-то магическое число общего размера памяти на процесс или переполнение какого-то сетчика размера памяти у самой птицы. 62500 стариниц по 16К - это ровно 1000000К памяти, т.е. 977M. 2 таких комплекта за 2Г не выходят. Но опасно близко.
Похоже, верный вывод такой - хоть тресни, но больше 2Г птица использвоать не сможет, пока на 64 бита не перейдет. Обидно, потому что в свете "глюка 2" (то, что виртуальная память винды дает более эффективное кеширование, чем кеш птицы), чем больше используешь - тем лучше.
2 Dmity:
Конечно, я прекрасно понимаю, что у него на каждую БД свой кеш, поэтому после обнаружения своей ошибки (что не проходили коннекты к разным БД) глюк и перестал быть столь мистическим.
Это ты у билли спроси.pticelov писал(а):2 hvlad:
Какое исчерпание памяти?
can not start thread выдаётся только если ОС не смогла создать поток.
Ещё вопросы ?
Сам придумал ?pticelov писал(а):Ее полно - и виртуальной и физической. В момент коннекта к БД (если это первый коннект к данной БД) птица выделяет память под кеш в полном объеме, но еще не использует ее. Прсото скачет размер выделенной памяти у процесса и все. Виртуальной памяти - еще несколько гигов (у меня минимальынй размер свопа - 4Г). Физической - тем более, ее вообще в момент коненкта не пользуют - она начинает заполняться по мере занесения данных в кеш.
А теперь включим мозг и подумаем - на куя птица будет просить у ОС под кеш виртуальную память ? И какого она будет делать это "по мере занесения данных в кеш" ?
НГ ещё не наступил, а сказки уже витают
Тебе совершенно точно сказали, в чём дело.pticelov писал(а):Вероятно, какое-то магическое число общего размера памяти на процесс или переполнение какого-то сетчика размера памяти у самой птицы
Хочешь фантазировать - твоё право
"Сам придумал ?" (C) hvladhvlad писал(а):Это ты у билли спроси.pticelov писал(а):2 hvlad:
Какое исчерпание памяти?
can not start thread выдаётся только если ОС не смогла создать поток.
Не надо за билли ничего придумывать - в этом состоянии треды прекрасно создаются, что элементарно проверяется запуском еще кучи программ. И объем свободной памяти (и физической, и виртуальной) прекрасно видно в taskmanager и taskinfo.
Как то ни странно - не сам. Просто нажал alt-ctrl-esc и посмотрел. Неожиданный ход?hvlad писал(а):Сам придумал ?pticelov писал(а):Ее полно - и виртуальной и физической. В момент коннекта к БД (если это первый коннект к данной БД) птица выделяет память под кеш в полном объеме, но еще не использует ее. Прсото скачет размер выделенной памяти у процесса и все. Виртуальной памяти - еще несколько гигов (у меня минимальынй размер свопа - 4Г). Физической - тем более, ее вообще в момент коненкта не пользуют - она начинает заполняться по мере занесения данных в кеш.
Отвечаю:hvlad писал(а):А теперь включим мозг и подумаем - на куя птица будет просить у ОС под кеш виртуальную память ? И какого она будет делать это "по мере занесения данных в кеш" ?
1. "на куя" - а другую не попросить. Только виртуальную память приложение и может запросить у системы
2. "И какого". Невнимательно читаешь. Я ж написал - выделяет виртуальную память оно сразу при первом коннекте к БД, в соответствии с установками кеширования для нее. А физическая выделяется приложению виндой по мерере необходимости. Это в любой книжке по архитектуре винды написано. Приложение попросило 1Г, винда сказала "отлично" (если свопфайла хватит), увеличила счетчик выделения памяти у приложения и подправила немножко у себя в табличках. И все.
Потом приложение начинает эту память использовать. Пишет куда-то байт, а физическую память-то не выделели ему еще, поэтому происходит прерывание по отсуствию страницы и винда выделяет страничку (при необходимости - сокращает системный кеш или выгружает в своп несколько страниц у этого или другого приложения, исходя из статистики работы спамятью). За динамикой этого процесса ты можешь понаблюдать в task managere - в настройке разреши показывать колоночку Virtual Memory size и посравнивай в динамике Memory usage (физическая память) и VM size.
hvlad писал(а):Тебе совершенно точно сказали, в чём дело.pticelov писал(а):Вероятно, какое-то магическое число общего размера памяти на процесс или переполнение какого-то сетчика размера памяти у самой птицы
Хочешь фантазировать - твоё право
Нет, к сожалению, фантазирует тут кто-то другой. Я даже не поленился в MSDN глянуть - лимит на выделение памяти в 2Г на процесс - это фича Windows 32-битной. В порядке исключения можно разрешить процессу использовать 3Г, но для этого надо специальный флаг установить в заголовке exe-файла (у fbserver'а он стоит), и ключ /3GB добавить в boot.ini. А вот его-то у меня и не было.
Еще приложение может использовать Address Windowing Extensions, чтобы работать более чем с 2Г (и более чем с 4Г), но этой фичей fbserver не пользуется (проверено поиском в списке импортируемых функций у fbserver.exe).
Ок. Покури gds__thread_start и, например, CCH_init, VIO_initpticelov писал(а):"Сам придумал ?" (C) hvladhvlad писал(а):Это ты у билли спроси.pticelov писал(а):2 hvlad:
Какое исчерпание памяти?
can not start thread выдаётся только если ОС не смогла создать поток.
Не надо за билли ничего придумывать - в этом состоянии треды прекрасно создаются, что элементарно проверяется запуском еще кучи программ. И объем свободной памяти (и физической, и виртуальной) прекрасно видно в taskmanager и taskinfo.
А насчёт VirtualLock ты прав, нет его у нас почему-то... Буду посмотреть в эту сторону
Покурил - не нашел ничего по обсуждаемому вопросу о том, почему может быть такая диагностика.
Про выделение памяти - нашел. Если не хватает, пытается выделить меньше. Но - это вроая версия птицы. А первая?
Есть возможность првавить? Тогда - не делай это ни в коем случае!hvlad писал(а):А насчёт VirtualLock ты прав, нет его у нас почему-то... Буду посмотреть в эту сторону
Самый глупый поступок, который может сделать разработчик под винду - вызвать VirtualLock, если он не понимает, зачем это ему. Обычно это приводит к снижению производительности, вместо ожидаемого повышения
Я показал тебе почти все места в коде с этим сообщением. Все они абсолютно одинаковы.pticelov писал(а):Покурил - не нашел ничего по обсуждаемому вопросу о том, почему может быть такая диагностика.
Так шта - вопросы таки к Билли
Не отличаетсяpticelov писал(а):Про выделение памяти - нашел. Если не хватает, пытается выделить меньше. Но - это вроая версия птицы. А первая?
Ещё чего - править Я же сказал - посмотрюpticelov писал(а):Есть возможность првавить? Тогда - не делай это ни в коем случае!hvlad писал(а):А насчёт VirtualLock ты прав, нет его у нас почему-то... Буду посмотреть в эту сторону
С НГ !