一条关于swap争用的报警邮件分析(一)(r7笔记第28天)

最近这些天有一台服务器总是会收到剩余swap过低的告警。 邮件内容大体如下: ############ ZABBIX-监控系统: ------------------------------------ 报警内容: Lack of free swap space on ora_test_s2_yangjr@10.127.2.xxxx ------------------------------------ 报警级别: PROBLEM ------------------------------------ 监控项目: Free swap space in %:21.59 % ------------------------------------ 报警时间:2015.11.23-04:10:57 简单查看了一下服务器配置,发现是一个32G的服务器,swap空间为8G,目前已经使用6G多。架构如下所示

top - 11:56:03 up 152 days, 2:06, 1 user, load average: 0.53, 0.34, 0.27 Tasks: 338 total, 1 running, 326 sleeping, 0 stopped, 11 zombie Cpu(s): 5.6%us, 0.0%sy, 0.0%ni, 94.4%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 32949076k total, 32846716k used, 102360k free, 237324k buffers Swap: 8385920k total, 6427096k used, 1958824k free, 28360876k cached 对于这个,简单分析了一下,原来这台服务器上再运行两个数据库实例 oracle 5606 1 0 Jun24 ? 00:01:12 ora_smon_ctest oracle 10533 1 0 Jun27 ? 00:01:11 ora_smon_catest oracle 21950 21560 0 17:54 pts/0 00:00:00 grep smon 从smon初始化的时间来看,这两个数据库实例大概是在7月底启动的,时间有一些先后。 这两个库是11g的DG环境。所以平时主要是会有归档的接收和应用。 为什么会发生swap争用呢,首先想到的就是内存组件的设置问题,是不是设置过大,导致没有富裕的内存资源可用了。 查看数据库实例ctest SQL> show parameter sga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 12032M sga_target big integer 12032M SQL> show parameter pga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ pga_aggregate_target big integer 4010M 所以对于ctest sga+pga=12G+4G=16G,大体如此。 对于数据库实例catest,内存组件大小为; SQL> show parameter sg NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ lock_sga boolean FALSE pre_page_sga boolean FALSE sga_max_size big integer 20G sga_target big integer 20G SQL> show parameter pga NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ pga_aggregate_target big integer 8530M 所以简单相加就是20G+8G=28G 如此一来,28G+16G=44G,而内存资源只有32G,那剩下的12G是怎么来的。如果排除法,也就只有swap了。 当然数据库层面没有任何的异常,也没有限制sga无法设置成功之类的问题。听起来倒也相安无事。 查看v$dynamic_components得到的信息如下: catest的内存组件大小为:2G+18G=20G

$sh showbuffer.sh
[oracle@scycard2 dbm_lite]$ sh showbuffer.sh
COMPONENT                       CURRENT_M      MIN_M      MAX_M SPECCIFIED_M LAST_OPER LAST_OPER_TYP  GRANULE_M
------------------------------ ---------- ---------- ---------- ------------ --------- ------------- ----------
shared pool                          2304       2304       2304            0           STATIC                64
large pool                             64         64         64            0           STATIC                64
java pool                              64         64         64            0           STATIC                64
streams pool                            0          0          0            0           STATIC                64
DEFAULT buffer cache                17920      17920      17920        15360           INITIALIZING          64
 
ctest的内存组件大小为:
$ sh showbuffer.sh
COMPONENT                       CURRENT_M      MIN_M      MAX_M SPECCIFIED_M LAST_OPER LAST_OPER_TYP  GRANULE_M
------------------------------ ---------- ---------- ---------- ------------ --------- ------------- ----------
shared pool                          1664       1664       1664            0           STATIC                32
large pool                             64         64         64            0           STATIC                32
java pool                              64         64         64            0           STATIC                32
streams pool                            0          0          0            0           STATIC                32
DEFAULT buffer cache                10176      10176      10176            0           INITIALIZING          32
内存组件大小为1.6G+10G约为12G
所以如此一算,刚好和内存的大小一致。看来尽管sga,pga会显示有一个很大的值,其实还是根据实际的内存资源来分配。
这个时候问题就来了,为什么能够设置sga,pga为一个较高的值,而且数据库中似乎能够验证通过。
这个地方也就只能用kernel层面才可以说清了。
cat /etc/sysctl.conf的配置如下,可以看到配置了shmmax为近100G的最大共享内存段,支持的共享内存段的页数也非常高。shmall还是很高的。
fs.aio-max-nr = 1048576
kernel.shmall = 33554432
kernel.shmmax = 107374182400
kernel.shmmni = 4096
查看当前的session设置的shmmax的值。
# more /proc/sys/kernel/shmmax
107374182400
如果查看共享内存段的内容如下:
# ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x74010013 2293760    root      600        4          0                       
0x740182d0 2981889    root      600        4          0                       
0x00000000 4194306    oracle    640        134217728  67                      
0x740182cf 2949123    root      600        4          0                       
0x00000000 4227076    oracle    640        21340618752 67                      
0x538bd97c 4259845    oracle    640        2097152    67                      
0x00000000 3768326    oracle    640        67108864   49                      
0x00000000 3801095    oracle    640        12549357568 49                      
0xaf0a22e4 3833864    oracle    640        2097152    49                      
0x6c0109ec 6455305    zabbix    600        995952     6  
所以内核参数的设置还是存在一定的问题,shmmax可以设置为内存的一半或者更高。一般会尝试用内存的80%等
#kernel.shmall = 33554432
#kernel.shmmax = 107374182400

kernel.shmall = 8388608
kernel.shmmax = 32212254720
比如可以设置为一个相对较大的值,使用getconf PAGE_SIZE得到的页大小一般都是4k.
那么我们来简单规范一下。
ctest数据库实例的设置为:
SQL> alter system set sga_max_size=12G scope=spfile;
System altered.
SQL> alter system set sga_target=12G scope=spfile;
System altered.
SQL> show parameter uniq
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_unique_name                       string      STEST
SQL> show parameter pga
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target                 big integer 4G
pga适度改小一些,然后停备库,听备库还有什么方法论吗,那就是看看session的情况,是否有其它额外的session在运行。
SQL> select username,count(*)from v$session group by username;
USERNAME                         COUNT(*)
------------------------------ ----------
                                       42
PUBLIC                                  5
SYS                                     1

SQL> shutdown immediate       之后就需要使用sysctl -p或者重启服务器的方式来设置生效了。         
没有sysctl -p之前,查看shmmax的设置还是100G
$ more /proc/sys/kernel/shmmax
107374182400
设置生效之后,再来看看swap的情况。发现一下子降下来了。
top - 17:34:47 up 154 days,  7:45,  2 users,  load average: 0.33, 0.32, 0.28
Tasks: 211 total,   1 running, 204 sleeping,   0 stopped,   6 zombie
Cpu(s):  0.3%us,  0.3%sy,  0.0%ni, 99.2%id,  0.2%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  32949076k total,  3464424k used, 29484652k free,   193008k buffers
Swap:  8385920k total,     4352k used,  8381568k free,  2901552k cached
至于swap的监控,可以使用下面的脚本来做一些简单的分析,还算是比较实用的。
因为环境的swap使用很低,所以可以找一台服务器swap相对较高的,然后使用下面的脚本来分析。
#   for i in $( cd /proc;ls |grep "^[0-9]"|awk ' $0 >100') ;do awk  '/Swap:/{a=a+$2}END{print '"$i"',a/1024"M"}' /proc/$i/smaps  2>/dev/null ; done | sort -k2nr | head -10 
19119 1503.39M
7520 50.7617M
18216 38.6172M
18218 26.3945M
18212 22.0938M
32219 11.8242M
18174 11.2539M
18286 7.8125M
18214 6.90625M
12507 5.17578M
可以看到哪个进程占用了较高的temp资源情况。
那么这儿问题如何验证,是否内核参数shmmax,shmall设置过高,会有sga_target设置的错觉。
SQL> show parameter sga
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
lock_sga                             boolean     FALSE
pre_page_sga                         boolean     FALSE
sga_max_size                         big integer 45G
sga_target                           big integer 45G
使用top -c查看的结果如下:
Tasks: 253 total,   1 running, 252 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  16319100k total,  5582080k used, 10737020k free,   429292k buffers
Swap: 16777200k total,    12956k used, 16764244k free,  4402968k cached
ipcs的情况可以参见下面的结果。
$ ipcs -m
------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 6062080    oracle     640        67108864   17                      
0x00000000 6094849    oracle     640        12515803136 17                      
0xfadedb24 6127618    oracle     640        2097152    17                      
0x00000000 6848515    oracle     640        268435456  27                      
0x00000000 6881284    oracle     640        24024973312 27                      
0x00000000 6914053    oracle     640        24024973312 27                      
0xc3655edc 6946823    oracle     640        2097152    27  

原文发布于微信公众号 - 杨建荣的学习笔记(jianrong-notes)

原文发表时间:2015-11-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java学习网

10 个影响程序性能的Hibernate 错误,学会让你少走弯路

我在很多应用程序中修复过性能问题,其中大部分都是由同样的错误引起的。修复之后,性能变得更溜,而且其中的大部分问题都很简单。所以,如果你想改进应用程序,那么可能也...

34350
来自专栏c#开发者

分析Oracle数据库日志文件(1)

分析Oracle数据库日志文件(1) 一、如何分析即LogMiner解释 从目前来看,分析Oracle日志的唯一方法就是使用Oracle公司提供的LogMin...

49150
来自专栏程序小工

windows7使用Sphinx+PHP+MySQL详细介绍

由于业务需要,需要做类似淘宝商城商品检索的功能,对于数据量很大的情况,MySQL 查询的效率损耗很大,需要使用专门的索引引擎进行搜索查询,实现功能,对于和 PH...

55010
来自专栏数据和云

【循序渐进Oracle】Oracle的逻辑备份与恢复

编辑手记:针对最近发生的炉石及GitLab事件,我们不得不再次强调备份的重要性。DBA的四大守则,第一条就是备份重于一切。年初做好备份,愿你的系统17无恙。 本...

47580
来自专栏Porschev[钟慰]的专栏

Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

前言   前面一有写到一篇Node.js+Express构建网站简单示例https://cloud.tencent.com/developer/article/...

2.3K90
来自专栏乐沙弥的世界

RMAN 数据库克隆文件位置转换方法

      在使用RMAN克隆数据库时,如果辅助数据库(新数据库)使用了与目标数据库(原数据库)使用了不同的路径,那么就存在位置转换的问题。在Oracle中,控...

8310
来自专栏MasiMaro 的技术博文

数据更新接口与延迟更新

title: 数据更新接口与延迟更新 tags: [OLEDB, 数据库编程, VC++, 数据库] date: 2018-02-12 14:29:35 ...

20220
来自专栏张戈的专栏

常用MySQL语句搜集整理

折腾 WordPress 多少要接触到 MySQL 的一些操作,比如,玛思阁之前重装 postview 插件后发现所有的 view 数据都被清空了!只好到 ph...

40750
来自专栏FreeBuf

Fuzz自动化Bypass软WAF姿势

0×00 前言 在我刚接触安全这块时候遇到注入有WAF的网站时候无从下手,寻找各种有关绕过waf的文章,在网页浏览器上使用SQL语句为了绕过WAF变了个法加了些...

1.1K100
来自专栏数据和云

【Oracle字符集】识别及转换导出文件的字符集

编辑手记:很多人在进行数据库导入导出操作的时候会遇到字符集的问题,今日拣选了 《循序渐进Oracle》一书中的相关章节,希望对初学Oracle的朋友有所帮助。 ...

51440

扫码关注云+社区

领取腾讯云代金券