在 DM8 的备份恢复和数据守护中,经常会遇到两个参数:PERMANENT_MAGIC 和 DB_MAGIC。尤其是在执行数据库恢复时,我们通常会看到最后一步:
RECOVER DATABASE '/dmdata/DAMENG/dm.ini' UPDATE DB_MAGIC;
如果只把 MAGIC 理解成一个“随机编号”,这些操作很难真正理解。按照达梦官方文档,PERMANENT_MAGIC 和 DB_MAGIC 都是在初始化数据库时生成、用于标识数据库的整数值。其中 PERMANENT_MAGIC 生成后通常不会改变,只有 DDL_CLONE 等特殊场景例外;DB_MAGIC 则会在数据库经过还原、恢复之后发生变化,用于区分备份源库和还原目标库。官方还明确将数据库恢复划分为“恢复一致性”和“更新 DB_MAGIC”两个步骤。
理解 MAGIC,可以先从 PERMANENT_MAGIC 开始。达梦官方数据守护文档明确指出,每个数据库都有永久魔数,主库进行日志传输时会判断该值是否一致,以确认数据库来自同一个数据守护环境;如果永久魔数不一致,日志无法正常传输。因此,数据守护搭建前必须通过备份还原方式同步数据,官方明确不允许通过“分别初始化两个数据库”的方式直接组成数据守护。
这个设计可以借用 DDIA 的思想来理解。分布式系统中,一个节点“在哪里”和它“是谁”并不是同一件事。IP 地址、主机名、端口甚至实例名都可以被重新使用。比如一台服务器重新安装后,仍然可以使用原来的 IP 和实例名,但服务器上的数据库实际上已经重新初始化。如果只依赖这些外部属性,就无法可靠判断两个数据库之间是否存在共同的数据来源。
因此,可以把 PERMANENT_MAGIC 理解为数据库的一种来源身份:
PERMANENT_MAGIC ——> 这些数据库是否来源于同一个数据库体系?
这里为了便于理解,可以借用 lineage,也就是“数据血统”这个概念。需要强调的是,lineage 是本文用于解释设计思想的概念,并不是达梦官方对 PERMANENT_MAGIC 的正式命名。
如果主库的备份被用于恢复一个备库,恢复后的数据库继承了原数据库的永久 MAGIC,因此二者可以被识别为来自同一个数据守护体系。反过来,如果两边分别运行 dminit,就会生成各自的永久 MAGIC。即使两边的表结构、用户名甚至业务数据看起来完全相同,从数据库内部身份来看,它们仍然不是同一个来源。
从 DDIA 的角度,可以把这个关系概括成一句话:
Identity 不应该依赖 Location。
数据库运行在哪里,与数据库本身的身份是两个不同的问题。
有了 PERMANENT_MAGIC,为什么还需要一个 DB_MAGIC?
这是 MAGIC 设计中最关键的问题。
假设有一个数据库 A,我们在某个时间点对它进行了备份。备份完成之后,数据库 A 继续运行,持续产生新的事务和 REDO。随后,我们使用之前的备份恢复出了数据库 B。
此时 A 和 B 显然存在共同来源,因为 B 的数据来自 A 的备份。但从恢复完成的那一刻开始,它们已经成为两个可以独立运行的数据库。
也就是说:
同一个源数据库
│
BACKUP
│
┌───────┴───────┐
│ │
▼ ▼
原数据库 A 恢复数据库 B
如果系统只有 PERMANENT_MAGIC,那么它只能表达:A 和 B 来自同一个数据库来源,却无法进一步表达:A 和 B 已经是两个不同的数据库,所以还需要引入 DB_MAGIC 。
达梦官方文档明确说明,DB_MAGIC 同样可以用于标识某一个数据库,但与永久 MAGIC 不同,它可以发生变化;数据库每经过一次还原、恢复后,DB_MAGIC 会发生变化,以此区分备份源库与还原目标库。
如果借用分布式系统里的概念,可以把它理解成一种 Database Incarnation Identity,即数据库某一次具体存在形态的身份:
PERMANENT_MAGIC ——> 我们是不是来自同一个数据库来源?
DB_MAGIC ——> 即使来源相同,我具体是哪一个数据库?
这里的 Incarnation 同样是用于帮助理解的分析概念,而不是达梦官方术语。
因此,当 PERMANENT_MAGIC 相同而 DB_MAGIC 不同时表达的是
来自同一个数据库来源,但现在是两个不同的数据库。
这也解释了为什么 DM 需要两个 MAGIC,而不是只设计一个数据库 ID。
理解了前面的身份模型,UPDATE DB_MAGIC 就很好解释了。
达梦官方将数据库恢复明确划分为两个阶段:
其中,第一步主要通过重做 REDO 等方式,使目标数据库达到一个一致的数据状态;第二步则更新目标数据库的 DB_MAGIC,并将数据库调整为可正常工作的状态。官方同时说明,数据库还原之后,更新 DB_MAGIC 是数据库级还原需要执行的步骤,而表空间等其他类型的还原不需要执行。
典型流程就是:
RESTORE DATABASE
│
▼
恢复数据文件
│
▼
RECOVER DATABASE
│
▼
利用 REDO 恢复一致性
│
▼
RECOVER DATABASE UPDATE DB_MAGIC
│
▼
生成新的数据库身份
这里可以看出两个完全不同的问题。
因此,从 DDIA 的视角,可以把这两个阶段分别理解为:
所以 UPDATE DB_MAGIC 不是简单地“为了让数据库能启动随便改一个数字”,它有非常明确的身份区分作用。
MAGIC 不仅存在于数据库自身,也进入了 DM 的日志体系。
达梦官方的 V$ARCH_FILE 动态视图中,可以看到:DB_MAGIC,PMNT_MAGIC,SRC_DB_MAGIC
| 参数 | 含义 |
|---|---|
| DB_MAGIC | 写入日志的数据库 MAGIC |
| PMNT_MAGIC | 数据库永久 MAGIC |
| SRC_DB_MAGIC | 产生日志的源数据库 MAGIC |
同时,视图中还记录 ARCH_LSN、CLSN、PREV_LSN 等日志位置信息。
数据守护文档进一步说明:DB_MAGIC 在数据库初始化时生成,数据库还原后会重新生成新的 DB_MAGIC;数据守护中的主备数据库具有不同的 DB_MAGIC。对于归档日志,主库归档中的 SRC_DB_MAGIC 与自身 DB_MAGIC 相同;备库生成的归档中,SRC_DB_MAGIC 则记录产生 REDO 的源数据库,也就是主库的 DB_MAGIC。
这说明 DM 在记录一份日志时,可以提供以下信息:
这时候,用 DDIA 的方法重新拆解就会非常清晰:
| 参数 | 含义 |
|---|---|
| PERMANENT_MAGIC | 数据库来源关系 |
| DB_MAGIC | 具体数据库身份 |
| SRC_DB_MAGIC | REDO 来源身份 |
| LSN | 日志历史中的位置 |
换句话说,MAGIC 和 LSN 解决的不是同一个问题。
MAGIC 更接近回答:Who?这是谁的数据、谁的日志?
而 LSN 更接近回答:Where in history?这份日志处在数据历史的什么位置?
因此,仅仅看到两个数据库的 LSN 一样,并不能从逻辑上把“LSN 相等”直接等价成“两个数据库身份相同”。身份与日志位置本来就是不同维度。
如果把达梦官方明确描述的这些机制放在一起,再借用 DDIA 的分布式系统思维,可以得到一个比较清晰的模型:
DM Database
│
┌───────────────┼───────────────┐
│ │ │
▼ ▼ ▼
来源关系 数据库身份 日志历史
│ │ │
▼ ▼ ▼
PERMANENT_MAGIC DB_MAGIC LSN / REDO
如果进一步放到数据守护系统中,还需要加上:
PRIMARY / STANDBY
Watcher
Monitor
故障切换
这一层解决的是另外一个问题:
谁当前应该承担 PRIMARY 角色?
达梦官方文档明确说明,数据守护依靠主备 Redo 传输与重演保持同步,守护进程负责监控数据库运行状态和同步状态,监视器用于监控系统、执行命令以及实现自动切换等功能。
所以不能把 DB_MAGIC 理解成“谁的值大谁就是主库”,也不能把它简单等同于 Raft 的 Term、Leader Epoch 或严格意义上的 fencing token。达梦官方对 DB_MAGIC 给出的核心语义,是标识数据库,并区分备份源库和还原目标库;主备切换和故障处理属于数据守护的另一套机制。
如果用四句话概括,就是:
PERMANENT_MAGIC
↓
我们是不是来自同一个数据库来源?
DB_MAGIC
↓
在共同来源下,我具体是哪一个数据库?
LSN / REDO
↓
我的数据历史推进到了什么位置?
PRIMARY / STANDBY / Data Watch
↓
当前数据库承担什么角色?
这几个维度有关联,但不能互相替代。
第一次看到 PERMANENT_MAGIC 和 DB_MAGIC,很容易觉得 DM 只是给数据库保存了两个不同的编号。
但从备份恢复和数据守护的完整流程来看,它实际上解决的是两个不同层次的身份问题。
PERMANENT_MAGIC 保留下来的,是数据库之间的来源关系。数据守护在日志传输过程中会检查永久 MAGIC,以确认数据库属于同一个数据守护环境。
DB_MAGIC 解决的则是另一个问题:即使两个数据库来自同一个来源,在经过备份、还原和恢复以后,它们也需要成为可以相互区分的数据库。于是恢复流程最终通过:
RECOVER DATABASE '<dm.ini>' UPDATE DB_MAGIC;
更新目标数据库的 MAGIC。
所以,如果借用 DDIA 的方法,而不是把这些概念机械地对应,可以把 DM 的 MAGIC 设计理解成:
PERMANENT_MAGIC → 来源 / Lineage
DB_MAGIC → 身份 / Incarnation
LSN + REDO → 历史 / Ordering
其中前两个概念是对 DM 官方机制的抽象解释,Lineage 和 Incarnation 并不是达梦官方术语。
最终可以用一句话概括:
PERMANENT_MAGIC 用来判断数据库是不是“同源”,DB_MAGIC 用来判断同源数据库中“具体是谁”。数据可以从备份中继承,但恢复出来的数据库必须拥有能够区分自己的身份。
理解这一点之后,再去看 DM 为什么要求通过备份还原搭建数据守护、为什么恢复最后必须执行 UPDATE DB_MAGIC、为什么归档日志还要保存 DB_MAGIC 和 SRC_DB_MAGIC,这些看起来零散的机制实际上都指向了同一个核心问题——数据库身份必须能够被可靠地识别。
文章
阅读量
获赞
