WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606
全部博文(599)
分类: Oracle
2011-09-13 16:20:08
1.1、RESTORE POINT ONLY状态解释
最近在做数据库闪回的时候,发现数据库不能闪回,经检查数据库FLASHBACK_ON状态是RESTORE POINT ONLY,一般正常情况下这种状态应该是YES,而也正是这个原因导致数据库不能闪回到我们想要的时间点。
以下摘自ORACLE联机文档对V$DATABASE列FLASHBACK_ON的解析:
FLASHBACK_ON VARCHAR2(3) Possible values are as follows:
YES - Flashback is on
NO - Flashback is off
RESTORE POINT ONLY - Flashback is on but one can only flashback to guaranteed restore points
联机文档的FLASHBACK_ON 是VARCHAR2(3)还没来得及更新,VARCHAR2(3)肯定无法容纳RESTORE POINT ONLY这么多字符。实际 V$DATABASE视图的FLASHBACK_ON列已经是VARCHAR2(18)。
状态YES和NO比较好理解。
联机文档对RESTORE POINT ONLY的解释是:闪回是开启的,但是只能闪回到担保的还原点。
由于担保的还原点的存在,ORACLE还没有立马关闭RVWR进程,此时闪回日志也没有删除,数据库还会继续进行闪回日志的维护,但是一旦担保的还原点删除,数据库的闪回将会立马关闭,对应的闪回日志也会立马删除。
如果你创建了一个担保的还原点,然后执行ALTER DATABASE FLASHBACK OFF命令,那么V$DATABASE的FLASHBACK_ON列将会处于RESTORE POINT ONLY状态。
如下所示:
SQL> CREATE RESTORE POINT SP1 GUARANTEE FLASHBACK DATABASE;
还原点已创建。
SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
YES ARCHIVELOG
SQL> ALTER DATABASE FLASHBACK OFF;
数据库已更改。
SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
RESTORE POINT ONLY ARCHIVELOG
这种情况下数据库只允许闪回到担保的还原点这个时间点。这个时候一旦删掉了担保的还原点FLASHBACK_ON列将会从RESTORE POINT ONLY变为OFF,对应的闪回日志也将会删除。
SQL> DROP RESTORE POINT SP1;
还原点已删除。
SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
NO ARCHIVELOG
1.2、FLASHBACK_ON=YES正常的对于FLASHBACK_ON列处于YES的状态,只要相关的闪回日志和归档日志存在,就可以闪回到任何时间点。
如下所示:
SQL> SELECT NAME,TO_CHAR(TIME,'YYYY/MM/DD HH24:MI:SS'),GUARANTEE_FLASHBACK_DATAB
ASE FROM V$RESTORE_POINT;
NAME TO_CHAR(TIME,'YYYY/ GUA
-------------------- ------------------- ---
SP1 2011/09/13 12:51:14 YES
SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
YES ARCHIVELOG
SQL> SELECT SYSDATE FROM DUAL;
SYSDATE
-------------------
2011/09/13 14:26:35
SQL> SHUTDOWN IMMEDIATE
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> STARTUP MOUNT
ORACLE 例程已经启动。
Total System Global Area 1073741824 bytes
Fixed Size 1250044 bytes
Variable Size 754978052 bytes
Database Buffers 310378496 bytes
Redo Buffers 7135232 bytes
数据库装载完毕。
SQL> FLASHBACK DATABASE TO TIMESTAMP TO_TIMESTAMP('2011/09/13 14:00:00','YYYY/M
M/DD HH24:MI:SS');
闪回完成。
SQL> ALTER DATABASE OPEN RESETLOGS;
数据库已更改。
1.3、FLASHBACK_ON=RESTORE POINT ONLY
而对于FLASHBACK_ON列处于RESTORE POINT ONLY的状态,只允许闪回到建立担保的还原点那个时刻。
下面从一个全新的环境开始测试,初始数据库闪回和归档都没开启。
1.3.1建立测试环境
SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
NO NOARCHIVELOG
SQL> SELECT NAME FROM V$RESTORE_POINT;
未选定行
SQL> SHUTDOWN IMMEDIATE
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> STARTUP MOUNT
ORACLE 例程已经启动。
Total System Global Area 1073741824 bytes
Fixed Size 1250044 bytes
Variable Size 754978052 bytes
Database Buffers 310378496 bytes
Redo Buffers 7135232 bytes
数据库装载完毕。
SQL> ALTER DATABASE ARCHIVELOG;
数据库已更改。
SQL> ALTER DATABASE FLASHBACK ON;
数据库已更改。
SQL> CREATE RESTORE POINT SP1 GUARANTEE FLASHBACK DATABASE;
还原点已创建。
SQL> ALTER DATABASE OPEN;
数据库已更改。
SQL> ALTER SESSION SET NLS_DATE_FORMAT='YYYY/MM/DD HH24:MI:SS';
会话已更改。
SQL> SELECT SYSDATE FROM DUAL;
SYSDATE
-------------------
2011/09/13 15:00:18
SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
YES ARCHIVELOG
SQL> COL NAME FORMAT A20
SQL> SELECT NAME,TO_CHAR(TIME,'YYYY/MM/DD HH24:MI:SS'),GUARANTEE_FLASHBACK_DATAB
ASE FROM V$RESTORE_POINT;
NAME TO_CHAR(TIME,'YYYY/ GUA
-------------------- ------------------- ---
SP1 2011/09/13 14:59:56 YES
首先将数据库开启到闪回模式,并且在14:59:56的时候建立了一个担保的还原点。
1.3.2建立测试表
将数据库切换到ADMIN用户,建立测试表TEST。
SQL> CONN ADMIN/ADMIN
已连接。
SQL> SET TIME ON
15:06:10 SQL> CREATE TABLE TEST(ID INT);
表已创建。
15:06:14 SQL> INSERT INTO TEST VALUES(1);
已创建 1 行。
15:06:21 SQL> COMMIT;
提交完成。
15:06:23 SQL> ALTER SYSTEM SWITCH LOGFILE;
系统已更改。
15:06:30 SQL> INSERT INTO TEST VALUES(2);
已创建 1 行。
15:06:34 SQL> COMMIT;
提交完成。
15:06:35 SQL> ALTER SYSTEM SWITCH LOGFILE;
系统已更改。
15:06:37 SQL> INSERT INTO TEST VALUES(3);
已创建 1 行。
15:06:39 SQL> COMMIT;
提交完成。
15:06:40 SQL> ALTER SYSTEM SWITCH LOGFILE;
系统已更改。
创建测试表TEST,并插入一些记录,如果将数据库闪回到15:06:30时刻,那么表TEST中只有一条记录。
1.3.3测试将数据库闪回到15:06:30时刻
切换到SYS用户关闭数据库的闪回,并行执行闪回。
15:06:46 SQL> CONN / AS SYSDBA
已连接。
15:07:38 SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
YES ARCHIVELOG
15:08:15 SQL> ALTER DATABASE FLASHBACK OFF;
数据库已更改。
15:08:26 SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
RESTORE POINT ONLY ARCHIVELOG
15:08:28 SQL> SHUTDOWN IMMEDIATE
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
15:09:32 SQL> STARTUP MOUNT
ORACLE 例程已经启动。
Total System Global Area 1073741824 bytes
Fixed Size 1250044 bytes
Variable Size 754978052 bytes
Database Buffers 310378496 bytes
Redo Buffers 7135232 bytes
数据库装载完毕。
15:10:11 SQL> FLASHBACK DATABASE TO TIMESTAMP TO_TIMESTAMP('2011/09/13 15:06:30
,'YYYY/MM/DD HH24:MI:SS');
FLASHBACK DATABASE TO TIMESTAMP TO_TIMESTAMP('2011/09/13 15:06:30','YYYY/MM/DD
H24:MI:SS')
*
第 1 行出现错误:
ORA-38726: 未启用闪回数据库事件记录。
15:12:38 SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
RESTORE POINT ONLY ARCHIVELOG
15:12:51 SQL> FLASHBACK DATABASE TO RESTORE POINT SP1;
闪回完成。
15:14:41 SQL> ALTER DATABASE OPEN READ ONLY;
数据库已更改。
15:15:13 SQL> CONN ADMIN/ADMIN
已连接。
15:15:25 SQL> DESC TEST;
ERROR:
ORA-04043: 对象 TEST 不存在
可以看到数据库不允许闪回到其他时刻,只允许闪回到担保的还原点。
1.3.4修改FLASHBACK_ON状态
首先将数据库恢复上面闪回之前的时刻,以便重新测试。
15:15:27 SQL> CONN / AS SYSDBA
已连接。
15:19:05 SQL> SHUTDOWN IMMEDIATE
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
15:35:37 SQL> STARTUP MOUNT
ORACLE 例程已经启动。
Total System Global Area 1073741824 bytes
Fixed Size 1250044 bytes
Variable Size 754978052 bytes
Database Buffers 310378496 bytes
Redo Buffers 7135232 bytes
数据库装载完毕。
15:36:10 SQL> RECOVER DATABASE;
ORA-00279: 更改 546092 (在 09/13/2011 15:05:06 生成) 对于线程 1 是必需的
ORA-00289: 建议: C:\ORACLE_BACKUP\ARCHIVELOG\ARC00002_0761755847.001
ORA-00280: 更改 546092 (用于线程 1) 在序列 #2 中
15:41:52 指定日志: {
AUTO
已应用的日志。
完成介质恢复。
15:41:58 SQL> ALTER DATABASE OPEN;
数据库已更改。
15:42:13 SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
RESTORE POINT ONLY ARCHIVELOG
15:44:14 SQL> SELECT * FROM ADMIN.TEST;
ID
----------
1
2
3
数据库已经恢复到原来的时刻。
对于FLASHBACK_ON处于RESTORE POINT ONLY的状态,可以重新关闭数据库执行ALTER DATABSE FLASHBACK
ON 将其重新修改为YES。
如果没有担保的还原点,在执行了ALTER DATABASE FLASHBACK OFF命令后,所有的闪回日志会被清空,这个时候是不能修改为YES了。
看看下面的情况:
15:45:55 SQL> SHUTDOWN IMMEDIATE
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
15:48:42 SQL> STARTUP MOUNT
ORACLE 例程已经启动。
Total System Global Area 1073741824 bytes
Fixed Size 1250044 bytes
Variable Size 754978052 bytes
Database Buffers 310378496 bytes
Redo Buffers 7135232 bytes
数据库装载完毕。
15:49:42 SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
RESTORE POINT ONLY ARCHIVELOG
15:50:09 SQL> ALTER DATABASE FLASHBACK ON;
数据库已更改。
15:50:15 SQL> SELECT FLASHBACK_ON,LOG_MODE FROM V$DATABASE;
FLASHBACK_ON LOG_MODE
------------------ ------------
YES ARCHIVELOG
一旦FLASHBACK_ON为YES,我们就可以闪回到我们想要的时刻,只要对应时刻的闪回日志和归档日志存在。
15:55:52 SQL> FLASHBACK DATABASE TO TIMESTAMP TO_TIMESTAMP('2011/09/13 15:06:30'
,'YYYY/MM/DD HH24:MI:SS');
闪回完成。
15:56:01 SQL> ALTER DATABASE OPEN READ ONLY;
数据库已更改。
15:56:19 SQL> SELECT * FROM ADMIN.TEST;
ID
----------
1
可以看到数据库已经闪回到我们想要的时刻。和上面唯一不同之处就是我们关闭了数据库重新打开了闪回(ALTER DATABASE FLASHBACK ON)。