HPE Community read-only access December 15, 2018
This is a maintenance upgrade. You will be able to read articles and posts, but not post or reply.
Hours:
Dec 15, 4:00 am to 10:00 am UTC
Dec 14, 10:00 pm CST to Dec 15, 4:00 am CST
Dec 14, 8:00 pm PST to Dec 15, 2:00 am PST
System Administration
cancel
Showing results for 
Search instead for 
Did you mean: 

large number of private memory mapped allocations

 

large number of private memory mapped allocations

On our Superdome running HP-UX 11.31 we have a large (1.4+ TB) Oracle database (9.2.0.8). Occaionally an Oracle forms process causes the oracle DB process to begin allocating memory as private memory mapped until all memory (ie. swap) is exhausted. Glance (C.04.70.001) keeps showing new entries like:
MEMMAP/Priv 1 64.0mb 64.1mb 0kb

It appears that Oracle is able to do this without triggering any kernel limits (eg. maxdsize, etc.) because these show up as "Other" instead of text,data,stack, or shmem quadrants (when did we end up with a 5th quadrant?!?).

Has anyone experiences this before? Apparently there is an Oracle patch to fix the problem, but our DBAs want to know (as do we) why no system limit was able to prevent this from exhausting swap which resulted in other processes being affected.

Any input would be most appreciated

Thanks.

Ted Fisher
Dana Corp.

7 REPLIES
Don Morris_1
Honored Contributor

Re: large number of private memory mapped allocations

Data and stack are both in the same quadrant.

There is no fifth quadrant (except on IPF where the Uarea is in Octant 5 for 32-bit... but you didn't need to know that).

And no -- private anonymous mmap is not limited by maxdsiz. It _is_ limited along with everything else by the RLIMIT_AS (total Address Space consumed) rlimit. Whether that's easily set by the shell is a different ballgame, but setrlimit() in a process which then started a shell/your Oracle scripts would work for getting it inherited by Oracle.

That is _total_, though -- so you need to be sure to account for the SGA, etc.

Re: large number of private memory mapped allocations

Thanks for the info Don. I'm confused about the memory quadrants though. HP has had three limits for the separate quadrants (along with their 64 bit counterparts): maxdsiz, maxssiz, and maxtsiz for the data, stack, and text segments. Then shmmax should cover the fourth quadrant (it seems). The memory being allocated by the Oracle process are falling to this "other" region which appears to fall below the existing limits. Also, if data and stack are in the same quadrant then why does HP have separate limits for them? Our DBAs want to know why no kernel limits are preventing the rogue oracle process from allocating memory excessively.
Don Morris_1
Honored Contributor

Re: large number of private memory mapped allocations

No, the limits are for data types. (shmmax is only part of the data in the third/fourth quadrant and may even be in the first or second quadrant in some layouts). Quadrants are orthogonal.

Memory Quadrants are an artifact of processor virtual address management. HP-UX on both PA and Itanium forms page table addresses (also known as Global Virtual Address [GVA]) using a space.offset system. The hardware architecture determines the allowed offset range per space (so how much virtual address space is tracked by each space value).

The offsets on PA 64-bit cover the total global address space using 4 spaces [and hence are still Quadrants]. The offsets on IPF cover it with 8 spaces [and are called octants, though folks still may say "the private quadrant" just for commonality/simplicity]. 32-bit PA and IPF both obviously are working with a much smaller view of the global address space, but for simplicity / backward compatibility still use 4 spaces for User objects and hence are called Quadrants.

What data is in _each_ quadrant is a function of the Address Space layout of the process. The default is that Text is in Quadrant 0, all Private data (Heap, MMF, Stack, etc.) is in Quadrant 1 and Shared objects (SysV Shmem, Shared MMF, etc.) are in Quadrants 2 _and_ 3. Quadrant 3 in 32-bit space is special because it is the default for shared objects flagged as "Global" meaning that everyone is likely to want to attach to them (like libc, for example).

But that's only the default -- there are other address space layouts like MPAS [all 4 quadrants are Private, Sharing is done via Alias translations on IPF], the various Magic flavors where Text and Data/Private objects both start in Quadrant 0, the stack is in Quadrant 1 (more Private space), and the whole Memory Windows issues where Quadrant 3 can become private to the process or private to a group of processes (shared between them), etc.

The limits for the various data types are for a few reasons:

1) Memory leaks on the heap are a very easy way to eat all the swap space on the box. Hence, maxdsiz.

2) Stack leaks are something to watch for in general as a swap/memory leak -- *plus* due to the way the stack grows, HP-UX has to pre-reserve the virtual address space for the stack from the same area used by the Heap and these private mmap objects, etc. Setting the limit up front allows control over the available space in the _rest_ of the private area (which may be one quadrant or may be more depending on the layout).

3) As I said, the RLIMIT_AS is there to catch other objects, so I disagree that there is "no kernel limit to prevent this". The limit ability is there -- this simply is not limited by default with a global tunable as some of the other rlimits are. You may choose to use your support channel to request one, and we can see where that goes. I will say that this would get interesting in that this sort of mmap area can be a pthread stack or other object, so arbitrarily limiting them on a system basis is more likely than not going to generate some confusion when things fail that didn't before.

Re: large number of private memory mapped allocations

Thanks much for the additional detail Don. Your final comment hits the real issue. Creating limits on the process may have an unintended impact (ie. something fails due to a limit that is more restrictive than desired). But, without a limit a single process can allocate memory until there is no more swap and then other processes fail. It appears that there is no way to prevent a single (rogue) process from affecting the entire system even though it seems that should be preventable. Am I wrong here?
Don Morris_1
Honored Contributor

Re: large number of private memory mapped allocations

Have any rogue process launching users (or potential ones) login in through a program which does a setrlimit() for RLIMIT_AS to a value suitably less than total swap reservations available [memory and device] is about all you could do.

And, like maxdsiz/maxssiz/etc. -- there's the multiplicative property:

maxdsiz isn't enough if nproc means a rogue process can fork itself enough times with each fork then claiming swap up to maxdsiz. Same for maxssiz.

shmmax doesn't mean that much by itself without accounting for shmmni as well.

There are doubtless other ways to abuse things (like eating up file systems, etc.) -- this is why resource limits exist. Data and stack simply have globally tunable defaults where this one doesn't, so if you want to enforce it -- you need to set up that enforcement.

Re: large number of private memory mapped allocations

An update on this - I opened a case with HP support for this which they tried to close saying that this is an Oracle issue. I replied with this:
from a systems/OS perspective we should be able to prevent a single process, whether Oracle or whatever else from consuming excessive memory. That is the purpose of the kernel limits maxdsiz, maxssiz, maxtsiz (and the corresponding 64 bit equivalents). They are to prevent a single process from adversely affecting the whole system (ie. all other processes). However, the benfit of those limits gets lost if there is some other method to allocate memory (ie. mmap) that is not subject to any kind of limit to prevent the same type of problems that the other kernel limits provides. I would expect that somewhere within HP-UX there is a way to prevent for any kind of memory access what is prevented by maxdsiz for example (since the mmap created segments are not protected by maxdsiz). I have heard that RLIMIT_AS could be used to limit memory consumption in a way similar to maxdsiz but affecting all memory used by a process. However, I cannot find how this should be implemented for this purpose. I am looking for HP to give direction on how to control memory consumption since maxdsiz alone no longer fullfills that need. Please to not archive this case as this is soemthing cannot get resolved elsewhere.

HP replied as follows:
As you have already been told, the RLIMIT_AS can be used to limit the total memory a process can use but this is set into the internal code of the application/process through a system call. See setrlimit(2)

The setrlimit system call limits the consumption of a variety of resources by the calling process, including the total memory of the process. See below:

RLIMIT_AS
This is the maximum size of a process's total available memory, in bytes. If this limit is exceeded, the brk(), malloc(), mmap(), and sbrk() functions will fail with errno set to ENOMEM. In addition, the automatic stack growth will fail with the effects outlined above.
On the other hand, please be aware that this need to be implemented on your Oracle application and therefore needs to be addressed by Oracle support.
Finally, I strongly recommend you to check with Oracle support if there are any parameters that need to be changed for your application to work correctly since this could be impacting the overall performance of your application and the entire system.

Again, I don't believe that this should be passed to the software vendor since the existing OS limits demonstrate the need to llimit an individual process from affecting all others. So I replied:
While maxdsiz and the other related kernel parms provide a limit that can be set at the system level regardless of the nature of the application there is nothing that can be done in a similar way to prevent excessive calls to mmap() from allocating huge amounts of memory.

If that is the case this is a serious flaw in the OS. Provision of kernel limits for certain types of memory allocation (maxdsiz, etc.) without doing so for others leaves the system in a precarious state. We have, in theory limits that prevent any given process from affecting all other processes on the system, and yet those limits are insufficient. How should we formally request that HP address this shortcoming in the OS?

I believe that if HP-UX includes maxdsiz (as it should) that the capability to limit a single process access to meory allocation should be comprehensive. Partil limits are incomplete and therefore flawed.
Any thoughts about this?
Don Morris_1
Honored Contributor

Re: large number of private memory mapped allocations

I've told you how you can use the rlimit to limit things.

Write a program that does setrlimit(RLIMIT_AS) to whatever you want.

Have that program fork and exec the desired shell, then exit. [Shell gets the lower value].

Set the program to the login program of non-root users.

Once you've done this, all your non-root users will get the lower limit automatically when they log in. Only root can raise the hard limit, so they're stuck with it. (One advantage to this over a tunable is that you could only limit some users if you want...)

Yes -- a system-wide tunable is an easier mechanism, I completely understand that you want this as an enhancement. But it is not the case that you can not limit your users.