Features - User Management (Phase 4.1): - Database: Add user_modules table for fine-grained module permissions - Database: Add 4 user permissions (view/create/edit/delete) to role_permissions - Backend: UserService (780 lines) - CRUD with tenant isolation - Backend: UserController + UserRoutes (648 lines) - 13 API endpoints - Backend: Batch import users from Excel - Frontend: UserListPage (412 lines) - list/filter/search/pagination - Frontend: UserFormPage (341 lines) - create/edit with module config - Frontend: UserDetailPage (393 lines) - details/tenant/module management - Frontend: 3 modal components (592 lines) - import/assign/configure - API: GET/POST/PUT/DELETE /api/admin/users/* endpoints Architecture Upgrade - Module Permission System: - Backend: Add getUserModules() method in auth.service - Backend: Login API returns modules array in user object - Frontend: AuthContext adds hasModule() method - Frontend: Navigation filters modules based on user.modules - Frontend: RouteGuard checks requiredModule instead of requiredVersion - Frontend: Remove deprecated version-based permission system - UX: Only show accessible modules in navigation (clean UI) - UX: Smart redirect after login (avoid 403 for regular users) Fixes: - Fix UTF-8 encoding corruption in ~100 docs files - Fix pageSize type conversion in userService (String to Number) - Fix authUser undefined error in TopNavigation - Fix login redirect logic with role-based access check - Update Git commit guidelines v1.2 with UTF-8 safety rules Database Changes: - CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled) - ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code) - INSERT 4 permissions + role assignments - UPDATE PUBLIC tenant with 8 module subscriptions Technical: - Backend: 5 new files (~2400 lines) - Frontend: 10 new files (~2500 lines) - Docs: 1 development record + 2 status updates + 1 guideline update - Total: ~4900 lines of code Status: User management 100% complete, module permission system operational
789 lines
17 KiB
Markdown
789 lines
17 KiB
Markdown
# 数据库连接配置
|
||
|
||
> **文档版本:** v1.0
|
||
> **创建日期:** 2025-11-09
|
||
> **维护者:** 架构团队
|
||
> **最后更新:** 2025-11-09
|
||
|
||
---
|
||
|
||
## 📋 文档说明
|
||
|
||
本文档记录Schema隔离架构实施相关的数据库连接和配置信息,包括:
|
||
- 当前数据库状态
|
||
- Schema隔离迁移配置
|
||
- 迁移过程的连接方式
|
||
- 验证和回滚方案
|
||
|
||
---
|
||
|
||
## 🗄️ 当前数据库状态
|
||
|
||
### 数据库基本信息
|
||
|
||
**连接信息:**
|
||
```
|
||
数据库类型:PostgreSQL 15+
|
||
数据库名称:ai_clinical_research
|
||
主机地址: localhost
|
||
端口: 5432
|
||
用户名: postgres
|
||
密码: postgres
|
||
```
|
||
|
||
**完整连接字符串:**
|
||
```
|
||
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research
|
||
```
|
||
|
||
---
|
||
|
||
### 当前Schema结构
|
||
|
||
**现有Schema:**
|
||
- ✅ **public** - 所有13个表都在这里
|
||
|
||
**表清单(13个):**
|
||
|
||
#### 1. 平台基础(2个表)
|
||
```sql
|
||
public.users -- 用户表
|
||
public.admin_logs -- 管理日志
|
||
```
|
||
|
||
#### 2. AI智能问答(5个表)
|
||
```sql
|
||
public.projects -- 项目管理
|
||
public.conversations -- 项目对话
|
||
public.messages -- 对话消息
|
||
public.general_conversations -- 通用对话
|
||
public.general_messages -- 通用消息
|
||
```
|
||
|
||
#### 3. 个人知识库(2个表)
|
||
```sql
|
||
public.knowledge_bases -- 知识库
|
||
public.documents -- 文档
|
||
```
|
||
|
||
#### 4. 批处理系统(3个表)
|
||
```sql
|
||
public.batch_tasks -- 批处理任务
|
||
public.batch_results -- 批处理结果
|
||
public.task_templates -- 任务模板
|
||
```
|
||
|
||
#### 5. 稿件审查(1个表)
|
||
```sql
|
||
public.review_tasks -- 审查任务
|
||
```
|
||
|
||
---
|
||
|
||
### 数据库统计信息
|
||
|
||
**表数量:** 13个
|
||
**索引数量:** 约40个
|
||
**外键约束:** 约15个
|
||
|
||
**当前数据量(估算):**
|
||
- users: ~10条
|
||
- projects: ~20条
|
||
- conversations: ~50条
|
||
- messages: ~500条
|
||
- knowledge_bases: ~5条
|
||
- documents: ~30条
|
||
- 其他表:测试数据
|
||
|
||
**总数据量:** < 10MB(测试环境)
|
||
|
||
---
|
||
|
||
## 🎯 Schema隔离目标架构
|
||
|
||
### 10个独立Schema
|
||
|
||
#### 需要详细设计+数据迁移(5个)
|
||
|
||
**1. platform_schema(平台基础层)**
|
||
```sql
|
||
-- 迁移表:
|
||
public.users → platform_schema.users
|
||
public.admin_logs → platform_schema.admin_logs (暂缓,待确认)
|
||
```
|
||
|
||
**2. common_schema(通用能力层)**
|
||
```sql
|
||
-- 新建表:
|
||
common_schema.llm_usage -- LLM使用记录
|
||
common_schema.feature_flags -- Feature Flags
|
||
```
|
||
|
||
**3. asl_schema(AI智能文献)**
|
||
```sql
|
||
-- 新建表:
|
||
asl_schema.literature_projects -- 文献项目
|
||
asl_schema.pico_configs -- PICO配置
|
||
asl_schema.literature_items -- 文献条目
|
||
-- 更多表见ASL设计文档
|
||
```
|
||
|
||
**4. aia_schema(AI智能问答)**
|
||
```sql
|
||
-- 迁移表:
|
||
public.projects → aia_schema.projects
|
||
public.conversations → aia_schema.conversations
|
||
public.messages → aia_schema.messages
|
||
public.general_conversations → aia_schema.general_conversations
|
||
public.general_messages → aia_schema.general_messages
|
||
```
|
||
|
||
**5. pkb_schema(个人知识库)**
|
||
```sql
|
||
-- 迁移表:
|
||
public.knowledge_bases → pkb_schema.knowledge_bases
|
||
public.documents → pkb_schema.documents
|
||
```
|
||
|
||
#### 只创建空Schema(5个)
|
||
|
||
**6. dc_schema(数据清洗)** - 暂无表结构
|
||
**7. rvw_schema(审稿系统)** - 暂无表结构
|
||
**8. admin_schema(运营管理)** - 暂无表结构
|
||
**9. ssa_schema(智能统计分析)** - 暂无表结构
|
||
**10. st_schema(统计分析工具)** - 暂无表结构
|
||
|
||
---
|
||
|
||
## 🔄 迁移过程连接配置
|
||
|
||
### 迁移前准备
|
||
|
||
**1. 备份当前数据库**
|
||
```bash
|
||
# Windows PowerShell
|
||
cd D:\MyCursor\AIclinicalresearch\backend
|
||
|
||
# 使用pg_dump备份
|
||
pg_dump -h localhost -U postgres -d ai_clinical_research -F c -f backup_before_schema_migration_$(Get-Date -Format 'yyyyMMdd_HHmmss').dump
|
||
|
||
# 或者使用SQL格式
|
||
pg_dump -h localhost -U postgres -d ai_clinical_research > backup_before_schema_migration_$(Get-Date -Format 'yyyyMMdd_HHmmss').sql
|
||
```
|
||
|
||
**2. 验证备份**
|
||
```bash
|
||
# 检查备份文件大小
|
||
ls -lh backup_*.dump
|
||
|
||
# 验证备份内容(SQL格式)
|
||
head -n 50 backup_*.sql
|
||
```
|
||
|
||
---
|
||
|
||
### 迁移过程连接方式
|
||
|
||
#### 方式1:使用Prisma Migrate(推荐)
|
||
|
||
**连接配置:**
|
||
```env
|
||
# backend/.env
|
||
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research
|
||
```
|
||
|
||
**执行迁移:**
|
||
```bash
|
||
cd backend
|
||
|
||
# 创建新的迁移
|
||
npx prisma migrate dev --name schema_isolation_10_schemas
|
||
|
||
# 查看迁移状态
|
||
npx prisma migrate status
|
||
```
|
||
|
||
---
|
||
|
||
#### 方式2:直接执行SQL脚本
|
||
|
||
**连接方式:**
|
||
```bash
|
||
# 使用psql连接
|
||
psql -h localhost -U postgres -d ai_clinical_research
|
||
|
||
# 或使用环境变量
|
||
export PGPASSWORD=postgres
|
||
psql -h localhost -U postgres -d ai_clinical_research -f migration_script.sql
|
||
```
|
||
|
||
**执行迁移脚本:**
|
||
```bash
|
||
cd docs/09-架构实施/migration-scripts
|
||
|
||
# 按顺序执行
|
||
psql -h localhost -U postgres -d ai_clinical_research -f 001-create-all-10-schemas.sql
|
||
psql -h localhost -U postgres -d ai_clinical_research -f 002-migrate-platform.sql
|
||
psql -h localhost -U postgres -d ai_clinical_research -f 003-migrate-aia.sql
|
||
psql -h localhost -U postgres -d ai_clinical_research -f 004-migrate-pkb.sql
|
||
# ... 更多脚本
|
||
```
|
||
|
||
---
|
||
|
||
#### 方式3:使用可视化工具
|
||
|
||
**pgAdmin 4:**
|
||
1. 连接信息:
|
||
- 主机:localhost
|
||
- 端口:5432
|
||
- 数据库:ai_clinical_research
|
||
- 用户:postgres
|
||
- 密码:postgres
|
||
|
||
2. 执行迁移:
|
||
- 打开Query Tool
|
||
- 加载SQL脚本
|
||
- 执行
|
||
|
||
**DataGrip / DBeaver:**
|
||
- 同样的连接信息
|
||
- 支持事务管理
|
||
- 方便回滚
|
||
|
||
---
|
||
|
||
## ✅ 迁移验证
|
||
|
||
### 1. 检查Schema创建
|
||
|
||
**SQL验证:**
|
||
```sql
|
||
-- 查看所有Schema
|
||
SELECT schema_name
|
||
FROM information_schema.schemata
|
||
WHERE schema_name NOT IN ('pg_catalog', 'information_schema')
|
||
ORDER BY schema_name;
|
||
|
||
-- 预期结果:
|
||
-- admin_schema
|
||
-- aia_schema
|
||
-- asl_schema
|
||
-- common_schema
|
||
-- dc_schema
|
||
-- pkb_schema
|
||
-- platform_schema
|
||
-- public
|
||
-- rvw_schema
|
||
-- ssa_schema
|
||
-- st_schema
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 检查表迁移
|
||
|
||
**验证platform_schema:**
|
||
```sql
|
||
-- 查看表
|
||
SELECT table_name
|
||
FROM information_schema.tables
|
||
WHERE table_schema = 'platform_schema';
|
||
|
||
-- 验证数据
|
||
SELECT COUNT(*) FROM platform_schema.users;
|
||
-- 预期:与原public.users的数量一致
|
||
```
|
||
|
||
**验证aia_schema:**
|
||
```sql
|
||
-- 查看所有表
|
||
SELECT table_name
|
||
FROM information_schema.tables
|
||
WHERE table_schema = 'aia_schema';
|
||
|
||
-- 验证数据完整性
|
||
SELECT COUNT(*) FROM aia_schema.projects;
|
||
SELECT COUNT(*) FROM aia_schema.conversations;
|
||
SELECT COUNT(*) FROM aia_schema.messages;
|
||
```
|
||
|
||
**验证pkb_schema:**
|
||
```sql
|
||
SELECT COUNT(*) FROM pkb_schema.knowledge_bases;
|
||
SELECT COUNT(*) FROM pkb_schema.documents;
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 验证外键关系
|
||
|
||
**检查跨Schema外键:**
|
||
```sql
|
||
-- 查看所有外键约束
|
||
SELECT
|
||
tc.table_schema,
|
||
tc.table_name,
|
||
kcu.column_name,
|
||
ccu.table_schema AS foreign_table_schema,
|
||
ccu.table_name AS foreign_table_name,
|
||
ccu.column_name AS foreign_column_name
|
||
FROM information_schema.table_constraints AS tc
|
||
JOIN information_schema.key_column_usage AS kcu
|
||
ON tc.constraint_name = kcu.constraint_name
|
||
JOIN information_schema.constraint_column_usage AS ccu
|
||
ON ccu.constraint_name = tc.constraint_name
|
||
WHERE tc.constraint_type = 'FOREIGN KEY'
|
||
AND tc.table_schema IN ('platform_schema', 'aia_schema', 'pkb_schema', 'asl_schema', 'common_schema')
|
||
ORDER BY tc.table_schema, tc.table_name;
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 验证索引
|
||
|
||
**检查索引是否正确迁移:**
|
||
```sql
|
||
-- 查看某个Schema的所有索引
|
||
SELECT
|
||
schemaname,
|
||
tablename,
|
||
indexname,
|
||
indexdef
|
||
FROM pg_indexes
|
||
WHERE schemaname = 'aia_schema'
|
||
ORDER BY tablename, indexname;
|
||
```
|
||
|
||
---
|
||
|
||
### 5. Prisma验证
|
||
|
||
**更新Prisma配置后验证:**
|
||
```bash
|
||
cd backend
|
||
|
||
# 生成Prisma Client
|
||
npx prisma generate
|
||
|
||
# 验证Prisma Client可用
|
||
npx ts-node -e "import { PrismaClient } from '@prisma/client'; const p = new PrismaClient(); p.user.count().then(console.log)"
|
||
```
|
||
|
||
---
|
||
|
||
## 🔙 回滚方案
|
||
|
||
### 场景1:迁移过程中发现问题
|
||
|
||
**立即回滚:**
|
||
```bash
|
||
# 如果使用Prisma Migrate
|
||
npx prisma migrate reset
|
||
|
||
# 恢复备份
|
||
psql -h localhost -U postgres -d ai_clinical_research < backup_before_schema_migration_YYYYMMDD_HHMMSS.sql
|
||
```
|
||
|
||
---
|
||
|
||
### 场景2:迁移完成后发现问题
|
||
|
||
**方案A:从备份恢复(推荐)**
|
||
```bash
|
||
# 1. 删除当前数据库
|
||
dropdb -h localhost -U postgres ai_clinical_research
|
||
|
||
# 2. 重新创建
|
||
createdb -h localhost -U postgres ai_clinical_research
|
||
|
||
# 3. 恢复备份
|
||
pg_restore -h localhost -U postgres -d ai_clinical_research backup_before_schema_migration_YYYYMMDD_HHMMSS.dump
|
||
```
|
||
|
||
**方案B:手动删除新Schema,保留public**
|
||
```sql
|
||
-- 删除新建的Schema(慎重!)
|
||
DROP SCHEMA IF EXISTS platform_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS aia_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS pkb_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS asl_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS common_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS dc_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS rvw_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS admin_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS ssa_schema CASCADE;
|
||
DROP SCHEMA IF EXISTS st_schema CASCADE;
|
||
|
||
-- public schema的表如果被删除了,从备份恢复
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 迁移检查清单
|
||
|
||
### 迁移前检查
|
||
|
||
- [ ] ✅ 数据库已备份(backup_before_schema_migration_*.dump)
|
||
- [ ] ✅ 备份文件已验证
|
||
- [ ] ✅ Prisma配置已更新(datasource.schemas)
|
||
- [ ] ✅ 迁移脚本已准备(001-010.sql)
|
||
- [ ] ✅ 测试环境已验证迁移步骤
|
||
|
||
---
|
||
|
||
### 迁移中检查
|
||
|
||
- [ ] ✅ 10个Schema创建成功
|
||
- [ ] ✅ 表迁移无错误(5个有数据的Schema)
|
||
- [ ] ✅ 数据完整性验证通过
|
||
- [ ] ✅ 外键约束正确
|
||
- [ ] ✅ 索引正确创建
|
||
|
||
---
|
||
|
||
### 迁移后检查
|
||
|
||
- [ ] ✅ Prisma Client生成成功
|
||
- [ ] ✅ 后端服务启动正常
|
||
- [ ] ✅ 现有功能测试通过(AIA、PKB)
|
||
- [ ] ✅ API调用正常
|
||
- [ ] ✅ 前端功能正常
|
||
|
||
---
|
||
|
||
## 🔧 常见问题
|
||
|
||
### 问题1:Schema创建失败
|
||
|
||
**错误:**
|
||
```
|
||
ERROR: schema "platform_schema" already exists
|
||
```
|
||
|
||
**解决:**
|
||
```sql
|
||
-- 检查Schema是否存在
|
||
SELECT schema_name FROM information_schema.schemata
|
||
WHERE schema_name = 'platform_schema';
|
||
|
||
-- 如果存在但为空,可删除重建
|
||
DROP SCHEMA platform_schema CASCADE;
|
||
CREATE SCHEMA platform_schema;
|
||
```
|
||
|
||
---
|
||
|
||
### 问题2:数据迁移失败
|
||
|
||
**错误:**
|
||
```
|
||
ERROR: duplicate key value violates unique constraint
|
||
```
|
||
|
||
**解决:**
|
||
1. 检查数据是否已部分迁移
|
||
2. 清理目标Schema
|
||
3. 重新执行迁移
|
||
|
||
---
|
||
|
||
### 问题3:外键约束错误
|
||
|
||
**错误:**
|
||
```
|
||
ERROR: foreign key constraint "fk_user_id" cannot be implemented
|
||
```
|
||
|
||
**解决:**
|
||
1. 确保被引用的表已先迁移
|
||
2. 检查外键字段类型匹配
|
||
3. 考虑先禁用外键,迁移后重建
|
||
|
||
---
|
||
|
||
## 🔧 云原生连接池配置(2025-11-16 新增)
|
||
|
||
> **⭐ 重要更新**:为支持阿里云 Serverless 部署,新增连接池配置
|
||
> **详细文档**:[平台基础设施规划](./04-平台基础设施规划.md)
|
||
|
||
### 背景:为什么需要连接池?
|
||
|
||
**问题场景**:
|
||
```
|
||
阿里云 SAE 自动扩容:
|
||
- 初始:1个实例,10个连接
|
||
- 高峰:100个实例,1000个连接
|
||
- RDS最大连接数:400 ❌ 超限!
|
||
|
||
结果:数据库连接耗尽,应用崩溃
|
||
```
|
||
|
||
**解决方案**:动态计算每实例连接数
|
||
|
||
```typescript
|
||
每实例连接数 = RDS最大连接数 / SAE最大实例数
|
||
示例:400连接 / 20实例 = 20连接/实例
|
||
```
|
||
|
||
---
|
||
|
||
### Prisma连接池配置
|
||
|
||
**文件位置**:`backend/src/config/database.ts`
|
||
|
||
**配置代码**:
|
||
|
||
```typescript
|
||
import { PrismaClient } from '@prisma/client'
|
||
|
||
// 动态计算连接数
|
||
const dbMaxConnections = Number(process.env.DB_MAX_CONNECTIONS) || 400
|
||
const maxInstances = Number(process.env.MAX_INSTANCES) || 20
|
||
const connectionLimit = Math.floor(dbMaxConnections / maxInstances)
|
||
|
||
console.log(`📊 数据库连接池配置:每实例最多${connectionLimit}个连接`)
|
||
|
||
// 创建全局Prisma Client
|
||
export const prisma = new PrismaClient({
|
||
datasources: {
|
||
db: {
|
||
url: process.env.DATABASE_URL,
|
||
},
|
||
},
|
||
log: process.env.NODE_ENV === 'development'
|
||
? ['query', 'error', 'warn']
|
||
: ['error'],
|
||
errorFormat: 'minimal',
|
||
})
|
||
|
||
// 优雅关闭连接
|
||
process.on('SIGTERM', async () => {
|
||
console.log('📊 正在关闭数据库连接...')
|
||
await prisma.$disconnect()
|
||
console.log('✅ 数据库连接已关闭')
|
||
process.exit(0)
|
||
})
|
||
|
||
process.on('SIGINT', async () => {
|
||
console.log('📊 正在关闭数据库连接...')
|
||
await prisma.$disconnect()
|
||
console.log('✅ 数据库连接已关闭')
|
||
process.exit(0)
|
||
})
|
||
|
||
// 启动时测试连接
|
||
prisma.$connect()
|
||
.then(() => console.log('✅ 数据库连接成功'))
|
||
.catch((err) => {
|
||
console.error('❌ 数据库连接失败:', err)
|
||
process.exit(1)
|
||
})
|
||
```
|
||
|
||
---
|
||
|
||
### 环境变量配置
|
||
|
||
**本地开发环境**:
|
||
|
||
```bash
|
||
# backend/.env.development
|
||
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/ai_clinical_research
|
||
|
||
# 本地开发无需配置连接池(单实例)
|
||
# DB_MAX_CONNECTIONS=N/A
|
||
# MAX_INSTANCES=N/A
|
||
```
|
||
|
||
**云端生产环境**:
|
||
|
||
```bash
|
||
# SAE控制台 -> 环境变量配置
|
||
DATABASE_URL=postgresql://user:password@rm-xxx.aliyuncs.com:5432/prod_db
|
||
DB_MAX_CONNECTIONS=400 # 阿里云RDS最大连接数
|
||
MAX_INSTANCES=20 # SAE最大实例数
|
||
```
|
||
|
||
**不同RDS规格的连接数**:
|
||
|
||
| RDS规格 | 最大连接数 | 建议SAE实例数 | 每实例连接数 |
|
||
|---------|-----------|--------------|-------------|
|
||
| 2核4GB | 200 | 10 | 20 |
|
||
| 4核8GB | 400 | 20 | 20 |
|
||
| 8核16GB | 800 | 40 | 20 |
|
||
|
||
---
|
||
|
||
### 监控数据库连接数
|
||
|
||
**实时查询连接数**:
|
||
|
||
```typescript
|
||
// backend/src/common/monitoring/metrics.ts
|
||
import { prisma } from '@/config/database'
|
||
import { logger } from '@/common/logging'
|
||
|
||
export class DatabaseMetrics {
|
||
// 查询当前连接数
|
||
static async getConnectionCount(): Promise<number> {
|
||
const result = await prisma.$queryRaw<Array<{ count: bigint }>>`
|
||
SELECT count(*) as count
|
||
FROM pg_stat_activity
|
||
WHERE datname = current_database()
|
||
`
|
||
return Number(result[0].count)
|
||
}
|
||
|
||
// 监控并告警
|
||
static async monitorConnections() {
|
||
const currentConnections = await this.getConnectionCount()
|
||
const maxConnections = Number(process.env.DB_MAX_CONNECTIONS) || 400
|
||
const usagePercent = (currentConnections / maxConnections) * 100
|
||
|
||
logger.info('数据库连接监控', {
|
||
current: currentConnections,
|
||
max: maxConnections,
|
||
usage: `${usagePercent.toFixed(1)}%`
|
||
})
|
||
|
||
// 告警:连接数超过80%
|
||
if (usagePercent > 80) {
|
||
logger.warn('⚠️ 数据库连接数告警', {
|
||
current: currentConnections,
|
||
max: maxConnections,
|
||
usage: `${usagePercent.toFixed(1)}%`,
|
||
action: '建议增加RDS规格或减少SAE实例数'
|
||
})
|
||
}
|
||
|
||
return { currentConnections, maxConnections, usagePercent }
|
||
}
|
||
}
|
||
```
|
||
|
||
**定时监控**(可选):
|
||
|
||
```typescript
|
||
// backend/src/index.ts
|
||
import { DatabaseMetrics } from '@/common/monitoring/metrics'
|
||
|
||
// 每5分钟监控一次
|
||
setInterval(async () => {
|
||
await DatabaseMetrics.monitorConnections()
|
||
}, 5 * 60 * 1000)
|
||
```
|
||
|
||
---
|
||
|
||
### 故障排查
|
||
|
||
**问题1:连接数耗尽**
|
||
|
||
**症状**:
|
||
```
|
||
Error: P1001: Can't reach database server
|
||
Error: remaining connection slots are reserved
|
||
```
|
||
|
||
**原因**:
|
||
- SAE实例数过多
|
||
- 每实例连接数配置过高
|
||
- 存在连接泄漏
|
||
|
||
**解决方案**:
|
||
```bash
|
||
# 1. 查看当前连接数
|
||
SELECT count(*) FROM pg_stat_activity
|
||
WHERE datname = 'ai_clinical_research';
|
||
|
||
# 2. 查看连接来源
|
||
SELECT client_addr, count(*)
|
||
FROM pg_stat_activity
|
||
WHERE datname = 'ai_clinical_research'
|
||
GROUP BY client_addr;
|
||
|
||
# 3. 调整配置
|
||
# 方案A:减少SAE最大实例数
|
||
MAX_INSTANCES=10 # 从20改为10
|
||
|
||
# 方案B:升级RDS规格
|
||
# 从2核4GB(200连接)升级到4核8GB(400连接)
|
||
```
|
||
|
||
---
|
||
|
||
**问题2:连接泄漏**
|
||
|
||
**症状**:
|
||
- 连接数持续增长
|
||
- 即使流量降低,连接数不下降
|
||
|
||
**排查**:
|
||
```typescript
|
||
// ❌ 错误:每次创建新实例
|
||
function getUser() {
|
||
const prisma = new PrismaClient() // 连接泄漏
|
||
return prisma.user.findMany()
|
||
}
|
||
|
||
// ✅ 正确:使用全局实例
|
||
import { prisma } from '@/config/database'
|
||
|
||
function getUser() {
|
||
return prisma.user.findMany()
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 最佳实践
|
||
|
||
**DO ✅**:
|
||
1. ✅ 使用全局 `prisma` 实例
|
||
2. ✅ 配置 `SIGTERM` 优雅关闭
|
||
3. ✅ 定期监控连接数
|
||
4. ✅ 设置连接数告警(80%阈值)
|
||
5. ✅ 使用连接池(Prisma默认启用)
|
||
|
||
**DON'T ❌**:
|
||
1. ❌ 每次请求新建 `PrismaClient`
|
||
2. ❌ 不关闭连接就退出进程
|
||
3. ❌ 忽略连接数监控
|
||
4. ❌ 设置过大的 `MAX_INSTANCES`
|
||
5. ❌ 在业务代码中直接执行 `$disconnect()`
|
||
|
||
---
|
||
|
||
## 📚 相关文档
|
||
|
||
- [平台基础设施规划](./04-平台基础设施规划.md) - 完整的连接池设计
|
||
- [云原生开发规范](../04-开发规范/08-云原生开发规范.md) - 数据库使用规范
|
||
- [环境配置指南](../07-运维文档/01-环境配置指南.md) - 环境变量配置
|
||
- [Schema隔离架构设计](../00-系统总体设计/03-数据库架构说明.md)
|
||
|
||
---
|
||
|
||
## 🔄 更新记录
|
||
|
||
| 日期 | 更新内容 | 更新人 |
|
||
|------|---------|--------|
|
||
| 2025-11-09 | 初始文档创建 | 架构团队 |
|
||
| 2025-11-16 | 新增云原生连接池配置章节 | 架构团队 |
|
||
|
||
---
|
||
|
||
**文档版本:** v1.0
|
||
**最后更新:** 2025-11-09
|
||
**维护者:** 架构团队
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|