# 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