Oracle 开启归档日志
开启归档日志 = 让 Oracle 具备“回到过去”的能力(本次演示采用 Windows 10 + Oracle19c 环境)。
| 归档日志(ARCHIVELOG)到底有什么用? | ||
|---|---|---|
| 场景 | 没有归档(NOARCHIVELOG) | 有归档(ARCHIVELOG) |
| 1. 时间点恢复 | 只能恢复到最后一次全库备份 | 可恢复到任意一秒(只要归档+在线日志还在) |
| 2. 联机备份 | 必须关闭数据库做冷备份 | 可以24×7 热备份,业务不中断 |
| 3. 增量/差异备份 | 不支持 | RMAN 支持增量、差异、块级恢复 |
| 4. 迁移/同步 | 只能停机拷文件 | 可配合 Data Guard、GoldenGate 做实时备库 |
| 5. 块损坏修复 | 发现坏块只能整库还原 | RMAN 可用归档+备份块级恢复坏块 |
| 6. 逻辑误操作 | 删错表/错更新,只能认栽 | 可闪回+归档把表恢复到误操作前 |
进入命令行模式的 SQL 输入,查看归档日志开启状态(archive log list;):
(以下所有命令均在cmd命令行模式下执行)

可以看到现在是禁用状态;
开启归档日志
1、创建一个存储归档日志的目录(物理目录);

2、设置归档日志的目的地:
SQL> alter system set log_archive_dest_1='LOCATION=D:\Oracle19c\archiveLog' scope=spfile;3、重启数据库并切换 mount 状态(命令行进入数据库执行):
SQL> shutdown immediate;
SQL> startup mount;4、开启归档模式:
SQL> alter database archivelog;5、打开数据库(把控制文件里记录的所有数据文件、临时文件、redo log 全部打开,普通会话才能登录并读写数据):
SQL> alter database open;6、重启数据库:
SQL> shutdown immediate;
SQL> startup;7、查看归档日志是否成功开启:
SQL> archive log list;上实操:

手动生成归档日志
只要数据库处于 ARCHIVELOG 模式,并且当前在线 redo log 被“写满”或收到“日志切换”命令,Oracle 就会立即把该组日志拷贝成归档日志。
这里展示一下手动生成归档日志:
SQL> alter system switch logfile;然后归档目录下就会生成一个归档文件:

这个文件名可能不太好看,因为现在的 log_archive_format 参数里根本没写 .arc,于是 Oracle 就按模板直接生成文件名,看起来“没有扩展名”。
查看当前命名模板:
SQL> show parameter log_archive_format;
这个命名模板生成的归档日志文件就是这样的,可以修改一下,改成 .arc 的会比较好看一点。
SQL> alter system set log_archive_format='%t_%s_%r_%d.arc' scope=spfile;参数介绍:
%t:线程号(单实例就是 1);
%s:序列号(每切换一次日志+1);
%r:RESETLOGS_ID(防止旧备份混淆);
%d:数据库 DBID(可选);
log_archive_format 属于 “静态参数”,必须重启实例才能生效,再重新生成归档日志,就可以获得一个 .arc 格式的归档日志文件。


普通的 INSERT / UPDATE / DELETE / SELECT 本身永远不会“直接”产生新的归档日志文件。
它们只产生 redo 记录,写进当前正在使用的在线 redo log 组。
只有当这组在线日志被写满(或你手工 switch logfile)发生日志切换时,Oracle 才把整组旧日志拷贝成归档日志,如:
t0 online redo group 1 正在写
t1 alter system switch logfile; → ARCn 立刻把 group 1 复制成 ARC0001_xxx.arc
t2 你继续大量 DML、commit
t3 group 2 写满,自动切到 group 3 → ARCn 复制 group 2 成 ARC0002_xxx.arc因此:
事务再多、再大,只要还没切换日志,就仍然只有那一组在线日志,磁盘上不会多出一个 .arc 文件。
一旦切换,无论切换是由“写满”还是你手动触发,才一次性生成一个归档文件,里面可能包含刚才那批 DML 的 redo,也可能包含更早事务的 redo。
删除归档日志
使用 RMAN 删除,一般用第一种方式。
# 连接 RMAN
rman target /# 1、删除7天前的归档日志
RMAN> DELETE ARCHIVELOG UNTIL TIME 'SYSDATE-7';# 2、删除所有归档日志
RMAN> DELETE ARCHIVELOG ALL;# 3、删除指定序列号的归档日志
RMAN> DELETE ARCHIVELOG UNTIL SEQUENCE 1000;有种情况,就是不知道删除的方式,然后直接去目录里面删了,但是 RMAN 的控制文件记录了归档日志的信息,使用 LIST ARCHIVELOG ALL; 这个命令还是能看到的,这样可能导致的下次的物理备份,会找不到该文件,从而导致失败。

解决方法:
# 使用 CROSSCHECK 自动识别丢失的归档
RMAN> CROSSCHECK ARCHIVELOG ALL;
# 删除那些 RMAN 记录中存在、但实际已丢失的归档日志记录。
RMAN> DELETE EXPIRED ARCHIVELOG ALL;
# 重新查询
RMAN> LIST ARCHIVELOG ALL;实操如图:

避坑指南
设置归档日志目的地的时候,不能写成:
alter system set log_archive_dest_1='D:\Oracle19c\archiveLog' scope=spfile;LOG_ARCHIVE_DEST_1 不是随便给一个路径字符串就行的,它必须写成 “LOCATION=路径” 的完整格式,否则实例启动时解析失败,报 ORA-16024: parameter LOG_ARCHIVE_DEST_1 cannot be parsed。
错误示例如下,然后就可能启不起来了:

解决方法:
在安装目录下找到这个文件

右键编辑,写入
db_name=orcl
memory_target=1G
control_files='D:\Oracle19c\oradata\ORCL\CONTROL01.CTL','D:\Oracle19c\fast_recovery_area\ORCL\CONTROL02.CTL'
compatible='19.0.0'
db_block_size=8192里面的 control_files 路径是你的电脑的改文件的路径,可以去 oracle 安装目录搜索这两个文件,然后右键打开文件位置,复制路径上去就行了。

然后删除这个文件。

再启动数据库,重新生成该文件:
-- 这次启动不要去找默认的 SPFILE,而是用我指定的这个文本参数文件(initorcl.ora)来启动实例。
SQL> startup pfile='%ORACLE_HOME%\database\initorcl.ora';
-- 重新生成 SPFILEORCL.ORA
SQL> create spfile from pfile;
-- 关闭数据库
SQL> shutdown immediate;
-- 重新启动
SQL> startup;具体实现如图:

这样就解决了,避坑!
