PlanetScale 数据迁移 #

本章将介绍如何在 PlanetScale 中进行数据迁移,包括从外部数据库导入数据、导出数据、以及数据同步等操作。

迁移概览 #

迁移方式对比 #

text
┌─────────────────────────────────────────────────────────────┐
│                    迁移方式                                   │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   1. 直接导入(小数据量)                                   │
│      ┌─────────────────────────────────────────────────┐   │
│      │  SQL 文件 / CSV 文件 ──> PlanetScale            │   │
│      │                                                  │   │
│      │  适合:< 1GB 数据                                │   │
│      │  工具:CLI、Web Console                          │   │
│      └─────────────────────────────────────────────────┘   │
│                                                             │
│   2. 数据库迁移服务(大数据量)                             │
│      ┌─────────────────────────────────────────────────┐   │
│      │  外部数据库 ──> PlanetScale 迁移服务            │   │
│      │                                                  │   │
│      │  适合:> 1GB 数据                               │   │
│      │  支持:MySQL、PostgreSQL                        │   │
│      └─────────────────────────────────────────────────┘   │
│                                                             │
│   3. 自定义迁移                                             │
│      ┌─────────────────────────────────────────────────┐   │
│      │  应用代码 ──> 读取 ──> 写入 ──> PlanetScale    │   │
│      │                                                  │   │
│      │  适合:复杂迁移场景                             │   │
│      │  灵活:可自定义逻辑                             │   │
│      └─────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

数据导入 #

使用 CLI 导入 #

bash
# 导入 SQL 文件
pscale shell my-database main < data.sql

# 或使用管道
cat data.sql | pscale shell my-database main

# 导入到特定分支
pscale shell my-database develop < test-data.sql

使用 Web Console 导入 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Web Console 导入                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   步骤:                                                    │
│                                                             │
│   1. 进入数据库 Console 页面                                │
│                                                             │
│   2. 点击 "Import" 或直接粘贴 SQL                          │
│                                                             │
│   ┌─────────────────────────────────────────────────────┐  │
│   │  INSERT INTO users (name, email) VALUES             │  │
│   │  ('Alice', 'alice@example.com'),                    │  │
│   │  ('Bob', 'bob@example.com'),                        │  │
│   │  ('Charlie', 'charlie@example.com');                │  │
│   └─────────────────────────────────────────────────────┘  │
│                                                             │
│   3. 点击 "Run" 执行                                       │
│                                                             │
│   限制:                                                    │
│   - 单次执行 SQL 大小有限制                                │
│   - 大数据量建议使用 CLI                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

导入 CSV 数据 #

bash
# 方法 1:转换为 SQL
# 使用工具将 CSV 转换为 INSERT 语句

# 方法 2:使用 LOAD DATA(需要代理)
pscale connect my-database main

# 另一个终端
mysql -h 127.0.0.1 my-database -e "
  LOAD DATA LOCAL INFILE 'users.csv'
  INTO TABLE users
  FIELDS TERMINATED BY ','
  LINES TERMINATED BY '\n'
  IGNORE 1 ROWS
  (name, email);
"

导入 JSON 数据 #

javascript
import mysql from 'mysql2/promise';
import fs from 'fs';

const connection = await mysql.createConnection(process.env.DATABASE_URL);

const users = JSON.parse(fs.readFileSync('users.json', 'utf8'));

for (const user of users) {
  await connection.execute(
    'INSERT INTO users (name, email) VALUES (?, ?)',
    [user.name, user.email]
  );
}

await connection.end();

数据导出 #

使用 CLI 导出 #

bash
# 导出整个数据库
pscale database dump my-database main --output ./backup

# 导出特定表
pscale shell my-database main -f export.sql

# export.sql 内容
SELECT * FROM users INTO OUTFILE '/tmp/users.csv'
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n';

使用 mysqldump 风格导出 #

bash
# 通过代理使用 mysqldump
pscale connect my-database main &

mysqldump -h 127.0.0.1 my-database users > users.sql

# 导出结构
mysqldump -h 127.0.0.1 --no-data my-database > schema.sql

# 导出数据
mysqldump -h 127.0.0.1 --no-create-info my-database > data.sql

导出为 JSON #

javascript
import mysql from 'mysql2/promise';
import fs from 'fs';

const connection = await mysql.createConnection(process.env.DATABASE_URL);

const [rows] = await connection.execute('SELECT * FROM users');

fs.writeFileSync('users.json', JSON.stringify(rows, null, 2));

await connection.end();

从外部数据库迁移 #

从 MySQL 迁移 #

text
┌─────────────────────────────────────────────────────────────┐
│                    MySQL 迁移流程                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   步骤 1:导出源数据库                                      │
│   ┌─────────────────────────────────────────────────────┐  │
│   │  mysqldump -h source-host source-db \               │  │
│   │    --single-transaction \                           │  │
│   │    --routines \                                     │  │
│   │    --triggers \                                     │  │
│   │    --no-create-db \                                 │  │
│   │    > source-backup.sql                              │  │
│   └─────────────────────────────────────────────────────┘  │
│                                                             │
│   步骤 2:处理不兼容语法                                    │
│   - 移除外键约束                                           │
│   - 移除存储过程                                           │
│   - 移除触发器                                             │
│                                                             │
│   步骤 3:导入到 PlanetScale                               │
│   pscale shell my-database main < source-backup.sql        │
│                                                             │
│   步骤 4:验证数据                                         │
│   - 检查表数量                                             │
│   - 检查行数                                               │
│   - 抽样验证数据                                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘

迁移脚本示例 #

bash
#!/bin/bash

SOURCE_HOST="source.mysql.host"
SOURCE_DB="source_db"
SOURCE_USER="source_user"
SOURCE_PASS="source_pass"

PLANETSCALE_DB="my-database"
PLANETSCALE_BRANCH="main"

echo "Step 1: Exporting schema..."
mysqldump -h $SOURCE_HOST -u $SOURCE_USER -p$SOURCE_PASS \
  $SOURCE_DB --no-data > schema.sql

echo "Step 2: Cleaning schema..."
sed -i '' '/FOREIGN KEY/d' schema.sql
sed -i '' '/CONSTRAINT/d' schema.sql
sed -i '' '/CREATE TRIGGER/d' schema.sql
sed -i '' '/CREATE PROCEDURE/d' schema.sql

echo "Step 3: Importing schema..."
pscale shell $PLANETSCALE_DB $PLANETSCALE_BRANCH < schema.sql

echo "Step 4: Exporting data..."
mysqldump -h $SOURCE_HOST -u $SOURCE_USER -p$SOURCE_PASS \
  $SOURCE_DB --no-create-info --single-transaction > data.sql

echo "Step 5: Importing data..."
pscale shell $PLANETSCALE_DB $PLANETSCALE_BRANCH < data.sql

echo "Migration complete!"

从 PostgreSQL 迁移 #

text
┌─────────────────────────────────────────────────────────────┐
│                    PostgreSQL 迁移                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   注意事项:                                                │
│   - 数据类型需要转换                                       │
│   - SERIAL → AUTO_INCREMENT                                │
│   - TEXT → TEXT (兼容)                                     │
│   - JSONB → JSON                                           │
│   - BOOLEAN → TINYINT(1)                                   │
│                                                             │
│   工具推荐:                                                │
│   - pgloader(自动类型转换)                               │
│   - 手动编写转换脚本                                       │
│                                                             │
│   pgloader 示例:                                          │
│   pgloader \                                               │
│     postgresql://user:pass@pg-host/pg-db \                 │
│     mysql://user:pass@pscale-host/ps-db                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

从其他云数据库迁移 #

text
┌─────────────────────────────────────────────────────────────┐
│                    云数据库迁移                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   AWS RDS / Aurora:                                        │
│   1. 使用 mysqldump 导出                                   │
│   2. 或使用 AWS DMS 服务                                   │
│                                                             │
│   Google Cloud SQL:                                        │
│   1. 使用 Cloud SQL 导出功能                               │
│   2. 导出为 SQL 文件                                       │
│                                                             │
│   Azure Database for MySQL:                                │
│   1. 使用 Azure 数据库导出                                 │
│   2. 或使用 mysqldump                                      │
│                                                             │
│   Heroku Postgres:                                         │
│   1. 使用 pg_dump 导出                                     │
│   2. 转换数据类型                                          │
│   3. 导入到 PlanetScale                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

数据同步 #

双向同步(高级) #

text
┌─────────────────────────────────────────────────────────────┐
│                    数据同步架构                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   场景:迁移期间保持同步                                    │
│                                                             │
│   ┌─────────────┐                    ┌─────────────┐       │
│   │  源数据库    │                    │ PlanetScale │       │
│   │             │                    │             │       │
│   │  ┌───────┐  │    CDC 同步        │  ┌───────┐  │       │
│   │  │ 数据   │──┼──────────────────>│  │ 数据   │  │       │
│   │  └───────┘  │                    │  └───────┘  │       │
│   │             │                    │             │       │
│   └─────────────┘                    └─────────────┘       │
│                                                             │
│   工具:                                                    │
│   - Debezium (CDC)                                         │
│   - AWS DMS                                                │
│   - 自定义同步脚本                                          │
│                                                             │
│   注意:                                                    │
│   - 需要处理冲突                                           │
│   - 需要监控同步状态                                       │
│   - 复杂度较高                                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

使用 Debezium 同步 #

yaml
debezium:
  source:
    connector: mysql
    host: source-host
    port: 3306
    user: source_user
    password: source_pass
    database: source_db
  
  sink:
    connector: mysql
    host: aws.connect.psdb.cloud
    port: 3306
    user: pscale_user
    password: pscale_pass
    database: my-database

迁移最佳实践 #

迁移前准备 #

text
┌─────────────────────────────────────────────────────────────┐
│                    迁移检查清单                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   □ 源数据库分析                                           │
│     - 表数量和大小                                         │
│     - 数据类型统计                                         │
│     - 外键和触发器                                         │
│     - 存储过程                                             │
│                                                             │
│   □ 兼容性检查                                             │
│     - 检查不支持的特性                                     │
│     - 准备替代方案                                         │
│     - 更新应用代码                                         │
│                                                             │
│   □ 迁移计划                                               │
│     - 选择迁移时间                                         │
│     - 估算迁移时间                                         │
│     - 准备回滚方案                                         │
│                                                             │
│   □ 测试迁移                                               │
│     - 在测试环境验证                                       │
│     - 测试应用兼容性                                       │
│     - 性能测试                                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

迁移执行 #

text
┌─────────────────────────────────────────────────────────────┐
│                    迁移执行步骤                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   1. 设置维护窗口                                          │
│      - 通知用户                                            │
│      - 停止写入                                            │
│                                                             │
│   2. 最终数据同步                                          │
│      - 导出最新数据                                        │
│      - 导入到 PlanetScale                                  │
│                                                             │
│   3. 验证数据完整性                                        │
│      - 检查行数                                            │
│      - 抽样验证                                            │
│      - 运行测试                                            │
│                                                             │
│   4. 切换应用                                              │
│      - 更新连接字符串                                      │
│      - 重启服务                                            │
│      - 监控错误                                            │
│                                                             │
│   5. 监控和优化                                            │
│      - 监控性能                                            │
│      - 处理问题                                            │
│      - 优化查询                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

数据验证 #

sql
-- 验证表数量
SELECT COUNT(*) FROM information_schema.tables 
WHERE table_schema = 'my-database';

-- 验证行数
SELECT 
  table_name,
  table_rows 
FROM information_schema.tables 
WHERE table_schema = 'my-database';

-- 抽样验证
SELECT * FROM users ORDER BY RAND() LIMIT 100;

-- 验证索引
SHOW INDEX FROM users;

备份与恢复 #

自动备份 #

text
┌─────────────────────────────────────────────────────────────┐
│                    自动备份策略                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   PlanetScale 自动备份:                                   │
│   ├── 每日自动备份                                         │
│   ├── 保留 7 天                                            │
│   ├── 支持时间点恢复                                       │
│   └── 跨区域复制(付费计划)                               │
│                                                             │
│   备份内容:                                                │
│   - Schema 结构                                            │
│   - 数据内容                                               │
│   - 分支信息                                               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

手动备份 #

bash
# 导出备份
pscale database dump my-database main --output ./backup-$(date +%Y%m%d)

# 备份特定表
pscale shell my-database main -c "SELECT * FROM users" > users-backup.sql

恢复数据 #

bash
# 从备份恢复
pscale shell my-database main < backup.sql

# 恢复到新分支
pscale branch create my-database restore-point
pscale shell my-database restore-point < backup.sql

常见问题 #

迁移速度慢 #

text
问题:大数据量迁移时间过长
解决:
  1. 分批导入数据
  2. 使用并行导入
  3. 禁用索引后导入
  4. 联系支持获取帮助

数据类型不兼容 #

text
问题:某些数据类型无法导入
解决:
  1. 检查 PlanetScale 支持的类型
  2. 修改 SQL 文件中的类型
  3. 使用转换脚本

字符编码问题 #

text
问题:导入后中文乱码
解决:
  1. 确保源数据库使用 UTF-8
  2. 导出时指定字符集
  3. 导入时使用 charset=utf8mb4

下一步 #

现在你已经掌握了数据迁移,接下来学习 性能优化,了解如何优化 PlanetScale 数据库性能!

最后更新:2026-03-29