Модель памяти DB2 UDB

Как DB2 использует память

Изучив эту статью, вы узнаете, как DB2 использует память. Также в статье будут подробно рассмотрены ограничения систем с 32-разрядной архитектурой памяти и представлены примеры распространенных проблем, касающихся распределения памяти для каждой из следующих поддерживаемых платформ: AIX, Solaris, HP-UX, Linux и Windows.

Сильвия Ки, тестировщик WebSphere Application Server, IBM  

Сильвия Ки (Sylvia F. Qi) в настоящее время работает в IBM Toronto Lab тестировщиком функций WebSphere Application Server. До этого она на протяжении шести лет работала инженером поддержки DB2 UDB второго уровня. Сильвия является сертифицированным специалистом IBM в области администрирования DB2 UDB и разработки приложений. Она имеет степень бакалавра в области вычислительной техники университета Макгилла. Сильвия пишет много статей для ресурса IBM developerWorks. Она является соавтором недавно вышедшей книги под названием Understanding DB2 - Learning Visually with Examples (ISBN 0131859161).



Майкл Дэнг, администратор базы данных DB2, IBM  

Майкл Дэнг (Michael D. T. Dang) в настоящее время работает в IBM Global Services старшим администратором баз данных DB2 UDB. Он работает в IBM на протяжении восьми лет. Майкл является сертифицированным специалистом IBM в области администрирования DB2 UDB и разработки приложений, и пишет много статей для ресурса IBM developerWorks.



06.07.2009

Получите используемые в этой статье программы

Если вы являетесь подписчиком developerWorks, то у вас уже имеется однопользовательская лицензия на использование DB2 Universal Database, а также других программных продуктов DB2®, Lotus®, Rational®, Tivoli® и WebSphere® (в том числе среды WebSphere Studio IDE, основанную на Eclipse) для разработки, тестирования, оценки и демонстрации ваших приложений. Если вы не являетесь подписчиком developerWorks, вы можете подписаться сегодня.


Введение

Понимание того, как DB2 использует память, позволит вам избежать переполнений памяти и поможет настроить ее на максимальную производительность.

Изучив эту статью, вы узнаете, как DB2 использует память, а также познакомитесь с концепциями разделяемой и собственной памяти. Весь изложенный материал относится как к 32-разрядным, так и к 64-разрядным системам. Хотя 64-разрядные системы и имеют ограничения, вряд ли мы столкнемся с ними в ближайшем будущем, так что в основном мы сосредоточимся на подробном рассмотрении ограничений, касающихся работы с памятью в 32-разрядных системах.

Сначала мы в общих чертах обсудим то, как DB2 использует память. После этого мы рассмотрим, чем отличается управление памятью в различных платформах (AIX, Sun, HP, Linux и Windows), и выясним, какое влияние это оказывает на DB2. В заключение будут представлены показательные примеры ситуаций и проблем, возникающих у пользователей в реальной жизни, а также способы их решения.

Материал, изложенный в этой статье, относится к DB2 версии 8.


Обзор структуры памяти DB2

Структура памяти DB2 изображена на рисунке 1; эта структура одинакова для всех платформ.

Примечание. В среде с несколькими разделами данная структура применяется к каждому разделу экземпляра.

Рисунок 1. Структура памяти DB2
Структура памяти DB2

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

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

Каждая область памяти состоит из различных пулов памяти (также называющихся хипами, или кучами). Имена пулов памяти также перечислены на рисунке 1. Например, locklist – это пул памяти, принадлежащий области разделяемой памяти базы данных, а sortheap – пул памяти, принадлежащий области собственной памяти агента.

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

Разделяемая память экземпляра

Каждый экземпляр DB2 содержит одну область разделяемой памяти экземпляра. Разделяемая память экземпляра выделяется в момент запуска менеджера базы данных (db2start) и освобождается в момент его останова (db2stop). Эта память используется для задач уровня экземпляра, таких как мониторинг, аудит и межузловое взаимодействие. Управление размерами области разделяемой памяти экземпляра и ее отдельных пулов осуществляется при помощи следующих параметров конфигурации менеджера базы данных (dbm cfg):

  • Память экземпляра (instance_memory).
  • Куча мониторинга (mon_heap_sz), использующаяся в целях мониторинга.
  • Буфер аудита (audit_buf_sz), обеспечивающий возможность использования средства db2audit.
  • Буферы быстрого взаимодействия (fcm_num_buffers), использующиеся для межузлового взаимодействия между разделами и агентами (в случаях экземпляров с несколькими разделами или экземпляров с параметром конфигурации INTRA_PARALLEL, установленным в ON.

Параметр instance_memory определяет количество памяти, зарезервированной для управления экземпляром. Значением по умолчанию является AUTOMATIC. Это означает, что DB2 будет подсчитывать количество памяти экземпляра, необходимое для текущей конфигурации, на основании размеров кучи мониторинга, буфера аудита и буферов быстрого взаимодействия (Fast Communication, FCM). Кроме того, DB2 выделяет некоторое дополнительное количество памяти под буфер переполнения. Буфер переполнения служит для того, чтобы отвечать требованиям к максимальной загрузке памяти любой кучи в области разделяемой памяти экземпляра в тех случаях, когда размер кучи превышает максимально заданный размер. В этом случае ограничения на размеры отдельных пулов являются мягкими (soft); они могут увеличиваться при максимальной загрузке памяти.

Если значением параметра instance_memory является число, то будет использоваться наибольшее из следующих: instance_memory или сумма mon_heap_sz, audit_buf_sz и fcm_num_buffers. В этом случае ограничение на размер памяти экземпляра будет являться жестким (hard), в противоположность мягкому ограничению. При достижении этого ограничения вы будете получать ошибки распределения памяти. По этой причине рекомендуется оставлять для параметра instance_memory значение AUTOMATIC.

Если значением параметра instance_memory является AUTOMATIC, вы можете вычислить его с помощью следующих команд:

  • db2 attach to имя_экземпляра
  • db2 get dbm cfg show detail

Следующий результат показывает, что 42 МБ зарезервировано под область разделяемой памяти экземпляра (всего 10313 страниц * 4096 байтов на страницу):

  • Size of instance shared memory (4KB) (INSTANCE_MEMORY) = AUTOMATIC(10313) AUTOMATIC(10313)

Параметр instance_memory только лишь устанавливает ограничение для разделяемой памяти экземпляра. Он не говорит вам о том, сколько памяти используется в текущий момент. Чтобы узнать, сколько памяти используется экземпляром, используйте утилиту DB2 db2mtrk, предназначенную для отслеживания памяти. Например:

  • db2start
  • db2mtrk -i -v

  • Memory for instance
  • FCMBP Heap is of size 17432576 bytes
  • Database Monitor Heap is of size 180224 bytes
  • Other Memory is of size 3686400 bytes
  • Total: 21299200 bytes

Из этого примера видно, что, хотя под область разделяемой памяти экземпляра зарезервировано 42 МБ, на момент запуска утилиты db2mtrk используется только около 21 МБ.

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

Разделяемая память базы данных

Каждая база данных DB2 содержит одну область разделяемой памяти базы данных. Разделяемая память базы данных выделяется в момент активации базы данных или в момент первого подключения к ней и освобождается в момент деактивации (если БД была активирована) или по завершении последнего подключения. Эта память используется для задач уровня базы данных, таких как резервное копирование и восстановление, блокировка и выполнение SQL-запросов.

На рисунке 2 изображены пулы, принадлежащие области разделяемой памяти базы данных. В скобках указаны параметры конфигурации, при помощи которых осуществляется управление размерами пулов памяти.

Рисунок 2. Разделяемая память базы данных DB2
Разделяемая память базы данных DB2

Полностью закрашенные зеленые квадраты означают, что в момент запуска базы данных пулы памяти используются полностью. В противном случае используется только часть памяти. Например, когда база данных запускается впервые, только около 16 КБ памяти распределено в сервисной куче независимо от того, какое значение имеет параметр util_heap_sz. Когда запущена одна из утилит базы данных, таких как резервное копирование, восстановление, экспорт, импорт и загрузка, весь объем памяти, определяемый параметром util_heap_sz, используется полностью.

Главные буферные пулы

Область одного или нескольких буферных пулов базы данных обычно является самым большим компонентом разделяемой памяти базы данных. В буферных пулах DB2 происходит управление всеми обычными и индексными данными. База данных должна иметь хотя бы один буферный пул и может иметь несколько буферных пулов в зависимости от характеристик рабочей нагрузки, размера страниц базы данных и так далее. Например, табличное пространство с размером страницы, равным 8 КБ, может использовать только буферный пул с размером страницы в 8 КБ.

Размер буферного пула может быть "расширен" с помощью опции EXTENDED STORAGE в предложении CREATE BUFFERPOOL. Расширенное хранилище (ESTORE) выступает в качестве вторичного кэша для страниц, которые удаляются из буферного пула, таким образом, уменьшая необходимость в выполнении операций ввода/вывода. Размер хранилища ESTORE задается с помощью параметров конфигурации базы данных num_estore_segs и estore_seg_sz. Если хранилище ESTORE присутствует, некоторое количество памяти отнимается из разделяемой памяти базы данных для управления этим хранилищем; таким образом, остается меньше доступной памяти для других пулов.

Теперь у вас может возникнуть вопрос – зачем вообще использовать ESTORE? Почему нельзя вместо этого выделить буферный пул большего размера? Ответ на этот вопрос связан с ограничением адресуемой (в отличие от физической) памяти, о которой мы поговорим позже.

Скрытые буферные пулы

При запуске базы данных выделяются четыре небольших буферных пула с размерами страниц 4 КБ, 8 КБ, 16 КБ и 32 КБ. Эти пулы являются "скрытыми", поскольку вы не увидите их в системных каталогах (запрос SELECT * FROM SYSCAT.BUFFERPOOLS не покажет их).

Когда задан слишком большой размер главных буферных пулов, есть вероятность, что они не поместятся в пространстве адресуемой памяти (о ней мы поговорим позже). Это означает, что DB2 не сможет запустить базу данных, поскольку база данных должна содержать, по меньшей мере, один буферный пул. Если база данных не запущена, вы не сможете подключиться к ней и изменить размеры буферного пула. По этой причине DB2 заранее выделяет четыре буферных пула небольшого размера. Если главные буферные пулы не смогут запуститься, DB2 запустит базу данных с небольшими буферными пулами (в этой ситуации пользователь получит предупреждение SQLSTATE 01626). При возникновении такой ситуации вы должны подключиться к базе данных и уменьшить размер главных буферных пулов.

Пороговый размер кучи сортировки (sheapthres, sheapthres_shr)

Сортировка требуется в том случае, когда для упорядочивания возвращенных запросом строк не подходит ни один индекс, или когда оптимизатор решает, что на выполнение сортировки потратится меньше ресурсов, чем на сканирование индекса. В DB2 существует два вида сортировки – приватная и разделяемая. Приватная сортировка выполняется в собственной памяти агента (ее мы будем обсуждать в следующем разделе); разделяемая сортировка выполняется в разделяемой памяти базы данных.

Параметр конфигурации базы данных sheapthres задает мягкое ограничение в пределах экземпляра на общее количество памяти, которая может быть использована для приватной сортировки в любой момент времени. Когда общий объем памяти, использованный во время приватной сортировки, достигает порогового значения, память, выделяемая для дополнительных входящих запросов на приватную сортировку, будет значительно сокращена. В журнале db2diag.log вы увидите следующее сообщение:

"Not enough memory available for a (private) sort heap of size размер кучи сортировки. Trying smaller size..."

Если вы включите внутрисекционный параллелизм или концентратор, DB2 может выполнить разделяемую сортировку, если определит, что этот метод может оказаться более эффективным, чем приватная сортировка. В случае выполнения разделяемой сортировки куча сортировки распределяется в разделяемой памяти базы данных. Максимальное количество памяти, используемой для разделяемой сортировки, задается с помощью параметра базы данных sheapthres_shr. Это жесткое ограничение на общее количество памяти, используемой разделяемыми сортировками в любой заданный момент времени, которое распространяется на всю базу данных. Когда количество используемой памяти достигает предела, приложение, запрашивающее сортировку, получает ошибку SQL0955 (rc2). Все дальнейшие запросы памяти для разделяемой сортировки не будут выполняться до тех пор, пока общее количество памяти, используемой для разделяемой сортировки, не станет меньше предельного значения, определенного параметром sheapthres_shr.

Требуемый размер области разделяемой памяти базы данных можно приблизительно определить по следующей формуле: разделяемая память базы данных = (главные буферные пулы + 4 скрытых буферных пула + куча базы данных + сервисная куча + пул locklist + кэш пакетов + кэш каталога) + (количество страниц estore * 100 Байтов) + приблизительно 10% дополнительного объема.

Для баз данных с включенным внутрисекционным параллелизмом или концентратором разделяемая память сортировки должна являться частью разделяемой памяти базы данных, таким образом, формула для подсчета памяти принимает следующий вид: разделяемая память базы данных = (главные буферные пулы + 4 скрытых буферных пула + куча базы данных + сервисная куча + пул locklist + кэш пакетов + кэш каталога + sheapthres_shr) + (количество страниц estore * 100 байтов) + приблизительно 10% дополнительного объема.

Совет. Чтобы узнать, сколько памяти выделено под главные буферные пулы, выполните следующую команду:
SELECT * FROM SYSCAT.BUFFERPOOLS

Хотя размеры большинства пулов памяти предопределены с помощью параметров конфигурации, размеры следующих двух пулов памяти по умолчанию являются динамическими:

  • Кэш пакетов: pckcachesz = maxappls * 8
  • Кэш каталога: catalogcache_sz = maxappls * 4
  • Максимальное число активных приложений: maxappls = AUTOMATIC

Установка параметра maxappls в AUTOMATIC позволяет обеспечить подключение любого числа приложений. DB2 автоматически выделит ресурсы, необходимые для поддержки новых запускаемых приложений. Таким образом, размеры кэша пакетов и кэша каталога могут варьироваться в зависимости от значения параметра maxappls.

Помимо вышеуказанных параметров существует еще один параметр, также влияющий на количество разделяемой памяти базы данных. Это параметр database_memory. Его значением по умолчанию является AUTOMATIC. Это означает, что DB2 будет подсчитывать количество памяти базы данных, необходимое для текущей конфигурации, основываясь на размерах различных пулов памяти, перечисленных выше. Кроме того, DB2 также выделит некоторое дополнительное количество памяти для буфера переполнения. Буфер переполнения обеспечивает выполнение требований к максимальной загрузке памяти для любой кучи в области разделяемой памяти базы данных в тех случаях, когда размер кучи превышает ее предварительно заданный размер.

Если значением параметра database_memory является число, то будет использоваться наибольшее из следующих: database_memory или сумма отдельных пулов памяти.

Если значением параметра database_memory является AUTOMATIC, вы можете вычислить его с помощью следующих команд:

  • db2 connect to имя_БД user ID_пользователя using пароль
  • db2 get db cfg for имя_БД show detail

Для отображения количества памяти, используемого в текущий момент, используйте утилиту db2mtrk: db2mtrk -i -d -v (в ОС Windows, необходимо указать параметр –i; в ОС UNIX параметр -i не является обязательным).

	Memory for database: SAMPLE
   	Backup/Restore/Util Heap is of size 16384 bytes
   	Package Cache is of size 81920 bytes
   	Catalog Cache Heap is of size 65536 bytes
   	Buffer Pool Heap is of size 4341760 bytes
   	Buffer Pool Heap is of size 655360 bytes
   	Buffer Pool Heap is of size 393216 bytes
   	Buffer Pool Heap is of size 262144 bytes
   	Buffer Pool Heap is of size 196608 bytes
   	Lock Manager Heap is of size 491520 bytes
   	Database Heap is of size 3637248 bytes
   	Other Memory is of size 16384 bytes
   	Application Control Heap is of size 327680 bytes
    	Application Group Shared Heap is of size 57344000 bytes
   	Total: 67829760 bytes

Разделяемая память группы приложений

Эта область разделяемой памяти применима только к следующим конфигурациям (для других конфигураций этой области памяти не существует):

  • Базы данных с несколькими разделами
  • Базы данных с одним разделом, для которых включена внутрипараллельная обработка
  • Базы данных, для которых включен концентратор подключений

Примечание. Концентратор подключений включен тогда, когда параметр max_connections больше параметра max_coordagents. Эти параметры находятся в конфигурации менеджера базы данных (для отображения конфигурации менеджера базы данных используйте команду GET DBM CFG).

В вышеперечисленных средах для выполнения задач приложений обычно требуется больше одного агента. Желательно, чтобы эти агенты могли взаимодействовать (передавать и получать данные) между собой. Чтобы достичь этого, мы помещаем эти агенты в группу, называющуюся группой приложений. Все агенты DB2, принадлежащие одной и той же группе приложений, взаимодействуют друг с другом, используя разделяемую память группы приложений.

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

Нескольким приложениям можно назначить одну и ту же группу приложений. Число приложений, которые могут уместиться в группе приложений, подсчитывается по следующей формуле: appgroup_mem_sz / app_ctl_heap_sz

Внутри группы приложений каждое приложений имеет свою собственную кучу управления приложением. Кроме того, часть разделяемой памяти группы приложений зарезервирована под разделяемую кучу группы приложений. Это показано на следующем рисунке.

Рисунок 3. Разделяемая память группы приложений DB2
Разделяемая память группы приложений DB2

Пример 1
Рассмотрим следующую конфигурацию базы данных:

  • Максимальный размер области памяти группы приложений (4 КБ) (APPGROUP_MEM_SZ) = 40000
  • Максимальный размер кучи управления приложением (4 КБ) (APP_CTL_HEAP_SZ) = 512
  • Процент памяти, используемой для кучи группы приложений (GROUPHEAP_RATIO) = 70

Исходя из этого, можно рассчитать следующее:

  • Область разделяемой памяти группы приложений: 40000 страниц * 4 KБ на страницу = 160 МБ
  • Размер разделяемой кучи группы приложений: 40000*70%= 28000 страниц по 4 КБ = 114 МБ
  • Число приложений, которые смогут уместиться в группе приложений: 40000/512 = 78
  • Куча управления приложением для каждого приложения: (100-70)% * 512 = 153 страниц по 4 КБ = 0.6 МБ

Обратите особое внимание на параметр app_ctrl_heap_sz. Этот параметр НЕ является размером кучи управления для каждого отдельного приложения в группе приложений, а является всего лишь значением, использующимся для подсчета количества приложений, которые могут уместиться в этой группе приложений. Реальный размер кучи управления для каждого приложения рассчитывается по формуле, представленной на рисунке 3: ((100 – group_heap_ratio)% * app_ctrl_heap_sz).

Таким образом, чем выше значение group_heap_ratio, тем больше размер разделяемой кучи группы приложений, а размер кучи управления для каждого приложения меньше.

Пример 2
Предположим, что в пиковые часы работы к базе данных, рассмотренной в примере 1, подключаются 200 приложений. Поскольку каждая группа приложений может содержать 78 приложений, нам потребуется 200/78=3 группы, чтобы в них уместились все 200 приложений. Убедитесь, что ваша система имеет достаточное количество оперативной памяти для поддержки этой конфигурации. В противном случае произойдет событие SQL10003N.

Собственная память агента

Каждый процесс агента DB2 должен получить для работы необходимое количество памяти. Эта память используется агентом для оптимизации, построения и выполнения планов доступа от имени приложения, выполнения сортировок, записи информации курсора, такой как его положение и состояние, сбора статистики и так далее. Собственная память агента выделяется для агента DB2 тогда, когда агент назначается приложению в результате запроса на подключение или нового SQL-запроса в параллельной среде.

Число агентов ограничено наименьшим из следующих значений:

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

Область собственной памяти агента состоит из следующих пулов памяти. Размеры этих пулов задаются в параметрах конфигурации базы данных, которые приведены в скобках:

  • Куча приложения (applheapsz)
  • Куча сортировки (sortheap)
  • Куча операторов (stmtheap)
  • Куча статистики (stat_heap_sz)
  • Куча запросов (query_heap_sz)
  • Куча интерпретатора Java (java_heap_sz)
  • Размер стека агента (agent_stack_sz) (только для ОС Windows)

Мы упомянули, что собственная память выделяется агенту DB2 тогда, когда агент "назначен" для выполнения определенного задания. А когда эта память освобождается? Ответ на этот вопрос зависит от значения параметра конфигурации менеджера базы данных num_poolagents. Значение этого параметра определяет максимальное число неактивных агентов, поддерживаемых в любой момент времени. Если значением этого параметра является 0, то неактивных агентов нет. Как только агент выполняет свою работу, он уничтожается, и занятая им память снова становится доступной операционной системе. Если значение отлично от нуля, то агент не уничтожается после выполнения своей работы, а вместо этого возвращается в пул неактивных агентов, максимальное количество которых задано параметром num_poolagents. Когда поступает новый запрос, неактивные агенты назначаются для его выполнения. Такая схема минимизирует издержки на создание и уничтожение агентов.

Когда агент становится неактивным, он продолжает занимать собственную память агента. Это сделано с целью улучшения производительности, поскольку, когда агент будет вызван снова, его собственная память уже будет готова. Если неактивных агентов много, и все они занимают собственную память, то существует вероятность того, что системе перестанет хватать памяти. Чтобы избежать этого, DB2 содержит регистровую переменную, ограничивающую количество памяти, которую может занимать каждый неактивный агент. Эта переменная называется DB2MEMMAXFREE и имеет значение по умолчанию, равное 8 388 608 байтам. Это означает, что каждый неактивный агент может занимать до 8 МБ его собственной памяти. Если у вас имеется 100 неактивных агентов, то они займут 800 МБ памяти, таким образом, достаточно быстро "съев" ее. В зависимости от количества установленной в системе оперативной памяти вы можете снизить или увеличить данное ограничение.

На рисунке 1 была показана структура для одного экземпляра DB2. На рисунке 4 изображены два экземпляра, одновременно запущенных в одной системе. Виртуальная память включает в себя физическую память и нерезидентную память. Области разделяемой памяти "стремятся" оставаться в оперативной памяти, поскольку доступ к ним производится более часто. Собственная память агента может быть выгружена из оперативной памяти, если агент оставался неактивным долгое время.

Рисунок 4. Два одновременно запущенных экземпляра DB2

Сравнение разделяемой и собственной памяти

К настоящему моменту мы рассмотрели разделяемую память экземпляра, разделяемую память базы данных, разделяемую память группы приложений и собственную память агента. Но какое значение имеет разделяемая и собственная память?

Для того чтобы понять различие между разделяемой и собственной памятью, давайте сначала ознакомимся с процессами агентов DB2, бегло прочитав статью DB2 process model (EN). В DB2 все запросы базы данных обслуживаются агентами или субагентами DB2. Например, когда приложение подключается к базе данных, ему назначается агент DB2. Когда приложение формирует какой-либо запрос к базе данных, например SQL-запрос, агент вступает в работу и выполняет все задачи, необходимые для завершения этого запроса, то есть, работает по запросу приложения (если база данных разбита на несколько разделов, или если для нее включен внутрисекционный параллелизм, то по запросу приложения назначаются несколько агентов; эти агенты называются субагентами).

Каждый агент или субагент рассматривается как процесс DB2 и для выполнения своей работы получает определенное количество памяти. Эта память называется собственной памятью агента – она не может использоваться любыми другими агентами. Как было упомянуто ранее, собственная память агента включает в себя несколько пулов памяти, таких как куча приложения, куча сортировки и куча операторов (обратитесь к рисунку 1).

В дополнение к своей собственной памяти, в которой агент выполняет "приватные" задачи, такие как приватные сортировки с использованием sortheap, агенту необходимы ресурсы уровня базы данных, такие как буферные пулы, пул locklist и буферы логов. Эти ресурсы расположены в разделяемой памяти базы данных (обратитесь к рисунку 1). DB2 работает так, что все ресурсы, находящиеся в разделяемой памяти базы данных, совместно используются всеми агентами или субагентами DB2, подключенными к одной и той же базе данных. Поэтому данная область памяти называется разделяемой памятью, в отличие от собственной памяти. Например, агент X, подключившийся к базе данных A, использует ресурсы, находящиеся в разделяемой памяти базы данных A. Теперь второй агент (агент Y) также подключается к базе данных A. В этом случае агент Y будет использовать разделяемую память базы данных A совместно с агентом X (конечно, оба агента имеют свою собственную память, которая не разделяется между ними).

Те же рассуждения применимы к разделяемой памяти экземпляра и к разделяемой памяти группы приложений.

На следующем рисунке показаны области памяти DB2, выделяемые при подключении агентов X и Y к базе данных A. Предположим следующее:

  • База данных A принадлежит экземпляру db2inst1
  • База данных A содержит группу приложений 1, и для этой БД включен внутрисекционный параллелизм
  • Оба агента, X и Y, входят в группу приложений 1.
Рисунок 5. Адресное пространство памяти процесса агента DB2
Адресное пространство памяти процесса агента DB2

На рисунке 5 изображены следующие области памяти, распределенные в ОЗУ:

  • Область разделяемой памяти экземпляра для экземпляра db2inst1;
  • Область разделяемой памяти базы данных для базы данных A;
  • Разделяемая память группы приложений для группы приложений 1;
  • Область собственной памяти агента для агента X;
  • Область собственной памяти агента для агента Y;
  • Зарезервированная память для таких компонентов, как ядро и библиотеки.

Агенты X и Y используют одну и ту же память экземпляра, память базы данных и память группы приложений, поскольку они принадлежат одному экземпляру, одной базе данных и одной группе приложений. Кроме того, каждый из них имеет свою отдельную собственную память агента.

Каждый процесс агента DB2 имеет свое собственное адресное пространство памяти. Адреса памяти в этом пространстве позволяют агенту получать доступ к памяти в физическом ОЗУ. Можно представить данные адреса в качестве указателей на ОЗУ, как показано на рисунке 5. Для любого процесса DB2 все четыре области памяти должны умещаться в этом адресном пространстве.

Ранее отмечалось, что для увеличения размера буферного пула используется хранилище ESTORE. Вы можете спросить: "Почему нельзя создать вместо этого буферный пул побольше?" Ответ на этот вопрос следующий: поскольку адресное пространство ограничено, буферный пул большего размера может не уместиться в нем! В таком случае вам необходимо определять буферный пул меньшего размера, который сможет уместиться в адресном пространстве. А если у вас есть запас свободной физической памяти, вы можете использовать его для настройки ESTORE.

Хорошо, как теперь мы можем узнать, насколько велико адресное пространство агента DB2? Размер адресного пространства зависит от того, какая архитектура экземпляра используется – 32- или 64-разрядная. Мы объясним это в следующем разделе.


Адресуемая память в 32-разрядной и 64-разрядной архитектурах

Если у вас имеется 64-разрядный экземпляр, это означает, что DB2 использует 64-разрядную архитектуру памяти. В этой архитектуре размер адресного пространства каждого процесса составляет 2 в 64 степени, или 18,446,744,073 ГБ, для всех платформ. Это огромное количество памяти. При размещении всех областей памяти DB2 в этом адресном пространстве не должно возникнуть никаких проблем.

С другой стороны, если у вас имеется 32-разрядный экземпляр, размер адресного пространства составляет лишь 2 в 32 степени, или 4 ГБ, для всех платформ (за исключением ОС Linux/390, адресное пространство которой на самом деле составляет 2 в 31 степени; однако, в этой статье мы не будем рассматривать DB2 под Linux/390). Таким образом, независимо от того, насколько велик размер физической памяти, разделяемая память группы приложений, ее собственная память агента плюс память для ядра и т. д. должны уместиться в адресном пространстве размером 4 ГБ.

Это ставит перед нами два очень важных вопроса:

  • Сколько памяти мы должны выделять под области памяти экземпляра, памяти базы данных и разделяемой памяти приложения, чтобы они могли уместиться в адресном пространстве размером 4 ГБ?
  • Как мы должны настраивать каждый из перечисленных на рисунке 1 параметров, чтобы наилучшим образом использовать доступную память?

Хотя ограничение в 4 ГБ на размер адресного пространства одинаково для всех платформ, ответы на поставленные вопросы будут зависеть от используемой платформы. Например, максимальный размер памяти базы данных, который вы можете выделить для базы данных DB2 в системе AIX, отличается от такового в системе Solaris. В следующих разделах рассматривается, как использование различных платформ влияет на конфигурацию памяти DB2.

Примечание. Оставшийся материал этой статьи будет посвящен только 32-разрядной архитектуре памяти. Все рассматриваемые далее вопросы не применимы к 64-разрядной архитектуре.


Конфигурация памяти DB2 в 32-разрядной системе AIX

В 32-разрядной системе AIX 4 ГБ адресного пространства разделены на 16 сегментов, размер каждого из которых составляет 256 МБ. На рисунке 6 изображено 32-разрядное адресное пространство памяти для процесса агента DB2 (исходя из предположения, что обе регистровых переменных DB2 – DB2_MMAP_READ и DB2_MMA_WRITE установлены в 0; в противном случае картина будет немного отличаться, о чем мы расскажем позже).

Рисунок 6. 32-разрядное адресное пространство памяти DB2 в системе AIX
32-разрядное адресное пространство памяти DB2 в системе AIX

Сегмент 0: зарезервирован под ядро AIX.

Сегмент 1: зарезервирован под процесс db2sysc.

Сегмент 2: зарезервирован под собственную память агента.

Сегмент 3: зарезервирован под разделяемую память экземпляра.

Сегменты с 4 по B: область разделяемой памяти базы данных начинается с сегмента 4, сегменты должны располагаться непрерывно. Теоретически, под разделяемую память базы данных могут быть использованы все 8 сегментов (2 ГБ). Тем не менее, каждая из следующих конфигураций уменьшает разделяемую память базы данных на один сегмент (256 МБ).

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

  • Если база данных распределена по нескольким разделам, или если включен внутрисекционный параллелизм или концентратор подключений, то один сегмент используется для разделяемой памяти группы приложений.
  • Менеджер быстрого взаимодействия (Fast Communication Manager, FCM), используется для взаимодействий между разделами, расположенными в пределах одного физического узла. По умолчанию это реализуется с помощью UNIX-сокетов. Если переменная DB2_FORCE_FCM_BP установлена в YES, то в разделяемой памяти выполняется FCM-взаимодействие. Это означает, что один сегмент используется менеджером быстрого взаимодействия. Хотя FCM-взаимодействие является более быстрым, разделяемая память базы данных уменьшается на один сегмент.
  • Определяемые пользователем функции и хранимые процедуры, выполняемые в отдельном адресном пространстве (fenced-функции). Если в базе данных функция или процедура выполняется в отдельном адресном пространстве, один сегмент используется для взаимодействия в режиме fenced mode.
  • Один сегмент используется для обработки взаимодействий между агентом и приложением, которое он обслуживает, если приложение является локальным. По умолчанию под этот сегмент взаимодействий отводится сегмент B адресного пространства агента. Если каждая из переменных DB2_MMAP_READ и DB2_MMAP_WRITE установлена в NO, то под сегмент взаимодействия отводится сегмент E, а сегмент B может быть использован для каких-либо других целей, возможно, для разделяемой памяти базы данных.
  • Если включено расширенное хранилище ESTORE, оно забирает еще один сегмент из разделяемой памяти базы данных. Таким образом, если вы включаете ESTORE, убедитесь, что его размер составляет, по крайней мере, 256 МБ, иначе в его использовании не будет смысла, поскольку сегмент размером 256 МБ отнимается из разделяемой памяти базы данных только для управления хранилищем ESTORE. Рекомендуется устанавливать размер сегмента ESTORE (estore_seg_sz) равным 256 МБ, а затем изменять число сегментов (num_estore_segs) в зависимости от количества доступной памяти.

Сегмент C: зарезервирован под функцию трассировки DB2.

Сегменты D и F: зарезервированы под совместно используемые библиотеки DB2.

Сегмент Е: по умолчанию этот сегмент не используется. Тем не менее, если вы установите переменные DB2_MMAP_READ=NO и DB2_MMAP_WRITE=NO, этот сегмент будет использоваться для взаимодействия между агентом DB2 и приложением, которое он обслуживает (как показано на рисунке 6). Это освобождает один сегмент разделяемой памяти базы данных.

Примечание.Чтобы максимально увеличить пространство, доступное для разделяемой памяти базы данных, используйте следующие значения регистровых переменных: DB2_FORCE_FCM_BP=NO (это значение по умолчанию), DB2_MMAP_READ=NO, DB2_MMAP_WRITE=NO.

Наиболее важные выводы, которые нужно извлечь после ознакомления с данной структурой:

  • Для системы с отключенным внутрисекционным параллелизмом, расположенной в пределах одного раздела, мы можем получить до 2 ГБ разделяемой памяти базы данных (сегменты с 4 по B), установив переменные DB2_MMAP_WRITE=NO и DB2_MMAP_WRITE=NO. В противном случае мы получим 1,75 ГБ.
  • Каждая из следующих конфигураций уменьшает размер разделяемой памяти базы данных на один сегмент (256 МБ): база данных с определяемыми пользователями функциями или хранимыми процедурами, выполняемыми в отдельном адресном пространстве; база данных с установленной переменной DB2_FORCE_FCM_BP=YES; база данных с включенным внутрисекционным параллелизмом или концентратором подключений, либо распределенная по нескольким разделам; база данных с включенным хранилищем ESTORE.

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

Примечание. Во время работы базы данных память может выделяться, освобождаться и перераспределяться между различными областями. Например, вы можете уменьшить объем пула locklist и затем увеличить объем любого заданного пула bufferpool на ту же величину.

Использование утилиты svmon для слежения за загрузкой памяти в AIX

Помимо утилиты db2mtrk tool, в AIX вы можете использовать утилиту svmon для слежения за использованием памяти процессом агента DB2 (необходимы полномочия пользователя root). Команда выглядит следующим образом: "svmon -P PID", где PID - идентификатор процесса любого из агентов DB2 (db2agent или db2agentp).

На рисунке 7 изображен пример вывода утилиты svmon для процесса с названием db2agent. База данных, связанная с этим процессом db2agent, имеет следующие характеристики:

  • Имя базы данных: TEST
  • INTRAP_PARALLEL = YES (get dbm cfg)
  • DB2_FORCE_FCM_BP = YES (db2set -all)
  • DB2_MMAP_READ=NO, DB2_MMAP_WRITE=NO (db2set -all)

Рисунок 7. Вывод утилиты svmon для процесса агента DB2 (svmon -P 11649046)
Вывод утилиты svmon для процесса агента DB2 (svmon -P 11649046)

Некоторые наблюдения из рисунка 7:

  • ID процесса – 11649046, имя процесса – db2agent (верхний левый угол). Этот агент подключен к базе данных TEST (при отображении имя базы данных было укорочено, поэтому мы видим только 'TES').

  • В столбце Esid отображены сегменты памяти, которые были выделены:
  • Сегмент 4 (зеленый) выделен под разделяемую память базы данных;
  • Сегмент 2 (оранжевый) выделен под собственную память агента;
  • Сегмент 3 (синий) выделен под разделяемую память экземпляра;
  • Сегмент B (фиолетовый) выделен под разделяемую память группы приложений, поскольку для базы данных включен внутрисекционный параллелизм;
  • Сегмент A (розовый) выделен под менеджер быстрого взаимодействия (FCM), поскольку установлена переменная DB2_FORCE_FCM_BP=YES;
  • Сегмент локального подключения был перемещен в сегмент E (красный), поскольку обе переменные DB2_MMAP_READ и DB2_MMAP_WRITE установлены в NO. В противном случае для взаимодействия агента и локального подключения использовался бы сегмент 8, поскольку оба сегмента A и B уже заняты, а сегмент 9 зарезервирован под взаимодействия в режиме fenced mode.

Эти наблюдения соответствуют тому, что было показано на рисунке 6.

Задание значения ulimit для данных и стека в 32-разрядной системе AIX

Ранее было сказано, что сегмент #2 на рисунке 6 используется под собственную память агента. На самом деле, это не совсем так.

Если быть точными, сегмент #2 зарезервирован под данные и стек. Данные содержат пользовательскую информацию (которая является собственной памятью агента). Стек содержит инструкции, которые необходимо выполнить. В пределах сегмента размером 256 МБ данные заполняются, начиная с адреса 0x20000000, по убыванию адресов. Стек заполняется, начиная с адреса 0x2FFFFFFF, по возрастанию. Важно задать их границы так, чтобы они не перекрывались друг с другом, поскольку если это произойдет, возникнет сбой экземпляра с сигналом 4 или с сигналом 11.

Рисунок 8. Сегмент данных и стека
Сегмент данных и стека

Границы данных и стека задаются через значения ulimits (/etc/security/limits). Используйте средства SMIT, чтобы задать следующие значения:
Data = 491519, Stack = 32767 (512 bytes)

Вышеуказанные значения задаются в блоках по 512 байтов, что эквивалентно 240 МБ для данных и 16 МБ для стека. При выводе значений границ с использованием команды "ulimit -a" эти значения выводятся в блоках по 1 КБ, а не по 512 байтов. Таким образом, эти значения примут следующий вид:
Data = 245760, Stack = 16384

Примечание. Файл /etc/security/limits содержит значения, выраженные в блоках по 512 байтов, а не по 1 КБ.

Распространенные проблемы распределения разделяемой памяти базы данных в 32-разрядной системе AIX

Когда инициализация разделяемой памяти базы данных не может выполниться надлежащим образом, возникают следующие ошибки:

  • Во время запуска базы данных (активация базы данных или первое подключение к ней) - SQL1478W, SQL0987C, SQL1084C
  • Во время выполнения - SQL10003N, SQL1042C

В следующих примерах показаны неправильные конфигурации, приводящие к проблемам.

Пример 1

Рассмотрим следующую конфигурацию (все страницы имеют размер 4 КБ):

  • Один раздел, концентратор отключен, INTRA_PARALLEL OFF, DB2_MMAP_READ=NO, DB2_MMAP_WRITE=NO, функций или процедур, выполняющихся в режиме fenced mode, нет
  • IBMDEFAULTBP 450,000 страниц
  • UTILHEAP 17,500 страниц
  • DBHEAP 10,000 страниц
  • LOCKLIST 1000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц

Ограничение: в этой конфигурации ограничение на размер разделяемой памяти базы данных составляет 2 ГБ, или 8 сегментов.

Расчет: используя формулу для подсчета разделяемой памяти базы данных, мы имеем:
Разделяемая память базы данных = (всего 486,000 страниц x 4 КБ на страницу) x 1.1 (учет дополнительных 10% объема) = ~2.1 ГБ = 9 сегментов

Примечание. Мы исключим из расчетов четыре скрытых буферных пула, поскольку они слишком малы, чтобы оказать существенное влияние на результат.

Проблема: полученный размер превышает ограничение в 2 ГБ. При активации базы данных или при первом подключении к ней вы получите следующее предупреждение:
SQL1478W The defined buffer pools could not be started. Instead, one small buffer pool for each page size supported by DB2 has been started. SQLSTATE=01626

В журнале db2diag.log вы обнаружите сообщение о том, что DB2 будет запущена с использованием скрытых буферных пулов. Для решения этой проблемы уменьшите размер главных буферных пулов.

Пример 2

Рассмотрим следующую конфигурацию (все страницы имеют размер 4 КБ):

  • Один раздел, INTRA_PARALLEL=ON, функций или процедур, выполняющихся в режиме fenced mode, нет
  • IBMDEFAULTBP 300,000 страниц
  • UTILHEAP 17,500 страниц
  • DBHEAP 10,000 страниц
  • SHEAPTHRES_SHR 50,000 страниц
  • LOCKLIST 1000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц

Ограничение: 1.5 ГБ (6 сегментов). Один сегмент используется под память группы приложений, поскольку переменная INTRA_PARALLEL установлена в ON. Еще один сегмент используется для локальных подключений, поскольку переменные DB2_MMAP_READ и DB2_MMAP_WRITE установлены в YES (по умолчанию).

Расчет:
Разделяемая память базы данных = (всего 386,000 страниц x 4 КБ на страницу) x 1.1 = ~1.67 ГБ = 7 сегментов

Проблема: полученный размер превышает ограничение в 1.5 ГБ. При активации базы данных или при первом подключении к ней вы получите следующее предупреждение:
SQL1042C An unexpected system error occurred. SQLSTATE=58004

Решение проблемы:

  • Установите переменные DB2_MMAP_READ и DB2_MMAP_WRITE в NO, используя db2set. Это заставит DB2 использовать сегмент E для локальных подключений, таким образом, освободив один сегмент для разделяемой памяти базы данных.

Пример 3

Рассмотрим следующую конфигурацию (все страницы имеют размер 4 КБ):

  • IBMDEFAULTBP 250,000 страниц
  • INTRA_PARALLEL=ON
  • UTILHEAP 17,500 страниц
  • DBHEAP 10,000 страниц
  • SHEAPTHRES_SHR 20,000 страниц
  • LOCKLIST 1000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц
  • Имеются пользовательская функция, выполняющаяся в режиме fenced mode

Ограничение: каждая из следующих функций использует один сегмент: включенный внутрисекционный параллелизм, локальные подключения и пользовательская функция, выполняющаяся в режиме fenced mode. Таким образом, под разделяемую память базы данных остается 5 сегментов, или 1.25 ГБ.

Расчет:
Разделяемая память базы данных = (всего 306,000 страниц x 4 КБ на страницу) x 1.1 = ~1.35 ГБ = 6 сегментов

Проблема: запрос, ссылающийся на пользовательскую функцию, завершится с ошибкой sql10003C. для решения этой проблемы запускайте определяемую пользователем функцию без использования режима fenced mode или уменьшите область разделяемой памяти базы данных так, чтобы она занимала не более 5 сегментов.


Конфигурация памяти DB2 в 32-разрядной системе Sun Solaris версии 2.6 и выше

В отличие от системы AIX, в которой каждый сегмент имеет размер 256 МБ, размер сегментов памяти в системе Solaris не фиксирован. Структура адресуемой памяти 32-разрядной системы Solaris изображена на рисунке 9.

Рисунок 9. 32-разрядное адресное пространство памяти DB2 в системе Sun Solaris
32-разрядное адресное пространство памяти DB2 в системе Sun Solaris

Адреса с 0x0 по 0x00010000 не используются. Первый сегмент начинается с адреса 0x00010000 и зарезервирован под исполняемые модули db2sysc и собственную память агента. По умолчанию этот сегмент заканчивается адресом 0x10000000, таким образом, имея размер 256 МБ (мы можем увеличить размер этого сегмента с помощью регистровой переменной DB2 DB2DBMSADDR, о чем будет рассказано ниже). Под выполнение db2sysc отводится лишь небольшая часть этого сегмента, остальной объем (более 200 МБ) выделяется под собственную память агента.

По умолчанию разделяемая память экземпляра начинается с фиксированного адреса 0x10000000. Тем не менее, это значение может быть увеличено, тем самым, оставляя больше пространства под собственную память агента. Например, если разделяемая память экземпляра начинается с адреса 0x12000000 вместо 0x10000000, то мы имеем дополнительные 32 МБ (0x12000000 минус 0x10000000), которые могут быть использованы под собственную память агента. Чтобы сделать это, установите регистровую переменную DB2DBMSADDR, как показано ниже:
db2set DB2DBMSADDR=0x12000000

Примечание. DB2DBMSADDR DB2 может принимать значения от 0x10000000 до 0x10FFFFFF с шагом 0x10000.

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

За разделяемой памятью базы данных следуют сегменты памяти для трассировки DB2, совместно используемых библиотек и стека (инструкции, которые должны быть выполнены). В отличие от системы AIX, в которой стек и собственная память агента расположены в одном сегменте памяти, в Solaris они расположены в отдельных сегментах. Благодаря этому, не существует риска, что стек и собственная память агента перекроются.

Поскольку размеры всех этих сегментов памяти не фиксированы, мы можем лишь предположительно оценить размеры разделяемой памяти экземпляра и базы данных по следующей формуле:
4ГБ - собственная память агента – сегмент трассировки DB2 – сегмент совместно используемых библиотек - стек

Обратите внимание на то, что полученное значение включает в себя как разделяемую память экземпляра, так и разделяемую память базы данных, и эти сегменты памяти должны быть непрерывными.

Чтобы посмотреть фактически используемый объем памяти, выполните команду /usr/proc/bin/pmap command (от имени пользователя root), указав ID любого из процессов db2sysc или db2agent.

Примечание. При использовании команды "-ef | grep имя_экземпляра" для отображения процессов DB2 в системе Solaris все процессы отображаются как db2sysc. Для вывода "реальных" имен процессов DB2 вы можете использовать команду db2ptree.

На рисунке 10 приведен пример вывода команды pmap.

Рисунок 10. Пример вывода команды pmap для процесса db2sysc (/usr/proc/bin/pmap -x 15444)
Пример вывода команды pmap для процесса db2sysc (/usr/proc/bin/pmap -x 15444)

Некоторые наблюдения из рисунка 10:

  • Сегмент с адреса 0x00010000 по 0x023F8000 зарезервирован под выполнение исполняемых модулей db2sysc (около 36 МБ)
  • Сегмент с адреса 0x023F8000 по 0x10000000, выделенный оранжевым цветом (куча), используется под собственную память агента.
  • Разделяемая память экземпляра, выделенная зеленым цветом, начинается с адреса по умолчанию 0x10000000. Это означает, что переменная DB2DBMSADDR не задана.
  • Все три сегмента, выделенные зеленым цветом, используются под разделяемую память, которая включает в себя как разделяемую память экземпляра, так и разделяемую память базы данных. Вывод команды pmap не говорит вам о том, какой из сегментов является разделяемой памятью экземпляра, а какой – разделяемой памятью базы данных. Все, что нам известно, это то, что разделяемая память базы данных заканчивается по адресу 0xFE002000, поскольку с этого адреса начинается сегмент анонимной памяти. Таким образом, общий объем разделяемой памяти экземпляра и разделяемой памяти базы данных составляет 0xFE002000 - 0x10000000 = 3,992,985,600 байтов = ~3.7 ГБ.
  • Адреса с 0xFFBC0000 по 0xFFFFFFFF являются сегментом памяти для стека (около 4 МБ).

Примечание. В 32-разрядной системе Solaris мы обычно ограничиваем размер разделяемой памяти базы данных DB2 примерно до 3.5 ГБ.

Если регистровая переменная DB2DBMSADDR задана, разделяемая память экземпляра будет начинаться с адреса, указанного в этой переменной. В следующем примере показано, как можно добиться этого.

Пример

Задайте значение регистровой переменной DB2DBMSADDR:

  • db2set DB2DBMSADDR = 0x12000000
  • db2stop
  • db2start (для вступления изменений в силу необходимо перезапустить экземпляр)

Получите ID процесса db2sys:

  • ps -ef | grep sylviaq ('sylviaq' – это имя экземпляра)

  • -ef | grep sylviaq
  • sylviaq 13166 1 0 13:09:12 pts/2 0:00 /export/home/sylviaq/sqllib/bin/db2bp 13049C11221 5
  • sylviaq 13263 13256 0 13:11:02 ? 0:00 db2sysc
  • sylviaq 13265 13256 0 13:11:03 ? 0:00 db2sysc
  • sylviaq 13257 13254 0 13:10:59 pts/3 0:00 -ksh
  • sylviaq 13256 13253 0 13:10:59 ? 0:00 db2sysc
  • sylviaq 13262 13256 0 13:11:00 ? 0:00 db2sysc
  • sylviaq 13360 13049 0 13:11:41 pts/2 0:00 grep sylviaq
  • sylviaq 13264 13256 0 13:11:02 ? 0:00 db2sysc
  • sylviaq 13266 13261 0 13:11:03 ? 0:00 db2sysc

Под учетной записью root перейдите в директорию /usr/proc/pmap и выполните команду pmap для любого из процессов db2sysc:
./pmap -x 13263

Вывод команды pmap:

  • 13263: db2sysc
  • Address Kbytes Resident Shared Private Permissions Mapped File
  • 00010000 35808 4064 1608 2456 read/exec db2sysc
  • 02316000 896 168 48 120 read/write/exec db2sysc
  • 023F6000 744 264 8 256 read/write/exec [ heap ]
  • 12000000 243472 243472 - 243472 read/write/exec/shared [shmid=0xbc3]
  • 21000000 22512 22512 - 22512 read/write/exec/shared [shmid=0xbc4]
  • FCC00000 8328 8328 - 8328 read/write/exec/shared [shmid=0xa96]
  • FE002000 8 - - - read/write/exec [ anon ]

Обратите внимание на то, что теперь разделяемая память экземпляра начинается с адреса 0x12000000, а не с адреса по умолчанию 0x10000000. Размер собственной памяти агента (обозначенный как 'heap') увеличился с 220 МБ (рисунок 10) до 252 МБ (0x12000000 - 0x023F6000 = 0xFC0A000 = 264282112 (десятичное значение) = ~252 МБ).

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

Хотя для разделяемой памяти базы данных в Solaris мы имеем большее адресное пространство по сравнению с 2 ГБ в AIX, в Solaris вся разделяемая память связана с физическим ОЗУ. Это существенным образом влияет на количество баз данных, которые вы можете запустить одновременно, если размер ОЗУ невелик. Такая ситуация рассматривается в примере 2 раздела "Распространенные проблемы распределения разделяемой памяти базы данных в 32-разрядной системе Solaris".

Наиболее важные выводы, которые нужно извлечь после ознакомления с данной структурой:

  • В отличие от AIX, сегменты памяти в Solaris не имеют ограничений по размеру. Собственную память агента можно увеличить путем перемещения разделяемой памяти экземпляра по более высокому адресу, задав значение регистровой переменной DB2DBMSADDR.
  • Максимальный размер разделяемой памяти базы данных составляет примерно 3.5 ГБ.
  • Разделяемая память связана с физическим ОЗУ и не может быть выгружена.

Распространенные проблемы распределения разделяемой памяти базы данных в 32-разрядной системе Solaris

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

  • Во время запуска базы данных (активация базы данных или первое подключение к ней) - SQL1478W, SQL1084C, зависание
  • Во время выполнения - SQL2043N, зависание

В состав DB2 для системы Solaris входит утилита под названием db2osconf. Эта утилита предлагает рекомендуемые значения для параметров ядра, основываясь на размере системы. Рекомендуемые значения для заданной системы позволяют настроить систему на рабочую нагрузку, которая в большинстве случаев оказывается достаточной.

Параметром ядра, который чаще всего настраивается неправильно, является shmmax. Этот параметр определяет максимальный размер (в байтах) сегмента разделяемой памяти, который может быть выделен в системе. Если СУБД DB2 настроена на создание области разделяемой памяти базы данных, размер которой превышает данный размер, запрос завершится с ошибкой. Другими параметрами ядра, на которые следует обратить внимание, являются shmseg и shmmni.

Другая распространенная проблема распределения разделяемой памяти базы данных в системе Solaris связана с тем, что сегмент разделяемой памяти связан с физическим ОЗУ. Если в ОЗУ окажется недостаточно доступных свободных страниц или других страниц, которые могут быть вытеснены из ОЗУ операционной системой с целью освободить место под сегмент базы данных, запрос на запуск базы данных завершится с ошибкой.

В следующих примерах демонстрируются неправильные конфигурации, приводящие к проблемам.

Пример 1

Рассмотрим следующую конфигурацию (все страницы имеют размер 4 КБ):

Сервер:

  • Объем физической памяти на сервере составляет 16 ГБ
  • shmsys:shminfo_shmmax = 2097152 (2 ГБ)

База данных:

  • IBMDEFAULTBP 400,000 страниц
  • UTILHEAP 17,500 страниц
  • DBHEAP 30,000 страниц
  • LOCKLIST 1000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц

Ограничение: любой запрос со стороны DB2 на создание области разделяемой памяти базы данных, превышающей значение параметра shmmax (в данном случае 2 ГБ), завершится с ошибкой типа "нехватка памяти".

Расчет:
Разделяемая память базы данных = (всего 456,000 страниц x 4 КБ на страницу) x 1.1 = ~2.0 ГБ

Проблема: может оказаться возможным активировать или подключиться к базе данных, тем не менее, при попытке запуска приложения вы можете получить следующее сообщение об ошибке:
SQL1224N A database agent could not be started to service request, or was terminated as a result of a database system shutdown or a force command. SQLSTATE=55032

Это наиболее вероятное сообщение, которое возвращает DB2. Однако на UNIX-серверах, работающих под управлением ОС, отличных от AIX, вероятнее всего, будет содержаться указание на проблему, связанную с ресурсами памяти. В частности, на неправильную настройку параметров ядра.

Чтобы решить эту проблему, настройте должным образом параметры ядра. Задайте следующее значение:
shmsys:shminfo_shmmax = 15099494 (~90% от 16 ГБ)

Пример 2

Рассмотрим следующую конфигурацию (все страницы имеют размер 4 КБ):

Объем физической памяти на сервере составляет 1 ГБ

База данных A:

  • IBMDEFAULTBP 137,500 страниц
  • INTRA_PARALLEL ON
  • UTILHEAP 10,000 страниц
  • DBHEAP 10,000 страниц
  • SHEAPTHRES_SHR 20,000 страниц
  • LOCKLIST 1000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц
  • APPGROUP_MEM_SZ 20,000 страниц

База данных B:

  • IBMDEFAULTBP 92,500 страниц
  • INTRA_PARALLEL ON
  • UTILHEAP 5,000 страниц
  • DBHEAP 10,000 страниц
  • SHEAPTHRES_SHR 15,000 страниц
  • LOCKLIST 1000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц
  • APPGROUP_MEM_SZ 20,000 страниц

Ограничение: поскольку разделяемая память связана с физическим ОЗУ, она никогда не будет выгружена. По этой причине мы может выделить для базы данных только 1 ГБ (объем доступной физической памяти) разделяемой памяти.

Расчет:

  • Разделяемая память базы данных A = (всего 186,000 страниц x 4 КБ на страницу) x 1.1 = ~818 МБ
  • Память группы приложений базы данных A = всего 20,000 страниц x 4 КБ на страницу = 80 МБ
  • Разделяемая память базы данных B = (всего 131,000 страниц x 4 КБ на страницу) x 1.1 = ~576 МБ
  • Память группы приложений базы данных B = всего 20,000 страниц x 4 КБ на страницу = 80 МБ

  • Для запуска базы данных A требуется: 818 МБ + 80 МБ = ~898 МБ
  • Для запуска базы данных B требуется: 576 МБ + 80 МБ = ~656 МБ

Проблема: предположим, что база данных A активирована. При этом, как минимум, 898 МБ разделяемой памяти связано с физическим ОЗУ. При попытке активации базы данных B вы получите следующее сообщение об ошибке:
SQL1084C Shared memory segments cannot be allocated. SQLSTATE=57019

При одновременном запуске базы данных A и базы данных B нам потребуется, по меньшей мере, 1.55 ГБ (898 МБ + 656 МБ) доступного физического ОЗУ, чтобы связать с ним разделяемую память. Очевидно, что 1 ГБ ОЗУ недостаточно. Для решения этой проблемы воспользуйтесь одним из следующих вариантов:

  • Попытайтесь уменьшить размеры буферных пулов обеих баз данных
  • Попытайтесь уменьшить размер памяти группы приложений
  • Наиболее подходящий вариант – увеличение физического ОЗУ. В данном случае для запуска обеих баз данных вам понадобится, как минимум, 1.55 ГБ физического ОЗУ

В нашем случае, учитывая вышеприведенные параметры конфигурации базы данных, вы можете запустить в любой момент времени одну базу данных (A или B), но не обе сразу. Необходимо добавить дополнительную физическую память.

Эта проблема не возникает в системе AIX, в которой разделяемая память не связана с физическим ОЗУ. В данном сценарии база данных B сможет запуститься. Однако это означает, что память базы данных A должна быть выгружена. Когда обращения со стороны приложений выполняются к базе данных A, должна быть выгружена память базы данных B. Вы можете представить, как часто в этом случае будет происходить выгрузка памяти.

Пример 3

Рассмотрим следующую конфигурацию (все страницы имеют размер 4 КБ):

Сервер:

  • Объем физической памяти на сервере составляет 16 ГБ
  • shmsys:shminfo_shmmax = 15099494 (~90% от 16 ГБ)

База данных:

  • IBMDEFAULTBP 350,000 страниц
  • UTILHEAP 17,500 страниц
  • DBHEAP 10,000 страниц
  • LOCKLIST 1000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц
  • ESTORE_SEG_SZ = 400000 страниц
  • NUM_ESTORE_SEGS = 1

Расчет:

  • Разделяемая память базы данных = (всего 386,000 страниц x 4 КБ на страницу + 400,000 страниц хранилища estore * 100 байтов) x 1.1 = ~1.66 ГБ
  • Память ESTORE = 400000 x 4 КБ = 1.6 ГБ

Проблема: объем разделяемой памяти базы данных составляет 1.66 ГБ и, соответственно, не превышает ограничения в 3.35 ГБ. Параметр shmmax задан правильно. Однако при запуске базы данных существует вероятность получить следующее сообщение об ошибке! В журнале db2diag.log вы можете обнаружить следующие строки:

  • 2003-12-04-10.10.13.362027 Instance:db2inst1 Node:000
  • PID:18327(db2agent (SAMPLE) 0) TID:1 Appid:*LOCAL.sample.047844091013
  • oper system services sqloVLMAttachVLMSegment Probe:20 Database:SAMPLE
  • sqloVLMAttachVLMSegment - shmat failed
  • 0xFFBE833C : 0x0000000C

shmat – это функция UNIX, которая присоединяет сегмент разделяемой памяти, связанный с разделяемой памятью, идентифицированной функцией shmid (еще одна функция Solaris), к сегменту данных вызывающего процесса. Выполнение shmat завершилось с ошибкой из-за кода ошибки 0x000000C (ENOMEM), который означает, что доступное пространство данных имеет недостаточный размер для того, чтобы уместить сегмент разделяемой памяти.

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

Как такое может быть? Ответ заключается в способе, которым мы пытались распределить ESTORE. Каждый сегмент ESTORE должен являться непрерывным блоком. В нашем примере мы пытались выделить для хранилища ESTORE один большой (последовательный) блок памяти (1.6 ГБ). Даже при наличии 16 ГБ ОЗУ он мог оказаться фрагментированным, и, таким образом, 1.6 ГБ памяти могли не быть непрерывными.

Для решения этой проблемы установите в файле конфигурации базы данных следующие значения для ESTORE:

  • ESTORE_SEG_SZ = 40000 страниц
  • NUM_ESTORE_SEGS = 10

Устанавливая вышеуказанные значения, фактически, мы все так же пытаемся выделить для ESTORE суммарный объем, равный 1.6 ГБ. Тем не менее, мы пытаемся выделить для ESTORE 10 участков памяти по 160 МБ. Это пространство для непрерывного распределения имеет намного меньший объем, поэтому, вероятнее всего, проблема будет решена.


Конфигурация памяти DB2 в 32-разрядной системе HP-UX

В 32-разрядной платформе HP-UX управление памятью по умолчанию основывается на квадрантах, в которых каждый процесс имеет свое собственное пространство. Каждый процесс (включая агенты DB2) может обращаться к памяти объемом до 4 ГБ. Эти 4 ГБ адресуемой памяти разделяются на 4 квадранта размером 1 ГБ каждый, как показано на рисунке 11.

Рисунок 11. 32-разрядное адресное пространство памяти DB2 в системе HP-UX
32-разрядное адресное пространство памяти DB2 в системе HP-UX

Квадрант 1 (1 ГБ) зарезервирован под текст программы (исполняемый код).

Квадрант 2 (1 ГБ) зарезервирован под глобальные данные программы.

Комбинация квадрантов 1 и 2 (за вычетом памяти ядра и других процессов) может быть использована под собственную память. Квадранты 1 и 2 существуют в количестве n экземпляров (по одному для каждого процесса).

Квадрант 3 (1 ГБ) зарезервирован под глобальную разделяемую память.

Квадрант 4 (0.75 ГБ) зарезервирован под глобальную разделяемую память. Оставшиеся 0.25 ГБ используются для преобразований ввода/вывода.

Здесь существует ограничение на размер разделяемой памяти в 1.75 ГБ, действующее для всей системы. То есть, все совместно используемые объекты (а не только DB2) сопоставляются квадрантам 3 и 4 в едином пространстве, используемом всеми процессами. Пространство разделяемой памяти разделено на 1 ГБ в квадранте 3 и 0.75 ГБ в квадранте 4. Тем не менее, сегмент разделяемой памяти не может располагаться в нескольких квадрантах, и нет никаких гарантий того, что это адресное пространство будет непрерывным. В зависимости от процесса DB2 использует различные сегменты. Каждый сегмент может быть сопоставлен только либо квадранту 3, либо квадранту 4, но не обоим. Таким образом, размер наибольшего сегмента разделяемой памяти в квадранте 3, который может использовать DB2, составляет 1 ГБ, а размер сегмента в квадранте 4 – 0.75 ГБ. В действительности этот размер, скорее всего, меньше, поскольку некоторые небольшие сегменты разделяемой памяти, возможно, уже были распределены (либо DB2, либо другим процессом). Это означает, что область разделяемой памяти базы данных имеет ограничение по размеру, в действительности составляющее от 0.75 до 1 ГБ. Это существенно меньше, чем любая область разделяемой памяти базы данных в других платформах UNIX.

Примечание. Архитектура памяти HP-UX по умолчанию использует исполняемый модуль ядра SHARE_MAGIC. В соответствии с изменениями ядра версии HP-UX 10.20 можно увеличить максимальный размер глобальной разделяемой памяти с 1.75 ГБ до 2.75 ГБ, скомпилировав приложение с указанием использования исполняемого модуля ядра SHMEM_MAGIC. Однако для кода DB2 на сегодняшний день не планируется поддержка компиляции с использованием модуля SHMEM_MAGIC.

В версии HP-UX 11.0 и более поздних версиях можно использовать искусственный прием в виде окон памяти для использования разделяемой памяти объемом более 1.75 ГБ. Окна памяти позволяют определять для каждого процесса уникальное глобальное пространство размером до 1 ГБ разделяемой памяти. Доступ к сегментам разделяемой памяти, помещенным в одно уникальное пространство, предоставляется только процессам, принадлежащим одному и тому же окну памяти. Однако различные приложения или отдельные экземпляры одного приложения могут быть помещены в различные окна памяти и, таким образом, использовать больший объем доступной физической памяти системы.

Окна памяти позволяют использовать квадрант 3 в качестве приватного пространства разделяемой памяти для группы процессов в соответствии с тем, как это определено в файле /etc/services.window. Реализация окон памяти в DB2 сопоставляет каждый экземпляр отдельному окну памяти. Другими словами, каждый экземпляр DB2 может иметь свое приватное пространство памяти в сегменте 3. Квадрант 4 при этом будет продолжать использоваться в качестве глобальной области разделяемой памяти, в которой могут распределяться сегменты любого совместно используемого процесса. Заметьте, что по возможности, совместно используемые библиотеки всегда будут сопоставляться, в первую очередь, квадранту 4. Таким образом, объем доступной экземпляру разделяемой памяти будет составлять 1 ГБ плюс объем свободной памяти, оставшейся в квадранте 4. Тем не менее, сегменты разделяемой памяти по-прежнему не могут выходить за границы квадрантов. В зависимости от типа и размера сегмента DB2 может создать его в квадранте 4. Максимальный размер области разделяемой памяти базы данных по-прежнему имеет ограничение приблизительно в 1 ГБ. Использование окон памяти позволяет нам выделить полный квадрант (квадрант 3, приблизительно 1 ГБ) экземпляру DB2, тогда как без использования окон памяти все экземпляры должны использовать общую для всей системы область памяти, ограниченную 1.75 ГБ.

Совет. Если вы создаете одну базу данных в каждом экземпляре, вы можете выделить до 1 ГБ разделяемой памяти базы данных для каждой из ваших баз данных.

Примечание. Окна памяти расширяют виртуальный объем памяти в системе только для 32-разрядных приложений. При этом вы сможете использовать больший объем физической памяти, имеющейся в системе. Без использования окон памяти будет задействовано только лишь 1.75 ГБ физической памяти, независимо от ее установленного объема.

Наиболее важные выводы, которые нужно извлечь после ознакомления с данной структурой:

  • Архитектура памяти HP-UX по умолчанию позволяет использовать максимум 1.75 ГБ разделяемой памяти для ВСЕХ процессов, а не только для DB2. Выделить разделяемую память на уровне экземпляра в HP-UX возможно только при использовании окон памяти.
  • Сегменты разделяемой памяти должны быть непрерывными, и, соответственно, они не могут быть выходить за границы квадрантов. Вследствие этого, максимальный объем разделяемой памяти базы данных имеет ограничение в 1 ГБ.
  • Окна памяти могут быть использованы для того, чтобы предоставить каждому экземпляру DB2 1 ГБ приватного пространства разделяемой памяти, плюс весь свободный объем, оставшийся в квадранте глобальной разделяемой памяти (квадрант 4).
  • Если в каждом экземпляре создается одна база данных, для каждой из них можно выделить до 1 ГБ разделяемой памяти базы данных.

Распространенные проблемы распределения разделяемой памяти базы данных в 32-разрядной системе HP-UX

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

  • Во время запуска менеджера базы данных – SQL1220N
  • Во время запуска базы данных (активация базы данных или первое подключение к ней) - SQL1478W, SQL1084C, SQL3605C, зависание
  • Во время выполнения - SQL2043N, зависание

Параметром ядра, который чаще всего настраивается неправильно, является shmmax. Обратитесь к документу Quick Beginnings, чтобы узнать, как следует настраивать этот параметр в зависимости от имеющегося объема физического ОЗУ. Параметр SHMMAX определяет максимальный размер (в байтах) сегмента разделяемой памяти, который может быть выделен в системе. Если СУБД DB2 UDB настроена на создание области разделяемой памяти базы данных, размер которой превышает данный размер, запрос завершится с ошибкой. Другим параметром ядра, на который следует обратить внимание, является shmmni.

В следующих примерах показаны неправильные конфигурации, приводящие к проблемам.

Пример 1

Рассмотрим следующую конфигурацию (все страницы имеют размер 4 КБ):

Сервер:

  • Объем физической памяти на сервере составляет 1 ГБ
  • shmmax = 966 367 641 (1 ГБ)
  • shmseg = 32

База данных:

  • IBMDEFAULTBP 100,000 страниц
  • UTILHEAP 5000 страниц
  • DBHEAP 10,000 страниц
  • LOCKLIST 17,500 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц

Расчет:
Разделяемая память базы данных = (всего 140,000 страниц x 4 КБ на страницу) x 1.1 = ~616 МБ

Проблема: может оказаться возможным активировать или подключиться к базе данных, тем не менее, при попытке подключения к базе данных вы можете обнаружить следующее сообщение об ошибке, периодически появляющееся в журнале db2diag.log:
DIA3605C Memory allocation failure occurred.

Заметьте, что расчет разделяемой памяти базы данных показывает нам, что мы не выходим за границы доступной разделяемой памяти в 1 ГБ. Теперь мы должны обратиться к конфигурации параметров ядра. Изучите рекомендации руководства "Quick Beginnings for DB2 Servers" по настройке параметров ядра в 32-разрядных платформах HP-UX. После изучения этого руководства вы обнаружите, что оно не содержит информации о параметре shmseg. Это означает, что вам нужно использовать значение по умолчанию. Значением по умолчанию для параметра shmseg является 120 (из-за того, что параметр ядра SHMSEG имеет слишком малое значение, некоторые сегменты памяти могли оказаться некорректно распределенными).

Для решения этой проблемы настройте должным образом параметры ядра. В нашем случае задайте следующее значение:

  • shmseg = 120

Пример 2

Рассмотрим следующую конфигурацию (все страницы имеют размер 4 КБ):

Сервер:

  • Объем физической памяти на сервере составляет 1 ГБ
  • shmmax = 966 367 641 (1 ГБ)
  • shmseg = 120
  • Размер SWAP-раздела на сервере составляет 500 МБ

База данных A:

  • IBMDEFAULTBP 100,000 страниц
  • UTILHEAP 2500 страниц
  • DBHEAP 10,000 страниц
  • LOCKLIST 20,000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц

База данных B:

  • IBMDEFAULTBP 160,000 страниц
  • UTILHEAP 7,500 страниц
  • DBHEAP 20,000 страниц
  • LOCKLIST 10,000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц

Ограничение: объем физического ОЗУ составляет лишь 1 ГБ, а разделяемая память базы данных может быть связана только с физически доступным ей объемом памяти, то есть, с ОЗУ размером 1 ГБ и swap-областью.

Расчет:

  • Разделяемая память базы данных A = (всего 140,000 страниц x 4 КБ на страницу) x 1.1 = ~616 МБ
  • Разделяемая память базы данных B = (всего 205,000 страниц x 4 КБ на страницу) x 1.1 = ~902 МБ

Проблема: вы можете активировать или подключиться в любой момент времени к базе данных A или к базе данных B, но не к обеим сразу. Попытка активировать одновременно обе базы данных приведет к следующей ошибке:
SQL1478W The defined buffer pools could not be started. Instead, one small buffer pool for each page size supported by DB2 has been started. SQLSTATE=01626

Когда база данных A и база данных B запускаются одновременно, требуется, как минимум, 1.52 ГБ (616 МБ + 902 МБ) разделяемой памяти. Можно связать базу данных A с квадрантом 4 (~0.75 ГБ доступной разделяемой памяти), а базу данных B – с квадрантом 3 (~0.75 ГБ). Однако в данном случае у нас ограничен объем физической памяти. Очевидно, что 1 ГБ ОЗУ недостаточно для сопоставления с 1.52 ГБ разделяемой памяти. Кроме того, swap-раздел слишком мал. Для решения этой проблемы воспользуйтесь одним из следующих вариантов:

  • Попытайтесь уменьшить размеры буферных пулов обеих баз данных
  • Попытайтесь увеличить размер swap-раздела, чтобы его объем стал в 2 раза больше объема физической памяти
  • Наиболее подходящий вариант – увеличение физического ОЗУ. В данном случае для запуска обеих баз данных вам понадобится, как минимум, 2 ГБ физического ОЗУ

Пример 3

Рассмотрим следующую конфигурацию (все страницы имеют размер 4 КБ):

Сервер:

  • Объем физической памяти на сервере составляет 6 ГБ
  • Экземпляр 1 (3 базы данных)

База данных A:

  • IBMDEFAULTBP 140,000 страниц
  • UTILHEAP 7,500 страниц
  • DBHEAP 20,000 страниц
  • LOCKLIST 10,000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц
  • APPGROUP_MEM_SZ 20,000 страниц

База данных B:

  • IBMDEFAULTBP 80,000 страниц
  • UTILHEAP 2500 страниц
  • DBHEAP 10,000 страниц
  • LOCKLIST 20,000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц
  • APPGROUP_MEM_SZ 20,000 страниц

База данных C:

  • IBMDEFAULTBP 130,000 страниц
  • UTILHEAP 7,500 страниц
  • DBHEAP 20,000 страниц
  • LOCKLIST 10,000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц
  • APPGROUP_MEM_SZ 20,000 страниц

Ограничение: объем физического ОЗУ составляет лишь 1 ГБ, а разделяемая память базы данных может быть связана только с физически доступным ей объемом памяти, то есть 1 ГБ + swap-область.

Расчет:

  • Разделяемая память базы данных A = (всего 185,000 страниц x 4 КБ на страницу) x 1.1 = ~814 МБ
  • Память группы приложений базы данных A = всего 20,000 страниц x 4 КБ на страницу = 80 МБ
  • Разделяемая память базы данных B = (всего 120,000 страниц x 4 КБ на страницу) x 1.1 = ~528 МБ
  • Память группы приложений базы данных B = всего 20,000 страниц x 4 КБ на страницу = 80 МБ
  • Разделяемая память базы данных C = (всего 175,000 страниц x 4 КБ на страницу) x 1.1 = ~770 МБ
  • Память группы приложений базы данных C = всего 20,000 страниц x 4 КБ на страницу = 80 МБ
  • Для запуска базы данных A требуется: 816 МБ + 80 МБ = ~894 МБ
  • Для запуска базы данных B требуется: 530 МБ + 80 МБ = ~608 МБ
  • Для запуска базы данных C требуется: 772 МБ + 80 МБ = ~850 МБ

Проблема: Запуск базы данных A и базы данных B был выполнен успешно. Запуск базы данных C завершился со следующей ошибкой:
SQL1478W The defined buffer pools could not be started. Instead, one small buffer pool for each page size supported by DB2 has been started. SQLSTATE=01626

Причина ошибки не заключается в физической памяти, поскольку ее у нас достаточно (6 ГБ). В процессе дальнейших тестов были получены следующие результаты запуска комбинаций баз данных:

  • Запуск баз данных A + B -> успех
  • Запуск баз данных B + C -> успех
  • Запуск баз данных A + C -> неудача
  • Запуск баз данных (A + B) + C -> неудача
  • Запуск баз данных (B + C) + A -> неудача

Запуск комбинаций (A + B) и (B + C) выполняется успешно потому, что в этих случаях общий объем разделяемой памяти, необходимый для инициализации баз данных, составляет 1.5 ГБ (894 + 608) и 1.46 ГБ (608+850) соответственно. Это меньше ограничения в 1.75 ГБ, и каждый сегмент разделяемой памяти базы данных может быть надежно сопоставлен квадранту и быть непрерывным. Запуск остальных комбинаций приводит к ошибке SQL1478W, поскольку в этих случаях либо превышается ограничение в 1.75 ГБ на объем разделяемой памяти, либо базе данных не может быть выделен непрерывный сегмент разделяемой памяти в границах квадранта.

Для решения этой проблемы воспользуйтесь следующим вариантом:

  • Используйте окна памяти. Наилучшим решением будет являться определение трех экземпляров DB2. Восстановите одну базу данных в каждом из экземпляров. Для каждого экземпляра создайте окно памяти. После этого каждая база данных будет иметь полный доступ к своему собственному окну пространства разделяемой памяти, размером в 1 ГБ. Примечание. Параметр ядра max_mem_windows должен быть установлен в 2 (количество экземпляров, уменьшенное на единицу).


Конфигурация памяти DB2 в 32-разрядной системе Linux/Intel

На рисунке 12 изображены 4 ГБ адресуемой памяти в 32-разрядной системе Linux/Intel.

Рисунок 12. 32-разрядное адресное пространство памяти DB2 в системе Linux/Intel
32-разрядное адресное пространство памяти DB2 в системе Linux/Intel

Сегмент, начинающийся с адреса 0x08048000 и заканчивающийся адресом 0x0FFFFFFF, зарезервирован под исполняемые модули db2sysc.

Сегмент с адреса 0x10000000 по 0x3FFFFFFF представляет собой разделяемую память экземпляра общим объемом 0.75 ГБ.

Совместно используемые библиотеки DB2 по умолчанию начинаются с адреса 0x40000000.

Можно загрузить совместно используемые библиотеки по более младшему адресу, оставляя больше пространства для разделяемой памяти базы данных (это также означает, что остается меньше пространства для разделяемой памяти экземпляра; но, поскольку разделяемая память экземпляра в большинстве случаев имеет достаточно небольшой размер по сравнению с памятью базы данных, мы получаем от этого существенный выигрыш). Например, если совместно используемые библиотеки загружены по адресу, младше, чем 0x40000000, разделяемая память базы данных может быть загружена по адресу 0x38000000. Если совместно используемые библиотеки загружены по адресу, младше, чем 0x2a000000, разделяемая память базы данных может быть загружена по адресу 0x30000000, что позволяет использовать более 2 ГБ для разделяемой памяти базы данных. Эти изменения требуют перекомпиляции ядра, которую мы не будем обсуждать в этой статье. Для получения дополнительной информации обратитесь к соответствующему разделу вашего справочного руководства по Linux.

Тем не менее, начиная с версии v8.1 FP2 в системе Redhat Advanced Server, а также в системе SuSE SLES 8, DB2 автоматически будет пытаться переместить совместно используемые библиотеки по младшим адресам, и для этого не требуется перекомпиляция ядра. В этих корпоративных дистрибутивах есть файл /proc/pid/mapped_base, содержащий адрес, по которому должны быть загружены совместно используемые библиотеки. По умолчанию этим адресом является 0x40000000, но мы может задать для него более низкое значение (вплоть до 0x20000000). В момент запуска db2sysc выполняется проверка существования файла mapped_base. Если этот файл существует, используется новое значение и выполняется перезапуск. После этого каждый подпроцесс, порожденный процессом, использующим измененное значение mapped_base, также использует новое значение.

Разделяемая память базы данных (включая буферные пулы) начинается с адреса 0x50000000 (по умолчанию) и увеличивается по направлению к стеку. Стек содержит инструкции, которые должны быть выполнены, и увеличивается, начиная с адреса 0xC0000000.

Важно, чтобы разделяемая память базы данных и стек не перекрывались. Мы рекомендуем выделять для стека 16 МБ памяти. В этом случае мы будем иметь ~1.73 ГБ для разделяемой памяти базы данных (с адреса 0x50000000 по 0xC0000000, за вычетом 16 МБ, используемых стеком).

При использовании команды "ulimit -a" или "ulimit -s" для вывода ограничений, значения выводятся в килобайтах.
Stack = 16384

Важно задать эти ограничения таким образом, чтобы стек и адресное пространство разделяемой памяти не перекрывались друг с другом. Если это произойдет, возникнет сбой экземпляра с сигналом 4 или с сигналом 11.

Последний 1 ГБ памяти зарезервирован под ядро Linux.

Вы могли заметить, что не существует сегмента под собственную память агента. Это действительно так. В 32-разрядной системе Linux/Intel не существует отдельного зарезервированного сегмента для собственной памяти. Собственная память агента выделяется в любом доступном пространстве между совместно используемыми библиотеками.

Чтобы узнать, сколько памяти используется в данный момент, просмотрите файл с названием /proc/PID/maps, где PID – идентификатор любого из процессов db2agent. На рисунке 13 изображен пример содержимого этого файла.

Рисунок 13. Maps-файл процесса db2sysc
Maps-файл процесса db2sysc

Некоторые наблюдения из рисунка 13:

  • Сегмент, выделенный синим цветом и начинающийся с адреса 0x10000000 – это разделяемая память экземпляра.
  • Совместно используемые библиотеки загружены, начиная с адреса 0x40000000. Между ними расположены сегменты собственной памяти агента (выделены оранжевым цветом).
  • Разделяемая память базы данных начинается с адреса 0x50000000 (выделена зеленым цветом).
  • Последний сегмент, выделенный фиолетовым цветом – это стек.

Наиболее важные выводы, которые нужно извлечь после ознакомления с данной структурой:

  • По умолчанию объем разделяемой памяти базы данных составляет 1.75 ГБ за вычетом стека.
  • Можно загрузить совместно используемые библиотеки по более младшему адресу, оставляя меньше пространства для разделяемой памяти экземпляра, но больше пространства для разделяемой памяти базы данных.

Распространенные проблемы распределения разделяемой памяти базы данных в 32-разрядной системе Linux

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

  • Во время запуска менеджера базы данных - SQL1220N
  • Во время запуска базы данных (активация базы данных или первое подключение к ней) - SQL1478W, SQL1084C, зависание
  • Во время выполнения - SQL2043N, зависание

Параметром ядра, который чаще всего настраивается неправильно, является shmmax. Обратитесь к документу Quick Beginnings, чтобы узнать, как следует настраивать этот параметр в зависимости от имеющегося объема физического ОЗУ. Параметр shmmax определяет максимальный размер (в байтах) сегмента разделяемой памяти, который может быть выделен в системе. Если СУБД DB2 UDB настроена на создание области разделяемой памяти базы данных, размер которой превышает данный размер, запрос завершится с ошибкой. Другим параметром ядра, на который следует обратить внимание, является shmmni.

В следующих примерах показаны неправильные конфигурации, приводящие к проблемам.

Пример 1

Сервер:

  • Объем физической памяти на сервере составляет 2 ГБ
  • kernel.shmmax = 32768 (32 КБ)

База данных:

  • IBMDEFAULTBP 200,000 страниц
  • INTRA_PARALLEL ON
  • UTILHEAP 17,500 страниц
  • DBHEAP 10,000 страниц
  • SHEAPTHRES_SHR 50,000 страниц
  • LOCKLIST 1000 страниц
  • PCKCACHE 5000 страниц
  • CATALOGCACHE 2500 страниц
  • APPGROUP_MEM_SZ 20,000 страниц (по умолчанию в версии v8)

Ограничение: параметр SHMMAX установлен равным 32 КБ. DB2START сможет выделить достаточный объем разделяемой памяти, необходимой для успешного запуска экземпляра.

Расчет:

  • Разделяемая память базы данных = (всего 286,000 страниц x 4 КБ на страницу) x 1.1 = ~1.26 ГБ
  • Разделяемая память группы приложений базы данных = (всего 20,000 страниц x 4 КБ на страницу) = 80 МБ

Проблема: во время запуска db2start возникает следующая ошибка:
SQL1220N The database manager shared memory set cannot be allocated.

Для решения этой проблемы увеличьте значение параметра SHMMAX до более приемлемого размера, например 2 ГБ.

Пример 2

Сервер:

  • СУБД: DB2 v8.1.0.0
  • Операционная система: Linux SuSE SLES-8
  • Версия библиотеки glibc: 2.2.5
  • Версия ядра: 2.4.19

Проблема: если параметр SHMMAX установлен равным в точности 2 ГБ, то есть 2147483648, db2start понизит его до 268435456. Если же первоначальное значение понизить на 1 байт, db2start не внесет никаких изменений.

Эта проблема НЕ возникает в системе SuSe 8.0.


Конфигурация памяти DB2 в 32-разрядной системе Windows

Архитектура DB2 UDB в системе Windows имеет фундаментальные отличия. Все операции DB2 реализованы в виде потоков одного процесса (db2sysc.exe). Модель процесса Windows может обращаться к памяти объемом до 4 ГБ, как показано на рисунке 14.

Рисунок 14. 32-разрядное адресное пространство памяти DB2 в системе Windows
32-разрядное адресное пространство памяти DB2 в системе Windows

В системе Windows не существует концепции областей разделяемой памяти. Все пулы разделяемой памяти, которые в системе UNIX являлись бы частью области памяти (буферные пулы, пул dbheap и т. д.), располагаются в области собственной памяти db2sysc в соответствии с требованиями.

В редакциях Windows, отличных от Advanced Server (Windows NT, 2000 Pro/Standard), 4 ГБ адресного пространства разделены на 2 ГБ пространства пользователя и 2 ГБ пространства ядра. Фактически, это ограничивает суммарную память, доступную процессу db2sysc, 2 гигабайтами.

В редакции Windows Advanced Server можно перераспределить данное отношение (2 ГБ/2 ГБ), выделив 3 ГБ под пространство пользователя и 1 ГБ под пространство ядра, как показано на рисунке 14.

Для того чтобы можно было выполнить такое перераспределение, необходимо использовать опцию /3GB в файле boot.ini. Одно из условий заключается в том, что опция /3GB поддерживается только в системах Windows 2000 Advanced Server, Windows 2000 DataCenter, Windows 2003 Enterprise Edition и Windows 2003 DataCenter. Вы можете использовать эту опцию в системе Windows 2000 Pro/Standard, но при этом пользовательское пространство будет иметь размер только 2 ГБ, хотя пространство ядра будет уменьшено до 1 ГБ; таким образом, мы просто потеряем 1 ГБ памяти.

Примечание. Чтобы получить эффект от использования опции /3GB, в вашей 32-разрядной системе Windows должно быть установлено не менее 4 ГБ физического ОЗУ.

Для преодоления ограничения в 2 ГБ (или 3 ГБ) на объем пространства пользователя в редакциях Windows 2000 Advanced Server и Windows 2003 Advanced Server имеются опции поддержки больших объемов памяти – Address Windowing Extensions (расширение адресного пространства – AWE) и Physical Address Extension (расширение физического пространства – PAE).

AWE – это механизм, обеспечивающий доступ к очень большому объему памяти через потенциально меньшее окно. Таким способом можно выполнять адресацию к большому пулу памяти так, как если бы он был линейным. По существу, AWE позволяет создавать буферные пулы размером более 2 ГБ. Функционал AWE реализован при помощи опции /PAE в файле boot.ini. Опция /PAE будет работать в системах Windows 2000 Pro/Standard, однако корпорация Microsoft будет осуществлять поддержку операционных систем с данной опцией только в том случае, если используются ОС Windows 2000 Advanced Server, Windows 2000 DataCenter, Windows 2003 Enterprise Edition и Windows 2003 DataCenter.

Наиболее важные выводы, которые нужно извлечь после ознакомления с данной структурой:

  • В системе Windows не существует концепции областей разделяемой памяти. Все пулы памяти (разделяемой или собственной), используемые DB2, располагаются в одном сегменте памяти – области пользователя, которая в системах Windows, отличных от редакции Advanced Server, ограничена двумя гигабайтами.
  • В операционных системах редакции Advanced Server можно увеличить размер области пользователя до 3 ГБ, используя опцию /3GB в файле boot.ini.
  • С помощью AWE можно создавать буферные пулы размером более 2 ГБ. В действительности, возможно задать буферный пул с максимальным размером 64 ГБ.


Заключение

Структура памяти DB2 состоит из четырех областей: разделяемая память экземпляра, разделяемая память базы данных, разделяемая память группы приложений (только если для базы данных включен внутрисекционный параллелизм или концентратор, или если база данных расположена в нескольких разделах) и собственная память агента. Каждая из этих областей памяти содержит отдельные пулы памяти. Например, буферный пул и куча базы данных – это два отдельных пула памяти, принадлежащих одной области памяти базы данных.

Каждый экземпляр содержит одну область разделяемой памяти экземпляра, которая используется совместно всеми базами данных этого экземпляра. Каждая база данных содержит одну область разделяемой памяти базы данных, которая используется совместно всеми агентами, подключенными к этой базе данных. Каждая группа приложений содержит одну область разделяемой памяти группы приложений, которая используется совместно всеми агентами, принадлежащими этой группе приложений. Каждый агент (или процесс) DB2 содержит одну область собственной памяти агента, которая используется эксклюзивно только этим агентом.

Независимо от фактического объема установленной физической памяти, в системах с 32-разрядной архитектурой памяти объем адресуемой памяти, к которой может обращаться любой процесс, составляет 4 ГБ для любой платформы. Более того, часть из этих 4 ГБ зарезервирована операционной системой. Для приложений (включая DB2) доступна только оставшаяся память (которая также называется пространством пользователя).

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

Таблица 1. Ограничения областей памяти DB2 для систем с 32-разрядной структурой памяти

ПлатформаРазделяемая память экземпляраРазделяемая память базы данныхСобственная память агента
AIX 256 МБ1.25 – 2 ГБ (1)240 МБ (2)
Solarisне фиксирован (3)3.5 ГБ~220 МБ (4)
HP-UX0.75 - 1 ГБ (5)0.75 – 1ГБКвадранты 1 и 2 (6)
Linux256 МБ1.75 – 2.25 ГБ256 МБ
Windowsнеприменимо (7)неприменимо (7)неприменимо (7)

Примечания:
(0) В среде с несколькими разделами, данные ограничения применяются к каждому разделу.
(1) Максимальный размер составляет 2 ГБ (с переменными DB2_MMAP_READ=NO и DB2_MMAP_WRITE=NO). Каждая из следующих конфигураций уменьшает размер разделяемой памяти базы данных на один сегмент (256 МБ), вплоть до минимума в 1.25 ГБ: функции или хранимые процедуры, выполняемыми в режиме fenced mode; переменная DB2_FORCE_FCM_BP=YES; включенный внутрисекционный параллелизм или концентратор подключений; база данных, распределенная по нескольким разделам.
(2) Сегмент размером 256 МБ разделен между данными (собственная память агента) и стеком. Если посредством ulimit размер стека установлен равным 16 МБ, то для собственной памяти агента доступно 240 МБ.
(3) В системе Solaris разделяемая память экземпляра теоретически может иметь очень большой размер, поскольку для сегментов разделяемой памяти не существует фиксированных адресов. Вместе разделяемая память экземпляра и разделяемая память базы данных имеют размер примерно 3.7 ГБ.
(4) В системе Solaris собственная память агента расположена в том же самом сегменте размером 256 МБ, что и исполняемые модули db2sysc. Исполняемые модули занимают примерно 36 МБ.
(5) В системе HP-UX все области разделяемой памяти расположены в квадранте 3 (1 ГБ) и квадранте 4 (0.75 ГБ).
(6) Комбинация квадрантов 1 и 2 (за вычетом памяти ядра и других процессов) может быть использована под собственную память.
(7) Вся разделяемая память экземпляра, разделяемая память базы данных и собственная память агента должна уместиться в 2 ГБ пространства пользователя (или в 3 ГБ в редакции Advanced Server, если используется опция the /3GB в файле boot.ini). Если система поддерживает AWE, этот объем составляет 64 ГБ.

При использовании 32-разрядной архитектуры памяти неважно, сколько физического ОЗУ установлено в системе – конфигурации экземпляров и баз данных ограничены 4 ГБ адресуемого пространства. Тем не менее, если у вас имеется достаточное количество ОЗУ, вы можете запускать несколько экземпляров или баз данных в системе одновременно, если каждая в отдельности будет удовлетворять вышеуказанному ограничению. Чтобы преодолеть это ограничение, следует рассмотреть переход на 64-разрядную версию DB2.


Благодарности

Выражаем особую благодарность Филиппу Чо (Philip Cho) и Майклу Корнишу (Michael Cornish) за технический обзор этой статьи.

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Information Management
ArticleID=407318
ArticleTitle=Модель памяти DB2 UDB
publish-date=07062009