以前写的,迁过来了。
从《长尾理论》想到的运维上面的一些事情
长尾理论1.0的书也看过,2.0买还是没买也记不得了。今天上午工作的时候,突然想到了一些问题。长尾理论主要介绍,经典的2/8理论已经不适合互联网的模式,互联网的由于他的信息检索方式,存储方式,以及购物方式都发起了根本性的转变,如同一本很久以前没有卖掉的书,可能经过一些推销,互联网推销成本还是比较低的,而且目的性也比较集中,可能就会把沉积多年的物品,通过互联网方式卖出去。
===============================================================
下面是在网上找到的关于“长尾理论”
http://wiki.mbalib.com/wiki/%E9%95%BF%E5%B0%BE%E7%90%86%E8%AE%BA
举例来说,我们常用的汉字实际上不多,但因出现频次高,所以这些为数不多的汉字占据了上图广大的红区;绝大部分的汉字难得一用,它们就属于那长长的蓝尾。 Chris认为,只要存储和流通的渠道足够大,需求不旺或销量不佳的产品共同占据的市场份额就可以和那些数量不多的热卖品所占据的市场份额相匹敌甚至更大。
长尾市场也称之为“利基市场”。 “利基 ” 一词是英文 “Niche” 的音译,意译为 “ 壁龛 ” ,有拾遗补缺或见缝插针的意思。菲利普·科特勒在《营销管理》中给利基下的定义为:利基是更窄地确定某些群体,这是一个小市场并且它的需要没有被服务好,或者说 “ 有获取利益的基础 ” 。
通过对市场的细分,企业集中力量于某个特定的目标市场,或严格针对一个细分市场,或重点经营一个产品和服务,创造出产品和服务优势。
===============================================================
我应该没记错,这个理论是成立的,而且已经被广大互联网服务商所认可,下面就要谈到我理解的关注点了,如果长尾理论是一条长长的尾巴,我可不可以理解成,用户的极少数需求会被满足,而且这种服务会支持到更长时间,很长,很长。这不会因为新出一个应用后,就发生100%的转变,肯定会有少部分的人还是会继续原有系统,就如互联网多NB,也没有替换掉短信一样。每个产品都有自己存在的理由和服务的用户群,未来就是有可能一直持续,持续到开发换了一波又一波,业务换了一波又一波。系统的各功能,会越积越多,系统的数量也会越来越多,但不会因为功能的增加,运维人员也跟着比例的增加。老板一般都不会这么想的。
也就说是未来的系统可能是会越来越多,因为产品只要还能提供利润,业务轻易不会下线这些机器的,道理简单的,只要来钱,他们才不会的动的,一动可能这部分钱就没有了。他才不管你的底层是如何有问题,有风险。当然这里存在一个沟通的维度,如果我们将事情的利弊讲清楚,明白其中道理的业务也会同意,但这不是本文章要关注的。本文章要关注的如果我们可以预估到一些这种情况,我们如何来构建我们的基础架构服务,如何来规划我们的运维工作。
问题 “在长尾理论的环境下,运维工作要如何有效的开展”写到现在才把问题抛出来,真心我的问题。:)
虽然背景我描述的很多,但真正要说到如何有效的开展,确也是没有想过太多。如果非要拿出一些结论和说法,我们还得透过现象看本质。谈一下我自己的看法,也只能说是看法。
长尾理论是非常小非常小的颗粒组成的,只要有足够多的小颗粒,组成起来就是大市场,我们系统也要考虑到小颗粒意味的对系统的访问压力和设计压力都不大。如果我们为每个颗粒都都建立一套系统,可能这个颗粒开始的时候很大,我们为他建立一套系统是正确的,但随着时间的流逝,用户的减少,不可能再有资源继续投入了。终成了一个僵尸系统,谁也不知道,谁也不敢动。这里面的涉及的开发职责暂不说,先说说运维怎么规划这件事情:
1)组件标准化,如一些系统组件如glibc版本,gcc 版本,PHP版本,mysql版本,尽量做到标准化,不使用特殊的扩展组件。
2)平台标准化,在颗粒建设初期,或者在没有建设系统的任务情况下,我们就应该着手考虑建立一个平台,系统平台可以整合多个业务平台。多个颗粒系统都是很重要的。
3)系统集成化,如果我们要将多个子系统集成化在一起,我们需要考虑哪些关键指标,访问压力、系统压力、流量压力、扩容压力、容灾压力、冗余压力、备份压力,好多,好多。
4)升级有序化,运行的业务平台多了,可能受限制的条件就多了,组件的升级工作可能将进行的异常缓慢,因为要考虑的点多了,顾及多了,自然就会慢许多了。稳定是压导一切的。
5)容灾一体化,包括备机,备份、异地容灾等,都是需要考虑的,因为现在的服务都是面向全国的,电信,联通互联是永远的痛,双线机房也不是完美的解决方案。所以各区域都部署机器也是不得已的方案。
就是得玩标准化,集成化,平台化,要不然多系统分散了,消耗人的精力也是非常巨大的。系统再没有迭代不发展的情况下,下线是个非常漫长的事情。非常难,非常难,公司越大,越难搞。
准备在2项内容里面多做些工作,考虑一下已有系统,包括其它业务的子系统,是可以建立一套基础平台,将一些访问压力小的业务,或者已经被长尾好久的系统都迁移到这台平台上,组织项目人员集中精力将这些系统进行标准化。同时也要考虑好3,5,1。至于4升级可能就很难很难,除非在初始迁移情况就进行一次,如果一旦进入这个平台,再升级的可能性就又被降低了。
涉及的内容太多了,做成什么样,准备怎么做,需要准备哪些东西,开发的支持资源有多少,迁移后的架构是什么,迁移后是否还有扩容需求,标准是什么。。。。。。。要准备的东西还很多。
最核心的问题是,1)在业务线运营时间越来越长,此业务给的支持不足够多的背景下,但运营指标还是很高要求下。我们是否可以用更少的资源来进行运营,这样可以给我们节约大量的人力和物力。
另一个扩展的问题是,如果新业务刚上线,机器数量少,无法建立比较完善的全国服务器布局,是否也可以利用这个平台进行运营初期的有效运行。也是要值得考虑的问题。
虽然事情说起来容易,但做起来难。还需要努力还做事情才是真格的。
列一些我考虑的难点吧:
1)什么业务及模块适合此模型系统
2)判断的标准什么
3)日后维护复杂是否会增加,是否可以分离出来,基础运维和应用运模,此对此模型
4)扩容指标,SET模型如何构建
5)多地部署应用,要考虑DB部署的情况
6)机器负载及最大可用性的评估
7)如果有效的进行系统的分离,避免因为一个业务出现BUG,过渡消耗机器资源,导致其它业务模块无法正常提供服务。
8)此业务系统搭建组件有哪些,如何提高高可用性,冗余性是重要的课题。
9)如何说报业务开发将现有系统迁称到此平台上,因为根据现在平台基础组件进行统一的升级工作。
主旨其实就是很简单的一个道理~~一个产品的生命周期的尾端如何可运维(前同事送我的一句话。比我厉害啊)
BYW:自有业务的平台化,跟开放开放平台的平台化,差异还是挺大的,自有业务都是已经存在多年,运营多年,开发放平台是近一两年再兴趣的,所以标准制定的也比较完善。所以往大了想,应该有一个大平台融合所有。从业务中把平台剥离出来。但需要至少几期工程才可以,“路漫漫其修远兮,吾将上下而求索”
php程序不能解析域名到IP
迁移程序到另一台机器,OS一样,apache,php一样,但程序就是报连不上数据库,在操作系统上ping,host,mysql,telnet都没问题。
把这个域名放到/etc/hosts下面就没问题,但用/etc/resolve.conf方式来查就行。下面是对这2种方式访问的时候进行的strace,对apache进行strace比较头痛,因为初始的子进程特别多,你也不知道是哪个。所以需要改httpd.conf参数,将进程放到1-2个这样就好监控了。当然这时候机器不能是线上的。
这两个输出的主要是右侧对stat64(“/etc/resolve.conf”…..)后就没有进行open这个文件,这是关键点,也是疑点,说明httpd进程,根本没有去读这个文件,自然解析不到相关的数据名域名。
这时候其实也不知道如何入手,具体怎么样的过程都忘记了,就是查到了httpd进程好象没有加载libnss_dns-2.4.s0,这个so是属于系统的glibc库的,不太可能有问题,问题在于httpd为什么不加载他,仔细看了strace说实话也没啥结果。
发现httpd进程初始的会读一些库,当然这是通过strace根本的结果,但不是启动后,是在开始启动的时候,如:
strace ./apache -k start
发现httpd会读好多目录的下的libnss_*.so,当然也包括libnss_dns-2.4.so,我就把/lib/libnss* 复制到/usr/local/lib/下面
各种ldconfig,发现还不生效,过了一会又试发现问题解决了。每次在页面执行的时候,再系统上lsof | grep libnss,发现httpd进程加读这个libnss_dns-2.4.so,只要读了这个库,php在apache里面就可以正常解析域名。
下面是解决之后再观察httpd进程启动的加载过程的
strace ./apache -k start
11:41:44 open(“/usr/local/httpd-2.0.59/lib/tls/i686/sse2/nosegneg/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/tls/i686/sse2/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/tls/i686/nosegneg/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/tls/i686/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/tls/sse2/nosegneg/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/tls/sse2/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/tls/nosegneg/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/tls/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/i686/sse2/nosegneg/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/i686/sse2/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/i686/nosegneg/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/i686/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/sse2/nosegneg/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/sse2/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/nosegneg/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
11:41:44 open(“/usr/local/httpd-2.0.59/lib/libnss_dns.so.2″, O_RDONLY) = -1 ENOENT (No such file or directory)
上面是要去/usr/local/httpd-2.0.59/lib/下面去读一大堆的libnss*的库,实际上这些库都是在/lib/下面。将libnss*复制到/usr/local/lib下后
11:41:44 open(“/etc/ld.so.cache”, O_RDONLY) = 18
11:41:44 fstat64(18, {st_mode=S_IFREG|0644, st_size=37181, …}) = 0
11:41:44 mmap2(NULL, 37181, PROT_READ, MAP_PRIVATE, 18, 0) = 0xb7727000
11:41:44 close(18) = 0
11:41:44 open(“/usr/local/lib/libnss_dns.so.2″, O_RDONLY) = 18
httpd就可以open 上库了。
11:41:44 read(18, “177ELF111331@16004360B004 n( 356004004004@1@15433453345334532323411270527055201354>354N354N230123416202?OO340340644t1t1t1 444″…, 512) = 512
11:41:44 fstat64(18, {st_mode=S_IFREG|0755, st_size=21427, …}) = 0
11:41:44 mmap2(NULL, 20616, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 18, 0) = 0xb7034000
11:41:44 madvise(0xb7034000, 20616, MADV_SEQUENTIAL|0×1) = 0
11:41:44 mmap2(0xb7038000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 18, 0×3) = 0xb7038000
11:41:44 close(18) = 0
11:41:44 munmap(0xb7727000, 37181) = 0
11:41:44 time(NULL) = 1340768504
读完libnss_dns库后,httpd会去读/etc/resolv.conf。然后就可以去连接DNS解析了
11:41:44 stat64(“/etc/resolv.conf”, {st_mode=S_IFREG|0755, st_size=61, …}) = 0
11:41:44 open(“/etc/resolv.conf”, O_RDONLY) = 18
11:41:44 fstat64(18, {st_mode=S_IFREG|0755, st_size=61, …}) = 0
11:41:44 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7730000
11:41:44 read(18, “search sitennameserver 172.27.x.xnnameserver 172.17.x.xn”, 4096) = 61
11:41:44 read(18, “”, 4096) = 0
11:41:44 close(18) = 0
11:41:44 munmap(0xb7730000, 4096) = 0
11:41:44 gettimeofday({1340768504, 899255}, NULL) = 0
11:41:44 socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 18
11:41:44 connect(18, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr(“172.27.x.x”)}, 28) = 0 <–这一条是去连接DNS服务器
11:41:44 fcntl64(18, F_GETFL) = 0×2 (flags O_RDWR)
11:41:44 fcntl64(18, F_SETFL, O_RDWR|O_NONBLOCK) = 0
这样就解决了,也只是把库复制到/usr/local/lib下面,httpd就可以读取了。这样就自动可以解析域名了。
环境是:suse 10sp2 32bit gcc 4.1.2
web模型和mail模型一点小感悟
早上在看书,突然想到,web模型和mail邮件模型很重要的一点是,数据一个关键的属性,“属主”不一样,直接导致整体的策略及业务不一样。数据的属性不一样,体现在数据是属性跟用户的访问是否有强一致关联,web不是强致性,mail确实强一致,这是导致必须用两种思维去考虑架构和设计。先记下来,怕忘记
原来一直在想,我老是讲web模型简单,这简单,那简单(相对简单,绝对不简单),一讲起来绝也无从下手,今天早上突然想到,记录了上面的话。不管什么模型,他最终会由数据来体现出来,只有数据才能被用户所感知,包括视觉,听觉,我这里都统一叫作数据。那数据就应该有一些特性,比如扩展性,一致性。只是讲我们在不同的视角,看到的数据特性为我们思想所用的时候,体现出来的数据的特征不一样。如两个模型的对比,我主要从用户访问角度来考虑。当然再提高一点层次,我们就得看到业务的不同了,不管是个人邮件,或企业邮件,他从被被发明到现在的应用,总脱离不了他的核心特点,每个会话数据传输独立的性,用户访问自有独立空间,数据访问空间的隔离性。
而web应用,他的产生和今天的扩大化应用(SNaS)已经变化比较大了,但他有独占也比较明显,如广播性,非强制每用户会话数据独立性。
而数据这些显著的特点是对比,我们可以清晰的看到两种主流应用的特点,如果在能将自己知识,经验在不同的模型中转换是很简单确实又很艰难的问题,简单讲:我是从结构往下走的,他们都面对的存储,索引,网络等基本元素,只要将这些概念理解深入,掌握到位,其实不管什么模型都是建立在“原子”之上的,这就是我讲的简单。难的地方,如果想做领导,或架构师,不能只考虑非常底层的东西,需要站的有高度有视野,但两种模型的差异放在那里,我们只能抽象一层考虑,如他们的数据模型是什么,他们的访问模型是什么(多地访问) ,再考虑不同类别东西的时候,我到现在的理解就是,理解不了的东西就抽象出来,再理解不了的东西再抽象出来。这样最后可能只会变成哲学里面讲的“物持和意识”,这个东西说多了就容易不物质了,但我们如果用一些方法去理解不同的业务,至少我没有想到好的办法,除了抽象应该是没有其它办法了。
这里有一个提升的点,也可能是我的年纪已经有点大了,不想再研究底层的东西,哈,其实也不是。如果我们对两种模型号抽象完之后,就停手,好好理解一下,毕竟任何一种技术都是有缺陷的,我们平时解决不了的问题,可能就是我们没有好好理解本质的东西,理解之后我们将可以将相互的经验来借鉴,有人可能说一个是postfix,一个是apache,别忘记我们是从更高层抽象来看,他们有本质的东西,如全国性访问速度,高可靠性。都是可以互相学习的,这可能才是最终我们抽象出来想看的东西,“互相学习,互相借鉴”。
好了就写这么多的吧,也是一时心血来潮,该收拾一下,赶班车去了。
fastyu
2012.6.28 晨
微博上遇到的几篇好文章,分享一下
作者是邓草原
这样设计的结果,你可能会发现*核心*实体映射到数据表后更象一个记录了本团块内实体的目录,这样的设计是正确的,因为,一、另一个团块内的实体如果想查找这个团块的实体,首先就是查这个目录;二、在分布式系统中,目录是最重要的;三、一个层次化甚至分布式系统的核心构架就是一级一级目录。
rand,srand学习
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i,seed;
printf(“this porgram displays the first five values of “”rand.n”);
for (;;) {
for (i=0;i<5;i++)
printf(“%d “,rand());
printf(“nnt”);
printf(“enter new seed value (o to terminate):”);
scanf(“%d”,&seed);
if (seed==0)
break;
srand(seed);
}
return 0;
}
rand函数和srand函数都是用来生成随机数的,rand函数会返回一个0~RAND_MAX(stdlib.h定义的宏)之间的数,rand函数是不承受机的,但这些数是由“种子”值产生的,每个种子值确定了一个特定的伪随机序列。srand是可以为rand函数提供种子的,意思是rand函数需要的种子是可以变化的了,但需要srand来提供。
# ./a.out
this porgram displays the first five values of rand.
1804289383 846930886 1681692777 1714636915 1957747793 A
tenter new seed value (o to terminate):3
1205554746 483147985 844158168 953350440 612121425 B
tenter new seed value (o to terminate):2
1505335290 1738766719 190686788 260874575 747983061
tenter new seed value (o to terminate):3
1205554746 483147985 844158168 953350440 612121425 B
tenter new seed value (o to terminate):
上面是初始会生成几个随机数,但重新输入种子3 后,会产生新的随机数,但再次输入3后就会再次产生相同的随机数(B行就说明了问题)
# ./a.out
this porgram displays the first five values of rand.
1804289383 846930886 1681692777 1714636915 1957747793 A
tenter new seed value (o to terminate):3
1205554746 483147985 844158168 953350440 612121425
tenter new seed value (o to terminate):
#
再次执行这个程序由于初始的承受机的种子初始是1所以开始显示的随机数还是一样的。下面的例子也说明,我即使给srand输入1,显示的跟程序初始执行的结果是一样的。
# ./a.out
this porgram displays the first five values of rand.
1804289383 846930886 1681692777 1714636915 1957747793
tenter new seed value (o to terminate):1
1804289383 846930886 1681692777 1714636915 1957747793
tenter new seed value (o to terminate):
dbm简单学习
编习例子apue的20-1.c
#include <apue.h>
#include “apue_db.h”
#include <fcntl.h>
int main(void)
{
DBHANDLE db;
if ((db=db_open(“db4″,O_RDWR|O_CREAT|O_TRUNC,FILE_MODE))==NULL)
err_sys(“db_open error”);
if (db_store(db,”alpha”,”data1″,DB_INSERT)!=0)
err_quit(“db_store error for alpha”);
if (db_store(db,”beta”,”data for beta”,DB_INSERT)!=0)
err_quit(“db_store error for beta”);
if (db_store(db,”gamma”,”recordd3″,DB_INSERT)!=0)
err_quit(“db_store error for gamma”);
db_close(db);
exit(0);
}
看apue_db.h还是比较简单的,
more /usr/include/apue_db.h
#ifndef _APUE_DB_H
#define _APUE_DB_H
typedef void * DBHANDLE;
DBHANDLE db_open(const char *, int, …);
void db_close(DBHANDLE);
char *db_fetch(DBHANDLE, const char *);
int db_store(DBHANDLE, const char *, const char *, int);
int db_delete(DBHANDLE, const char *);
void db_rewind(DBHANDLE);
char *db_nextrec(DBHANDLE, char *);
/*
* Flags for db_store().
*/
#define DB_INSERT 1 /* insert new record only */
#define DB_REPLACE 2 /* replace existing record */
#define DB_STORE 3 /* replace or insert */
/*
* Implementation limits.
*/
#define IDXLEN_MIN 6 /* key, sep, start, sep, length, n */
#define IDXLEN_MAX 1024 /* arbitrary */
#define DATLEN_MIN 2 /* data byte, newline */
#define DATLEN_MAX 1024 /* arbitrary */
#endif /* _APUE_DB_H */
但编译的时候有问题
# gcc 20-1.c
/tmp/ccc3stZr.o: In function `main’:
20-1.c:(.text+0×382): undefined reference to `db_open’
20-1.c:(.text+0x3ba): undefined reference to `db_store’
20-1.c:(.text+0x3ed): undefined reference to `db_store’
20-1.c:(.text+0×420): undefined reference to `db_store’
20-1.c:(.text+0x43b): undefined reference to `db_close’
collect2: ld returned 1 exit status
在apue_db.h添加一个,把apue包里的db.c复制到/usr/include里面
#include “db.c”
# more 20-1.c
#include <apue.h>
#include “apue_db.h”
#include <fcntl.h>
int main(void)
{
DBHANDLE db;
if ((db=db_open(“db4″,O_RDWR|O_CREAT|O_TRUNC,FILE_MODE))==NULL)
err_sys(“db_open error”);
if (db_store(db,”alpha”,”data1″,DB_INSERT)!=0)
err_quit(“db_store error for alpha”);
if (db_store(db,”beta”,”data for beta”,DB_INSERT)!=0)
err_quit(“db_store error for beta”);
if (db_store(db,”gamma”,”recordd3″,DB_INSERT)!=0)
err_quit(“db_store error for gamma”);
db_close(db);
exit(0);
}
# l
再编译还是有问题
# cd ../../learn/
# gcc 20-1.c
/tmp/ccIedg2e.o: In function `db_open’:
20-1.c:(.text+0x54e): undefined reference to `lock_reg’
20-1.c:(.text+0x68b): undefined reference to `lock_reg’
/tmp/ccIedg2e.o: In function `db_fetch’:
20-1.c:(.text+0x8b9): undefined reference to `lock_reg’
/tmp/ccIedg2e.o: In function `_db_find_and_lock’:
20-1.c:(.text+0x94c): undefined reference to `lock_reg’
20-1.c:(.text+0×995): undefined reference to `lock_reg’
/tmp/ccIedg2e.o:20-1.c:(.text+0xe98): more undefined references to `lock_reg’ follow
collect2: ld returned 1 exit status
#
说找到lock_reg,发现在apue包里面有lock_reg.c将他复制到/usr/include下面,然后修改apue.h
#include “lockreg.c”
添加这么一行。再编译就过去了。
执行程序
# strace ./a.out
execve(“./a.out”, ["./a.out"], [/* 58 vars */]) = 0
brk(0) = 0x804c000
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f39000
access(“/etc/ld.so.preload”, R_OK) = -1 ENOENT (No such file or directory)
open(“/etc/ld.so.cache”, O_RDONLY) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=36952, …}) = 0
mmap2(NULL, 36952, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb7f2f000
close(4) = 0
open(“/lib/libc.so.6″, O_RDONLY) = 4
read(4, “177ELF111331340Y1″…, 512) = 512
fstat64(4, {st_mode=S_IFREG|0755, st_size=1548470, …}) = 0
mmap2(NULL, 1312188, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 4, 0) = 0xb7dee000
madvise(0xb7dee000, 1312188, MADV_SEQUENTIAL|0×1) = 0
mmap2(0xb7f28000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 4, 0×139) = 0xb7f28000
mmap2(0xb7f2c000, 9660, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7f2c000
close(4) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7ded000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7ded6b0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb7f28000, 8192, PROT_READ) = 0
munmap(0xb7f2f000, 36952) = 0
brk(0) = 0x804c000
brk(0x806d000) = 0x806d000
open(“db4.idx”, O_RDWR|O_CREAT|O_TRUNC, 0644) = 4 <–索引文件
open(“db4.dat”, O_RDWR|O_CREAT|O_TRUNC, 0644) = 5 <-数据文件
fcntl64(4, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}) = 0
fstat64(4, {st_mode=S_IFREG|0644, st_size=0, …}) = 0
write(4, “ 0 0 0 0 0 “…, 829) = 829
fcntl64(4, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}) = 0
lseek(4, 829, SEEK_SET) = 829
fcntl64(4, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=264, len=1}) = 0
lseek(4, 264, SEEK_SET) = 264
read(4, “ 0″, 6) = 6
lseek(4, 264, SEEK_SET) = 264
read(4, “ 0″, 6) = 6
fcntl64(4, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=1}) = 0
lseek(4, 0, SEEK_SET) = 0
read(4, “ 0″, 6) = 6
fcntl64(4, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl64(5, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}) = 0
lseek(5, 0, SEEK_END) = 0
writev(5, [{"data1", 5}, {"n", 1}], 2) = 6
fcntl64(5, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}) = 0
fcntl64(4, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=829, len=0}) = 0
lseek(4, 0, SEEK_END) = 829
writev(4, [{" 0 10", 10}, {"alpha:0:6n", 10}], 2) = 20
fcntl64(4, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=829, len=0}) = 0
lseek(4, 264, SEEK_SET) = 264
write(4, “ 829″, 6) = 6
fcntl64(4, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=264, len=1}) = 0
fcntl64(4, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=468, len=1}) = 0
lseek(4, 468, SEEK_SET) = 468
read(4, “ 0″, 6) = 6
lseek(4, 468, SEEK_SET) = 468
read(4, “ 0″, 6) = 6
fcntl64(4, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=1}) = 0
lseek(4, 0, SEEK_SET) = 0
read(4, “ 0″, 6) = 6
fcntl64(4, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl64(5, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}) = 0
lseek(5, 0, SEEK_END) = 6
writev(5, [{"data for beta", 13}, {"n", 1}], 2) = 14
fcntl64(5, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}) = 0
fcntl64(4, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=829, len=0}) = 0
lseek(4, 0, SEEK_END) = 849
writev(4, [{" 0 10", 10}, {"beta:6:14n", 10}], 2) = 20
fcntl64(4, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=829, len=0}) = 0
lseek(4, 468, SEEK_SET) = 468
write(4, “ 849″, 6) = 6
fcntl64(4, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=468, len=1}) = 0
fcntl64(4, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=234, len=1}) = 0
lseek(4, 234, SEEK_SET) = 234
read(4, “ 0″, 6) = 6
lseek(4, 234, SEEK_SET) = 234
read(4, “ 0″, 6) = 6
fcntl64(4, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=1}) = 0
lseek(4, 0, SEEK_SET) = 0
read(4, “ 0″, 6) = 6
fcntl64(4, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=0, len=1}) = 0
fcntl64(5, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=0, len=0}) = 0
lseek(5, 0, SEEK_END) = 20
writev(5, [{"recordd3", 8}, {"n", 1}], 2) = 9
fcntl64(5, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=0, len=0}) = 0
fcntl64(4, F_SETLKW, {type=F_WRLCK, whence=SEEK_SET, start=829, len=0}) = 0
lseek(4, 0, SEEK_END) = 869
writev(4, [{" 0 11", 10}, {"gamma:20:9n", 11}], 2) = 21
fcntl64(4, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=829, len=0}) = 0
lseek(4, 234, SEEK_SET) = 234
write(4, “ 869″, 6) = 6
fcntl64(4, F_SETLK, {type=F_UNLCK, whence=SEEK_SET, start=234, len=1}) = 0
close(4) = 0
close(5) = 0
exit_group(0) = ?
Process 6267 detached
#
# more db4.dat
data1
data for beta
recordd3
# more db4.idx
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 869 0 0 0 0
829 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 849 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0
0 10alpha:0:6
0 10beta:6:14
0 11gamma:20:9
# file db4.dat
db4.dat: ASCII text
# file db4.idx
db4.idx: ASCII text, with very long lines
#