AIX虚拟内存管理机制
AIX采用了基于分页的虚拟内存机制。页面一般都是统一大小的(默认页面大小4k,当然也可以启用大页面内存支持,POWER5 芯片支持四种虚拟内存页面的大小:4KB、64KB、16MB 和 16GB),这样可以简化整个的管理算法。页面是基于整个虚拟内存地址空间分割的,一个页面最终可能映射到物理内存,也可能映射到磁盘的交换区(paging space)上。很明显,内存中的页面访问速度要快得多,但是内存大小有限,某些页面将不得不被挤出内存。淘汰页面的算法一般都是基于LRU算法的,通过ps -k可以看到AIX有一个lrud的内核守护进程,就是AIX分页替换守护进程。
AIX将所有的内存页面分成两大类型:
- 工作存储分页(Working storage pages)
- 永久存储分页(Permanent storage pages)
工作存储分页的内容都是易失性的,在磁盘上没有对应的永久存储文件数据,诸如进程数据/堆栈/共享内存/内核数据等,都是这一类的。而永久存储分页其实就是文件数据。分成这两种类型,是因为从内存中淘汰页面时,需要做不同的处理。对于工作存储分页,只要释放掉对应的内存页面(其实就是修改某些标志位)就可以了。而永久存储分页,则需要判断是否有数据修改,没有修改的话,和工作存储分页的处理一样,直接标志回收即可,如果有修改,则需要将相应的修改数据写回磁盘。
而根据缓存的文件的不同,永久存储分页又分成两种,一种就是新的jfs2文件系统和NFS文件系统的文件缓存,叫做客户端分页(Client pages)。而原来老的jfs文件系统的文件缓存页面,就是非客户端页面(Non-client pages)。
上面对于分页的分类法,是根据缓存的数据类型,需要在淘汰时选择不同的处理方式。而AIX在选择哪些页面需要淘汰的时候,却是按照另外一种标准的。根据这个标准,可以将所有分页分成另外两种类型:
- 计算型分页(Computational pages)
- 非计算型分页(Non-computational pages)
首先,所有的工作存储分页都是计算型分页,也就是说,Oracle的PGA/SGA等都是属于计算型分页的。而永久存储分页,则根据缓存的文件的类型,如果是可执行文件,则对应的分页是计算型的,如果是数据文件,则是非计算型的,同一个文件对应的页面,要么全部是计算型,要么全部是非计算型的。显然的,为了提供Oracle等应用的性能,假如需要淘汰页面,优先应当交换非计算型页面。
用Perl的hash数组实现个性化监控
对于DBA来说,一个准确稳定的监控系统,不啻于一柄尚方宝剑。几十上百套系统,如果每天都靠人工来检查,工作量之大无法想象,而且人工也无法做到实时捕获错误。
但是这么多数据库系统,每个库承载的压力不一样,对于整个系统的重要度也不一样,负责的DBA也不可能是同一个人。如果都按同样的KPI同样的门限来做监控,则有些重要的系统可能无法准确的告警,有些不重要的系统却又会频繁误报。
比如系统的load,有些核心库由于采用了比较高端的硬件,即使一直在20~30左右都是正常的,而一些边缘的库则可能超过5就比较危险了,所以对于load,不同的库必须设置不同的检查门限。
如果要通过shell脚本来实现这个需求,可能需要写一堆的if或者case判断,一旦要做配置变更就十分的头疼。不过perl的hash数组可以很好的解决这个问题。
# creator: NinGoo
############################################################
use strict;
# 配置各主机各KPI的检查门限
# 这里配置了两个门限值,达到第一个值发IM提醒,达到第二个值发手机短信
# server, load1 load2
my %cutoff=("db1", [ 30, 40 ],
"db2", [ 20, 35 ],
"db3", [ 10, 18 ]
);
# 配置各个门限值的数组中的位置,这样在以后即使修改门限的位置,也不需要修改功能代码
# 将配置和功能分开,将极大的简化后续维护工作
my ($load1,$load2)=(0,1);
############################################################
# 检查load的函数
sub check_load{
my($server)=@_;
my $load=get_server_load(); #获得数据库主机当前load,具体实现这里就不赘述了
my $cutoff1=$cutoff{$server}[$load1];
my $cutoff2=$cutoff{$server}[$load2];
if ( $load > $cutoff2){
my $mesg=$server." load more than ".$cutoff2.",now is ".$load."\n";
send_mobile($server,$mesg); # 大于load2,发送手机告警
}
elsif( $load > $cutoff1){
my $mesg=$server." load more than ".$cutoff1.",now is ".$load."\n";
send_wangwang($server,$mesg); # 大于load1,发送旺旺告警
}
}
############################################################
#循环检查所有主机的load
foreach my $server(keys(%cutoff)){
print "---- ".$server." -----\n";
check_load($server);
}
在send_mobile和send_wangwang实现告警发送的函数中,传入了$server参数,同样可以使用hash数组配置发送给不同的责任人,基本思想和这里没有大的差别,就不重复贴代码了。
编写Perl模块
这两天在用Perl编写一些监控脚本,其实写代码也是一件挺有意思的事情,就是挺废时间的。而且,由于语法不太熟,基本想到一个东西都要先Google一下看怎么实现。Perl的语法相对来说有点晦涩,主要是一些内置变量和函数处理得相当精巧,而过于精致的东西理解起来就有点费力。相对于Shell,Perl在很多方面更加强大高效,比如Hash(关联数组)就非常好用,如果要将不同主机发出来的告警信息发送到不同的责任人,在shell中要做非常多的if或者case判断,修改起来也非常费力,而使用关联数组,则可以轻松实现该功能,代码简洁,配置方便,一个字,爽。
Perl支持以模块对代码进行封装。著名的CPAN上就有非常多好用的Module,可以极大的减轻开发量。一个简单的模块:
require Exporter;
use strict;
use warnings;
our @ISA = qw(Exporter);
our @EXPORT = qw(fun_public); #要输出给外部调用的函数或者变量,以空格分隔
our @version = 1.0;
sub func_private{
print "This is a private function";
}
sub func_public{
print "Hello,world\n";
func_private();
}
1;
__END__
模块的文件名一般以.pm做后缀,名字和package相同,也就是上面这个Module的名字为NinGoo.pm。然后在普通的.脚本中调用:
# creator: NinGoo
# function: test perl module
BEGIN {
push (@INC,'/home/module');
}
use strict;
use NinGoo;
func_public();
O’Relly出版了一系列Perl的图书,比较著名的大骆驼《Programming Perl》在这里有一个在线中文版本的,可以看看。
WindowsXP上chm文件无法打开一例
从网上下了本电子书《Perl for Oracle DBAs》,chm格式的。但是无法打开,所有的页面都显示:
此程序无法显示网页
最可能的原因是:
未连接到 Internet。
该网站遇到了问题。
在地址中可能存在键入错误。
…
由于并非系统中所有的chm文件都无法打开,那么问题应该在这个文件本身了。Google了一下,找到了解决方法,在该chm文件上点右键,选择属性,会发现有一个解除锁定的按钮,并且有说明文字:
此文件来自其他计算机,可能被阻止以保护该计算机
点击解除锁定,重新打开文件,问题解除。Windows这么做是出于安全考虑,因为chm是可执行文件,由html打包而成,里面有可能包含恶意代码。
除此之外,chm文件还有一种比较常见的打不开的情况,显示“不能打开文件mk:@MSITStore:\****.chm”,这可能是由于一个ocx控件注册有问题,重新注册一下该控件可能有帮助: