PlanetScale 生产实践 #

本章将介绍 PlanetScale 在生产环境中的最佳实践,帮助你构建稳定、高效、安全的数据库服务。

生产环境检查清单 #

部署前检查 #

text
┌─────────────────────────────────────────────────────────────┐
│                    部署前检查清单                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   数据库配置:                                              │
│   □ 选择正确的区域                                         │
│   □ 确认计划满足需求                                       │
│   □ 配置多区域(如需要)                                   │
│                                                             │
│   安全配置:                                                │
│   □ 创建生产环境专用密码                                   │
│   □ 使用最小权限原则                                       │
│   □ 配置 IP 白名单(如需要)                               │
│   □ 审查团队成员权限                                       │
│                                                             │
│   连接配置:                                                │
│   □ 配置合理的连接池大小                                   │
│   □ 启用 SSL/TLS                                          │
│   □ 设置连接超时                                           │
│                                                             │
│   监控配置:                                                │
│   □ 设置告警阈值                                           │
│   □ 配置通知渠道                                           │
│   □ 准备监控面板                                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

监控配置 #

关键指标监控 #

text
┌─────────────────────────────────────────────────────────────┐
│                    监控指标                                   │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   资源使用:                                                │
│   ├── 存储使用量                                           │
│   ├── 行读取量                                             │
│   ├── 行写入量                                             │
│   └── 连接数                                               │
│                                                             │
│   性能指标:                                                │
│   ├── 查询延迟                                             │
│   ├── 慢查询数量                                           │
│   ├── 错误率                                               │
│   └── 可用性                                               │
│                                                             │
│   告警阈值建议:                                            │
│   ├── 存储使用 > 80%                                       │
│   ├── 行读取 > 90% 配额                                    │
│   ├── 慢查询 > 100/小时                                    │
│   └── 错误率 > 1%                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

自定义监控脚本 #

javascript
import { connect } from '@planetscale/database';

const conn = connect({ url: process.env.DATABASE_URL });

async function checkHealth() {
  const startTime = Date.now();
  
  try {
    await conn.execute('SELECT 1');
    const latency = Date.now() - startTime;
    
    return {
      status: 'healthy',
      latency,
      timestamp: new Date().toISOString()
    };
  } catch (error) {
    return {
      status: 'unhealthy',
      error: error.message,
      timestamp: new Date().toISOString()
    };
  }
}

setInterval(async () => {
  const health = await checkHealth();
  console.log(JSON.stringify(health));
}, 60000);

性能优化 #

查询优化 #

sql
-- 使用 EXPLAIN 分析查询
EXPLAIN SELECT * FROM users WHERE email = 'test@example.com';

-- 确保使用索引
-- type: ref, range, const 是好的
-- type: ALL 需要优化

-- 优化前
SELECT * FROM users WHERE YEAR(created_at) = 2024;

-- 优化后
SELECT * FROM users WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01';

连接池优化 #

javascript
import mysql from 'mysql2/promise';

const pool = mysql.createPool({
  uri: process.env.DATABASE_URL,
  connectionLimit: 10,
  waitForConnections: true,
  queueLimit: 0,
  connectTimeout: 10000,
  acquireTimeout: 30000
});

setInterval(() => {
  console.log('Pool stats:', {
    total: pool.pool._allConnections.length,
    free: pool.pool._freeConnections.length,
    waiting: pool.pool._connectionQueue.length
  });
}, 60000);

故障排查 #

常见问题诊断 #

text
┌─────────────────────────────────────────────────────────────┐
│                    故障排查指南                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   问题 1:连接超时                                          │
│   症状:Connection timeout                                 │
│   诊断:                                                    │
│   1. 检查网络连通性                                        │
│   2. 检查区域是否正确                                      │
│   3. 检查防火墙规则                                        │
│   解决:                                                    │
│   - 增加连接超时时间                                       │
│   - 使用 CLI 代理测试                                      │
│   - 联系支持                                               │
│                                                             │
│   问题 2:查询慢                                            │
│   症状:查询响应时间长                                     │
│   诊断:                                                    │
│   1. 使用 EXPLAIN 分析                                    │
│   2. 检查索引使用情况                                      │
│   3. 检查查询复杂度                                        │
│   解决:                                                    │
│   - 添加合适的索引                                         │
│   - 优化查询语句                                           │
│   - 减少返回数据量                                         │
│                                                             │
│   问题 3:配额超限                                          │
│   症状:Row read/write limit exceeded                      │
│   诊断:                                                    │
│   1. 检查使用统计                                          │
│   2. 分析查询模式                                          │
│   解决:                                                    │
│   - 优化查询减少读取                                       │
│   - 添加缓存                                               │
│   - 升级计划                                               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

诊断脚本 #

javascript
import { connect } from '@planetscale/database';

const conn = connect({ url: process.env.DATABASE_URL });

async function diagnose() {
  console.log('=== Database Diagnostics ===\n');

  const tables = await conn.execute(`
    SELECT 
      table_name,
      table_rows,
      ROUND(data_length / 1024 / 1024, 2) as data_mb,
      ROUND(index_length / 1024 / 1024, 2) as index_mb
    FROM information_schema.tables
    WHERE table_schema = DATABASE()
  `);
  
  console.log('Tables:');
  console.table(tables.rows);

  const indexes = await conn.execute(`
    SELECT 
      table_name,
      index_name,
      GROUP_CONCAT(column_name ORDER BY seq_in_index) as columns
    FROM information_schema.statistics
    WHERE table_schema = DATABASE()
    GROUP BY table_name, index_name
  `);
  
  console.log('\nIndexes:');
  console.table(indexes.rows);
}

diagnose();

备份与恢复 #

备份策略 #

text
┌─────────────────────────────────────────────────────────────┐
│                    备份策略                                   │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   自动备份:                                                │
│   ├── PlanetScale 每日自动备份                             │
│   ├── 保留 7 天                                            │
│   └── 支持时间点恢复                                       │
│                                                             │
│   手动备份:                                                │
│   ├── 定期导出关键数据                                     │
│   ├── 重要变更前备份                                       │
│   └── 存储到安全位置                                       │
│                                                             │
│   备份命令:                                                │
│   pscale database dump my-db main --output ./backup        │
│                                                             │
│   恢复:                                                    │
│   - 联系 PlanetScale 支持                                  │
│   - 或从导出文件恢复                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

自动备份脚本 #

bash
#!/bin/bash

DATE=$(date +%Y%m%d)
BACKUP_DIR="./backups/$DATE"

mkdir -p $BACKUP_DIR

pscale database dump my-database main --output $BACKUP_DIR

echo "Backup completed: $BACKUP_DIR"

# 上传到云存储
# aws s3 sync $BACKUP_DIR s3://my-bucket/backups/$DATE/

安全最佳实践 #

生产安全清单 #

text
┌─────────────────────────────────────────────────────────────┐
│                    安全检查清单                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   访问控制:                                                │
│   □ 审查所有成员权限                                       │
│   □ 使用最小权限原则                                       │
│   □ 定期轮换密码                                           │
│   □ 删除未使用的密码                                       │
│                                                             │
│   连接安全:                                                │
│   □ 强制使用 SSL/TLS                                       │
│   □ 验证服务器证书                                         │
│   □ 使用环境变量存储密码                                   │
│                                                             │
│   数据安全:                                                │
│   □ 敏感数据加密存储                                       │
│   □ 不在日志中记录敏感信息                                 │
│   □ 定期审计数据访问                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

灾难恢复 #

恢复计划 #

text
┌─────────────────────────────────────────────────────────────┐
│                    灾难恢复计划                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   场景 1:数据误删                                          │
│   步骤:                                                    │
│   1. 立即停止写入操作                                      │
│   2. 联系 PlanetScale 支持                                 │
│   3. 提供时间点恢复请求                                    │
│   4. 验证恢复数据                                          │
│                                                             │
│   场景 2:Schema 变更错误                                   │
│   步骤:                                                    │
│   1. 评估影响范围                                          │
│   2. 创建回滚分支                                          │
│   3. 执行反向变更                                          │
│   4. 部署回滚                                              │
│                                                             │
│   场景 3:服务不可用                                        │
│   步骤:                                                    │
│   1. 检查 PlanetScale 状态页                               │
│   2. 检查应用日志                                          │
│   3. 联系支持                                              │
│   4. 准备备用方案                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

运维自动化 #

CI/CD 集成 #

yaml
name: Production Deployment

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install PlanetScale CLI
        run: curl -fsSL https://raw.githubusercontent.com/planetscale/cli/main/install.sh | bash

      - name: Check for pending deploy requests
        env:
          PLANETSCALE_SERVICE_TOKEN: ${{ secrets.PLANETSCALE_SERVICE_TOKEN }}
        run: |
          pscale auth login --service-token $PLANETSCALE_SERVICE_TOKEN
          DR_COUNT=$(pscale deploy-request list my-app --format json | jq 'length')
          if [ "$DR_COUNT" -gt 0 ]; then
            echo "Pending deploy requests found"
            pscale deploy-request deploy my-app 1
          fi

      - name: Deploy to Vercel
        run: vercel --prod

健康检查端点 #

typescript
import { getConnection } from '@/lib/db';
import { NextResponse } from 'next/server';

export async function GET() {
  const checks = {
    database: false,
    timestamp: new Date().toISOString()
  };

  try {
    const conn = getConnection();
    await conn.execute('SELECT 1');
    checks.database = true;
  } catch (error) {
    console.error('Database health check failed:', error);
  }

  const allHealthy = checks.database;
  const status = allHealthy ? 200 : 503;

  return NextResponse.json(checks, { status });
}

总结 #

PlanetScale 提供了强大的无服务器 MySQL 平台,通过遵循本章的最佳实践,你可以构建稳定、高效、安全的生产环境应用。关键要点:

  1. 监控先行:配置完善的监控和告警
  2. 安全第一:遵循最小权限原则
  3. 性能优化:合理使用索引和连接池
  4. 故障准备:制定灾难恢复计划
  5. 持续改进:定期审查和优化

祝你的 PlanetScale 生产之旅顺利!

最后更新:2026-03-29