




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第1章 引起数据库性能问题的因素1.1 软件设计对数据库的影响1.1.1 软件架构设计对数据库性能的影响软件系统的架构对数据库的影响是非常直接的。例如一套系统,如果并发数非常大,比如是超过3000个并发,通常这种情况下,我们会考虑采用一套软件来搭建一个中间层,这就是通常讲到的3层或是多层结构。使用这一套软件的目的是用来构建一个缓冲池,在数据库之前对大量的并发进行处理,以便于每次只有少数的用户连接到数据库中,其他的用户在缓冲池的队列中等待。当然,这只是一个动态的过程,程序会尽可能快地去响应所有用户的请求,这种提前对大量并发用户进行处理的方式,会比让这3000个用户直接连接到数据库中效果要好得多,
2、同时数据库也可以使用更多的资源来处理用户的操作请求而不是去开3000个进程来处理每个用户的请求,这个开销是非常大的。所以对于大量并发的系统来讲,在数据库之前建一个缓冲用户请求的中间件服务,显得至关重要。同时,很多这种中间件软件还提供了负载均衡的功能。当然,Oracle数据库自身也提供了一种MTS的技术,作用和这种中间件服务是一样的,但目前看来,采用商业中间件软件或是开发商自己开发一套中间件服务的做法更多一些(参见图1-1)。图1-1 多层架构体系1.1.2 软件代码的编写对数据库性能的影响软件代码对数据库的影响,通常指的是应用程序代码中对数据库操作的代码部分对数据库产生的影响。具体来讲就是SQ
3、L语句或是PL/SQL包。SQL语句造成的影响,一种是SQL语句本身在逻辑上就是效率低下的,另一种就是SQL语句没有绑定变量。性能低下的SQL语句,比如使用Hint,不合适的外连接,谓词的隐含转换,优化器的选择等,会对SQL的执行产生非常大的影响,特别是多表关联的情况下,影响更是显著。它主要体现为SQL语句的执行受到了人为的约束,比如数据的访问方式(索引还是全表扫描),以及表关联方式的选择上(Hah Join,Nested Loops)。 人为地在SQL代码中加入Hint来约束SQL的执行计划我曾经遇到的一个例子就是这样,开发人员为了要求每次对一个表做操作的时候都使用索引,于是在代
4、码中强行加入了Hint约束SQL的执行计划,它的样子大概是这样:Select /*+ index(t1 ind_t1) */ col1,col2 from t1 where col1>. and col1<.我猜测他们在系统上线之前测试的阶段,发现这条SQL选择索引比全表扫描效率高得多,为了保证以后执行计划能够始终选择索引,他们在代码中的SQL里加入了这个Hint。系统上线后,没有出现过问题,直到有一天用户抱怨查询非常慢,我从数据库里得到了用户端发出的SQL,才知道这个SQL在代码里加入了Hint。问题是,为什么之前操作都没有问题呢?我登录这个数据库,查看了一下这个表的信息,惊奇地
5、发现,这个表每天仍然定时在做分析操作,这是一个奇怪的现象,人为地对表进行定时分析,却不允许数据库来选择执行计划,这显然是不合理的事情。但这种现象在开发人员当中又是比较普遍的,大家了解一些数据库的技术,却无法将这些知识整合起来运用,系统设计及开发阶段,没有DBA参与进来,直到系统进入运行维护阶段,才有DBA来充当救火队员的角色,这在当前中国软件开发中是一个很普遍的现象。接着说这个案例。这是一个Oracle 10gr2的数据库,CBO(基于成本的优化器)的技术已经比较成熟,所以此时应该选择由Oracle数据库来决定SQL的执行计划。我分别执行了这条原始SQL和去掉了Hint的SQL,并获得了各自的
6、执行计划,执行计划显示出,去掉Hint的SQL选择了全表扫描(Full Table Scan),执行中扫过的数据块远远小于通过索引访问数据的SQL,于是原因找到了。可是为什么之前没有出现过这个问题?我对比了一下最近的数据和之前的数据,发现近期的数据在创建索引的列上的列值重复率要远远高于从前,因此Oracle在选择索引之后,比以前读取了更多的索引块和数据块,造成了大量的I/O操作。因此,对于高版本的数据库(10g以上),我们还是应该让数据库自己根据表、索引的统计分析信息来决定SQL的执行计划,因为表中的数据是会变化的,这种人为的强行干预,必然会在某个时候出现问题。1.1.2.2 不必要的外连接操
7、作外连接是一个代价非常昂贵的执行过程。如果业务需要,这种操作是必要的,但是有时候会出现人为地在SQL中使用不必要的外连接的情形,这实际上是因为有的开发人员担心遗漏一些数据而刻意使用它,这就非常有可能留下隐患,让数据库选择昂贵的执行计划而不是最优的那一个。下面的这个例子说明了一个不必要的外连接使用。我们创建两个简单的表,并插入一些数据,同时给其中的一个表T2的C列上插入一些空值:SQL> create table t1 as select rownum a,rownum+100 b from dba_users where rownum<10; 表已创建。 SQL
8、> create table t2 as select decode(mod(rownum,2),0,rownum) c,rownum+1000 d from dba_users where rownum<10; 表已创建。 SQL> select * from t1; A B- - 1 101 2 102 3 103 4 104 5 105 6 106 7 107 8 108 9 109 已选择9行。 SQL> select * from t2; C D- - 1001 2 1002 1003 4 100
9、4 1005 6 1006 1007 8 1008 1009 已选择9行。 通过下面这条语句,通过使用A字段和T2表C字段关联,我们获取了T1表上所有的行,以及T2表上符合条件的行:SQL> select a,b,c,d from t1,t2 where t1.a=t2.c(+) ; A B C D- - - - 2 102 2 1002 4 104 4 1004 6 106 6 1006 8 108 8 1008 1 101 3 103 5 105 7 107 9 109 请看下面这条SQL,它是什么意思呢?SQL> select a,b
10、,c,d from t1,t2 where t1.a=t2.c(+) and t2.d>1000; A B C D- - - - 2 102 2 1002 4 104 4 1004 6 106 6 1006 8 108 8 1008 这条SQL的意思是告诉数据库,我要得到T1表上所有的行,并且用A列和T2表C做关联,同时要求T2表C列的值大于1000。让我们再看看另一条结果集完全一样的SQL:SQL> select a,b,c,d from t1,t2 where t1.a=t2.c and t2.d>1000; A B C D- - - - 2 102
11、 2 1002 4 104 4 1004 6 106 6 1006 8 108 8 1008 从结果集上来看,这是两条等价的SQL语句,就是说,在这种情况下,外连接其实是没有用的,是人为地在SQL里设定的限制!如果仔细看一下第一条语句,我们不难发现,条件中T2.C>1000已经明确地指出,在结果集中,T2表在任何一行,C列都应该有值的,也就是在这种情况下,根本就不需要使用外连接,业务逻辑上讲,外连接在这里是多余的。这种情况在开发人员的代码中有时候会遇到,对他们来讲,只要保证结果集正确就好,但对数据库来讲,在执行时可能会引起极大的性能差别。1.1.2.3 CBO下优化器模式的选择
12、通常对于一种功能单一的数据库来讲,在实例级设置一个优化器模式就可以了,比如对于OLAP系统,绝大多数时候数据库上运行着的是报表作业,执行基本上是聚合类的SQL操作,比如GROUP BY,这时候,把优化器模式设置成all_rows是恰当的。而对于一些分页操作比较多的网站类数据库,设置成first_rows会更好一些。我却遇到了另外的一件事情。我们的数据库上运行着的基本上是一个OLAP系统,所以优化器模式设置为ALL_ROWS,这有利于报表SQL的快速完成。但数据库上还运行着一些用户查询的业务,查询的方式可以说成是分页的。有时候就会出现用户抱怨查询慢的问题,尽管我知道问题所在,却比较难解决,因为这
13、些SQL已经被开发人员写到代码里面了。针对这种情况,如果能在开发阶段就考虑到这个问题,针对需要分页操作的SQL,开发人员在SQL里通过Hint的方式来将优化模式转换成FIRST_ROWS,这样就可以大大地提高数据的处理速度。比如这样一个每次取出10条记录的分页查询:Select * from (SELECT /*+ first_rows(10) */ a.*,rownum rnum from (SELECT /*+ first_rows(10) */ id,name from t1 order by id) aWhere rownum<=10)Where rnum>=1;
14、;可以在每个子查询中重复使用FIRST_ROWS(n)来提高查询效率。尽管说在SQL中人为地加入Hint操作不是一个好主意,但是有些时候,比如需要兼顾其他的用户操作时,可以考虑做这样的设定。但前期需要做一些测试工作,以确保这样的设定能够带来性能上的提高,同时不会对数据库造成其他方面的影响。这是系统设计阶段应该仔细考虑好的一个问题。1.1.2.4 没有绑定变量的SQL对于这个话题,其实很多人存在着一个误区。记得有一次在广州出差,我和一个同样做数据库的同事,有这样一段对话:同事:“我们的系统有没有绑定变量?”我:“不知道.”同事:“我发现没有绑定。”他的表情很凝重,仿佛发现了数据库的一个致命隐患一
15、般。我:“无所谓吧?”他立即反驳我说:“谁说无所谓,SQL没有绑定变量,数据库每次执行就会发生硬分析(Hard parse,喜欢读Statspack Report的朋友对这个词应该很敏感吧,我的同事就是一个Statspack fans,那时候他正在研究Statspack,觉得如果硬分析太多了,天就要塌下来,仿佛把这些硬分析变为软分析之后,数据库性能会提高成百上千倍一样),这样性能肯定会大受影响,有时候用户反映查询慢,会不会是这个原因导致的?”我说不是这个原因导致的,我可以保证,因为我们是这样的一个系统:数据库的用户连接数很少,大概不会超过50个,每个用户每天发出的查询操作不会超过50个,这对于
16、一个运行在内存8个GB,10几个CPU的系统上的数据库来说,硬分析对数据库性能的影响微乎其微,完全可以忽略掉,因为我们是一个OLAP系统。他想了一下,认同了我的观点。我想说的绑定变量的误区就和上面这个案例一样,有时候它对性能的影响被夸大化了。我在ITPUB上总看到很多这样的帖子,大家在谈及SQL时必定要求绑定变量,仿佛不这样系统就要出问题了一样。实际上,至少对于OLAP系统(在线分析系统,通常指的是这样的一个系统,数据库存放着海量的数据,连接的用户少,SQL语句基本上都是用户产生报表的大查询)来说,未绑定变量对数据库的影响是很有限的,甚至是完全没有必要的,因为只有少量的用户和少量的SQL操作,
17、数据库不需要花多少资源在SQL分析上面。这个话题我们会在后续的章节中讨论到。绑定变量的真正用途是在一个OLTP系统中,这个系统通常有这样的特点,用户并发数很大,用户的请求十分密集,并且这些请求的SQL大多数是可以重复使用的,我们试想,当这些成千上万的SQL被数据库一遍又一遍地进行语法分析、语义分析,生成执行计划时,这对数据库的压力该有多大?如果一条SQL执行一遍之后就被缓存到数据库的内存当中(实际上是在共享池里),以后的成百上千的用户请求都使用这个SQL解析后的结果,那效率将有多么大的提高!所以,我的观点是,当你要考察绑定变量对你的数据库的影响有多大时,先确定你的系统是OLTP系统或是OLAP
18、系统;当然,现在很多数据库同时担负这两种角色,那么你需要分析数据库的性能情况,比如,做一个Statspack Report来帮助你确定变量是否绑定,以及是否已经对系统的性能构成严重的影响。1.1.2.5 PL/SQL包如果你的程序里面有PL/SQL包,请考虑使用存储过程来代替它,存储过程是经过成功编译后存放在数据库中的代码,执行起来的效率要比程序代码中PL/SQL包的效率高很多,因为它不再需要做语法和语义的分析(语法的分析指的是数据库对代码进行检查,看它是否存在语法上的错误;而语义分析是查看语句执行的对象是否存在,比如需要操作的表、列等,以及是否有执行这些操作的权限)。 1.2 数据
19、库的设计数据库的设计在系统设计当中是一个非常重要的环节,但目前看来,很多开发商忽略了它应有的重要性,大多数的数据库设计基本上等同于创建业务所需要的所有对象,仅此而已。这是作者从事了10年DBA工作的切身体会,也许这也不能全怪开发商,比如他们有工期的压力,有人员成本的压力,那应该是另外一个话题。对于数据库的设计,我认为除了一些必需的对象创建之外,应该还要更多地考虑在整个系统运行的生命周期中,按照系统的实际情况及可能的变化做一些前瞻性的设计,以基本满足系统生命周期里的各方面需求,不至于发生大的修改或是升级。说起系统的升级,这是一个有趣的话题,可能很多开发人员,特别是做项目开发的人员,应该会深有体会
20、。比如我身边的一些案例,明明是最初设计上存在着缺陷或者疏漏,导致后来系统出了问题,却成了开发商项目的二期、三期的理由,也成为软件1.0版、2.0版的理由。基本上看来,前期数据库设计的一个根基就是要弄清楚数据库的类型。通常来说,我们把业务分为两类,在线事务处理系统(OLTP)和在线分析系统(OLAP)或者DSS(决策支持系统),这两类系统在数据库的设计上是如此不同,甚至有些地方的设计是貌似相悖的。比如OLTP系统强调数据库的内存效率,强调内存各种指标的命中率,强调绑定变量,强调并发操作;而OLAP系统则强调数据分析,强调SQL执行时长,强调磁盘I/O,强调分区等。因为这些区别,在数据库设计的阶段
21、,弄清楚数据库类型是至关重要的,只有在这个前提之下,才能够讨论数据库的具体设计,否则设计必然是盲目的,“皮之不存毛将焉附”。1.2.1 OLTP数据库OLAP和OLTP是两类完全不同的系统,对数据库的要求也截然不同。通常来讲,OLTP(在线事务处理系统)的用户并发数都很多,但他们只对数据库做很小的操作,数据库侧重于对用户操作的快速响应,这是对数据库最重要的性能要求。我清楚地记得在2008年的时候,某个门票在线销售系统允许人们通过网络购买门票,这是一个典型的OLTP系统。我当时还想尝试去买一张,结果是还没等到我去买,就听说系统瘫痪了。我想,应该是在线购票的用户数太多吧,导致数据库(我不太确定,也
22、可能是中间件系统)没有办法处理大量的连接,从而导致了系统崩溃。这真是一个惨痛的教训,它用事实告诉我们,对于一个系统,特别是非常重要的系统,一些前瞻性的预测和系统的压力测试有多么的重要。对于一个OLTP系统来说,数据库内存设计显得很重要,如果数据都可以在内存中处理,那么数据库的性能无疑会提高很多。我知道有些对处理速度要求很高的系统,已经采用了一些内存数据库,比如Oracle的Times Ten。内存的设计通常是通过调整Oracle和内存相关的初始化参数来实现的,比较重要的几个是内存相关的参数,包括SGA的大小(Data Buffer,Shared Pool)、PGA大小(排序区,Hash区等)等
23、,这些参数在一个OLTP系统里显得至关重要,OLTP系统是一个数据块变化非常频繁、SQL语句提交非常频繁的系统。对于数据块来说,应尽可能让数据块保存在内存当中,对于SQL来说,尽可能使用变量绑定技术来达到SQL的重用,减少物理I/O和重复的SQL解析,能极大地改善数据库的性能。关于一些初始化参数的设定的问题,我认为,这里绝没有一个确定的标准,这和每个数据库上运行的业务直接相关,能够确定这些参数值的唯一方法就是测试,先给这些参数设定一个经验值,然后通过搭建测试环境对数据库进行测试,通过一些性能报告(比如AWR或者Staspack 报告)作为依据,不断地调整这些参数值,以达到最佳的性能。除了内存、
24、没有绑定变量的SQL会对OLTP数据库造成极大的性能影响之外,还有一些因素也会导致数据库的性能下降,比如热块(hot block)的问题,当一个块被多个用户同时读取的时候,Oracle为了维护数据的一致性,需要使用一种称为Latch的东西来串行化用户的操作。当一个用户获得了这个Latch后,其他的用户就只能被迫等待。获取这个数据块的用户越多,等待就越明显,就造成了这种热块问题。这种热块可能是数据块,也可能是回滚段块。对于数据块来讲,通常是数据块上的数据分布不均匀导致,如果是索引的数据块,可以考虑创建反向索引来达到重新分布数据的目的,对于回滚段数据块,可以适当多增加几个回滚段来避免这种争用(热块
25、部分在后面有专门的章节讨论)。1.2.2 OLAP数据库我一直认为OLAP数据库在内存上可优化的余地很小,甚至觉得增加CPU处理速度和磁盘I/O速度是最直接的提高数据库性能的方式,但这将意味着系统成本的增加。实际上,用户对OLAP系统性能的期望远远没有对OLTP性能的期望那么高。内存的优化,对OLAP来讲影响很小,比如我曾经遇到的一个数据库,每天晚上运行的报表程序,基本上都是对几亿条或者几十亿条数据进行聚合处理,这种海量的数据,全部在内存中操作是很难的,同时也完全没有必要,因为这些数据块很少重用,缓存起来没有实际意义,倒是物理I/O相当大,这种系统的瓶颈往往是在磁盘I/O上面。对于OLAP系统
26、,SQL的优化显得非常重要,试想,如果一张表中只有几千条数据,无论执行全表扫描或是使用索引,对我们来说差异都很小,几乎感觉不出来,但是当数据量提升到几亿或者几十亿甚至更多的时候,全表扫描、索引可能导致极大的性能差异,因此SQL的优化显得重要起来。看下面的一个例子,它对比了索引和全表扫描的效率:* select * from t where object_id<100 call count cpu elapsed disk query current rows- - - -Parse 1 0.01 0.00 0 0 0 0Execute 1 0.00 0.00 0 0
27、0 0Fetch 8 0.00 0.00 0 17 0 98- - - -total 10 0.01 0.00 0 17 0 98 Misses in library cache during parse: 1Optimizer mode: ALL_ROWSParsing user id: 55 Rows Row Source Operation- - 98 TABLE ACCESS BY INDEX ROWID T (cr=17 pr=0 pw=0 time=95 us) 98 INDEX RANGE SCAN T_INX (cr=9 pr=0 pw=0 time=23
28、83 us)(object id 51627) * select /*+ full(t) */ * from t where object_id<100 call count cpu elapsed disk query current rows- - -Parse 1 0.00 0.00 0 0 0 0Execute 1 0.00 0.00 0 0 0 0Fetch 8 0.01 0.00 0 695 0 98- - -total 10 0.01 0.01 0 695 0 98 Misses in library cache duri
29、ng parse: 1Optimizer mode: ALL_ROWSParsing user id: 55 Rows Row Source Operation- - 98 TABLE ACCESS FULL T (cr=695 pr=0 pw=0 time=116 us) * 我们看到,在这个只有几万条记录的表中,相同的SQL语句,全表扫描扫过的数据块(一致性读)是695个,而索引只扫过了17个,差别还是非常大的。分区技术在OLAP数据库中很重要,这种重要主要体现在数据管理上,比如数据加载,可以通过分区交换的方式实现,备份可以通过备份分区表空间实现,删除数据可
30、以通过分区进行删除;至于分区在性能上的影响,不能一概而论,认为分区的性能将始终好于非分区,这个结论是不成立的,至少是片面的,我们通过以下几种情况来分析它。1. 当查询的范围正好落在某个分区的时候这时候分区的效率自然是高于没有分区的,因为SQL在有分区的表上只扫过一个分区的数据,而对于没有分区,需要扫描整个表,这也是大多数人认为分区会提高性能的一个原因吧,比如下面的例子:* select count(*) from t where x<1000 call count cpu elapsed disk query current rows- - -Parse
31、1 0.00 0.00 0 0 0 0Execute 1 0.00 0.00 0 0 0 0Fetch 2 0.00 0.00 0 23 0 1- - -total 4 0.00 0.00 0 23 0 1 Misses in library cache during parse: 1Optimizer mode: ALL_ROWSParsing user id: 55 Rows Row Source Operation- - 1 SORT AGGREGATE (cr=23 pr=0 pw=0 time=2495 us) 999 PARTITION RANGE SINGL
32、E PARTITION: 1 1 (cr=23 pr=0 pw=0 time=9085 us) 999 TABLE ACCESS FULL T PARTITION: 1 1 (cr=23 pr=0 pw=0 time=4077 us) * select count(*) from t1 where x<1000 call count cpu elapsed disk query current rows- - -Parse 1 0.00 0.00 0 0 0 0Execute 1 0.00 0.00 0 0 0 0Fetch 2 0.01 0.0
33、0 0 84 0 1- - -total 4 0.01 0.01 0 84 0 1 Misses in library cache during parse: 1Optimizer mode: ALL_ROWSParsing user id: 55 Rows Row Source Operation- - 1 SORT AGGREGATE (cr=84 pr=0 pw=0 time=9015 us) 999 TABLE ACCESS FULL T1 (cr=84 pr=0 pw=0 time=4077 us) 第一个SQL只扫过了一个分区的数据,扫过的数据块为2
34、3个;第二个SQL做了全表扫描,扫过的数据块为84个,这种情况下肯定是分区表的效率要高一些。2. 当查询的范围跨越几个分区时这时候分区可能并不绝对是最优的,比如下面的例子,我们把查询的范围扩大到分区表的13个分区,让CBO使用FAST INDEX FULL SCAN的方式扫描索引,另外我们创建另一张非分区表,表结果和数据同分区表完全一样,我们使用同一条SQL,并且也让CBO强制使用FAST INDEX FULL SCAN的方式访问非分区表上的全局索引。我们要验证的一个观点是,分区索引并不一定比全局索引在任何时候都快,有时候它反而会慢。下面是输入的结果:Select /*+ index_ffs(
35、t t_ind) */ count(*) from t where x<13000 call count cpu elapsed disk query current rows- - -Parse 1 0.00 0.00 0 0 0 0Execute 1 0.00 0.00 0 0 0 0Fetch 2 0.03 0.02 0 164 0 1- - -total 4 0.03 0.03 0 164 0 1 Misses in library cache during parse: 1Optimizer mode: ALL_ROWSParsing user
36、id: 55 Rows Row Source Operation- - 1 SORT AGGREGATE (cr=164 pr=0 pw=0 time=29234 us) 12999 PARTITION RANGE ALL PARTITION: 1 13 (cr=164 pr=0 pw=0 time=117074 us) 12999 INDEX FAST FULL SCAN T_IND PARTITION: 1 13 (cr=164 pr=0 pw=0 time=52408 us)(object id 51774) select /*+ index_ffs(t1 t1_i
37、nd) */ count(*) from t1 where x<13000 call count cpu elapsed disk query current rows- - -Parse 1 0.00 0.00 0 0 0 0Execute 1 0.00 0.00 0 0 0 0Fetch 2 0.03 0.02 0 117 0 1- - -total 4 0.03 0.02 0 117 0 1 Misses in library cache during parse: 1Optimizer mode: ALL_ROWSParsing user id:
38、55 Rows Row Source Operation- - 1 SORT AGGREGATE (cr=117 pr=0 pw=0 time=24755 us) 12999 INDEX FAST FULL SCAN T1_IND (cr=117 pr=0 pw=0 time=52082 us)(object id 51788) * 在这个例子里面,分区索引之所以扫过了更多的数据块,是因为分区索引在做FFS(INDEX FAST FULL SCAN)的时候只能够在本地索引上进行,如果涉及其他的分区,还需要按照访问索引的方式去访问其他索引(比如先找到其他分区索引的
39、根数据块,再找到最左边的叶块,然后执行FFS操作),这样,查询跨过的分区越多,这种额外的代价就越大;而在这种情况下,全局索引只需要定位到一个叶块,然后执行一次FFS就能够扫过所有的索引叶块,这样性能就会好于分区索引。上面的例子是想说明,OLAP环境中,分区主要的功能是管理上的方便性,它并不能绝对保证查询性能的提高,有时候分区会带来性能上的提高,有时候甚至会降低,就像我们在例子中看到的一样。 1.3 数据库的硬件设计数据库的硬件设计在性能上主要体现在:lCPUlI/Ol 负载情况 这些指标需要对业务进行综
40、合评估和系统测试之后,做出一个合理的硬件配置清单。数据库的硬件设计包含了数据库服务器的架构和数据存储。这些因素在数据库设计阶段将作为重点的考虑因素。如果当系统上线之后,出现冗余或者空间不足的问题,将是一件非常麻烦的事情。数据的存储和安全应该主要考虑以下几个问题。1.3.1 存储容量如果一个系统的生命周期可以确定,或者说数据库中的数据保存时间可以确定,那么我们就可以通过一个简单的计算,大致估算出数据库所存放的数据量的大小,以作为存储设备采购的一个依据。可以通过估算占有存储空间的所有数据库对象(其实主要是估算业务用户下的所有对象)的容量,来计算数据的容量。占用空间的对象都可以在DBA_SEGMEN
41、TS视图里面找到,数据库的空间的分配是以段的形式分配的,凡是段对象,都是要占用空间的,它包括表、索引、物化视图、其他的一些大对象(比如全文索引对象)。如果在开发阶段能够预测每个表的记录数,然后我们取得这个表的字段总长度,于是表的容量=记录数*字段长度。一个表中索引的大小和索引的类型,以及索引键值的重复率有很大的关系,开发人员可以通过模拟一些实际数据来估算出索引和表数据的一个比例,然后做出索引所占空间的估算。一个计算容量的例子如下。我们创建一个表,然后在表上创建索引,之后对表和索引进行分析,然后查询视图user_tables就可以得到表的大致容量。SQL> create table t a
42、s select * from dba_objects; Table created. SQL> create index t_ind on t(object_id); Index created. SQL> exec dbms_stats.gather_table_stats(user,'t',cascade=>true); PL/SQL procedure successfully completed. SQL> select avg_row_len from user_tables whe
43、re table_name='T' AVG_ROW_LEN- 93 这个数值就是表的平均行长,如果我们能够估算出预期表的记录数N,那么最终表占用的空间就是 93 bytes*N:SQL> select segment_name,segment_type,bytes from user_segments where segment_name in ('T','T_IND'); SEGMENT_NAME SEGMENT_TYPE BYTES- - -T TABLE 6291456T_IND INDEX 104857
44、6 SQL> select trunc(1048576/6291456)*100) ind_pct from dual; IND_PCT- 16 我们取得了测试表中表和索引的大小,计算出索引和表大小的百分比,这样,我们就获得了最终这个表的空间使用量为:表的总使用量 = 93 bytes*N(1+16) 这就是预期这个表的容量,如果能够预测出未来数据库的数据量,我们就可以比较客观地估算出数据库预期的容量大小。另外一个容易被开发商忽略的问题是对系统备份数据占用空间的考虑。我遇到的一些系统就有这个问题,系统上线之后才发现,设计人员根本就没有考虑过系统备
45、份的问题,也没有预留出足够的空间来做数据备份,给DBA带来的压力相当大。为了保证数据的安全,我设计了一套备份方案,由于磁盘的空间有限,在备份新的数据的同时,还需要及时删除一些旧的备份数据,在这种磁盘空间捉襟见肘的空隙下工作,DBA有时候觉都不能睡安稳。1.3.2 存储的物理设计现在越来越多的大数据量数据库选择了SAN存储结构(参见图1-2),这是一个扩展性非常好的存储设计,它可以非常方便地将存储设备增加到存储网络当中,但成本和故障点相应地就会变多,对维护人员的技术要求就很高,它不但要求维护人员懂得磁盘阵列的技术,还要掌握SAN交换机的相关技术。 图1-2 SAN存储架构1.3.3 数据的安全数
46、据的安全是系统设计阶段应该充分考虑好的一个问题,要按照用户对数据安全级别要求的高低,以及运行业务停止的时长来设计数据库的安全解决方案。大致来讲,用户对数据安全的要求有如下几个层次。1.3.3.1 Data Guard结构如果用户对数据的安全性要求非常高,并且对系统的宕机时间要求很高,可以考虑Data Guard设计结构(参见图1-3),当主数据库出现故障时,维护人员可以用最短的时间启用备用数据库,保证业务的正常进行。1.3.3.2 RAC结构RAC结构(参见图1-4)和Data Guard结构分属于不同级别的安全设计,Data Guard能够保证数据不丢失或者尽可能少丢失(注:Data Guard有三种保护模式,具体细节请参考Oracle官方文档),它是数据库级别的一个冗余结构。而RAC则是实例级的一个冗余结构,它能够保证数据库在一个实例出现故障之后,用户操作可以无缝地由另外一个实例接管,现在很多对业务连续性要求很高的系统都采用了RAC+Data Guard的数据库结构设计。 图1-3 Data Guard结构 图1-4 RAC结构1.3.3.3 Rman+归档的方式Rman+归档的备份方式相对RAC+Data Guard来看,它的优势在于成本上要廉价,并
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 高中原电池课件
- 高中doing课件教学课件
- 高一知识培训课件
- 山地土地租赁合同范本(山地生态旅游项目合作开发)
- 知识产权评估与交易全权委托合作协议书
- 金融信息行业用工合同及商业秘密保护协议
- 宫颈糜烂护理知识细则
- 心理学在安全生产中的应用
- 养殖场水质监测指南
- 如何引导初高中学生建立正确的人生规划
- 2025年下半年全国教师资格证考试中学《综合素质》真题及答案
- 2025年乡镇综合执法队员职业素养要求及考试要点
- 2025年村级后备干部考试题库(含答案)
- 2025-2026学年教科版(2024)小学体育与健康三年级全一册《情绪会调控》教学设计
- 2025合同范本技术咨询合同
- 脑梗死恢复期护理查房范文讲课件
- 京东安全工程师笔试题库
- 2025版校园食堂日管控、周排查、月调度记录表
- ISO 37001-2025 反贿赂管理体系要求及使用指南(中文版-雷泽佳译-2025)
- 高等数学精品课程说课课件
- 10kv高压无功补偿装置技术规范书
评论
0/150
提交评论