我遇见的问题:
最近一台服务器内存60G,交换分区30G。
最近平时负载内存使用59G 交换分区 使用10G
服务器上有1个oracle数据库 数据库的SGA设置为30G pga设置6G
每个连接占用内存基本在5M,这样1000个连接只占用6G内存,SGA内存30G,35G,而总共内存有60G,怎么会内存不足呢?
top查看大部分进程被oracle占用
最后试着用cat /proc/meminfo查看内存时
PageTables: 59004 kB
PageTables占用的内存居然高达59G。PageTables是Linux下虚拟内存到物理内存中做映射时映射表占用的空间,这个映射表居然占用了这么大的内存。
为了解决这个问题,想到了Linux的大页管理,正常的页大小为4k,而大页管理的页大小为2M,通过大页管理后,映射表占用的空间将会大大减少。
转载他人经验;
在Linux中配置hugepage可以提高oracle的性能,减少oracle sga的页交换
为什么 使用大页?
LINUX内存的默认块大小是4K
如果SGA为:128G
select 128*1024*1024/4 from dual;33554432个(三千多万),
select 128*1024/2 from dual; 65536个
每个内存页,有一个页表项(大概10个字节),记录页的状态、位置
默认块大小是4K时--页表大小:320M。
在大页下2M时,页表只占.625M
在Linux中,每个进程页表独立,有各自的页表。
如果有1000个进程:1000*320M大约是320G。
而1000个进程使用大页:1000*0.625=625M
设置了大页,但没被Oracle使用,原因只有两个:
(1)、SGA_MAX_SIZE超过了大页
(2)、没有设置内存锁
内存:是进程活动的舞台,ORACLE数据库在startup时会自动去查找是否设置有大页。
如有,在大页中分配SGA。
如没有,则正常使用默认数据块大小启动。
#############
设置大页步骤:
1.查看系统当前的大页使用情况:
[oracle@bys3 ~]$ cat /proc/meminfo |grep Huge
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize:2048 kB--大页大小是2M
BYS@ bys3>show parameter sga_max --查看数据库SGA大小--我的实验机
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sga_max_size big integer 216M
2. 设置大页的数量
--这里是200个*2M=400M,SGA最大216M,大页的内存要大于SGA大小,才能被ORACLE使用,所以我设置200个。
vi /etc/sysctl.conf
在里面增加一行:
vm.nr_hugepages=200
保存之后执行:
sysctl -p
查看: --如果HugePages_Free:未到200,多执行几次sysctl -p
[root@bys3 ~]# cat /proc/meminfo |grep Huge
HugePages_Total: 200
HugePages_Free: 200
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
3.还需要设置内存锁:-- memlock数量要大于大页的数量--设置为-1,不限制。
vi /etc/security/limits.conf
oracle soft memlock -1
oracle hard memlock -1
[root@bys3 ~]# ulimit -l
3500000 -----这个数字就是针对大页数量的限制的,足够用。
4.重启数据库,大页已经被ORACLE用上了。
SYS@ bys3>shutdown immediate;
SYS@ bys3>startup
重启数据库过程中不断执行;cat /proc/meminfo |grep Huge,能看到HugePages_Free:的数量不断减少,说明大页正在被使用。
[root@bys3 ~]# cat /proc/meminfo |grep Huge
HugePages_Total: 200
HugePages_Free: 101
HugePages_Rsvd: 10
HugePages_Surp: 0
Hugepagesize: 2048 kB