GBase 8a 数据导入导出完整指南:gload、LOAD DATA 与 SELECT INTO OUTFILE
数据的进出是 MPP 数据仓库最高频的操作之一。本文系统讲解 GBase 8a 的导入导出工具选型、核心参数配置、字符集处理、错误排查,以及实际生产中的调优经验。
一、导入方式选型
GBase 8a 支持三种数据导入方式,适用场景各有不同:
| 方式 | 命令 | 吞吐量 | 适用场景 |
|---|---|---|---|
| gload | gload -f load.cfg | 最高 | 生产级大批量导入,支持并行、断点续传 |
| LOAD DATA INFILE | SQL 语句 | 中等 | 单文件导入,语法简单,适合开发测试 |
| INSERT INTO ... VALUES | SQL 语句 | 低 | 少量数据写入,不适合批量场景 |
大批量数据导入(>1GB)强烈推荐 gload,其并行处理能力远超 LOAD DATA。
二、gload 工具详解
2.1 配置文件结构
gload 通过 .cfg 配置文件驱动,以下是完整示例:
# load_orders.cfg
# 数据库连接信息
host = 10.168.10.26
port = 5258
user = gbase
password = your_password
database = sales_db
# 目标表
table = orders
# 数据文件(支持通配符,一次导入多个文件)
infile = /data/orders/orders_2024_*.csv
# 文件格式
fields terminated by ',' # 字段分隔符
enclosed by '"' # 字符串引用符
lines terminated by '\n' # 行终止符
ignore 1 lines # 跳过第 1 行(表头)
# 列映射(按文件列顺序映射到表列)
(order_id, customer_id, dept_id, amount, status, order_date, create_time)
# 错误处理
errors = 1000 # 允许最大错误行数(超过则整体回滚)
执行加载:
gload -f load_orders.cfg
2.2 分隔符和格式细节
实际数据文件格式千变万化,以下是几种常见格式的配置:
CSV 文件(逗号分隔,字符串加引号):
fields terminated by ','
enclosed by '"'
lines terminated by '\n'
TSV 文件(Tab 分隔):
fields terminated by '\t'
lines terminated by '\n'
竖线分隔(|),无引用符:
fields terminated by '|'
lines terminated by '\n'
跳过文件头并指定列映射(文件列与表列顺序不同):
ignore 1 lines
# 文件只有 4 列,对应表的 order_id, amount, order_date, status
(order_id, amount, order_date, status)
2.3 字符集配置
字符集不匹配是导入乱码最常见的原因。gload 和 LOAD DATA 都需要明确指定:
# 在 cfg 文件中
character_set = utf8 # 数据文件的字符集
服务端字符集参数(gbase.cnf):
character_set_server = utf8
character_set_database = utf8
character_set_client = utf8
调试技巧:若导入后发现中文乱码,先用
file或hexdump确认数据文件的实际编码,再与character_set_client对齐。GBK 编码的文件需将character_set = gbk写入 cfg,同时确认表定义使用了DEFAULT CHARSET=utf8(服务端会自动转换)。
2.4 错误数据收集
开启错误收集参数后,加载失败的行会被记录(参考上一篇运维文章)。gload 执行完成后,可通过 task_id 查看错误明细:
# gload 的输出中会打印 task_id,例如:
# Load task id: 20240601_143022_000001
-- 查看错误行
SELECT
task_id,
error_row_no,
error_msg,
SUBSTR(raw_data, 1, 200) AS raw_line
FROM gclusterdb.load_error_log
WHERE task_id = '20240601_143022_000001'
LIMIT 50;
2.5 gload 性能调优参数
| 参数 | 位置 | 说明 | 建议值 |
|---|---|---|---|
gcluster_loader_max_data_processors | gcluster | 并发处理线程数 | 物理 CPU 核数/2 |
gcluster_loader_min_chunk_size | gcluster | 每次分发给 gnode 的数据块大小(字节) | 67108864(64MB) |
gbase_loader_parallel_degree | gnode | gnode 上并行写入线程数 | 4~8 |
gbase_loader_buffer_count | gnode | 写入缓冲区个数 | 4 |
gbase_loader_read_timeout | gnode | 读取数据超时(秒) | 300 |
三、LOAD DATA INFILE 详解
3.1 基本语法
LOAD DATA INFILE '/data/orders/orders.csv'
INTO TABLE orders
CHARACTER SET utf8
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
ESCAPED BY '\\'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(order_id, customer_id, dept_id, amount, status, order_date, @create_time)
SET create_time = STR_TO_DATE(@create_time, '%Y-%m-%d %H:%i:%s');
几个关键点:
INFILE的路径是 gcluster 节点上的路径,不是客户端路径IGNORE N LINES跳过 N 行头(表头)- 可以用
@var接收列值,然后在SET中做转换(如日期格式转换) ESCAPED BY '\\\\'注意 SQL 字符串中的转义层
3.2 通过 LOCAL 关键字从客户端上传
-- 不推荐生产使用(性能差),但调试方便
LOAD DATA LOCAL INFILE '/local/path/data.csv'
INTO TABLE orders
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n';
LOCAL 表示文件在客户端本地,gcluster 会从客户端读取并传输,适合小文件测试。
四、SELECT INTO OUTFILE 导出
4.1 基本用法
SELECT order_id, customer_id, amount, order_date
INTO OUTFILE '/data/export/orders_2024.csv'
CHARACTER SET utf8
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
ESCAPED BY '\\'
LINES TERMINATED BY '\n'
FROM orders
WHERE order_date >= '2024-01-01';
注意事项:
- 导出路径是 gcluster 节点上的本地路径
- 目标文件必须不存在,否则报错(不会覆盖)
- 只有 gcluster 有写入权限的目录才能使用
4.2 导出目录配置
默认情况下,导出文件会写到当前工作目录。可以通过参数指定允许写入的目录:
# gcluster 的 gbase.cnf
gbase_export_directory = /data/export
设置后,INTO OUTFILE 的路径必须以此目录为前缀,防止越权写文件。
4.3 分区表导出特定分区
-- 只导出 2024 年 Q1 的数据(分区裁剪生效)
SELECT *
INTO OUTFILE '/data/export/orders_2024q1.csv'
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
FROM orders PARTITION (p2024q1);
4.4 导出大表时的并发方案
SELECT INTO OUTFILE 是单文件单线程写入,导出超大表时可以分段并发导出:
#!/bin/bash
# 按 order_date 月份并发导出,最后合并
for month in 01 02 03 04 05 06 07 08 09 10 11 12; do
gccli -u gbase -p password -e "
SELECT * INTO OUTFILE '/data/export/orders_2024${month}.csv'
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n'
FROM orders
WHERE order_date BETWEEN '2024-${month}-01' AND LAST_DAY('2024-${month}-01')
" &
done
wait
echo "All exports done"
五、监控导出任务进度
导出任务同样记录在系统表中:
-- 查看正在执行的导出任务
SELECT
task_id,
table_name,
status,
start_time,
exported_rows,
TIMESTAMPDIFF(SECOND, start_time, NOW()) AS elapsed_sec
FROM gclusterdb.export_task
WHERE status = 'RUNNING';
-- 查看历史导出记录
SELECT
task_id,
table_name,
status,
exported_rows,
start_time,
end_time
FROM gclusterdb.export_task
ORDER BY start_time DESC
LIMIT 20;
六、常见问题排查
问题 1:导入后行数比预期少,但没有报错
很可能是数据中存在非法字符(如控制字符、不合法的 NULL 表示),被静默跳过了。
排查步骤:
-- 开启错误收集
SET gbase_loader_logs_collect = ON;
-- 重新导入,然后查 error_log
SELECT COUNT(*), error_msg
FROM gclusterdb.load_error_log
WHERE task_id = '...'
GROUP BY error_msg;
问题 2:导入速度慢,磁盘 I/O 不高
原因通常是并发度配置过低。检查:
SHOW VARIABLES LIKE 'gcluster_loader_max_data_processors';
SHOW VARIABLES LIKE 'gbase_loader_parallel_degree';
适当调高后,通过 gclusterdb.load_task 中的 loaded_rows 变化速率判断是否改善。
问题 3:OUTFILE 报错 "Can't create/write to file"
原因:
- 目标路径不存在 → 手动创建目录并赋予 gbase 用户写权限
- 文件已存在 → 删除旧文件后重试
gbase_export_directory限制了写入目录 → 修改导出路径到允许的目录
问题 4:导入日期时报 "Incorrect datetime value"
数据文件中的日期格式与表字段类型不匹配。使用 @var + SET 做格式转换:
LOAD DATA INFILE '/data/orders.csv'
INTO TABLE orders
FIELDS TERMINATED BY ','
(@order_id, @customer_id, @amount, @order_date_str)
SET
order_id = @order_id,
customer_id = @customer_id,
amount = @amount,
-- 将 '20240601' 格式转换为 DATE
order_date = STR_TO_DATE(@order_date_str, '%Y%m%d');
七、导入导出最佳实践
| 场景 | 推荐方案 |
|---|---|
| 每日增量数据入库(>1GB) | gload + 配置文件,分时间段多文件并发 |
| 开发环境小表测试导入 | LOAD DATA LOCAL INFILE |
| 定期全量导出做备份 | SELECT INTO OUTFILE 分区并发导出 |
| 跨库数据迁移 | gload 配合 SELECT INTO OUTFILE 管道 |
| 数据质量检查 | 先开启 gbase_loader_logs_collect,看错误分布 |
gload 是生产环境首选,它在 gcluster 和 gnode 两层都实现了并行处理,能充分利用 MPP 集群的多节点并发写入能力,吞吐量通常是 LOAD DATA 的 3~5 倍。
评论
热门帖子
- 12025-12-01浏览数:182366
- 22023-05-09浏览数:24608
- 42023-09-25浏览数:17917
- 52020-05-11浏览数:16938