Часто задаваемые вопросы по OpenEdge RDBMS
XIII. Разделяемая память
92. Мой сервер имеет 16 гигабайт памяти, но я не могу использовать буферный пул больше 2 гигабайт. Почему?
Потому что вы используете 32-битовую версию OpenEdge RDBMS. Никто не должен этого делать без хорошей причины, а таких причин мало. 64-битовые версии OpenEdge доступны для Linux, AIX, Solaris, HP-UX и Windows (для их использования вам нужны 64-битовые версии этих операционных систем).
Для всех 32-битовых версий OpenEdge на всех операционных системах имеется предел в 2 гигабайта (приблизительно) на общий объем разделяемой памяти, который может быть создан базой данных. Это ограничение накладывается на адресное пространство всех 32-разрядных процессов. Точное значение зависит от операционной системы и различных других факторов. Теоретически, 32-битовый процесс имеет максимальное полезное адресное пространства до 4 гигабайт, но вы не можете использовать его для данных полностью. Операционные системы используют часть адресного пространства для себя. Имеются также другие ограничения, накладываемые операционной системой. Объем адресного пространства, который доступен для разделяемой памяти, уменьшается из-за этих ограничений.
- 32-битовая операционная система Windows резервирует 2 GB адресного пространства для себя, оставляя 2 GB процессу. Имеется возможность изменить это ограничение, так что Windows зарезервирует только 1 гигабайт и выделит процессу 3 гигабайта, но это может вызвать неприятные побочные эффекты для всей системы. Вы не должны этого делать, даже если вы знаете, как. Вы были предупреждены. Из 2 GB, выделенных процессу, приблизительно 1,6 GB может быть использовано для разделяемой памяти.
- HP-UX выделяет в общей сложности приблизительно 1,7 GB разделяемой памяти для всей системы. В HP-UX имеется возможность, называющаяся «Memory Windows» (вы можете прочитать про это здесь: http://docs.hp.com/en/943/memwn1_4.pdf), которая предоставляет частичный и не особенно полезный обходной путь. Эта возможность трудна для использования, и только увеличивает предел для всей системы, но не предел для одной базы данных.
- В Linux, максимальный размер разделяемой памяти составляет приблизительно 2,7 GB.
- В AIX, 32-битовый процесс может прикрепить максимум 11 сегментов разделяемой памяти. Существует способ увеличить этот предел, используя переменную среды EXTSHM, но это приводит к ряду нежелательных побочных эффектов. Вы не должны использовать EXTSHM. Вы были предупреждены. До версии 10.1B, максимальный размер сегмента, используемый в OpenEdge RDBMS, составлял 128 мегабайт, эффективно ограничивая вас примерно 1,4 GB разделяемой памяти. Или меньше, если вы одновременно подключаете несколько баз данных в режиме self-serving, так как предел в 11 сегментов относится ко всему процессу.
Попытка превышения максимального числа сегментов для процесса приводит к сообщению об ошибке «(1175) Maximum number of shared-memory segments per process exceeded».
Некоторые или все из следующих элементов (иногда некоторые из них не используются) должны храниться в полезной части адресного пространства процесса:
- код и статические данные программы
- куча (heap) динамической памяти
- стеки потоков
- буферы файлов, дескрипторы файлов и т.д.
- UI-виджеты и связанные элементы
- сетевые подключения и соответствующие буферы
- разделяемые библиотеки (.dll)
- отображаемые на память файлы
- разделяемые библиотеки r-кода
- разделяемые сегменты памяти
- семафоры
- куча других вещей
Некоторые из перечисленных выше элементов (например, код, разделяемая память, разделяемые библиотеки) могут также разделяться с другими процессами, и будут представлены одной копией, используемой многими процессами. Другие элементы являются личными для процесса, и каждый процесс имеет свой собственный экземпляр (например, куча, стеки, буферы файлов и т.д.).
Исполняемые файлы _mprosrv, _mprshut, _sqlsrv2, и _progres, _prowin являются отдельными программами, которые будут использовать одну и ту же область разделяемой памяти для данной базы данных, но не так много кода. Каждая программа использует различные объемы стекового пространства и динамически размещаемых личных структур данных. Несколько экземпляров одного и того же исполняемого файла могут разделять собственный код и некоторые статические данные, а также области разделяемой памяти подключенных баз данных.
Заметим, что _mprosrv и _mprshut работают одновременно с единственной базой данных и разделяемой памятью, но _progres и _prowin могут подключаться к нескольким базам данных в режиме self-serving. В режиме self-serving, разделяемая память всех подключенных баз данных должна помещаться в адресное пространство. Когда _progres или _prowin подключается к базе данных через сетевое (socket) подключение, он не подключается к разделяемой памяти этой базы данных.
Как Вы можете видеть, адресное пространство 32-битового процесса должно содержать множество разных вещей, и вы не можете использовать его целиком для буферного пула базы данных.
64-битовые версии исполняемых файлов OpenEdge не подвержены жестким пределам адресного пространства, описанным выше. Жестким по современным стандартам, конечно. На протяжении многих лет это не было проблемой. В Progress версии 5 максимальный размер буферного пула был лишь немного более 32 МБ. В 64-битовых системах вы можете значительно увеличить параметр -B (предполагая, что вы имеете достаточно физической памяти). Это является основным преимуществом использования 64-битовых адресных пространств в системах баз данных. Это имеет свою цену: 64-битовый код немного медленнее и немного больше, чем 32-битовый для многих процессоров, но маловероятно, что вы заметите разницу.
Если вы запускаете базу данных под управлением 64-битового сервера базы данных OpenEdge, 32-битовые клиенты не смогут подключаться к серверу в режиме self-serving (так как структуры данных в разделяемой памяти не совместимы между 32-битовыми и 64-битовыми версиями OpenEdge), но смогут подключаться через сетевые (socket) подключения.
93. Я увеличил значение -B и теперь я не могу подключиться к базе данных. Почему?
Потому что вы превысили предел 32-битового адресного пространства, который обсуждался в предыдущем вопросе, или 32-битовое адресное пространство вашего клиента слишком фрагментировано, что будет обсуждаться в следующем вопросе. Если вы видите сообщения об ошибках типа «(1175) Maximum number of shared-memory segments per process exceeded» или «(1176) The data space of the process is not enough for the shm segment», когда вы подключаетесь в режиме self-serving, то это наиболее вероятная причина.
94. Какое значение следует установить для параметра -shmsegsize?
Вы должны использовать значение по умолчанию, если вы не столкнулись с проблемами. В версии 10.1B и более поздних изменился способ управления разделяемой памятью, что позволяет использовать меньшее число больших сегментов, и для 32-битового OpenEdge в некоторых операционных системах (например, AIX) общий объем доступной разделяемой памяти увеличился.
Когда используются большие сегменты, существует вероятность, что 32-разрядный self-serving клиент OpenEdge может быть не в состоянии подключиться к базе данных, поскольку адресное пространство клиента слишком фрагментировано, и не существует достаточно больших неиспользуемых блоков, доступных для сегментов общей памяти. Вы можете получить сообщение об ошибке типа «(1176) The data space of the process is not enough for the shm segment» или другое сообщение об ошибке, связанное с разделяемой памятью. В этом случае вы можете избежать проблемы, используя меньшее значение (например, 128) для параметра -shmsegsize.
Вы также можете избежать подобных проблем, используя 64-битовую версию OpenEdge RDBMS. В 64-битовых версиях OpenEdge вам обычно не требуется использовать конфигурационный параметр -shmsegsize.
95. Какое значение является наилучшим для конфигурационного параметра -Mxs?
Нулевое, но все же прочитайте ответ дальше. База данных вычисляет необходимое количество разделяемой памяти при запуске. Размер большинства структур данных, которые находятся в области разделяемой памяти, определяется на основе значений различных параметров конфигурации и размеров блоков, и пространство для них выделяется во время инициализации. Однако, некоторые структуры, связанные с операциями индексирования и определением обязательных для заполнения полей, размещаются динамически при необходимости. Объем дополнительной памяти, требующийся для этих динамически размещаемых структур, точно не известен и может быть только оценен.
По умолчанию значение оценки требующегося объема динамически распределяемой разделяемой памяти равно (16384 + (nusers * 400)) байтов для 64-битовых версий OpenEdge и (16384 + (nusers * 300)) байтов для 32-битовых версий («nusers» здесь равно значению стартового параметра -n).
Параметр -Mxs существует для того, чтобы вы могли выделить дополнительную память, если оценка окажется слишком низкой.
Если вы столкнулись с переполнением разделяемой памяти и получили сообщение об ошибке «Out of free shared memory. Use -Mxs to increase», то это может быть вызвано следующими причинами:
- Вы имеете больше обязательных для заполнения (mandatory) полей, чем позволяет оценка (для каждой таблицы, имеющей mandatory поля, требуется 48 байтов плюс 12 байтов на каждое mandatory поле);
- Произошла ошибка при вычислении размера разделяемой памяти;
- Произошло переполнение таблицы блокирования.
Если причина в переполнении таблицы блокирования, правильное решение заключается либо в увеличении размера таблицы блокирования, либо в изменении вашего кода так, чтобы использовать меньше количество одновременных блокировок. В противном случае вы можете использовать конфигурационный параметр -Mxs для увеличения объема выделяемой памяти.
96. Каковы пределы разделяемой памяти для 64-битовых версий OpenEdge?
Предполагая, что у вас имеется достаточно физической памяти и операционная система позволяет ее использовать, вы можете иметь до 256 сегментов разделяемой памяти, и каждый сегмент может иметь размер до 32 гигабайт. В операционных системах Linux и UNIX, параметр ядра SHMMAX определяет максимальный размер сегмента разделяемой памяти. Вам может потребоваться увеличить его, если он слишком мал. Если вы увеличиваете значение SHMMAX, вам также может потребоваться увеличить значение параметра SHMALL. Параметр SHMALL должен быть равен (SHMMAX / page-size)-страниц. Размер страницы зависит от системы, обычное значение равно 4096.