# 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. 联系技术支持