假设我们将一个Hive表存储在HDFS上作为目录,如下所示:
data/
|-- file1
|-- file2
|-- file3
如果我在此目录上启动长查询,然后删除其中一个文件会怎样?
我可以想到3个场景:
如果Hive的行为类似于(2)并且在查询期间删除文件是不安全的,从被查询的目录中删除旧数据的正确方法是什么?
答案 0 :(得分:1)
正如@Shankarsh所述,Hive尝试使用" lock"来协调其查询。表在其Metastore DB中。尝试运行show locks ;
命令,而另一个会话正在运行长SELECT或INSERT查询,而另一个会话尝试更改表(必须等到它可以获取独占锁)才能自己查看。
不幸的是,这不会阻止直接HDFS访问文件和目录。 AFAIK在HDFS中只有一种类型的锁,它是一个独占锁,用于创建/追加/截断文件(或现有文件中的最后一个块)。
典型情况:您提交查询; Hive在查询编译时检索文件和文件块的列表然后启动一些映射器以从这些块读取;同时另一个工作要求删除其中一个文件==>其中一位地图制作者将崩溃与FileNotFoundException
(我已经在那里!)
另一个典型情况:...同时另一个作业创建一个新文件,或将一个新块附加到现有文件==>这些数据永远不会被访问 - 顺便说一句,这并不是件坏事。
底线:避免删除Hive表(无论是托管还是外部)使用的HDFS目录中的文件,除非您可以确保当前没有查询正在运行,或者可能很快就会运行。如果要一次删除所有文件,对于托管表,请在表/分区级别使用TRUNCATE
,让Hive执行脏协调。
在某些情况下,您可能尝试使用具有单个分区的临时表,EXCHANGE PARTITION
Hive命令(... coordination ...),然后临时目录中的HDFS删除的复杂技巧,然后另一个EXCHANGE PARTITION
将所有剩余的文件返回原位 - 当然,在它们之间启动的任何查询都会看到一个空表,这可能是个问题。
答案 1 :(得分:0)
我猜Hive会做一个表级锁定(只读共享),它不允许在表上进行任何更新/删除,所以理想情况下它不允许删除数据。
请看一下这篇文章: