
# 使用脚本完成随机内容抽样比对
1. 在华为云购买一台与源端、目的端都相通的ECS（建议购买CentOS操作系统的ECS）。 
   图1购买ECS   
   ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002514138463.png)
   要使该ECS和源端目的端数据库都通，需要在源端和目的端配置安全组。
   - 源端设置服务器防火墙 ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002481978612.png)
     ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002481818648.png)
     
   
   - 目的端设置安全组 ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002513978493.png)
     ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002514138465.png)
     
   
   - 结果 ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002481978614.png)
     
   
   
   
   
2. 在第一步购买的ECS上安装sqlcmd 
   安装参考：[在 Linux 上安装 sqlcmd 和 bcp SQL Server 命令行工具](https://learn.microsoft.com/zh-cn/sql/linux/sql-server-linux-setup-tools?view=sql-server-2017&tabs=redhat-install)
   安装步骤如下：
   1. 下载Microsoft Red Hat存储库配置文件 curl https://packages.microsoft.com/config/rhel/8prod.repo \| sudo tee /etc/yum.repos.d/mssql-release.repo
      ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002481818650.png)
      
   
   
   
   2. 如果安装了早期版本的mssql-tools，请删除所有旧的unixODBC包 sudo yum remove mssql-tools unixODBC-utf16 unixODBC-utf16-devel
      ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002513978495.png)
      
   
   
   
   3. 运行以下命令，以使用unixODBC开发人员包安装mssql-tools18 sudo yum install -y mssql-tools18 unixODBC-devel
      ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002514138467.png)
      若要将**mssql-tools**更新至最新版本，请运行以下命令：
      sudo yum check-update
      sudo yum update mssql-tools18
      ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002481978616.png)
      
   
   4. 向bash shell中的PATH环境变量添加/opt/mssql-tools18/bin/ 若要使sqlcmd和bcp能从登录会话的 bash shell 进行访问，请使用下列命令修改\~/.bash_profile 文件中的 PATH
      echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' \>\> \~/.bash_profile
      source \~/.bash_profile
      ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002481818654.png)
      
    
   
   
3. 将校验脚本、源端/目的端的配置信息文件、校验表配置文件导入ECS。 
   ECS check脚本如下：
   ```
   #!/bin/bash
   # 日志函数
   log() {
       echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
   }
   # 错误处理函数
   error_exit() {
       log "错误: $1"
       exit 1
   }
   # 检查参数
   if [ "$#" -ne 2 ]; then
       error_exit "用法: $0 <配置文件路径> <表信息文件路径>"
   fi
   config_file=$1
   table_info_file=$2
   # 检查文件是否存在
   [ -f "$config_file" ] || error_exit "配置文件 $config_file 不存在"
   [ -f "$table_info_file" ] || error_exit "表信息文件 $table_info_file 不存在"
   # 读取第一个SQL Server连接信息
   server1=$(awk -F'=' '/^server1/ {print $2}' "$config_file" | tr -d ' ')
   user1=$(awk -F'=' '/^user1/ {print $2}' "$config_file" | tr -d ' ')
   password1=$(awk -F'=' '/^password1/ {print $2}' "$config_file" | tr -d ' ')
   database1=$(awk -F'=' '/^database1/ {print $2}' "$config_file" | tr -d ' ')
   # 读取第二个SQL Server连接信息
   server2=$(awk -F'=' '/^server2/ {print $2}' "$config_file" | tr -d ' ')
   user2=$(awk -F'=' '/^user2/ {print $2}' "$config_file" | tr -d ' ')
   password2=$(awk -F'=' '/^password2/ {print $2}' "$config_file" | tr -d ' ')
   database2=$(awk -F'=' '/^database2/ {print $2}' "$config_file" | tr -d ' ')
   # 检查连接信息是否完整
   if [ -z "$server1" ] || [ -z "$user1" ] || [ -z "$password1" ] || [ -z "$database1" ] ||
      [ -z "$server2" ] || [ -z "$user2" ] || [ -z "$password2" ] || [ -z "$database2" ]; then
       error_exit "配置文件缺少必要的连接信息"
   fi
   # 检查sqlcmd是否可用
   command -v sqlcmd >/dev/null 2>&1 || error_exit "sqlcmd命令未找到，请确保SQL Server命令行工具已安装"
   # 处理表信息文件
   total_tables=0
   success_tables=0
   failed_tables=0
   for line in `cat  $table_info_file`
   do
       # 去除空格
       table1=$(echo $line | awk -F',' '{print $1}' | tr -d ' ')
       table2=$(echo $line | awk -F',' '{print $2}' | tr -d ' ')
       pk_column=$(echo $line | awk -F',' '{print $3}' | tr -d ' ')
       gt_value=$(echo $line | awk -F',' '{print $4}' | tr -d ' ')
       lt_value=$(echo $line | awk -F',' '{print $5}' | tr -d ' ')
       ((total_tables++))
       log "开始比较表 #$total_tables: $table1 (服务器1) 和 $table2 (服务器2)"
       # 构建WHERE子句
       where_clause=""
       if [ -n "$pk_column" ]; then
           conditions=()
           if [ -n "$gt_value" ]; then
               conditions+=("$pk_column > $gt_value")
           fi
           if [ -n "$lt_value" ]; then
               conditions+=("$pk_column < $lt_value")
           fi
           if [ $ -gt 0 ]; then
               where_clause="WHERE $(printf '%s AND ' "${conditions[@]}" | sed 's/ AND $//')"
           fi
       fi
       # 获取表1的checksum
       sql1="SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) AS checksum FROM $table1 $where_clause"
       checksum1=$(sqlcmd -S "$server1" -U "$user1" -P "$password1" -d "$database1" -h -1 -Q "SET NOCOUNT ON; $sql1" 2>/dev/null | tr -d ' ' | tr -d '\r\n')
       if [ $? -ne 0 ]; then
           log "警告: 无法获取表 $table1 的checksum，跳过此表"
           ((failed_tables++))
           echo "----------------------------------------"
           continue
       fi
       # 获取表2的checksum
       sql2="SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*)) AS checksum FROM $table2 $where_clause"
       checksum2=$(sqlcmd -S "$server2" -U "$user2" -P "$password2" -d "$database2" -h -1 -Q "SET NOCOUNT ON; $sql2" 2>/dev/null | tr -d ' ' | tr -d '\r\n')
       if [ $? -ne 0 ]; then
           log "警告: 无法获取表 $table2 的checksum，跳过此表"
           ((failed_tables++))
           echo "----------------------------------------"
           continue
       fi
       # 比较checksum
       if [ "$checksum1" == "$checksum2" ]; then
           log "结果: 表内容一致 (Checksum: $checksum1)"
           ((success_tables++))
       else
           log "结果: 表内容不一致"
           log "表 $table1 (服务器1) Checksum: $checksum1"
           log "表 $table2 (服务器2) Checksum: $checksum2"
           ((failed_tables++))
       fi
       echo "----------------------------------------"
   done
   log "比较完成"
   log "总计表数: $total_tables"
   log "一致表数: $success_tables"
   log "不一致表数: $failed_tables"
   if [ "$failed_tables" -gt 0 ]; then
       exit 1
   else
       exit 0
   fi
   ```
   - 源/目标信息配置文件 vi config.cfg
     server1=testdbvm.database.windows.net
     user1=azuser
     password1=XXXXX
     database1=smsa_mig
     server2= 123.60.216.120
     user2=rdsuser
     password2=XXXXXXX
     database2= smsa_mig
     ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002513978499.png)
     ![](https://support.huaweicloud.com/bestpractice-drs/public_sys-resources/note_3.0-zh-cn.png)
     server user password与database用户需要按照实际需要修改。
     
   
   - 同步对比表配置文件 (源表名，目标表名，主键，\> 范围，\<范围,逗号分隔)
     vim table_info.txt
     如第一行校验dbo.check1全表，不指定范围
     如第二行校验dbo.check2，根据id\>11 and id \< 13的范围校验
     dbo.check1,dbo.check1
     dbo.check2,dbo.check2,id,11,13
     ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002514138473.png)
     ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002481978622.png)
     
    
   
   
4. 执行校验文件脚本。 
   sh chech.sh config.cfg table_info.txt
   ![](https://support.huaweicloud.com/bestpractice-drs/zh-cn_image_0000002481818658.png)
   
   
 
