gongxiangp2/docs/migration-guide.md

275 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# S3素材无感迁移指南
## 📋 概述
本迁移方案用于将老素材的S3文件迁移到新位置(统一使用路径前缀),实现存储路径的统一管理。
**核心原则**:
- ✅ 所有素材、人员信息、元数据都不能动
- ✅ 无感迁移,用户无感知
- ✅ 支持断点续传和错误重试
- ✅ 迁移后验证所有功能正常
## 🔍 迁移范围
### 需要迁移的S3字段
| 字段 | 说明 | 示例 |
|------|------|------|
| `previewUrl` | 预览图URL | `https://s3.1080p.hk/jsxiangche/preview-xxx.webp` |
| `zipFileName` | 音频/视频源文件URL | `https://s3.1080p.hk/jsxiangche/audio-xxx.mp3` |
| `displayImages` | 详情图数组 | `["https://s3.1080p.hk/jsxiangche/img1.jpg", ...]` |
| `videoSourceUrl` | 视频源文件URL | `https://s3.1080p.hk/jsxiangche/video-xxx.mp4` |
| `videoPreview540Url` | 540P预览视频URL | `https://s3.1080p.hk/jsxiangche/preview-540p.mp4` |
| `videoPreviewClipUrl` | 视频片段URL | `https://s3.1080p.hk/jsxiangche/clip-xxx.mp4` |
| `videoCoverUrl` | 视频封面URL | `https://s3.1080p.hk/jsxiangche/cover-xxx.jpg` |
### 不需要迁移的内容
- ✅ **本地源文件**(`./uploads` 目录)- 不需要迁移
- 压缩包文件:存储在 `./uploads` 目录(`zipFilePath` 字段)
- 新老素材都使用同一目录,无需迁移
- ✅ **外网服务器源文件**(103.118.245.6)- 不需要迁移
- 部分老素材的源文件存储在外网服务器(通过FRP穿透访问)
- `zipFilePath` 字段可能包含 `103.118.245.6` 或 `http://` 开头的URL
- 这些文件保持原样,不进行迁移
- ✅ **数据库中的其他字段**(人员信息、元数据等)- 保持不变
- ✅ **已使用新路径的素材** - 跳过
### 📌 重要说明:源文件存储位置
系统中的源文件(压缩包/视频)存储在不同位置:
| 存储位置 | 说明 | 字段 | 是否需要迁移 |
|---------|------|------|-------------|
| **本地文件系统** | `./uploads` 目录(Docker挂载) | `zipFilePath` | ❌ 不需要 |
| **外网服务器** | 103.118.245.6(老素材,通过FRP访问) | `zipFilePath` | ❌ 不需要 |
| **S3存储** | 音频/视频源文件(S3 URL) | `zipFileName` | ✅ **需要迁移** |
**注意**:
- `zipFileName` 字段可能是:
- 本地文件名(如 `material-xxx.zip`)- 不需要迁移
- S3 URL(如 `https://s3.1080p.hk/jsxiangche/audio-xxx.mp3`)- **需要迁移**
- 迁移脚本会自动识别 `zipFileName` 是否为S3 URL,只迁移S3中的文件
### 🔗 FRP穿透说明
系统中存在**多个FRP穿透**,用于不同的服务:
| 穿透类型 | 用途 | 外网地址 | FRP服务器 | 本地服务 | 说明 |
|---------|------|---------|----------|---------|------|
| **S3存储穿透1** | MinIO S3服务(老) | `s3.1080p.hk` (156.233.232.106) | 180.97.221.140 | 192.168.58.20:9000/9001 | 用于老S3预览图、视频转码文件等 |
| **S3存储穿透2** | MinIO S3服务(新) | `s3.yydd.ai` (103.118.245.6) | 未知(同源文件穿透) | 未知 | 用于新S3预览图、视频转码文件等 |
| **源文件穿透** | 老素材源文件 | `103.118.245.6` | 未知 | 外网服务器目录 | 用于老素材的压缩包/视频文件下载 |
**重要发现**(2025-12-22测试):
- ✅ **`s3.yydd.ai` 也使用FRP穿透**:DNS解析到 `103.118.245.6`,访问该IP返回 `"The server is powered by frp"`
- ✅ **`s3.yydd.ai` 和源文件穿透使用同一个FRP服务器**:都是 `103.118.245.6`
- ⚠️ **两个S3域名都有穿透问题**:`s3.1080p.hk` 和 `s3.yydd.ai` 都通过FRP穿透,都会受到带宽限制
**重要说明**:
- **S3存储穿透**:所有S3中的文件(预览图、视频转码文件、音频/视频源文件)都通过FRP穿透访问
- **源文件穿透**:仅用于部分老素材的源文件下载,新素材源文件存储在本地,不需要穿透
- **性能影响**:由于都使用FRP穿透,大文件加载会较慢(首字节时间可能>10秒)
- 迁移脚本只处理S3存储中的文件,不涉及源文件穿透
## 🎯 迁移目标
**老素材URL格式**:
```
https://s3.1080p.hk/jsxiangche/preview-xxx.webp
```
**新素材URL格式**(迁移后):
```
https://s3.1080p.hk/jsxiangche/由壹点AI/preview-xxx.webp
```
## 📝 迁移前准备
### 1. 备份数据库
```bash
# 使用 pg_dump 备份
pg_dump -h localhost -U postgres -d lobechat > backup_$(date +%Y%m%d_%H%M%S).sql
```
### 2. 检查环境变量
确保 `.env.local` 文件包含以下变量:
```bash
S3_ENDPOINT=https://s3.yydd.ai
S3_BUCKET=gongxiangpan
S3_ACCESS_KEY_ID=your_access_key
S3_SECRET_ACCESS_KEY=your_secret_key
S3_PUBLIC_DOMAIN=https://s3.yydd.ai/gongxiangpan
S3_FILE_PATH=由壹点AI/
DATABASE_URL=postgresql://user:password@localhost:5432/lobechat
```
### 3. 安装依赖
```bash
npm install
npx prisma generate
```
## 🚀 执行迁移
### 方式一:使用PowerShell脚本(推荐)
```powershell
# 干运行模式(只检查,不实际迁移)
.\scripts\run-migration.ps1 -DryRun
# 执行迁移
.\scripts\run-migration.ps1
```
### 方式二:直接运行TypeScript脚本
```bash
# 需要先安装 tsx
npm install -g tsx
# 执行迁移
npx tsx scripts/migrate-s3-materials.ts
```
## 📊 迁移过程
### 1. 查询需要迁移的素材
脚本会自动查询所有包含老S3 URL的素材:
- 只迁移未删除的素材(`deletedAt IS NULL`)
- 自动识别需要迁移的字段
### 2. 迁移文件
对于每个需要迁移的文件:
1. 从老位置下载文件
2. 上传到新位置(带路径前缀)
3. 验证新文件可访问
4. 更新数据库中的URL
### 3. 断点续传
- 如果新文件已存在,自动跳过(支持断点续传)
- 每10个素材保存一次日志(防止中断丢失)
### 4. 错误处理
- 自动重试(最多10次)
- 记录失败详情到日志文件
- 失败的文件不影响其他文件的迁移
## 📁 迁移日志
迁移日志保存在 `logs/migration/` 目录,文件名格式:
```
migration-{timestamp}.json
```
日志格式:
```json
[
{
"materialId": "uuid",
"field": "previewUrl",
"oldUrl": "https://s3.1080p.hk/jsxiangche/preview-xxx.webp",
"newUrl": "https://s3.1080p.hk/jsxiangche/由壹点AI/preview-xxx.webp",
"status": "success",
"timestamp": "2025-01-20T10:00:00.000Z"
}
]
```
## ✅ 迁移后验证
### 1. 检查迁移统计
迁移完成后会显示统计信息:
- 总计:需要迁移的文件数
- 成功:成功迁移的文件数
- 跳过:已存在的文件数
- 失败:迁移失败的文件数
### 2. 验证素材显示
随机抽查几个素材:
- 预览图是否正常显示
- 详情图是否正常显示
- 视频预览是否正常播放
- 音频文件是否正常播放
### 3. 验证下载功能
测试几个素材的下载功能:
- 压缩包下载是否正常
- 视频文件下载是否正常
- 音频文件下载是否正常
### 4. 检查数据库
```sql
-- 检查是否还有老URL
SELECT COUNT(*) FROM materials
WHERE deletedAt IS NULL
AND (
previewUrl LIKE '%s3.1080p.hk/jsxiangche/%'
AND previewUrl NOT LIKE '%由壹点AI/%'
);
```
## 🔄 回滚方案
如果迁移后发现问题,可以回滚:
### 1. 恢复数据库备份
```bash
psql -h localhost -U postgres -d lobechat < backup_20250120_100000.sql
```
### 2. 删除新位置的文件(可选)
如果需要清理新位置的文件,可以使用S3管理工具或API删除。
## ⚠️ 注意事项
1. **迁移时间**:建议在低峰期执行迁移,避免影响用户使用
2. **网络稳定性**:确保网络连接稳定,避免迁移中断
3. **存储空间**:确保S3有足够的存储空间(迁移会临时占用双倍空间)
4. **监控**:迁移过程中监控系统资源使用情况
5. **验证**:迁移后务必验证所有功能正常
## 🐛 常见问题
### Q: 迁移失败怎么办?
A: 检查日志文件,找到失败的原因。常见原因:
- 网络连接问题
- S3权限问题
- 文件不存在
### Q: 可以分批迁移吗?
A: 可以。脚本支持断点续传,可以随时中断和恢复。
### Q: 迁移会影响系统使用吗?
A: 不会。迁移过程中系统可正常使用(只读模式),迁移是后台进行的。
### Q: 迁移后老文件会删除吗?
A: 不会。迁移脚本只复制文件到新位置,不删除老文件。如果需要清理,可以手动删除。
## 📞 技术支持
如有问题,请:
1. 查看迁移日志文件
2. 检查错误信息
3. 联系技术支持