11.23.06
403e读书笔记二–ORACLE备份恢复产品及特点
简要介绍所有ORACLE备份恢复产品及特征
Oracle支持多种备份恢复 Read the rest of this entry »
简要介绍所有ORACLE备份恢复产品及特征
Oracle支持多种备份恢复 Read the rest of this entry »
数据库服务结构
备份与恢复组件相关术语
数据库的ACID属性
REDO与UNDO的区别
1、实例与数据库
实例=进程+内存结构,启动和关闭的都是实例
数据库=磁盘上的物理文件的集合:数据文件+控制文件+日志文件
(参数文件,密码文件和归档日志文件属辅助文件)
一个完整的数据库备份应包括以上所有文件。
进程:DBWR,LGWR,CKPT,SMON,PMON,ARCn
归档模式:非归档模式+一定备份策略一般来说可以保障数据安全性,
但是在故障恢复时有较多局限性。例如不能脱机数据文件,不能进行热备。
前几天刚刚处理的一个现场故障就是因为非归档下的一个数据文件损坏而
不得不重建相应表空间,
如果是归档模式而且归档日志存在的话就不需要重建表空间了。
BLOCK and DATA BLOCK:oracle数据库文件由块组成(通常是一个块由多个
操作系统块组成)。块根据存储内容的不同可分为:
data block,index block,segment header,bitmap header,file header。
通常用data block来取代block以区别于redo和controlfile的block
数据文件与表空间:
多元化控制文件与日志文件:oracle推荐使用多元化的控制文件和日志文件
(不是磁盘镜像),因为磁盘镜像不能保护delete操作带来的文件丢失风险。
2、常见数据库操作
select:select操作也可能导致数据库发生写操作。服务器进程读取数据到缓冲区,
提取数据,返回给客户端。在这个过程中需要分配空间以容纳读取的数据块,
因此可能导致已经commit的脏数据块写入数据文件已腾出空间。
(oracle定义一些规则空间脏数据的写入,例如:达到阀值,
扫描40%的数据块仍没找到可用空闲块,checkpoint等等)。
DML:服务器进程读取相应的数据块到缓冲区,更新日志缓冲区和数据块.
更新数据块时需要首先更新回滚段和段头,这些操作均需要产生redo信息.
在需要的时候数据块被写入文件.
commit:服务器进程更新回滚段头(以释放回滚段),产生少量的redo,
然后请求LGWR进程empty日志缓存区,完成后返回‘complete’给用户。
Rollback:服务器进程读取事务所属的回滚段信息,将老的数据放回数据块中(
偶尔会将改数据块向前移,因为可能有其他事务修改了该块中的其他行,
不能恢复到原来的状态)。这里对块的改变只产生redo,不产生undo信息。
同commit一样,最后会产生标记并请求flush redo buffer。
DDL:与DML类似,在字典缓冲区完成。
3、备份与恢复
实例恢复:在断电或shutdown abort之后数据重新启动时自动执行,
只需要在线日志文件。未提交的数据的延迟回归将在数据库打开之后完成。
媒体恢复:使用recover命令执行。可能需要归档和在线日志文件。
数据库在发现数据文件头与控制文件不一致,或数据文件未正常关闭时将请求进行媒体恢复。
未提交的延迟事务回滚在数据库打开之后完成。
冷备(脱机备份):数据库关闭情况下手工备份文件或使用RMAN在mount状态下进行
热备(联机备份):数据库必须运行在归档模式下。
手工备份前需要将表空间置于热备模式。
使用RMAN将采用特殊的机制已保证块的一致性,因此不需要处于热备模式。
恢复:分成两部分restore和recover。restore从备份中恢复拷贝到数据库路径。
recover应用归档或在线日志。
不一致类型:
约束不一致:例如外健约束,这种情况一般发生在约束被disable或enable novalidate时,
属于应用上的不一致,可通过analyze table validate structure检测到
结构一致:例如数据文件丢失,数据库找不到字典中描述的文件时将无法启动数据库。
另外一种情况是索引叶结点没有指向正确的数据行,通常是异常或bug引起,
可通用analyze检测到错误
物理不一致:在数据块的内部,除了包含了表的内容的数据行之外,还有很多结构,
例如指向外健、ITL槽的指针等,如果这些指针指向了错误的块或不存在,
就会产生物理不一致。
另外数据库的不同部分,例如物理文件中的块和内存结构中的被修改过的块在
发生异常关闭后将导致数据库不一致,数据文件的各个块也可能由于某些原因
不在同一个时间点(SCN)。
这些都是物理不一致。
数据库的ACID属性—Atomicity(原子性),Consistency(一致性),
Isolation(独立性),Durability(容错性)
A-事务对数据库状态的修改具有原子性。要么成功,要么失败回退到修改之前的状态
C-事务对数据库状态的修改不违反任何完整性约束
I-对并发事务的支持,oracle的读一致性通过undo构建block的不同版本来实现
D-事务故障恢复,oracle实例恢复保障事务容错,任何提交或未提交的事务均可得到恢复
REDO与UNDO
redo—后映像,用于重复一个数据库的修改,在修改结果丢失后重做,
保障数据库的容错性,任何数据块的改动(包括表,索引,undo数据,控制文件,
数据块结构指针,文件等等)都将产生redo信息除非采用nologging忽略日志记录。
注意temp data不产生日志。
global temporary table不记录数据修改日志,但是会产生undo,进而产生redo信息.
undo—前映像,用于获取修改前的原数据,回滚事务时需要用以保障事务原子性,
保障数据库的独立性。任何用户或数据字典数据的改动都将产生undo信息。
undo信息是不能被忽略的,undo data的改变也会产生redo信息.
恢复与事务
恢复的特点:使用redo,用于非预料的数据库崩溃,通常需要手工干预
事务的特点:需要undo作读一致性,产生redo和undo,使用undo作rollback
1、识别坏块
2、修复坏块
1、数据块概述
oracle数据库需要为所有的数据分配逻辑空间,其实逻辑空间只是为了便于管理认为的划分,物理上并不存在这样的空间单元。oracle逻辑空间的分配以块为最小单位,也称作逻辑块或页。依次向上有:分区(extent)—一定数量的连续的数据块。段—存储一定类型数据库对象的一个或多个分区的组合。Oracle用High Water mark来作为已使用和未使用数据块的分界。
数据块结构分为:块头,表目录,行目录,空闲空间和数据区
块头包含通用块信息,例如块地址,所属段类型等等。
表目录包含数据块所属的表相关信息。
行目录记录块中的数据行信息,包括行地址等。
空闲空间是为了为新插入行或update所需空间。
行数据区存储块中实际包含的数据内容。
2、识别坏块
方法一:analyze table table_name validate structure cascade;
方法二:dbv file=xxx.dbf start= end= blocksize= (仅限于数据文件)
方法三:使用dbms_repair包(此方法仅用于被标记为corrupt的块)
另外使用rman备份时,也将对坏块进行表记。
3、恢复方法
方法一:使用dbms_repair包修复块(可能丢失坏块数据)
方法二:从备份中恢复,可使用9i新特性blockrecover
方法三:BBED从备份文件中拷贝(在某些情况下可能奏效,但应谨慎使用)
方法四:如果损坏的是索引块,只需要rebuild该索引即可。
方法五:使用事件使oracle访问时跳过坏块。
需要关注的几个事件
Setting events 10210, 10211, 10212, and 10225 can be done by adding the following line for each event in the init.ora file:
Event = “event_number trace name errorstack forever, level 10“
When event 10210 is set, the data blocks are checked for corruption by checking their integrity. Data blocks that don’t match the format are marked as soft corrupt.
When event 10211 is set, the index blocks are checked for corruption by checking their integrity. Index blocks that don’t match the format are marked as soft corrupt.
When event 10212 is set, the cluster blocks are checked for corruption by checking their integrity. Cluster blocks that don’t match the format are marked as soft corrupt.
When event 10225 is set, the fet$ and uset$ dictionary tables are checked for corruption by checking their integrity. Blocks that don’t match the format are marked as soft corrupt.
Set event 10231 in the init.ora file to cause Oracle to skip software- and media-corrupted blocks when performing full table scans:
Event=”10231 trace name context forever, level 10“
Set event 10233 in the init.ora file to cause Oracle to skip software- and media-corrupted blocks when performing index range scans:
Event=”10233 trace name context forever, level 10“
http://www.quest-pipelines.com/newsletter-v4/0103_C.htm
http://www.eygle.com/archives/2005/06/eoaoracle9iaebl.html
http://www.eygle.com/archives/2005/09/how_to_simulate_block_corruption_with_bbed.html
今天完成了一个sybase开发库的迁移工作,中间碰到sybase的字符集问题,又学到一点东西,虽然是比较基础的东西。
通常sybase软件和数据库服务配置完成后,都需要修改default language和charset以满足你的应用需求。本例在windows下安装后,sybase server的default language 为english,charset为cp850,而应用需要采用的字符集eucgb,语言为chinse。
服务器端修改方法如下:
1、查看当前数据库字符集
sql>sp_helpsort
sql>go
2、安装字符集
$SYBASEcharsetseucgb> charset -Usa -Psa_pass -Sserver_name binary.srt eucgb
3.在SQL环境中
>select name,id from syscharsets
>go
找到name为cucgb对应的id(假设为170)
4.配置默认字符集
>sp_configure “default character set id”,170
>go
5、修改完成后重启两次(第一次重启数据库会down掉)
客户端:
在$SYBASElocaleslocales.dat中找到[NT]项下面的
locale = enu, us_english, iso_1
locale = fra, french, iso_1
locale = deu, german, iso_1
locale = japanese, japanese, sjis
locale = chs, chinese, eucgb
locale = cht, tchinese, big5
locale = kor, korean, eucksc
locale = us_english.utf8, us_english, utf8
locale = default, us_english, iso_1
直接修改最后一行default的language和charset即可。
当然用server config也同样能完成上面的功能
详细可参考:http://www.sybase.cn/cn/content/support/exp_jszc_ase_cj_031105.html
下午项目部的一兄弟说有个job改了时间后执行有问题。next时间总是不对。远程连上去一看似乎确实如此,要求job在每个小时的20分执行,而实际显示的next时间却不在20分。job如下:
begin
sys.dbms_job.submit(job => :job,
what => ‘DPC_EXCUTE_HOUR;’,
next_date => to_date(‘01-08-2006 16:20:00’, ‘dd-mm-yyyy hh24:mi:ss’),
interval => ‘trunc(sysdate,’‘hh’‘) + 20/(60*24)’);
commit;
end;
/
看起来好像没有什么问题。突然发现job的failures<>0,也就是说上次执行很可能没成功,于是手工run了一下,果然报错了:
ERROR at line 1:
ORA-12011: execution of 1 jobs failed
ORA-06512: at “SYS.DBMS_IJOB”, line 242
ORA-06512: at “SYS.DBMS_JOB”, line 218
ORA-06512: at line 1
尝试解决
1、手工执行存储过程,没问题
2、重建job后依然如故
好像没什么道理,仔细检查job的执行时间,才发现原来是interval的间隔设置有问题,改成’trunc(sysdate,’‘hh’‘) + 1/24+20/(60*24)’,问题得到解决,呵呵,不注意这个地方还真容易出错:)
现场的sybase生产库越来越大,不久的将来就要达到每月增长3000w(一张表)的规模,不转移历史数据是不行的了!
将历史数据从运行生产库转移到历史库,oracle有比较成熟的技术了dblink+job,高级复制,stream等等.至少作起来不会无从下手了
sybase的从来没做过这种方式的,google了一下才发现sybase原来也有类似功能CIS,测试了一下,大致过程如下
(1) 在历史库上配置interface服务名grv32
(2) 在历史库上建立远程服务器配置sp_addserver grv32,grv32 (sp_addserver grv32,ASEnterprise,grv32)
select * from sysservers—查看当前服务
(3) 创建代理表
CREATE PROXY_TABLE P_DATA_DLSD
at ‘grv32.GRDATA.dbo.DATA_DLSD’
(4)更新统计信息
update statistics P_DATA_DLSD
(5)修改CIS参数go sp_configure “enable cis”,1 go
剩下的就可以通过存储过程+job来转移历史数据了,CIS还提供RPC来完成数据同步等其他功能。
测试的时侯没有作update statistics,结果性能好象不是很好,明显不如Oracle的dblink,还需要做优化测试.
另外,sybase还提供了replication server,也可实现sybase数据库之间的数据复制,有空再研究下了!
早上一来就接到现场一个数据库连接不上的消息,等我远程连上去的时候,数据库服务已被项目部的兄弟停掉了(汗),但过了10多分钟数据库还没down下去,svrmgrl也进不去。
查看日志文件:
Errors in file d:oracleadminorclbdumporclDBW0.TRC:
ORA-01242: data file suffered media failure: database in NOARCHIVELOG mode
ORA-01114: IO error writing block to file 29 (block # 87391)
ORA-01110: data file 29: ‘E:ORADATAUSER_LDATA08.DBF’
ORA-27070: skgfdisp: async read/write failed
OSD-04016: 查询非同步 I/O 请求发生错误.
O/S-Error: (OS 23) 数据错误 (循环冗余检查)。
心理一凉,不会是硬盘挂了吧(据上次硬盘坏了还不到一个月呢)。电话打到现场说没亮黄灯。难道是数据文件损坏,看样子这种情况多半是要恢复数据了。报告了老板准备去现场了,老板说要想出个一劳永逸的方案,不要总是出这种问题。呵呵,不是我不想,巧妇难为无米之炊哟!!
不过事情也并不是想像得那么坏,试着强行终止oracle进程,然后startup结果出乎意料,居然起来了,日志文件没有任何错误信息。赫赫,真有点莫名其妙。会不会有坏块了或其他问题?看来还得继续观察.
Wor l dwi de RDBMS Sof twar e Revenue by Top 5 Vendo r , 2 003200 5 ( $M) Vendor 2003 2004 2005 2004Share (%) 2005Share (%) 20042005Growth (%) Oracle Corporation 5,362.7 5,982.4 6,494.7 45.0 44.6 8.6 IBM 2,825.0 2,923.0 3,113.0 22.0 21.4 6.5 Microsoft Corporation 1,650.0 2,013.0 2,441.5 15.1 16.8 21.3 Sybase Inc. 442.0 470.9 502.6 3.5 3.5 6.7 NCR Teradata 325.4 390.0 423.0 2.9 2.9 8.5 Other 1,441.3 1,528.8 1,590.8 11.5 10.9 4.1 Total 12,046.4 13,308.1 14,565.6 100.0 100.0 9.4 Note: 2005 values are preliminary estimates. Source: IDC, 2006
近段时间总有人问commit了怎么回退,如何查看是谁delete了数据。比较郁闷的说
下午整理了下logminer贴出来
刚刚做完升级方案,准备歇会的。项目部的一兄弟就打个电话过来说yq的数据库连不上了,而且连错误也没有。客户端或pl/sql连上去后就停在那里不动了。把日志发回来看了看也没有萨问题的(主要是习惯拿来日志就搜索ora-xxx,最后还是仔细看日志发现了问题)。没办法,看来一下子还不知道是撒问题。那地方又不能远程控制,只能用QQ了,QQ还真是好咚咚,虽然远程控制速度奇慢(公司网络也够差的了),最后是我通过QQ看他的桌面,然后指挥他操作。
先是tnsping oradb没有问题,初步判断应该不是监听的问题。
然后用sqlplus / as sysdba 连进去也是正常的,那就说明数据库也是好的。那问题出在哪里呢?
突然想起来日志中有一段很奇怪:
Thread 1 cannot allocate new log, sequence 145372
All online logs needed archiving
怎么会需要归档呢,应该是非归档模式的吖。
archive log list 一看,我靠真是归档模式,而且没有启用自动归档。这就难怪了,上次(大概半月前)项目部的兄弟就说出现过类似问题,重启后又好了
晕哟,也不知道是一开始装的时候就这样了还是后来有人改过(日志被清空过)
我们的数据库居然就这样一直跑了一年多了........汗!!!
以前每次用8i客户端导出9i数据库,再导入到8i库好像都没撒问题,这次开发组的兄弟说就是有问题了
IMP-00017: 由于 ORACLE 错误6550,以下的语句失败 “BEGIN ” “sys.dbms_logrep_imp.instantiate_schema(schema_name=>‘SDUSER’, export_db_nam” “e=>‘HLSD’, inst_scn=>‘4008049’);” “COMMIT; END;”
IMP-00003: ORACLE 错误6550出现 ORA-06550: 第 2 行, 第 1 列:
PLS-00201: 必须说明标识符 ‘SYS.DBMS_LOGREP_IMP’ ORA-06550: 第 2 行, 第 Cause
找了半天metalink解释如下