WOS与ROS
在企业模式下运行时,Vertica将数据存储在两个容器中:
-
写优化存储(WOS) - 将数据存储在内存中,无需压缩或索引。您可以使用INSERT,UPDATE和COPY语句将数据加载到WOS中。
-
读取优化存储(ROS) - 将数据存储在磁盘上。对数据进行分段,排序和压缩以实现高度优化。您可以使用COPY语句将数据直接加载到ROS中。
WOS的存在是为了防止许多小数据加载(通常称为涓流加载)强制Vertica 创建许多小的ROS容器。大量小型ROS容器的效率低于大型容器。
Tuple Mover使用以下过程将数据从WOS(内存)移动到ROS(磁盘):
- Moveout将数据从WOS复制到Tuple Mover,然后复制到ROS, 数据被分类,编码和压缩成列文件。
- Mergeout将较小的ROS容器组合成较大的容器,以减少碎片。
您通常使用COPY语句批量加载数据。它可以将数据加载到WOS中,或者将数据直接加载到ROS中。
3种加载方式
auto
使用copy命令方式时,默认使用auto方式。
COPY使用AUTO方法将数据加载到Vertica WOS中。对于较小的批量装载,请使用此默认的自动加载方法。当您无法确定文件的大小时,AUTO选项最为有用。一旦WOS已满,COPY将继续直接加载到磁盘上的ROS容器,对ROS数据进行排序和编码。
direct
COPY使用DIRECT方法将数据直接加载到ROS容器中。对于大批量负载(100 MB或更多),请使用DIRECT加载方法。 DIRECT方法通过避免WOS并将数据加载到ROS容器中来提高大文件的性能。使用DIRECT加载许多较小的数据集会导致许多ROS容器,这些容器必须稍后组合。
trickle
COPY使用TRICKLE方法将数据直接加载到WOS中。 完成初始批量加载后,使用TRICKLE加载方法递增地加载数据。 如果WOS已满,则会发生错误,并回滚整个数据加载。 只有在您的节点上进行了精细调整的负载和移出过程时,才能使用此方法,并且您确信WOS可以保存正在加载的数据。 当将数据加载到分区表中时,此选项比AUTO更有效。
并行加载
vertica可以在copy命令中指定一个或多个节点名称及文件,来实现多个数据源的同时加载,如下所示:
COPY schema-name.target-table FROM
'/path/1.dat' ON node0001,
'/path/2.dat' ON node0002,
'/path/3.dat' ON node0003,
'/path/4.dat' ON node0004,
'/path/5.dat' ON node0005 DIRECT;
如果全部数据只在本地文件系统的某一个节点上时,可以使用如下方法:
1.在集群中建立共享文件系统(NFS),将实际存放数据的节点作为服务器节点,其他节点作为客户端节点。
2.copy 时使用 on any node 命令。指定此子句,COPY将打开该文件并从群集中的任何节点解析该文件。
ON ANY NODE是HDFS和S3路径的默认值。
如从共享文件目录加载一些大文件到表:
COPY myTable FROM '/data/manyfiles/*.dat' ON ANY NODE direct;
Tuple Move函数
当加载数据完成后,可以使用DO_TM_TASK函数,将WOS数据转移到ROS或者合并ROS。
1.将WOS中属于表t1的数据移动到表t1中。
SELECT DO_TM_TASK('moveout', 't1');
2.合并ROS
SELECT DO_TM_TASK('mergeout', 't1');
注意:当进行大量或长时间的数据加载后,若没有及时的合并ROS,可能会出现“Too Many ROS Containers”的报错。大量小的ROS容器的存在,会影响数据库的性能。虽然vertica会自动进行合并,但是由于自动合并需满足的条件较多,所以,有时候还需要手动的去合并ROS。
关于Tuple Mover的一些参数设置,可参考:
https://www.vertica.com/docs/9.1.x/HTML/index.htm#Authoring/AdministratorsGuide/ConfiguringTheDB/TupleMoverParameters.htm
可通过查询系统表TUPLE_MOVER_OPERATIONS
来查看各个节点的Tuple Move情况。
如:
SELECT node_name, operation_status, projection_name, plan_type
FROM TUPLE_MOVER_OPERATIONS;
node_name | operation_status | projection_name | plan_type
-------------------+------------------+------------------+-----------
v_vmart_node0001 | Running | p1_b2 | Mergeout
v_vmart_node0002 | Running | p1 | Mergeout
v_vmart_node0001 | Running | p1_b2 | Replay Delete
v_vmart_node0001 | Running | p1_b2 | Mergeout
v_vmart_node0002 | Running | p1_b2 | Mergeout
v_vmart_node0001 | Running | p1_b2 | Replay Delete
v_vmart_node0002 | Running | p1 | Mergeout
v_vmart_node0003 | Running | p1_b2 | Replay Delete
v_vmart_node0001 | Running | p1 | Mergeout
v_vmart_node0002 | Running | p1_b1 | Mergeout
加载数据时的拒绝信息和拒绝表
COPY语句自动将每个被拒绝行的副本保存在被拒绝的数据文件中。 COPY还保存了对异常文件中拒绝原因的相应解释。 默认情况下,Vertica将这两个文件保存在名为CopyErrorLogs的数据库目录子目录中,如下所示:
v_mart_node003_catalog\CopyErrorLogs\trans-STDIN-copy-from-rejected-data.1
v_mart_node003_catalog\CopyErrorLogs\trans-STDIN-copy-from-exceptions.1
可以查看这些文件,以确定那些行加载错误以及可能的错误原因。
你可以在copy语句中指定拒绝信息的存放位置,使用REJECTED DATA reject_path and EXCEPTIONS except_path
命令来完成。如:
COPY myTable FROM '/data/manyfiles/*.dat' REJECTED DATA '/opt/vertica/data/' and EXCEPTIONS '/opt/vertica/data/';
也可以使用REJECTED DATA AS TABLE reject_table
语句将错误信息存储在一个表中,如:
COPY loader FROM STDIN REJECTED DATA AS TABLE loader_rejects;
然后可以通过查看该表获得错误信息:
SELECT * FROM loader_rejects;
-[ RECORD 1 ]-------------+--------------------------------------------
node_name | v_vmart_node0001
file_name | STDIN
session_id | v_vmart_node0001.example.-24016:0x3439
transaction_id | 45035996274080923
statement_id | 1
batch_number | 0
row_number | 4
rejected_data | a
rejected_data_orig_length | 1
rejected_reason | Invalid integer format 'a' for column 1 (x)
其他
所有类型的COPY语句共享相同的方法和过程,但它们都有不同的限制。无论差异如何,COPY声明总是有两个阶段:
-
第一阶段(启动器)加载和解析文件并将文件分发到其他节点。
-
第二阶段(执行者)处理所有节点上的数据。
该部分内容具体可参考:https://blog.csdn.net/mashengwang/article/details/78622778
补充
1.copy命令默认是自动commit的,也可以在copy语句后指定no commit来不自动提交。
本文主要参考:vertica官方文档9.1.x版本