DBA团队的使命

2011-08-16

有7人发表了评论 | 赶紧发表评论吧 | 作者:grassbell

DBA团队的使命:提供高可用、高性能、可扩展的数据存储服务

高可用:可用性是运维的根本,我们不管做什么事情,都要把可用性放在第一位。
高性能:对性能的关注是我们一直坚持、做的最好的一面,仍需要继续做到极致。
可扩展:也就是最适合的,易部署,可线形透明伸缩。
数据存储:不只是关注某个数据库本身,是基于对各种最先进的数据存储技术的精深理解,提供最专业的服务



Alibaba DBA 团队招聘高级JAVA工程师

2011-08-09

有8人发表了评论 | 赶紧发表评论吧 | 作者:grassbell

岗位名称:高级JAVA工程师
岗位描述:负责数据库运营相关系统设计、开发
工作地点: 杭州
职位要求:
1、精通web编程,3年以上java web开发经验。
2、熟悉html,javascript,至少掌握一种web界面开发方法,有extjs开发经验优先。
3、熟悉jsp,jdbc开发,熟悉基于spring,ibatis框架的java开发。
4、熟悉数据库开发技术,对数据库技术有浓厚兴趣。Oracle或者MySQL均可。
5、熟悉linux操作系统。
6、具有良好的学习能力,沟通技能,团队合作能力。

说白了,只要你有几年JAVA WEB开发经验,对数据库内部技术有浓厚兴趣,都欢迎加入。
在这里,你可以与国内顶级DBA一起切磋数据库问题,可以对海量数据进行分析与挖掘,掌握快速发现系统性能瓶颈的方法。

职位发展方向:开发技术、数据库技术、运维经验思想三位一体的牛人。

简历请发给: zhengsheng.yezs@alibaba-inc.com



oracle 9i&10g 数据库实现11g active standby 的方法

2011-04-26

有6人发表了评论 | 赶紧发表评论吧 | 作者:admin

还记得以前部门同事一起讨论过一个问题, 能否让oracle 9i ,10g standby数据库 可以边恢复边提供读服务? 提供像11g active standby 类似的功能,还问过oracle 是否有专门的包可以下放到9i,10g 数据库,打个补丁之类的就可以提供此功能

最近发现市场上竟然真的有这样的产品,据说卖的很不错,主要应用在移动电信领域,了解了一下,基本知道其中的做法,里面的有些想法还是蛮有意思的,跟大家分享一下:

其实原理也很简单,他们是解析了oracle redolog 文件,不过他们解析的是变化的块号,然后根据变化的块号,到主库去将文件中的数据块读取出来,最后覆盖到standby 中对应的数据文件(standby 一直是处于open read only 状态)。

这样覆盖后,就有个需要处理的地方

1 . 如果原先有一个数据块被cache ,那么覆盖了数据文件后,为了得到最新的数据,就需要程序定期去刷新buffer cache ,从而才能让oracle 去读取最新的数据块。

2. 由于程序去定期刷新buffer cache ,那么如果发出一个select 查询,就会出现有些块在内存中数据已经是比较老的,有些数据块直接从文件中读取读取的是最新的数据块,这样就会造成数据不一致的情况。 那这种情况怎么去处理呢 ? 是否记得oracle 中有个语法 select * from table as scn of XX ? 让oracle 自己去查询某个时间点的数据,自己去构造一致性读取。但是这样就会造成另外一个问题,这个SCN 号如何去取呢 ? 那么很简单,我们只要select min(scn) from x$bh where scn > 我上次flush buffer cache 时间点的SCN, 得到buffer cache 中最小数据块的SCN 号,然后发出一个命令,以小于buffer cache 中最小SCN 号的方式去查询,那么就可以查到一致的数据。比如buffer cache 中数据块最小的SCN 号 是100 ,那么我们select * from table as scn of 95 ,那么肯定数据查出来在那个时间点是一致的。 这样就带来另外一个问题,是不是需要让应用去改造sql 呢,每个select 都要加上scn 号去查询? 这边就用了一个技巧,先得到全局SCN 号在SGA 中的内存地址,然后用程序去修改成我们需要的SCN 号,这样oracle 去查询的时候总是会去构造一致性查询

好了,解决了上面的问题,还有一个问题就是DDL 引起的share pool 的变化,这就需要程序去定期刷新shared pool ,虽然我一直认为这会存在问题,但是据卖这款产品说,客户反映用的还蛮好

看的出来,上面做的东西在OLTP 中不太好用,跟oracle 11g 的active standby 也存在差距。但是如果用在报表系统或者给DW 批量拉数据,还是非常不错的。在保证有备份的同时,又能给用户提供服务,最大化利用了资产



NoSQL or Relational ?

2011-01-20

有3人发表了评论 | 赶紧发表评论吧 | 作者:sky

随着数据存储技术的迅猛发展,随着各种 NoSQL 技术的产生,无论是我们同事之间还是整个互联网行业,都出现关于“分布式 数据 存储/处理 解决方案”方面的选择分歧。就我目前所了解到的主流意见主要有以下三种:

  • 去关系型,NoSQL是王道
  • NoSQL靠边站,关系型才是王道
  • 以关系型为核心,NoSQL为补充

三种意见中前面两种观点较为极端,都是“非对即错”的选择,当然也有更为理性的第三种方案。

如果作为开发人员,从我目前所了解的信息来看,主要还是倾向于第一种思路。因为在他们看来,分布式的 NoSQL 系统是一个非常美的架构,不仅仅解决了扩展性的问题,同时也解决了可靠性问题,同时还可以让程序开发免去关系型模型的约束,不选择他才是傻子呢!

从我个人的角度来看,我目前更倾向于第三种思路,至少在现阶段是如此。

Why?

但是如果是从运维的角度出发,所考虑的风险点可能完全不一样。作为一个存储数据的核心组件,在需要对其数据进行人工订正维护的时候是否方便操作?在需要抽取其中某部分数据到线下给开发/测试部门使用的时候是否方便?最重要的是,当他整个 Crash 之后我们可以怎么恢复?当我们面对这些问题的时候,我们是否有合适便利的手段来避免或者解决?

确实,理念很完美,架构很完美,但目前的NoSQL产品的实现是不是真的也如此完美呢?我想没有哪个产品敢拍着自己的胸脯说他们的产品不会Crash,就像没有厂商向我们保证他们的硬件在达到标称的使用寿命之前不会损坏一样。既然存在整个 Crash 的可能,那就必须考虑如何应对。我们不能只是考虑这个听上去完美的分布式系统在某个节点 Crash 之后可以很好的”自愈”,不能只考虑当目前整个集群资源达到瓶颈之后仅仅只需要在线增加一个节点就可以”自我完成负载/数据重分布”。我们还需要考虑他的整体可靠性,还需要考虑更为恶劣的环境更为残酷的场景下,他是否还能生存。

关系型数据库在刚开始产生的时候,同样面临了各种各样的问题,同样受到过大量的质疑。但是,当他在风风雨雨中走过了这么多年之后,通过不断的完善和适应,不论在灾难恢复方面还是在可操作性和可维护性方面都做了大量的工作。当然,在这么多年的市场需求下,也培养出了大量的专业技术人员。但 NoSQL 发展到现在,才经历了很短的时间,缺少在恶劣环境下的磨炼,缺少复杂环境下的检验,更缺少有丰富经验的专业技术人员。在这种情况下,你还敢轻易决定将一个公司最为核心的资本(数据)轻易从关系型数据库中迁移出来吗?

当然,我们并不一定要一个完美的产品,就像我们无法让我们自己成为一个完美的人一样。但我们必须清楚一个产品的可能存在的风险和缺陷,并且清楚如何做能避免这些风险和缺陷,同时还要让我们自己有能力避免这些风险和缺陷。只有在这样的前提下,我们才会在比较重要的场景下使用。但要积累这些经验,积累这些信任,培养专业技术人员,都需要一定的时间。

所以在我个人看来,在近几年,NoSQL 暂时还不可能成为数据管理软件领域的主角,仍然只能作为特定场景下的数据存/取解决方案的补充,即使在互联网行业也是如此。至于在未来,比如五年十年以后会是什么样子,我就无法预测了。

注:文中观点仅代表个人,基于个人目前的认知,欢迎大家拍砖!

原文出自:  NoSQL or Relational ?



单个MySQL Instance 接多个 Master 的一点想法

2011-01-20

有7人发表了评论 | 赶紧发表评论吧 | 作者:sky

时常遇到一些希望从多个 MySQL 实例将数据复制到单个MySQL 实例上的需求场景,又苦于原生的 MySQL 并不支持这样的实现方案,开源社区中也没有哪位大拿提供解决这方面需求的插件。 有时候就想,要不公司里面组织力量修改一下 MySQL 代码来搞定这个问题得了。可转念一想,后面如果需要升级版本的时候怎么办呢?再修改一次代码?这样的成本有多大呢?如此的问题让人很是纠结。 最近突然想明白了:为啥非要在现在代码中来实现这个需求呢?为啥不能通过在外部想办法呢?我们需要的不是看上去的美,而是最终的结果。看上去漂亮完美的架构方案并不一定就是最好的。 如是就有了下面这样的想法:

  • 通过在 Master 和 Slave 之间增加一层复制代理服务
  • 多个线程连接上多个 Master 上请求 Binlog(完全模拟 Slave 上的IO线程)
  • 多个线程连接上单个 Slave 实例,直接以类似于应用程序的方式并行应用 Binlog中的Event(部分模拟Slave 上的SQL线程)
  • 由于很清楚业务场景,在应用线程方面可以在一些特定规则约束下实现并行应用以改善 Slave 端延时

由于 MySQL 开源的特性,实现上述功能其实很简单,还可以保持原生 MySQL 不会被动任何手术即可完成我们的需求,看来是该动手的时候了。

BTW: 我的需求中,各个 Master 中的数据是不会有任何重叠的。

原文出自: 单个MySQL Instance 接多个 Master 的一点想法



OOW 分享的 PPT

2011-01-20

有2人发表了评论 | 赶紧发表评论吧 | 作者:sky

前几天,受 Oracle 所遥,在 OOW 上的 OTN Lounge 分享了一下最近一年来在利用MySQL 在高可用可扩展架构方面的一些心得,这里贴上 PPT,供大家拍砖。

内容方面,前面的部分可能有不少朋友以前有看到过,可能是听我介绍过,也有可能本身自己就对这些架构很了解。无所谓,只要能对一少部分人有用,那也欣慰。不过,最后两页 PPT 的内容,我想肯定没有人在其他渠道见过,因为这两张图片是我第一次在公开场合展示。

废话少说,上 PPT 吧,呵呵!

高可用可扩展数据层 - MySQL架构实践

View more presentations from Sky Jian.

原文出自:OOW 分享的 PPT



Oracle hash join

2010-11-28

有6人发表了评论 | 赶紧发表评论吧 | 作者:八神

hash join是oracle里面一个非常强悍的功能,当做hash join时,oracle会选择一个表作为驱动表,先根据过滤条件排除不必要的数据,然后将结果集做成hash表,放入进程的hash area,接着扫描第二张表,将行的键值做hash运算,到内存的hash表里面去探测,如果探测成功,就返回数据,否则这行就丢弃掉这个是最基本的解释,实际情况中,考虑到单个进程PGA的大小,oracle不会让进程任意的消耗OS内存,hash area是有一定限制的,所以在oracle中,hash也有三种模式:
optimal,onepass,multipass

optimal:当驱动结果集生成的hash表全部可以放入PGA的hash area时,称为optimal,大致过程如下:
1.先根据驱动表,得到驱动结果集
2.在hash area生成hash bulket,并将若干bulket分成一组,成为一个partition,还会生成一个bitmap的列表,每个bulket在上面占一位
3.对结果集的join键做hash运算,将数据分散到相应partition的bulket中,当运算完成后,如果键值唯一性较高的话,bulket里的数据会比较均匀,也有可能有的桶里面数据会是空的,这样bitmap上对应的标志位就是0,有数据的桶,标志位会是1
4.开始扫描第二张表,对jion键做hash运算,确定应该到某个partition的某个bulket去探测,探测之前,会看这个bulket的bitmap是否会1,如果为0,表示没数据,这行就直接丢弃掉
5.如果bitmap为1,则在桶内做精确匹配,判断OK后,返回数据

这个是最优的hash join,他的成本基本是两张表的full table scan,在加微量的hash运算

onepass
如果进程的pga很小,或者驱动表结果集很大,超过了hash area的大小,会怎么办?当然会用到临时表空间,此时oracle的处理方式稍微复杂点需奥注意上面提到的有个partition的概念,可以这么理解,数据是经过两次hash运算的,先确定你的partition,再确定你的bulket,假设hash area小于整个hash table,但至少大于一个partition的size,这个时候走的就是onepass
当我们生成好hash表后,状况是部分partition留在内存中,其他的partition留在磁盘临时表空间中,当然也有可能某个partition一半在内存,一半在磁盘,剩下的步骤大致如下:
1.扫描第二张表,对join键做hash运算,确定好对应的partition和bulket
2.查看bitmap,确定bulket是否有数据,没有则直接丢弃
3.如果有数据,并且这个partition是在内存中的,就进入对应的桶去精确匹配,能匹配上,就返回这行数据,否则丢弃
4.如果partition是在磁盘上的,则将这行数据放入磁盘中暂存起来,保存的形式也是partition,bulket的方式
5.当第二张表被扫描完后,剩下的是驱动表和探测表生成的一大堆partition,保留在磁盘上
6.由于两边的数据都按照相同的hash算法做了partition和bulket,现在只要成对的比较两边partition数据即可,并且在比较的时候,oracle也做了优化处理,没有严格的驱动与被驱动关系,他会在partition对中选较小的一个作为驱动来进行,直到磁盘上所有的partition对都join完

可以发现,相比optimal,他多出的成本是对于无法放入内存的partition,重新读取了一次,所以称为onepass,只要你的内存保证能装下一个partition,oracle都会腾挪空间,每个磁盘partition做到onepass

multipass
这是最复杂,最糟糕的hash join,此时hash area小到连一个partition也容纳不下,当扫描好驱动表后,可能只有半个partition留在hash area中,另半个加其他的partition全在磁盘上,剩下的步骤和onepass比价类似,不同的是针对partition的处理
由于驱动表只有半个partition在内存中,探测表对应的partition数据做探测时,如果匹配不上,这行还不能直接丢弃,需要继续保留到磁盘,和驱动表剩下的半个partition再做join,这里举例的是内存可以装下半个partition,如果装的更少的话,反复join的次数将更多,当发生multipass时,partition物理读的次数会显著增加



oracle数据库的CPU/IO信息采集

2010-11-04

有4人发表了评论 | 赶紧发表评论吧 | 作者:八神

CPU时间采集

从10G开始,oracle引入了时间模型,我们可以从oracle的角度来看CPU的使用程度
先说说几个概念
db time:oracle数据库消耗的时间,这个范围比较大,包括了CPU使用,等待IO子系统返回,网络处理等
db cpu:指oracle单纯消耗CPU,做CPU运算的时间,关于IO,网络的等待都不在这个范围内,用它来统计真实CPU的消耗比较准确
CPU TIME:这个是我取的名字,表示CPU能给你提供的最大时间,比如你有4个cpu/core,那么1小时内,CPU TIME就是4X60分钟

我通过一个测试脚本来看看oracle里面关于CPU时间的统计

#killcpu.sh
#!/bin/sh
export ORACLE_SID=innodb
export ORACLE_HOME=/opt/oracle/products/11.2.0

$ORACLE_HOME/bin/sqlplus /nolog <<_kof_
connect iops/iops@innodb
declare v_count pls_integer := 0;
begin
        for x in 1..400000000 loop
                for d in 1..400000000 loop
                        for c in 1..400000000 loop
                                v_count :=mod(c, mod(x,d));
                        end loop;
                end loop;
        end loop;
end;
/
_kof_

测试机器是Intel(R) Xeon(R) CPU E7530的4C6核 CPU,虚拟出来总共是48个core
killcpu采用24并发,48并发,60并发做测试,每个10分钟,通过statspack收集信息,按照上面的公式,我们的cpu time=10min*60 * 48core=28800秒
最终结果如下(时间单位都是秒):

并发数 db time db cpu cpu time top显示CPU占用率 LOAD
24 14066 14064 28800 50 24
48 27984 27401 28800 100 48
60 34556 27179 28800 100 57

从结果可以看出:
24并发,oracle使用了24个core,整体的CPU占用率在50%,load在24,非常准确,此时db time基本和db cpu一致,因为你干的所有事情,都是在CPU上
48并发,oracle使用了48个core,CPU使用率达到100%,oracle在多cpu环境下对资源的利用确实很高,此时db time,db cpu,cpu time一致了,CPU在满负荷运转
60并发,这个时候会发现,db cpu没变,因为CPU已经耗尽,没得涨了,db time现在已经远大于cpu time和db cpu,这说明我们有一部分的程序根本抢不到CPU,进入了
等待,load也超过了core数量,达到57

通过db cpu/db time,我们可以看出这个数据库是否是CPU使用很重的应用,比如大量的运算,latch争用等,
如果是一个IO很重的应用,会发现db cpu站的比例会很小

IO负载统计

IO表现在两个方面,IOPS和吞吐量,我们OLTP系统,一般比较关心IOPS,及每个IO的响应时间,
以前针对IOPS统计,我们一直是按照statspack的physical reads+physical writes来统计,这个是很不准确的
按照文档的解释:
physical reads:Total number of data blocks read from disk
这个是按照block读取的数量来统计的,oracle的IO种类有很多,如果是scatter read或者parallel read,一个IO会读取多块的,
这样计算IOPS会偏大,重新调整后,发现统计出来的曲线和从存储段观察的比较吻合

9I:
–IOPS&MBPS
select sum(iops) as iops,sum(mbps) as mbps
from (
select sum(phyrds + phywrts) as IOPS,
sum(phyblkrd + phyblkwrt) as MBPS
from (select a.phyrds,a.phywrts,a.phyblkrd * b.block_size / 1024 / 1024 as phyblkrd,a.phyblkwrt * b.BLOCK_SIZE / 1024 / 1024 as phyblkwrt
from v$filestat a,v$datafile b
where a.file# = b.file#)
union all
select sum(decode(name,’redo writes’,value,’0′)) as IOPS,
sum(decode(name,’redo size’,value,’0′)) / 1024 / 1024  as MBPS
from v$sysstat where name in( ‘redo writes’,'redo size’));

10G/11G
–IOPS&MBPS
select sum(decode(name,’physical read IO requests’,value,’physical write IO requests’,value,0)) as iops,
sum(decode(name,’physical read bytes’,value,’physical write bytes’,value,0)) / 1024 / 1024 as mbps
from v$sysstat
where name in (’physical read IO requests’,'physical write IO requests’,
‘physical read bytes’,'physical read total bytes’,
‘physical write bytes’,'physical write total bytes’,'physical read total IO requests’,'physical write total IO requests’
);

最近将这些统计指标做进了监控系统,看看效果怎么样



较旧的文章

DBA