其实并不希望用户都来浏览这篇文章,如果是自己学习还好,如果是出现问题了,可能就比较麻烦了。
经常会有用户咨询我们,我不小心删除了ArcSDE里面的相关表,或者删除了相关记录,导致ArcSDE服务、连接、编辑等出现的相关问题,先不说这些问题怎么解决,对出现这种现象就应该坚决杜绝,老有许多用户属于那种不知道事大事小,什么都敢亲身实践,虽然他们知道“实践是检验真理的唯一途径”,但是如果你不了解数据库或者ArcSDE的相关原理,你就自认为的操作,出现问题负责任的肯定是自己。之所以说这些还是希望用户不要擅自操作,数据库一旦挂了,前端再高效再炫的客户端也是白搭啊。
虽然这篇文章的题目是恢复ArcSDE的要素类和要素,但是我并没有真正的在ArcSDE里面做例子,或者但是我以oracle的删除表和删除记录为例作测试,至于ArcSDE,那么就需要用户了解ArcSDE的表结构之后,做相关的解决了,我也会给用户进行相关的说明。
删除记录的恢复
测试场景:我删除sde用户下table_locks里面的若干记录,然后恢复
操作步骤:
需要用户以管理员身份登录
1:查看table_locks,然后删除,提交
SQL> select * from sde.table_locks;
SDE_ID REGISTRATION_ID LO
---------- --------------- --
2031 179 S
2031 192 S
2010 179 S
2010 192 S
SQL> delete from sde.table_locks where sde_id=2010;
已删除2行。
SQL> commit;
提交完成。
SQL> select * from sde.table_locks;
SDE_ID REGISTRATION_ID LO
---------- --------------- --
2031 179 S
2031 192 S
相关原理:SCN
SCN: System Change Number
SCN是顺序递增的一个数字,在Oracle 中用来标识数据库的每一次改动,及其先后顺序。SCN的最大值是0xffff.ffffffff。
Oracle对SCN的管理(RAC环境就由DBA来管理吧)
单节点的instance中,SCN值存在SGA区,由system commit number latch保护。任何进程要得到当前的SCN值,都要先得到这个latch。
SCN的机制
数据库运行时的SCN
我们先看下oracle事务中的数据变化是如何写入数据文件的:
1、 事务开始;
2、 在buffer cache中找到需要的数据块,如果没有找到,则从数据文件中载入buffer cache中;
3、 事务修改buffer cache的数据块,该数据被标识为“脏数据”,并被写入log buffer中;
4、 事务提交,LGWR进程将log buffer中的“脏数据”写入redo log file中;
5、 当发生checkpoint,CKPT进程更新所有数据文件的文件头中的信息,DBWr进程则负责将Buffer Cache中的脏数据写入到数据文件中。
Redo log中的high scn和low scn
Oracle的Redo log会顺序纪录数据库的各个变化。一组redo log文件写满后,会自动切换到下一组redo log文件。则上一组redo log的high scn就是下一组redo log的low scn。在current log中high scn为无穷大。
可通过查询v$log_history查看 low scn和 high scn。
更多了解:
http://czmmiao.iteye.com/blog/1010267
http://www.cnblogs.com/daduxiong/archive/2010/08/19/1803764.html
2:通过SCN的方法来恢复
--获得当前的SCN
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
19078853
--select * from sde.table_locks as of scn 19078843;
--确定删除的数据是否存在,如果存在,则恢复数据;如果不是,则继续缩小scn号
SQL> select * from sde.table_locks as of scn 19078830;
SDE_ID REGISTRATION_ID LO
---------- --------------- --
2031 179 S
2031 192 S
2010 179 S
2010 192 S
--将table_locks闪回到前面的scn
SQL> flashback table sde.table_locks to scn 19078830;
flashback table sde.table_locks to scn 19078830
*
第 1 行出现错误:
ORA-08189: cannot flashback the table because row movement is not enabled
--这个命令的作用是,允许Oracle 修改分配给行的rowid。在Oracle 中,插入一行时就会为它分配一个rowid,而且这一行永远拥有这个rowid。闪回表处理会对EMP 完成DELETE,并且重新插入行,这样就会为这些行分配一个新的rowid。要支持闪回就必须允许Oracle 执行这个操作
SQL> alter table sde.table_locks enable row movement;
表已更改。
SQL> flashback table sde.table_locks to scn 19078830;
闪回完成。
SQL> select * from sde.table_locks;
SDE_ID REGISTRATION_ID LO
---------- --------------- --
2031 179 S
2031 192 S
2010 179 S
2010 192 S
3:使用时间恢复删除数据
以下信息仅供参考
1、查询当前系统时间
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
2、查询删除数据的时间点的数据
select * from 表名 as of timestamp to_timestamp('2013-05-29 15:29:00','yyyy-mm-dd hh24:mi:ss'); (如果不是,则继续缩小范围)
3、恢复删除且已提交的数据
flashback table 表名 to timestamp to_timestamp('2013-05-29 15:29:00','yyyy-mm-dd hh24:mi:ss');
ArcSDE的建议:
我们上面演示的只针对单个表的记录删除的恢复,那么对ArcSDE来说
1:如果是非版本数据的编辑,就可以完全结合上面的例子直接恢复
2:如果是版本编辑的话,这个就需要用户去了解ArcSDE的版本表了。
至少用户需要对:基表、增量表、版本表(States、State_lineages、Versions等)进行闪回,而且如果是多用户并发编辑的话,状态表里面的数据就不仅仅是一个版本的信息,所以这个就比较麻烦。
可能有用户来说,其实版本编辑,误删除了,大不了重新编辑,或者不要这个版本的信息,反正我的default版本的数据并没有变化,恭喜你,如果你想到这一点,说明你对版本原理比较了解。
删除表的恢复
测试场景:drop一个数据库中的表对象,然后进行恢复
操作步骤:
对误删的表,只要没有使用PURGE永久删除选项,那么从flash back区恢复回来希望是挺大的。
1:删除一个表对象
SQL> select count(*) from test.a;
COUNT(*)
----------
33769
SQL> drop table test.a;
表已删除。
SQL> commit;
提交完成。
SQL> select count(*) from test.a;
select count(*) from test.a
*
第 1 行出现错误:
ORA-00942: ???????
2:使用闪回方法来恢复
原理:在Oracle数据库,用户删除的对象会存储在一个类似回收站的表里面,这些信息会在这个表里面进行存储,但是如果用户的删除操作比较多,这个表里面的信息会类似非归档日志,重新写入新的信息,如果那样的话就不好恢复了,所以出现问题,赶紧解决才是正道。
用户需要连接test用户,因为删除的表a属于该用户,查看回收表信息
SQL> select original_name,operation,type from recyclebin;
ORIGINAL_NAME OPERATION TYPE
---------------------------------------------------------------- ------------------ --------------
D138 DROP TABLE
D138_IDX1 DROP INDEX
D138_PK DROP INDEX
KEYSET_1247 DROP TABLE
KEYSET_1300 DROP TABLE
KEYSET_1301 DROP TABLE
KEYSET_1316 DROP TABLE
ARCGIS_SECURITY_USER_ROLE DROP TABLE
SYS_C0018056 DROP INDEX
ARCGIS_SECURITY_ROLES DROP TABLE
SYS_C0018067 DROP INDEX
ORIGINAL_NAME OPERATION TYPE
---------------------------------------------------------------- ------------------ --------------
ARCGIS_SECURITY_USER_ROLE DROP TABLE
SYS_C0018070 DROP INDEX
ARCGIS_SECURITY_ROLES DROP TABLE
SYS_C0018074 DROP INDEX
ARCGIS_SECURITY_USER_ROLE DROP TABLE
SYS_C0018077 DROP INDEX
A DROP TABLE
BIN$3fw3ulkOXtPgQKjApdwLHg==$0 DROP INDEX
SYS_LOB0000094656C00018$$ DROP LOB
SYS_IL0000094656C00018$$ DROP LOB INDEX
我们可以看到有A名称的表,然后进行恢复即可
SQL> flashback table test.a to before drop;
闪回完成。
SQL> select count(*) from test.a;
COUNT(*)
----------
33769
但注意oracle( Release 10.2.0.1.0)回收站不支持系统表空间,如果删除的这个在系统表空间,这个表是不能闪回的
对表数据更新一段时间后,只有在初始化参数UNDO_RETENTION设置的时间内才可以查询到表flashback_transaction_query的数据更改记录。而且,只有初始化参数UNDO_MANAGEMENT设置为AUTO后才能使用闪回查询。
ArcSDE的建议:对ArcSDE来说也是一样
1:如果没有注册版本,如果使用ArcGIS客户端对要素类进行删除,我们可以看到数据库里面有
SQL> select original_name,operation,type from recyclebin where droptime='2013-05-31:12:25:41';
ORIGINAL_NAME OPERATION TYPE
---------------------------------------------------------------- ------------------ --------------
A DROP TABLE
SYS_LOB0000094656C00018$$ DROP LOB
SYS_IL0000094656C00018$$ DROP LOB INDEX
BIN$3fxefjQC5+rgQKjApdwUEQ==$2 DROP INDEX
所以说,使用ArcMap删除不仅仅是要素类,还包含相关的索引对象还有其他,所以使用上面的方法可以只恢复同名表A,对ArcGIS10.1是没有问题的,完全可以通过桌面进行注册即可,对10版本之前的可能就有点小问题了,但是最主要的同名表恢复过来,我们可以通过sdelayer -o register方法注册也可以。
2:如果是注册版本
还是老样子,基表、增量表,ArcSDE的其他表的管理信息需要恢复记录(比如sde用户下table_regisertry会注册SDE库里面存储的要素类),那么使用数据库的方法闪回删除的要素类的同名表,类似这些注册信息的表的记录也需要进行操作。
也就是说,需要用户考虑基本和增量表的回复,其他的可以通过sdetable -o register将数据注册到ArcSDE中,通过Register as geodatabase将数据注册到Geodatabase中。
以上方法都是根据数据库的方式对ArcSDE的误操作进行一些简单的补救措施,仅供参考!