# Redis config repl-stream-db

{% hint style="info" %}
背景:

同步数据的时候，源节点是主库时，则增量的第一条数据是 select 命令。

当源节点使用的从库，发现同步完 RDB 之后，第一条增量的数据并没有 select db，故而会默认写到到 db0，其实增量的数据应该写到 db3 的，这个是否发现应该读取 rdb 中的 `repl-stream-db` 信息，使用此 db 作为第一条增量同步的命令。
{% endhint %}

在 Redis 的持久化与复制机制中，`repl-stream-db` 是 **RDB 文件头部的元数据字段之一**，用于记录持久化时主节点正在使用的数据库编号（即当前选中的 DB）。其核心作用是为复制过程提供上下文信息，确保从节点能正确加载数据并同步到对应数据库。以下是详细说明：

## 1 字段来源与存储位置

* **RDB 文件结构**：Redis 的 RDB 持久化文件由文件头和实际数据组成。文件头包含元数据（如 Redis 版本、复制信息等），而 `repl-stream-db` 是文件头中的关键字段之一。
* **存储内容**：该字段记录主节点在生成 RDB 文件时使用的数据库编号（如 `DB 0`、`DB 1` 等），从节点通过解析此字段可确定数据应加载到哪个数据库。

## 2 核心作用

* **复制同步的上下文保障**：
  * 在主从复制中，主节点生成 RDB 文件后，会将文件传输给从节点。从节点需知道数据应加载到哪个数据库，而 `repl-stream-db` 提供了这一信息，避免从节点错误地将数据写入默认数据库（如 `DB 0`）。
  * 例如，若主节点在生成 RDB 时使用的是 `DB 1`，从节点会通过此字段将数据加载到 `DB 1`，确保主从数据一致性。
* **支持增量复制的元数据**：
  * 当 Redis 配置了 `appendonly yes`（启用 AOF）且 AOF 文件包含 RDB 前导（即混合持久化模式）时，`repl-stream-db` 会出现在 AOF 文件的 RDB 前导部分，为后续的增量复制提供数据库上下文。

## 3 场景

{% hint style="info" %}
[ https://github.com/tair-opensource/RedisShake/pull/430#issuecomment-1099014464](https://github.com/tair-opensource/RedisShake/pull/430#issuecomment-1099014464)
{% endhint %}

DTS 同步数据场景，如 redis-shake 同步数据时，解析 RDB 时，返回下 repl-stream-db

> （RedisShake-4）internal/rdb/rdb.go

```
// ParseRDB parse rdb file
// return repl stream db id
func (ld *Loader) ParseRDB(ctx context.Context) int {
	var err error
	ld.fp, err = os.OpenFile(ld.filPath, os.O_RDONLY, 0666)
	if err != nil {
		log.Panicf("open file failed. file_path=[%s], error=[%s]", ld.filPath, err)
	}
	defer func() {
		err = ld.fp.Close()
		if err != nil {
			log.Panicf("close file failed. file_path=[%s], error=[%s]", ld.filPath, err)
		}
	}()
	rd := bufio.NewReader(ld.fp)
	// magic + version
	buf := make([]byte, 9)
	_, err = io.ReadFull(rd, buf)
	if err != nil {
		log.Panicf(err.Error())
	}
	if !bytes.Equal(buf[:5], []byte("REDIS")) {
		log.Panicf("verify magic string, invalid file format. bytes=[%v]", buf[:5])
	}
	version, err := strconv.Atoi(string(buf[5:]))
	if err != nil {
		log.Panicf(err.Error())
	}
	log.Debugf("[%s] RDB version: %d", ld.name, version)

	// read entries
	ld.parseRDBEntry(ctx, rd)

	return ld.replStreamDbId
}
```
