通过 select into outfile / load data infile 进行数据导入导出学习笔记

OceanBase 内核自带的功能,无需额外维护更多工具,并且易用性也足够好。

OceanBase 数据库支持使用 SQL 语句的方式将数据库中数据导出到外部文件和向数据库中插入数据。

通过 load data 导入数据文件

字符集和编码

在通过 load data 导入数据之前,建议了解字符集和字符的编码原理,以避免在数据导入后读数据时出现乱码。编码和解码使用不同的规则,或者字符集不匹配将导致乱码 。导入数据文件出现乱码,可能是数据存储正确但是读取的编码不正确,·也可能是数据存储时编码不正确。从数据文件自身到读取数据文件、写入到 OceanBase 数据库,每个环节的字符集设置均影响最终数据的正确性。

数据文件的字符集

请确保数据文件使用正确的字符集。在导出数据文件时,推荐以 UTF8 格式保存 ,这样大部分的字符(特别是中文字符 )都能在文件中正确保存。如果数据内容包含表情字符 等,在导出数据文件时,推荐以 UTF8MB4 格式保存。

以 Linux 环境为例,查看文件的编码:

客户端的字符集

请确保客户端能正确读取数据文件。

可以在 Windows、Linux 或国产操作系统使用图形化工具。如果使用的是 Linux 系统,请确保 Linux 系统支持目标字符集 。使用命令 locale -m 查看系统可用的字符编码方案 。GBK 或 UTF-8 均支持中文。推荐使用 UTF-8。如果操作系统不支持 GBK 或 UTF-8,需要安装简体中文对应的语言包 。然后在Shell 环境下设置环境变量 LANG 为 GBK 或 UTF-8 。终端的编码将决定终端中输入中文字符后转换的编码,以及读取中文内容时显示的编码。使用以下方式设置会话的显示语言和编码:

注意

请确保操作系统的语言包含目标字符集(如简体中文),并且 OceanBase 图形化客户端工具也支持目标字符集。推荐将编码设置为 UTF-8。

OceanBase 租户的字符集

请确保 OceanBase 租户的字符集支持目标字符集 。可以在创建租户时指定租户的字符集 。推荐将字符集设置为 UTF8MB4 。这样在任何一个客户端环境出现中文乱码的概率最低,因为上文已建议将客户端操作系统以及客户端工具的字符集编码均设置为 UTF-8。如果使用的是 MySQL 租户,在创建数据库或者建表时可以改变字符集。MySQL 的字符集参数比较复杂,推荐将 MySQL 模式的租户的字符集设置为 UTF8MB4。以下示例新建了一个 MySQL 租户,字符集选择 GBK。GBK 支持中文正常读写。

说明此示例仅为说明原理。生产中不常用。

租户字符集选择了 GBK,上文提到客户端程序以及 Linux 环境变量中的字符集编码均设置为 UTF-8(因为 UTF-8 能兼容 GBK)。

假设还想创建一个字符集是 utf8mb4 的数据库 test2。

obclient [test]> CREATE DATABASE test2 CHARACTER SET = utf8mb4;
Query OK, 1 row affected (0.084 sec)

obclient [test]> use test2;
Database changed

obclient [test]> create table t1(id bigint,c1 varchar(50));
Query OK, 0 rows affected (0.292 sec)

obclient [test]> 
obclient [test]> insert into t1 values(1,'中');
Query OK, 1 row affected (0.028 sec)

obclient [test]> 
obclient [test]> show full columns from t1;
+-------+-------------+--------------------+------+-----+---------+-------+---------------------------------+---------+
| Field | Type        | Collation          | Null | Key | Default | Extra | Privileges                      | Comment |
+-------+-------------+--------------------+------+-----+---------+-------+---------------------------------+---------+
| id    | bigint(20)  | NULL               | YES  |     | NULL    |       | SELECT,INSERT,UPDATE,REFERENCES |         |
| c1    | varchar(50) | utf8mb4_general_ci | YES  |     | NULL    |       | SELECT,INSERT,UPDATE,REFERENCES |         |
+-------+-------------+--------------------+------+-----+---------+-------+---------------------------------+---------+
2 rows in set (0.013 sec)

obclient [test]> 
obclient [test]> select id,c1,hex(c1) from t1;
+------+------+---------+
| id   | c1   | hex(c1) |
+------+------+---------+
|    1 | 中   | E4B8AD  |
+------+------+---------+
1 row in set (0.004 sec)

obclient [test2]> SHOW VARIABLES LIKE '%character%';
+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| character_sets_dir       |         |
| character_set_client     | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database   | utf8mb4 |
| character_set_filesystem | binary  |
| character_set_results    | utf8mb4 |
| character_set_server     | utf8mb4 |
| character_set_system     | utf8mb4 |
+--------------------------+---------+
8 rows in set (0.005 sec)

从返回结果看出,虽然租户字符集是 GBK,但是有多个字符集变量值是跟随客户端环境的,值为utf8mb4.

变量的作用如下:

  • character_set_client:客户端发送的查询数据的字符集。
  • character_set_connection:客户端与服务器连接时的数据字符集
  • character_set_results:服务器返回给客户端结果时使用的字符集。
  • character_set server:服务器存储数据时使用的字符集
  • character_set_results 决定查询结果集中的数据编码方式。

character set results 默认与character set connection 保持一致。也可以单独设置 character set results,以在返回数据时使用不同的字符集。

上述示例未出现乱码。如果在导入数据过程中遇到了乱码,请参考上述示例分析哪个环节的字符集编码设置不正确,从而导致字符数据传输过程中发生了编码转换错误。要识别是不是转换错误,需要关注显示的字符以及字符对应的编码。在 MySQL 租户中使用 hex 系统函数查看。在 Linux Shell 中使用 xxd 命令查看。

数据导入准备

为提高导入性能,请确保待导入数据的目标表除了主键外,不包含索引和其他约束 。可以在数据导入成功后创建索引和约束 。但是,如果数据文件是目标表的增量数据,且表包含唯一约束或索引,必须提前建好约束或索引。

数据导入方案

数据导入方案跟数据文件格式和位置有关。常见数据文件格式为 SQL和 CSV。SQL 文件包括 DDL 和

DML

SQL 文件导入

SQL 文件可能包含 DDL和 DML。推荐将 DDL 和 DML 文件分开 。可以通过 OceanBase 的客户端命令 obclient 调用执行 SQL 文件。如果使用的是 MySQL 租户,也可以使用 mysql 调用执行 。此外,有些图形化客户端工具,例如 ODC 和 DBeaver,也可以执行 SQL 文件。例如,使用以下命令执行 SQL 文件:

CSV 文件导入

可以使用 SQL命令 load data[local]infile 导入 CSV 文件。

在导入 CSV 文件之前,请检查:

  • CSV 文件格式是否正确。

  • 文件首行是否包含列名。

    • 请确保数据导入到对应的列。如果数据错位,可能会因为类型不对而报错。如果数据文件中的列跟目标列无法映射,需要在导入命令中指定列映射(如果使用的是load data,需要指定列名)。
  • 导入数据时允许的最大报错行数。

    • 如果报错数量超出允许的最大报错行数,数据导入将报错
  • 日期和时间类型数据的格式。

    • 在导入日期和时间类型 的数据时,需要将 OceanBase 数据库的时间格式变量(如 MySQL 租户的 datetime_format 和 time_format)调整为与数据文件的时间列格式,以避免时间数据(字符串格式)写入到时间列(如 date、time 或 datetime 等)类型转换报错。load data 命令不支持对列使用预处理函数

如果 CSV 文件位于 OceanBase 租户数据所在的服务器节点上 ,可以直连 OBServer 节点并使用 load data infile 命令从服务器端加载文件在导入之前,还需要通过 socket 直连到 OBServer 节点并设置租户全局变量 secure_file_priv 值这个值是一个目录,它必须包含需要导入的文件目录。 以下是通过 OceanBase 业务租户的任意一个 OBServer 节点上的 socket 文件直连的示例。

如果 CSV 文件不在 OceanBase 租户所在的服务器节点,而在客户端所在的节点上,则可以使用命令load data local infile 命令从客户端加载文件。 obclient 在启动的时候需要带上参数 --local-infile 以启用加载本地数据的功能。

示例命令如下:

如果 CSV 文件位于对象存储 ,可以通过 ODP 连接租户并使用命令 load data remote_oss infile 命令从对象存储中加载文件。 对象存储目前支持阿里云OSS (地址协议头:oss://)、腾讯云COS (地址协议头:cos://)和 S3 协议的对象存储(地址协议头:s3://)。需要在对象存储的路径里指定访问地址(host)、访问账户(accessid)和访问密码(access key) 此外,如果 CSV 文件位于对象存储**,还可以在 OceanBase 数据库中创建基于这组 CSV 文件的外部表,** 通过外部表直接读取 CSV 内容,然后通过INSERT INTO . SELECT…FROM.命令将 CSV 文件读取到目标表中。

在使用 load data 导入数据时,如果目标表已有存在数据(有主键或唯一键),使用参数 replace 或ignore 设置是替换数据还是忽略新数据。如果没有主键或唯一键,可以忽略两个参数。 数据导入中报错的数据会记录到 obloaddata.log.日志文件中,日志文件默认会在 OceanBase 软件目录下的 log 目录 (/home/admin/oceanbase/log/)中。 大批量的导入任务也会导致这个目录下日志文件增多。如果有大量导入报错,请留意这个日志文件的大小。

性能调优

针对大规模数据导入(>100G)的性能优化需要采取灵活的平衡策略。导入速度过慢会延长等待时间,影响业务进度,而导入速度过快可能造成 OceanBase 资源过度消耗。建议在保证系统稳定的前提下优化导入性能。此处的资源分为三类:CPU、内存和磁盘。

CPU 资源分析和优化

同一个租户内部默认所有会话的 CPU 资源使用是平等的,在 CPU 调度上,OceanBase 租户会将队列分为两个:一个用于满足快的 SQL 请求,一个用于满足慢的 SQL 请求

快和慢的分界点是集群参数 large_query_threshold(默认值是 5s) 。慢队列的 CPU 使用比例上限由集群参数 large_query_worker_percentage(默认值是 30,表示 30%)决定。在 OceanBase 数据库V4.X 版本中,默认使用 cgroup 做租户之间的 CPU 资源隔离。在某些客户场景里,可能会关闭cgroup 功能。此时通过集群参数 enable_cgroup 来控制。这个参数设置为 false 的时候,就退回到OceanBase V4.0 以前的版本资源隔离方式。 数据导入会话使用的是目标租户的 CPU 资源。在不开启并行导入的情况下,就是个单线程会话,对租户 CPU使用不会很大(跟其他业务会话公平竞争)。

内存资源分析和优化

在使用 OceanBase 数据库时,需要关注租户的内存管理机制每个租户的所有会话分配的总内存都受限于其内存配额 。当数据导入速度过快时,会导致单位时间内的内存消耗剧增,从而挤压了业务事务可用的内存空间。虽然 OceanBase 的 MemStore(写内存)管理机制具有一定的灵活性,当内存使用超过预设的 freeze_trigger_percentage 阈值时系统会自动将部分数据冻结并转储到磁盘,释放内存空间。 但是,如果数据写入速度远超过内存转储速度,MemStore 的使用率仍可能趋近 100%。这种情况下,业务事务和数据导入会话都可能遇到 -4002 错误。同时,数据导入任务也会报错。为了及时发现潜在问题,建议持续监控租户的 MemStore 内存使用情况。推荐使用 OCP 监控租户性能的 MemStore 指标图。

OceanBase 数据库提供写入限速功能

写入限速通过writing_throttling_trigger_percentage 和 writing_throttling_maximum_duration(默认为 2 小时)控制。

在 V4.2 和 V4.3 版本中,由于 writing_throttling_trigger_percentage 的默认值为 100,这一保护机制实际上并未发挥作用。为了预防 MemStore 内存耗尽,推荐将该参数值调整至 90 左右。具体的参数设置可以根据租户内存大小灵活调整。内存较大的租户可以适当提高这个值,而内存较小的租户则应该相应降低。参数的最终设定应当基于对数据导入时内存消耗速度的合理评估。

数据导入性能调优的核心方法之一是优化内存 MemStore 相关参数:

  • writing_throttling_trigger_percentage:控制数据转储的触发阈值。较大的转储量会增加 IO 开销导致写入性能出现较大波动且持续时间更长。过早转储可以预留更多内存空间,但会增加转储频率造成资源浪费。推荐根据业务负载特点设置合适的阈值。
  • writing_throttling_trigger_percentage:决定写入限速的触发点。设置过低会导致过度限速,影响写入性能并浪费内存资源。设置过高可能引发内存不足错误。推荐通过压测确定最优值,在性能和稳定性之间取得平衡。
  • memstore limit:用于控制租户内存中 MemStore 的占比,默认为 50。写密集型业务可适当提高此值。

注意

  • 参数调整会影响所有租户,需要全局评估。
  • 对于小内存(小于 8G)租户,大型查询可能挤占 MemStore 空间导致参数失效。

磁盘资源分析和优化建议

OceanBase 数据库在转储过程中会将内存数据写入磁盘文件,默认采用Iz4 压缩算法。系统每天执行一次 Major Freeze 合并操作,将最近 24 小时的内存增量数据、磁盘增量数据以及上一次合并的基线数据进行合并,生成新的基线版本。这些操作会占用磁盘空间,且由于数据多版本存储特性可能导致空间放大。虽然合并操作仅针对发生变化的数据块,但在进行大批量数据导入时,仍可能造成大量的数据合并,从而导致数据文件存储空间暂时增长。如果数据文件剩余空间不足,系统将报告空间错误。

OceanBase 数据库支持通过 datafile_maxsize 和 datafile_next 参数控制数据文件自动扩展。

在 OCP 默认部署的集群中,这两个参数未配置。因此对于初始配置较小的数据文件(datafile size)推荐在文件系统空间充足的情况下启用自动扩展功能。而对于初始配置较大的数据文件则无需此设置。这也是企业级部署的典型特征:配置大容量初始数据文件并关闭自动扩展。

在转储和合并过程中,系统使用不同的压缩算法。转储过程生成的中间版本数据块采用1z4 算法,而合并后的最终版本数据块使用 zstd 算法 。由于 1z4 算法的压缩比相对较低(但 CPU 资源消耗较少),中间数据会占用更多存储空间。因此在评估系统所需剩余容量时,需要考虑这一因素带来的临时空间增长。

可以使用 OCP 查看 OceanBase 的租户空间,但是 OCP 有延迟。也可以在集群的 sys 租户下,使用以下 SQL 实时查看一个表在所有节点上所有版本的数据大小。

还需要关注数据导入对磁盘性能的影响。这种影响体现在两个方面:内存数据转储和合并过程中的顺序写 IO,这种操作是间歇性的。OceanBase 事务日志(ciog)的持续化也是顺序写小IO。当数据文件和事务日志文件部署在 NVMe SSD 存储上时,可以忽略 IO 影响。如果发现 IO 压力过大,可以通过降低数据导入速度来缓解。OCP 提供实时磁盘 IO性能监控,可以据此进行精确评估和调整。

参数建议

OceanBase 集群参数经验值:

说明:在数据导入后,将系统变量和参数务必重新修改为默认值

并行导入

提升数据导入效率的主要方法是增加并发度,load data 命令支持通过 hint /*+ PARALLEL(n) /设置并行度为 n,可以与旁路导入 的 hint /+ APPEND */ 配合使用。

旁路导入

OceanBase 数据库支持旁路导入。旁路导入有如下特点:

1.绕过常规 SQL 层的大部分接口。

2.数据直接写入数据文件,而不经过租户的 MemStore 内存。

3.通过 KV Cache 中的内存缓冲区写入数据文件

4.由于写入路径更短,在大批量数据插入时性能更好,

当执行旁路导入时,客户端程序(obclient 或Java 程序等)需要通过 OBServer 的 RPC 端口(默认2882)发送 SQL。当使用 OBProxy 转发连接时,需要同时开通 OBProxy 的 RPC 端口(默认2885)。虽然也可以通过负载均衡设备访问并开通 OBProxy的 RPC 端口转发,但由于旁路导入会产生大量网络流量,可能影响其他应用的网络带宽使用,因此推荐大批量数据导入时直接连接固定的OBProxy。

为 obclient 命令行下 INSERT SQL 或 load data 开启旁路导入,需要添加以下 Hint:

  • append:等效于 direct(true,0)。同时可以在线收集统计信息,相当于GATHER OPTIMIZER STATISTICS。
  • direct(bool,int,[load mode]:bool 表示数据写入时是否排序(true:数据排序;false:数据不排序)。int 表示最大容忍报错行数。load_mode 可选,表示导入式,默认值 ful 表示全量导入,新增功能值 inc 表示增量导入(支持 insert ignore),新增功能值(inc_replace)表示增量导入,但不检查主键重复,相当于replace(跟 ignore 冲突)
  • enable_parallel_dml parallel(N):可选,表示加载数据的并行度,是使用旁路导入示例

在 V4.3.5 版本中,OceanBase 数据库支持在租户全局级别设置默认数据加载模式,这样上面 SQL 就不用写旁路导入相关的 Hint。

重新登录,再执行以下 SQL,就会自动进行旁路导入。

旁路导入不使用 MemStore 而是使用独立的内存空间 ,因此与普通数据导入的内存使用特点有所不同。在使用旁路导入时,需要确保分配足够的 KV Cache 内存,以防出现内存不足。另外,由于旁路导入会直接写入数据文件且数据压缩比较低,因此数据文件会快速增长,建议提前预留充足的数据文件存储空间。

注意:旁路导入要求会话 SQL 不能在事务中。

通过 select into 导出 Parquet 和 ORC 格式的文件

OceanBase 从 4.3.5 开始,支持了通过 select into 导出 Parquet 和 ORC 格式文件的功能,selectinto 这一部分内容,重点为大家介绍除了 CSV 以外的这两种新格式的导出方式。

导出 Parquet

数据类型映射

目前 OceanBase 通过 select Into 导出 Parquet 格式支持了 MSQL 的数据类型,数据类型的映射表如下:

语法

使用新增的 FORMAT 语法导出 Parquet 文件,指定 type 为 Parquet 即可。

  • COMPRESSION 用于指定 Parquet文件的压缩格式,ROW_GROUP_SIZE 用于指定 Parquet 文件的 ROW GROUP 大小。生成的 Parquet 文件后缀名为.parquet 。
  • COMPRESSION 选项支持的参数:"NCOMPRESSED’(表示文件没有压缩),SNAPPY,GZIP’BROTLI,‘ZSTD,‘LZ4’,LZ4_HADOOP’。不指定时默认值为’UNCOMPRESSED’
  • ROW GROUP SIZE 选项可以写数字,单位为字节,或者写形如’64MB’ 的字符串。不指定时默认值为’256MB’。建议使用默认值。

使用示例

导出 ORC

数据类型映射

目前 OceanBase 通过 select Into 导出 ORC 格式支持了 MySQL 的数据类型,数据类型的映射

表如下:

语法

使用新增的 FORMAT 语法导出 ORC 文件,指定 type 为 ORC 即可

  • COMPRESSION 用于指定 ORC 文件的压缩格式。
  • COMPRESSION 选项支持的参数:"UNCOMPRESSED’(表示文件没有压缩),‘SNAPPY’,‘ZLIB’,‘LZ4’,‘ZSTD’。不指定时默认值为’UNCOMPRESSED’
  • COMPRESSION_BLOCK_SIZE 指的是数据在压缩时被分割成的块大小,可以写数字(单位为字节),或者写形如’64KB’的字符串。不指定时默认值为 256KB。建议用户使用默认值。
  • STRIPE_SIZE 用于指定 ORC 文件的 stripe 大小,可以写数字(单位为字节),或者写形如’64MB’ 的字符串。不指定时默认值为 64 MB。建议用户使用默认值。
  • ROW_INDEX STRIDE 是控制索引记录的频率的参数,定义了每隔多少行记录一次索引,不指定时默认值为10000。建议用户使用默认值。
  • 生成的 ORC 文件后缀名为.orc。

使用示例

附录

CSV/Parquet/ORC 格式简介

CSV

Parquet/ORC

嵌套数据类型的 Schema

Parquet 是一个由 Google Dremel 格式启发而来的列存格式,在大数据领域通常作为存储格式,被iceberg 等湖、各种查询引擎能够合理的使用。

Parquet schema模型能比较简洁处理嵌套和重复。嵌套关系用“属性组”(groups)表示,重复属性用"重复度"(repeated field)表示。一个属性的"重复度"可以有几种定义:

  • required:刚好出现一次
  • optional:出现0或1次
  • repeated:出现0或多次

Parquet 存储数据的例子

假如有 schema 是:

country_tab 记录包含 continent、country、name三个属性,其中country是一个属性组,包含 city、population两个属性。city 是一个repeated 字段,因此可以有多个值,从而表达了数组。

如何存储下面一行数据 ?

其中,city 是个数组,数组中元素可以是任意个,假设 population 可能是未知的,可以被设置为NULL,其他属性都是不能为 NULL 的。

Parquet 认为以上schema有4列(仅存储叶子结点)

假如有 2 行数据,因为一行中的数据可以 repeat,也可以为 null,如何区分一个 column chunk据到底是属于哪一行的?

通过数据上定义的 defination level 和 repetitive level。

类似地,Maps,List or Sets 都可以用重复和属性组(groups+repeated field)表达出来。

相比之下,ORC 使用一个单独的 bitmap 来存储节点是否存在,比较容易理解

1.Struct 只记录 Struct 本身的 PRESENT

2.List = Present Stream + Length Stream.

3.Map = Map 等价于一种很奇怪的 List 和 List 表现一样,但后面有一组 Key 一组 Value。

4.Union 分成 PRESENT+Tag,后面接不同种类的 Stream。

Parquet/Orc 对比示例

实验过程

该实验是如何通过 SELECT INTOLOAD DATA 语句进行数据导出导入。

  • 有关 SELECT INTO 导出数据的 SQL 介绍,参考 SELECT INTO
  • 有关 LOAD DATA 导入数据的 SQL 介绍,参考 LOAD DATA
  • 以 MySQL 模式为例进行说明。

在单机版下 2C8G 规格的机器上进行的演示。数据导出导入的效率会因为环境和机器规格不同而有所差异。

构造测试数据

连接数据库

obclient -h127.0.0.1 -uroot@sys -P2881 -Dtest -A

创建测试表 orders

CREATE TABLE orders (
    order_id BIGINT NOT NULL,
    cust_id BIGINT NOT NULL,
    order_status CHAR(1) DEFAULT NULL,
    total_price DECIMAL(12,2) DEFAULT NULL,
    clerk VARCHAR(15) NOT NULL DEFAULT '',
    ship_priority INT DEFAULT NULL,
    comment VARCHAR(100) DEFAULT NULL,
    PRIMARY KEY (clerk, order_id)
    ) 
    PARTITION BY HASH(order_id) PARTITIONS 100;

创建表 tbl1

CREATE TABLE tbl1 (col1 INT PRIMARY KEY);

向表 tbl1 中插入数据

INSERT INTO tbl1 VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

返回结果如下:

obclient [test]> INSERT INTO tbl1 VALUES(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
Query OK, 10 rows affected (0.030 sec)
Records: 10  Duplicates: 0  Warnings: 0

设置 SQL 最大执行时间

SET ob_query_timeout = 1000000000;

有关设置 SQL 最大执行时间的介绍,参见 ob_query_timeout

向测试表 orders 中插入数据

INSERT /*+ PARALLEL(12) ENABLE_PARALLEL_DML */ INTO orders
    SELECT * 
    FROM (
        SELECT
            N AS ORDER_ID,
            N % 500000 AS CUST_ID,
            FLOOR(N/4000000) AS ORDER_STATUS,
            N % 100000 AS TOTAL_PRICE,
            LEFT(MD5(N % 500), 15) AS CLERK,
            N % 10 AS SHIP_PRIORITY,
            CONCAT(MD5(RAND()), UUID(), MD5(RAND())) AS COMMENT
        FROM (
            SELECT 
                (t1.col1 + t2.col1*10 + t3.col1*100 + t4.col1*1000 + t5.col1*10000 + t6.col1*100000) AS N
            FROM tbl1 t1, tbl1 t2, tbl1 t3, tbl1 t4, tbl1 t5, tbl1 t6
            )
        );

返回结果如下:

Query OK, 1000000 rows affected (13.314 sec)
Records: 1000000  Duplicates: 0  Warnings: 0

查看测试表 orders 中数据数量

SELECT count(*) FROM orders;

返回结果如下:

obclient [test]> SELECT count(*) FROM orders;
+----------+
| count(*) |
+----------+
|  1000000 |
+----------+
1 row in set (1.419 sec)

退出 OBClient 命令行

输入 exit 后回车,或者按快捷键 Ctrl + D 退出 OBClient 命令行。

设置导入导出的文件路径

连接数据库

obclient -S /home/admin/oceanbase/observer/run/sql.sock -uroot@sys

设置导入或导出文件时可以访问的路径没有限制

SET GLOBAL secure_file_priv = "/";

有关设置导入或导出文件时可以访问路径的介绍,参考 secure_file_priv

退出 OBClient 命令行

输入 exit 后回车,或者按快捷键 Ctrl + D 退出 OBClient 命令行。

导出数据

重新连接数据库

obclient -h127.0.0.1 -uroot@sys -P2881 -Dtest -A

设置 SQL 最大执行时间

SET ob_query_timeout = 1000000000;

导出表 orders 中数据到 CSV 文件并自定义名称

导出表 orders 中数据到 CSV 文件,指定文件名为 orders.csv

SELECT /*+ PARALLEL(32) */ 
    ORDER_ID,
    CUST_ID,
    ORDER_STATUS,
    TOTAL_PRICE, 
    CLERK,
    SHIP_PRIORITY,
    COMMENT
INTO OUTFILE '/home/admin/orders.csv'
FIELDS TERMINATED BY ','
FROM orders;

返回如下结果:

Query OK, 1000000 rows affected (8.808 sec)

清空表 orders

TRUNCATE TABLE orders;

验证清空结果

SELECT * FROM orders;

返回结果如下:

obclient [test]> SELECT * FROM orders;
Empty set (0.024 sec)

导入数据

CSV 文件重新导入到 orders 表中,并行度为 32

LOAD DATA /*+ PARALLEL(32) */ INFILE '/home/admin/orders.csv'
INTO TABLE orders
FIELDS TERMINATED BY ',';

返回结果如下:

obclient [test]> LOAD DATA /*+ PARALLEL(32) */ INFILE '/home/admin/orders.csv'
    -> INTO TABLE orders
    -> FIELDS TERMINATED BY ',';
Query OK, 1000000 rows affected (25.225 sec)
Records: 1000000  Deleted: 0  Skipped: 0  Warnings: 0

验证数据完整性:

obclient [test]> SELECT COUNT(*) FROM orders;
+----------+
| COUNT(*) |
+----------+
|  1000000 |
+----------+
1 row in set (0.598 sec)
1 个赞