备份与恢复 #
一、备份概述 #
1.1 备份策略 #
text
FaunaDB备份方式:
├── 导出/导入
│ └── 数据导出为JSON
├── 时间旅行
│ └── 利用历史数据恢复
├── 副本数据库
│ └── 创建数据库副本
└── 外部备份
└── 导出到外部存储
1.2 备份考虑 #
text
备份规划:
├── 备份频率
├── 保留周期
├── 存储位置
├── 恢复时间目标(RTO)
└── 恢复点目标(RPO)
二、数据导出 #
2.1 使用CLI导出 #
bash
# 导出整个数据库
fauna export my_database --output=./backup
# 导出特定集合
fauna export my_database --collections=users,products --output=./backup
# 导出为JSON格式
fauna export my_database --format=json --output=./backup
2.2 使用FQL导出 #
javascript
// 导出集合数据
Map(
Paginate(Documents(Collection("users")), { size: 10000 }),
Lambda("ref", Get(Var("ref")))
)
// 导出特定字段
Map(
Paginate(Documents(Collection("users"))),
Lambda("ref",
Let(
{ doc: Get(Var("ref")) },
{
id: Select(["ref", "id"], Var("doc")),
name: Select(["data", "name"], Var("doc")),
email: Select(["data", "email"], Var("doc"))
}
)
)
)
2.3 导出脚本 #
javascript
// 分页导出大数据量
CreateFunction({
name: "export_collection",
role: Role("admin"),
body: Query(
Lambda(["collectionName", "pageSize"],
Let(
{
pages: Query(
Lambda("cursor",
Let(
{
page: If(
Equals(Var("cursor"), null),
Paginate(
Documents(Collection(Var("collectionName"))),
{ size: Var("pageSize") }
),
Paginate(
Documents(Collection(Var("collectionName"))),
{
size: Var("pageSize"),
after: Var("cursor")
}
)
)
},
{
data: Map(
Select(["data"], Var("page")),
Lambda("ref", Get(Var("ref")))
),
nextCursor: If(
ContainsPath(Var("page"), ["after"]),
Select(["after"], Var("page")),
false
)
}
)
)
)
},
Var("pages")
)
)
)
})
三、数据导入 #
3.1 使用CLI导入 #
bash
# 导入数据
fauna import my_database --file=./backup/users.json
# 导入到特定集合
fauna import my_database --collection=users --file=./backup/users.json
# 更新模式(更新已存在的文档)
fauna import my_database --file=./backup/users.json --mode=update
3.2 使用FQL导入 #
javascript
// 批量导入
Foreach(
[
{ name: "User 1", email: "user1@example.com" },
{ name: "User 2", email: "user2@example.com" },
{ name: "User 3", email: "user3@example.com" }
],
Lambda("userData",
Create(Collection("users"), {
data: Var("userData")
})
)
)
3.3 导入函数 #
javascript
// 创建导入函数
CreateFunction({
name: "import_data",
role: Role("admin"),
body: Query(
Lambda(["collectionName", "data"],
Foreach(
Var("data"),
Lambda("item",
Create(Collection(Var("collectionName")), {
data: Var("item")
})
)
)
)
)
})
// 调用导入
Call(Function("import_data"), ["users", [
{ name: "User 1", email: "user1@example.com" },
{ name: "User 2", email: "user2@example.com" }
]])
四、数据库复制 #
4.1 创建副本数据库 #
javascript
// 创建备份数据库
CreateDatabase({
name: "my_database_backup"
})
// 复制数据
Let(
{
sourceCollection: Collection("users"),
targetCollection: Collection("users", Database("my_database_backup"))
},
Foreach(
Paginate(Documents(Var("sourceCollection"))),
Lambda("ref",
Let(
{ doc: Get(Var("ref")) },
Create(Var("targetCollection"), {
data: Select(["data"], Var("doc"))
})
)
)
)
)
4.2 增量同步 #
javascript
// 增量同步函数
CreateFunction({
name: "sync_collection",
role: Role("admin"),
body: Query(
Lambda(["sourceDb", "targetDb", "collectionName", "lastSyncTime"],
Let(
{
sourceColl: Collection(Var("collectionName"), Database(Var("sourceDb"))),
targetColl: Collection(Var("collectionName"), Database(Var("targetDb"))),
// 获取变更的文档
changedDocs: Filter(
Paginate(Documents(Var("sourceColl"))),
Lambda("ref",
GT(
Select(["ts"], Get(Var("ref"))),
Var("lastSyncTime")
)
)
)
},
Foreach(
Var("changedDocs"),
Lambda("ref",
Let(
{
doc: Get(Var("ref")),
docId: Select(["ref", "id"], Var("doc")),
targetRef: Ref(Var("targetColl"), Var("docId"))
},
If(
Exists(Var("targetRef")),
Update(Var("targetRef"), {
data: Select(["data"], Var("doc"))
}),
Create(Var("targetRef"), {
data: Select(["data"], Var("doc"))
})
)
)
)
)
)
)
)
})
五、时间旅行恢复 #
5.1 恢复到历史时间点 #
javascript
// 恢复单个文档
Let(
{
ref: Ref(Collection("users"), "user_001"),
targetTime: Time("2024-01-15T00:00:00Z"),
historicalDoc: Get(Var("ref"), Var("targetTime"))
},
Update(Var("ref"), {
data: Select(["data"], Var("historicalDoc"))
})
)
5.2 批量历史恢复 #
javascript
// 批量恢复
Let(
{
targetTime: Time("2024-01-01T00:00:00Z"),
refs: Paginate(Documents(Collection("products")))
},
Foreach(
Var("refs"),
Lambda("ref",
Let(
{
historicalDoc: Get(Var("ref"), Var("targetTime"))
},
Update(Var("ref"), {
data: Select(["data"], Var("historicalDoc"))
})
)
)
)
)
六、灾难恢复 #
6.1 恢复流程 #
text
灾难恢复步骤:
├── 1. 评估损失范围
├── 2. 确定恢复时间点
├── 3. 创建临时数据库
├── 4. 导入备份数据
├── 5. 验证数据完整性
├── 6. 切换应用连接
└── 7. 监控恢复状态
6.2 恢复脚本 #
javascript
// 完整恢复函数
CreateFunction({
name: "disaster_recovery",
role: Role("admin"),
body: Query(
Lambda(["targetDb", "backupData", "collections"],
Let(
{
db: Database(Var("targetDb")),
result: Map(
Var("collections"),
Lambda("collName",
Let(
{
coll: Collection(Var("collName"), Var("db")),
data: Select(Var("collName"), Var("backupData"))
},
{
collection: Var("collName"),
imported: Count(
Foreach(
Var("data"),
Lambda("item",
Create(Var("coll"), { data: Var("item") })
)
)
)
}
)
)
)
},
{
status: "completed",
timestamp: Now(),
details: Var("result")
}
)
)
)
})
七、备份自动化 #
7.1 定时备份 #
javascript
// 创建备份记录
CreateFunction({
name: "create_backup_record",
role: Role("admin"),
body: Query(
Lambda(["type", "collections", "status"],
Create(Collection("backup_records"), {
data: {
type: Var("type"),
collections: Var("collections"),
status: Var("status"),
timestamp: Now(),
size: 0,
location: ""
}
})
)
)
})
7.2 备份验证 #
javascript
// 验证备份完整性
CreateFunction({
name: "verify_backup",
role: Role("admin"),
body: Query(
Lambda("backupId",
Let(
{
backup: Get(Ref(Collection("backup_records"), Var("backupId"))),
collections: Select(["data", "collections"], Var("backup")),
verification: Map(
Var("collections"),
Lambda("collName",
Let(
{
sourceCount: Count(Documents(Collection(Var("collName")))),
// 假设备份存储了计数
backupCount: Select(
["data", "counts", Var("collName")],
Var("backup"),
0
)
},
{
collection: Var("collName"),
source: Var("sourceCount"),
backup: Var("backupCount"),
valid: Equals(Var("sourceCount"), Var("backupCount"))
}
)
)
)
},
{
backupId: Var("backupId"),
timestamp: Now(),
results: Var("verification"),
allValid: All(
Map(Var("verification"), Lambda("v", Select("valid", Var("v"))))
)
}
)
)
)
})
八、最佳实践 #
8.1 备份策略 #
text
备份策略建议:
├── 定期备份(每日/每周)
├── 多重备份(本地+远程)
├── 版本化备份
├── 加密敏感数据
└── 测试恢复流程
8.2 备份保留 #
text
保留策略:
├── 每日备份:保留7天
├── 每周备份:保留4周
├── 每月备份:保留12个月
└── 年度备份:长期保留
8.3 安全考虑 #
text
安全建议:
├── 加密备份数据
├── 限制备份访问权限
├── 安全存储备份凭证
├── 审计备份操作
└── 定期更新加密密钥
九、实际应用示例 #
9.1 完整备份系统 #
javascript
// 创建完整备份系统
CreateFunction({
name: "full_backup",
role: Role("admin"),
body: Query(
Lambda("databaseName",
Let(
{
db: Database(Var("databaseName")),
collections: Select(
["data"],
Paginate(Collections(), { size: 100 })
),
timestamp: Now(),
backup: Map(
Var("collections"),
Lambda("collRef",
Let(
{
collName: Select(["id"], Var("collRef")),
docs: Map(
Paginate(
Documents(Var("collRef")),
{ size: 10000 }
),
Lambda("ref", Get(Var("ref")))
)
},
{
collection: Var("collName"),
count: Count(Var("docs")),
data: Var("docs")
}
)
)
),
// 创建备份记录
record: Create(Collection("backup_records"), {
data: {
database: Var("databaseName"),
timestamp: Var("timestamp"),
type: "full",
status: "completed",
collections: Map(
Var("backup"),
Lambda("b", Select("collection", Var("b")))
),
counts: Map(
Var("backup"),
Lambda("b",
{
collection: Select("collection", Var("b")),
count: Select("count", Var("b"))
}
)
)
}
})
},
{
backupId: Select(["ref", "id"], Var("record")),
timestamp: Var("timestamp"),
summary: Map(
Var("backup"),
Lambda("b",
{
collection: Select("collection", Var("b")),
documents: Select("count", Var("b"))
}
)
)
}
)
)
)
})
十、总结 #
备份与恢复要点:
| 方法 | 说明 |
|---|---|
| CLI导出 | 使用fauna命令行 |
| FQL导出 | 使用查询导出 |
| 数据库复制 | 创建副本数据库 |
| 时间旅行 | 利用历史数据 |
| 自动化 | 定时备份脚本 |
下一步,让我们学习性能优化!
最后更新:2026-03-27