Postgres比较两个数据库

时间:2017-05-29 14:09:21

标签: postgresql

我们运行两个数据库服务器,其中包含大约10个数据库和多个模式(生产和测试)。每天晚上我们都会恢复一些测试。我们使用pg_dump进行备份并使用pg_restore进行恢复。现在,生产和恢复数据库的大小从几kb到700mb不等。

现在我想确保恢复的数据与生产中的数据相同。我已经看到这通常是postgres但我们必须向我们的经理证明这一点。恢复后数据库服务器相同的最简单的证明是什么?

2 个答案:

答案 0 :(得分:0)

让我建议你另一种方法。您可以将pg_restoresingle transaction一起使用。引自de docs

  

1
  --single-transaction
将恢复作为单个事务执行(即,将发出的命令包装在BEGIN / COMMIT中)。这确保了   要么所有命令都成功完成,要么没有更改   应用。此选项意味着--exit-on-error。

在这种情况下,您不需要比较两侧所有表格上的COUNT,因为如果pg_restore返回0(零),那么一切都进展顺利。

答案 1 :(得分:0)

刚刚解决了我们现在提供的解决方案。

#!/bin/bash
#
#change to the dir this script is located in (just to be sure)
cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# CONFIGURATION
remoteHost=stackoverflow.com
remotePort=5432
remoteUser=postgres
logfile=00comparsion.txt
#######################
cat "" > $logfile
databases=$(psql -U postgres -t -c "SELECT datname FROM pg_database WHERE datistemplate = false")
for database in $databases; do
    echo -------------------------------------------------------------------------------  >> $logfile
    echo $database >> $logfile
    echo ------------------------------------------------------------------------------- 
    echo $database
    if [ "$(psql -U $remoteUser -h $remoteHost -p $remotePort -tAc "SELECT datname FROM pg_database WHERE datname='$database'" )" = '' ]
    then
        echo "Database '$database' does not exist on remote host! I quit now!"  >> $logfile
        exit 3
    fi
    schemas=$(psql -U postgres -d $database -t -c "SELECT SCHEMA_NAME FROM information_schema.schemata
                                                    WHERE SCHEMA_NAME NOT IN ('pg_toast',
                                                                              'pg_temp_1',
                                                                              'pg_toast_temp_1',
                                                                              'pg_catalog',
                                                                              'information_schema')")

    for schema in $schemas; do
        echo --$schema  >> $logfile
        if [ "$(psql -U $remoteUser -h $remoteHost -p $remotePort -tAc "SELECT SCHEMA_NAME FROM information_schema.schemata
                                                    WHERE SCHEMA_NAME='$schema'" )" = '' ]
        then
            echo "Schema '$schema' does not exist on remote host! I quit now!" >> $logfile
            exit 3
        fi
        tables=$(psql -U postgres -d $database -t -c "SELECT TABLE_NAME FROM information_schema.tables
                                                        WHERE table_schema = '$schema'")
        for table in $tables; do
            if [ "$(psql -U $remoteUser -h $remoteHost -p $remotePort -tAc "SELECT TABLE_NAME FROM information_schema.tables
                                                        WHERE table_name = '$table'" )" = '' ]
            then
                echo "table '$table' does not exist on remote host! I quit now!"  >> $logfile
                exit 3
            fi
            orderField=$(psql -U postgres -d $database -t -c "SELECT column_name FROM information_schema.columns
                                                                WHERE table_schema = '$schema'
                                                                  AND table_name   = '$table' LIMIT 1")

            #psql -U postgres -d $database -t -c "SELECT * FROM $table order by $orderField" > l.txt
            #fetch same table data on remote instance
            #psql -U $remoteUser -h $remoteHost -p $remotePort -d $database -t -c "SELECT * FROM $table order by $orderField" > r.txt
            #if !(cmp --print-chars "l.txt" "r.txt")
            lcl=$(psql -U postgres -d $database -t -c "SELECT * FROM $table order by $orderField")
            rmt=$(psql -U $remoteUser -h $remoteHost -p $remotePort -d $database -t -c "SELECT * FROM $table order by $orderField")
            if !("$lcl"="$rmt")
            then
               echo ---$table ✘  >> $logfile
               exit 3
            else
               echo ---$table ✔  >> $logfile
            fi          
        done
    done
done
rm l.txt r.txt
echo ------------------------------------------------------------------------------- >> $logfile
echo comparsion finished, sir! >> $logfile
exit 0