您的位置:首页 > 数据库

shmall参数设置不当引起数据库启动时报out of memory报错

2013-12-26 15:05 423 查看
shmall是全部允许使用的共享内存大小,单位是页,可以通过getconf PAGESIZE来获取每页的大小,一般为4096字节
shmmax是单个段允许使用的最大共享内存大小
可以使用 ipcs -l 看到shmall,shmmax设置的值。ipcs -u可以看到实际使用的情况。
oracle@fly007:~> ipcs -l
------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 4194304 //shmmax为4G
max total shared memory (kbytes) = 8388608  //shmall为8G
min seg size (bytes) = 1
------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
max ops per semop call = 100
semaphore max value = 32767
------ Messages: Limits --------
max queues system wide = 16
max size of message (bytes) = 65536
default max size of queue (bytes) = 65536
oracle@fly007:~> ipcs -u
------ Shared Memory Status --------
segments allocated 3
pages allocated 3
pages resident  3
pages swapped   0
Swap performance: 0 attempts     0 successes
------ Semaphore Status --------
used arrays = 4
allocated semaphores = 488
------ Messages: Status --------
allocated queues = 0
used headers = 0
下面为shmall和shmmax参数相关的案例
环境介绍:
操作系统:suse 11 sp1 64bit
数据库版本:oracle 11g R1 64bit
主机内存:94G
1、主机内存94G,更改数据库的sga_target为40G,重启数据库生效该参数,在启动过程报ORA-27102: out of memory错误:
SQL> alter system set sga_target=40G scope=spfile;
System altered.
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORA-27102: out of memory
Linux-x86_64 Error: 28: No space left on device
2、当前的shmall和shmmax参数设置如下:
fly007:~ #  cat /etc/sysctl.conf | grep -E 'shmall|shmmax'
kernel.shmall = 4194304
kernel.shmmax = 50708928512
3、shmmax是单个段允许使用的最大共享内存大小,单位是字节,一般shmmax>sga_target的大小,这样整个sga就在一个共享内存段,这是推荐的做法,我们这设置的shmmax为物理内存的一半,也就是47G,大于sga_target=40G,该参数设置正确
fly007:~ #  cat /etc/sysctl.conf | grep shmmax
kernel.shmmax = 50708928512
fly007:~ #  echo "50708928512/1024/1024/1024" | bc
47
4、shmall是全部允许使用的共享内存大小,注意单位是页,通过getconf PAGESIZE命令得到每页的大小为4096字节,也是就4194304*4096/1024/1024/1024=16G
fly007:~ # getconf PAGESIZE
4096
fly007:~ #  cat /etc/sysctl.conf | grep shmall
kernel.shmall = 4194304
fly007:~ # echo "4194304*4096/1024/1024/1024" | bc
16
5、全部允许使用的共享内存大小为16G<40G,所以启动数据库报错了,shmall参数可以这样设置,shmall=shmmax/4096=50708928512/4096=12380109
6、设置shmall参数为12380109,生效该设置,启动数据库,正常启动
fly007:~ # cat /etc/sysctl.conf | grep shmall
kernel.shmall = 12380109
fly007:~ # sysctl  -p
fly007:~ # su - oracle
oracle@fly007:~> sqlplus /nolog
SQL*Plus: Release 11.1.0.7.0 - Production on Wed Dec 25 23:45:04 2013
Copyright (c) 1982, 2008, Oracle.  All rights reserved.
SQL> conn /as sysdba
Connected to an idle instance.
SQL> startup
ORACLE instance started.
Total System Global Area 4.8103E+10 bytes
Fixed Size                  2170704 bytes
Variable Size            1.9998E+10 bytes
Database Buffers         2.8052E+10 bytes
Redo Buffers               50548736 bytes
Database mounted.
Database opened.
SQL>
以下关于shmall和shmmax内容来自:http://dbasolutions.wikispaces.com/SHMMAX+and+SHMALL

Configuring SHMMAX and SHMALL for Oracle in Linux
======
SHMMAX and SHMALL are two key shared memory parameters that directly impact’s the way by which Oracle creates an SGA. Shared memory is nothing but part of Unix IPC System (Inter Process Communication) maintained by kernel where multiple processes share a single chunk of memory to communicate with each other.
While trying to create an SGA during a database startup, Oracle chooses from one of the 3 memory management models a) one-segment or b) contiguous-multi segment or c) non-contiguous multi segment. Adoption of any of these models is dependent on the size of SGA and values defined for the shared memory parameters in the linux kernel, most importantly SHMMAX.
SHMMAX and SHMALL -
SHMMAX is the maximum size of a single shared memory segment set in “bytes”.
silicon:~ # cat /proc/sys/kernel/shmmax
536870912
SHMALL is the total size of Shared Memory Segments System wide set in “pages”.
silicon:~ # cat /proc/sys/kernel/shmall
1415577
The key thing to note here is the value of SHMMAX is set in "bytes" but the value of SHMMALL is set in "pages".

What’s the optimal value for SHMALL?
As SHMALL is the total size of Shard Memory Segments System wide, it should always be less than the Physical Memory on the System and should also be less than sum of SGA’s of all the oracle databases on the server. Once this value (sum of SGA’s) hit the limit, i.e. the value of shmall, then any attempt to start a new database (or even an existing database with a resized SGA) will result in an “out of memory” error (below). This is because there won’t be any more shared memory segments that Linux can allocate for SGA.
ORA-27102: out of memory
Linux-x86_64 Error: 28: No space left on device.
So above can happen for two reasons. Either the value of shmall is not set to an optimal value or you have reached the threshold on this server.
Setting the value for SHMALL to optimal is straight forward. All you want to know is how much “Physical Memory” (excluding Cache/Swap) you have on the system and how much of it should be set aside for Linux Kernel and to be dedicated to Oracle Databases.
For e.g. Let say the Physical Memory of a system is 6GB, out of which you want to set aside 1GB for Linux Kernel for OS Operations and dedicate the rest of 5GB to Oracle Databases. Then here’s how you will get the value for SHMALL.
Convert this 5GB to bytes and divide by page size. Remember SHMALL should be set in “pages” not “bytes”.
So here goes the calculation.

Determine Page Size first, can be done in two ways. In my case it’s 4096 and that’s the recommended and default in most cases which you can keep the same.
silicon :~ # getconf PAGE_SIZE
4096
or
silicon:~ # cat /proc/sys/kernel/shmmni
4096
Convert 5GB into bytes and divide by page size, I used the linux calc to do the math.
silicon:~ # echo "( 5 * 1024 * 1024 * 1024 ) / 4096 " | bc -l1310720.00000000000000000000

Reset shmall and load it dynamically into kernel
silicon:~ # echo "1310720" > /proc/sys/kernel/shmall
silicon:~ # sysctl –p Verify if the value has been taken into effect.
silicon:~ # sysctl -a | grep shmallKernel.shmall = 1310720
Another way to look this up is
silicon:~ # ipcs -lm
------ Shared Memory Limits --------max number of segments = 4096 /* SHMMNI */max seg size (kbytes) = 524288 /* SHMMAX */max total shared memory (kbytes) = 5242880 /* SHMALL */min seg size (bytes) = 1

To keep the value effective after every reboot, add the following line to /etc/sysctl.conf

echo “kernel.shmall = 1310720” >> /etc/sysctl.conf
Also verify if sysctl.conf is enabled or will be read during boot.
silicon:~ # chkconfig boot.sysctlboot.sysctl on
If returns “off”, means it’s disabled. Turn it on by running
silicon:~ # chkconfig boot.sysctl onboot.sysctl on
What’s the optimal value for SHMMAX?
Oracle makes use of one of the 3 memory management models to create the SGA during database startup and it does this in following sequence. First Oracle attempts to use the one-segment model and if this fails, it proceeds with the next one which's the contiguous multi-segment model and if that fails too, it goes with the last option which is the non-contiguous multi-segment model.
So during startup it looks for shmmax parameter and compares it with the initialization parameter *.sga_target. If shmmax > *.sga_target, then oracle goes with one-segment model approach where the entire SGA is created within a single shared memory segment.
But the above attempt (one-segment) fails if SGA size otherwise *.sga_target > shmmax, then Oracle proceeds with the 2nd option – contiguous multi-segment model. Contiguous allocations, as the name indicates are a set of shared memory segments which are contiguous within the memory and if it can find such a set of segments then entire SGA is created to fit in within this set.

But if cannot find a set of contiguous allocations then last of the 3 option’s is chosen – non-contiguous multi-segment allocation and in this Oracle has to grab the free memory segments fragmented between used spaces.
So let’s say if you know the max size of SGA of any database on the server stays below 1GB, you can set shmmax to 1 GB. But say if you have SGA sizes for different databases spread between 512MB to 2GB, then set shmmax to 2Gigs and so on.
Like SHMALL, SHMMAX can be defined by one of these methods..
Dynamically reset and reload it to the kernel..

silicon:~ # echo "536870912" > /proc/sys/kernel/shmmaxsilicon:~ # sysctl –p -- Dynamically reload the parameters.Or use sysctl to reload and reset ..
silicon:~ # sysctl -w kernel.shmmax=536870912
To permanently set so it’s effective in reboots…
silicon:~ # echo "kernel.shmmax=536870912" >> /etc/systctl.conf
Install doc for 11g recommends the value of shmmax to be set to "4GB – 1byte" or half the size of physical memory whichever is lower. I believe “4GB – 1byte” is related to the limitation on the 32 bit (x86) systems where the virtual address space for a user process can only be little less than 4GB. As there’s no such limitation for 64bit (x86_64) bit systems, you can define SGA’s larger than 4 Gig’s. But idea here is to let Oracle use the efficient one-segment model and for this shmmax should stay higher than SGA size of any individual database on the system.
####################################################################################################################################

PURPOSE
Shared memory and semaphores are two important resources for an Oracle
instance on Unix. An instance cannot start if it is unable to allocate what
it needs. This paper primarily discusses the process Oracle goes through to
allocate shared memory and semaphores at instance startup. Other important
points unrelated to startup as well as some troubleshooting information will
be touched upon.
SCOPE & APPLICATION
Understanding Oracle and Shared Memory/Semaphores.

Unix Semaphores and Shared Memory Explained
===============================
General
=======
Shared memory is exactly that - a memory region that can shared between
different processes. Oracle uses shared memory for implementing the
SGA, which needs to be visible to all database sessions. Shared memory
is also used in the implementation of the SQL*Net V1 Fast driver as a
means of communicating between the application and shadow process. On
the RS/6000, each shadow process stores its PGA in a shared memory
segment (however, only the shadow attaches this segment). In the
latter two cases, Oracle allocates the shared memory dynamically as
opposed to the allocation of the SGA, which occurs at instance startup.
This allocation will not be discussed in this paper.
Semaphores can be thought of as flags (hence their name, semaphores).
They are either on or off. A process can turn on the flag or turn it off.
If the flag is already on, processes who try to turn on the flag will
sleep until the flag is off. Upon awakening, the process will
reattempt to turn the flag on, possibly suceeding or possibly sleeping
again. Such behaviour allows semaphores to be used in implementing a
post-wait driver - a system where processes can wait for events (i.e.
wait on turning on a semphore) and post events (i.e. turning of a
semaphore). This mechanism is used by Oracle to maintain concurrency
control over the SGA, since it is writeable by all processes attached.
Also, for the same reasons, use of the Fast Driver requires additional
semaphores. However, these semaphores will be allocated dynamically
instead of at instance startup. This allocation will not be discussed in
this paper.
Instance startup
================
On instance startup, the first things that the instance does is:
-Read the "init<SID>.ora"
-Start the background processes
-Allocate the shared memory and semphores required
The size of the SGA will be calculated from various "init.ora" parameters.
This will be the amount of shared memory required. The SGA is broken into 4
sections - the fixed portion, which is constant in size, the variable portion,
which varies in size depending on "init.ora" parameters, the redo block
buffer, which has its size controlled by log_buffers, and the db
block buffer, which has its size controlled by db_block_buffers.
The size of the SGA is the sum of the sizes of the 4 portions.
There is unfortunately no simple formula for determining the size
of the variable portion. Generally, the shared pool dominates all
other parts of the variable portion, so as a rule of thumb, one can
estimate the size as the value of shared_pool_size (in v6, one can
ignore the size of the variable portion).
The number of semphores required is much simpler to determine. Oracle will
need exactly as many semaphores as the value of the processes "init.ora"
parameter.
Note that the recommended kernel parameter values in the ICG are enough
to support the default database (4M SGA, 50 processes), but may be
insufficient to run a larger instance. With the above estimations and the
information which follows, a DBA should be able to build a kernel with
appropriate settings to support the instance.

Shared memory allocation
========================
Oracle has 3 different possible models for the SGA - one-segment,
contiguous multi-segment, and non-contiguous multi-segment.
When attempting to allocate and attach shared memory for the SGA, it
will attempt each one, in the above order, until one succeeds or raises
an ORA error. On other, non-fatal, errors, Oracle simply cleans up and
tries again using the next memory model. The entire SGA must fit into
shared memory, so the total amount of shared memory allocated under any
model will be equal to the size of the SGA. This calculated value will
be referred to below as SGASIZE.
The one-segment model is the simplest and first model tried. In this
model, the SGA resides in only one shared memory segment. Oracle attempts
to allocate and attach one shared memory segement of size equal to total
size of the SGA. However, if the SGASIZE is larger than the configured
SHMMAX, this will obviously fail (with EINVAL). In this case, the SGA will
need to be placed in multiple shared memory segments, and Oracle proceeds
to the next memory model for the SGA. If an error other than EINVAL occurs
when allocating the shared memory with shmget(), Oracle will raise an
ORA-7306. If the segment was received (i.e. if SHMMAX > SGASIZE), Oracle
attempts to attach it at the start address defined in ksms.o. An error
on the attach will raise an ORA-7307.
With multiple segments there are two possibilities. The segments
can be attached contiguously, so that it appears to be one large
shared memory segment, or non-contiguously, with gaps between the
segments. The former wastes less space that could be used for the stack
or heap, but depending on alignment requirements for shared memory
(defined by SHMLBA in the kernel), it may not be possible.
At this point, Oracle needs to determine SHMMAX so it can determine how many
segments will be required. This is done via a binary search
algorithm over the range [1...SGASIZE] (since Oracle is trying this
model and not the one segment model it must be that SHMMAX<SGASIZE)
The value of SHMMAX calculated will then be rounded to an even page size
(on some machines, possibly to an even 2 or 4 page block).
In the contiguous segment model, Oracle simply divides the SGA into
SGASIZE/SHMMAX (rounded down) segments of size SHMMAX plus another segment
of size SGASIZE modulo SHMMAX. If more than SS_SEG_MAX segments are
required total, an ORA-7329 is raised. It then allocates and attaches
one segment at a time, attaching the first segment at the start address
defined in "ksms.o". Subsequent segments are attached at an address equal
to the previous segment's attach address plus the size of the previous
segment so that they are contiguous in memory.
For example, if SHMMAX is 2M, SGASIZE is 5M, and the start address is
0xd0000000, there would be 3 segments, 2 of 2M and 1 of 1M. They would be
attached at 0xd0000000, 0xd0000800 (0xd0000000+2M), and 0xd0001000
(0xd0000800+2M). If Oracle receives an error allocating a shared memory
segment, an ORA-7336 is raised.
If an error is raised on attaching a shared memory segement, Oracle checks
the system error returned. If it is EINVAL, the attach address used is most
likely badly aligned (not a mulitple of SHMLBA). In this case, Oracle tries
the next model for SGA allocation, non-contiguous segments. Otherwise, an
ORA-7337 is raised.
The last model Oracle will try is the non-contiguous model. Here,
things become a bit more complicated. After calculating SHMMAX, Oracle
first checks to see if it can put the fixed and variable portion into
one shared memory segment just large enough to hold the two portions
If it can, it allocates a segment just big enough to hold both portions.
If it cannot, it will put them each into their own seperate segment just
large enough to hold each portion. If the fixed portion is larger than
SHMMAX, an ORA-7330 will be raised. If the variable portion is larger
than SHMMAX, an ORA-7331 will be raised. Then Oracle computes the number
of redo block buffers it can fit in a segment (rounded down to an
integral number of buffers - buffers cannot overlap segments). An ORA-7332
is raised is SHMMAX is smaller than the size of a redo block.
Similarly, the number of db block buffers per segment is calculated, with an
ORA-7333 raised if SHMMAX is too small to hold one db block. Then Oracle can
compute the total number of segments required for both the redo and database
block buffers. This will be buffers/buffers per segment (rounded down) segments
and one (if necessary) of buffers modulo buffers per segment size, calculated
seperately for both the redo and db block buffers. These segments will be
of a size just large enough to hold the buffers (so no space is wasted).
The total number of segments allocated will then be the number needed for
the fixed and variable portions (1 or 2) plus the number needed for the
redo block buffers plus the number of segments needed for the database block
buffers. If this requires more than SS_SEG_MAX segments, an ORA-7334 is
raised.
Once the number of segments and their sizes is determined, Oracle
then allocates and attaches the segments one at a time; first the fixed
and variable portion segment(s), then the redo block buffer segment(s),
then the db block buffer segment(s). They will be attached non-contiguously,
with the first segment attached at the start address in "ksms.o" and following
segments being attached at the address equal to the attach address of the
previous segment plus the size of the previous segment, rounded up to a
mulitple of SHMBLA.
If Oracle receives an error allocating a shared memory segment, an ORA-7336 is
raised. If an error is raised on attaching a shared memory segement, Oracle
checks the system error returned. If it is EINVAL, normally another model
would be tried, but as there are no more models to try, an ORA-7310 is raised.
Other attach errors raise an ORA-7337.
At this point, we have either attached the entire SGA or returned an
ORA error. The total size of segments attached is exactly SGASIZE;
no space is wasted. Once Oracle has the shared memory attached, Oracle
proceeds to allocating the semaphores it requires.
Semaphore allocation
====================
Semaphore allocation is much simpler than shared memory. Oracle just
needs to allocate a number of semaphores equal to the processes parameter
in "init.ora". PROCESSES will be used to refer to this value. Note on
machines with a post-wait kernel extension, Oracle does not need to allocate
semaphores (because it doesn't need to implement its own post-wait mechanism).
Oracle uses semaphores to control concurrency between all the
background processes (pmon, smon, dbwr, lgwr, and oracle shadows).
Semaphores are also used to control two-task communication between
the user process and shadow process if the fast (shared memory)
driver is used. And in the Unix ports based on MIPS RISC
processors, Oracle uses a special semaphore to perform basic
test & set functions that are not provided by the processor.

本文出自 “斜阳悠悠寸草心” 博客,请务必保留此出处http://fly007.blog.51cto.com/8301004/1345072
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐