Domanda

Currently, I am using Master-Slave replication (MySQL) as backup plan. Master feed any update/insert query to slave database and I automatically set a schedule in slave server to do regular full backup. What I concern the most is that there could be a rare case that my slave might not have the same data as my master.

Is there any way that I can confirm that my slave has the same data as my master database. Usually, I randomly check the ID of some tables and if the latest ID are the same then I assume that it is more likely that both have the same data (at least, have the same number of rows).

This question could fit better in other StackExchange website such as StackExchange - Database Administrators and Serverfault, but I prefer it here because this site has the most active people, and this question is not totally irrelevant to programmer. However, feel free to move if you think it is inappropriate.

È stato utile?

Soluzione 2

I found a solution, but cannot be done directly from SQL, so I decide to write the following scripts:

<?php
    function tablesCheckSum($host, $database, $user, $pass) {
        try {
            $db = new PDO("mysql:host={$host}; dbname={$database}", $user, $pass);
            $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

            $result = $db->query('SHOW TABLES;')->fetchAll();

            // Construct tables
            foreach($result as $value) {
                $row = $db->query("CHECKSUM TABLE `" . $value[0] . "`")->fetch();
                $tables[substr($row[0], strlen($database) + 1)] = $row[1]; 
            }
        } catch(PDOException $ex) {
            print_r($ex->getMessage());
        }

        return $tables;
    }

    // Collecting all the 
    $db1 = tablesCheckSum('host1', 'db1', 'root', 'pass');
    $db2 = tablesCheckSum('host2', 'db1', 'root', 'pass');
?>


<table>
    <tr>
        <td>Table Name</td>
        <td>DB1 Checksum</td>
        <td>DB2 Checksum</td>
        <td>Matched?</td>
    </tr>
<?php
    foreach($db1 as $key => $value) {
?>
    <tr>
        <td><?php echo $key; ?></td>
        <td><?php echo $value; ?></td>
        <td><?php echo $db2[$key]; ?></td>
        <td><?php echo ($value == $db2[$key])?'True':'False'; ?></td>
    </tr>
<?php
    }
?>
</table>

Altri suggerimenti

One idea is to compare the total size of tables on the master and compare it to the total sie of the tables on the slave:

select sum(data_length + index_length) "Tables Size in Bytes"
from information_schema.tables;

Granted it will not tell you whether you have exactly the same data but what are the chances of the data being different but the size of the data being exactly the same?

EDIT

You could extend this further and create a sort of checksum value through concatenating the following meta data:

  • Total table rows

  • Total data length

  • Total index length

Something like this:

select cast(concat(sum(table_rows),sum(data_length),sum(index_length)) as char) as checkSum from information_schema.tables;

Just a thought....

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top