php 脚本比对两个数据库是否一致

<?php
//比较两个数据库是否一样
$db1 = '';
$db2 = '';
$db1_tables = [];
$db2_tables = [];
//db1
$db1_connect_info = array(
    'name'   => 'db1',                             //数据库名称
    'dbms'   => 'mysql',                             //数据库类型
    'host'   => '192.168.5.139',                     //数据库主机名
    'dbName' => 'test',                              //使用的数据库
    'user'   => 'root',                              //数据库连接用户名
    'pass'   => 'rootroot',                          //对应的密码
);
//db2
$db2_connect_info = array(
    'name'   => 'db2',                             //数据库名称
    'dbms'   => 'mysql',                             //数据库类型
    'host'   => '192.168.5.144',                     //数据库主机名
    'dbName' => 'test',                              //使用的数据库
    'user'   => 'root',                              //数据库连接用户名
    'pass'   => 'rootroot',                          //对应的密码
);
function init_mysql_connect(){
    global $db1;
    global $db2;
    global $db1_connect_info;
    global $db2_connect_info;
    try {
        $db1 = new PDO(
            $db1_connect_info['dbms'].':host='.$db1_connect_info['host'].';dbname='.$db1_connect_info['dbName'],
            $db1_connect_info['user'],
            $db1_connect_info['pass']
        ); //初始化一个PDO对象
        echo $db1_connect_info['name']."连接成功!".PHP_EOL;
    } catch (PDOException $e) {
        die ("Error!: " . $e->getMessage() . "<br/>");
    }
    try {
        $db2 = new PDO(
            $db2_connect_info['dbms'].':host='.$db2_connect_info['host'].';dbname='.$db2_connect_info['dbName'],
            $db2_connect_info['user'],
            $db2_connect_info['pass']
        ); //初始化一个PDO对象
        echo $db2_connect_info['name']."连接成功!".PHP_EOL;
    } catch (PDOException $e) {
        die ("Error!: " . $e->getMessage() . "<br/>");
    }
};

function init()
{
    $start_time = time();
    init_mysql_connect();
    diff_tables();
    diff_datas();
    $end_time = time();
    echo "开始时间:".date("Y-m-d H:i:s",$start_time).";".PHP_EOL;
    echo "结束时间:".date("Y-m-d H:i:s",$end_time).";".PHP_EOL;
    echo "用时:".($end_time-$start_time)." 秒;".PHP_EOL;
}
//比较数据
function diff_datas(){
    global $db1;
    global $db2;
    global $db1_tables;
    foreach ($db1_tables as $k1 => $v1) {
        //检查两个表的记录数是否相同
        $sql1 = "SELECT count(*) FROM ".$v1['TABLE_NAME'];
        $stmt = $db1->prepare($sql1);
        $stmt->execute();
        $table_count_1 = $stmt->fetch(PDO::FETCH_COLUMN);
        $stmt = $db2->prepare($sql1);
        $stmt->execute();
        $table_count_2 = $stmt->fetch(PDO::FETCH_COLUMN);
        if ($table_count_1 == $table_count_2) {
            echo "两个数据库的".$v1['TABLE_NAME']."表数据记录数量一致".PHP_EOL;
        } else {
            echo "ERROR: 两个数据库的".$v1['TABLE_NAME']."表数据记录数量不一致".PHP_EOL;
            exit();
        }
        // 循环比对数据
        $page_size=5000;
        $total_page=$table_count_2/$page_size;
        $cur_page=1;
        $sql = "SELECT * FROM ".$v1['TABLE_NAME']." LIMIT ?,?;";
        $stmt1 = $db1->prepare($sql);
        $stmt2 = $db2->prepare($sql);
        for ($i=0; $i < $total_page; $i++) {
            $start = ($cur_page-1)*$page_size;
            $stmt1->bindValue(1, $start, PDO::PARAM_INT);
            $stmt1->bindValue(2, $page_size, PDO::PARAM_INT);
            $stmt1->execute();
            $db1_datas = $stmt1->fetchAll(PDO::FETCH_ASSOC);
            $stmt2->bindValue(1, $start, PDO::PARAM_INT);
            $stmt2->bindValue(2, $page_size, PDO::PARAM_INT);
            $stmt2->execute();
            $db2_datas = $stmt2->fetchAll(PDO::FETCH_ASSOC);
            if(md5(json_encode($db1_datas))==md5(json_encode($db2_datas))){
                echo "两个数据库的".$v1['TABLE_NAME']."表数据记录".$start."-".($start+$page_size)."一致".PHP_EOL;
            }else {
                //找出那几条记录有问题
                $error_rows = [];
                foreach ($db1_datas as $k2 => $v2) {
                    if (md5(json_encode($v2)) != md5(json_encode($db2_datas[$k2]))) {
                        $error_rows[] = $v2['id'];
                    }
                }
                $error_id_str = implode(",", $error_rows);
                //退出
                echo "ERROR: 两个数据库的".$v1['TABLE_NAME']."表数据记录".$start."-".($start+$page_size)."不一致".PHP_EOL;
                echo "ERROR: DIFFERENT ID IS ".$error_id_str.PHP_EOL;
                exit();
            }
            $cur_page++;
        }
    }

}
//比较表结构
function diff_tables()
{
    global $db1;
    global $db2;
    global $db1_connect_info;
    global $db2_connect_info;
    global $db1_tables;
    global $db2_tables;
    //比较两个表的名字数量
    $sql1 = "SELECT TABLE_NAME FROM information_schema.`TABLES` WHERE TABLE_SCHEMA = '".$db1_connect_info['dbName']."'";
    $stmt = $db1->prepare($sql1);
    $stmt->execute();
    $db1_tables = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $db1_md5 = md5(json_encode($db1_tables));
    $sql2 = "SELECT TABLE_NAME FROM information_schema.`TABLES` WHERE TABLE_SCHEMA = '".$db2_connect_info['dbName']."'";
    $stmt = $db2->prepare($sql2);
    $stmt->execute();
    $db2_tables = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $db2_md5 = md5(json_encode($db2_tables));
    if ($db1_md5 == $db2_md5) {
        echo "db1 和 db2 数据库表数量和名称相同".PHP_EOL;
    }else {
        echo "ERROR: db1 和 db2 数据库表数量和名称不相同".PHP_EOL;
        exit;
    }
    //比较两个数据库之间表的结构
    foreach ($db2_tables as $key => $value) {
        $sql1 = "show create table ".$value['TABLE_NAME'];
        $stmt = $db1->prepare($sql1);
        $stmt->execute();
        $row1 = $stmt->fetch(PDO::FETCH_ASSOC);
        $stmt = $db2->prepare($sql1);
        $stmt->execute();
        $row2 = $stmt->fetch(PDO::FETCH_ASSOC);
        if (md5(json_encode($row1))==md5(json_encode($row2))) {
            echo "两个数据库的表".$value['TABLE_NAME']."结构相同".PHP_EOL;
        }else {
            echo "ERROR: 两个数据库的表".$value['TABLE_NAME']."结构不相同".PHP_EOL;
            exit;
        }
    }

}
init();

03-05 15:41