注册
实时归档、即时归档与 KEEP
专栏/技术分享/ 文章详情 /

实时归档、即时归档与 KEEP

🌌 2026/08/28 131 0 0
摘要

归档:把刷盘线程里的 RLOG_PKG 送到本机目录,或经 MAL 送到另一个实例。归档一共九类。本文只写 本地(LOCAL)、实时(REALTIME)、即时(TIMELY),以及实时路径上的 KEEP_RLOG_PKG。其余(REMOTE、ASYNC、SYNC、SUBSCRIBE、RAFT、LEARNER)不展开。

实时、即时只在 PRIMARY 上真正发送。目标实例必须是 STANDBY。DM 实时目标 1~8 个,即时目标 1~8 个。任意一路实时或即时失败,主库进 SUSPEND。发送方是日志刷盘线程,不是 dmwatcher

配置文件是实例目录下的 dmarch.inidm.iniARCH_INI=1 才会读它。同一 GLOBAL 守护组内,各实例的 ARCH_TYPE 集合要配成一样。


1. 本地归档

NORMAL / PRIMARY:包写入联机日志之后,归档线程再写本地文件。STANDBY:收到对端原包后直接写入本地归档,同时 APPLY;本机重演时新写的 Redo 只进联机日志,不进归档文件。于是组内各节点归档文件里都是「源库产生的那份包」,不是各写各的联机日志拷贝。

联机日志两个文件循环覆盖。本地归档不能覆盖,直到删除或碰到空间上限。ARCH_SPACE_LIMIT=0 表示不限制;盘满且所有本地归档的 ARCH_HANG_FLAG 行为又要求挂起时,实例停在那里等空间。

字段 含义
PMNT_MAGIC 库初始化时生成,组内相同(DDL_CLONE 还原并 UPDATE DB_MAGIC 除外)
DB_MAGIC 标识写入这份归档文件的库。初始化生成,还原后会变。组内各库不同
SRC_DB_MAGIC 标识产生 Redo 的库。主库归档里与 DB_MAGIC 相同;备库归档里等于主库 DB_MAGIC

PRIMARY/NORMAL 文件名:

ARCH_NAME_DB_MAGIC_EP节点号_YYYY-MM-DD_HH-MM-SS.log

例:ARCHIVE_LOCAL1_0x567891_EP0_2022-03-20_10-35-34.log

STANDBY 文件名:

STANDBY_ARCHIVE_P_DB_MAGIC_EP节点号_SELF_DB_MAGIC_日期时间.log

例:STANDBY_ARCHIVE_0x123456_EP0_0x234567_2022-03-20_10-35-34.log

节名不要叫 STANDBY_ARCHIVE,手册保留给备库生成的文件。

完整本地段:

ARCH_WAIT_APPLY = 0 ARCH_RESERVE_TIME = 0 [ARCHIVE_LOCAL1] ARCH_TYPE = LOCAL ARCH_DEST = /dmarch/DAMENG/ ARCH_FILE_SIZE = 1024 ARCH_SPACE_LIMIT = 5120 ARCH_FLUSH_BUF_SIZE = 2 ARCH_HANG_FLAG = 1
范围与默认 说明
ARCH_FILE_SIZE 64~2048 MB,默认 1024 单个归档文件,仅 LOCAL
ARCH_SPACE_LIMIT 0 或 1024~2147483647 MB,默认 0 0 不限制;到上限删最早的文件
ARCH_FLUSH_BUF_SIZE 0~128 MB,默认 2 0 关闭归档刷盘缓存
ARCH_HANG_FLAG 0/1/2,默认 1 见下
ARCH_RESERVE_TIME 分钟,默认 0 仅 LOCAL。0 不按时间删。服务器约每 5 分钟扫一次超龄文件

ARCH_HANG_FLAG

  • 0:写失败直接报错,不再试。
  • 1:挂起,反复写直到成功。
  • 2:删最老文件再写,删光仍失败则报错返回。

若库上所有本地归档都不是 1,写失败可能造成归档缺口,后面备份还原会缺日志。

删归档(单机本地归档也可以用;有备库时不要删对方还没拿到的那段):

SELECT SF_ARCHIVELOG_DELETE_BEFORE_TIME('2026-01-01 00:00:00'); SELECT SF_ARCHIVELOG_DELETE_BEFORE_LSN(100000);

第二个参数换成现场 V$RLOG 里已经不需要的 LSN,不要拍脑袋填。


2. 实时归档

时机:写入主库联机日志 之前,MAL 把包发给目标。目标 CTL 校验连续性、是否 OPEN。失败则主库试图 SUSPEND;磁盘损坏一类会 HALT。成功:旧 KEEP 进 APPLY 队列,新包留在内存当 KEEP,然后响应。默认不等 APPLY 完。主库收齐全部实时目标的成功响应,才写自己的联机日志,再走本地归档。

失败时该路状态先不改 Invalid,交给守护 Failover。即时失败则立刻 Invalid。

[ARCHIVE_REALTIME1] ARCH_TYPE = REALTIME ARCH_DEST = STANDBY_INST_NAME WAIT_APPLY = 0 ARCH_FAILOVER = 0

ARCH_DEST 是目标 实例名,与 INSTANCE_NAME 一致,不能写本实例、不能写 IP。目标若是 DSC,写成 DSC01/DSC02 这种用 / 拼起来的全部实例名。

ARCH_SEND_POLICY(全局,仅 REALTIME):

  • 0(默认):发出去就等响应,再写联机日志。
  • 1:先写联机日志,同时等响应,刷盘和等待重叠。

ARCH_FAILOVER 仅 REALTIME/TIMELY,且仅 DW_TYPE=GLOBALDW_MODE=AUTO 时有意义。0:发送失败要 SUSPEND,走守护 Failover,该目标允许自动接管。1:该目标不允许自动接管,仍可手动接管。默认 0

ARCH_STANDBY_APPLY:是否按目标已重演 LSN 决定本机本地归档能不能删。0 否(默认),1 是。多个目标都配了,按已重演 LSN 最小的那路来。支持 REALTIME/TIMELY/SYNC/ASYNC/RAFT。


3. KEEP_RLOG_PKG

实时路径上,目标确认「收到」时,源端联机日志里可能还没有这一包。若目标立刻重演,源端在落盘前宕机:源端重启后包不在自己的联机日志里,目标页上已经有。只能切角色,再把旧源端重建。

因此目标把 最新一包 放在内存,不立刻重演,称为 KEEP_RLOG_PKG。KLSN / KSEQ 描述这包。即时路径先落盘再发,不会出现「目标比源端联机日志多一包」,没有 KEEP。

KEEP 重演的三个时机:

  1. 又到新包:旧 KEEP 进 APPLY,新包成为 KEEP。
  2. 源端通知 FILE_LSN 已等于目标 SLSN:源端已经落盘,KEEP 可以重演。
  3. 升主(switchover / takeover / 自动接管)之前必须重演,APPLY_LSN 不会小于旧源端 FILE_LSN。

源端仍以 PRIMARY 起来时,守护可以让目标丢掉 KEEP,不必切一次角色。

视图在跑实时目标的实例上:

SELECT * FROM V$KEEP_RLOG_PKG; SELECT * FROM V$RAPPLY_SYS; SELECT * FROM V$RAPPLY_LOG_TASK; SELECT * FROM V$RAPPLY_PARALLEL_INFO;

空闲时 KEEP 非空是常见现象:最新一包还在等落盘确认或等下一包。


4. 即时归档

时机:先写入源端联机日志(并本地归档),再 MAL 发送。目标校验后直接 APPLY。

失败:该路立刻 Invalid,源端 SUSPEND。该目标上若有影子会话,会被断开。

即时的组分裂窗口:源端已落盘、尚未发出去时宕机,目标少一包。强制接管后旧源端再起来,可能判分裂,要备份还原。KEEP 管的是相反的窗口(目标多一包)。

[ARCHIVE_TIMELY1] ARCH_TYPE = TIMELY ARCH_DEST = STANDBY_INST_NAME WAIT_APPLY = 1 ARCH_FAILOVER = 0

5. 发送与失败

LOCAL REALTIME TIMELY
目标个数 最多 8 1~8 1~8
走 MAL
时机 写入联机日志后写文件 写入联机日志前发送 写入联机日志后发送
谁做 归档线程 刷盘线程 刷盘线程
失败 盘满按 HANG_FLAG;盘坏 HALT SUSPEND,状态先不动,等守护 SUSPEND,该路立刻 Invalid
目标响应 见 WAIT_APPLY 见 WAIT_APPLY
源模式 PRIMARY / STANDBY / NORMAL PRIMARY PRIMARY
目标模式 STANDBY STANDBY

归档状态:LOCAL / REALTIME / TIMELY 为 Valid、Invalid。Valid 正常干活。Invalid:源端不再把联机包发到该目标。启动时默认 Valid;守护 Open 主库前,日志对不齐的路会改成 Invalid。实时失败挂起后 Failover 再改 Invalid。即时失败直接 Invalid。恢复追上后:源端 SUSPEND → 该路改 Valid → 再 OPEN。

SELECT ARCH_NAME, ARCH_TYPE, ARCH_DEST, ARCH_STATUS FROM V$DM_ARCH_INI; SELECT * FROM V$ARCH_STATUS;

MOUNT 下才能改归档配置(不含增加/删除同步归档这类例外)。PRIMARY 下还有「不能改 arch_ini 参数」等限制,改 dmarch.ini 后通常要 MOUNT 再生效。


6. WAIT_APPLY

仅 REALTIME、TIMELY。文件头全局项 ARCH_WAIT_APPLY;某段上写了 WAIT_APPLY 则以该段为准。

名称 行为
0 高性能 收到即响应,再 APPLY。实时默认
1 事务一致 APPLY 完再响应。即时默认

事务一致:COMMIT 返回时该包已在目标侧重演完。之后按读提交查已提交数据,在源端和目标端应对齐。尚未返回时两边都看不到这次更新。目标越多,提交越慢。

高性能:COMMIT 可在 APPLY 前返回。下一句若在目标端查询,可能仍是上一时刻。

-- 高性能下会踩空的写法(逻辑上,不必真有第二实例) INSERT INTO T VALUES (1); COMMIT; -- 紧接着若在尚未 APPLY 的副本上: SELECT TOP 1 C1 INTO VAR1 FROM T; UPDATE T SET C1 = VAR1 + 1 WHERE C1 = VAR1;

实时路径上 WAIT_APPLY=1 还要求守护 AUTO。DSC 作实时守护源时不能把该项配 1。


7. 上机实验

ARCH_INI、归档线程、文件滚动、空间上限、按 LSN 删除。

数据在 /dmdata/DAMENG,归档在 /dmarch/DAMENG

mkdir -p /dmarch/DAMENG

dm.ini 里确认或准备设:

ARCH_INI = 1

若库已在跑,MOUNT 后改:

ALTER DATABASE MOUNT; SP_SET_PARA_VALUE(2, 'ARCH_INI', 1);

dmarch.ini 只保留本地段,路径存在且对启动用户可写:

[ARCHIVE_LOCAL1] ARCH_TYPE = LOCAL ARCH_DEST = /dmarch/DAMENG/ ARCH_FILE_SIZE = 64 ARCH_SPACE_LIMIT = 1024 ARCH_HANG_FLAG = 1 ARCH_FLUSH_BUF_SIZE = 2

ARCH_FILE_SIZE 临时改小,容易看到第二个文件出现。改完 OPEN:

ALTER DATABASE OPEN; SELECT PARA_NAME, PARA_VALUE FROM V$DM_INI WHERE PARA_NAME = 'ARCH_INI'; SELECT ARCH_NAME, ARCH_TYPE, ARCH_DEST, ARCH_STATUS FROM V$DM_ARCH_INI; SELECT CUR_LSN, FILE_LSN, CKPT_LSN FROM V$RLOG;

造 Redo(单机会写联机日志,本地归档应跟上):

CREATE TABLE ARCH_SOLO(C1 INT, C2 VARCHAR(100)); BEGIN FOR I IN 1..20000 LOOP INSERT INTO ARCH_SOLO VALUES (I, 'redo-gen'); IF MOD(I, 1000) = 0 THEN COMMIT; END IF; END LOOP; COMMIT; END; / CHECKPOINT; SELECT CUR_LSN, FILE_LSN, CKPT_LSN FROM V$RLOG;

看目录(Linux):

ls -l /dmarch/DAMENG/ ls /dmarch/DAMENG/*.log | wc -l du -sh /dmarch/DAMENG

应出现 ARCHIVE_LOCAL1_<DB_MAGIC>_EP0_*.log。文件个数随 ARCH_FILE_SIZE 和日志量增加。到 ARCH_SPACE_LIMIT 后最早的文件会被删。

查魔数,核对文件名里的那一截:

SELECT DB_MAGIC FROM V$DATABASE; -- 若当前版本无此列,用: SELECT * FROM V$DATABASE;

再把 ARCH_SOLO 多插几轮,对比 FILE_LSN 前进和目录里最新文件的时间戳。

按 LSN 删之前先记下当前 FILE_LSN,只删明显落后的值:

SELECT FILE_LSN, CKPT_LSN FROM V$RLOG; -- 确认该 LSN 已不需要保留后再执行,例如: -- SELECT SF_ARCHIVELOG_DELETE_BEFORE_LSN(某个已过时的值);

删完再 ls,最早的文件应减少。ARCH_RESERVE_TIME 配成较小分钟数后等两个 5 分钟周期,也可看到超龄文件消失。

挂起策略不要在生产盘上用 0 做实验。单机若故意把 ARCH_DEST 指到只读目录,ARCH_HANG_FLAG=1 时会话会卡在归档写入;改回可写目录或把 flag 改掉并重启归档配置后才能恢复。做这种试验用独立目录。

相关状态(单机也能执行,和归档失败时的主库行为是同一组语句):

ALTER DATABASE SUSPEND; ALTER DATABASE OPEN; ALTER DATABASE MOUNT; ALTER DATABASE OPEN;

SUSPEND 限制 Redo 刷盘,COMMIT 会卡住。看清效果后立刻 OPEN,不要挂在业务库上。PRIMARY/STANDBY 下 OPEN 要加 FORCE。单机 NORMAL 一般不用 FORCE。

ALTER DATABASE PRIMARY / STANDBY 会改角色。没有第二实例时不要改成 STANDBY 。

相关上机截图:
请添加图片描述

请添加图片描述
请添加图片描述


8. 和 KEEP 有关分裂窗口的机制

即时:源端已把包写入联机日志,MAL 尚未送到目标时源端宕机。目标少包。强制接管后旧源端再起,组分裂。

实时:KEEP 填的是目标多包、源端未落盘。升主前重演 KEEP;源端继续当主则丢 KEEP。

两种窗口都不是守护「重做日志」能凭空补出来的。分裂库看 dmwatcher.ctl,重建靠备份还原。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服