## 主要变更
### 1. Storage 配置修改
- 修改 docker-compose.yml: STORAGE_BACKEND 从 s3 改为 file
- 注释所有 GLOBAL_S3_* 环境变量
- 启用 FILE_STORAGE_BACKEND_PATH=/var/lib/storage
- 停止使用 MinIO 容器(docker-compose.s3.yml)
### 2. 文档更新
- 新增 docs/STORAGE_FILE_BACKEND_MIGRATION.md - 迁移详细文档
- 新增 docs/STORAGE_TROUBLESHOOTING.md - 故障排查指南
- 更新 README.md - 反映新的架构
### 3. 存储架构变更
- 从 MinIO S3 对象存储 -> 本地文件系统
- 存储路径: volumes/storage/undefined/stub/{bucket}/{file}/{version}
- 不再需要额外的 MinIO 容器
## 测试结果
- ✅ 上传文件 - 正常
- ✅ 下载文件 - 正常
- ✅ 删除文件 - 正常
- ✅ 签名 URL - 正常
- ⚠️ 更新文件 - 已知bug(使用删除+上传代替)
## 注意事项
- 旧的 S3 后端数据需要清理数据库元数据
- 文件更新操作有已知bug,需使用删除+重新上传
- 备份文件保存在 *.backup-before-rustfs
## 回滚方法
如需回滚到 MinIO:
```bash
cp docker-compose.yml.backup-before-rustfs docker-compose.yml
docker compose -f docker-compose.s3.yml up -d
docker compose restart storage
```
日期: 2025-12-05
状态: ✅ 测试通过 (4/5 功能正常)
284 lines
5.8 KiB
Markdown
284 lines
5.8 KiB
Markdown
# Storage 故障排查指南
|
||
|
||
## 常见问题
|
||
|
||
### 1. 下载文件返回 500 错误
|
||
|
||
**症状**:
|
||
```
|
||
GET /storage/v1/object/{bucket}/{file}
|
||
Status: 500 Internal Server Error
|
||
{"statusCode":"500","error":"Internal","message":"Internal Server Error"}
|
||
```
|
||
|
||
**原因**:
|
||
- 数据库中有对象元数据,但文件系统中没有实际文件
|
||
- 通常发生在后端切换后(S3 → 文件系统)
|
||
|
||
**解决方法**:
|
||
|
||
```bash
|
||
# 方法 1: 清理单个 bucket 的旧数据
|
||
docker exec supabase-db psql -U postgres -d postgres \
|
||
-c "DELETE FROM storage.objects WHERE bucket_id = 'your-bucket-name';"
|
||
|
||
# 方法 2: 查看所有对象
|
||
docker exec supabase-db psql -U postgres -d postgres \
|
||
-c "SELECT bucket_id, name, created_at FROM storage.objects ORDER BY created_at DESC LIMIT 20;"
|
||
|
||
# 方法 3: 清理所有对象(谨慎!)
|
||
docker exec supabase-db psql -U postgres -d postgres \
|
||
-c "TRUNCATE TABLE storage.objects CASCADE;"
|
||
```
|
||
|
||
重新上传文件后测试:
|
||
```bash
|
||
python3 examples/test_https_storage.py
|
||
```
|
||
|
||
### 2. 文件更新返回 500 错误
|
||
|
||
**症状**:
|
||
```
|
||
PUT /storage/v1/object/{bucket}/{file}
|
||
Status: 500
|
||
TypeError: paths[1] must be of type string
|
||
```
|
||
|
||
**原因**:
|
||
- 文件系统后端的已知 bug
|
||
- 更新文件时路径解析错误
|
||
|
||
**解决方法**:
|
||
|
||
使用 DELETE + POST 代替 PUT:
|
||
|
||
```python
|
||
import requests
|
||
|
||
headers = {'apikey': API_KEY, 'Authorization': f'Bearer {API_KEY}'}
|
||
|
||
# 1. 删除旧文件
|
||
requests.delete(
|
||
f'{BASE_URL}/storage/v1/object/bucket/file.txt',
|
||
headers=headers
|
||
)
|
||
|
||
# 2. 上传新文件
|
||
with open('file.txt', 'rb') as f:
|
||
requests.post(
|
||
f'{BASE_URL}/storage/v1/object/bucket/file.txt',
|
||
headers={**headers, 'Content-Type': 'text/plain'},
|
||
data=f
|
||
)
|
||
```
|
||
|
||
### 3. 文件路径包含 "undefined"
|
||
|
||
**症状**:
|
||
```
|
||
volumes/storage/undefined/stub/bucket/file.txt/version-id
|
||
```
|
||
|
||
**说明**:
|
||
- 这不是错误!
|
||
- "undefined" 是文件系统后端的固定目录结构
|
||
- 完全正常,可以忽略
|
||
|
||
### 4. 旧 S3 后端的文件无法访问
|
||
|
||
**症状**:
|
||
- 从 MinIO (S3) 迁移到文件系统后端
|
||
- 旧文件无法下载,返回 500 或 404
|
||
|
||
**原因**:
|
||
- 文件元数据格式不兼容
|
||
- 数据库记录的路径与实际存储不匹配
|
||
|
||
**解决方法**:
|
||
|
||
1. **清理旧数据** (推荐):
|
||
```bash
|
||
# 清理特定 bucket
|
||
docker exec supabase-db psql -U postgres -d postgres \
|
||
-c "DELETE FROM storage.objects WHERE bucket_id = 'old-bucket';"
|
||
```
|
||
|
||
2. **迁移数据到新 bucket**:
|
||
```python
|
||
# 1. 从 MinIO 下载所有文件(如果还在运行)
|
||
# 2. 清理数据库
|
||
# 3. 重新上传到文件系统后端
|
||
```
|
||
|
||
3. **保留 MinIO** (最简单):
|
||
```bash
|
||
# 回滚到 MinIO 后端
|
||
cp docker-compose.yml.backup-before-rustfs docker-compose.yml
|
||
docker compose -f docker-compose.s3.yml up -d
|
||
docker compose restart storage
|
||
```
|
||
|
||
### 5. Storage 服务启动失败
|
||
|
||
**检查日志**:
|
||
```bash
|
||
docker logs supabase-storage --tail 50
|
||
```
|
||
|
||
**常见问题**:
|
||
|
||
- 数据库连接失败
|
||
```bash
|
||
docker ps | grep supabase-db
|
||
docker logs supabase-db --tail 20
|
||
```
|
||
|
||
- 环境变量配置错误
|
||
```bash
|
||
docker exec supabase-storage env | grep STORAGE
|
||
```
|
||
|
||
- 卷挂载问题
|
||
```bash
|
||
ls -la volumes/storage/
|
||
chmod 777 volumes/storage/
|
||
```
|
||
|
||
## 诊断命令
|
||
|
||
### 检查 Storage 配置
|
||
|
||
```bash
|
||
# 查看后端类型
|
||
docker exec supabase-storage env | grep STORAGE_BACKEND
|
||
|
||
# 文件后端 -> STORAGE_BACKEND=file
|
||
# S3 后端 -> STORAGE_BACKEND=s3
|
||
```
|
||
|
||
### 检查数据库
|
||
|
||
```bash
|
||
# 列出所有 buckets
|
||
docker exec supabase-db psql -U postgres -d postgres \
|
||
-c "SELECT id, name, public, created_at FROM storage.buckets;"
|
||
|
||
# 列出所有对象
|
||
docker exec supabase-db psql -U postgres -d postgres \
|
||
-c "SELECT bucket_id, name, created_at FROM storage.objects LIMIT 10;"
|
||
|
||
# 统计对象数量
|
||
docker exec supabase-db psql -U postgres -d postgres \
|
||
-c "SELECT bucket_id, COUNT(*) FROM storage.objects GROUP BY bucket_id;"
|
||
```
|
||
|
||
### 检查文件系统
|
||
|
||
```bash
|
||
# 查看存储目录
|
||
ls -la volumes/storage/
|
||
|
||
# 查找所有文件
|
||
find volumes/storage/ -type f
|
||
|
||
# 检查文件大小
|
||
du -sh volumes/storage/*
|
||
```
|
||
|
||
## 最佳实践
|
||
|
||
### 1. 后端选择
|
||
|
||
**生产环境**:
|
||
- ✅ 使用 MinIO (S3) 后端
|
||
- 功能完整、稳定可靠
|
||
- 有管理界面
|
||
|
||
**开发/测试环境**:
|
||
- ✅ 可使用文件系统后端
|
||
- 简单、资源占用少
|
||
- 注意功能限制
|
||
|
||
### 2. 数据迁移
|
||
|
||
如需切换后端:
|
||
|
||
1. **备份数据库**
|
||
```bash
|
||
docker exec supabase-db pg_dump -U postgres postgres > backup.sql
|
||
```
|
||
|
||
2. **导出文件**(MinIO → 文件系统)
|
||
```bash
|
||
# 下载所有文件
|
||
# 清理数据库
|
||
# 重新上传
|
||
```
|
||
|
||
3. **测试验证**
|
||
```bash
|
||
python3 examples/test_https_storage.py
|
||
```
|
||
|
||
### 3. 日常维护
|
||
|
||
**定期检查**:
|
||
```bash
|
||
# 检查存储空间
|
||
df -h volumes/storage/
|
||
|
||
# 检查对象数量
|
||
docker exec supabase-db psql -U postgres -d postgres \
|
||
-c "SELECT COUNT(*) FROM storage.objects;"
|
||
|
||
# 检查服务健康
|
||
docker ps | grep storage
|
||
```
|
||
|
||
**清理无用数据**:
|
||
```bash
|
||
# 删除孤立的数据库记录(没有对应文件)
|
||
# 手动检查并清理
|
||
```
|
||
|
||
## 快速测试
|
||
|
||
### 完整功能测试
|
||
|
||
```bash
|
||
python3 examples/test_https_storage.py
|
||
```
|
||
|
||
### 单项测试
|
||
|
||
```bash
|
||
# 上传
|
||
curl -X POST "https://amiap.hzau.edu.cn/supa/storage/v1/object/test/file.txt" \
|
||
-H "apikey: YOUR_KEY" \
|
||
-H "Authorization: Bearer YOUR_KEY" \
|
||
-H "Content-Type: text/plain" \
|
||
-d "test content"
|
||
|
||
# 下载
|
||
curl "https://amiap.hzau.edu.cn/supa/storage/v1/object/test/file.txt" \
|
||
-H "apikey: YOUR_KEY" \
|
||
-H "Authorization: Bearer YOUR_KEY"
|
||
|
||
# 删除
|
||
curl -X DELETE "https://amiap.hzau.edu.cn/supa/storage/v1/object/test/file.txt" \
|
||
-H "apikey: YOUR_KEY" \
|
||
-H "Authorization: Bearer YOUR_KEY"
|
||
```
|
||
|
||
## 相关文档
|
||
|
||
- `STORAGE_FILE_BACKEND_MIGRATION.md` - 后端迁移指南
|
||
- `FINAL_ARCHITECTURE_MINIO_INTERNAL.md` - MinIO 架构
|
||
- `examples/test_https_storage.py` - 测试脚本
|
||
|
||
---
|
||
|
||
**最后更新**: 2025-12-05
|
||
**适用版本**: Supabase Storage API v1.29.0
|