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