数据导出
数据导出
1. 功能概述
IoTDB 支持三种方式进行数据导出:
数据导出工具:
export-data.sh/bat位于tools目录下,能够将指定 SQL 的查询结果导出为 CSV、SQL 及 TsFile(开源时间序列文件格式)格式。基于 PIPE 框架的 TsFileBackup:
tsfile-backup.sh/bat位于tools目录下,能够使用 PIPE 将指定的数据文件导出为 TsFile 格式。Copy SQL 导出 TsFile:通过 SQL 将查询结果写回到指定路径的 TsFile 中。
| 文件格式 | IoTDB工具 | 具体介绍 |
|---|---|---|
| CSV | export-data.sh/bat | 纯文本格式,存储格式化数据,需按照下文指定 CSV 格式进行构造 |
| SQL | 包含自定义 SQL 语句的文件 | |
| TsFile | 开源时序数据文件格式 | |
| tsfile-backup.sh/bat | 开源时序数据文件格式,支持 Object 数据类型 | |
| Copy SQL | 开源时序数据文件格式 |
2. 数据导出工具
2.1 公共参数
| 参数缩写 | 参数全称 | 参数含义 | 是否必填 | 默认值 |
|---|---|---|---|---|
-ft | --file_type | 导出格式:csv、sql 或 tsfile | 是 | - |
-sql_dialect | --sql_dialect | 选择模型;tree 或 table。表模型需指定 table | 是 | tree |
-db | --database | 目标数据库;表模型三种格式均需指定 | 是 | - |
-table | --table | 目标表;省略时遍历数据库中的所有表 | 否 | 数据库中的所有表 |
-start_time | --start_time | 起始时间,自动查询生成 time >= start_time | 否 | - |
-end_time | --end_time | 结束时间,自动查询生成 time <= end_time | 否 | - |
-h | --host | 服务地址 | 否 | 127.0.0.1 |
-p | --port | RPC 端口 | 否 | 6667 |
-u | --username | 用户名 | 否 | root |
-pw | --password | 密码;只写 -pw 而不跟值时交互式隐藏输入 | 否 | TimechoDB@2021 |
-t | --target | 输出目录;目录不存在时自动创建 | 是 | - |
-pfn | --prefix_file_name | 指定导出文件的名称。例如:abc,生成的文件是 abc_0.tsfile、abc_1.tsfile | 否 | dump_0.tsfile |
-q | --query | 自定义查询。推荐用于 CSV;指定后时间范围应直接写在 SQL 中 | 否 | 自动生成查询 |
-timeout | --query_timeout | 查询超时时间,单位为毫秒 | 否 | Long.MAX_VALUE |
-mfs | --rpc_max_frame_size | RPC 最大帧大小,单位为字节 | 否 | 536870912 |
-help | --help | 查看指定格式帮助,例如 -sql_dialect table -help csv | 否 | - |
-usessl | --use_ssl | 是否启用 SSL,必须跟随布尔值 true 或 false;启用 SSL 时写成 -usessl true。 | 否 | - |
-ts | --trust_store | TrustStore 路径 | 否 | - |
-tpw | --trust_store_password | TrustStore 密码,支持隐藏输入 | 否 | - |
-ks | --key_store | 双向 TLS 使用的 KeyStore 路径 | 否 | - |
-kpw | --key_store_password | KeyStore 密码 | 否 | - |
-ssl_protocol | --ssl_protocol | SSL/TLS 协议 | 否 | - |
说明:
表模型必须显式指定
-sql_dialect table和目标数据库-db。-start_time和-end_time形成闭区间,可以只指定其中一个。未指定-table时,相同时间条件会应用到数据库中的每一张表。
2.2 CSV 格式
CSV 适合离线分析、报表、审计和数据交换,也是使用自定义查询时最稳妥的格式。
2.2.1 运行命令
# Unix/OS X
tools/export-data.sh -ft csv -sql_dialect table -db <database> [-table <table>] \
[-start_time <start_time>] [-end_time <end_time>] [-h <host>] [-p <port>] [-u <username>] [-pw <password>] \
[-usessl <true|false>] [-ts <trust_store>] [-tpw <trust_store_password>] [-ks <key_store>] \
[-kpw <key_store_password>] [-ssl_protocol <ssl_protocol>] -t <target_directory> \
[-pfn <prefix_file_name>] [-q <query_command>] [-timeout <query_timeout>] [-mfs <rpc_max_frame_size>] \
[-dt <true|false>] [-lpf <lines_per_file>] [-tf <time_format>] [-tz <timezone>]
# Windows(V2.0.4.x 之前)
tools\export-data.bat -ft csv -sql_dialect table -db <database> [-table <table>] ^
[-start_time <start_time>] [-end_time <end_time>] [-h <host>] [-p <port>] [-u <username>] [-pw <password>] ^
[-usessl <true|false>] [-ts <trust_store>] [-tpw <trust_store_password>] [-ks <key_store>] ^
[-kpw <key_store_password>] [-ssl_protocol <ssl_protocol>] -t <target_directory> ^
[-pfn <prefix_file_name>] [-q <query_command>] [-timeout <query_timeout>] [-mfs <rpc_max_frame_size>] ^
[-dt <true|false>] [-lpf <lines_per_file>] [-tf <time_format>] [-tz <timezone>]
# Windows(V2.0.4.x 及之后)
tools\windows\export-data.bat -ft csv -sql_dialect table -db <database> [-table <table>] ^
[-start_time <start_time>] [-end_time <end_time>] [-h <host>] [-p <port>] [-u <username>] [-pw <password>] ^
[-usessl <true|false>] [-ts <trust_store>] [-tpw <trust_store_password>] [-ks <key_store>] ^
[-kpw <key_store_password>] [-ssl_protocol <ssl_protocol>] -t <target_directory> ^
[-pfn <prefix_file_name>] [-q <query_command>] [-timeout <query_timeout>] [-mfs <rpc_max_frame_size>] ^
[-dt <true|false>] [-lpf <lines_per_file>] [-tf <time_format>] [-tz <timezone>]2.2.2 私有参数
| 参数缩写 | 参数全称 | 参数含义 | 是否为必填项 | 默认值 |
|---|---|---|---|---|
-dt | --datatype | 是否在表头输出数据类型。当前实现中该参数不会可靠改变表头,不建议依赖 | 否 | false |
-lpf | --lines_per_file | 每个 CSV 文件的数据行数,表模型中实际有效 | 否 | 10000 |
-tf | --time_format | 时间格式:timestamp、number、long 或自定义格式。 | 否 | ISO8601 |
-tz | --timezone | 设置时区,例如 +08:00 或 -01:00 | 否 | 本机时区 |
关于时间格式输出的补充说明:-tf 只影响 CSV 文件的 Time 列。以下示例中的时间均以 +08:00 时区为准。
-tf 值 | Time 列输出格式 | 示例 |
|---|---|---|
timestamp | 十进制毫秒时间戳 | 1767225600000 |
number | 十进制毫秒时间戳 | 1767225600000 |
long | 十进制毫秒时间戳 | 1767225600000 |
省略 -tf(默认 ISO8601) | ISO 8601,包含毫秒和时区偏移 | 2026-01-01T08:00:00.000+08:00 |
自定义格式 yyyy-MM-dd HH:mm:ss | 按指定模式格式化的本地日期时间 | 2026-01-01 08:00:00 |
2.2.3 运行示例
# 正确示例
> export-data.sh -ft csv -sql_dialect table -t /path/export/dir -db database1 -q "select * from table1"
# 异常示例
> export-data.sh -ft csv -sql_dialect table -t /path/export/dir -q "select * from table1"
Parse error: Missing required option: db2.3 SQL 格式
SQL 格式会把查询结果中的每行数据转换为一条 INSERT INTO 写入语句。将导出的 SQL 文件提交到结构兼容的目标数据库执行,即可重新写入这些数据,因此适合小规模数据迁移、数据修复和人工审计。
2.3.1 运行命令
# Unix/OS X
tools/export-data.sh -ft sql -sql_dialect table -db <database> [-table <table>] \
[-start_time <start_time>] [-end_time <end_time>] [-h <host>] [-p <port>] [-u <username>] [-pw <password>] \
[-usessl <true|false>] [-ts <trust_store>] [-tpw <trust_store_password>] [-ks <key_store>] \
[-kpw <key_store_password>] [-ssl_protocol <ssl_protocol>] -t <target_directory> \
[-pfn <prefix_file_name>] [-q <query_command>] [-timeout <query_timeout>] [-mfs <rpc_max_frame_size>] \
[-lpf <lines_per_file>] [-tf <time_format>] [-tz <timezone>]
# Windows(V2.0.4.x 之前)
tools\export-data.bat -ft sql -sql_dialect table -db <database> [-table <table>] ^
[-start_time <start_time>] [-end_time <end_time>] [-h <host>] [-p <port>] [-u <username>] [-pw <password>] ^
[-usessl <true|false>] [-ts <trust_store>] [-tpw <trust_store_password>] [-ks <key_store>] ^
[-kpw <key_store_password>] [-ssl_protocol <ssl_protocol>] -t <target_directory> ^
[-pfn <prefix_file_name>] [-q <query_command>] [-timeout <query_timeout>] [-mfs <rpc_max_frame_size>] ^
[-lpf <lines_per_file>] [-tf <time_format>] [-tz <timezone>]
# Windows(V2.0.4.x 及之后)
tools\windows\export-data.bat -ft sql -sql_dialect table -db <database> [-table <table>] ^
[-start_time <start_time>] [-end_time <end_time>] [-h <host>] [-p <port>] [-u <username>] [-pw <password>] ^
[-usessl <true|false>] [-ts <trust_store>] [-tpw <trust_store_password>] [-ks <key_store>] ^
[-kpw <key_store_password>] [-ssl_protocol <ssl_protocol>] -t <target_directory> ^
[-pfn <prefix_file_name>] [-q <query_command>] [-timeout <query_timeout>] [-mfs <rpc_max_frame_size>] ^
[-lpf <lines_per_file>] [-tf <time_format>] [-tz <timezone>]2.3.2 私有参数
| 参数缩写 | 参数全称 | 参数含义 | 是否为必填项 | 默认值 |
|---|---|---|---|---|
-lpf | --lines_per_file | 每个 SQL 文件包含的 INSERT 行数,表模型中实际有效 | 否 | 10000 |
-tf | --time_format | 表模型 SQL 文件按查询结果输出 ISO8601 时间;当前参数不会改变 SQL 中的时间格式 | 否 | ISO8601 |
-tz | --timezone | 设置时区;当前源码未将该值应用到表模型会话 | 否 | 本机时区 |
2.3.3 运行示例
# 正确示例
> export-data.sh -ft sql -sql_dialect table -t /path/export/dir -db database1 -start_time 1
# 异常示例
> export-data.sh -ft sql -sql_dialect table -t /path/export/dir -start_time 1
Parse error: Missing required option: db2.4 TsFile 格式
TsFile 适合大数据量迁移和数据库级离线归档。自动查询模式下,每张表生成一个 TsFile,并在文件中携带表结构信息。
2.4.1 运行命令
# Unix/OS X
tools/export-data.sh -ft tsfile -sql_dialect table -db <database> [-table <table>] \
[-start_time <start_time>] [-end_time <end_time>] [-h <host>] [-p <port>] [-u <username>] [-pw <password>] \
[-usessl <true|false>] [-ts <trust_store>] [-tpw <trust_store_password>] [-ks <key_store>] \
[-kpw <key_store_password>] [-ssl_protocol <ssl_protocol>] -t <target_directory> \
[-pfn <prefix_file_name>] [-q <query_command>] [-timeout <query_timeout>] [-mfs <rpc_max_frame_size>] \
[-dt <true|false>] [-tf <time_format>] [-tz <timezone>]
# Windows(V2.0.4.x 之前)
tools\export-data.bat -ft tsfile -sql_dialect table -db <database> [-table <table>] ^
[-start_time <start_time>] [-end_time <end_time>] [-h <host>] [-p <port>] [-u <username>] [-pw <password>] ^
[-usessl <true|false>] [-ts <trust_store>] [-tpw <trust_store_password>] [-ks <key_store>] ^
[-kpw <key_store_password>] [-ssl_protocol <ssl_protocol>] -t <target_directory> ^
[-pfn <prefix_file_name>] [-q <query_command>] [-timeout <query_timeout>] [-mfs <rpc_max_frame_size>] ^
[-dt <true|false>] [-tf <time_format>] [-tz <timezone>]
# Windows(V2.0.4.x 及之后)
tools\windows\export-data.bat -ft tsfile -sql_dialect table -db <database> [-table <table>] ^
[-start_time <start_time>] [-end_time <end_time>] [-h <host>] [-p <port>] [-u <username>] [-pw <password>] ^
[-usessl <true|false>] [-ts <trust_store>] [-tpw <trust_store_password>] [-ks <key_store>] ^
[-kpw <key_store_password>] [-ssl_protocol <ssl_protocol>] -t <target_directory> ^
[-pfn <prefix_file_name>] [-q <query_command>] [-timeout <query_timeout>] [-mfs <rpc_max_frame_size>] ^
[-dt <true|false>] [-tf <time_format>] [-tz <timezone>]2.4.2 私有参数
- 无
2.4.3 运行示例
# 正确示例
> /tools/export-data.sh -ft tsfile -sql_dialect table -t /path/export/dir -db database1 -start_time 0
# 异常示例
> /tools/export-data.sh -ft tsfile -sql_dialect table -t /path/export/dir -start_time 0
Parse error: Missing required option: db2.5 场景示例
2.5.1 场景选择
| 需求 | 推荐方式 | 范围指定方式 | 输出结果 |
|---|---|---|---|
| 导出数据库中的所有表 | CSV | 只指定 -db,不指定 -table | 每张表生成一个 CSV 文件 |
| 导出单张表的全部数据 | CSV | 指定 -db 和 -table,不指定时间范围 | 只生成指定表的 CSV 文件 |
| 按时间范围抽取单表原始数据 | CSV | 使用 -table、-start_time 和 -end_time | 可直接由 Excel、Python、Spark 等工具读取 |
| 按业务条件筛选部分列和数据行 | CSV | 使用 -q 编写自定义查询 | 只输出查询选中的列和数据 |
| 生成分时间窗口的设备统计报表 | CSV | 在 -q 中使用聚合函数和时间窗口 | 每个设备、每个时间窗口生成一行统计结果 |
| 按时间范围进行小规模迁移、修复或审计 | SQL | 使用 -table 和起止时间 | 生成可查看和执行的 INSERT INTO 语句 |
| 单表大批量迁移或离线归档 | TsFile | 使用 -table,需要时增加起止时间 | 生成携带表结构信息的二进制 TsFile |
2.5.2 准备数据
表中使用 plant_id、device_id 标识设备,model 保存设备属性,其他列保存时序数据。
CREATE DATABASE export_demo_table;
CREATE TABLE export_demo_table.machine_metrics (
plant_id STRING TAG,
device_id STRING TAG,
model STRING ATTRIBUTE,
temperature FLOAT FIELD,
status BOOLEAN FIELD,
remark STRING FIELD
);
CREATE TABLE export_demo_table.alert_events (
plant_id STRING TAG,
device_id STRING TAG,
severity INT32 FIELD,
message STRING FIELD
);
INSERT INTO export_demo_table.machine_metrics(time,plant_id,device_id,model,temperature,status,remark)
VALUES(1767225600000,'P01','D01','M-A',72.5,true,'normal');
INSERT INTO export_demo_table.machine_metrics(time,plant_id,device_id,model,temperature,status,remark)
VALUES(1767225660000,'P01','D01','M-A',75.0,true,'normal');
INSERT INTO export_demo_table.machine_metrics(time,plant_id,device_id,model,temperature,status,remark)
VALUES(1767225720000,'P01','D01','M-A',81.5,false,'high_temperature');
INSERT INTO export_demo_table.machine_metrics(time,plant_id,device_id,model,temperature,status,remark)
VALUES(1767225780000,'P01','D01','M-A',79.0,true,'recovered');
INSERT INTO export_demo_table.machine_metrics(time,plant_id,device_id,model,temperature,status,remark)
VALUES(1767225840000,'P01','D01','M-A',83.0,false,'high_temperature');
INSERT INTO export_demo_table.machine_metrics(time,plant_id,device_id,model,temperature,status,remark)
VALUES(1767225600000,'P01','D02','M-B',70.0,true,'normal');
INSERT INTO export_demo_table.machine_metrics(time,plant_id,device_id,model,temperature,status,remark)
VALUES(1767225660000,'P01','D02','M-B',71.5,true,'normal');
INSERT INTO export_demo_table.machine_metrics(time,plant_id,device_id,model,temperature,status,remark)
VALUES(1767225720000,'P01','D02','M-B',73.0,true,'normal');
INSERT INTO export_demo_table.machine_metrics(time,plant_id,device_id,model,temperature,status,remark)
VALUES(1767225780000,'P01','D02','M-B',76.5,true,'warming');
INSERT INTO export_demo_table.machine_metrics(time,plant_id,device_id,model,temperature,status,remark)
VALUES(1767225840000,'P01','D02','M-B',78.0,false,'inspection');
INSERT INTO export_demo_table.alert_events(time,plant_id,device_id,severity,message)
VALUES(1767225720000,'P01','D01',2,'temperature_high');
INSERT INTO export_demo_table.alert_events(time,plant_id,device_id,severity,message)
VALUES(1767225840000,'P01','D02',1,'inspection_required');执行以下查询可以查看原始数据:
USE export_demo_table;
SELECT time, plant_id, device_id, model, temperature, status, remark
FROM machine_metrics
ORDER BY device_id, time;查询结果如下,共 10 行:
| time | plant_id | device_id | model | temperature | status | remark |
|---|---|---|---|---|---|---|
| 2026-01-01T08:00:00.000+08:00 | P01 | D01 | M-A | 72.5 | true | normal |
| 2026-01-01T08:01:00.000+08:00 | P01 | D01 | M-A | 75.0 | true | normal |
| 2026-01-01T08:02:00.000+08:00 | P01 | D01 | M-A | 81.5 | false | high_temperature |
| 2026-01-01T08:03:00.000+08:00 | P01 | D01 | M-A | 79.0 | true | recovered |
| 2026-01-01T08:04:00.000+08:00 | P01 | D01 | M-A | 83.0 | false | high_temperature |
| 2026-01-01T08:00:00.000+08:00 | P01 | D02 | M-B | 70.0 | true | normal |
| 2026-01-01T08:01:00.000+08:00 | P01 | D02 | M-B | 71.5 | true | normal |
| 2026-01-01T08:02:00.000+08:00 | P01 | D02 | M-B | 73.0 | true | normal |
| 2026-01-01T08:03:00.000+08:00 | P01 | D02 | M-B | 76.5 | true | warming |
| 2026-01-01T08:04:00.000+08:00 | P01 | D02 | M-B | 78.0 | false | inspection |
alert_events 表包含 2 行告警数据,用于验证全库导出时不同表分别生成文件:
| time | plant_id | device_id | severity | message |
|---|---|---|---|---|
| 2026-01-01T08:02:00.000+08:00 | P01 | D01 | 2 | temperature_high |
| 2026-01-01T08:04:00.000+08:00 | P01 | D02 | 1 | inspection_required |
2.5.3 全库 CSV 导出
需要一次性抽取数据库中的全部表时,只指定 -db,不要指定 -table。工具会遍历数据库中的表,并为每张表生成一个 CSV 文件。
/tools/export-data.sh ^
-sql_dialect table -h 127.0.0.1 -p 6667 -u root ^
-ft csv -db export_demo_table ^
-t /export_demo_table/csv_all_tables -pfn all_tables -timeout 20000控制台对两张表均输出 Export completely!,生成以下文件:
| 文件 | 大小 | 数据行数 |
|---|---|---|
all_tables0_0.csv | 173 字节 | 2 |
all_tables1_0.csv | 768 字节 | 10 |
其中 all_tables0_0.csv 对应 alert_events,all_tables1_0.csv 对应 machine_metrics;文件序号按工具执行 show tables 返回的表顺序确定。
all_tables0_0.csv 内容如下:
time,plant_id,device_id,severity,message
2026-01-01T08:02:00.000+08:00,"P01","D01",2,"temperature_high"
2026-01-01T08:04:00.000+08:00,"P01","D02",1,"inspection_required"2.5.4 单表全量 CSV 导出
只需要某一张表的全部数据时,增加 -table,但不指定时间范围。
/tools/export-data.sh ^
-sql_dialect table -h 127.0.0.1 -p 6667 -u root ^
-ft csv -db export_demo_table -table machine_metrics ^
-t D/export_demo_table/csv_one_table -pfn machine_metrics -timeout 20000控制台输出 Export completely!,只生成 /export_demo_table/csv_one_table/machine_metrics0_0.csv,文件大小为 768 字节,包含 1 行表头和 10 行数据。
2.5.3 时间范围 CSV 导出
需要抽取单表指定时间范围内的原始数据时,使用 -table、-start_time 和 -end_time。起止时间形成闭区间。
/tools/export-data.sh ^
-sql_dialect table -h 127.0.0.1 -p 6667 -u root ^
-ft csv -db export_demo_table -table machine_metrics ^
-start_time 1767225660000 -end_time 1767225780000 ^
-t /export_demo_table/csv_range -pfn metrics_range -timeout 20000控制台输出 Export completely!,生成 /export_demo_table/csv_range/metrics_range0_0.csv,内容如下:
time,plant_id,device_id,model,temperature,status,remark
2026-01-01T08:01:00.000+08:00,"P01","D02","M-B",71.5,true,"normal"
2026-01-01T08:02:00.000+08:00,"P01","D02","M-B",73.0,true,"normal"
2026-01-01T08:03:00.000+08:00,"P01","D02","M-B",76.5,true,"warming"
2026-01-01T08:01:00.000+08:00,"P01","D01","M-A",75.0,true,"normal"
2026-01-01T08:02:00.000+08:00,"P01","D01","M-A",81.5,false,"high_temperature"
2026-01-01T08:03:00.000+08:00,"P01","D01","M-A",79.0,true,"recovered"2.5.4 条件筛选 CSV 导出
需要选择部分列并按照业务条件筛选数据时,使用 -q。下面只导出温度超过 80 的记录。
/tools/export-data.sh ^
-sql_dialect table -h 127.0.0.1 -p 6667 -u root ^
-ft csv -db export_demo_table ^
-t /export_demo_table/csv_filter -pfn high_temperature ^
-q "select time,plant_id,device_id,model,temperature,status,remark from machine_metrics where temperature > 80 order by time,device_id" ^
-timeout 20000指定 -q 后,时间条件也需要写入查询,-table、-start_time 和 -end_time 不参与查询构造。
控制台输出 Export completely!,生成 /export_demo_table/csv_filter/high_temperature0_0.csv,内容如下:
time,plant_id,device_id,model,temperature,status,remark
2026-01-01T08:02:00.000+08:00,"P01","D01","M-A",81.5,false,"high_temperature"
2026-01-01T08:04:00.000+08:00,"P01","D01","M-A",83.0,false,"high_temperature"2.5.5 聚合报表 CSV 导出
需要生成统计报表时,可以使用 CSV 导出聚合查询。下面按 2 分钟时间窗口分别统计两个设备的温度数据量和平均值。
/tools/export-data.sh ^
-sql_dialect table -h 127.0.0.1 -p 6667 -u root ^
-ft csv -db export_demo_table ^
-t /export_demo_table/csv_aggregate -pfn temperature_by_2m ^
-q "select date_bin(2m,time,2026-01-01T08:00:00) as window_start,device_id,count(temperature) as point_count,avg(temperature) as avg_temperature from machine_metrics group by 1,2 order by 1,2" ^
-timeout 20000控制台输出 Export completely!,生成 /export_demo_table/csv_aggregate/temperature_by_2m0_0.csv,内容如下:
window_start,device_id,point_count,avg_temperature
2026-01-01T08:00:00.000+08:00,"D01",2,73.75
2026-01-01T08:00:00.000+08:00,"D02",2,70.75
2026-01-01T08:02:00.000+08:00,"D01",2,80.25
2026-01-01T08:02:00.000+08:00,"D02",2,74.75
2026-01-01T08:04:00.000+08:00,"D01",1,83.0
2026-01-01T08:04:00.000+08:00,"D02",1,78.02.5.6 增量数据 SQL 导出
需要按时间范围进行小规模逻辑迁移、数据修复或人工审计时,可以导出 SQL。目标端需要提前创建结构兼容的数据库和表。
/tools/export-data.sh ^
-sql_dialect table -h 127.0.0.1 -p 6667 -u root ^
-ft sql -db export_demo_table -table machine_metrics ^
-start_time 1767225660000 -end_time 1767225780000 ^
-t /export_demo_table/sql_range -pfn metrics_range -timeout 20000控制台输出 Export completely!,生成 /export_demo_table/sql_range/metrics_range0_0.sql,内容如下:
insert into machine_metrics(time,plant_id,device_id,model,temperature,status,remark) values(2026-01-01T08:01:00.000+08:00,'P01','D02','M-B',71.5,true,'normal');
insert into machine_metrics(time,plant_id,device_id,model,temperature,status,remark) values(2026-01-01T08:02:00.000+08:00,'P01','D02','M-B',73.0,true,'normal');
insert into machine_metrics(time,plant_id,device_id,model,temperature,status,remark) values(2026-01-01T08:03:00.000+08:00,'P01','D02','M-B',76.5,true,'warming');
insert into machine_metrics(time,plant_id,device_id,model,temperature,status,remark) values(2026-01-01T08:01:00.000+08:00,'P01','D01','M-A',75.0,true,'normal');
insert into machine_metrics(time,plant_id,device_id,model,temperature,status,remark) values(2026-01-01T08:02:00.000+08:00,'P01','D01','M-A',81.5,false,'high_temperature');
insert into machine_metrics(time,plant_id,device_id,model,temperature,status,remark) values(2026-01-01T08:03:00.000+08:00,'P01','D01','M-A',79.0,true,'recovered');2.5.7 TsFile 迁移归档
需要单表大批量迁移或离线归档时,使用 TsFile。文件中携带表结构信息,适合后续加载到兼容实例。
/tools/export-data.sh ^
-sql_dialect table -h 127.0.0.1 -p 6667 -u root ^
-ft tsfile -db export_demo_table -table machine_metrics ^
-t /export_demo_table/tsfile -pfn machine_metrics -timeout 20000控制台输出 Export completely!,生成 /export_demo_table/tsfile/machine_metrics0.tsfile。TsFile 是二进制文件,不能像 CSV 或 SQL 一样直接展示数据行。
3. 基于 PIPE 框架的 TsFileBackup
IoTDB 自 V2.0.9.2 版本起支持 tsfile-backup.sh/bat 脚本,该脚本能够自动生成并向服务端发送 CREATE PIPE SQL 指令,将指定的数据文件导出为 TsFile 格式。
注意:
使用该脚本需联系天谋团队获取相关的 jar 包(
tsfile-remote-sink-<version>-jar-with-dependencies.jar),并放至 IoTDB 可访问的路径(例如所有数据节点主机)。该脚本支持 Object 类型数据导出为 TsFile 文件。
3.1 运行命令
# Unix/OS X
> tools/tsfile-backup.sh [-sql_dialect <sql_dialect>] [-h <host>] [-p <port>]
[-u <username>] [-pw <password>] [-path <path>] [-db <db>] [-table
<table>] [-s <start_time>] [-e <end_time>] [-t <target_directory>]
[-th <target_host>] [-tu <target_host_user>] [-tp <target_host_port>]
[--rate_limit] [--plugin_jar] [-help]
# Windows
> tools\windows\tsfile-backup.bat [-sql_dialect <sql_dialect>] [-h <host>] [-p <port>]
[-u <username>] [-pw <password>] [-path <path>] [-db <db>] [-table
<table>] [-s <start_time>] [-e <end_time>] [-t <target_directory>]
[-th <target_host>] [-tu <target_host_user>] [-tp <target_host_port>]
[--rate_limit] [--plugin_jar] [-help]3.2 脚本参数
| 参数缩写 | 参数全称 | 参数含义 | 是否为必填项 | 默认值 |
|---|---|---|---|---|
-sql_dialect | --sql_dialect | 指定数据模型类型,可选值:tree(树模型) 或table(表模型)。 | 是 | - |
-h | --host | 本地主机地址。指当前数据所在的 IoTDB 实例 IP。 | 否 | 127.0.0.1 |
-p | --port | 端口号,IoTDB RPC 服务端口。 | 否 | 6667 |
-u | --user | 用户名,用于登录 IoTDB 验证。 | 否 | root |
-pw | --password | 密码,对应用户的IoTDB密码,支持隐藏输入。 | 否 | root |
-t | --target | 导出目标目录。在 SCP 模式下,此路径指远程服务器上的绝对物理路径。TsFile 和关联的 Object 目录将导出至此。 | 是 | - |
-db | --database | 数据库名称 (表模型可选) | 否 | .* |
-table | --table | 表名 (表模型可选) | 否 | .* |
-s | --start_time | 起始时间。支持 ISO8601 格式(如 2026-01-01T00:00:00)或毫秒时间戳。仅导出该时间点及之后的数据。 | 否 | - |
-e | --end_time | 截止时间。格式同上。仅导出该时间点之前的数据。 | 否 | - |
-th | --target_host | 远程目标主机 IP,默认自动识别启动脚本的IP。指定此参数后,脚本将自动配置 Pipe 使用 SCP 模式进行数据传输。 | 否 | - |
-tu | --target_host_user | 远程主机用户名。用于 SSH/SCP 登录目标服务器。 | 否 | - |
-tpw | --target_host_pw | 远程主机密码。用于远程身份验证,支持隐藏输入。 | 否 | - |
-tp | --target_host_port | 远程 SSH 端口。 | 否 | 22 |
--rate_limit | --rate_limit | 发送速率限制。单位:字节/秒 (Bytes/s)。防止导出任务占用过多网络带宽。 | 否 | - |
--plugin_jar | --plugin_jar | 指定 Pipe 插件的Jar包路径 | 否 | - |
--object-parallelism | --object-parallelism | 指定object文件发送最大并行度 | 否 | - |
--object-batch-size | --object-batch-size | 限制每个对象文件上传批次的总字节数,用于控制内存占用和单次 SCP 传输大小 | 否 | - |
-help | --help | 查看帮助 | 否 | - |
3.3 运行示例
示例一:SCP 远程导出(-tpw 不跟值时隐藏输入密码)
./tsfile-backup.sh -sql_dialect table -db test_db -t /remote/archive/ \
-th 192.168.1.100 -tu backup_user -tpw示例二:带限速的远程 Object 数据导出
./tsfile-backup.sh -sql_dialect table -t /mnt/backup/ -th 10.0.0.5 \
-tu iot_admin -tpw --rate_limit 5242880示例三:指定 Pipe jar 目录
./tsfile-backup.sh -sql_dialect table -db test -table .* -t /tmp/backup \
--plugin_jar /local/lib/tsfile-remote-sink-<version>-jar-with-dependencies.jar注意:SCP 模式导出 Object 类型数据时,为避免出现握手异常、连接失败或 Pipe 频繁启停问题,建议采取以下任一措施:
适当调低配置参数 object-parallelism
按需调大目标机的 MaxStartups,修改后执行 sshd reload 或 sshd restart 使配置生效
4. Copy SQL
注意:该功能自 V2.0.11.1 版本起支持。
4.1 运行命令
// ---------------------------------------- Copy Statement ---------------------------------------------------------
copyToStatement
: COPY '(' query ')' TO fileName=string ((WITH)? copyToStatementOptions)?
| COPY tableName=qualifiedName ('(' tableColumns=identifierList ')')? TO fileName=string ((WITH)? copyToStatementOptions)?
;
copyToStatementOptions
: '(' copyToStatementOption (',' copyToStatementOption)* ')'
;
copyToStatementOption
: FORMAT identifier
| TABLE identifier
| TAGS '(' identifierList ')'
| TIME identifier
| MEMORY_THRESHOLD memory=INTEGER_VALUE
;参数介绍
| 名称 | 说明 | 默认值 |
|---|---|---|
| FORMAT | 导出格式,当前仅有 TsFile | TsFile |
| TABLE | 指定生成的 TsFile 中的 Table 名称 | 如果查询 SQL 仅涉及一个 table,使用这个 table 名,否则使用 default |
| TIME | 指定使用结果集中的哪一列作为 TIME 列。<br>手动指定时:列类型非 TIMESTAMP、找不到指定列均会报错;<br>未手动指定时:若存在列名 time 但类型非 TIMESTAMP 也会报错。<br>按以下优先级构造 time 列:<br>1. 查询仅涉及的一个 table 中的 time 列名称相同的列<br>2. 寻找列名为 "time" 且类型为 TIMESTAMP 的列作为时间列<br>3. 使用对应 device 写入的当前行数作为 time 生成时间列,列名为 "time" | - |
| TAGS | 指定哪些列为 TAG 列,有多个 TAG 列时,最终生成的 table 内的顺序和指定的顺序一致。<br>手动指定时:列不存在、列类型非 STRING、存在重复列名均会报错。<br>如果查询仅涉及一个 table,且 table 所有 tag 列在查询结果集中可以找到,则推断为这个 table 的 tag 列,否则默认值为空列表,即除了 TIME 列以外其余所有列都被视为 FIELD 列 | 空列表 |
| MEMORY_THRESHOLD | 用于在生成 TsFile 时进行内存控制(单位:byte),手动指定数值小于等于 0 时将报错 | 32MB |
结果集说明
| 列名 | 数据类型 | 说明 |
|---|---|---|
| path | STRING | 生成的目标文件的绝对路径 |
| row_count | INT64 | 总写入行数 |
| device_count | INT64 | 生成的设备数量 |
| size_in_bytes | INT64 | 生成的目标文件大小 |
| table_name | STRING | 目标文件中的表名,如果是自动生成的,会通过 (auto_gen) 进行标记 |
| time_column | STRING | 目标文件中的表的 time 列名,如果是自动生成的,会通过 (auto_gen) 进行标记 |
| tag_columns | STRING | 目标文件中的表的 tag 列名,以 , 分隔 |
其他注意事项
对于文件生成位置:
如果指定的是文件名,生成的 TsFile 保存在客户端直连的 DataNode 的
${dn_data_dirs}/copy_to下,配置多个目录时,按照配置项dn_multi_dir_strategy的策略生成;如果指定的是一个路径,则放在指定的路径下。
执行过程中可能出现的异常:
按照给定的 schema 写入 TsFile,存在乱序时间戳时报错
非法文件名或目标文件已存在时报错
查询结果中存在重复列名
磁盘空间不足
4.2 运行示例
以[示例数据](../Reference/Sample-Data.md)中 table1 为例
- 通过 select 语句将 table1 中的全部数据导出到文件 copysql1.tsfile
TimechoDB:database1> copy (select * from table1) to 'copysql1.tsfile'
+-----------------------------------------------------+---------+------------+-------------+----------+-----------+-----------------------------+
| path|row_count|device_count|size_in_bytes|table_name|time_column| tag_columns|
+-----------------------------------------------------+---------+------------+-------------+----------+-----------+-----------------------------+
|/timechodb/data/datanode/data/copy_to/copysql1.tsfile| 18| 6| 4636| table1| time|[region, plant_id, device_id]|
+-----------------------------------------------------+---------+------------+-------------+----------+-----------+-----------------------------+
Total line number = 1
It costs 0.336s- 通过表名将 table1 中的全部数据导出到文件 copysql2.tsfile
TimechoDB:database1> copy table1 to 'copysql2.tsfile'
+-----------------------------------------------------+---------+------------+-------------+----------+-----------+-----------------------------+
| path|row_count|device_count|size_in_bytes|table_name|time_column| tag_columns|
+-----------------------------------------------------+---------+------------+-------------+----------+-----------+-----------------------------+
|/timechodb/data/datanode/data/copy_to/copysql2.tsfile| 18| 6| 4636| table1| time|[region, plant_id, device_id]|
+-----------------------------------------------------+---------+------------+-------------+----------+-----------+-----------------------------+
Total line number = 1
It costs 0.048s- 通过表名(列)的方式将 table1 中的部分数据导出到文件 copysql3.tsfile
TimechoDB:database1> copy table1 (device_id,temperature) to 'copysql3.tsfile'
+-----------------------------------------------------+---------+------------+-------------+----------+--------------+-----------+
| path|row_count|device_count|size_in_bytes|table_name| time_column|tag_columns|
+-----------------------------------------------------+---------+------------+-------------+----------+--------------+-----------+
|/timechodb/data/datanode/data/copy_to/copysql3.tsfile| 18| 1| 558| table1|time(auto_gen)| []|
+-----------------------------------------------------+---------+------------+-------------+----------+--------------+-----------+
Total line number = 1
It costs 0.064s- 通过 select 语句将 table1 中部分数据的聚合结果导出到文件 copysql4.tsfile
TimechoDB:database1> copy (select count(temperature), count(humidity) from table1 group by device_id) to 'copysql4.tsfile'
+-----------------------------------------------------+---------+------------+-------------+----------+--------------+-----------+
| path|row_count|device_count|size_in_bytes|table_name| time_column|tag_columns|
+-----------------------------------------------------+---------+------------+-------------+----------+--------------+-----------+
|/timechodb/data/datanode/data/copy_to/copysql4.tsfile| 2| 1| 543| table1|time(auto_gen)| []|
+-----------------------------------------------------+---------+------------+-------------+----------+--------------+-----------+
Total line number = 1
It costs 0.155s- 通过 select 语句将 table1 中的部分数据导出到文件 copysql5.tsfile ,并指定目标表、time列及 tag 列
TimechoDB:database1> copy (select time,region,device_id,temperature from table1 order by time) to 'copysql5.tsfile' (TABLE copytable, TIME time, TAGS (region,device_id))
+-----------------------------------------------------+---------+------------+-------------+----------+-----------+-------------------+
| path|row_count|device_count|size_in_bytes|table_name|time_column| tag_columns|
+-----------------------------------------------------+---------+------------+-------------+----------+-----------+-------------------+
|/timechodb/data/datanode/data/copy_to/copysql5.tsfile| 18| 4| 1199| copytable| time|[region, device_id]|
+-----------------------------------------------------+---------+------------+-------------+----------+-----------+-------------------+
Total line number = 1
It costs 0.047s