查看linux下的Oracle共享內存段
[oracle@oradb ~]$ ipcs -m
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 1835009 oracle 640 100663296 180
0x00000000 1867778 oracle 640 1174405120 180
0x00000000 1900547 oracle 640 1174405120 180
0x00000000 1933316 oracle 640 1174405120 180
0x00000000 1966085 oracle 640 1174405120 180
0x00000000 1998854 oracle 640 1174405120 180
0x00000000 2031623 oracle 640 1174405120 180
0x00000000 2064392 oracle 640 1174405120 180
0x00000000 2097161 oracle 640 1174405120 180
0x00000000 2129930 oracle 640 1174405120 180
0x00000000 2162699 oracle 640 1174405120 180
0x00000000 2195468 oracle 640 1174405120 180
0x00000000 2228237 oracle 640 1174405120 180
0x00000000 2261006 oracle 640 1174405120 180
0x00000000 2293775 oracle 640 1174405120 180
0x00000000 2326544 oracle 640 637534208 180
0x73c02390 2359313 oracle 640 2097152 180
可以看出Oracle的內存共享段,分成了10余個內存共享段。
為什么會是1174405120
字節呢?
通過查詢
[oracle@oradb ~]$ cat /etc/sysctl.conf |grep shmmax
kernel.shmmax = 1200000000
[oracle@oradb ~]$ cat /etc/sysctl.conf |grep shmall
kernel.shmall = 10388608
可以知道
shmmax
是核心參數中最重要的參數之一,用於定義單個共享內存段的最大值。
64 位 linux 系統:可取的最大值為物理內存值 -1byte ,建議值為多於物理內存的一半,一般取值大於 SGA_MAX_SIZE 即可,可以取物理內存 -1byte 。
* 內存為 12G 時,該值為 12*1024*1024*1024-1 = 12884901887
* 內存為 16G 時,該值為 16*1024*1024*1024-1 = 17179869183
* 內存為 32G 時,該值為 32*1024*1024*1024-1 = 34359738367
* 內存為 64G 時,該值為 64*1024*1024*1024-1 = 68719476735
* 內存為 128G 時,該值為 128*1024*1024*1024-1 = 137438953471
shmall
該參數控制可以使用的共享內存的總頁數。 Linux 共享內存頁大小為 4KB, 共享內存段的大小都是共享內存頁大小的整數倍。
一個共享內存段的最大大小是 16G ,那么需要共享內存頁數是 16GB/4KB==4194304 (頁),
- 當內存為 12G 時, kernel.shmall = 3145728
- 當內存為 16G 時, kernel.shmall = 4194304
- 當內次為 32G 時, kernel.shmall = 8388608
- 當內存為 64G 時, kernel.shmall = 16777216
- 當內存為 128G 時, kernel.shmall = 33554432
調節kernel.shmall和kernel.shmmax的原因
如果我們的sga為16GB。物理服務器是32GB。那么這兩個參數設置值如下:
kernel.shmall = 8388608
kernel.shmmax = 17179869184
為什么要設置大一點的shmall和shmmax,因為想讓Oracle的一個instance包含在一個共享內存段中。
可以看,上述服務器的共享內存段分配了14個,這樣會出現內存地址斷層(GAP)。當數據庫進行IPC通信時,會出現跨共享內存段的內部數據交互。這樣會降低內存段間的數據交互效率。
因此,1個共享內存段包含數據庫instance實例所需要的內存,可以減少跨內存段的交互,提高數據庫的性能。