假设我们在hdfs上有一个hive表作为目录存储,如下所示:
data/
|-- file1
|-- file2
|-- file3
如果我开始对这个目录进行长查询,然后删除其中一个文件,会发生什么情况?
我可以想到三种情况:
文件描述符在查询开始时打开,数据保留到查询结束,即使新查询的文件路径不再可用。
配置单元会记住文件路径,如果找不到已删除的文件,则查询将失败。
配置单元不记得文件路径,只获取当前目录中的文件。
如果配置单元的行为类似于(2),并且在查询过程中删除文件是不安全的,那么从被查询的目录中删除旧数据的正确方法是什么?
2条答案
按热度按时间yfjy0ee71#
正如@shankarsh所说,hive试图使用metastore db中的“lock”表来协调查询。试着运行
show locks ;
命令,而另一个会话正在运行一个长的select或insert查询,而另一个会话试图更改表(必须等到它可以获得独占锁)以便自己查看。不幸的是,这不会阻止hdfs直接访问文件和目录。在hdfs中只有一种类型的锁,它是用于创建/附加/截断文件(或现有文件中的最后一个块)的独占锁。
典型场景:提交查询;hive在查询编译时检索文件和文件块的列表,然后启动一些Map程序来读取这些块;同时,另一个作业请求删除其中一个文件==>其中一个Map程序将崩溃
FileNotFoundException
(我去过那里!)另一个典型的场景是:…同时另一个作业创建一个新文件,或者将一个新块附加到一个现有文件==>数据将永远不会被访问--顺便说一下,这不是一件坏事。
一句话:避免删除配置单元表(无论是托管的还是外部的)所使用的hdfs目录中的文件,除非您可以确保当前没有运行任何查询,或者可能很快就会运行任何查询。如果要一次删除所有文件,对于托管表,请使用
TRUNCATE
在表/分区级别,让hive做一些肮脏的协调工作。在某些情况下,您可能会尝试一个复杂的技巧,临时表有一个单独的分区
EXCHANGE PARTITION
hive命令(…coordination…),然后在temp目录中删除hdfs,然后再删除另一个EXCHANGE PARTITION
返回所有剩余的文件——当然,在这两者之间启动的任何查询都会看到一个空表,这可能是个问题。kxeu7u2r2#
我猜hive将有一个表级锁(共享只读),它不允许对表进行任何更新/删除,所以理想情况下它不允许删除数据。
请也看看这个帖子:
在一个表上运行select时,配置单元会锁定整个数据库