You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sqoop导出数据不全排查:Shell脚本统计Hive与SQL Server行数问询

解决Sqoop导出Hive到SQL Server的数据一致性校验问题

我之前也碰到过Sqoop偶尔漏导数据的情况,你的"行数校验+自动重导"方案很靠谱。下面详细说明如何在Shell脚本中实现这两个表的行数统计,以及完整的执行逻辑:

一、统计Hive表的行数

在Shell中可以通过Hive CLI或者Beeline来执行计数查询,提取结果数值:

方法1:使用Hive CLI(适合传统Hive部署)

直接通过hive命令执行count(*),然后过滤掉日志行,只保留最终的数值:

# 替换为你的Hive库名和表名
HIVE_DB="your_hive_database"
HIVE_TABLE="your_hive_table"

# 统计行数并赋值给变量
hive_count=$(hive -e "select count(*) from ${HIVE_DB}.${HIVE_TABLE};" | grep -v "WARN" | tail -n 1)
  • grep -v "WARN":过滤掉Hive输出的警告日志行
  • tail -n 1:取最后一行的计数结果(前面的行可能是Hive的启动日志)

方法2:使用Beeline(适合HiveServer2部署,更推荐)

如果你的集群用HiveServer2,建议用Beeline连接,安全性和稳定性更好:

HIVE_JDBC_URL="jdbc:hive2://your_hive_server:10000"
HIVE_USER="your_hive_username"

hive_count=$(beeline -u "${HIVE_JDBC_URL}" -n "${HIVE_USER}" -e "select count(*) from ${HIVE_DB}.${HIVE_TABLE};" | grep -v "WARN" | grep -v "Connected" | tail -n 1)
  • grep -v "Connected":过滤掉Beeline的连接成功提示行

二、统计SQL Server表的行数

需要用到SQL Server官方的命令行工具sqlcmd(确保脚本执行服务器已经安装该工具),通过它执行计数查询并返回纯数值:

# 替换为你的SQL Server连接信息
SQLSERVER_HOST="your_sqlserver_host"
SQLSERVER_PORT="1433"
SQLSERVER_DB="your_sqlserver_database"
SQLSERVER_TABLE="your_sqlserver_table"
SQLSERVER_USER="your_sqlserver_username"
SQLSERVER_PWD="your_sqlserver_password"

# 统计行数并赋值给变量
sqlserver_count=$(sqlcmd -S "${SQLSERVER_HOST},${SQLSERVER_PORT}" -U "${SQLSERVER_USER}" -P "${SQLSERVER_PWD}" -d "${SQLSERVER_DB}" -Q "select count(*) from ${SQLSERVER_TABLE};" -h -1)
  • -h -1:关闭表头输出,直接返回计数数值
  • 注意:生产环境不要明文写密码,建议用环境变量或者加密存储的方式读取,比如SQLSERVER_PWD=$(cat /path/to/encrypted/pwd | decryption_command)

三、完整的Shell脚本示例

把上面的逻辑整合起来,实现校验+自动重导:

#!/bin/bash

# -------------------------- 配置参数 --------------------------
# Hive相关
HIVE_DB="your_hive_db"
HIVE_TABLE="your_hive_table"
HIVE_JDBC_URL="jdbc:hive2://hive-server:10000"
HIVE_USER="hive_user"

# SQL Server相关
SQLSERVER_HOST="sqlserver-host"
SQLSERVER_PORT="1433"
SQLSERVER_DB="sqlserver_db"
SQLSERVER_TABLE="sqlserver_table"
SQLSERVER_USER="sql_user"
# 生产环境建议用环境变量传递密码
SQLSERVER_PWD="${SQLSERVER_PWD_ENV}"

# Sqoop导出命令(替换为你的实际Sqoop脚本内容)
SQOOP_CMD="sqoop export --connect jdbc:sqlserver://${SQLSERVER_HOST}:${SQLSERVER_PORT};databaseName=${SQLSERVER_DB} \
    --username ${SQLSERVER_USER} \
    --password ${SQLSERVER_PWD} \
    --table ${SQLSERVER_TABLE} \
    --export-dir /user/hive/warehouse/${HIVE_DB}.db/${HIVE_TABLE} \
    --input-fields-terminated-by '\001' \
    --m 1"
# --------------------------------------------------------------

# 1. 统计Hive表行数
echo "开始统计Hive表行数..."
hive_count=$(beeline -u "${HIVE_JDBC_URL}" -n "${HIVE_USER}" -e "select count(*) from ${HIVE_DB}.${HIVE_TABLE};" | grep -v "WARN" | grep -v "Connected" | tail -n 1)
# 校验是否获取到有效数值
if ! [[ "${hive_count}" =~ ^[0-9]+$ ]]; then
    echo "ERROR: 无法获取Hive表行数"
    exit 1
fi
echo "Hive表行数: ${hive_count}"

# 2. 统计SQL Server表行数
echo "开始统计SQL Server表行数..."
sqlserver_count=$(sqlcmd -S "${SQLSERVER_HOST},${SQLSERVER_PORT}" -U "${SQLSERVER_USER}" -P "${SQLSERVER_PWD}" -d "${SQLSERVER_DB}" -Q "select count(*) from ${SQLSERVER_TABLE};" -h -1)
if ! [[ "${sqlserver_count}" =~ ^[0-9]+$ ]]; then
    echo "ERROR: 无法获取SQL Server表行数"
    exit 1
fi
echo "SQL Server表行数: ${sqlserver_count}"

# 3. 对比行数并执行重导逻辑
if [ "${hive_count}" -ne "${sqlserver_count}" ]; then
    echo "行数不一致,开始清空SQL Server表并重新导出..."
    # 清空SQL Server表(用truncate比delete更快)
    sqlcmd -S "${SQLSERVER_HOST},${SQLSERVER_PORT}" -U "${SQLSERVER_USER}" -P "${SQLSERVER_PWD}" -d "${SQLSERVER_DB}" -Q "truncate table ${SQLSERVER_TABLE};"
    # 执行Sqoop导出
    ${SQOOP_CMD}
    if [ $? -eq 0 ]; then
        echo "重新导出完成,再次校验行数..."
        # 再次统计SQL Server行数
        new_sqlserver_count=$(sqlcmd -S "${SQLSERVER_HOST},${SQLSERVER_PORT}" -U "${SQLSERVER_USER}" -P "${SQLSERVER_PWD}" -d "${SQLSERVER_DB}" -Q "select count(*) from ${SQLSERVER_TABLE};" -h -1)
        if [ "${hive_count}" -eq "${new_sqlserver_count}" ]; then
            echo "校验通过,数据导出成功!"
        else
            echo "ERROR: 重新导出后行数仍然不一致,请人工排查!"
            exit 1
        fi
    else
        echo "ERROR: Sqoop重新导出失败!"
        exit 1
    fi
else
    echo "行数一致,无需执行导出操作"
    exit 0
fi

额外注意事项

  • 如果Hive表是分区表,count(*)会扫描全表数据,可能耗时较长,若追求速度可以考虑使用Hive的统计信息(ANALYZE TABLE生成),但准确性不如直接count。
  • sqlcmd的安装:CentOS/RHEL可以通过yum install mssql-tools安装,Ubuntu可以用apt-get install mssql-tools。
  • 脚本中加入了数值有效性校验,避免因日志格式变化导致获取到非数值的结果,提升稳定性。

内容的提问来源于stack exchange,提问作者Aakib

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:02:32