昨天有人问我redo log file header,redo block header, redo record header的区别,这三个确实容易混淆,简单聊聊这三个概念,This is importance.
以16进制格式来分析.偶尔会穿插点10进制的dump格式.
一.redo log file header

redo log file header即为重做日志文件头,文件头的内容部分其实包含2个,一个为file header block,一个为redo log header block.可能这么说还有点含糊,那么看下面这张图:

3

如上图所示,一个redo log文件的头部有2个块,第一个块为file header block,第二个块为redo log header block.下面大致的分析下每个块的存储内容.
截取第一个块的内容如下(我用UE打开格式):

log1

10进制的dump格式:

DUMP OF REDO FROM FILE '/oradata/ora10g/lu10g/redo03.log'
 Opcodes *.*
 RBAs: 0x000000.00000000.0000 thru 0xffffffff.ffffffff.ffff
 SCNs: scn: 0x0000.00000000 thru scn: 0xffff.ffffffff
 Times: creation thru eternity
 FILE HEADER:
	Compatibility Vsn = 169870080=0xa200300
	Db ID=2561616225=0x98af2961, Db Name='LU10G'
	Activation ID=2561579617=0x98ae9a61
	Control Seq=564=0x234, File size=102400=0x19000
	File Number=3, Blksiz=512, File Type=2 LOG
 descrip:"Thread 0001, Seq# 0000000009, SCN 0x00000099c24d-0x0000009a40c4"
 thread: 1 nab: 0x16910 seq: 0x00000009 hws: 0x4 eot: 0 dis: 0
 resetlogs count: 0x31bca923 scn: 0x0000.000716f7 (464631)
 resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
 prev resetlogs count: 0x268ea86b scn: 0x0000.00000001 (1)
 prev resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
 Low  scn: 0x0000.0099c24d (10076749) 04/15/2014 12:08:04
 Next scn: 0x0000.009a40c4 (10109124) 04/16/2014 06:56:19
 Enabled scn: 0x0000.000716f7 (464631) 12/17/2013 23:00:51
 Thread closed scn: 0x0000.0099c24d (10076749) 04/15/2014 12:08:04
 Disk cksum: 0xeb7d Calc cksum: 0xeb7d
 Terminal recovery stop scn: 0x0000.00000000
 Terminal recovery  01/01/1988 00:00:00
 Most recent redo scn: 0x0000.00000000
 Largest LWN: 2134 blocks
 End-of-redo stream : No
 Unprotected mode
 Miscellaneous flags: 0x0
 Thread internal enable indicator: thr: 0, seq: 0 scn: 0x0000.00000000

在ue打开的16进制中每行是16bytes,一共32行,这为第一个块file header block.这个block包含的信息有限,逐一分析:
从第一个字节开始到第二个字节为0×22,这2个字节通常为oracle 文件类型的标识,像数据文件的开头这里就为0xA2,这里的0×22就代表redo log file.接着下来第一行就没有有意义的东西了其中的0xFFC0应该和scn中的base部分有关.再看看第二行的16个字节,可以发现在第21和22字节0×0200换算成10进制格式则为512,这里即代表block size.从第25到28字节0×00019000换算成10进制后为102400,而0×00019000代表redo block的数量,这里即为代表这个file的blocks或者理解为这个file的size.而在后续跟着的0x7a7b7c7d为文件标识符,为oracle快速识别文件的一种标识.到这之后第一个块的信息就没啦!

接下来分析第二个块redo log header block,第二个块的信息是在文件中的第33行开始,具体如下:
log2

后续再更新吧,有点耗时间.

, ,

此文章摘自id 28989.1,为解析redo部分必读的一个文章,没翻译,大家凑合吧.
====================================================================
You are working with Oracle Technical Support. As part of the diagnostic
process, you have been asked to take a dump of the redo log files. The
information in the logs is often used to help diagnose corruption issues.

The following commands will be used in this process:

1. The ‘alter session’ command is used to dump redo headers.

2. Use the ‘alter system dump logfile’ to dump log file contents.

This command requires ‘ALTER SYSTEM’ system privilege. The database can be in
mount, nomount or open state when the command is issued. An online log file
or an archived log file can be dumped. It is even possible to dump a
file from another database, as long as the operating systems are the same.

Output from the command is put into the session’s trace file.

The following ways of dumping a redo log file are covered:

1. To dump records based in DBA (Data Block Address)
2. To dump records based on RBA (Redo Block Address)
3. To dump records based on SCN
4. To dump records based on time
5. To dump records based on layer and opcode
6. Dump the file header information
7. Dump an entire log file:

1. To dump records based on DBA (Data Block Address)
————————————————–

This will dump all redo records for the range of data
blocks specified for a given file # and block # range.

From sqlplus (sqldba or svrmgr for older versions), issue the following command:

ALTER SYSTEM DUMP LOGFILE ‘filename’
DBA MIN fileno . blockno
DBA MAX fileno . blockno;

Example:
========
ALTER SYSTEM DUMP LOGFILE ‘u01/oracle/V7323/dbs/arch1_76.dbf’
DBA MIN 5 . 31125
DBA MAX 5 . 31150;

This will cause all the changes to the specified range of data blocks to be
dumped to the trace file. In the example given, all redo records for file #5,
blocks 31125 thru 31150 are dumped.

Note
====
For 10g:
ALTER SYSTEM DUMP LOGFILE ‘u01/oracle/V7323/dbs/arch1_76.dbf’
DBA MIN 5 . 31125 DBA MAX 5 . 31150;

will raise:
ORA-01963: Must specify a block number

In 10g we need to skip the dot ‘.’ while doing the redo dumps
ALTER SYSTEM DUMP LOGFILE ‘u01/oracle/V7323/dbs/arch1_76.dbf’
DBA MIN 5 31125 DBA MAX 5 31150;

@ As per Bug 3536989

2. To dump records based on RBA (Redo Block Address)
————————————————-

This will dump all redo records for the range of redo
addresses specified for the given sequence number and block number.

Syntax:
ALTER SYSTEM DUMP LOGFILE ‘filename’
RBA MIN seqno . blockno
RBA MAX seqno . blockno;

Example:
ALTER SYSTEM DUMP LOGFILE ‘u01/oracle/V7323/dbs/arch1_76.dbf’
RBA MIN 2050 . 13255
RBA MAX 2255 . 15555;

3. To dump records based on SCN
—————————-

Using this option will cause redo records owning changes within the SCN range
specified to be dumped to the trace file.

ALTER SYSTEM DUMP LOGFILE ‘filename’
SCN MIN minscn
SCN MAX maxscn;

Example:
ALTER SYSTEM DUMP LOGFILE ‘u01/oracle/V7323/dbs/arch1_76.dbf’
SCN MIN 103243
SCN MAX 103294;

If the purpose is to check the dumpfile you can rather do the following,
SQL> ALTER SYSTEM DUMP LOGFILE ‘filename’ SCN MIN 1 SCN MAX 1;

If the above completes sucessfully it ensures no issues with the archivelog.

4. To dump records based on time.
——————————

Using this option will cause redo records created within the time range
specified to be dumped to the trace file.

From sqlplus (sqldba or svrmgr for older versions), issue the following command:

ALTER SYSTEM DUMP LOGFILE ‘filename’
TIME MIN value
TIME MAX value;

Example:
========
ALTER SYSTEM DUMP LOGFILE ‘u01/oracle/V7323/dbs/arch1_76.dbf’
TIME MIN 299425687
TIME MAX 299458800;

Please Note: the time value is given in REDO DUMP TIME

@See Note 34026.1 for SQL script on converting date/time to REDO DUMP time.

5. To dump records based on layer and opcode.
——————————————

LAYER and OPCODE are used to dump all log records for a particular type of
redo record, such as all dropped row pieces.

From sqlplus (sqldba or svrmgr for older versions), issue the following command:

ALTER SYSTEM DUMP LOGFILE ‘filename’
LAYER value
OPCODE value;

Example:
========
ALTER SYSTEM DUMP LOGFILE ‘u01/oracle/V7323/dbs/arch1_76.dbf’
LAYER 11
OPCODE 3;

@Note: See Note 29733.1 for the list of LAYER and OPCODE values and their
@meaning.

6. Dump the file header information:
———————————

This will dump file header information for every
online redo log file.

From sqlplus (sqldba or svrmgr for older versions), issue the following command:

alter session set events ‘immediate trace name redohdr level 10′;

For dumping archivelog header,issue the following command:

ALTER SYSTEM DUMP LOGFILE ‘filename’ RBA MIN 1 1 RBA MAX 1 1;

7. Dump an entire log file:
————————

From sqlplus (sqldba or svrmgr for older versions), issue the following command:

ALTER SYSTEM DUMP LOGFILE ‘filename’;

Please note:
Fully qualify the filename, and include the single quotes.

Example:
========
ALTER SYSTEM DUMP LOGFILE ‘u01/oracle/V7323/dbs/arch1_76.dbf’;

The dump of the logfile will be written into a trace file in the udump destination.
Use the command ‘show parameters dump’ within an sqlplus session.
The ouput will show the location for the udump destination where
the trace file exists.

@ References:
@ ===========
@ Note 28989.1

声明:我写这一系列文章纯作为个人兴趣研究,只代表个人观点,如有误欢迎大家斧正.
在说明vector之前我补充要对redo log file header以及redo block header还有redo record header做个区分

change vector顾名思义变更向量,redo record中除了header之外,存储的就是change vector.它

,

本文以Oracle服务为背景,讲述工程师如何面对客户,我觉得讲得很有道理,转到博客,原文摘自转自CSDN.

一. 概述
oracle数据库服务的市场需求也是十分巨大的,国内在做oracle第三方服务的厂商挺多,面对如此众多的卖方选择,面对着令人眼花缭乱的服务商,可以说既爱又恨。爱的是有时候真的能帮自己解决问题,减轻自己的压力,有时候又解决不了问题,让自己也不好交代。
客户工程师各有不同,他们有自己的喜好,有自己的情绪。而对于提供oracle服务的工程师来说,同样有自己的喜怒哀乐。客户的喜好忧愁,与服务商工程师的酸甜苦辣交织在一起,谱写了五彩斑斓的服务与被服务篇章。
作为处于弱势地位的现场工程师,如何去面对处于甲方地方的客户工程师?都值得每个现场工程师很好总结和体味。经历这些真实的挑战,一定对客户是上帝的理解十分深刻。
现场工程师,面对的不仅仅只是技术问题,实际上是一个公司的代表。很多技术也许派不上用场,需要自己灵活处置、随机应变。需要把握一个度,快速、准确、弱势、协调、解释。当然,在现场,具备解决问题的技术能力是必要的,在这个基础上,具备应对现场的过硬的交际能力和心理素质,也是非常重要的,体现了一个人的综合素质,从一方面代表公司形象。

二. 客户的分类
俗话说,林子大了,什么鸟都有。仅仅对其中一部分进行描述。
从理论上来说,我们是平等的,是一种合作关系,而现实中,我们是一种买卖的关系,确实存在不平等地位,一方是强势的甲方,一方是弱势的乙方。甲方一句话,乙方得客气的做出应答。也许没这种必要,但是,现场大多数就是这种情形。
需要服务的与提供服务的,本应该是一种合作的平等关系,但是具体到人,就变了,这是大家已经习以为常的现实。且看客户的类型。
2.1 热情周到型
有的客户十分的热情,也很周到,在你到达现场前,为你准备好了餐票。解决问题后,会好好的请你吃顿饭,更有甚者,会开车带你去兜风。这种客户一般是条件比较好的客户,而且对于你来能解决他们存在的问题心存感激。(其实没必要心存感激)。
2.2 不冷不热型
这种客户,在你到达、处理问题的过程以及离开时,都没有特别的反应,他们团队的氛围就是这样,大家彼此不需要太多的客套,属于那种非主动,一问一答型。
2.3 先礼后兵型
有些客户对于你的来到,充满期待,对你十分的热情友好,对你提出的要求,尽量满足。但是,如果你不能解决问题,或者弄出新的问题,他们会毫不犹豫的对你进行投诉。并且不允许你下次再来他们的现场,要求换人。
2.4 强烈依赖型
客户对于你的技术,有十分严重的依赖,有时候并非客户不懂,而大多数情况下,客户是不想对可能出现的后果负责,因为做数据库的操作有时候有巨大风险。所以,什么事情,都由你来做,比如扩一下表空间,删除一些不要的文件等。
2.5 自力更生型
有时候在现场,可能会让你觉得,客户买你们公司的服务是不是一种多余,因为,每次都是你们公司主动要求去做一下什么所谓的检查,好像是为了完成合同规定的任务,而去了之后,客户工程师似乎不情愿让你碰任何系统,不允许接入任何机器,你需要做的是,提供保证没有病毒的相关脚本和操作说明。他们自己来操作。
2.6 实力强大型
有时候在现场,客户似乎表现的比你技高一筹,有时候让你感到有点内心打鼓,客户无论是从交流沟通,还是貌似请教,都好像设下埋伏,对你其实在进行试探,这些人既有很快速的操作技能,也具有很深的理论水平。而且他们自己本身就有很强大的dba团队。
2.7 完全不懂型
出于某些原因,客户那边可能临时缺少人手,或者dba刚离职,客户工程师只是临时接手这个任务,或者客户就是刚刚入门,做一个不太重要的系统在维护,实际上让你能教教他,也许一个命令,敲一个字母,都需要向你咨询,这种属于完全不懂型。
2.8 压力巨大型
有时候客户工程师在现场面临强大的压力,通宵达旦,连续奋战,只要没有解决问题,他都面临上级的强大压力,或者是上级也面临这更上级的压力,这种压力是硬性的,一层层传递,最终也必然要传递到现场工程师身上。这种客户工程师可能面临考核的巨大压力,因此,对于实施服务的现场工程师具有非常高的要求,而且要确保能解决问题,并且容易出现情绪问题,容易表现在脸上。
2.9 压榨型
有些客户有一种心态,我买了你们的服务,你们就得听我使唤。而很多第三方厂商,迫于竞争的激烈,对客户是有求必应,对现场工程师也是要求尽量满足客户,进一步助长了此种心态的客户的此种心态。客户认为花了钱,就得给我好好的处理问题,尽量的提供服务,似乎是要把花出去的钱全部捞回来,尽量物有所值。你的所有时间都是客户的,包括你的周末甚至是你的夜晚。就是周末搬个桌椅,都需要你来代劳。

三. 客户的要求
3.1 快速响应
有客户曾经对我说,购买你们的服务,其中一个非常重要的因素,就是看重快速响应的机制。一般客户问问题,都要引起重视,有时候客户是在不经意间提出,有时候是比较正式的提出,无论客户自己是否重视,都应该引起你自己的足够重视,否则,可能会引起客户的不满,严重的会导致投诉。
3.2 技术靠谱
有一些客户对提供服务的工程师有比较苛刻的要求,甚至要求通过他们自己设置的面试与笔试考核,其他的客户可能要求不是很高,但是都要求技术工程师的技术要靠谱,一般来说,技术不好的工程师,往往会在一些好说话的客户、不重要的系统上先熟悉,练练手,有机会再进入重要客户的重要系统。如果没有一定的技术实力,很容易引起客户的不满意。如果一问三不知,客户也会对你失去信心。
3.3 问题的精确定位与处理
对于问题原因的精准定位,是一项非常重要的技能。也是所提供服务的质量体现。有经验的工程师能够快速熟练的去验证问题,而不太有经验的工程师,会逐一尝试排查,最终找到问题症结。不管怎样,如果对于问题的分析不合理,不具有说服力,客户可能是不会接受的。
3.4 超出合同范围的过分要求
有时候可能客户会提一些超出你能力范围的,甚至是合同范围的要求,超出能力范围的事情可以找公司协调资源,寻求帮助,但是超出合同范围的事情,你只能跟销售反映了。比如如果只是做数据库的维保服务,而客户要求你检查主机硬件,或者提出一些诸如要求你们公司组建什么水平的试验室等等的要求。

四. 问题和矛盾
4.1 有些不能解决的矛盾,这是在现实中客观存在的。
不是所有的问题都是能解决的,不是所有的技术问题非得技术手段来解决。很多问题是目前的水平没办法解决的,这些是客观存在的。就算是原厂派资深的工程师,也解决不了问题。
4.2 合同中的技术实力与现场中区别甚大
有时候,客户认为,签合同时候说的天花乱坠,合同签了之后,实际上没那么强,没那么好,甚至有很大的落差。会让客户产生一些不满。

五. 应对客户的技巧
5.1 答应客户要办的事情,一定要办。
许多时候,很多工程师,在离开客户之前,回家心切,或者想早点离开客户这里,免得又会有什么问题来麻烦自己,只要客户问的问题,往往口头上满口答应,表示回去后再看看,不过可能回去没看,没引起重视,或者忘了,就容易引起客户投诉。
答应客户的事情一定要给一个结果,不管结果如何,都要给客户反馈。
5.2 表现一种姿态
很多时候,说实在的,可能解决不了问题,但是你至少得有个姿态,表明我确实尽力了。从服务态度上加分,如果问题没解决,又一副大爷般的神态,那结果往往也会不妙。
5.3 同客户工程师搞好关系
同客户工程师搞好关系,其实也是一个工程师的能力体现。一旦同客户工程师的关系做好了,处理问题起来就会得心应手,如果跟客户关系搞不好,相互暗中抱怨,平添一堵墙。比如请客户吃顿饭,或者天南地北的说一通,或者一起深入的沟通一些他们关心的其他问题。对客户表现出一种真诚、职业、热忱、敬业的品质。搞好关系实际上是解决问题的一种润滑剂。
5.4 注意同其他厂商的工程师保持通畅的沟通
在现场,往往会有多家厂商,共同来做一件事,大家实际上有一个共同的目标,就是让系统高效稳定的运行,大家的目标是一致的,出了问题大家相互支援,尽量不要造成那种有事情相互推诿扯皮,这样大家都不好受。
5.5 其他力所能及的帮助
作为培养客户关系的一部分,适当的满足一下客户的其他要求,也是有帮助的,比如给客户拷贝一些技术资料,给客户做一个小小的培训,以解答客户心中的疑惑,往往会有很好的效果。
5.6 提交详细文档
客户工程师有很多时候,对发生的问题,需要有个技术文档,以便下次遇到同样问题,知道原因,并可能会采取措施避免,有的可能需要一份报告,向领导交差。不管怎样,事后提交一份友好、专业的报告,都是非常必要

跨平台的oracle迁移对于企业在目前来讲是比较少碰到的.碰到跨平台项目一般都是碰到数据整合,或者项目升级的情况.这里我以个人的角度浅浅的描述下oracle跨平台迁移涉及到的一些技术以及解决方案,顺便附上关于这方面的资料,只作个人的闲余消遣,更多的是我把我某一个项目中关于oracle迁移的经验思路理出来作分享
Oracle跨平台迁移一般使用手段便是如下所列的几种:

1.使用export工具,包括Datapump,对于Datapump,要求数据库为10.1.0.2以上版本
2.10G 或更高版本可使用 Transportable Tablespaces(TTS)。
3.10G 或更高版本可使用 RMAN Convert Database 功能。
4.Streams 流复制。
5.Create Table As Select (CTAS)
6.Dataguard 基于异构平台的物理主备库。
7.Oracle Golden Gate

每种办法都会有其优势和局限,包括数据类型、所需时间和潜在成本,我列举一个我迁移项目的例子:
(如要转载请标注原创).

首先平台环境,原始环境平台:

oracle 10203
aix 5203

目标环境平台:

oracle rac 11.2.0.3.8
OElinux 6.1
aix 5203

这是我一个金融行业用户的核心生产要升级的项目,从Ibm的aix平台迁移到linux 平台,单机变双机,数据库版本也横跨了大版本.那么在项目初期,客户的期望就是我要迁过去,这样硬件升级还能有双活节点,有高可用做保障,对于DBA怎么迁移,他可不管,也不会问到非常细的环节(每个客户都是不一样的).那么作为乙方,我认为在处理这样的项目的时候,从接手开始就应该尽量的把你专业的一方面表现出来,尽可能的考虑到各种情况.这个升级项目涉及到的方方面面,在这个项目中我通常首先要了解的是时间窗口、整个DB的数据量,在我这项目中一开始我得到的信息为时间窗口是24小时,数据量是600多g.哟呵,有点儿意思,时间很充足,数据量马马虎虎,在这个行业里算大了,眼看就要想要用什么技术来迁移了.其实还早,时间窗口是用户确定了足信,至于数据量更多时候我一定会到数据库里再确定一次,那么怎么确定正确的数据量?确定数据量的办法挺多,肯定会有人说看dba_data_files的总和减去dba_free_space,剩下的就是实际数据量了,没准还会有更可爱的说看tablespace占了多少.哎呀其实都没错,在一些特定的技术环节下是要看这些,但是这里我想补充2个信息,就是从exp或者datapump的导出dump文件大小以及用rman做备份后的实际的备份集考虑.这只是在选择迁移技术前的信息判断而已,这些信息是越多越好,我最终选择的技术还是使用expdp,没有选择tts或者是dg.

那么为啥呢?别急容我慢慢述来.

1.数据量实际大小为290G,这与用户的描述有出入,经过了解是因为客户是通过sql语句来计算容量的,而实际上客户经常对一些历史表做delete的清理,并未做空间的回收操作,这样就会有大量的空间实际上是没有数据但是确占用着表空间容量的.得出这个数据后我逐测试了下exp和expdp的在生产系统空闲时间段的导出时间,expdp导出大小为270左右,开8个并行耗时80–120分钟.
2.在搭建好的linux平台(未来的核心平台)上测试导入时间,采取并行,索引分离,扩大PGA,分用户(应用用户相对独立)双节点导入等手段,最终在导入时间可以控制在80分钟以内.

那大头为什么不用tts或者dg,ogg,stream呢?
.
1.tts虽然我用的次数挺多,这里不用是因为用户表空间建的较大,整体加起来接近2t,表空间众多,操作繁冗.
2.虽然dg支持aix和linux的异构同步,但是这里对停机时间要求没有很严格,而且如果用dg一开始就要对生产系统停机维护,还需要规避bug.最重要的是,大头对这个技术虽然做过测试,但是经验不足,我不能保证会没有问题.我肯定会选择我可控的胸由成竹的技术.
3.ogg很美好,但是转眼想下,做ogg有必要么?初始化过程就相当于一次迁移了.又不需要无缝停机,即使真的无缝停机,ogg也不大可能会满足要求的,因为注定要经过一翻波折之后ogg才会这服在你额运维手段之下.
4.stream,快要淘的技术了,转眼像在ogg上复活了,ogg我都拒绝了,流再见吧.

理解了大头的用心良苦了么?汇总下上面的信息

项目起始选择迁移方式无外乎要注意几个重点:
1.尽可能多的收集和迁移相关的信息,而且要亲自去确认排除可能的情况
2.如果有测试数据支持,那么方案将更加有说服力
3.尽可能去结合项目的场景要求选择自己熟悉的适合技术,不要为项目,为自己,为技术团队添加意外的风险
4.如果遭遇客户的追问,123就是你的答复.

其实这个项目在使用datapump过程也对工程师的技术要求较高,虽然本身datapump的技术并不复杂,但是需要考虑的方面很多,我总结如下:
1.dblink,无论是出去的,还是进来的dblink都需要做一遍梳理.11.2.0.2之后重建dblink可以使用转换过的密码直接重建哦!
2.函数,同义词与dblink的依赖需要格外关注
3.物化视图迁移到11g后是一起迁移的,需要关注迁移后的物化视图是否为正常状态
4.导出的dump文件传输到目标库的时间是要计算到整个迁移时间的
5.统计信息最好不要一起迁移
6.如果导入过程碰到约束错误不要慌,报错的表可以在后续重新导入
7.在导入完成后需要验证每个用户下的对象信息是否与原库相符,最好有类似veridata软件对比原库和目标库行数信息的工具来支撑,否则就需要应用来做验证数据迁移的完整性
8.迁移的回退工作,万一遭遇datapump的bug,如何快速恢复初始环境?最好是在导入之前做一份目标库的rman全备份.
9.记得把temp表空间设大,把pga调大,把DB的归档关闭.
有不足的地方大家继续补充~欢迎大家斧正.

以上这就是一个最基本的迁移工作要注意的环节,以及datapump的使用注意事项.其他跨平台迁移方式相关资料大家可以参考如下,
luadtou
Note.556636.1 Oracle Server – Export Data Pump and Import DataPump FAQ
Note.351598.1 Export/Import DataPump The Minimum Requirements to Use Export DataPump and Import DataPump (System Privileges)
Note.243304.1 10g : Transportable Tablespaces Across Different Platforms
Note:371556.1 How move tablespaces across platforms using Transportable Tablespaces with RMAN
Note: 413484.1 Data Guard Support for Heterogeneous Primary and Physical Standbys in Same Data Guard Configuration
NOTE:1401921.1 – Cross-Platform Database Migration (across same endian) using RMAN Transportable Database
NOTE:62290.1 – Changing between 32-bit and 64-bit Word Sizes

, ,

下面为rac常见的5个问题,结合经验和参考metalink给出。

问题 1:ORA-29770 LMHB 终止实例

症状:

LMON (ospid: 31216) waits for event 'control file sequential read' for 88 secs.
Errors in file /oracle/base/diag/rdbms/prod/prod3/trace/prod3_lmhb_31304.trc (incident=2329):
ORA-29770: global enqueue process LMON (OSID 31216) is hung for more than 70 seconds
LMHB (ospid: 31304) is terminating the instance.

或
LMON (ospid: 8594) waits for event 'control file sequential read' for 118 secs.
ERROR: LMON is not healthy and has no heartbeat.
ERROR: LMHB (ospid: 8614) is terminating the instance.

 

可能的原因:

LMON 等待读取控制文件,导致LMHB 使实例崩溃
Bug 11890804 LMHB crashes instance with ORA-29770 after long “control file sequential read” waits
解决方案:

Bug 8888434 已在 11.2.0.2 及以上版本 中得到修正
Bug 11890804 已在 11.2.0.3及以上版本中得到修正
请参阅 Document 1197674.1, Document 8888434.8 和 Document 11890804.8 了解详细信息

问题 2:ORA-481 导致的实例崩溃

症状:

1. PMON (ospid: 12585): terminating the instance due to error 481
LMON 进程跟踪文件显示:
Begin DRM(107) (swin 0)
* drm quiesce

LMS 进程跟踪文件显示:

2011-07-05 10:53:44.218905 : Start affinity expansion for pkey 81885.0
2011-07-05 10:53:44.498923 : Expand failed: pkey 81885.0, 229 shadows traversed, 153 replayed 1 retries

2. PMON (ospid: 4915562): terminating the instance due to error 481
Sat Oct 01 19:21:37 2011
System state dump requested by (instance=2, osid=4915562 (PMON)), summary=[abnormal instance termination].

可能的原因:

1. Bug 11875294 LMS gets stuck during DRM, Instance crashed with ORA-481
2. HAIP 在部分集群节点上离线,或者 HAIP 在所有集群节点上都在线,但是无法通过其进行通信,例如ping操作失败。
解决方案:

1. Bug 11875294 已在 11.2.0.3 中得到修正,绕过问题的方法是:
通过设置
_gc_read_mostly_locking=FALSE 来禁用read mostly。
请参阅 < Document 11875294.8> 了解详细信息。

2. 修正 HAIP 问题,请参阅 Document 1383737.1

问题 3:ORA-600[kjbmprlst:shadow]、ORA-600[kjbrref:pkey]、ORA-600[kjbmocvt:rid]、[kjbclose_remaster:!drm]、ORA-600 [kjbrasr:pkey] 导致的实例崩溃

症状:

由于 ORA-600 [kjbmprlst:shadow]、ORA-600[kjbrref:pkey]、ORA-600[kjbmocvt:rid]、[kjbclose_remaster:!drm] 或 ORA-600 [kjbrasr:pkey] 导致 RAC 实例崩溃

可能的原因:

这一组 ORA-600 与 DRM(dynamic resource remastering)消息或 read mostly 锁有关。涉及多个 bug,包括:
Document 9458781.8 Missing close message to master leaves closed lock dangling crashing the instance with assorted Internal error
Document 9835264.8 ORA-600 [kjbrasr:pkey] / ORA-600 [kjbmocvt:rid] in RAC with dynamic remastering
Document 10200390.8 ORA-600[kjbclose_remaster:!drm] in RAC with fix for 9979039
Document 10121589.8 ORA-600 [kjbmprlst:shadow] can occur in RAC
Document 11785390.8 Stack corruption / incorrect behaviour possible in RAC
Document 12408350.8 ORA-600 [kjbrasr:pkey] in RAC with read mostly locking
Document 12834027.8 ORA-600 [kjbmprlst:shadow] / ORA-600 [kjbrasr:pkey] with RAC read mostly locking
解决方案:

上述大部分 bug 都在 11.2.0.3 中得到了修正,安装 11.2.0.3 补丁集应该可以避免这些 bug,除了 Bug 12834027,此 bug 将在 12.1 中进行修正。绕过这个 bug 的方法是:

禁用 DRM

禁用read mostly
例如:设置 “_gc_read_mostly_locking”=FALSE

有关每个 bug 的说明和解决方案,请参阅上述相关文档。

问题 4:启用flash cache后产生kcldle/kclfplz/kcbbxsv_l2/kclfprm,导致实例崩溃

症状:

警报日志中报告了 ORA-7445[kcldle]
ORA-7445[kclfplz]
ORA-7445[kcbbxsv_12]
ORA-744[kclfprm]

可能的原因:

它们是由不同的 bug 引起的,而这些bug都归结为 基础bug Bug 12337941 Dumps on kcldle / kclfplz / kcbbxsv_l2 / kclfprm using flash
解决方案:

此 bug 已在 11.2.0.3 中得到修正,请安装补丁集或使用以下方法绕过这个问题:禁用 Flash Cache
请参阅 Document 12337941.8 ,了解更多详细信息

问题 5:LMS 报 ORA-600 [kclpdc_21]错误,实例崩溃

症状:

警报日志中报告了 ORA-600[kclpdc_21]

可能的原因:

Document 10040035.8 LMS gets ORA-600 [kclpdc_21] and instance crashes
解决方案:

此 bug 已在 11.2.0.3 中得到修正

10.2.0.5 的问题

症状:

1. LMS进程 报 ORA-600[kjccgmb:1]错误导致实例崩溃, LMS: terminating instance due to error 484
2. 由于以下原因导致实例崩溃:
Received an instance abort message from instance 2 (reason 0x0)
Please check instance 2 alert and LMON trace files for detail.
LMD0: terminating instance due to error 481

可能的原因:

1. Bug 11893577 – LMD CRASHED WITH ORA-00600 [KJCCGMB:1]
2. Bug 9577274 – 1OFF:UNABLE TO VIEW REQUEST OUTPUT AND LOG AFTER APPLYING FIX TO ISSUE IN BUG 9400041
解决方案:

1. 对于 10.2.0.5.0,安装合并的补丁 12616787
2. 对于 10.2.0.5.5,安装合并的补丁 13470618
撰写本文时,只有特定平台才有可用补丁。对于任何 10.2.0.5.x 版本,不需要同时安装上述两个补丁。

, , ,

参考文档:drmdiag.sql
适用 11.2.0.1 to 12.1.0.1 [Release 11.2 to 12.1]

-- NAME: DRMDIAG.SQL
-- ------------------------------------------------------------------------
-- AUTHOR: Michael Polaski - Oracle Support Services
-- ------------------------------------------------------------------------
-- PURPOSE:
-- This script is intended to provide a user friendly guide to troubleshoot
-- drm (dynamic resource remastering) waits. The script will create a file
-- called drmdiag_.out in your local directory.

set echo off
set feedback off
column timecol new_value timestamp
column spool_extension new_value suffix
select to_char(sysdate,'Mondd_hh24mi') timecol,
'.out' spool_extension from sys.dual;
column output new_value dbname
select value || '_' output
from v$parameter where name = 'db_name';
spool drmdiag_&&dbname&&timestamp&&suffix
set trim on
set trims on
set lines 140
set pages 100
set verify off
alter session set optimizer_features_enable = '10.2.0.4';
set feedback on

PROMPT DRMDIAG DATA FOR &&dbname&&timestamp
PROMPT Important paramenters:
PROMPT
PROMPT _gc_policy_minimum (default is 1500). Increasing this would cause DRMs to happen less frequently.
PROMPT Use the "OBJECT_POLICY_STATISTICS" section later in this report to see how active various objects are.
PROMPT
PROMPT _gc_policy_time (default to 10 (minutes)). Amount of time to evaluate policy stats. Use the
PROMPT "OBJECT_POLICY_STATISTICS" section later in this report to see how active various objects are for the
PROMPT _gc_policy_time. Usually not necessary to change this parameter.
PROMPT
PROMPT _gc_read_mostly_locking (default is TRUE). Setting this to FALSE would disable read mostly related DRMs.
PROMPT
PROMPT gcs_server_processes (default is derived from CPU count/4). May need to increase this above the
PROMPT default to add LMS processes to complte the work during a DRM but the default is usually adequate.
PROMPT
PROMPT _gc_element_percent (default is 110). May need to apply the fix for bug 14791477 and increase this to
PROMPT 140 if running out of lock elements. Usually not necessary to change this parameter.
PROMPT
PROMPT GC Related parameters set in this instance:
show parameter gc
PROMPT
PROMPT CPU count on this instance:
show parameter cpu_count

PROMPT
PROMPT SGA INFO FOR &&dbname&&timestamp
PROMPT
PROMPT Larger buffer caches (above 100 gig) may increase the cost of DRMs significantly.
set lines 120
set pages 100
column component format a40 tru
column current_size format 99999999999999999
column min_size format 99999999999999999
column max_size format 99999999999999999
column user_specified_size format 99999999999999999
select component, current_size, min_size, max_size, user_specified_size
from v$sga_dynamic_components
where current_size > 0;

PROMPT
PROMPT ASH THRESHOLD...
PROMPT
PROMPT This will be the threshold in milliseconds for total drm freeze
PROMPT times. This will be used for the next queries to look for the worst
PROMPT 'drm freeze' minutes. Any minutes that have an average log file
PROMPT sync time greater than the threshold will be analyzed further.
column threshold_in_ms new_value threshold format 999999999.999
select decode(min(threshold_in_ms),null,0,min(threshold_in_ms)) threshold_in_ms
from (select inst_id, to_char(sample_time,'Mondd_hh24mi') minute,
sum(time_waited)/1000 threshold_in_ms
from gv$active_session_history
where event like '%drm freeze%'
group by inst_id,to_char(sample_time,'Mondd_hh24mi')
order by 3 desc)
where rownum <= 10; PROMPT PROMPT ASH WORST MINUTES FOR DRM FREEZE WAITS: PROMPT PROMPT APPROACH: These are the minutes where the avg drm freeze time PROMPT was the highest (in milliseconds). column event format a30 tru column program format a35 tru column total_wait_time format 999999999999.999 column avg_time_waited format 999999999999.999 select to_char(sample_time,'Mondd_hh24mi') minute, inst_id, event, sum(time_waited)/1000 TOTAL_WAIT_TIME , count(*) WAITS, avg(time_waited)/1000 AVG_TIME_WAITED from gv$active_session_history where event like '%drm freeze%' group by to_char(sample_time,'Mondd_hh24mi'), inst_id, event having sum(time_waited)/1000 > &&threshold
order by 1,2;

PROMPT
PROMPT ASH DRM BACKGROUND PROCESS WAITS DURING WORST MINUTES:
PROMPT
PROMPT APPROACH: What is LMS doing when 'drm freeze' waits
PROMPT are happening? LMD and LMON info may also be relevant
column inst format 999
column minute format a12 tru
column event format a50 tru
column program format a55 wra
select to_char(sample_time,'Mondd_hh24mi') minute, inst_id inst,
sum(time_waited)/1000 TOTAL_WAIT_TIME , count(*) WAITS,
avg(time_waited)/1000 AVG_TIME_WAITED,
program, event
from gv$active_session_history
where to_char(sample_time,'Mondd_hh24mi') in (select to_char(sample_time,'Mondd_hh24mi')
from gv$active_session_history
where event like '%drm freeze%'
group by to_char(sample_time,'Mondd_hh24mi'), inst_id
having sum(time_waited)/1000 > &&threshold and sum(time_waited)/1000 > 0.5)
and (program like '%LMS%' or program like '%LMD%' or
program like '%LMON%' or event like '%drm freeze%')
group by to_char(sample_time,'Mondd_hh24mi'), inst_id, program, event
order by 1,2,3,5 desc, 4;

PROMPT
PROMPT POLICY HISTORY INFO:
PROMPT See if you can correlate policy history events with minutes of high
PROMPT wait time.
select * from gv$policy_history
order by event_date;
PROMPT
PROMPT DYNAMIC_REMASTER_STATS
PROMPT This shows where time is spent during DRM operations.
set heading off
set lines 60
select 'Instance: '||inst_id inst, 'Remaster Ops: '||remaster_ops rops,
'Remaster Time: '||remaster_time rtime, 'Remastered Objects: '||remastered_objects robjs,
'Quiesce Time: '||quiesce_time qtime, 'Freeze Time: '||freeze_time ftime,
'Cleanup Time: '||cleanup_time ctime, 'Replay Time: '||replay_time rptime,
'Fixwrite Time: '||fixwrite_time fwtime, 'Sync Time: '||sync_time stime,
'Resources Cleaned: '||resources_cleaned rclean,
'Replayed Locks Sent: '||replayed_locks_sent rlockss,
'Replayed Locks Received: '||replayed_locks_received rlocksr,
'Current Objects: '||current_objects
from gv$dynamic_remaster_stats
order by 1;
set lines 120
set heading on

PROMPT
PROMPT OBJECT_POLICY_STATISTICS:
PROMPT The sum of the last 3 columns (sopens,xopens,xfers) decides whether the object
PROMPT will be considered for DRM (_gc_policy_minimum). The duration of the stats
PROMPT are controlled by _gc_policy_time (default is 10 minutes).
select object,node,sopens,xopens,xfers from x$object_policy_statistics;

PROMPT
PROMPT ACTIVE OBJECTS (OBJECT_POLICY_STATISTICS)
PROMPT These are the objects that are above the default _gc_policy_minimum (1500).
select object, node, sopens+xopens+xfers activity
from x$object_policy_statistics
where sopens+xopens+xfers > 1500
order by 3 desc;

PROMPT LWM FOR LE FREELIST
PROMPT This number should never get near zero, if it does consider the fix for bug 14791477
PROMPT and/or increasing _gc_element_percent.
select sum(lwm) from x$kclfx;

PROMPT
PROMPT GCSPFMASTER INFO WITH OBJECT NAMES
column objname format a120 tru
select o.name || ' - '|| o.subname objname, o.type#, h.*
from v$gcspfmaster_info h, obj$ o where h.data_object_id=o.dataobj#
order by data_object_id;

PROMPT
PROMPT ASH DETAILS FOR WORST MINUTES:
PROMPT
PROMPT APPROACH: If you cannot determine the problem from the data
PROMPT above, you may need to look at the details of what each session
PROMPT is doing during each 'bad' snap. Most likely you will want to
PROMPT note the times of the high drm freezewaits, look at what
PROMPT LMS, LMD0, LMON is doing at those times, and go from there...
set lines 140
column program format a45 wra
column sample_time format a25 tru
column event format a30 tru
column time_waited format 999999.999
column p1 format a40 tru
column p2 format a40 tru
column p3 format a40 tru
select sample_time, inst_id inst, session_id, program, event, time_waited/1000 TIME_WAITED,
p1text||': '||p1 p1,p2text||': '||p2 p2,p3text||': '||p3 p3
from gv$active_session_history
where to_char(sample_time,'Mondd_hh24mi') in (select
to_char(sample_time,'Mondd_hh24mi')
from gv$active_session_history
where event like '%drm freeze%'
group by to_char(sample_time,'Mondd_hh24mi'), inst_id
having sum(time_waited)/1000 > &&threshold)
and time_waited > 0.5
order by 1,2,3,4,5;

spool off

PROMPT
PROMPT OUTPUT FILE IS: drmdiag_&&dbname&&timestamp&&suffix
PROMPT

报错信息:

/tmp/OraInstall2011-09-24_10-16-11PM/jre/1.4.2/lib
/i386/libawt.so: libXp .so.6: cannot open  shared object file: No such file or directory occurred..

这个错误是我在以前安装时候碰到的,最近问的人挺多,则顺便趁早上这个点发布出来.首先我们从错误上看能很明显看到是libxp.so.6这个文件出问题了,但是你使用rpm -qa | grap libXp你会发现,这个包已经安装了,
仔细检查你会发现,系统提示的是/tmp/OraInstall2011-09-24_10-16-11PM/jre/1.4.2/lib/i386/libawt.so,i386而不是686,而现在安装的平台都常都是linux 6.1 x64上,默认安装的libXp版本也是64bit版本的,所以这里的解决办法基本就可以明了了,使用rpm -e | grep libXp,然后安装正确的386版本的libXp即可。如果有依赖包先卸载依赖包。

,

数据库hang住的原因很多,以往碰到得案例不少,大部分都和内存的抖动引起的进程僵死,或者bug造成,或者其他类似如归档满了,dg最高级模式下网络阻塞等原因.今天这里我介绍的这个案例偏门,几乎很难碰到.这里测试的版本为11.2.0.2版本,基于linux内核2.6.18 ×64. 且10g和11r1版本此类测试无效.这应该算是11.0.2.2的一个bug.

在linux中有一个命令strace,它常被用来跟踪进程执行时的系统调用和所接收的信号。
具体的参数含义如下:

-c 统计每一系统调用的所执行的时间,次数和出错的次数等. 
-d 输出strace关于标准错误的调试信息. 
-f 跟踪由fork调用所产生的子进程. 
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号. 
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪. 
-h 输出简要的帮助信息. 
-i 输出系统调用的入口指针. 
-q 禁止输出关于脱离的消息. 
-r 打印出相对时间关于,,每一个系统调用. 
-t 在输出中的每一行前加上时间信息. 
-tt 在输出中的每一行前加上时间信息,微秒级. 
-ttt 微秒级输出,以秒了表示时间. 
-T 显示每一调用所耗的时间. 
-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出. 
-V 输出strace的版本信息. 
-x 以十六进制形式输出非标准字符串 
-xx 所有字符串以十六进制形式输出. 
-a column 
设置返回值的输出位置.默认 为40. 
-e expr 
指定一个表达式,用来控制如何跟踪.格式如下: 
[qualifier=][!]value1[,value2]... 
qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用来限定的符号或数字.默认的 qualifier是 trace.感叹号是否定符号.例如: 
-eopen等价于 -e trace=open,表示只跟踪open调用.而-etrace!=open表示跟踪除了open以外的其他调用.有两个特殊的符号 all 和 none. 
注意有些shell使用!来执行历史记录里的命令,所以要使用\\. 
-e trace=set 
只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all. 
-e trace=file 
只跟踪有关文件操作的系统调用. 
-e trace=process 
只跟踪有关进程控制的系统调用. 
-e trace=network 
跟踪与网络有关的所有系统调用. 
-e strace=signal 
跟踪所有与系统信号有关的 系统调用 
-e trace=ipc 
跟踪所有与进程通讯有关的系统调用 
-e abbrev=set 
设定 strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all. 
-e raw=set 
将指 定的系统调用的参数以十六进制显示. 
-e signal=set 
指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号. 
-e read=set 
输出从指定文件中读出 的数据.例如: 
-e read=3,5 
-e write=set 
输出写入到指定文件中的数据. 
-o filename 
将strace的输出写入文件filename 
-p pid 
跟踪指定的进程pid. 
-s strsize 
指定输出的字符串的最大长度.默认为32.文件名一直全部输出. 
-u username 
以username 的UID和GID执行被跟踪的命令

如果做过在linux的开发,那么对这个命令一定不会陌生,哈哈。闲话不多说,我们接着猪蹄,今天我们主要是采用-p -o这2个参数,用它对oracle的进程进行跟踪调用。
首先我对lgwr进程进行跟踪调用,执行如下:

[root@ludatou ~]# ps -ef | grep lgwr
root     10136  9578  0 06:30 pts/1    00:00:00 grep lgwr
ora10g   32496     1  0 Apr15 ?        00:00:04 ora_lgwr_lu11r2
[root@ludatou ~]# export ORACLE_SID=lu11r2
[root@ludatou ~]# strace -p $(pgrep -fx ora_lgwr_$ORACLE_SID) -o /tmp/l.out -T &
[1] 10257
[root@ludatou ~]# Process 32496 attached - interrupt to quit

这个时候日志l.out的输出大致如下(我db是空闲的):

gettimeofday({1397602111, 401986}, NULL) = 0 <0.000032>
gettimeofday({1397602111, 402111}, NULL) = 0 <0.000032>
gettimeofday({1397602111, 402233}, NULL) = 0 <0.000032>
gettimeofday({1397602111, 402356}, NULL) = 0 <0.000031>
gettimeofday({1397602111, 402510}, NULL) = 0 <0.000032>
gettimeofday({1397602111, 402537}, NULL) = 0 <0.000011>
gettimeofday({1397602111, 402551}, NULL) = 0 <0.000007>
gettimeofday({1397602111, 402560}, NULL) = 0 <0.000005>
times(NULL)                             = 436324232 <0.000002>
gettimeofday({1397602111, 402570}, NULL) = 0 <0.000003>
gettimeofday({1397602111, 402573}, NULL) = 0 <0.000002>
semtimedop(131073, 0xbfa12088, 1, {3, 0}

这个时候数据库运行正常,正常读写提交,具体如下:

SQL> conn luda/luda
Connected.
SQL> create table t1 as select * from dba_objects;

Table created.

SQL> alter table t1 add ludatou varchar2(200);

Table altered.

SQL> update t1 set ludatou=250;

50068 rows updated.

SQL> commit;

Commit complete.

下一步我将strace跟踪lgwr的进程杀掉后,再看看数据库是否运行正常,具体如下:

1.杀掉跟踪进程

[root@ludatou ~]# kill %1
[root@ludatou ~]# Process 32496 detached
--这个时候提示守护进程和32496进程(lgwr)分离

2.在数据库层面执行
SQL> update t1 set ludatou=250;

50068 rows updated.

SQL> commit;

到这一步会发现….一直没反应,查看全库等待事件为log file sync.这个时候检测lgwr的进程状态可以发现为如下:

[ora11g@ludatou ~]$ ps $(pgrep -fx ora_lgwr_$ORACLE_SID)
  PID TTY      STAT   TIME COMMAND
32496 ?        Ts     0:00 ora_lgwr_lu11r2

进程32496为Ts的状态,意味着该进程为停止状态或者该进程被其他进程控制.但是实际上我已经把strace停止。我们将其唤醒:

kill -SIGCONT 32496
[ora11g@ludatou ~]$ ps $(pgrep -fx ora_lgwr_$ORACLE_SID)
  PID TTY      STAT   TIME COMMAND
32496 ?        Ss     0:00 ora_lgwr_lu11r2

这个时候进程变为ss状态,而且数据库也随之恢复正常。这不知道应算是数据库的bug还是linux的bug,个人更倾向linux,毕竟我执行退出strace了,实际上strace进程还附加在lgwr进程上不断callout进程。这个测试我只在11.2.0.2,11.1.0.7,10.2.0.4版本上测试过,目前只有11.2.0.2有这个情况。

遭遇ORA-00600 [ksnwait:nsevwait]

这件事情在遭遇时候恰巧我们公司一个上海工程师到客户现场修复数据库安全漏洞打了CPU,但是当天晚上数据库就宕机了,客户把事故的根源矛头直指我们,临危受命之下连夜赶往客户现场。
在现场后才感受到此次故障对客户的影响之深,科技部的领导都到位了,匆匆忙忙落位开始诊断,发现数据库alert.log报错如下:

Errors in file /app/oracle/diag/rdbms/prod/prod/trace/prod_pmon_401638.trc:
ORA-00600: internal error code, arguments: [ksnwait:nsevwait], [], [], [], [], [], [], [], [], [], [], []
PMON (ospid: 401638): terminating the instance due to error 472
Instance terminated by PMON

当前环境为:
aix 6.1
oracle 11.2.0.1

从上面的报错可以很明确的看到是因为pmon进程宕掉,最终引起数据库崩溃.

关键报错信息00600,ksnwait:nsevwait,这类报错第一眼的感觉就是bug,在OTN上验证了我的诊断,此错误为bug8554900引起,修复补丁为Patch:8554900.
在不应用修复补丁的情况下可以通过尝试使用用参数SQLNET.OUTBOUND_CONNECT_TIMEOUT设置大一点的值去规避,这个bug在11.2.0.2版本之后修复完了,而且考虑到这个版本为11.2.0.1的初始版本,漏洞会比较多,我建议直接将数据库升级到版本11.2.0.3.8版本,客户同意了我的解决方案,并于当晚升上去,最终和开发部分standby一晚上,我还做好了各种回退工作,技术不累人,就是熬夜真心伤身.也幸好客户对我们的信任依然如旧.

总结:
由上面所见,选择一个稳定的数据库版本,可以为后续的数据库运维工作,为数据库的运行带来长远的效益。且行且小心。

, ,