Регистрация

Разбиваем БД на области

Готовим статьи для FAQ
Администратор
Аватара пользователя
Сообщения: 1880
Зарегистрирован: 25 мар 2005, 17:05
Откуда: Progress Technologies

Разбиваем БД на области

Сообщение Arelav » 26 дек 2005, 19:49

Недавно разбивал БД на области. Решил, что быть может кому-то план по которому я это делал будет интересен. А кто-то может внесет какие-либо коррективы, дабы улучшить данный процесс.


Процедура смены структуры базы данных Progress
(разбиваем БД на области)

    План:

    1. Анализ существующей БД и создание нового структурного файла
     Количество и размеры томов областей
    2. Dump данных
    3. Dump метаданных
    4. Backup существующей БД
    5. Удаление существующей БД
    6. Создание новой БД
     Создание новой структуры
     Копирование БД с эталона
     Загрузка метаданных
    7. Load данных
    8. Переиндексация БД
    9. Анализ созданной БД

1. Анализ существующей БД и создание нового структурного файла

Анализ базы данных заключается в формировании отчета по состоянию таблиц и индексов БД. Данный отчет формируется по средствам утилиты Progress – dbanalys. Синтаксис утилиты выглядит так:
    proutil <DBNAME> -C dbanalys > <файл для выгрузки отчета>
Из отчета необходимо выделить таблицы, размер которых приближен или уже превысил 1Gb. Эти таблицы будут выделены в отдельную область данных.
Пример:
    Таблица Записей Разм. Мин. Макс. Сред. Всего Фактор Фактор
    PUB.table1 18406680 1.4G 56 131 82 18406760 1.0 2.8
    PUB.table4 40294556 7.2G 78 13227 191 40296284 1.0 2.0
    PUB.table5 7491323 5.2G 190 1509 747 7529434 1.0 3.6
    PUB.table10 11540526 952.0M 50 256 86 11540661 1.0 2.4
Из этого фрагмента видно, что мы имеем три таблицы (table1, table4, table5) намного превысившие размер в 1Gb, и одну таблицу, приближающуюся к этому пределу. Следовательно, намечается четыре потенциальные области данных.
Для каждой области необходимо определить RPB, для этого можно использовать файл &laquo;blk-calc.xls&raquo;. На основании результатов работы алгоритмов этого файла мы получаем следующую картину:
    Область RPB
    Table1 Area 128
    Table4 Area 64
    Table5 Area 128
    Table10 Area 128
Оставшиеся таблицы выделяем в отдельную общую область.
RPB этой области можно также определить с помощью файла &laquo;blk-calc.xls&raquo;. При этом мы используем данные не каждой таблицы, а их общие суммы. В итоге получаем значение RPB общей области равное 128.
Для области индексов значение RPB определим по умолчанию равным 1. RPB для индексных блоков имеет скорее символическое значение. В области с RPB 1 индексные блоки будут на 1-2% компактнее, так что это значение выбрано большей степенью для сигнализации – в этой области хранятся только индексы!
( http://forum.infobit.ru/viewtopic.php?t=17 )

Количество и размеры томов областей.

Размер статического тома любой области принимается равным 1Gb. Количество томов в области прямо зависит от объема загружаемых в нее данных. Например, таблица Table4 имеет размер 7,2 Gb. Зная максимальный размер тома, мы получаем 7 статических томов плюс 1 динамический, итого 8 томов. В случае, если размер таблицы приближается к 1 Gb, как в таблице Table10, добавляется не один а два тома – 1 статический и 1 динамический. Это связано с тем, чтобы заранее исключить необходимость добавление тома в ближайшем будущем.

Таким образом, мы получаем следующий структурный файл:
    #
    B <db>.b1
    #
    d "Schema Area":6,64 <db>.d1
    #
    d "Table1 Area":7,128 <db>_7.d1 f 1048576
    d "Table1 Area":7,128 <db>_7.d2

    #
    d "Table4 Area":8,64 <db>_8.d1 f 1048576
    d "Table4 Area":8,64 <db>_8.d2 f 1048576
    d "Table4 Area":8,64 <db>_8.d3 f 1048576
    d "Table4 Area":8,64 <db>_8.d4 f 1048576
    d "Table4 Area":8,64 <db>_8.d5 f 1048576
    d "Table4 Area":8,64 <db>_8.d6 f 1048576
    d "Table4 Area":8,64 <db>_8.d7 f 1048576
    d "Table4 Area":8,64 <db>_8.d8
    #
    d "Table5 Area":9,128 <db>_9.d1 f 1048576
    d "Table5 Area":9,128 <db>_9.d2 f 1048576
    d "Table5 Area":9,128 <db>_9.d3 f 1048576
    d "Table5 Area":9,128 <db>_9.d4 f 1048576
    d "Table5 Area":9,128 <db>_9.d5 f 1048576
    d "Table5 Area":9,128 <db>_9.d6
    #
    d "All Area":10,128 <db>_10.d1 f 1048576
    d "All Area":10,128 <db>_10.d2 f 1048576
    d "All Area":10,128 <db>_10.d3 f 1048576
    d "All Area":10,128 <db>_10.d4 f 1048576
    d "All Area":10,128 <db>_10.d5 f 1048576
    d "All Area":10,128 <db>_10.d6 f 1048576
    d "All Area":10,128 <db>_10.d7
    #
    d "Idx Area":11,256 <db>_11.d1 f 1048576
    d "Idx Area":11,256 <db>_11.d2
    #
    d "Table10 Area":12,128 <db>_12.d1 f 1048576
    d "Table10 Area":12,128 <db>_12.d2
    #
    a <db>.a1
    #
    a <db>.a2
    #
    a <db>.a3
    #
    a <db>.a4
    #
    a <db>.a5
    #
    a <db>.a6
    #
    a <db>.a7
    #
    a <db>.a8
    #
    a <db>.a9
    #
    a <db>.a10



2. Dump данных

При выгрузке данных мы будем использовать двоичный dump. Общая процедура выгрузки разделяется на два этапа:
 Формирование скрипта выгрузки
 Запуск скрипта выгрузки

Формирование скрипта выгрузки.

Этот скрипт формируется следующей программой:
    def var dbase as char init "<полное имя БД>".
    def var dmpdir as char init "<каталог выгрузки данных>".

    output to value("<имя скрипта>").
    for each _file where _file-num > 0 no-lock.
    output to value("<имя скрипта dump>") append.
    put unformatted "_proutil " + dbase + " -C dump " + _file-name + " " + dmpdir skip.
    output close.
    output to value("<имя скрипта load>") append.
    put unformatted "_proutil " + dbase + " -C load " + dmpdir + _file-name + ".bd" skip.
    output close.
    end.
Эта программа сформирует скрипт для dump`а примерно следующего содержания:
    _proutil <db> -C dump <table1> /home/dump/
    _proutil <db> -C dump <table2> /home/dump/
    _proutil <db> -C dump <table3> /home/dump/
А также параллельно скрипт для load`а:
    _proutil <db> -C load /home/dump/<table>.bd
    _proutil <db> -C load /home/dump/<table>.bd
    _proutil <db> -C load /home/dump/<table>.bd
Внимание: скрипт загрузки формируется по принципу одна таблица – одна запись в скрипте. Это верно для маленьких таблиц, не превышающих размер 2 Gb. Если таблица превышает размер в 2 Gb, то нужно самостоятельно добавить строки, что гарантирует полную загрузку таблицы, например, так:
    _proutil <db> -C load /home/dump/<table>.bd
    _proutil <db> -C load /home/dump/<table>.bd2
    _proutil <db> -C load /home/dump/<table>.bd3
    _proutil <db> -C load /home/dump/<table>.bdN
Связано это с тем, что progress не поддерживает файлы более 2Gb. Поэтому перед выгрузкой необходимо в Unix установить значение ulimit равное 1000000. Это позволит скрипту выгрузки (dump) переключаться на формирование следующего файла с записями, по достижении предела установленного в ulimit. После завершения выгрузки, нужно посмотреть какие таблицы выгружены в более чем один файл и добавить соответствующие строки в скрипт загрузки.

(http://forum.infobit.ru/viewtopic.php?t ... c&start=15 (from George))

Примечание: Выгрузку данных лучше всего делать на остановленной базе.



3. Dump метаданных

После формирования скриптов выгрузки и загрузки, необходимо сформировать df-файл всех таблиц БД, через Dump Data and Definitions редактора Progress. А также выгрузить данные по пользователям – таблица _user и значения сиквенсов – таблица _seqvals.

4. Backup существующей БД

Обязательно выполнить полную резервную копию базы, на случай восстановления БД, если в процессе разбиения на области, произойдут какие-либо ошибки.



5. Удаление существующей БД

После резервного копирования можно удалять базу данных, это выполняется утилитой prodel
    Prodel <OldDBname>

Предварительно сервер БД должен быть остановлен.


6. Создание новой БД

Поместите новый структурный файл в каталог, где будет находиться новая база данных, и запустите команду prostrct create:
    Prostrct create <newdbname> <имя структурного файла> -blocksize 8192

В указанном каталоге будет создана новая структура БД. Примечание: данная структура еще не является рабочей БД, чтобы она стала пригодна для использования необходимо скопировать системные данные с эталонной базы.

Копирование БД с эталона, происходит следующей командой:
    Procopy /usr/dlc/empty <newdbname>


Загрузка метаданных

После копирования, база данных готова к работе. Теперь необходимо загрузить файл описаний таблиц (df), файл с данными пользователей и файл со значениями сиквенсов.

Внимание:
В связи с изменением структуры БД необходимо внести изменения в df-файл, заменив названия областей у таблиц и индексов, которые будут выделены. Предварительно сохраните копию df-файла.

Также, можно перенести необходимые таблицы в нужные области, уже после загрузки df-файла.

Перенести таблицу из одной области в другую можно следующей командой:
    proutil <db name> -C tablemove <table name> <area name>

Перенести индексы из одной области в другую можно так:
    proutil <db name> -C indexmove <index name> <area name>

Также, сейчас можно прогрузить df-файлы, содержащие новые индексы. Внимание: большое количество индексов, может привести к тому, что в момент переиндексации окажется недостаточным количество томов в области с индексами. Поэтому, предусмотрительно добавить в эту область как минимум еще два тома.


7. Load данных

Примечание: загрузка данных будет происходить быстрее, если база данных будет запущена в многопользовательском режиме.

Загрузка данных будет происходить по средствам скрипта загрузки. Можно разделить скрипт на несколько более меньших файлов с различным содержанием загружаемых таблиц. Это позволит уменьшить время загрузки.
Внимание: не желательно при параллельной загрузке использовать одновременно и индексацию данных. Во всяком случае, у меня это привело к чрезмерному росту bi-файла и к останову БД. Быть может, этот процесс можно как-то контролировать, но я пока об этом не знаю. Также не стоит делать одновременную индексацию, если загружаются данные таблиц, дамп-файлы которых разделены (db, db2,bd3 и т.д.)

8. Переиндексация БД

После завершения загрузки данных, таблицы в базе являются не индексированными, в результате чего, ни одна запись не доступна. Для этого необходимо сделать полную переиндексацию. Конечно же, можно было сформировать скрипт загрузки так чтобы записи сразу индексировались, но это не приемлемо когда загружаемая таблица разбита на несколько бинарных файлов. Можно также исключить подобные таблицы из общей загрузки, а потом отдельно их проиндексировать. Но мы будет считать, что общая переиндексации наиболее выгодна для нас. Возможно, в будущем это может измениться. А пока, команда для полной переиндексации следующая:
    proutil <db> -C idxbuild -TM 32 -TB 31 -SS <db>.srt

Подробнее о команде:

Параметры –TM и –TB увеличивают скорость сортировки за счет использования большего дискового пространства
Параметр –SS указывает на файл структуры каталогов сортировки. Он должен содержать полные пути к каждому каталогу, который будет задействован в процессе сортировки. В нашем случае он имеет следующее содержание:
    512000 <path>/srt/srt1/
    512000 <path>/srt/srt2/
    512000 <path>/srt/srt3/
    512000 <path>/srt/srt4/
    512000 <path>/srt/srt5/
    512000 <path>/srt/srt6/
    512000 <path>/srt/srt7/
    512000 <path>/srt/srt8/
    512000 <path>/srt/srt9/
    512000 <path>/srt/srt10/
    512000 <path>/srt/srt11/
    512000 <path>/srt/srt12/
    512000 <path>/srt/srt13/
    512000 <path>/srt/srt14/
    512000 <path>/srt/srt15/
    512000 <path>/srt/srt16/
    512000 <path>/srt/srt17/
    512000 <path>/srt/srt18/
    512000 <path>/srt/srt19/
    0 <path>/srt/srt20/


Последняя строка указывает на то, что заполнение этого каталога должно происходить пока есть свободное место на диске, в то время как использование места в предыдущих строках строго ограничено 500 Mb. Также, если есть возможность, можно распределить srt-каталоги между различными дисковыми массивами.


9. Анализ созданной БД

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

Если ошибок не обнаружено, то разделение базы данных на области было успешно завершено.



Заключение

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

:wink:

Старожил
Аватара пользователя
Сообщения: 1016
Зарегистрирован: 04 авг 2005, 16:19
Откуда: Pennsylvania, USA

re:Разбиваем БД на области

Сообщение dmitri » 28 дек 2005, 00:10

Очень хорошая статья и здорово написано. Одна небольшая поправка.

Валерий писал(а):7. Load данных
Примечание: загрузка данных будет происходить быстрее, если база данных будет запущена в многопользовательском режиме.

загрузка данных будет происходить значительно быстрее, если база данных будет запущена в no-integrity mode ( -i ). Обычно загрузка с no-integrity быстрее не на какие то % а во много много раз.

_proutil <db> -C load /home/dump/<table>.bd -TB 31 -TM 32 -i -G 0

И ещё мелочь.

Валерий писал(а):_proutil <db> -C dump <table1> /home/dump/
_proutil <db> -C dump <table2> /home/dump/
_proutil <db> -C dump <table3> /home/dump/


Последнее время вместо выше упомянутого метода, я просто состаблаю список таблиц file.list и использую следуюший unix скрипт.
    load_em()
    {
    for tab in $(<$tablist)
    do
    echo $tab
    $DLC/bin/proutil <db> -C load /home/dump/${tab}.bd -TB 31 -TM 32 -i -G 0 -t
    done
    }

    tablist="file.list"
    load_em

Где file.list это просто список таблиц созданний тем же for each _file where _file-num > 0 ...
customer
order
salesrep


Данний метод удобнее тем что нагляднее и проще редактировать файл file.list. Аналогичный скрипт dump_em

    dump_em()
    {
    for tab in $(<$tablist)
    do
    echo $tab
    $DLC/bin/proutil <db> -C dump $tab /home/dump -RO -B 4000 -G 0
    done
    }
    tablist="file.list"
    dump_em

Старожил
Аватара пользователя
Сообщения: 2871
Зарегистрирован: 12 май 2004, 17:03
Откуда: Питер

Re: Разбиваем БД на области

Сообщение George » 08 янв 2006, 16:45

Валерий писал(а):Недавно разбивал БД на области.

Возможно стоило открыть три разных темы:
1. Анализ базы для разбиения ее на области;
2. Перезагрузка данных в новую базу;
3. Переиндексация базы.

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

Анализ базы данных заключается в формировании отчета по состоянию таблиц и индексов БД.

На мой взгляд этого недостаточно.

Начну с утверждение - областей должно быть много. В первую очередь преимущества от расселения объектов базы по отдельным секциям почувствует администратор базы при выполнении штатных процедур. Большинство таких процедур можно выполнять на уровне области. Больше областей => меньше размер каждой области => быстрее закончится "атомарная" операция => сокращаются требования к временному окну, втечении которого база должна находиться в offline. Но разбиение базы также может улучшить производительность при работе с базой конечных пользователей. Это трудно доказать исходя из абстрактных предпосылок, но практика подверждает утверждение.

Но в количестве областей не стоит доходить до экстремизма. Их число должно быть ограниченным. Администратор обязан отслеживать свободное место для каждой из областей. Каноническое :wink: утверждение Даннилы Бригадира - в базе должно быть 24 области - чтобы их список умещался на одном экране символьного клиента. В моем вольном переводе :lol: с бригадирского языка это звучало бы примерно так - базу стоит разбить на десяток или несколько десятков областей.

Чем более мощная машина (количество процессоров, количество физических дисков) - тем больше стоит делать областей.

"Базодробильный" процесс можно строить на следующих принципах:

1. Люкс для "монстров" - под большие таблицы выделяем отдельные области. Обычно под "большими таблицами" понимают таблицы, чей объем превышает гигабайт или в которых более миллиона записей. Но такое опредение, по-моему, неполиткорректно. Все таблицы были когда-то маленькими. Сформулируем принцип так: большая таблица - это таблица, чей объем состовляет существенный процент (скажем 20%) объема базы или области.

Понятно, что выделить в базе "монстров" можно на основе dbanalys'а.

2. Подбираем пары по "характеру" - делим все таблицы на три группы: статичные (a.k.a справочники), динамичные и архивные.

Статичные таблицы характеризуются к тем, что они почти никогда (или очень мало) модифицируются. Основная операция с ними - чтение.

Для динамичные таблиц соотношение операций чтения и модификации (включая создание и удаление записей) сопоставимо между собой.

Архивные таблицы отличаются тем, что данные в них в основном только добавляются. П своей сути архивные таблицы часто также оказываются "большими" таблицами, которые мы уже расселили.

Такие характеристики таблиц из dbanalys'а не извлечешь. Нужно некоторое время понаблюдать за работой приложения, собирая в конце дня статистику из системных таблиц _TableStat и _IndexStat. Для этого чтобы такая статистика была полной база должна быть запущена с достаточно большими значениями параметров -tablerangesize/-indexerangesize (1000 и 4000 будет достаточно практически для любого приложения).

Если в приложении есть стадии обработки, когда в базе единовременно создается большое количество записей в разных таблицах, то эти таблицы стоит разести по разным областям, чтобы при создании записей процессы, их создающие, не конкурировали между собой за головной блок в RM- или Free-цепочках. Такие цепочки в каждой области свои.

3. Дальнейшее "измельчение" областей. Если два предыдущие подхода породили слишком мало областей, то для дальнейшего дробления базы можно разбить на группы с примерно равным средним размером записей - чтобы для них было бы оптимальным одно и тоже значение RPB. Либо разбиваем просто в алфавитном порядке или исползуем любой другой волюнтаристский принцип - лишь довести количество областей до желаемого числа.

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

Для каждой области нужно задать свое RPB. Для небольших областей можно задать RPB равным 256. Либо определять более точно как
RPB = DbBlockSize / MeanRecSize,
где MeanRecSize - средний размер записей по всем таблицам в данной области, но не как среднее значение средних размеров записей индивидуальных таблиц, которые приводятся в dbanalys'е. В качестве MeanRecSize в области стоит взять отношение общего размера всех записей всех таблиц в данной области к количеству этих записей.

Для больших областей настоятельно рекомендуется подбирать RPB исходя из реальных характеристик данных. Подробности в статье:
KB-P111065: FAQ - 'Best Practices' For Managing Records-Per-Block Settings

Все, что было сказано выше, относилось к таблицам. Для каждой "табличной" области рекомендуется завести симметричную ей "индексную" область, в которой бы хранились все индексы всех таблиц, расположенных в данной "табличной" области.

Для области индексов значение RPB определим по умолчанию равным 1. RPB для индексных блоков имеет скорее символическое значение. В области с RPB 1 индексные блоки будут на 1-2% компактнее, так что это значение выбрано большей степенью для сигнализации – в этой области хранятся только индексы!
( http://forum.infobit.ru/viewtopic.php?t=17 )


Согласен. :wink:

Количество и размеры томов областей.

Размер статического тома любой области принимается равным 1Gb. Количество томов в области прямо зависит от объема загружаемых в нее данных. Например, таблица Table4 имеет размер 7,2 Gb. Зная максимальный размер тома, мы получаем 7 статических томов плюс 1 динамический, итого 8 томов. В случае, если размер таблицы приближается к 1 Gb, как в таблице Table10, добавляется не один а два тома – 1 статический и 1 динамический. Это связано с тем, чтобы заранее исключить необходимость добавление тома в ближайшем будущем.


Почему размер тома ограничивать одним гигабайтом? Почему не 2 Гб? А если Progress и файловая система поддерживают работу с файлами большого размера, то может стоит дать тому возможность расти больше 2 Гб? На производительность размер тома мало влияет. Более того чем меньше фалов тем, вообще говоря, лучше для производительности.

Делайте тома такого размера, как вам удобно, например при копировании файлов.

Рекомендуемое чтение:
KB-P32184: Best database extent size
KB-P92875: Is there any performance impact when using database extent sizes more than 2GB?

Не стоит читать:
KB-19611: Extent size optimization under Unix
KB-16645: What is the optimum or recommended extent size for my OS?
Эти статьи устарели много лет назад.
Последний раз редактировалось George 09 янв 2006, 02:35, всего редактировалось 1 раз.

Старожил
Аватара пользователя
Сообщения: 2871
Зарегистрирован: 12 май 2004, 17:03
Откуда: Питер

Re: re:Разбиваем БД на области

Сообщение George » 08 янв 2006, 17:58

dmitri писал(а):Аналогичный скрипт dump_em
    dump_em()
    {
    for tab in $(<$tablist)
    do
    echo $tab
    $DLC/bin/proutil <db> -C dump $tab /home/dump -RO -B 4000 -G 0
    done
    }
    tablist="file.list"
    dump_em

Мелкая придирка - почему бы не передавать список как параметр?
    dump_em()
    {
    tablist=$1
    ...}
    dump_em "file.list"
А теперь серьезней :D :
$DLC/bin/proutil <db> -C dump $tab /home/dump -RO -B 4000 -G 0

1. Я бы запустил ВСЕ процессы одновременно. Обычно рекомендуют 2-4 процесса на процессор. Да полно те! Мелкие таблицы сдампируются почти сразу. Останутся только несколько крупных "игроков". Если процессор и/или диски будут загружены на 100% - система работает с максимальной загрузкой.

2. Значение параметра -B, по-моему, слишком велико. Большой кэш не дает выигрыша при последовательном чтении записей. При "хорошем" индексе (т.е. задающем порядок чтения, соответсвующий физическому расположению записей на диске) нет повторного обращения к одним и тем же данным. При "плохом" индексе кэширование будет иметь заметный эффект только, если объем кэша сопоставим с объемом всей таблицы. Большое значение -B - это задержка при старте процесса. Эту задержку легко измерить:
time pro empty8 -B 4000 -rr
Сессия стартует, а поскольку параметр -rr требует задания значения для параметра -p, то сессия тут же с руганью завершается.
Абсолютная велична задержки невелика, то это время будет тратиться при каждом запуске даже если таблица пуста.

3. В V10 параметр -RO, по-видимому, утратил свое свойство ускорителя (10-20%). Жаль.

4. Параметр -G 0 здесь совсем не нужен. Это параметр работы с bi файла. Read-only сессия не выполняет crash recovery и тем более не модифицирует базу, т.е. с bi файлом она не работает.

К тому, что написал Валерий о процедуре дампирования я бы добавил запуск dbanаlys'а непосредствено пред дампом. Во-первых будет возможность проверить, что во время "переправы" ни одна запись не утонула. :D Во-вторых время работы dbanаlys'а может служить оценкой скорости работы отчетов. Будет с чем сравнить после перезагрузки. Время старта и завершения dbanаlys'а приводится в его логе. Если база уже разбита на области, то работу dbanаlys'а можно ускорить, запустив его параллельно для каждой области. Это недокументированная возможность (просто забыли продокументировать). Синтаксис:
proutil <db> -C dbanalys "<Area Name>"

Загрузка.

загрузка данных будет происходить значительно быстрее, если база данных будет запущена в no-integrity mode ( -i ). Обычно загрузка с no-integrity быстрее не на какие то % а во много много раз.

_proutil <db> -C load /home/dump/<table>.bd -TB 31 -TM 32 -i -G 0

Согласен с важности no-integrity моды. Но при этом базу все равно стоит запускать в многопользовательском режиме (и еще при этом запустить фоновые процессы - APW - несколько - и BIW). Тогда параметр -i (и -G 0) при запуске proutil -C load будут проигнорированы.

Списки таблиц нужны по областям. Загрузку данных в разные области можно запускать параллельно:
    load_em area1 &
    load_em area2 &
    ..


После загрузки записей (до перестройки индексов) снова запускаем dbanalys и проверяем, что в строке Итого число записей осталось тем же, что и перед выгрузкой.

Старожил
Аватара пользователя
Сообщения: 2871
Зарегистрирован: 12 май 2004, 17:03
Откуда: Питер

Re: Разбиваем БД на области

Сообщение George » 08 янв 2006, 20:31

Валерий писал(а):8. Переиндексация БД

Начиная с V9.1D07, при переиндексации для наивысшей производительности стоит использовать следующие параметры:
    proutil <db> -C idxbuild all -B 256 -TM 32 -TB 31 -SG 64 -SS <sort-file>
Параметры –TM и –TB увеличивают скорость сортировки за счет использования большего дискового пространства

Параметры –TM и –TB действительно очень существенно увеличивают скорость сортировки, но не за счет дискового пространства. При перестройке индексов для временных файлов требуется 80-120% от объема наибольшей области. Параметр –TB как-то влияет объем временных файлов, но нелинейно и теория, стоящая за этим "явлением" мне не известна.

Весь объем временных файлов можно разместить либо в одной файловой системе (задавается параметром -T) либо раскидать по разным файловым системам с помощью файла структуры каталогов сортировки (параметр -SS).

Progress создает несколько временных файлов, число которых зависит от значения параметра -SG.

Начиная с V9.1D09, временные файлы могут достигать размера больше 2 Гб, если файловая система поддерживает работу с большими файлами. Включать поддержку больших файлов для базы при этом необязательно.
Исключения:
1. SCO и Unixware, где Progress традиционно не поддерживает работу с большими файлами.
2. Linux V9.D09. На Linux'е работа с большими файлами появилась в V9.1E
3. AIX. Причина - баг.

Если временные файлы не могут быть больше 2 Гб, а есть большие таблицы или области, то надо использовать многотомные временные файлы (-SS).
В нашем случае он имеет следующее содержание:
    512000 <path>/srt/srt1/
    ...

Я бы установил ограничение в 2000000 Кб (это меньше, чем 2 Гб). Больше максимальный размер файлов, меньше файлов потребуется создать. Количество временных файлов, открываемых утилитой idxbuild, в худшем случае может достигать -SG * <количество каталогов, указанных в .srt>. Плюс все экстенты базы данных. Плюс еще несколько файлов. Параметры ядра Unix'а должны обеспечить возможность открыть такое количество файлов.

Поскольку сама утилита использует незначительный объем оперативной памяти, то перед запуском idxbuild можно создать memfs (файловая система, размещенная в памяти) и разместить здесь один том временных файлов. В одном из экспериментов это ускорило работу в 1.5 раза. Чем крупнее база и чем больше памяти можно отдать под memfs, тем заметнее будет эффект. По окончании работы idxbuil'а эту файловую систему надо, конечно, удалить.

Кстати этот трюк можно использовать и при загрузки данных, временно разместив на memfs bi файл базы данных.
    0 <path>/srt/srt20/
Последняя строка указывает на то, что заполнение этого каталога должно происходить пока есть свободное место на диске, в то время как использование места в предыдущих строках строго ограничено 500 Mb.

И если idxbuild все же использовал последний каталог, то надо расширить список каталогов с фиксированным размером.

В нашем случае он имеет следующее содержание:
    512000 <path>/srt/srt1/
    512000 <path>/srt/srt2/
    ...

Можно использовать один и тот же каталог. Файлы будут создаваться с уникальными именами так что проблемы не возникнет. Лишь бы в файловой системе было достаточно свободного места.

Конечная черта в пути обязательна.

Старожил
Аватара пользователя
Сообщения: 1016
Зарегистрирован: 04 авг 2005, 16:19
Откуда: Pennsylvania, USA

re:Разбиваем БД на области

Сообщение dmitri » 09 янв 2006, 22:56

George писал(а):"Базодробильный" процесс можно строить на следующих принципах:

К тем областям которые George выше перечислил я ещё добавляю область для временных таблиц. это таблицы записи в которых хранятся только несколько часов или дней. Например у нас есть таблица интерфейсов к Oracle, которая нас интересует только если интерфейс не работает ( for debug иначе говоря ). В ней создается и удаляется многие тысячи записей в день. Что бы такая таблица не сделала "щвейцарский сыр" и области базы данных я помешаю такие таблицы в отдельную область.

Администратор
Аватара пользователя
Сообщения: 1880
Зарегистрирован: 25 мар 2005, 17:05
Откуда: Progress Technologies

Сообщение Arelav » 16 авг 2006, 18:20

Я наконец-то вернулся к этой теме. :)
Подготовил, как я считаю, окончательный вариант этой статьи.
Народ, как считаете, стоит выкладывать ее заново в эту тему или сразу разместить здесь :roll:
http://progress.infobit.ru/modules.php?op=modload&name=FAQ&file=index ?

Van, как это сделать? 8)

Старожил
Аватара пользователя
Сообщения: 2871
Зарегистрирован: 12 май 2004, 17:03
Откуда: Питер

Сообщение George » 16 авг 2006, 21:42

Валерий писал(а):Народ, как считаете, стоит выкладывать ее заново в эту тему

Насколько я понимаю здесь - рабочий стол для шлифовки.
или сразу разместить здесь :roll:
http://progress.infobit.ru/modules.php?op=modload&name=FAQ&file=index ?

А тут - отливка в бронзе.

Валерий, выложи куда-нибуть - не томи. :D
Если выложишь "не туда", то модераторы подчистят. :D

Администратор
Аватара пользователя
Сообщения: 1880
Зарегистрирован: 25 мар 2005, 17:05
Откуда: Progress Technologies

Сообщение Arelav » 16 авг 2006, 22:01

George, там ни чего особенного то и нету, просто добавил Ваши же комментраии к первому
варианту :roll:




    Процедура смены структуры базы данных Progress
    (разбиваем БД на области)



    План:

    1. Анализ существующей БД и создание нового структурного файла
     Количество и размеры томов областей
    2. Dump данных
    3. Dump метаданных
    4. Backup существующей БД
    5. Удаление существующей БД
    6. Создание новой БД
     Создание новой структуры
     Копирование БД с эталона
     Загрузка метаданных
    7. Load данных
    8. Переиндексация БД
    9. Анализ созданной БД

    1. Анализ существующей БД и создание нового структурного файла

    Анализ базы данных заключается в формировании отчета по состоянию таблиц и индексов БД. Данный отчет формируется по средствам утилиты Progress – dbanalys. Синтаксис утилиты выглядит так:

    proutil <DBNAME> -C dbanalys > <файл>

    Из отчета необходимо выделить таблицы, размер которых приближен или уже превысил 1Gb. Эти таблицы будут выделены в отдельную область данных.
    Пример:
    Таблица Записей Разм. Мин. Макс. Сред. Всего Фактор Фактор
    PUB.table1 18406680 1.4G 56 131 82 18406760 1.0 2.8
    PUB.table4 40294556 7.2G 78 13227 191 40296284 1.0 2.0
    PUB.table5 7491323 5.2G 190 1509 747 7529434 1.0 3.6
    PUB.table10 11540526 952.0M 50 256 86 11540661 1.0 2.4

    Из этого фрагмента видно, что мы имеем три таблицы (table1, table4, table5) намного превысившие размер в 1Gb, и одну таблицу, приближающуюся к этому пределу. Следовательно, намечается четыре потенциальные области данных.
    Для каждой области необходимо определить RPB, для этого можно использовать файл &laquo;blk-calc.xls&raquo;. На основании результатов работы алгоритмов этого файла мы получаем следующую картину:
    Область RPB
    Table1 Area 128
    Table4 Area 64
    Table5 Area 128
    Table10 Area 128

    Оставшиеся таблицы выделяем в отдельную общую область.
    RPB этой области можно также определить с помощью файла &laquo;blk-calc.xls&raquo;. При этом мы используем данные не каждой таблицы, а их общие суммы. В итоге получаем значение RPB общей области равное 128.

    На первый взгляд, кажется, что для анализа, выше описанной процедуры достаточно. На практике же это не совсем так.
    Начну с утверждения – областей должно быть много. В первую очередь, преимущество от расселения объектов базы по отдельным секциям почувствует администратор базы при выполнении штатных процедур. Большинство таких процедур можно выполнять на уровне области. Больше областей => меньше размер каждой области => быстрее закончится “атомарная” операция => сокращаются требования к временному окну, в течении которого база должна находится в offline. Разбиение базы также может улучшить производительность при работе с ней конечных пользователей. Это трудно доказать исходя из абстрактных предпосылок, но практика подтверждает утверждение.
    Конечно же, в количестве областей не стоит доходить до экстремизма. Их число должно быть ограниченным. Администратор обязан отслеживать свободное место для каждой из областей. Каноническое утверждение Дена Форемана (Dan Foreman) – в базе должно быть 24 области – чтобы список умещался на одном экране символьного клиента. В вольном переводе это звучало бы примерно так – базу стоит разбить на десяток или несколько десятков областей.
    Чем более мощная машина (количество процессоров, количество физических дисков) – тем больше стоит делать областей.
    “Базодробильный” процесс можно строить на следующих принципах:
    1. Люкс для “монстров” – под большие таблицы выделяем отдельные области (этот принцип мы использовали в примере описанном выше). Обычно под “большими таблицами” понимают таблицы, чей объем превышает гигабайт или в которых более миллиона записей. Но такое определение, не совсем корректно. Все таблицы были когда-то маленькими. Сформулируем принцип так: большая таблица – это таблица, чей объем составляет существенный процент (скажем 20%) объема базы или области. Понятно, что выделиь в базе “монстров” можно на основе dbanalys`а.
    2. Подбираем пары по “характеру” – делим все таблицы на три группы: статичные (справочники), динамичные и архивные. Статичные таблицы характеризуются тем, что они почти никогда (или очень мало) модифицируются. Основная операция с ними – чтение. Для динамичных таблиц соотношение операций чтения и модификации (включая создание и удаление записей) сопоставимо между собой. Архивные таблицы отличаются тем, что данные в них в основном только добавляются. По своей сути, архивные таблицы часто также оказываются “большими” таблицами, которые мы уже расселили. Такие характеристики таблиц из dbanalys`а не извлечешь. Нужно некоторое время понаблюдать за работой приложения, собирая в конце дня статистику из системных таблиц _TableStat и _IndexStat. Для того чтобы такая статистика была полной, база должна быть запущена с достаточно большим значением параметров –tablerangesize/-indexerangesize (1000 и 4000 будет достаточно практически для любого приложения). Если в приложении есть стадии обработки, когда в базе единовременно создается большое количество записей в разных таблицах, то эти таблицы стоит разнести по разным областям, чтобы при создании записей процессы, их создающие, не конкурировали между собой за головной блок RM- или Free-цепочках. Такие цепочки в каждой области свои.
    3. Дальнейшее “измельчение” областей. Если два предыдущих подхода породили слишком мало областей, то для дальнейшего дробления базы, можно разбить таблицы на группы с примерно равным средним размером записей – чтобы для них было бы оптимальным одно и тоже значение RPB. Либо разбиваем просто в алфавитном порядке или используем любой другой волюнтаристский принцип – лишь довести количество областей до желаемого числа.
    4. “Рюшечки”. При работе может использоваться только часть функционала приложения – какие-то таблицы могут быть пустыми. Причем количество таких таблиц может быть весьма большим. Возможно стоит их всех выделить в отдельную “ясельную” область. Можно также завести “карантинную” область для новых таблиц (т.е. тех, что только что появились в приложении), про которые непонятно как они будут себя вести. Присмотревшись к ним в течении некоторого времени, можно будет их переселить в более подходящее место. Возможно, стоит иметь под рукой “запасную” область на случай, если понадобится новая область, а базу останавливать нельзя. Впрочем, для этого можно использовать “ясельную” или “карантинную” области.

    Для каждой области нужно задать своё RPB. Для небольших, можно принять равным 256. Либо определять более точно как RPB = DbBlockSize/MeanRecSize,
    где MeanRecSize – средний размер записей по всем таблицам в данной области, но не как среднее значение средних размеров записей индивидуальных таблиц, которые приводятся в dbanalys`е. В качестве MeanRecSize в области стоит взять отношение общего размера всех записей таблиц в данной области к количеству этих записей.
    Для больших областей настоятельно рекомендуется подбирать RPB исходя из реальных характеристик данных. Подробности в статье:
    KB-P111065: FAQ - 'Best Practices' For Managing Records-Per-Block Settings

    Все, что было сказано выше, относилось к таблицам. Для каждой "табличной" области рекомендуется завести симметричную ей "индексную" область, в которой бы хранились все индексы всех таблиц, расположенных в данной "табличной" области.
    Для области индексов значение RPB определим по умолчанию равным 1. RPB для индексных блоков имеет скорее символическое значение. В области с RPB 1 индексные блоки будут на 1-2% компактнее, так что это значение выбрано большей степенью для сигнализации – в этой области хранятся только индексы! (http://forum.infobit.ru/viewtopic.php?t=17 )

    Количество и размеры томов областей.

    Размер статического тома любой области принимается равным 1Gb. Количество томов в области прямо зависит от объема загружаемых в нее данных. Например, таблица Table4 имеет размер 7,2 Gb. Зная максимальный размер тома, мы получаем 7 статических томов плюс 1 динамический, итого 8 томов. В случае, если размер таблицы приближается к 1 Gb, как в таблице Table10, добавляется не один, а два тома – 1 статический и 1 динамический. Это связано с тем, чтобы заранее исключить необходимость добавление тома в ближайшем будущем.
    Может возникнуть вопрос. Почему размер тома ограничивать одним гигабайтом? Почему не 2 Гб? А если Progress и файловая система поддерживают работу с файлами большого размера, то может, стоит дать им возможность расти больше 2 Гб? На производительность размер тома мало влияет. Более того, чем меньше файлов тем, вообще говоря, лучше для производительности. Делайте тома такого размера, как вам удобно, например, при копировании файлов.
    Рекомендуемое чтение:
    KB-P32184: Best database extent size
    KB-P92875: Is there any performance impact when using database extent sizes more than 2GB?
    Не стоит читать:
    KB-19611: Extent size optimization under Unix
    KB-16645: What is the optimum or recommended extent size for my OS?
    Эти статьи устарели много лет назад.

    Вернемся к нашему примеру.
    Таким образом, мы получаем следующий структурный файл:
    #
    B <db>.b1
    #
    d "Schema Area":6,64 <db>.d1
    #
    d "Table1 Area":7,128 <db>_7.d1 f 1048576
    d "Table1 Area":7,128 <db>_7.d2

    #
    d "Table4 Area":8,64 <db>_8.d1 f 1048576
    d "Table4 Area":8,64 <db>_8.d2 f 1048576
    d "Table4 Area":8,64 <db>_8.d3 f 1048576
    d "Table4 Area":8,64 <db>_8.d4 f 1048576
    d "Table4 Area":8,64 <db>_8.d5 f 1048576
    d "Table4 Area":8,64 <db>_8.d6 f 1048576
    d "Table4 Area":8,64 <db>_8.d7 f 1048576
    d "Table4 Area":8,64 <db>_8.d8
    #
    d "Table5 Area":9,128 <db>_9.d1 f 1048576
    d "Table5 Area":9,128 <db>_9.d2 f 1048576
    d "Table5 Area":9,128 <db>_9.d3 f 1048576
    d "Table5 Area":9,128 <db>_9.d4 f 1048576
    d "Table5 Area":9,128 <db>_9.d5 f 1048576
    d "Table5 Area":9,128 <db>_9.d6
    #
    d "All Area":10,128 <db>_10.d1 f 1048576
    d "All Area":10,128 <db>_10.d2 f 1048576
    d "All Area":10,128 <db>_10.d3 f 1048576
    d "All Area":10,128 <db>_10.d4 f 1048576
    d "All Area":10,128 <db>_10.d5 f 1048576
    d "All Area":10,128 <db>_10.d6 f 1048576
    d "All Area":10,128 <db>_10.d7
    #
    d "Idx Area":11,256 <db>_11.d1 f 1048576
    d "Idx Area":11,256 <db>_11.d2
    #
    d "Table10 Area":12,128 <db>_12.d1 f 1048576
    d "Table10 Area":12,128 <db>_12.d2
    #
    a <db>.a1
    #
    a <db>.a2
    #
    a <db>.a3
    #
    a <db>.a4
    #
    a <db>.a5
    #
    a <db>.a6
    #
    a <db>.a7
    #
    a <db>.a8
    #
    a <db>.a9
    #
    a <db>.a10

    2. Dump данных

    При выгрузке данных мы будем использовать двоичный dump. Общая процедура выгрузки разделяется на два этапа:
     Формирование скрипта выгрузки
     Запуск скрипта выгрузки

    Формирование скрипта выгрузки.

    Этот скрипт формируется следующей программой:

    def var dbase as char init "<полное>".
    def var dmpdir as char init "<каталог>".

    output to value("<имя>").
    for each _file where _file-num > 0 no-lock.
    output to value("<имя>") append.
    put unformatted "_proutil " + dbase + " -C dump " + _file-name + " " + dmpdir skip.
    output close.
    output to value("<имя>") append.
    put unformatted "_proutil " + dbase + " -C load " + dmpdir + _file-name + ".bd" skip.
    output close.
    end.

    Эта программа сформирует скрипт для dump`а примерно следующего содержания:

    _proutil <db> -C dump <table1> /home/dump/
    _proutil <db> -C dump <table2> /home/dump/
    _proutil <db> -C dump <table3> /home/dump/

    А также параллельно скрипт для load`а:
    _proutil <db> -C load /home/dump/<table>.bd
    _proutil <db> -C load /home/dump/<table>.bd
    _proutil <db> -C load /home/dump/<table>.bd

    Внимание: скрипт загрузки формируется по принципу одна таблица – одна запись в скрипте. Это верно для маленьких таблиц, не превышающих размер 2 Gb. Если таблица превышает размер в 2 Gb, то нужно самостоятельно добавить строки, что гарантирует полную загрузку таблицы, например, так:

    _proutil <db> -C load /home/dump/<table>.bd
    _proutil <db> -C load /home/dump/<table>.bd2
    _proutil <db> -C load /home/dump/<table>.bd3
    _proutil <db> -C load /home/dump/<table>.bdN

    Связано это с тем, что progress не поддерживает файлы более 2Gb. Поэтому перед выгрузкой необходимо в Unix установить значение ulimit равное 1000000. Это позволит скрипту выгрузки (dump) переключаться на формирование следующего файла с записями, по достижении предела установленного в ulimit. После завершения выгрузки, нужно посмотреть какие таблицы выгружены в более чем один файл и добавить соответствующие строки в скрипт загрузки. (http://forum.infobit.ru/viewtopic.php?t ... c&start=15 (from George))
    Для ускорения выгрузки можно запустить несколько процессов дампирования одновременно. Обычно рекомендуют 2-4 процесса на процессор. Мелкие таблицы сдампируются почти сразу. Останутся только несколько крупных "игроков". Если процессор и/или диски будут загружены на 100% - система работает с максимальной загрузкой.

    К процедуре дампирования я бы добавил запуск dbanаlys'а непосредствено пред дампом. Во-первых, будет возможность проверить, что во время "переправы" ни одна запись не утонула. Во-вторых, время работы dbanаlys'а может служить оценкой скорости работы отчетов. Будет с чем сравнить после перезагрузки. Время старта и завершения dbanаlys'а приводится в его логе. Если база уже разбита на области, то работу dbanаlys'а можно ускорить, запустив его параллельно для каждой области. Это недокументированная возможность (просто забыли продокументировать). Синтаксис:
    proutil <db> -C dbanalys "<Area>"

    3. Dump метаданных

    После формирования скриптов выгрузки и загрузки, необходимо сформировать df-файл всех таблиц БД, через Dump Data and Definitions редактора Progress. А также выгрузить данные по пользователям – таблица _user и значения сиквенсов – таблица _seqvals.


    4. Backup существующей БД

    Обязательно выполнить полную резервную копию базы, на случай восстановления БД, если в процессе разбиения на области, произойдут какие-либо ошибки.


    5. Удаление существующей БД

    После резервного копирования можно удалять базу данных, это выполняется утилитой prodel

    Prodel <OldDBname>

    Предварительно сервер БД должен быть остановлен.


    6. Создание новой БД

    Поместите новый структурный файл в каталог, где будет находиться новая база данных, и запустите команду prostrct create:

    Prostrct create <newdbname> <имя> -blocksize 8192

    В указанном каталоге будет создана новая структура БД. Примечание: данная структура еще не является рабочей БД, чтобы она стала пригодна для использования необходимо скопировать системные данные с эталонной базы.

    Копирование БД с эталона, происходит следующей командой:

    Procopy /usr/dlc/empty <newdbname>


    Загрузка метаданных

    После копирования, база данных готова к работе. Теперь необходимо загрузить файл описаний таблиц (df), файл с данными пользователей и файл со значениями сиквенсов.

    Внимание:
    В связи с изменением структуры БД необходимо внести изменения в df-файл, заменив названия областей у таблиц и индексов, которые будут выделены. Предварительно сохраните копию df-файла.

    Также, можно перенести необходимые таблицы в нужные области, уже после загрузки df-файла.

    Перенести таблицу из одной области в другую можно следующей командой:
    proutil <db> -C tablemove <table> <area>

    Перенести индексы из одной области в другую можно так:
    proutil <db> -C indexmove <index> <area>

    Также, сейчас можно прогрузить df-файлы, содержащие новые индексы. Внимание: большое количество индексов, может привести к тому, что в момент переиндексации окажется недостаточным количество томов в области с индексами. Поэтому, предусмотрительно добавить в эту область как минимум еще два тома.


    7. Load данных

    Примечание: загрузка данных будет происходить быстрее, если база данных будет запущена в многопользовательском режиме в режиме no-integrity (-i).

    Загрузка данных будет происходить по средствам скрипта загрузки. Можно разделить скрипт на несколько файлов с различным содержанием загружаемых таблиц, или разделить их по областям. После чего загружать параллельно - это позволит уменьшить время загрузки.
    Внимание: не желательно при параллельной загрузке использовать одновременно и индексацию данных. Во всяком случае, у меня это привело к чрезмерному росту bi-файла и к останову БД. Быть может, этот процесс можно как-то контролировать, но я пока об этом не знаю. Также не стоит делать одновременную индексацию, если загружаются данные таблиц, &laquo;дамп-файлы&raquo; которых разделены (db, db2,bd3 и т.д.)
    После загрузки записей (до перестройки индексов) снова запускаем dbanalys и проверяем, что в строке Итого число записей осталось тем же, что и перед выгрузкой.

    8. Переиндексация БД

    После завершения загрузки данных, таблицы в базе являются не индексированными, в результате чего, ни одна запись не доступна. Для этого необходимо сделать полную переиндексацию. Конечно же, можно было сформировать скрипт загрузки так чтобы записи сразу индексировались, но это не приемлемо когда загружаемая таблица разбита на несколько бинарных файлов, да и может привести к черезмерному росту bi - файла. Можно также исключить подобные таблицы из общей загрузки, а потом отдельно их проиндексировать. Но мы будет считать, что общая переиндексации наиболее выгодна для нас. Возможно, в будущем это может измениться. А пока, команда для полной переиндексации следующая:

    proutil <db> -C idxbuild all -B 256 -TM 32 -TB 31 -SG 64 -SS <sort>

    Подробнее о команде:

    Параметры –TM и –TB увеличивают скорость сортировки. При перестройке индексов для временных файлов требуется 80-120% от объема наибольшей области. Параметр –TB как-то влияет объем временных файлов, но нелинейно и теория, стоящая за этим "явлением" мне не известна.
    Весь объем временных файлов можно разместить либо в одной файловой системе (задается параметром -T), либо раскидать по разным файловым системам с помощью файла структуры каталогов сортировки (параметр -SS).
    Progress создает несколько временных файлов, число которых зависит от значения параметра -SG.
    Начиная с V9.1D09, временные файлы могут достигать размера больше 2 Гб, если файловая система поддерживает работу с большими файлами. Включать поддержку больших файлов для базы при этом необязательно.
    Исключения:
    1. SCO и Unixware, где Progress традиционно не поддерживает работу с большими файлами.
    2. Linux V9.D09. На Linux'е работа с большими файлами появилась в V9.1E
    3. AIX. Причина - баг.

    Если временные файлы не могут быть больше 2 Гб, а есть большие таблицы или области, то надо использовать многотомные временные файлы (-SS).
    Файла структуры каталогов сортировки должен содержать полные пути к каждому каталогу, который будет задействован в процессе сортировки. В нашем случае, он имеет следующее содержание:
    2000000 <path>/srt/srt1/
    2000000 <path>/srt/srt2/
    2000000 <path>/srt/srt3/
    2000000 <path>/srt/srt4/
    2000000 <path>/srt/srt5/
    2000000 <path>/srt/srt6/
    2000000 <path>/srt/srt7/
    2000000 <path>/srt/srt8/
    2000000 <path>/srt/srt9/
    2000000 <path>/srt/srt10/
    2000000 <path>/srt/srt11/
    2000000 <path>/srt/srt12/
    2000000 <path>/srt/srt13/
    0 <path>/srt/srt14/

    Последняя строка указывает на то, что заполнение этого каталога должно происходить пока есть свободное место на диске, в то время как использование места в предыдущих строках строго ограничено 2000000.
    И если idxbuild все же использовал последний каталог, то надо расширить список каталогов с фиксированным размером.
    Ограничение в 2000000 Кб (это меньше, чем 2 Гб). Больше максимальный размер файлов, меньше файлов потребуется создать. Количество временных файлов, открываемых утилитой idxbuild, в худшем случае может достигать -SG * <количество>. Плюс все экстенты базы данных. Плюс еще несколько файлов. Параметры ядра Unix'а должны обеспечить возможность открыть такое количество файлов.
    Поскольку сама утилита использует незначительный объем оперативной памяти, то перед запуском idxbuild можно создать memfs (файловая система, размещенная в памяти) и разместить здесь один том временных файлов. Это может ускорить работу примерно в 1.5 раза. Чем крупнее база и чем больше памяти можно отдать под memfs, тем заметнее будет эффект. По окончании работы idxbuild'а эту файловую систему надо, конечно, удалить.
    Кстати этот трюк можно использовать и при загрузки данных, временно разместив на memfs bi файл базы данных.
    Также, если есть возможность, можно распределить srt-каталоги между различными дисковыми массивами.
    Конечная черта в пути каталога сортировки обязательна.


    9. Анализ созданной БД

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

    Если ошибок не обнаружено, то разделение базы данных на области было успешно завершено.


    Заключение

    Материал подготовлен на основе дискуссии в форуме http://forum.infobit.ru/, и успешно опробован на реальных базах данных.


Вообщем-то документ готовился для внутреннего использования. Типа, на случай если я куданить денусь... :roll:
Последний раз редактировалось Arelav 17 авг 2006, 12:58, всего редактировалось 1 раз.

Администратор
Аватара пользователя
Сообщения: 1880
Зарегистрирован: 25 мар 2005, 17:05
Откуда: Progress Technologies

Сообщение Arelav » 16 авг 2006, 22:07

Да к стати, на счет dbanalys сразу после загрузки.
Если мне память не изменяет, то если взять его до переиндексации, то он ни чего не покажет - записи ведь не индексированны, а значит и не доступны, что dbanalys будет считать? Хотя, может я чего и путаю, давно было... надо повторить . 8)
Ладно, на сегодня всё. Вторые сутки без сна, все сливается... обсуждение завтра :wink:

Старожил
Аватара пользователя
Сообщения: 2871
Зарегистрирован: 12 май 2004, 17:03
Откуда: Питер

Сообщение George » 16 авг 2006, 22:25

Валерий писал(а):Да к стати, на счет dbanalys сразу после загрузки.
Если мне память не изменяет, то если взять его до переиндексации, то он ни чего не покажет - записи ведь не индексированны, а значит и не доступны, что dbanalys будет считать?

Путаешь. Dbanalys индексы не использует, а сканирует базу блок за блоком. В этом и состоит его прелесть - мы считаем фактическое количество записей, а не количество проиндексированных записей, как в случае 4GL.

Администратор
Аватара пользователя
Сообщения: 1880
Зарегистрирован: 25 мар 2005, 17:05
Откуда: Progress Technologies

Сообщение Arelav » 17 авг 2006, 12:59

Ок, :)
Код: Выделить всё
Тогда вношу дополнение в пукт загрузки данных
После загрузки записей (до перестройки индексов) снова запускаем dbanalys и проверяем, что в строке Итого число записей осталось тем же, что и перед выгрузкой.


Изменения внесу прямо в сообщение со статьей, чтобы не плодить эти самы сообщения :wink:

Старожил
Аватара пользователя
Сообщения: 2871
Зарегистрирован: 12 май 2004, 17:03
Откуда: Питер

Сообщение George » 18 авг 2006, 17:12

Валерий писал(а): Формирование скрипта выгрузки
 Запуск скрипта выгрузки

Мы с dmitri, похоже, тебя не убедили, что лучше разделить сам скрипт (логику выполнения команд) и входные данные (список таблиц). :)

Для дампирования список таблиц можно "выковырять" из dbanalys'а. Тогда, например, можно было бы и не пытаться дампировать пустые таблицыи видимая картина по бинарным файлам соответствовала бы реальному состоянию дел - все эти файлы действительно нужно грузить. Это скорее улучшение "для глаз" поскольку пропуск пустых таблиц никак бы не повлиял на производительность (если, конечно, кто-нибуть не попытался бы грузить их в однопользовательской моде).

Кстати в скрипт стоит добавил проверку сообщений бинарного дампа, отфильтровав все "обычные" сообщения, а все "необычные" сообщения сбрасывать в специальный лог. В частности разработчики Progress'а почему-то решили, что будет вполне нормально, если бинарный дамп может использовать неактивный индекс, т.е. такой индекс, который не соответствует реальному набору записей. Что при этом сдампируется (и сдампируется ли что-нибуть вообще) не известно. Утилита в такой ситуации выдаст предупреждение (да и то в последних версиях). Такое предупреждение можно и не заметить среди тысяч строк нормальных сообщений.

Внимание: скрипт загрузки формируется по принципу одна таблица – одна запись в скрипте. Это верно для маленьких таблиц, не превышающих размер 2 Gb. Если таблица превышает размер в 2 Gb, то нужно самостоятельно добавить строки, что гарантирует полную загрузку таблицы, например, так:

_proutil <db> -C load /home/dump/<table>.bd
_proutil <db> -C load /home/dump/<table>.bd2
_proutil <db> -C load /home/dump/<table>.bd3
_proutil <db> -C load /home/dump/<table>.bdN

Связано это с тем, что progress не поддерживает файлы более 2Gb.

Если это FAQ, то надо говорить об общем случае. Progress не поддерживает работу с файлами более 2Gb только на SCO или в более ранних чем 9.1E версиях на Linux'е.

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

Для ускорения выгрузки можно запустить несколько процессов дампирования одновременно. Обычно рекомендуют 2-4 процесса на процессор.

Это все-таки устаревшая рекомендация. Сейчас говорят о дампе "всего и сразу".
Highly Parallel Dump and Load.
http://www.greenfieldtech.com/downloads ... h06db8.ppt
Кстати на этом же сайте Tom Bascom выложил программы, реализующую другую стратегию перезагрузки базы - 4GL сессии перетаскивают данные из одной базы в другую без "приземления" их на диск в дамп-файл:
http://www.greenfieldtech.com/downloads/files/dl.tar

3. Dump метаданных

После формирования скриптов выгрузки и загрузки, необходимо сформировать df-файл всех таблиц БД, через Dump Data and Definitions редактора Progress. А также выгрузить данные по пользователям – таблица _user и значения сиквенсов – таблица _seqvals.

Таблицы _seqvals не существует да и значения сиквенций не хранятся ни в какой таблице.

6. Создание новой БД

Поместите новый структурный файл в каталог, где будет находиться новая база данных, и запустите команду prostrct create:

Prostrct create <newdbname> <имя> -blocksize 8192

Утилиту prostrct create стоит забыть за ненадобностью.

В связи с изменением структуры БД необходимо внести изменения в df-файл, заменив названия областей у таблиц и индексов, которые будут выделены.

Такое редактирование df-файла реального приложения было бы героическим подвигом. :D
Здесь на форуме обсуждался скрипт, который работает на основе списка для переноса таблиц:
Table "Old Area" "New Area"

Вообщем-то всё здесь сказанное - это и не замечания даже, а так - мелкие придирки. :D

Старожил
Аватара пользователя
Сообщения: 1016
Зарегистрирован: 04 авг 2005, 16:19
Откуда: Pennsylvania, USA

Сообщение dmitri » 18 авг 2006, 21:20

Кстати на этом же сайте Tom Bascom выложил программы, реализующую другую стратегию перезагрузки базы - 4GL сессии перетаскивают данные из одной базы в другую без "приземления" их на диск в дамп-файл:
http://www.greenfieldtech.com/downloads/files/dl.tar

Советую тем кто будет в Афинах сходить на "Тома".
Он делает дамп и лоад во время своего выступления, постоянно переходя от лекции к просмотру статуса дамп и лоада.
За время лекции (1 час) перегрузил по моему 6GB.

Старожил
Аватара пользователя
Сообщения: 2871
Зарегистрирован: 12 май 2004, 17:03
Откуда: Питер

Сообщение George » 18 авг 2006, 22:16

dmitri писал(а):Советую тем кто будет в Афинах сходить на "Тома".
Он делает дамп и лоад во время своего выступления

А можно прийти со своими данными? :roll:

След.

Вернуться в СТАТЬИ

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1