使用BBED修改SCN

2012-05-09

目前还没有人发表评论 | 赶紧发表评论吧 | 作者:vogts

下面这个错误,我想是很多DBA的痛。

@>startup ;
ORACLE instance started.

Total System Global Area  838860800 bytes
Fixed Size                  2087608 bytes
Variable Size             494929224 bytes
Database Buffers          335544320 bytes
Redo Buffers                6299648 bytes
Database mounted.
ORA-01113: file 5 needs media recovery
ORA-01110: data file 5: ‘/data/oracle/oradata/orcl/wt_tbs01.dbf’

有备份还好,没备份基本上只有把数据文件offline了。DBA准备打包回家吧。

经过无数次的测试,确认修改SCN号可以搞定。目前网上的文章,多少还是有些错误。经过反复的测试,确认没有问题。
我们直接使用BBED查看下当前SYSTEM TBS表空间的SCN号:

BBED> set file 1
FILE#           1

数据文件头就是第一个block块,因此我们不需要设置其他block块,
此外map可以显示block里的详细信息。我们发现就一个“kcvfh”,OK直接查看这个吧。
BBED> map
File: /data/oracle/oradata/bops10g/system01.dbf (1)
Block: 1                                     Dba:0×00400001
————————————————————
Data File Header

struct kcvfh, 676 bytes                    @0

ub4 tailchk                                @8188

print出来的内容太多,我做了删剪,留下我们有用的内容。
BBED> print kcvfh
struct kcvfh, 676 bytes                     @0
…………………………
struct kcvfhckp, 36 bytes                @484
struct kcvcpscn, 8 bytes              @484
ub4 kscnbas                        @484      0×000748bf–SCN的低位
ub2 kscnwrp                        @488      0×0000–SCN的高位
ub4 kcvcptim                          @492      0×2ea86f92 –最后一次checkpoint time
ub2 kcvcpthr                          @496      0×0001

………………………………
ub4 kcvfhcpc                             @140      0×0000007f—checkpoint count
ub4 kcvfhrts                             @144      0×2ea86844
ub4 kcvfhccc                             @148      0×0000007e
–oracle 一个TBS最多30个字符,通过BBED ,我们发现这里是定长的
text kcvfhtnm[0]                         @338     S
text kcvfhtnm[1]                         @339     Y
text kcvfhtnm[2]                         @340     S
text kcvfhtnm[3]                         @341     T
text kcvfhtnm[4]                         @342     E
text kcvfhtnm[5]                         @343     M
text kcvfhtnm[6]                         @344
text kcvfhtnm[7]                         @345
text kcvfhtnm[8]                         @346
text kcvfhtnm[9]                         @347
text kcvfhtnm[10]                        @348
text kcvfhtnm[11]                        @349
text kcvfhtnm[12]                        @350
text kcvfhtnm[13]                        @351
text kcvfhtnm[14]                        @352
text kcvfhtnm[15]                        @353
text kcvfhtnm[16]                        @354
text kcvfhtnm[17]                        @355
text kcvfhtnm[18]                        @356
text kcvfhtnm[19]                        @357
text kcvfhtnm[20]                        @358
text kcvfhtnm[21]                        @359
text kcvfhtnm[22]                        @360
text kcvfhtnm[23]                        @361
text kcvfhtnm[24]                        @362
text kcvfhtnm[25]                        @363
text kcvfhtnm[26]                        @364
text kcvfhtnm[27]                        @365
text kcvfhtnm[28]                        @366
text kcvfhtnm[29]                        @367
………………………………

这4个offset的位置内容,文档上是这样说的:

Oracleconsiders four attributes of this data structure when determining if a datafile is sync with the other data files of the database:

(1)kscnbas (at offset 484) - SCN of last change to the datafile.

(2)kcvcptim (at offset 492) -Time of the last change to the datafile.

(3)kcvfhcpc (at offset 140) - Checkpoint count.

(4)kcvfhccc (at offset 148) - Unknown, but is always 1 less than thecheckpoint point count.

oracle主要通过这4个来判断一致性,至于中文说明,我也写在上面了。

接下去,我们看看坏掉的wt-tbs01.dbf的信息:

wt_tbs.dbf
struct kcvfhckp, 36 bytes                @484
struct kcvcpscn, 8 bytes              @484
ub4 kscnbas                        @484      0×000747a5
ub2 kscnwrp                        @488      0×0000
ub4 kcvcptim                          @492      0×2ea86f03
ub2 kcvcpthr                          @496      0×0001
union u, 12 bytes                     @500
struct kcvcprba, 12 bytes          @500
ub4 kcrbaseq                    @500      0×00000004
ub4 kcrbabno                    @504      0×00000019
ub2 kcrbabof                    @508      0×0010
**********************
ub4 kcvfhcpc                             @140      0×00000007
ub4 kcvfhrts                             @144      0×2ea86844
ub4 kcvfhccc                             @148      0×00000006

好,484,492,140,148直接修改就好了。
/**************
484
****************/
ub4 kscnbas                        @484      0×000747a5-> 0×000748bf–> bf487400

set offset 484
modify /x bf48
set offset 486
modify /x 0700

/**************
492
******************/
ub4 kcvcptim                          @492      0×2ea86f03->0×2ea86f92 –>926fa8ea

set offset 492
modify /x 926f
set offset 494
modify /x a82e

/**************
140
******************/

ub4 kcvfhcpc                             @140      0×00000007->0×0000007f–>7f000000

set offset 140
modify /x 7f00
set offset 142
modify /x 0000

/**************
148
**************/
ub4 kcvfhccc                             @148      0×00000006->0×0000007e->7e000000

set offset 148
modify /x 7e00
set offset 150
modify /x 0000

最后做下checksum,就OK了

BBED> sum dba 5,1 apply
Check value for File 5, Block 1:
current = 0×554c, required = 0×554c
接下去就简单了,重建控制文件,数据库OPEN RESETLOG搞定

@>startup nomount;
ORACLE instance started.

Total System Global Area  838860800 bytes
Fixed Size                  2087608 bytes
Variable Size             494929224 bytes
Database Buffers          335544320 bytes
Redo Buffers                6299648 bytes
@>CREATE CONTROLFILE REUSE DATABASE “orcl” RESETLOGS  NOARCHIVELOG
2      MAXLOGFILES 5
3      MAXLOGMEMBERS 5
4      MAXDATAFILES 100
5      MAXINSTANCES 1
MAXLOGHISTORY 292
6    7  LOGFILE
8    GROUP 1 ‘/data/oracle/oradata/orcl/redo101.log’  SIZE 10M,
9    GROUP 2 ‘/data/oracle/oradata/orcl/redo201.log’  SIZE 10M,
10    GROUP 3 ‘/data/oracle/oradata/orcl/redo301.log’  SIZE 10M
11  — STANDBY LOGFILE
12  DATAFILE
13    ‘/data/oracle/oradata/orcl/system01.dbf’,
14    ‘/data/oracle/oradata/orcl/undotbs01.dbf’,
15    ‘/data/oracle/oradata/orcl/sysaux01.dbf’,
16    ‘/data/oracle/oradata/orcl/users01.dbf’,
17    ‘/data/oracle/oradata/orcl/wt_tbs01.dbf’
18  CHARACTER SET US7ASCII
19  ;

Control file created.

@>RECOVER DATABASE USING BACKUP CONTROLFILE
ORA-00279: change 477375 generated at 05/09/2012 01:49:06 needed for thread 1
ORA-00289: suggestion : /data/oracle/arch/orcl/1_4_782784012.arc
ORA-00280: change 477375 for thread 1 is in sequence #4

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
cancel
Media recovery cancelled.
@>ALTER DATABASE OPEN RESETLOGS;

Database altered.

小小广告下,我的微薄( ),http://weibo.com/vogts 有问题可以直接找我一起探讨下,Thanks!



DBA团队的使命

2011-08-16

有9人发表了评论 | 赶紧发表评论吧 | 作者: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

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

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

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

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

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

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

Why?

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

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

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

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

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

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

原文出自:  NoSQL or Relational ?



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

2011-01-20

有8人发表了评论 | 赶紧发表评论吧 | 作者: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

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

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物理读的次数会显著增加



较旧的文章

DBA