hive 锁机制(S锁,X锁) 是由hive的事务管理器出发,锁的原理是 一张表简称A表,我们对A表做查询操作的时候,就会获取到 A表的S锁(共享锁), 如果对A表做alter 等其他操作就会获取A表的X锁(排他锁) 如果A表同时拥有S锁和X锁,A表就会死锁。死锁后的现象就是做drop truncate 等操作会很慢一直运行中,因为这时候操作已经阻塞了。
解决方法:
1. 查看被锁的表是否被其他任务所引用,比如我们一个任务是对A表做查询,另一个任务在 对A表做其他操作比如写入,修改表结构等 就会导致表被锁。如果有就把其中一个任务kill掉。
2. 先用 show locks 命令查看被锁的表 然后用 unlock table tableName 进行解锁,也可以对分区 解锁 unlock table tableName partition(dt="yyyyMMdd")。 hive表锁机制针对分区表 有表锁和表分区锁,表分区锁是细粒度的锁。
#查看HIVE表是否被锁
SHOW LOCKS <TABLE_NAME>;
#查看哪一个SQL锁了HIVE表
SHOW LOCKS <TABLE_NAME> EXTENDED;
#查看HIVE表分区是否被锁
SHOW LOCKS <TABLE_NAME> PARTITION (<PARTITION_DESC>);
#查看哪一个SQL锁了HIVE表分区
SHOW LOCKS <TABLE_NAME> PARTITION (<PARTITION_DESC>) EXTENDED;
3. set hive.support.concurrency=false; 默认为true 这个参数可以让hive在当前session关闭锁机制,但是全局还是有表锁机制的问题,也可以把参数写到hive的配置文件里,那么hive的表锁机制就一直关闭了。
4. 最暴力的方法,现在hive的元数据服务基本都存储在MySql,在MySql 的hive 库 可以找到一张 hive_locks表 把里面的数据truncate 也可以,但是治标不治本,而且Hive源码也有自动定期清理的线程不过默认是关的 可以在配置文件配置开启,这个方法注意不要把hive_locks表删了,不然启动hive服务会有问题,truncate就行。
5. 在Hive3.X 版本 建表不指定存储格式的话 默认是orc事务表,可以用parquet格式存储 就不会受到表锁机制的问题,不过orc存储的文件更小 并且支持 ACID/DELETE/UPDATE。