使用SELECT INTO OUTFILE OBS命令导出数据
操作场景
您可以使用 SELECT INTO OUTFILE OBS 语句从TaurusDB数据库中查询数据,并将数据保存到OBS桶中存储的文本文件。文件首先存储到本地临时盘上,然后导出到OBS。导出完成后,将删除本地文件。
该语句仅将表数据导出为文本文件,不会导出表结构。
前提条件
- 开启导入导出功能,需打开参数开关rds_load_from_obs_enable,修改参数值为ON。参数修改请参见修改TaurusDB实例参数。
- 执行导出的用户必须有对应库表的 SELECT和FILE权限。
- 您必须先为TaurusDB数据库集群授予OBS的访问权限,然后才能从OBS存储桶中加载数据。
- 如果用户通过主账号开启加载OBS存储桶,不需要任何额外配置。如果是IAM子用户并且是第一次操作开启加载OBS存储桶,则需要给子用户临时配置创建委托的权限。
- 加载OBS存储桶时必须拥有如下IAM权限:
表1 IAM权限与委托 IAM策略
IAM权限
委托
基于角色或策略
- iam:agencies:listAgencies
- iam:agencies:createAgency
- iam:permissions:listRolesForAgencyOnProject
- iam:permissions:grantRoleToGroupOnProject
- iam:permissions:grantRoleToAgencyOnProject
- iam:roles:listRoles
- iam:roles:createRole
如不满足,请创建自定义策略。
会自动创建委托DbsObsLoadAgency,该委托用户可见,删除委托会导致加载OBS存储桶失败。
基于身份策略
iam:agencies:list
如不满足,请创建自定义身份策略。
需要手动创建DbsObsLoadAgency委托。如果您已创建过委托,可跳过。
约束限制
- 导出到OBS桶的文件数量取决于SELECT INTO OUTFILE OBS语句选择的数据量以及OBS文件大小阈值。OBS默认的文件大小阈值约为6GB。
- 数据量 < 阈值:生成单个OBS文件。
- 数据量 ≥ 阈值:需设置MANIFEST=ON,系统自动创建多个OBS文件,并自动生成清单文件。
- TaurusDB保证数据文件中的行记录不会跨文件边界拆分。系统会尽量使每个数据文件(除最后一个外)的大小接近预设阈值。为确保行数据完整性,当一行数据超出当前文件剩余空间时,整行数据也会完整写入到当前文件,此时文件大小会大于文件大小阈值。
- 如果要选择的数据量很大(超过25GB),建议您使用多个SELECT INTO OUTFILE OBS语句,将数据导出到OBS中。
每个语句应选择不同部分的数据来保存,并且在保存数据文件时OBS-URI中使用不同的object对象名。使用多个语句对数据进行分段导出,可以便于快速恢复,避免长时间运行的单个大事务,减少对数据库性能的影响。
若某条导出语句出错,只需重新执行该部分数据,无需重新导出全部数据。
- 如果多个SELECT INTO OUTFILE OBS中 OBS_URI 相同,并且是并行执行这些语句,则导出行为是不确定的,部分SQL语句会执行失败,只有一个SQL会执行成功。
- 如果重新运行中断的SELECT INTO OUTFILE OBS语句,需先删除OBS桶中与OBS_URI相同的文件,或使用SELECT INTO OUTFILE OBS OVERWRITE ON语句进行覆盖。
- 如果OBS桶中存在与 OBS-URI 相同的文件,导出时会报“文件已存在”,此时您可以修改OBS-URI对象名为不重复的对象名,或删除OBS文件,或配置OVERWRITE ON。
- 当前不支持查询导出进度,但可以通过导出到OBS的文件大小与所选数据量的数据大小对比,估算导出进度。
- 执行SELECT INTO OUTFILE OBS时,如果发生crash,需手动清理OBS残留文件。
- 语法树中的所有参数项有顺序要求,调转顺序会报语法错误。
- 导出时,文件名不能以 .manifest结尾,因为导出清单文件时默认使用此关键字,避免冲突。
手动创建DbsObsLoadAgency委托
使用SELECT INTO OUTFILE OBS导出数据
- 语法介绍
SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] select_expr [, select_expr ...] [FROM table_references [PARTITION partition_list] [WHERE where_condition] [GROUP BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]] [HAVING where_condition] [ORDER BY {col_name | expr | position} [ASC | DESC], ...] [LIMIT {[offset,] row_count | row_count OFFSET offset}] INTO OUTFILE OBS 'OBS_URI' [CHARACTER SET charset_name] [export_options] [MANIFEST {ON | OFF}] [OVERWRITE {ON | OFF}]export_options:
[FORMAT {CSV|TEXT} [HEADER]] [{FIELDS | COLUMNS} [TERMINATED BY 'string'] [[OPTIONALLY] ENCLOSED BY 'char'] [ESCAPED BY 'char'] ] [LINES [STARTING BY 'string'] [TERMINATED BY 'string'] ]SELECT INTO OUTFILE OBS语句使用以下特定的必需和可选参数。更多参数请参考MySQL官方文档 。
- FORMAT {CSV|TEXT}:指定导出文件的格式,CSV或TEXT格式。
- HEADER:指定导出文件包含一个标题行,标题与SELECT语句中的列名相对应。
- select_expr:要查询并导出的列或表达式。
- OBS_URI:OBS文件地址,格式固定为obs://bucket/object。
- bucket:要将数据保存到的OBS桶的名称。
- object:指定要保存到OBS的文件的名称。
- MANIFEST {ON | OFF}:指示是否创建清单文件。字段可选,默认为OFF。
如果在查询中指定 MANIFEST ON,则会在创建并上传所有数据文本文件后,在 OBS中自动创建JSON格式的清单文件,文件内容包含所有已上传的文本文件的url。
文件名会添加`.part_xxxxx`后缀,其中xxxxx为五位整数,如:`obs://bucket/object.part_00000`。
清单文件路径为:`obs://bucket/object.manifest`。
清单文件是JSON格式文件,此文件列出了要加载到数据库的表的文本文件。其格式和内容如下:
{ "entries": [ { "url": "obs://bucket/customermeta", "mandatory": true }, { "url": "obs://bucket/customerdata", "mandatory": true } ] } - OVERWRITE {ON | OFF}
指示上传到OBS时,是否覆盖桶中现有文件。如果指定OVERWRITE ON,则会覆盖相同URI的文件,否则重复文件会报错。
- FIELDS 和 COLUMNS:可选参数。指定字段格式。
- TERMINATED BY:指定字段间的分隔符,默认是 \t。
- ENCLOSED BY:指定字段值的封装字符,如果使用OPTIONALLY,则只封装字符类型字段;若不指定,则封装所有字段。
- ESCAPED BY:指定转义字符,默认为反斜杠"\"。
- LINES:可选参数。指定行格式。
- STARTING BY:指定每行数据忽略的前缀字符串。
- TERMINATED BY:指定行终止符,默认为换行符"\n"。
- 参考示例
- 导出单个文件。
将TaurusDB数据库中test库下的t表导出到OBS上bucket桶中的t.txt文本文件中。
SELECT * FROM test.t into OUTFILE OBS "obs://bucket/t.txt";
- 导出清单文件。
- 将TaurusDB数据库中的t表数据,导出到OBS上bucket桶中的test.part_00000、test.part_00001等数据文件中,并生成test.manifest清单文件。
SELECT * FROM t into OUTFILE OBS "obs://bucket/test" MANIFEST ON;
- 将bucket桶中同名的文件全部覆盖,包括test.part_00000等数据文件,和test.manifest清单文件。
SELECT * FROM t into OUTFILE OBS "obs://bucket/test" MANIFEST ON OVERWRITE ON;
- 将TaurusDB数据库中的t表数据,导出到OBS上bucket桶中的test.part_00000、test.part_00001等数据文件中,并生成test.manifest清单文件。
- 复杂导出语句示例。 如下SQL语句从特定的分区表中提取去重后的已完成订单,进行分组统计(带 ROLLUP 总计)和降序排列,最后以标准 CSV 格式导出到 OBS。该语句开启了覆盖模式和清单记录。
SELECT DISTINCT -- 过滤重复 HIGH_PRIORITY -- 优化器高优先级 id, user_name, order_amount FROM orders PARTITION (p2023, p2024) -- 仅导出指定分区 WHERE order_status = 'COMPLETED' GROUP BY id, user_name, order_amount ASC WITH ROLLUP -- 分组排序并生成聚合统计行 HAVING order_amount > 100 ORDER BY order_amount DESC LIMIT 1000 -- 只取前1000条 INTO OUTFILE OBS 'obs://bucket/export/order_report/' CHARACTER SET utf8mb4 -- 指定字符集 FORMAT CSV HEADER -- CSV格式带表头 FIELDS TERMINATED BY ',' -- 逗号分隔 OPTIONALLY ENCLOSED BY '""' -- 字符串用双引号 ESCAPED BY '\\' -- 反斜杠转义 LINES STARTING BY '' -- 行无前缀 TERMINATED BY '\n' -- 换行符 MANIFEST ON -- 生成清单文件 OVERWRITE ON; -- 允许覆盖旧文件
- 包含更多关键字示例。
从users表和orders表中,强制以users表为驱动进行连接,并按照用户 ID 分组(附带总计行)去重后,将结果以竖线分隔、带表头的文本格式导出到OBS存储,同时生成清单文件并覆盖已有文件。
SELECT DISTINCTROW -- 同 DISTINCT,指定从结果集中移除重复行 SQL_SMALL_RESULT -- 告诉优化器结果集很小,直接用内存临时表 SQL_CALC_FOUND_ROWS -- 指示计算结果集中的行数,且不考虑任何 LIMIT 子句。随后可通过 SELECT FOUND_ROWS() 获取行数 STRAIGHT_JOIN -- 强制表连接顺序,users 表作为驱动表,orders表作为被驱动表 u.user_id, o.order_no FROM users u JOIN orders o ON u.user_id = o.user_id WHERE u.status = 'active' GROUP BY u.user_id DESC WITH ROLLUP -- 产生小计/总计行,即在按用户ID分组统计的基础上,额外增加一行总计行 INTO OUTFILE OBS 'obs://bucket/full_test/data_' CHARACTER SET gbk -- 指定字符集为 gbk FORMAT TEXT HEADER -- 文本格式带表头 COLUMNS TERMINATED BY '|' OPTIONALLY ENCLOSED BY ""'"" ESCAPED BY '!' -- 使用感叹号作为转义符 LINES STARTING BY '>>>' -- 每行开头都加上前缀 TERMINATED BY '\r\n' -- Windows 风格换行符 MANIFEST ON OVERWRITE ON;
- 导出单个文件。
常见错误信息
导入文本文件时,错误信息中包含的OBS Error错误码具体含义如下:
| 错误码 | 错误信息 | 处理措施 |
|---|---|---|
| HttpErrorNotFound | 对象不存在 | 请检查OBS桶中对象是否存在。 |
| InvalidAccessKeyId | AK不合法 | SQL执行时间过长,临时AK已过期。建议避免单次导出过大数据量。 |
其他常见OBS错误码,请参见OBS错误码。


