- Add iit_schema with 5 tables - Create module structure and types (223 lines) - WeChat integration verified (Access Token success) - Update system docs to v2.4 - Add REDCap source folders to .gitignore - Day 1/14 complete (11/11 tasks)
1179 lines
26 KiB
Markdown
1179 lines
26 KiB
Markdown
# PostgreSQL 15 数据库部署操作手册
|
||
|
||
**文档版本**: v1.0
|
||
**创建时间**: 2025-12-24
|
||
**适用场景**: 本地PostgreSQL数据库迁移到阿里云RDS
|
||
**数据库版本**: PostgreSQL 15
|
||
**部署方式**: pg_dump全量导入
|
||
**预计时间**: 30分钟
|
||
|
||
---
|
||
|
||
## 📋 目录
|
||
|
||
1. [部署概述](#1-部署概述)
|
||
2. [前置条件检查](#2-前置条件检查)
|
||
3. [部署步骤](#3-部署步骤)
|
||
4. [验证测试](#4-验证测试)
|
||
5. [安全加固](#5-安全加固)
|
||
6. [常见问题](#6-常见问题)
|
||
7. [回滚方案](#7-回滚方案)
|
||
8. [最佳实践](#8-最佳实践)
|
||
|
||
---
|
||
|
||
## 1. 部署概述
|
||
|
||
### 1.1 部署目标
|
||
|
||
```yaml
|
||
目标: 将本地Docker PostgreSQL数据库完整迁移到阿里云RDS PostgreSQL 15
|
||
|
||
方法: pg_dump全量导出 + psql导入
|
||
|
||
优势:
|
||
✅ 100%完整(结构+数据+索引+外键)
|
||
✅ 一次性完成
|
||
✅ 可重复执行
|
||
✅ 简单可靠
|
||
✅ 包含pg-boss表(不需要单独处理)
|
||
```
|
||
|
||
### 1.2 部署架构
|
||
|
||
```
|
||
本地环境 阿里云RDS
|
||
┌─────────────────┐ ┌─────────────────┐
|
||
│ │ │ │
|
||
│ Docker │ pg_dump导出 │ RDS PostgreSQL │
|
||
│ PostgreSQL 15 │ ────────────────>│ 15.14 │
|
||
│ │ psql导入 │ │
|
||
│ 26 MB数据 │ │ VPC内网 │
|
||
│ 10个Schema │ │ 2核4GB │
|
||
│ 34个表 │ │ 50GB存储 │
|
||
└─────────────────┘ └─────────────────┘
|
||
```
|
||
|
||
### 1.3 数据库信息
|
||
|
||
#### 本地数据库
|
||
|
||
```yaml
|
||
容器名称: ai-clinical-postgres
|
||
镜像: postgres:15-alpine
|
||
数据库名: ai_clinical_research
|
||
用户名: postgres
|
||
密码: postgres
|
||
端口: 5432
|
||
数据大小: 约26 MB
|
||
```
|
||
|
||
#### RDS数据库
|
||
|
||
```yaml
|
||
实例ID: pgm-2zex1m2y3r23hdn5
|
||
内网地址: pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432
|
||
数据库名: ai_clinical_research
|
||
用户名: airesearch
|
||
密码: Xibahe@fengzhibo117
|
||
版本: PostgreSQL 15.14
|
||
规格: 2核4GB
|
||
存储: 50GB SSD
|
||
地域: 华北2(北京)
|
||
VPC: vpc-2ze055cptkew9c38w4r06 (172.17.0.0/16)
|
||
白名单: 172.17.0.0/16(VPC网段)
|
||
时区: Asia/Shanghai
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 前置条件检查
|
||
|
||
### 2.1 本地环境检查
|
||
|
||
```powershell
|
||
# 1. 检查Docker是否运行
|
||
docker --version
|
||
|
||
# 2. 检查PostgreSQL容器状态
|
||
docker ps --filter "name=ai-clinical-postgres"
|
||
# 预期输出: 容器状态为 Up,健康状态为 healthy
|
||
|
||
# 3. 验证本地数据库连接
|
||
docker exec ai-clinical-postgres psql -U postgres -d ai_clinical_research -c "SELECT version();"
|
||
# 预期输出: PostgreSQL 15.x
|
||
|
||
# 4. 检查数据库大小
|
||
docker exec ai-clinical-postgres psql -U postgres -d ai_clinical_research -c "SELECT pg_size_pretty(pg_database_size('ai_clinical_research'));"
|
||
# 预期输出: 约26 MB
|
||
```
|
||
|
||
### 2.2 RDS环境检查
|
||
|
||
```yaml
|
||
☑️ RDS实例已创建且运行中
|
||
☑️ VPC和交换机已配置
|
||
☑️ 白名单已配置: 172.17.0.0/16
|
||
☑️ 时区已设置: Asia/Shanghai
|
||
☑️ 数据库用户已创建: airesearch
|
||
☑️ 数据库密码已记录: Xibahe@fengzhibo117
|
||
```
|
||
|
||
### 2.3 网络连接检查
|
||
|
||
```yaml
|
||
方案A: 有ECS跳板机
|
||
- 准备ECS公网IP
|
||
- 准备SSH密钥或密码
|
||
- 确保ECS在同一VPC
|
||
|
||
方案B: 临时外网访问(本文档采用)
|
||
- 需要临时开启RDS外网地址
|
||
- 需要配置白名单(临时使用0.0.0.0/0)
|
||
- ⚠️ 完成后立即关闭外网访问
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 部署步骤
|
||
|
||
### 步骤1: 导出本地数据库(5分钟)
|
||
|
||
#### 1.1 导出数据库
|
||
|
||
```powershell
|
||
# 在项目根目录执行
|
||
cd D:\MyCursor\AIclinicalresearch
|
||
|
||
# 导出完整数据库(包括结构、数据、索引、外键)
|
||
docker exec ai-clinical-postgres pg_dump `
|
||
-U postgres `
|
||
-d ai_clinical_research `
|
||
--format=plain `
|
||
--no-owner `
|
||
--no-acl `
|
||
--encoding=UTF8 `
|
||
> "rds_init_$(Get-Date -Format 'yyyyMMdd_HHmmss').sql"
|
||
```
|
||
|
||
**参数说明:**
|
||
|
||
```yaml
|
||
-U postgres: 使用postgres用户
|
||
-d ai_clinical_research: 指定数据库名
|
||
--format=plain: 纯文本SQL格式
|
||
--no-owner: 不导出所有者信息(避免用户名冲突)
|
||
--no-acl: 不导出权限信息(使用RDS默认权限)
|
||
--encoding=UTF8: UTF-8编码(中文支持)
|
||
```
|
||
|
||
#### 1.2 验证导出文件
|
||
|
||
```powershell
|
||
# 检查文件大小和创建时间
|
||
Get-ChildItem rds_init_*.sql |
|
||
Sort-Object LastWriteTime -Descending |
|
||
Select-Object -First 1 |
|
||
Format-Table Name, @{Name="Size(MB)";Expression={[math]::Round($_.Length/1MB,2)}}, LastWriteTime -AutoSize
|
||
```
|
||
|
||
**预期结果:**
|
||
|
||
```
|
||
Name Size(MB) LastWriteTime
|
||
---- -------- -------------
|
||
rds_init_20251224_154529.sql 88.23 2025/12/24 15:45:30
|
||
```
|
||
|
||
**检查要点:**
|
||
|
||
```yaml
|
||
✅ 文件大小合理(50-100 MB)
|
||
✅ 文件创建时间为刚才
|
||
✅ 文件名包含时间戳
|
||
```
|
||
|
||
---
|
||
|
||
### 步骤2: 开启RDS外网访问(3分钟)
|
||
|
||
⚠️ **重要安全提示:** 此步骤会临时开放数据库的公网访问,存在安全风险。必须在导入完成后立即关闭!
|
||
|
||
#### 2.1 登录RDS控制台
|
||
|
||
```
|
||
访问: https://rdsnext.console.aliyun.com/
|
||
地域: 华北2(北京)
|
||
```
|
||
|
||
#### 2.2 申请外网地址
|
||
|
||
1. 找到实例:`pgm-2zex1m2y3r23hdn5`
|
||
2. 点击实例ID,进入实例详情
|
||
3. 左侧菜单:**数据库连接** → **申请外网地址**
|
||
4. 端口:`5432`(默认)
|
||
5. 点击 **确定**
|
||
6. 等待30-60秒,外网地址生成
|
||
|
||
**生成的外网地址示例:**
|
||
|
||
```
|
||
pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com
|
||
```
|
||
|
||
⚠️ **记录此地址,后续步骤需要使用!**
|
||
|
||
#### 2.3 配置白名单
|
||
|
||
**阿里云会弹窗询问:**
|
||
|
||
```
|
||
是否将 0.0.0.0/0 加入白名单?
|
||
```
|
||
|
||
**选择:点击「是」**
|
||
|
||
**风险说明:**
|
||
|
||
```yaml
|
||
风险: 全世界任何人都可以尝试连接你的RDS
|
||
|
||
缓解措施:
|
||
✅ 密码强度高(Xibahe@fengzhibo117)
|
||
✅ 仅用10分钟完成导入
|
||
✅ 导入后立即关闭外网访问
|
||
✅ 实际暴露时间极短
|
||
|
||
可接受性: ✅ 临时调试,可接受
|
||
```
|
||
|
||
---
|
||
|
||
### 步骤3: 创建数据库(1分钟)
|
||
|
||
#### 3.1 连接到RDS
|
||
|
||
```powershell
|
||
# 测试连接(连接到默认postgres数据库)
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d postgres `
|
||
-c "SELECT version();"
|
||
```
|
||
|
||
**预期输出:**
|
||
|
||
```
|
||
version
|
||
------------------------------------------------------------
|
||
PostgreSQL 15.14 on x86_64-pc-linux-gnu, compiled by gcc
|
||
(1 row)
|
||
```
|
||
|
||
#### 3.2 创建数据库
|
||
|
||
```powershell
|
||
# 创建ai_clinical_research数据库
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d postgres `
|
||
-c "CREATE DATABASE ai_clinical_research WITH ENCODING='UTF8' LC_COLLATE='en_US.utf8' LC_CTYPE='en_US.utf8' TEMPLATE=template0;"
|
||
```
|
||
|
||
**预期输出:**
|
||
|
||
```
|
||
CREATE DATABASE
|
||
```
|
||
|
||
#### 3.3 验证数据库创建
|
||
|
||
```powershell
|
||
# 验证数据库存在
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d postgres `
|
||
-c "\l ai_clinical_research"
|
||
```
|
||
|
||
---
|
||
|
||
### 步骤4: 导入数据到RDS(5-8分钟)⭐⭐⭐
|
||
|
||
⏰ **这是最关键的步骤,请耐心等待!**
|
||
|
||
#### 4.1 执行导入
|
||
|
||
```powershell
|
||
# 通过管道将SQL文件导入RDS
|
||
$env:PGPASSWORD="Xibahe@fengzhibo117"
|
||
Get-Content "rds_init_20251224_154529.sql" | `
|
||
docker exec -i -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d ai_clinical_research
|
||
```
|
||
|
||
**注意:** 请将文件名 `rds_init_20251224_154529.sql` 替换为实际导出的文件名。
|
||
|
||
#### 4.2 导入过程输出示例
|
||
|
||
```
|
||
SET
|
||
SET
|
||
CREATE SCHEMA
|
||
CREATE SCHEMA
|
||
...(中间省略数百行)...
|
||
CREATE TABLE
|
||
CREATE TABLE
|
||
COPY 1204 ← 导入1204行数据
|
||
COPY 783
|
||
COPY 3
|
||
...
|
||
CREATE INDEX
|
||
CREATE INDEX
|
||
ALTER TABLE
|
||
...
|
||
```
|
||
|
||
**导入时间估算:**
|
||
|
||
```yaml
|
||
文件大小: 88 MB
|
||
预计时间: 5-8 分钟
|
||
取决于: 网络带宽和RDS写入速度
|
||
|
||
进度指示:
|
||
- 看到 CREATE SCHEMA → Schema创建中
|
||
- 看到 CREATE TABLE → 表创建中
|
||
- 看到 COPY 数字 → 数据导入中(数字是行数)
|
||
- 看到 CREATE INDEX → 索引创建中
|
||
- 看到 ALTER TABLE → 外键创建中
|
||
```
|
||
|
||
#### 4.3 导入完成标志
|
||
|
||
当命令执行完成返回提示符时,说明导入完成。
|
||
|
||
---
|
||
|
||
### 步骤5: 验证导入结果(3分钟)
|
||
|
||
#### 5.1 验证Schema
|
||
|
||
```powershell
|
||
# 检查Schema数量
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d ai_clinical_research `
|
||
-c "SELECT nspname FROM pg_namespace WHERE nspname LIKE '%_schema' ORDER BY nspname;"
|
||
```
|
||
|
||
**预期输出:**
|
||
|
||
```
|
||
nspname
|
||
--------------------
|
||
admin_schema
|
||
aia_schema
|
||
asl_schema
|
||
common_schema
|
||
dc_schema
|
||
pkb_schema
|
||
platform_schema
|
||
rvw_schema
|
||
ssa_schema
|
||
st_schema
|
||
(10 rows)
|
||
```
|
||
|
||
✅ **应该看到10个Schema**
|
||
|
||
#### 5.2 验证表数量
|
||
|
||
```powershell
|
||
# 检查每个Schema的表数量
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d ai_clinical_research `
|
||
-c "SELECT schemaname, COUNT(*) as table_count FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema') GROUP BY schemaname ORDER BY schemaname;"
|
||
```
|
||
|
||
**预期输出:**
|
||
|
||
```
|
||
schemaname | table_count
|
||
-----------------+-------------
|
||
aia_schema | 5
|
||
asl_schema | 6
|
||
dc_schema | 6
|
||
pkb_schema | 5
|
||
platform_schema | 8
|
||
public | 4
|
||
(6 rows)
|
||
```
|
||
|
||
✅ **总计:34个表**
|
||
|
||
#### 5.3 验证pg-boss表(关键)
|
||
|
||
```powershell
|
||
# 检查pg-boss的6个表是否存在
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d ai_clinical_research `
|
||
-c "SELECT tablename FROM pg_tables WHERE schemaname = 'platform_schema' AND tablename IN ('job', 'queue', 'schedule', 'subscription', 'job_common', 'version') ORDER BY tablename;"
|
||
```
|
||
|
||
**预期输出:**
|
||
|
||
```
|
||
tablename
|
||
--------------
|
||
job
|
||
job_common
|
||
queue
|
||
schedule
|
||
subscription
|
||
version
|
||
(6 rows)
|
||
```
|
||
|
||
✅ **pg-boss的6个表全部存在**
|
||
|
||
**说明:**
|
||
|
||
```yaml
|
||
pg-boss表的作用:
|
||
- job: 任务队列表
|
||
- queue: 队列配置表
|
||
- schedule: 定时任务表
|
||
- subscription: 订阅表
|
||
- job_common: 任务通用配置表
|
||
- version: pg-boss版本表
|
||
|
||
为什么重要:
|
||
- backend应用依赖pg-boss进行异步任务处理
|
||
- 如果这些表不存在,backend启动会失败
|
||
- 通过pg_dump导入,这些表会自动包含
|
||
- 不需要在Prisma Schema中定义
|
||
```
|
||
|
||
#### 5.4 验证数据量
|
||
|
||
```powershell
|
||
# 检查关键表的数据量
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d ai_clinical_research `
|
||
-c "SELECT COUNT(*) as user_count, 'platform_schema.users' as table_name FROM platform_schema.users UNION ALL SELECT COUNT(*), 'aia_schema.projects' FROM aia_schema.projects UNION ALL SELECT COUNT(*), 'asl_schema.literatures' FROM asl_schema.literatures;"
|
||
```
|
||
|
||
**预期输出示例:**
|
||
|
||
```
|
||
user_count | table_name
|
||
------------+------------------------
|
||
3 | platform_schema.users
|
||
2 | aia_schema.projects
|
||
1204 | asl_schema.literatures
|
||
(3 rows)
|
||
```
|
||
|
||
✅ **数据量与本地一致**
|
||
|
||
#### 5.5 验证索引和外键
|
||
|
||
```powershell
|
||
# 检查索引数量
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d ai_clinical_research `
|
||
-c "SELECT schemaname, COUNT(*) as index_count FROM pg_indexes WHERE schemaname NOT IN ('pg_catalog', 'information_schema') GROUP BY schemaname ORDER BY schemaname;"
|
||
```
|
||
|
||
```powershell
|
||
# 检查外键约束数量
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d ai_clinical_research `
|
||
-c "SELECT COUNT(*) as fk_count FROM pg_constraint WHERE contype = 'f';"
|
||
```
|
||
|
||
---
|
||
|
||
### 步骤6: 关闭外网访问(2分钟)⭐⭐⭐⭐⭐
|
||
|
||
⚠️ **这是最重要的安全步骤,必须立即执行!**
|
||
|
||
#### 6.1 释放外网地址
|
||
|
||
1. **回到RDS控制台**
|
||
- 实例详情页面
|
||
|
||
2. **找到「数据库连接」**
|
||
|
||
3. **找到外网地址**
|
||
```
|
||
pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com
|
||
```
|
||
|
||
4. **点击「释放外网地址」**
|
||
|
||
5. **在确认对话框中点击「确定」**
|
||
|
||
6. **等待几秒钟**
|
||
|
||
7. **确认状态变为「未申请」** ✅
|
||
|
||
#### 6.2 验证外网访问已关闭
|
||
|
||
```powershell
|
||
# 尝试从本地连接外网地址(应该失败)
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d ai_clinical_research `
|
||
-c "SELECT 1;" `
|
||
--connect-timeout=5
|
||
|
||
# 预期结果: 连接超时或连接失败
|
||
```
|
||
|
||
**预期错误:**
|
||
|
||
```
|
||
psql: error: connection timed out
|
||
```
|
||
|
||
✅ **这个错误说明外网访问已成功关闭!**
|
||
|
||
#### 6.3 最终安全状态
|
||
|
||
```yaml
|
||
RDS连接配置:
|
||
内网地址: pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com ✅ (保留)
|
||
外网地址: 已删除 ✅
|
||
白名单: 172.17.0.0/16 (VPC网段) ✅
|
||
|
||
安全状态:
|
||
✅ 外网无法访问
|
||
✅ 只有VPC内的SAE应用可以连接
|
||
✅ 安全风险已消除
|
||
✅ 数据库处于最安全状态
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 验证测试
|
||
|
||
### 4.1 本地应用连接测试(可选)
|
||
|
||
如果需要本地测试连接RDS,需要建立SSH隧道:
|
||
|
||
```powershell
|
||
# 前提: 需要有ECS跳板机
|
||
|
||
# 建立SSH隧道
|
||
ssh -N -L 5433:pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432 root@ECS公网IP
|
||
|
||
# 在另一个终端测试连接
|
||
$env:PGPASSWORD="Xibahe@fengzhibo117"
|
||
psql -h localhost -p 5433 -U airesearch -d ai_clinical_research -c "SELECT version();"
|
||
```
|
||
|
||
### 4.2 配置backend连接RDS
|
||
|
||
```bash
|
||
# backend/.env
|
||
DATABASE_URL=postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical_research?connection_limit=10&pool_timeout=10&connect_timeout=10
|
||
|
||
# ⚠️ 注意: 密码中的 @ 符号必须转义为 %40
|
||
```
|
||
|
||
**URL编码规则:**
|
||
|
||
```yaml
|
||
特殊字符转义:
|
||
@ -> %40
|
||
# -> %23
|
||
$ -> %24
|
||
% -> %25
|
||
& -> %26
|
||
+ -> %2B
|
||
空格 -> %20
|
||
```
|
||
|
||
### 4.3 backend启动测试
|
||
|
||
```powershell
|
||
cd backend
|
||
npm run dev
|
||
|
||
# 预期日志:
|
||
# ✅ 数据库连接成功
|
||
# ✅ pg-boss started
|
||
# ✅ Server listening on 0.0.0.0:3001
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 安全加固
|
||
|
||
### 5.1 密码安全
|
||
|
||
```yaml
|
||
当前密码: Xibahe@fengzhibo117
|
||
|
||
强度评估:
|
||
✅ 长度: 21个字符
|
||
✅ 大写字母: Xibahe, X, S
|
||
✅ 小写字母: ibahe, fengzhibo
|
||
✅ 数字: 117
|
||
✅ 特殊符号: @
|
||
✅ 强度: 高
|
||
|
||
建议:
|
||
- 定期轮换密码(每3-6个月)
|
||
- 不要在代码中硬编码密码
|
||
- 只在SAE环境变量中配置
|
||
- 不要提交到Git仓库
|
||
```
|
||
|
||
### 5.2 白名单配置
|
||
|
||
```yaml
|
||
当前配置: 172.17.0.0/16 (VPC网段)
|
||
|
||
最佳实践:
|
||
✅ 使用VPC网段,不用单机IP
|
||
✅ SAE实例IP会变化,单机IP会导致连接失败
|
||
❌ 不要配置 0.0.0.0/0(全网开放)
|
||
❌ 不要配置多个单机IP(维护困难)
|
||
|
||
验证:
|
||
- RDS控制台 > 数据安全性 > 白名单设置
|
||
- 确认只有 172.17.0.0/16
|
||
- 确认没有 0.0.0.0/0
|
||
```
|
||
|
||
### 5.3 访问控制
|
||
|
||
```yaml
|
||
用户权限:
|
||
airesearch: 应用专用用户
|
||
- 权限: SELECT, INSERT, UPDATE, DELETE
|
||
- 不要用超级用户 postgres
|
||
- 最小权限原则
|
||
|
||
连接限制:
|
||
- 配置 connection_limit=10(每个SAE实例)
|
||
- 避免连接池耗尽
|
||
- RDS最大连接数: 400
|
||
```
|
||
|
||
### 5.4 备份策略
|
||
|
||
```yaml
|
||
RDS自动备份(强制开启):
|
||
数据备份: 每天一次
|
||
日志备份: 实时(PITR支持)
|
||
保留时间: 7天(免费)
|
||
备份时间: 凌晨2:00-4:00
|
||
|
||
手动快照(重要操作前):
|
||
- Schema变更前
|
||
- 大版本升级前
|
||
- 删除大量数据前
|
||
- 保留30-60天
|
||
|
||
恢复能力:
|
||
✅ 时间点恢复(PITR)
|
||
✅ 可恢复到任意秒
|
||
✅ 备份存储在OSS
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 常见问题
|
||
|
||
### 问题1: 导出时提示权限不足
|
||
|
||
**症状:**
|
||
|
||
```
|
||
pg_dump: error: permission denied for table xxx
|
||
```
|
||
|
||
**原因:** 使用的用户没有足够权限
|
||
|
||
**解决:**
|
||
|
||
```bash
|
||
# 使用超级用户postgres
|
||
docker exec ai-clinical-postgres pg_dump -U postgres -d ai_clinical_research ...
|
||
|
||
# 而不是普通用户
|
||
```
|
||
|
||
---
|
||
|
||
### 问题2: 导入时连接超时
|
||
|
||
**症状:**
|
||
|
||
```
|
||
psql: error: connection timed out
|
||
```
|
||
|
||
**原因:**
|
||
|
||
1. 外网地址未开启
|
||
2. 白名单未配置
|
||
3. 网络问题
|
||
|
||
**排查步骤:**
|
||
|
||
```bash
|
||
# 1. 确认外网地址已开启
|
||
# RDS控制台 > 数据库连接 > 查看外网地址
|
||
|
||
# 2. 确认白名单配置
|
||
# RDS控制台 > 数据安全性 > 白名单设置
|
||
# 应该包含 0.0.0.0/0(临时)或你的公网IP
|
||
|
||
# 3. 测试网络连通性
|
||
ping pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com
|
||
|
||
# 4. 测试端口连通性
|
||
Test-NetConnection -ComputerName pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com -Port 5432
|
||
```
|
||
|
||
---
|
||
|
||
### 问题3: 导入时提示数据库不存在
|
||
|
||
**症状:**
|
||
|
||
```
|
||
psql: error: database "ai_clinical_research" does not exist
|
||
```
|
||
|
||
**原因:** 忘记创建数据库
|
||
|
||
**解决:**
|
||
|
||
```bash
|
||
# 先创建数据库
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d postgres `
|
||
-c "CREATE DATABASE ai_clinical_research WITH ENCODING='UTF8';"
|
||
|
||
# 然后再导入
|
||
```
|
||
|
||
---
|
||
|
||
### 问题4: 导入后pg-boss表缺失
|
||
|
||
**症状:**
|
||
|
||
```
|
||
backend启动日志显示:
|
||
Error: relation "platform_schema.job" does not exist
|
||
```
|
||
|
||
**原因:** 导出时未包含pg-boss表
|
||
|
||
**排查:**
|
||
|
||
```bash
|
||
# 1. 检查导出的SQL文件
|
||
Get-Content rds_init_*.sql | Select-String "CREATE TABLE.*job"
|
||
|
||
# 应该看到:
|
||
# CREATE TABLE platform_schema.job ...
|
||
# CREATE TABLE platform_schema.queue ...
|
||
# 等6个表
|
||
|
||
# 2. 如果没有,重新导出
|
||
docker exec ai-clinical-postgres pg_dump -U postgres -d ai_clinical_research --format=plain --no-owner --no-acl > rds_init_new.sql
|
||
|
||
# 3. 重新导入
|
||
```
|
||
|
||
**预防:**
|
||
|
||
```yaml
|
||
确保使用正确的导出命令:
|
||
✅ 使用 pg_dump(导出整个数据库)
|
||
❌ 不要用 prisma migrate(只导出Prisma定义的表)
|
||
```
|
||
|
||
---
|
||
|
||
### 问题5: 密码中的特殊字符导致连接失败
|
||
|
||
**症状:**
|
||
|
||
```
|
||
backend启动失败:
|
||
Error: password authentication failed for user "airesearch"
|
||
```
|
||
|
||
**原因:** DATABASE_URL中的密码未正确转义
|
||
|
||
**解决:**
|
||
|
||
```bash
|
||
# 错误示例(@ 未转义)
|
||
DATABASE_URL=postgresql://airesearch:Xibahe@fengzhibo117@host:5432/db
|
||
|
||
# 正确示例(@ 转义为 %40)
|
||
DATABASE_URL=postgresql://airesearch:Xibahe%40fengzhibo117@host:5432/db
|
||
```
|
||
|
||
**URL编码工具:**
|
||
|
||
```javascript
|
||
// 在浏览器控制台运行
|
||
encodeURIComponent("Xibahe@fengzhibo117")
|
||
// 输出: Xibahe%40fengzhibo117
|
||
```
|
||
|
||
---
|
||
|
||
### 问题6: SAE应用无法连接RDS
|
||
|
||
**症状:**
|
||
|
||
```
|
||
SAE日志显示:
|
||
connection to server failed: Connection timed out
|
||
```
|
||
|
||
**原因:**
|
||
|
||
1. 使用了外网地址(已删除)
|
||
2. 白名单未包含VPC网段
|
||
3. SAE和RDS不在同一VPC
|
||
|
||
**排查步骤:**
|
||
|
||
```yaml
|
||
1. 确认使用内网地址:
|
||
✅ pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com(内网)
|
||
❌ pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com(外网,已删除)
|
||
|
||
2. 确认白名单配置:
|
||
RDS控制台 > 数据安全性 > 白名单设置
|
||
应该包含: 172.17.0.0/16
|
||
|
||
3. 确认VPC一致:
|
||
- RDS VPC: vpc-2ze055cptkew9c38w4r06
|
||
- SAE VPC: 应该相同
|
||
- 查看方式: SAE控制台 > 应用详情 > 网络配置
|
||
|
||
4. 确认SAE环境变量:
|
||
DATABASE_URL=postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical_research
|
||
注意: 不要有 -ko 后缀
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 回滚方案
|
||
|
||
### 7.1 回滚场景
|
||
|
||
```yaml
|
||
需要回滚的情况:
|
||
- 导入后发现数据不完整
|
||
- 导入过程中断
|
||
- 数据验证失败
|
||
- 应用连接异常
|
||
```
|
||
|
||
### 7.2 回滚步骤
|
||
|
||
```bash
|
||
# 方案A: 删除数据库重新导入(推荐)
|
||
|
||
# 1. 连接到RDS
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h pgm-2zex1m2y3r23hdn5ko.pg.rds.aliyuncs.com `
|
||
-p 5432 `
|
||
-U airesearch `
|
||
-d postgres
|
||
|
||
# 2. 终止所有连接
|
||
SELECT pg_terminate_backend(pid)
|
||
FROM pg_stat_activity
|
||
WHERE datname = 'ai_clinical_research' AND pid <> pg_backend_pid();
|
||
|
||
# 3. 删除数据库
|
||
DROP DATABASE ai_clinical_research;
|
||
|
||
# 4. 重新创建并导入
|
||
CREATE DATABASE ai_clinical_research WITH ENCODING='UTF8';
|
||
\q
|
||
|
||
# 5. 重新导入
|
||
Get-Content rds_init_*.sql | docker exec -i -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql -h ... -d ai_clinical_research
|
||
```
|
||
|
||
```bash
|
||
# 方案B: 使用RDS快照恢复(如果创建了快照)
|
||
|
||
# 1. 登录RDS控制台
|
||
# 2. 备份恢复 > 备份列表
|
||
# 3. 找到导入前的快照
|
||
# 4. 点击「恢复」
|
||
# 5. 选择恢复方式:
|
||
# - 按备份集恢复(恢复到快照时间点)
|
||
# - 按时间点恢复(PITR,恢复到任意时间)
|
||
# 6. 确认恢复
|
||
```
|
||
|
||
### 7.3 回滚验证
|
||
|
||
```bash
|
||
# 验证回滚后的数据
|
||
docker exec -e PGPASSWORD="Xibahe@fengzhibo117" ai-clinical-postgres psql `
|
||
-h ... `
|
||
-d ai_clinical_research `
|
||
-c "SELECT schemaname, COUNT(*) FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema') GROUP BY schemaname;"
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 最佳实践
|
||
|
||
### 8.1 部署前准备
|
||
|
||
```yaml
|
||
☑️ 准备检查清单:
|
||
1. 本地数据库已备份
|
||
2. RDS实例已创建并配置完成
|
||
3. VPC网络已规划
|
||
4. 白名单已配置(VPC网段)
|
||
5. 数据库用户和密码已记录
|
||
6. 时区已设置(Asia/Shanghai)
|
||
7. 自动备份已开启
|
||
|
||
☑️ 时间窗口选择:
|
||
- 业务低峰期(如晚上11点后)
|
||
- 预留足够时间(30-60分钟)
|
||
- 团队成员在线支持
|
||
```
|
||
|
||
### 8.2 执行过程中
|
||
|
||
```yaml
|
||
☑️ 操作规范:
|
||
1. 逐步执行,不要跳步骤
|
||
2. 每步验证结果再继续
|
||
3. 记录每步的输出和时间
|
||
4. 遇到错误立即停止排查
|
||
5. 不要同时执行多个操作
|
||
|
||
☑️ 安全意识:
|
||
1. 外网访问最小化(10分钟内完成)
|
||
2. 导入完成立即关闭外网
|
||
3. 不要在公共网络操作
|
||
4. 不要泄露连接信息
|
||
```
|
||
|
||
### 8.3 部署后检查
|
||
|
||
```yaml
|
||
☑️ 功能验证:
|
||
1. Schema和表数量正确
|
||
2. 数据量与本地一致
|
||
3. pg-boss表存在
|
||
4. 索引和外键完整
|
||
5. backend能正常连接
|
||
6. 应用功能正常
|
||
|
||
☑️ 性能验证:
|
||
1. 连接延迟 < 50ms(VPC内网)
|
||
2. 查询响应时间正常
|
||
3. RDS CPU使用率 < 30%
|
||
4. 连接数 < 100
|
||
|
||
☑️ 安全验证:
|
||
1. 外网地址已删除 ✅
|
||
2. 白名单只有VPC网段 ✅
|
||
3. 密码强度高 ✅
|
||
4. 自动备份已开启 ✅
|
||
```
|
||
|
||
### 8.4 监控告警
|
||
|
||
```yaml
|
||
☑️ 配置监控:
|
||
1. RDS连接数告警(>300)
|
||
2. RDS CPU告警(>70%)
|
||
3. RDS磁盘告警(>80%)
|
||
4. 慢查询告警(>1秒)
|
||
5. 备份失败告警
|
||
|
||
☑️ 日常巡检:
|
||
1. 每天检查RDS监控
|
||
2. 每周查看慢查询日志
|
||
3. 每月验证备份可用性
|
||
4. 每季度恢复演练
|
||
```
|
||
|
||
### 8.5 文档维护
|
||
|
||
```yaml
|
||
☑️ 更新文档:
|
||
1. 记录实际执行时间
|
||
2. 记录遇到的问题和解决方案
|
||
3. 更新连接信息
|
||
4. 补充特殊情况处理
|
||
|
||
☑️ 知识沉淀:
|
||
1. 总结经验教训
|
||
2. 优化部署流程
|
||
3. 培训团队成员
|
||
4. 建立FAQ
|
||
```
|
||
|
||
---
|
||
|
||
## 9. 附录
|
||
|
||
### 9.1 完整检查清单
|
||
|
||
```yaml
|
||
部署前检查 (Before):
|
||
☐ 本地数据库运行正常
|
||
☐ Docker Desktop运行正常
|
||
☐ RDS实例已创建
|
||
☐ VPC和交换机已配置
|
||
☐ 白名单已配置(172.17.0.0/16)
|
||
☐ 数据库用户已创建(airesearch)
|
||
☐ 时区已设置(Asia/Shanghai)
|
||
☐ 自动备份已开启
|
||
|
||
部署过程检查 (During):
|
||
☐ 导出文件大小正常(50-100 MB)
|
||
☐ 外网地址申请成功
|
||
☐ 白名单临时配置(0.0.0.0/0)
|
||
☐ 数据库创建成功
|
||
☐ 数据导入完成(无错误)
|
||
☐ 外网地址已删除 ⭐⭐⭐
|
||
|
||
部署后检查 (After):
|
||
☐ 10个Schema全部存在
|
||
☐ 34个表全部存在
|
||
☐ pg-boss的6个表存在
|
||
☐ 用户数据完整
|
||
☐ 索引完整
|
||
☐ 外键完整
|
||
☐ backend能连接RDS
|
||
☐ 应用功能正常
|
||
☐ 外网访问已关闭 ⭐⭐⭐
|
||
```
|
||
|
||
### 9.2 快速参考
|
||
|
||
#### 连接信息
|
||
|
||
```yaml
|
||
RDS内网地址: pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432
|
||
数据库名: ai_clinical_research
|
||
用户名: airesearch
|
||
密码: Xibahe@fengzhibo117
|
||
|
||
DATABASE_URL:
|
||
postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical_research?connection_limit=10&pool_timeout=10
|
||
```
|
||
|
||
#### 常用命令
|
||
|
||
```powershell
|
||
# 导出数据库
|
||
docker exec ai-clinical-postgres pg_dump -U postgres -d ai_clinical_research --no-owner --no-acl > backup.sql
|
||
|
||
# 导入数据库
|
||
Get-Content backup.sql | docker exec -i -e PGPASSWORD="密码" ai-clinical-postgres psql -h RDS地址 -U airesearch -d ai_clinical_research
|
||
|
||
# 检查Schema
|
||
docker exec -e PGPASSWORD="密码" ai-clinical-postgres psql -h RDS地址 -U airesearch -d ai_clinical_research -c "\dn"
|
||
|
||
# 检查表
|
||
docker exec -e PGPASSWORD="密码" ai-clinical-postgres psql -h RDS地址 -U airesearch -d ai_clinical_research -c "\dt platform_schema.*"
|
||
|
||
# 检查数据量
|
||
docker exec -e PGPASSWORD="密码" ai-clinical-postgres psql -h RDS地址 -U airesearch -d ai_clinical_research -c "SELECT COUNT(*) FROM platform_schema.users;"
|
||
```
|
||
|
||
---
|
||
|
||
## 📚 相关文档
|
||
|
||
- [部署架构总览](./00-部署架构总览.md)
|
||
- [快速部署SOP](./01-快速部署SOP-零基础版.md)
|
||
- [PostgreSQL部署策略摸底报告](./PostgreSQL部署策略-摸底报告.md)
|
||
- [Node.js后端部署指南](./05-Node.js后端-SAE容器部署指南.md)
|
||
|
||
---
|
||
|
||
## 📝 变更历史
|
||
|
||
| 版本 | 日期 | 作者 | 变更说明 |
|
||
|------|------|------|---------|
|
||
| v1.0 | 2025-12-24 | AI助手 | 初始版本,基于实际部署经验 |
|
||
|
||
---
|
||
|
||
## 🆘 支持
|
||
|
||
如有问题,请检查:
|
||
|
||
1. ✅ 本文档的「常见问题」章节
|
||
2. ✅ RDS实时日志(RDS控制台 > 日志管理)
|
||
3. ✅ backend应用日志(SAE控制台 > 日志)
|
||
4. ✅ PostgreSQL部署策略摸底报告
|
||
|
||
---
|
||
|
||
**文档结束**
|
||
|
||
祝部署顺利!🎉
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|