Files
labweb/supabase-stack/docs/STORAGE_TROUBLESHOOTING.md
zly 1f7a2ed1e4 feat: 迁移 Storage 后端从 MinIO 到文件系统
## 主要变更

### 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 功能正常)
2025-12-05 19:44:11 +08:00

284 lines
5.8 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.
# 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