# 维护

常规维护程序，包括升级、证书轮换、数据库维护和运维手册。

## 前提条件

- Kubernetes 集群或基础设施管理员访问权限
- 熟悉滚动更新策略
- 访问备份系统

## 滚动更新

### 后端更新

```bash
# 构建新镜像
SHORT_SHA=$(git rev-parse --short HEAD)
gcloud builds submit --config=backend/cloudbuild.yaml \
  --substitutions=SHORT_SHA=$SHORT_SHA \
  --machine-type=E2_HIGHCPU_8 --region=southamerica-east1 backend/

# 如果 Cloud Build 自动部署，Pod 会自动更新
# 否则手动更新：
kubectl set image deployment/pix-backend -n pix \
  pix-backend=REGISTRY/pix-backend:$SHORT_SHA

# 监控发布
kubectl rollout status deployment/pix-backend -n pix
```

::: tip 相同标签警告
使用相同镜像标签（如 `latest`）不会触发 Pod 重启。始终使用唯一标签（commit SHA）或强制重启：
```bash
kubectl rollout restart deployment/pix-backend -n pix
```
:::

### 前端更新

```bash
gcloud builds submit --config=frontend/admin/cloudbuild.yaml \
  --substitutions=SHORT_SHA=$SHORT_SHA \
  --machine-type=E2_HIGHCPU_8 --region=southamerica-east1 frontend/admin/
```

### 数据库迁移

后端更新后始终执行迁移：

```bash
kubectl exec -n pix deployment/pix-backend -- bin/monetarie_pix eval "Shared.Release.migrate()"
```

## 证书轮换

### ICP-Brasil（BACEN）

1. 在到期前获取新证书
2. 转换为 PEM 格式
3. 更新 K8s Secret：
   ```bash
   kubectl create secret generic bacen-certs -n pix \
     --from-file=cpic.pem=new-cpic.pem \
     --from-file=cpic-key.pem=new-cpic-key.pem \
     --from-file=bacen-ca.pem=bacen-ca.pem \
     --dry-run=client -o yaml | kubectl apply -f -
   ```
4. 重启后端（CertificatePool 在启动时重新加载）：
   ```bash
   kubectl rollout restart deployment/pix-backend -n pix
   ```

### TLS 证书

使用 cert-manager 时轮换自动完成。手动证书：

```bash
kubectl create secret tls monetarie-dev-tls -n pix \
  --cert=new-tls.crt --key=new-tls.key \
  --dry-run=client -o yaml | kubectl apply -f -
```

## 数据库维护

### Vacuum 和 Analyze

```bash
# 连接数据库
kubectl exec -n pix deployment/pix-backend -- \
  bin/monetarie_pix eval "Shared.Repo.query!('VACUUM ANALYZE monetarie_spi.messages')"
```

### 分区管理

`PartitionManager` GenServer 每日运行：
- 为 `activity_log` 和 `login_history` 提前 60 天创建分区
- 通过 `XmlArchiver.purge_expired/0` 清除过期审计记录

手动分区检查：

```sql
SELECT schemaname, tablename FROM pg_tables
WHERE tablename LIKE '%activity_log%' OR tablename LIKE '%login_history%'
ORDER BY tablename;
```

### 索引维护

```sql
-- 检查索引使用情况
SELECT schemaname, tablename, indexname, idx_scan
FROM pg_stat_user_indexes
WHERE schemaname IN ('monetarie_spi', 'monetarie_dict', 'monetarie_auth')
ORDER BY idx_scan;

-- 按需重建索引
REINDEX INDEX CONCURRENTLY idx_messages_e2e_trgm;
```

## NATS 维护

### 流维护

```bash
# 检查流状态
nats stream ls
nats stream info MONETARIE_SPI

# 清除旧消息（如需要）
nats stream purge MONETARIE_SPI --keep=10000

# 检查消费者延迟
nats consumer info MONETARIE_SPI pix-inbound-processor
```

## Redis 维护

```bash
# 检查内存使用
redis-cli INFO memory

# 检查键数量
redis-cli DBSIZE

# 清除过期键（TTL 自动清除）
# 手动清除（谨慎使用）：
redis-cli FLUSHDB
```

## 健康验证手册

在任何维护操作后执行：

```bash
# 1. 检查所有 Pod
kubectl get pods -n pix

# 2. 健康检查
curl -s https://pixapi-dev.fluxiq.com.br/health
curl -s https://pixapi-dev.fluxiq.com.br/metrics | head -20

# 3. 检查错误日志
kubectl logs -n pix deployment/pix-backend --tail=50 | grep -i error

# 4. 验证 NATS Worker
kubectl logs -n pix deployment/pix-backend | grep "Worker started"

# 5. 测试登录
curl -X POST https://pixapi-dev.fluxiq.com.br/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"Admin@2026!"}'
```

## 预期结果

遵循维护程序后：

- 滚动更新零停机完成（PDB 确保最少 1 个 Pod）
- 证书在到期前完成轮换
- 定期 vacuum 和索引检查维持数据库性能
- 分区管理自动运行
- 健康验证确认所有服务正常运行
