【集群迁移】使用Shell脚本获取老集群整个Hive库的建库、建表DDL
做集群迁移时,肤浅的SQL Boy们只会在Hue用Hive执行show create table db1.tb1;
这种方式,来手动一步一步获取到单个表的建表DDL,当然不能说做法有错误,但是这样效率明显低下不少。笔者去年做集群迁移时,首先想到的当然就是使用Java去写JDBC来遍历库表获取到所有的DDL,但是出于安全管控等要求,其中一套老CDH5.16集群是不允许随意放Jar包的,故当时的做法是使用Shell脚本去遍历,非编译的明文脚本过审要容易很多。
Hive和Beeline脚本:https://lizhiyong.blog.csdn.net/article/details/126688391
资深的SQL Boy们或者运维当然也会写这种脚本,其实原理很简单:当执行了hive -e或者beeline命令后,底层就会走JDBC协议连接到Hive Server或者Hive Server2,并最终通过stdout输出给Linux黑窗口,那么只需要借助输出重定向,就可以将这部分有用的内容给固化到文本中,进而自动获取到所需的信息。不需要手动拉取建库、建表的DDL了,方便省事。
话不多说,直接上shell脚本:
#! /bin/bash
current_dir=$(cd $(dirname $0);pwd)
echo "当前路径:${current_dir}"
# 导出Hive库名
hive -e "show databases;" > ${current_dir}/all_database.db
# 删除警告
sed -i '/^WARN:/d' ${current_dir}/all_database.db
# 导出各个Hive库下所有表的DDL
for database in `cat ${current_dir}/all_database.db`
do
echo "create database if not exists ${database};" >> ${current_dir}/create_database_all_DDL.sql
hive -e "use ${database};show tables;" > ${current_dir}/${database}.tb
sed -i '/^WARN:/d' ${current_dir}/${database}.tb
# 导出建表DDL
for table in `cat ${current_dir}/${database}.tb`
do
hive -e "show create table ${database}.${table};" >> ${current_dir}/${database}_all_DDL.sql
sed -i '/^WARN:/d' ${current_dir}/${database}_all_DDL.sql
done
done
老的集群会有警告等多余信息,需要去掉它们。但是有的集群并没有这类多余信息,需要具体场景具体分析。
这个脚本会先来个查库操作,获取到所有的库名,然后外层循环遍历所有的库名,并且将建库语句追加到sql文件。之后获取到当前库的所有表名。
内层循环会遍历表名,获取到对应的建表DDL并不断追加到sql文件。
经过2层循环,就获取到了整个Hive库表的所有DDL,后续批量修改location写死的路径【例如:维度表可能会指定使用Alluxio存储来提速,或者内部表、外部表要按业务模块、部门租户等重新划分路径】,或者批量修改为统一Parquet建表,比纯手工肯定是方便不少。
对于某些机器,可能从来就没有安装过中文语言包,或者集群的Hive、存储元数据的MySQL配置有问题,就会导致当comment中有中文【或者其它语言】时出现乱码。这种情况需要视情况,修改集群MySQL的字符集编码或者给安装中文语言包。还有一部分乱码是历史问题,远古时代的DDL中comment已经乱码了,那就只能知情人士去手动修复。
如果有Kerberos认证,当然需要在头上+一句:
kinit -kt 租户.keytab 租户名称
先过了Kerberos认证,并且确认当前租户有权限查看DDL才能执行脚本,否则需要先找网管或者平台管理员开通租户的Ranger或者Sentry权限。
能自动化的事情,尽量去自动化。挑个资源充足的时间段,挂那里自动跑,小集群也就跑个把小时的事情。大集群几百个库的几十万个表的DDL也可以自动拉出来,稍微慢一点。纯人工方式估计干到离职、干到Hive被全面淘汰都干不完!!!
转载请注明出处:https://lizhiyong.blog.csdn.net/article/details/127777207