Hive 事务和锁的功能测试
Hive 事务和锁的功能测试
Hive 的事务和锁,可以在会话级别设置。
1. 无事务、无锁的方式
各云厂商,如阿里云,百度云默认都采用此方案。如果不使用此方案,用户需要手动改配置。
此方案读写表都没有限制。任务的执行时间可以估计,不会出现长时间等待锁的情况。
1.1 普通表
创建表
create database if not exists test;
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager;
set hive.support.concurrency=false;drop table if exists t_web_sales;
create table t_web_sales(ws_sold_time_sk bigint,ws_ship_date_sk bigint,ws_item_sk bigint) stored as parquet;
- 两个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager;
set hive.support.concurrency=false;
select current_timestamp();
insert overwrite table t_web_salesselect ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务能同时运行。
1.2 分区表
创建表
create database if not exists test;
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager;
set hive.support.concurrency=false;drop table if exists t_web_sales;
create table t_web_sales(ws_sold_time_sk bigint,ws_ship_date_sk bigint,ws_item_sk bigint) partitioned by (dt string) stored as parquet;
- 两个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager;
set hive.support.concurrency=false;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务能同时运行。
1.3 动态分区
创建表
create database if not exists test;
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager;
set hive.support.concurrency=false;drop table if exists t_web_sales;
create table t_web_sales(ws_sold_time_sk bigint,ws_ship_date_sk bigint,ws_item_sk bigint) partitioned by (dt string) stored as parquet;
- 两个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager;
set hive.support.concurrency=false;
select current_timestamp();
insert overwrite table t_web_sales select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk,mod(hash(ws_sold_time_sk),10) from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务能同时运行。
1.4. 事务表
创建表失败,只能用 DbTxnManager 的情况下使用事务表。
create database if not exists test;
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager;
set hive.support.concurrency=false;drop table if exists t_web_sales;
create table t_web_sales(ws_sold_time_sk bigint,ws_ship_date_sk bigint,ws_item_sk bigint) partitioned by (dt string) stored as orc tblproperties('transactional'='true');
1.5 insert only 事务表
创建表失败,只能用 DbTxnManager 的情况下使用事务表。
create database if not exists test;
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager;
set hive.support.concurrency=false;drop table if exists t_web_sales;
create table t_web_sales(ws_sold_time_sk bigint,ws_ship_date_sk bigint,ws_item_sk bigint) partitioned by (dt string) stored as parquet tblproperties('transactional'='true','transactional_properties'='insert_only');
2. DbTxnManager锁表的方案
DbTxnManager 是现有的方式配置,使用DbLockManager。
2.1 普通表
创建表
create database if not exists test;
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;drop table if exists t_web_sales;
create table t_web_sales(ws_sold_time_sk bigint,ws_ship_date_sk bigint,ws_item_sk bigint) stored as parquet;
- 两个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_salesselect ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务不能同时运行。
2.2 分区表
2.2.1 插入相同的分区
创建表
create database if not exists test;
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;drop table if exists t_web_sales;
create table t_web_sales(ws_sold_time_sk bigint,ws_ship_date_sk bigint,ws_item_sk bigint) partitioned by (dt string) stored as parquet;
- 两个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务不能同时运行。
- 两个会话同时执行以下 insert into SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert into table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务可以同时运行。
2.2.2 插入不同的分区
创建表
create database if not exists test;
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;drop table if exists t_web_sales;
create table t_web_sales(ws_sold_time_sk bigint,ws_ship_date_sk bigint,ws_item_sk bigint) partitioned by (dt string) stored as parquet;
- 第1个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
- 第2个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230102')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务能同时运行。
2.2.3 一个SQL读分区,一个SQL 插入其他分区
- 第1个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
- 第2个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();select count(distinct ws_sold_time_sk) from t_web_sales where dt='20230102';
select current_timestamp();
可以看到两个任务不能同时运行。
2.3 动态分区
创建表
create database if not exists test;
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;drop table if exists t_web_sales;
create table t_web_sales(ws_sold_time_sk bigint,ws_ship_date_sk bigint,ws_item_sk bigint) partitioned by (dt string) stored as parquet;
- 两个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk,mod(hash(ws_sold_time_sk),10) from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务可以同时运行。
2.4. 事务表
create database if not exists test;
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;drop table if exists t_web_sales;
create table t_web_sales(ws_sold_time_sk bigint,ws_ship_date_sk bigint,ws_item_sk bigint) partitioned by (dt string) stored as orc tblproperties('transactional'='true');
事务表更严格,抛出的异常种类更多。需要在 metastore 开启 compactor,容易 compactor 和普通任务的相互竞争,导致报错。社区的 bug 很多,有 bug 导致内存溢出。
2.4.1 插入相同的分区
- insert overwrite 两个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务不能同时运行,并且抛出以下异常:
FAILED: Hive Internal Error: org.apache.hadoop.hive.ql.lockmgr.LockException(Transaction manager has aborted the transaction txnid:86949. Reason: Aborting [txnid:86949,86950] due to a write conflict on test/t_web_sales/dt=20230101 committed by [txnid:86947,86949] u/u)
- insert into 两个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert into table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务可以同时运行
2.4.2 插入不同的分区
- 第1个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
- 第2个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230102')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务能同时运行。
2.4.3 一个SQL读分区,一个SQL 插入其他分区
- 第1个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
- 第2个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();select count(distinct ws_sold_time_sk) from t_web_sales where dt='20230102';
select current_timestamp();
可以看到两个任务不能同时运行。
2.4.4 一个SQL读分区,一个SQL insert into 其他分区
- 第1个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert into table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
- 第2个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();select count(distinct ws_sold_time_sk) from t_web_sales where dt='20230102';
select current_timestamp();
可以看到两个任务可以同时运行。
2.5 insert only 事务表
只能用 DbTxnManager 的情况下使用事务表。数据格式可以是其他格式。对相同分区可以多个会话使用 insert 但是不能使用 insert overwrite.
create database if not exists test;
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;drop table if exists t_web_sales;
create table t_web_sales(ws_sold_time_sk bigint,ws_ship_date_sk bigint,ws_item_sk bigint) partitioned by (dt string) stored as parquet tblproperties('transactional'='true','transactional_properties'='insert_only');
2.5.1 插入相同的分区
- insert overwrite 两个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales limit 10000;
select current_timestamp();
可以看到两个任务不能同时运行,并且抛出以下异常:
Hive Internal Error: org.apache.hadoop.hive.ql.lockmgr.LockException(Transaction manager has aborted the transaction txnid:86999. Reason: Aborting [txnid:86999,87000] due to a write conflict on test/t_web_sales/dt=20230101 committed by [txnid:86997,86999] u/u)
- insert into 两个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert into table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务可以同时运行
2.5.2 插入不同的分区
- 第1个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
- 第2个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230102')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
可以看到两个任务能同时运行。
2.5.3 一个SQL读分区,一个SQL 插入其他分区
- 第1个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert overwrite table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
- 第2个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();select count(distinct ws_sold_time_sk) from t_web_sales where dt='20230102';
select current_timestamp();
可以看到两个任务不能同时运行。
2.5.4 一个SQL读分区,一个SQL insert into 其他分区
- 第1个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();
insert into table t_web_sales partition(dt='20230101')select ws_sold_time_sk,ws_ship_date_sk,ws_item_sk from tpcds_bos_orc_30.web_sales;
select current_timestamp();
- 第2个会话同时执行以下 SQL
use test;
set hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager;
set hive.support.concurrency=true;
select current_timestamp();select count(distinct ws_sold_time_sk) from t_web_sales where dt='20230102';
select current_timestamp();
可以看到两个任务可以同时运行。