国内数据库技术大牛:牛新庄博士自传(附:项目经验)

国内数据库技术大牛:牛新庄博士自传(附:项目经验)

发表于: DataBase, DB2, IT精英, Linux, Oracle, UNIX | 作者: 谋万世全局者
标签: 博士, 技术大牛, 数据库, 牛新庄, 自传

牛新庄博士,是国内顶尖数据库维护、优化和架构专家,以217万年薪受聘于中国建行总行资深技术专家,在国内的金融六大行、证券、保险、电信、邮政、移动等行业,以及青岛海尔、云南红塔、中远集团、上海宝钢等知名企业做数据库的设计、维护、问题诊断和性能调优。

牛新庄博士拥有20多项国际厂商认证(包括DB2 V5~V9的全部认证),获得过国内数据库领域最高荣誉的“2006年中国首届杰出数据库工程师”奖,首届IBM杰出软件专家奖,“2006年IT 168技术卓越”奖等奖项。

牛新庄博士自传

牛新庄博士,研究方向为数据仓库和数据挖掘。是IBM官方资深培训讲师(培训DB2,AIX,MQ,WebSphere和CICS)。2002年获IBM 杰出软件专家奖,2006年获“首届中国杰出数据库工 程师奖”、“2006年IT168技术卓越奖”。是中信银行、山东农信、广东农信等公司资深技术顾问,中国建设银行总行特聘资深技术专家。拥有OCP, AIX,DB2,HP-UX,MQ,CICS和WebSphere等二十多项国际认证。著有《Oracle数据库开发讲座—— Oracle9i Jdeveloper与J2EE实务应用》、《DB2应用开发实战指导》、《循序渐进DB2-系统管理、运行维护与应用案例》、《深入解析DB2-高级管理、内部体系结构与诊断案例》和《DB2性能调整与优化》等书。

选定发展方向

1999年,我在开始读研时就给自己确定了以后的发展方向。

当时有两个方向:网络,数据库技术。因为在2000年之时,网络大热,市场上拥有CCNP、CCIE证书的人特别牛。所以我当时也考下了CCNP证书,但 后来发现网络方向涉及很多硬件层面的东西,这些都对厂商的依赖性太强,个人发挥空间不大。而我喜欢钻研,所以慢慢开始转向专攻数据库技术。

在认准数据库这个方向后,我开始深入学习数据库理论方面的知识。当时,人大王珊教授的《数据库系统原理教程》一书,我读了几十遍。在学习数据库理论的同时,我开始接触并深入学习DB2和 Oracle,并从1999年开始使用DB2 V5.2。那时,市场上关于DB2方面的技术书籍几乎没有,互联网也不像现在这么发达。因为我的导师做一个 课题需要用到DB2数据库,但是我只能依靠查看 DB2随机文档来学习。那时,我还自己兼职,通过帮别人做些小软件赚钱,外加课题经费,以支付考OCP认 证和DB2认证的费用。

到现在为止,我一直认为考认证是一个很好的学习动力。因为考试费用不菲,如果不想浪费钱只能拼命看书。我在读 研的2000年就通过了OCP 8i认证,后来又陆续通过DB2 V5.2认证。这些认证极大地增强了我的自信。同时,在帮助导师用PB、Delphi等编程工具做应用开发时,我有意识地增强对SQL的学习,这对我后来的性能调优工作非常有帮助。

这里我想说的是,做好一个时期的人生规划非常重要。我们首先要有一个明确的努力方向和规划,然后有意识的往这个方向努力。这种积极主动的学习要比被动学习效率高很多。

第一次做培训

“机遇偏爱于有准备的头脑”,这句话虽是老生常谈,却是人生真谛。记得2000年底,我在网上看到一个帖子说需要一个人去安装DB2数据库,差旅报销,每 天500元,我喜出望外。因为这项工作需要有DB2认证才能去,而我那时DB2高级系统管理和应用开发的认证都有,所以很快就通过了对方的审核。但是当我 到客户现场时才发现,不是安装DB2而是要给客户讲课,当时我就傻眼了,因为讲课需要的知识远比安装配 置数据库要难得多,更何况我之前根本没有讲过课。没办法,压力也是动力,只能前一天夜里看教材备课到凌晨5点。短短睡了两个小时后,8点半去讲课。四天讲 课下来,我总共休息了12个小时。还好自己毕竟有 DB2应用开发经验和DB2认证做基础,总算勉强应付了过去。只是没想到的是,这次并不算顺利的培训, 竟是我未来几年培训生涯的开始。

将培训当学习的动力

经过第一次讲课后,我看到了自己的差距,知道仅有认证是不够的。客户的很多问题,书本上没有答案,需要自己在实践经验上做努力。另外,讲课前讲师需要把一些原理、概念性的东西弄清楚,也需要对数据库进行深入学习。

后来,IBM培训部通过一些渠道知道我能讲DB2且拥有相关证书,就找我讲授DB2系列课程。所以,从2001年开始,我就经常作为IBM官方讲师讲授 DB2系列的所有课程。我自认为讲课是一个很好的学习过程,因为课前要深入了解概念,对于自己的理论深入学习有很大帮助。同时,课堂上学员的实际操作问 题也会强迫自己做更深入的研究。

我对培训有这样的认识:学员听你讲三个小时,要远远胜过自己看3小时的书。如果把一堂课的内容比喻成 一杯水,那老师至少应该提前储备一桶水。所以,在讲课之前,我精心准备实验,深入和学员交流。我讲课从不照本宣科,而是自己准备了很多教材外比较实用的知 识来扩展教材内容。同时争取上课过程中把一些概念用浅显易懂的例子来讲解。要想做到这些,首先自己必须对这个概念有深刻的理解才行,这一切都在客观上促进 了自己的学习。

随着培训的增多,有部分客户开始找我做实际的调优工作。记得我第一次去为客户现场调优是2001年,去大连大通证券解 决锁等待问题。客户环境用的是AIX 和CICS。当时虽然问题解决了,但自己心里还是比较虚,因为对AIX和CICS不了解,万一是这两个方面有问题, 自己就没办法搞定了;这让我认识到一个复杂系统的调整往往需要具备多方面的知识。这件事之后,我在网上买了一个140的IBM工作站小机,自己安装AIX 并开始学习。

数据库学习Tips

根据我对数据库的理解,目前市场上虽然有Oracle,DB2, Informix,Sybase和SQL Server数据库,但Informix数据库已经被IBM收购,而Sybase数据库在技术和市场上正走向没 落,占据市场主要份额的就是 Oracle,DB2和SQL Server数据库。SQL Server数据库非常好,但是很遗憾的是只能在 Windows平台使用。所以如果你深入研究SQL Server数据库,我只能说获取高薪的概率稍低,而且坦白的说,使用SQL Sever数据库的企业一 般是中小企业居多。而国内做Oracle数据库的人太多,如果你想在Oracle领域出人头地,难度极大。但是,做DB2数据库的人反而不太多,物以稀为 贵。况且,DB2数据库广泛应用在银行、电信、制造行业、零售行业、保险行业等“高薪”领域中,所以我强烈建议学习DB2数据库,做IBM技术一般获取高 薪的概率相对会大一些。我们的时间精力是有限的,所以必须选择好方向然后努力为之。除了SQL Server,这几个数据库我都在使用,我个人感觉除了功 能外,对于运行稳定而言,相对于Oracle不太稳定的优化器,DB2无疑是最稳定的,它的优化器无比强大。如果能在锁方面再有更先进的技术,那么DB2 将是完美的。

这期间,我一边学习,一边通过了AIX的全部认证。记得非常清楚的是,为了做HA的实验,我花费了很大工夫。因为那时小型机 不像今天这么普及,无法搞到7133阵列。后来我又学习了CICS、WebSphere、MQ和存储。就这样,在我培训的过程中,发现自己哪方面薄弱并且 感觉这个方向有前途,我就会开始学习。不过,那时我的技术主要还是围绕IBM产品为主。由于自己对培训比较用心且颇受客户好评,找我做培训的国内培训机构 开始变多。这个期间我自己的技术水平也增长很快。

2002年11月,我参加了首届 “IBM DeveloperWorksLive! China 2002”大会,并获得IBM首次在国内评选的“杰出软件技术专家”奖,当时在6名获奖 者中名列第2。这个奖项客观上对我在客户群的拓展方面起到很大帮助。找我解决问题的人更多了,所以2002—2003年也成了我技术提升最快的两年。

这两年内,我陆续学习了HP-UX、WebSphere和MQ并通过认证。我自己的感觉是,如果你把一门技术研究得非常深、非常透,由于触类旁通的缘故, 再去学习另一门技术时就很轻松。所以,我在学完AIX再去学习HP-UX时,感觉非常轻松。同样,在学习ORACLE和DB2后再去学习 Informix 也同样很容易。通过这种纵向的深入和横向的比较,各种产品的所长所短也会非常清楚,自己的技术视野无意间更加全面化。而且通过对一个产 品的深入,你往往能够发现这个产品的缺点和需要改进的地方。就拿DB2来说,每次版本更新的新特性,在新版本未上市前我就可以猜得差不多了。这主要有三个 原因:一是我贴近真实用户,了解他们的真正需求;二是自己一直在用且不断总结思考;三是这些特性别的数据库有,而DB2没有,那在下个版本就会增加。所以 相对来说,我自身对新版本的新特性学习就非常轻松了。就DB2而言,我拥有DB2 V5.2 、V7.1、V8.1和DB2 V9的全部认证,而且我应该 是国内第一个把DB2 V8认证全部通过的人,当然,这其中也有巧合的成分。

重要的一点是:学习过程中,要不断地把实践和理论融合,知其然更知其所以然,这样提升就会快很多。

现场救援“赶场”记

2004—2005年 是我最忙碌的两年,那时候找我讲课的培训机构和需要性能调优的客户非常多,基本上整天在天上飞。培训机构找我讲课常常需要提前一个月预约。那两年内,除了 过年几天,其他时间都是在做培训和诊断、调优,足迹遍及国内主要城市。我自己基本上是国内六大银行开发中心和数据中心培训的指定讲师,并为北京银信科技、 山东农信、广东农信,交行大集中IBP等项目做数据库技术顾问。

那时的我年轻、精力充沛。记得最刺激的一次是2004年9月的一天, 上午9点为上海移动IT部门做AIX动态逻辑分区(DLPAR)培训,结束时是17 点。之后,立刻坐出租车前往扬州,于20点到达扬州供电局并协助他们 进行电力负荷控制系统项目上线,一直奋战到凌晨3点半。接着,又连夜乘出租车赶往上海,在凌晨6点到达酒店。休息两小时后,8点出发,准时出现在上海移动 培训现场。那时我对报酬不太在意,想的主要是用心积累技术经验和客户资源。在我看来,能够不断通过实践让自己成长是第一要义。而且,去的客户现场越多,处 理的问题就越多,也就越多地发现自己的不足,然后再拼命学习,不断积累、总结和思考,进入了一个良性循环。

至今我仍然怀念那段充实、 紧张而充满激情的光辉岁月。2004年和2005年,一方面因为以独立咨询顾问的个人身份无法出具发票;另一方面,项目越做越大,尤其是很多银行的数据库 架构和维护项目涉及合同金额也越来越大,需要签订正式公司合同。于是,我就分别在上海、北京注册了公司。当然这些年我并非都是一帆风顺,也犯过一些重大错 误,例如:我曾经在2002年5月1日把海南美兰机场的数据库调死,导致机场航班信息管理系统瘫痪。早期也曾经因为调整某证券系统宕机而影响股民交易,这 些都对客户造成了影响,但这些都是成长必须要走的路。经过这两次事件后,我自己也思考、总结了很多,在之后的调优工作中我基本上再没有犯过错误。

我的秘诀:学习、积累、规划

2006年8月我获得“2006年中国首届杰出数据库工程师”称号,算是对我多年学习数据库的一个总结。自2007年开始,我专注于做一些大客户的运维工作,并相应减少了培训次数。2008年,我被建设银行以年薪217万聘请为资深技术专家来维护Oracle和Informix数据库。就做技术而言,以一己之力能挣到年薪几百万常常令我感到自豪,也让我感受到技术的魅力,觉得自己多年来对技术的钻研得到了认可。

之所以讲述我的技术之路,主要目的是给大家一些参考,尽可能多地去了解社会的需求,有意识给自己制定人生规划。我自己认为,多年来能取得这样的成绩,勤奋、努力和坚持一直是我最看重的。因为有了这些,才不至于当机遇光顾时,你却不知所措。

现在很多年轻人,恰恰缺少的就是这样的忘我与痴迷,在我熟悉的数据库技术领域,很多年轻人越来越早地将注意力集中在薪水和职位上,这是很不明智的行为。其 实,往往那些将诸如高薪与职位忘怀的人反而能更快地取得成功。“不经一番寒彻骨,安得梅花扑鼻香?”这样的道理人人都懂,可能够真正去实践的人却并不多。 结合我的学习经验与感悟,我总结有16字要诀:去除浮躁,认真学习,不断积累,寻找机遇。

最后,我用这句话与大家共勉:古之成大事者,不唯有超世之才,亦唯有坚韧不拔之志也!

牛新庄项目经验:

项目一: 交通银行全国大集中IBP(国际业务系统)项目
项目简介(功能与用途):
交通银行自从2002年开始做全国的数据大集中,其中IBP(国际业务系统)项目,是实现交行国际业务中现有的国际结算、贸易融资,外汇管理、以及外汇资金管理服务,覆盖现有的进口,出口,汇款、融资及头寸管理等主要功能,提供总分行各种参数管理,公共控制、公共信息管理、公共业务和打印、查询、报表等辅助服务,同时,IBP系统还提供与大集中核心帐务系统(简称IBS),大集中信贷管理系统(简称CMIS)、环球同业银行金融电讯协会(简称SWIFT),以及外汇管理系统的连接。是整个大集中业务逻辑比较复杂和技术难度比较高的项目,该项目一期由神州数码公司负责程序编码。
项目难点与解决方案:
交通银行IBP(国际业务系统)是国内首个基于J2EE架构纯 java的国际结算系统。后台数据库为DB2数据库,中间件为Websphere,MQ,运行在IBM AIX操作系统上,IBP系统采用 Browser/Server应用系统架构,利用主流的中间件(Websphere,MQ)系统来接管通讯和交易调度,以达到交易调度的平台化。
该项目的难点主要由以下几点:
1, 由于IBP数据库表结构非常复杂(很多表有几百个字段),而且总行数据大集中后,数据量非常大,所以项目前期合理的数据库的物理设计和后期的性能调优就非常重要。
2, 由于国际业务系统采用报文传输,而且报文的长度非常大,所以数据库中传统的varchar和long varchar数据类型无法满足业务逻辑需求,所以数据库中使用大量大对象(BLOB,CLOB,DBCLOB)数据类型,由于数据库对大对象类型的访问无法通过内存,所以大对象类型的存在直接对数据访问的性能产生影响。
3, 由于并发用户非常多,所以在压力测试期间,数据库中有大量锁等待(lock wait)和死锁(deadlock)和锁升级现象产生,直接影响交易并发。
4, 应用中部分SQL语句比较复杂,而且SQL语句的写法和谓词等方面使用不当,直接造成低效率的SQL运行,占用系统I/O和内存。
5, 数据库中索引构建不合理,存在很多冗余的无用索引,很多应该创建的合理的索引没有构建。
6, 用户希望把个别频繁访问的小表放在内存中长时间运行,如何解决这个技术难题。
7, 如何把应用(J2EE),中间件(Websphere,MQ),数据库(DB2),操作系统(AIX)能全局的调优,不至于在某个环节造成全局的瓶颈。
对于上述问题,分别采用了如下解决方案:
1,在数据库的设计中,采用DB2中的DMS表空间,分别把表中的索引(index),常规数据(data)和大对象(BLOB,CLOB,DBCLOB)分割存放在不同的DMS表空间中,并且把DMS表空间放在IBM ESS存储的裸设备(raw device)上,这样大大提高了读写(I/O)的并行访问,优化了数据访问的速度;另外在缓冲池的设计上,创建了多个缓冲池,分别为索引表空间,数据表空间指定各自的缓冲池,这样可以使它们减少对一个大缓冲池的竞争,从而减少交换(swapping)操作,提高从缓冲池命中率(hit ratio),提高访问速度。下面是部分数据库设计的脚本:
缓冲池:
IBMDEFAULTBP         1000
DATA_DMS_4K_BP      128000
INDEX_DMS_4K_BP      76800
INDEX_DMS_8K_BP      12800
BP_DMS_32K_BP        1000
DATA_DMS_8K_BP       25600
BIGTAB_DATA_4K_BP    25600
BIGTAB_INDEX_4K_BP 25600
WFW_DATA_4K_BP      12800
WFW_INDEX_4K_BP     12800
表空间:
Name     = SYSCATSPACE
Name     = TEMPSPACE1
Name     = USERSPACE1
Name     = LOB_DMS_8K
Name     = DATA_DMS_8K
Name     = LOB_DMS_4K
Name     = DATA_DMS_4K
Name     = INDEX_DMS_4K
Name     = INDEX_DMS_8K
Name     = BIGTAB_DATA_DMS
Name     = BIGTAB_INDEX_DMS
Name     = WFW_DATA_DMS
Name     = WFW_INDEX_DMS
Name     = BPBD_DMS_32K
Name     = BPBD_32K_SYS_TMP
Name     = BPBD_8K_SYS_TMP
同时,由于数据库中存在大量连接(join),分组(group by),排序(sort)操作,所以为了提高这些操作的速度,对系统临时表空间所在的文件系统预留了大量文件系统空间。
2,在最初的数据库物理设计中,数据库中共有238个大对象的字段,这个大对象类型的存在,对系统的性能和I/O读写直接带来性能的低下,为了减少这些大字段,和业务人员详细了解了业务需求,避免了无必要的加大大对象的长度,考虑把有些大对象用varchar代替(例如:原来长度为8000字节的大对象用两个长度为varchar(4000)的字段代替,最后对这两个字段再做concat的字符合并操作),经过详细了解和间接的采用一些技术替代大对象后,最后数据库中只有35个对象,大对象的减少直接带来了I/O访问速度的提高。
3,系统在上线投产前期进行压力测试期间,数据库中有大量死锁和锁等待出现,为了解决上述问题,首先,需要加大相关数据库中有关锁的参数(locklist,maxlocks,locktimeout和dlchktime)等数据库配置参数;其次,为了让锁的快速释放不至于引起交易阻塞,就需要我们在表上创建合理的索引。所以,造成引起锁等待的应用程序和SQL语句,对这样应用和SQL进行合理的构建索引。
4,应用开发中的很多SQL语句运行效率低下,这些SQL语句在写法和谓词使用存在很多问题,例如:大量使用select *,select count(*),使用not in,not exist,使用函数等,对于这些问题,需要对开发人员详细解释如何高效的使用SQL,所以给相关开发人员专门讲解三天的SQL使用和如何编写高效的SQL。
5,应用开发人员往往凭借自己对业务的理解在表上建立了很多索引,结果是这些索引在SQL执行期间根本没有使用,这些冗余索引的存在直接导致了空间存储的浪费和对插入(insert)操作的影响;所以,正确的做法是我们应该正确的分析该表的读写情况,分析表中SQL语句执行的频率,对每一条SQL语句做解释(explain)从而来评估为该表创建最合理的索引。
6,使用缓存(cache)表来解决上述问题,该特性是DB2数据库新增加的一个特性,要能够合理的把数据库最新的最先进的技术运用到我们的数据库设计中。
7,调整操作系统交换空间(page space),内核参数;调整数据库配置参数;合理的设置websphere的相关和数据库的接口配置,调整应用性能;最后用压力测试软件来找出引起性能的瓶颈并解决各个层面的瓶颈。
项目成功与失败的经验归纳:
IBP项目已经在2004.7.14日杭州第一家正式上线,上线近两年来,系统非常稳定和高效的运行,IBP项目的成功经验有以下几点:
1, 数据库前期的合理的架构设计(物理设计和逻辑设计)是整个项目成败的关键,合理的架构设计为整个项目稳定可靠高效运行打下了良好的基础,同时也起到了事半功倍的作用。
2, 根据系统的物理资源,对数据库的配置参数做合理的调整,保证系统物理资源(CPU,I/O,内存和网络)和逻辑资源(裸设备,文件系统等)合理的分布和应用。
3, 在应用层,要保证编程人员编写高效的SQL,通过对相关编程人员专门的进行SQL培训,培养他们养成良好的编写高效SQL的习惯;对编程人员讲解SQL执行的原理和步骤,教会他们如何使用相关解释工具(explain)来对SQL进行分析解释从而来选择最合理的执行计划(access plan)。
4, 要学会充分运用数据库中最新的数据库技术运用到实际的编程应用中(例如:DB2 V8中的缓存表等技术)。
5, 要结合不同的数据库产品,在保证业务逻辑允许的情况下,使用合理的隔离级别(例如:UR隔离级别)来最大程度上提高数据库的并发。
6, 对数据库创建最合理的索引(太多,影响insert速度,浪费存储;太少,不能显著提高查询速度),尽量的多创建复合索引和包含(include)索引。
你在项目中岗位与贡献:
负责完成交通银行IBP国际业务系统的整体数据库物理设计和逻辑设计;负责完成数据库后期的性能监控,性能调优;负责培训编程人员如何编写高效的SQL,从而使整体应用运行效率提高;负责构建数据库的索引并删除冗余的索引;负责制定IBP项目的备份和恢复策略;负责制定IBP项目的安全策略;负责培训交通银行全国各分行技术人员。
项目二:梅州农信综合业务系统项目
项目简介(功能与用途):
梅州农村信用社综合业务系统是梅州农信投资2000多万实施的一个电子商务系统,梅州农信综合业务系统的实施,将实现梅州农信现有业务的电子化网络联接,并把梅州农信的综合业务系统建成为梅州银行业领先的综合业务系统,为提高梅州农信的竞争能力和业务经营决策及科学管理的水平做出积极贡献,并能够利用信息技术为客户提供金融服务和帐务管理,尽快实现网络综合业务系统。
项目难点与解决方案:
梅州农信综合业务系统后台数据库为DB2数据库,前台应用采用java开发,运行在IBM AIX操作系统上。
该项目的难点和存在的问题主要由以下几点:
1, 由于国内的银行核心业务系统后台核心大多采用c或c++开发,而梅州农信综合业务系统后台采用java开发,而java应用开发不太适合做银行后台的核心交易处理, 而且java比较占用内存资源,所以该项目难点是在整体架构设计不能改变的情况下,注定了后续的工作只能是“打补丁”的工作。
2, 数据库架构不合理,数据库的物理设计和逻辑设计不合理,需要做数据迁移。
3, 数据库做并发交易非常慢。
4, 数据库装载数据和数据移植慢。
5, 晚上做批处理的处理时间太长。
6, 报表查询时间太长,无法满足实际业务需求。
7, 数据库安全规划不合理,存在安全隐患。
8, 数据库备份和恢复策略不合理。
对于上述问题,分别采用了如下解决方案:
1, 由于前台应用采用java开发,java应用开发不太适合做银行后台的核心交易处理,而且java比较占用内存资源,针对java比较占用内存资源的情况,需要对应用作出优化,尤其需要在应用中对java的内存使用进行垃圾回收。
2, 梅州农信综合业务系统数据库架构设计不合理,数据库设计采用了SMS表空间,而且表中索引,常规数据和大对象数据没有分割存放;SMS表空间采用目录方式访问,并且使用大量操作系统调用(system call),读写效率低下。所以为了保证数据库高性能并发I/O,需要对原有的数据库进行重新物理架构设计并对现有数据进行数据迁移。
3, 梅州农信综合业务系统在上线初期,数据库的并发非常慢,数据库中经常存在锁表的现象,有大量的死锁(deadlock),锁等待(lock wait)和锁升级(lock escation)出现,为了解决这些问题,采用了如下解决方案:一是首先调整数据库中和锁相关的配置参数(locklist,maxlocks,dlchktime)等参数,其次是找出系统是哪些应用和SQL长时间的持有锁,对这些应用和SQL作出调整。
4, 梅州农信综合业务系统在上线初期,需要对以往的历史数据进行移植和装载到新的数据库中,在初期他们采用了import方式来进行数据移植和装载数据;在DB2数据库中有import和load两种数据入库方式,import的方式是非常慢的,所以采用import方式根本无法定期按时上线。为此,重新用load编写移植脚本,这样保证了系统定期按时上线。所以,一定要采用数据库中最合理的技术来进行相应的操作。
5, 系统在上线初期,每天晚上做批处理的时间特别长(大概7个小时)左右,这是不合理的,对批处理进行监控发现批处理中存在很多对数据库的大表的delete操作;指导应用开发人员在开发中用load的API函数来代替delete,因为直接delete会产生很多日志和锁,删除速度慢并且容易出现表的“碎片”。经过上述调整后,批处理时间减少为3小时左右。
6, 在每天晚上的报表处理时候,报表处理速度非常慢,往往处理一张报表需要几个小时,经过分析发现报表的SQL语句非常复杂,这些SQL语句一是没有经过调优,运行效率低下;二是对这条复杂的SQL语句没有创建最合理的索引。经过调优SQL和创建索引后,报表的速度减少为几分钟。
7, 梅州农信综合业务系统上线后,数据库安全和操作系统安全都是缺省的设置,没有经过合理的安全规划,存在严重的安全隐患。为此,对相关用户进行角色划分并进行合理的权限分配,同时对每一个用户进行安全的审查(audit)工作,这样保证了系统安全可靠的运行。
8, 梅州农信综合业务系统上线后,数据库没有一个很好的安全和备份策略,这样存在很大的数据丢失风险。根据梅州农信数据库特点,编写相关脚本,每天晚上对数据库做批前备份和批后备份,并把备份好的数据库和数据库日志tar到IBM 3583带库中并定期做恢复的模拟演练。
项目成功与失败的经验归纳:
梅州农信综合业务系统从2002年开始实施到2003年系统上线,系统虽然现在稳定的运行,不过项目中出现的一些问题还是值得后续项目深思的。
1.业务系统前期的选型和架构设计是非常关键的,这是一个方向性的问题,成功的选型和架构设计是成功的一半,由于梅州农信选用了java平台,而java应用开发不太适合银行业务系统后台核心帐务处理,这直接导致了运行效率的低下和对资源的消耗,如果前期他们有一个很好的高级数据库架构设计工程师也许可以避免这些问题的出现。
2.应用编程人员需要对业务需求有详细的了解,应该充分做好前期的业务需求分析,在梅州农信综合业务系统中经常出现很多由于前期业务需求没有做好而导致后期重新“返工”现象,这直接影响了项目的按时上线。所以,编程人员和数据库工程师需要对企业的业务需求有更详尽的了解和分析。
3.需要一个全面数据库人才来做数据库的物理设计和逻辑设计,梅州农信由于前期数据库物理设计和逻辑设计不合理,导致系统未能充分的利用物理资源和逻辑资源,所以后期需要对数据库重新做架构设计,而这些需要做数据迁移,这无疑增加了系统的风险性。
4.由于前期的架构设计和选型不当,直接导致了后续的工作只能是“打补丁”的工作,这些导致了后续项目的被动性以及和其它银行系统和新上线系统的兼容性。
5.应该为企业信息系统制定合理的安全规范以消除潜在的安全隐患。
6.需要为企业的信息系统制定一个合理的备份恢复和灾备策略。
你在项目中岗位与贡献:
由于梅州农信综合业务系统的前期我并没有参加,所以在整个项目的后期出项性能问题的时候,我主要在现在的架构和选型上保证业务系统能够安全,可靠,稳定的运行。主要负责完成梅州农信综合业务系统历史数据移植;负责完成梅州农信综合业务系统的数据库性能监控,性能调优;负责制定梅州农信数据库安全策略;负责制定信息系统的备份和恢复策略,负责制定信息系统的异地灾难备份策略;负责完成原有的数据库的重新物理设计和数据迁移工作;负责指导编程人员编写高效的SQL;负责构建数据库的索引并删除冗余的索引。
项目三: 湖南移动业务运营支撑(BOSS)系统
项目简介(功能与用途):
湖南移动通信公司业务运营支持系统(BOSS SYSTEM)系统是整合营业、计费、结算、账务、收费等业务,实现”以客户为中心、业务的开发和管理面向客户、网络管理面向业务”的运营原则,大大提高企业的营销和服务水平的核心业务支撑系统。
项目难点与解决方案:
BOSS系统从2003年初开始陆续上线,营帐系统在上线运行后出现性能问题。主要表现在对最终用户的交互响应不如预期,尤其在业务繁忙时更是无法得到及时的交互响应。从主机(AIX)系统上观察,主要表现在系统的I/O等待较大。营帐系统是由业务应用程序,Oracle数据库,AIX主机,IBM ESS存储多个部分组成,因此性能瓶颈的定位和性能的优化都比较复杂。
该项目的难点主要由以下几点:
1,湖南移动通信BOSS SYSTEM系统是一个大型的复杂系统。在这个系统中从上至下包括以下几个层次:应用程序、数据库、主机系统(操作系统)、SAN网络和ESS存储系统。在发生系统的性能问题时,性能问题的定位和调优就很复杂。
2,数据库容量大,整个数据容量有约2120GB,整个数据的迁移需要几十个小时的时间,而在生产系统上是不允许有很长的停机时间进行数据迁移。
3,湖南移动BOSS系统是7×24的应用,不允许停机。
4,应用中部分SQL语句非常复杂,而且SQL语句的写法和谓词等方面使用不当,直接造成低效率的SQL运行,占用系统I/O和内存,需要找出这些SQL语句并对之进行调整。
5,需要对Oracle数据库部分参数作出调整。
6,需要对操作系统内核参数作出调整。
7,需要对数据库的数据在ESS存储上的物理分布重新调整。
对于上述问题,分别采用了如下解决方案:
1,针对湖南移动BOSS SYSTEM系统出现的性能问题,根据湖南移动BOSS SYSTEM系统的实际应用, 借助ESS Expert和Precise等性能监测工具软件,对主机系统和存储进行了监控,调整和优化,同时对Oracle数据库和应用系统提出调优建议。
项目分为以下几个阶段:
·         检查BOSS SYSTEM系统中所有硬件系统,特别是SAN网络中的硬件。
·         检查SAN交换机的数据流量,观察是否有通道流量不对称、数据包丢失或数据传输过程中有效验错的问题。
·         分析ESS上的数据分布,安装和配置ESS Expert监测软件,观察是否存在有FC通道、cluster、SSA卡或SSA loop负载不平均的现象。
·         检查并优化主机系统上AIX运行的参数,使之适合SYSTEM系统的运行。
·         安装和配置Precise Indepth for Oracle软件,检查ORACLE数据库的参数设置,确定最影响性能的应用程序,协助软件开发商优化应用程序。
·         两次调整在ESS存储系统上的数据分布,并通过StorWatch EXPERT软件监测ESS存储系统的性能表现;
·         利用Precise软件监测数据库和应用对系统资源的占用,对主机系统作进一步的调优,并提出对Oracle 数据库和应用程序的调优建议;
·         性能瓶颈的定位
一般的调优策略如下:

在湖南移动的调优中,在数据库的设计和应用设计不做更改的前提下,首先,对IBM存储系统和主机系统作深入细致的参数和配置调整。同时,在湖南移动计费中心技术人员的全力配合下,对ESS存储系统上的数据分布作了大规模的调整,并且通过Precise软件对Oracle数据库性能参数的监控,定位对系统CPU, I/O等资源消耗严重的瓶颈,对Oracle数据库和应用系统提出性能调优建议。
2,针对应用的性能状况,修改Oracle的性能参数。
ü             cursor_sharing的值从exact改为force, 减少internal lock wait.
ü             spin_count的值从2000调整到5000。
·         根据Precise的监测和分析结果,检查资源消耗最大SQL语句的逻辑设计,将排名靠前SQL语句的表数据与索引分别存储,建立合适的分区索引,提高资源消耗靠前SQL语句的并行度。
·         通过StorWatch Expert软件持续监控ESS的使用,掌握ESS的性能表现和使用状况。
·         通过Precise软件对Oracle和应用有限数据的分析,确定当前应用系统并没有达到理想的运行状态,建议对应用系统作相应的检查和调整。同时,为了更准确定位应用问题所在,建议收集更长时间的数据,再进行更深入的分析。
3,调整数据在ESS上的分布。
首先将数据平均地分布在两个cluster上,之后将数据分布在尽可能多的通道上。
由于整个数据容量有约2120GB,整个数据的迁移需要几十个小时的时间,而在生产系统上是不允许有很长的停机时间进行数据迁移。
根据多个方案的论证对比,决定采用逻辑卷镜像的方案实施数据迁移。具体的步骤是先将所有的逻辑卷在目的的硬盘上建立镜像、同步数据、再将原硬盘上的镜像部分删除。整个数据迁移工作全部在系统的后台进行,共进行了60个小时,完成所有数据迁移。
4,对操作系统内核参数作出调整
·         对vmtune的参数进行调整如下:
-p       -P        -r          -R         -f       -F       -N        -W
minperm maxperm minpgahead maxpgahead minfree maxfree pd_npages maxrandwrt
396414   792828      0          0        960     1024 65536       1
-M      -w      -k      -c        -b         -B           -u        -l    -d
maxpin npswarn npskill numclust numfsbufs hd_pbuf_cnt lvm_bufcnt lrubucket defps
3250555   65536   16384      16    2048       2656 9      131072     1
-s              -n         -S         -L          -g           -h
sync_release_ilock nokilluid v_pinshm lgpg_regions lgpg_size strict_maxperm
1               0           0           0            0        0
-t           -j              -J               -z
maxclient j2_nPagesPer j2_maxRandomWrite j2_nRandomCluster
792828           32            0                  0
-Z                  -q                    -Q                -y
j2_nBufferPer j2_minPageReadAhead j2_maxPageReadAhead   memory_affinity
512              2                    8                 0
-V                  -i
num_spec_dataseg spec_dataseg_int
0                512
PTA balance threshold percentage = 50.0%
number of valid memory pages = 4063193 maxperm=20.0% of real memory
maximum pinable=80.0% of real memory    minperm=10.0% of real memory
number of file memory pages = 1955960   numperm=49.3% of real memory
number of compressed memory pages = 0   compressed=0.0% of real memory
number of client memory pages = 0       numclient=0.0% of real memory
# of remote pgs sched-pageout = 0       maxclient=20.0% of real memory
·         对schedtune参数的调整如下:
THRASH           SUSP       FORK             SCHED
-h    -p    -m      -w    -e      -f       -d       -r        -t       -s
SYS PROC MULTI   WAIT GRACE   TICKS   SCHED_D SCHED_R TIMESLICE MAXSPIN
0   4     2        1      2      10       16       16         1      8192
CLOCK   SCHED_FIFO2   IDLE MIGRATION   FIXED_PRI
-c          -a            -b              -F
%usDELTA   AFFINITY_LIM BARRIER/16       GLOBAL(1)
100           7             4               0
红色的为要调整的值。
5,检查资源消耗最大语句的逻辑设计。
l         建立合适的分区索引
l         将排名靠前语句的表数据与索引分别存储。
l         提高资源消耗靠前语句的并行度。
l         Oracle 的参数cursor_sharing设为force减少internal lock wait
l         调整Latch的数量(如DB_BLOCK_LRU_LATCHES)或内存的一些参数(如SHARED_POOL_SIZE等)解决内部锁问题。
6,由于数据存储调整后,系统I/O性能状况良好,系统和存储端的性能表现已调整至最佳,系统和存储端的性能调优工作已经完成。建议客户下一步的工作重点是解决应用系统的性能瓶颈,结合Precise对应用的监控结果,检查应用的逻辑设计,数据索引的建立和分布。协助应用开发商修改应用。
7,调整操作系统交换空间(page space)。
项目成功与失败的经验归纳:
在湖南移动BOSS系统的性能调优中,项目的成功经验有以下几点:
1. 数据库前期的合理的架构设计(物理设计和逻辑设计)是整个项目成败的关键,合理的架构设计为整个项目稳定可靠高效运行打下了良好的基础,同时也起到了事半功倍的作用。在湖南移动BOSS系统中就是因为数据库在ESS物理存储的不合理分布而直接导致了系统的I/O瓶颈。
2. 根据系统的物理资源,对数据库的配置参数和操作系统内核参数做合理的调整,保证系统物理资源(CPU,I/O,内存和网络)和逻辑资源(裸设备,文件系统等)合理的分布和应用。
3. 要善于借助于第三方的监控软件(如:StorWatch Expert和Precise软件),这些软件的运用可以快速的定位性能瓶颈从而更快速的作出性能调整。
4. 检查资源消耗最大SQL语句的逻辑设计,将排名靠前SQL语句的表数据与索引分别存储,建立合适的分区索引,提高资源消耗靠前SQL语句的并行度。很多性能瓶颈往往是由于“恶劣”的SQL造成的。
5. 要有一个很好的性能调整流程和性能调整方法步骤,循序渐进,一步一步定位,逐步缩小范围,知道最后定位性能瓶颈。
6. 要善于团队合作,在整个性能调整中,我负责软件调整,要和硬件调整,网络调整的技术人员通力合作。
7. 性能调整是全局的工作,涉及应用开发,中间件,数据库,操作系统,存储,网络等。需要对全局的信息架构有清晰的认识。
你在项目中岗位与贡献:
在湖南移动BOSS系统的性能调整中,我是以IBM技术顾问身份参与性能调整的,主要负责对Oracle数据库配置参数的调整;负责完成数据库后期的性能监控,性能调优;负责检查资源消耗最大SQL语句的逻辑设计,将排名靠前SQL语句的表数据与索引分别存储,建立合适的分区索引,提高资源消耗靠前SQL语句的并行度。负责在操作系统层面定位性能瓶颈(CPU,内存,I/O和网络瓶颈)并调整操作系统内核参数。负责协助开发人员对应用开发作出修改和SQL性能调整。
项目四:江苏电力公司负控系统
项目简介(功能与用途):
江苏电力公司电力负荷管理及用电监控(简称负控系统)系统是为了解决了近年来江苏的“电荒”而上线的一个电力调度系统。通过负控系统可以合理进行电力的调度从而最大程度上保证企业和用户的用电。
项目难点与解决方案:
江苏电力公司负控系统后台数据库为DB2数据库,中间件为IBM CICS交易中间件,运行在IBM AIX操作系统上,前台采用VB和C开发。
该项目的难点主要由以下几点:
1, 系统上线的时间非常紧迫,限期在江苏17个地市上线,这就是说要确保每次每个地方上线都要成功不能失败。
2, 由于采用了IBM 的交易中间件CICS,这就需要在应用,数据库和CICS之间合理的调整相关配置参数,确保系统运行性能。
3, 在白天高峰期间,交易并发多,数据库性能不好。
4, 应用中部分SQL语句比较复杂,而且SQL语句的写法和谓词等方面使用不当,直接造成低效率的SQL运行,占用系统I/O和内存。
5, 各地市使用的DB2的版本(DB2 V5,DB2 V6,DB2 V7,DB2 V8)不一致,使用的操作系统(AIX 4.3.3 ,AIX 5L,AIX 5.2)版本也不一致,使用的CICS版本(CICS 4.3,CICS 5.0,CICS 5.1)也不一致;这需要在有限的时间内在不同的版本上做调试并且只能成功。
6, 负控系统关联营销系统和调度系统并且在同一台主机上工作,所以上线需要和相关部门和省电力公司协调,必须确保不能影响别的业务系统,必须保证首先不能因为负控系统不能上线而影响别的系统,其次保证负控系统上线后不能因为应用对资源的占用而影响其它系统。
对于上述问题,分别采用了如下解决方案:
1,             CICS版本做充分的测试,确保应用万无一失。在应用开发期间,对不同的数据库版本,不同的操作系统版本和不同的
2,             locklist,maxlocks,locktimeoutdlchktime)等数据库配置参数;其次,为了让锁的快速释放不至于引起交易阻塞,就需要我们在表上创建合理的索引。所以,造成引起锁等待的应用程序和SQL语句,对这样应用和SQL进行合理的构建索引。在业务逻辑允许的情况下,尽量使用UR(uncommit read)的隔离级别来提高读并发。对于负控系统白天并发期间产生的大量锁现象,首先,需要加大相关数据库中有关锁的参数(
3,             SQL语句,利用DB2监控工具(事件监视器)找出这些SQL语句并作出解释分析判断SQL语句的瓶颈,对于这些问题,对开发人员详细解释如何高效的使用SQL,协助开发人员修改应用。对于应用开发中的很多运行效率低下
4,             CICS的接口,CICS和数据库的XA接口,在业务逻辑满足的情况下,尽量采用一阶段提交(1pc,因为1pc的运行性能要比两阶段提交好。对于应用程序和
5,             DB2的数据库性能调整中,详细评估系统中可以使用的资源和系统最大可能占用的资源,逐步调整数据库的配置参数并进一步监控调整的结果。因为负控系统和营销系统,调度系统运行在同一台机器上,所以在进行
项目成功与失败的经验归纳:
江苏电力公司负控系统从2004.4月首先在无锡上线到2004年11月在南通最后上线,整个系统上线期间如履薄冰,如临深渊。现在系统已经稳定运行近两年,负控系统的成功经验有以下几点:
1, 需要对企业信息架构有全局的了解,因为现在企业信息架构非常复杂,往往涉及到的不只是数据库,还有操作系统,中间件,应用,存储等,所以需要对信息架构全局有很全面的了解,这就需要不断的学习和更新新的技术。这次我们在负控系统上线期间,因为时间紧迫(一个地市只有一晚上将近10小时时间),在这么短的时间内,很难保证很顺利的上线,如果出现问题,一定要快速的定位是在什么层面(操作系统,数据库,中间件,应用,存储等)出现的问题然后快速解决之,所以必须具备全局的对信息架构的驾驭能力。
2, 和相关业务部门的沟通和协调非常关键,很多时候我们需要他们配合才能完成相关工作,所以交流和沟通是非常关键的。国内很多垄断部门的员工往往非常牛,这就需要我们耐心的,不厌其烦的去和他们做好沟通和协调。这一点对负控系统的按时上线也非常关键。
3, 在企业内部,往往可能存在很多不同版本的数据库,操作系统,CICS和应用版本,他们之间的兼容性非常关键。我们曾经碰到很多DB2 V8客户端无法访问DB2 V7服务器的情况,也碰到很多DB2 V7客户端访问DB2 V8服务器时出现实例crash的现象。同样还有很多操作系统版本和CICS版本不一致所带来的问题。这就需要我们详细了解数据库,CICS,应用和操作系统之间的兼容性问题。
4, 在部分地市,由于使用了最新的DB2版本,发现上线后有很多问题,后来经过问题诊断和咨询IBM,发现是DB2新版本bug的问题,所以企业在使用相关软件的时候,最好不要用最新的版本而要用相对稳定的版本。
5, 在进行数据库的配置参数调整时,一定详细了解系统的物理资源和逻辑资源,以及目前系统中已经在运行的系统和应用,确保新上线的应用不影响已有的应用。
6, 要结合不同的数据库产品,在保证业务逻辑允许的情况下,使用正确的隔离级别(UR)和CICS的一阶段提交来最大程度上提高数据库的并发和应用的性能。
你在项目中岗位与贡献:
负责完成江苏电力公司负控系统在17地市的上线;负责完成负控系统数据库后期的性能监控,性能调优;负责培训编程人员如何编写高效的SQL,从而使整体应用运行效率提高;负责构建数据库的索引并删除冗余的索引;负责负控系统的数据移植;负责协调上线期间和业务部门的交流沟通;负责负控系统后期的数据库维护和技术支持。
项目五:乌鲁木齐商业银行综合业务系统
项目简介(功能与用途):
乌鲁木齐商业银行银行综合业务系统是商行的核心系统,负责处理金卡工程、电话银行、网上银行、POS、ATM 及各种自助终端,该系统稳定运行保证了联机交易和批量处理能力的可靠性和高可用性,大大地简化了业务操作,为完善乌鲁木齐商业银行的信息决策管理体系,为提高各业务部门的风险控制和科学管理水平提供了必要的保障。
项目难点与解决方案:
乌鲁木齐商业银行数据库在2003-08-13日出现系统故障,造成银行综合业务系统停机,影响了业务的正常进行,造成了经济损失和不良的社会影响。乌鲁木齐商业银行后台采用DB2数据库,运行在IBM AIX平台上,使用IBM CICS交易中间件,前台采用嵌入C编程。
该项目的难点主要由以下几点:
1, 由于系统宕机后,为了保证系统快速启动,相关的CICS日志未能保存,这给后续的问题诊断带来的困难。
2, 由于该系统涉及到应用开发商(中联),系统集成商,系统维护商和客户,所以在进行问题诊断时,大家莫衷一是,都相互推诿责任,这对准确的定位带来了困难。
3, 客户使用的DB2版本很老(DB2 V6),IBM已经停止技术支持和补丁更新。
4, 客户的应用程序编写人员已经离开应用开发商公司,这给程序的更改带来很大困难。
5, 客户希望能够快速定位问题所在,并且杜绝这种问题的重现。
对于上述问题,分别采用了如下解决方案:
1, 仔细查看操作系统日志,数据库诊断日志和CICS的部分日志,仔细的定位问题所在,并且详细询问客户相关技术人员在系统宕机前都做了哪些操作。
2, 协调应用开发商,系统集成商和系统维护商,大家群策群力共同定位问题所在,应用开发商负责联系以前的编程人员,了解程序。系统集成商和系统维护商在测试机上搭建模拟环境,争取在模拟环境中能够把问题重现。
3,经过诊断发现是CICS编程中调用了C的malloc()函数而引起的,这需要协助开发商修改程序。
4,引起系统宕机的诱因是在白天做tar磁带的操作,由于tar磁带导致AIX系统文件内存使用完,CICS程序无法获取所需的资源从而导致业务系统宕机。
5,调整AIX的内核参数,调整文件内存和计算内存的页面替换算法所关联的vmtune所对应的maxperm,minperm和maxclient参数。
项目成功与失败的经验归纳:
通过对乌鲁木齐商业银行业务系统的宕机做问题诊断,得出以下几点经验:
1, 用户是希望能够解决问题并保证系统的稳定运行,这需要应用开发商,系统集成商和系统维护商能够通力合作共同找出问题并解决之而不是相互推卸责任。
2, 要保存好相关操作系统,CICS和数据库的诊断日志以保证系统在出现故障时准确定位,为客户编写脚本自动在机器宕机时候保存相关诊断日志。
3, 与客户相关技术人员详细沟通,沟通系统宕机前所做的操作,这一点非常重要。
4, 不但要定位问题,而且一定要有解决该问题的方法,避免该问题重现,所以必须指导相关开发人员修改程序,这需要我们具备良好的编程基础。
5, 告诫客户技术人员不要在高峰期间做compress,tar和大文件的ftp操作。
6, 在做问题诊断时,必须具备全局的操作系统,数据库,中间件和应用编程技术。这就需要我们要拓宽知识面,不断补充和学习新的技术。
你在项目中岗位与贡献:
在该项目中,我主要是客户所请的顾问,代表客户负责定位诊断引起系统停机的主要原因;负责协调应用开发商修改程序,系统集成商和系统维护商搭建模拟测试环境;负责调整相关操作系统内核参数;在找出问题的原因后负责协助开发人员修改程序并在测试系统上模拟测试并确保稳定可靠运行。
项目六:海口美兰机场离港系统
项目简介(功能与用途):
海口美兰机场离港系统(Departure Control System 简称DCS)主要提供办理登机、航班控制和配载平衡三大功能。离港系统是机场和旅客直接接触最主要的系统之一,牵涉到旅客办理登机手续、行李托运等各个环节。
项目难点与解决方案:
海口美兰机场离港系统(Departure Control System 简称DCS)后台数据库为DB2数据库,双机热备软件HACMP,网管软件为Netview,运行在IBM AIX操作系统上,前台采用Delphi开发。
该项目的难点主要由以下几点:
海口美兰机场离港系统(Departure Control System 简称DCS)是我参与开发的软件,该系统在2001年四月份上线后先后出现的性能问题。为此需要对数据库配置参数作出调整。
对于上述问题,分别采用了如下解决方案:
在2001年五月一日早上8:30左右,由于离港系统数据库运行性能非常低下,我决定对数据库配置参数作出调整,于是我在没有详细考虑的情况下,对DB2数据库的相关配置参数作出了等于原来10倍的调整,数据库配置参数生效后,大概在8:33分左右,离港系统小型机宕机,直接造成了从早上8:33分到9:40分这将近一小时的停机,直接影响了旅客的登机,办理值机手续,广播,电话和航显,造成了很大的影响。
项目成功与失败的经验归纳:
从这次失败的的经过中,我得到如下经验:
1, 系统(操作系统,数据库,中间件,应用)性能调整需要循序渐进,不可一蹴而就。
2, 调整相关配置参数时,需要对该配置参数有深刻的理解,当然这需要不断的补充理论知识。
3, 在性能调整时,要做好系统备份和数据库备份,要胆大心细,小心谨慎。
4, 在数据库配置调整时,一定要有最坏的打算,做好失败冗余和恢复方案。
5, 不可完全相信所谓的经验法则,那只是提供一种参考,我就是看了书上说的把缓冲池调整为系统内存的70%这条经验法则才间接导致系统停机的。
6, 在系统运行高峰期间,如果能够忍受,尽量保持系统的平衡稳定运行,否则可以尝试先在备机或测试机上调整。
7, 要不断的认真总结经验,积累。
8, 要把在书上看到的理论和在实践中碰到的实际问题结合起来。
你在项目中岗位与贡献:
失败的经验是一种宝贵的财富,它对我后期从事性能调整产生了很深远的影响,所以有时候要好好的总结失败并从中汲取经验教训。

项目经验来源:http://blog.csdn.net/best_dba/article/details/952249

永久链接 : http://www.ha97.com/4176.html

你可能感兴趣的:(软件人物)