joegreen0991/db-sync

高效的 MySQL 数据对比和同步工具

v3.3.0 2017-04-10 12:06 UTC

README

Build Status Coverage Status Latest Stable Version License Total Downloads SensioLabsInsight

警告 - 此软件包会修改数据库表。请在运行前谨慎使用并备份数据库。

始终先执行干运行(这是默认操作),然后再指定 --execute (-e) 选项。

这是什么?

DbSync 是一个用于高效比较和同步两个或多个远程 MySQL 数据库表的工具。

为了在不比较每个数据字节的情况下完成此操作,该工具在源表和目标表上的一个行范围内执行校验和(MD5、SHA1、CRC32),并仅比较哈希。如果发现某个块存在不一致,则该工具将对块的每一半执行校验和,递归地进行(直到最小块传输大小),直到找到不一致。

关于删除的说明

当指定 --delete 选项时,DbSync 只会从目标中删除那些在源中不再存在的行。请谨慎使用此选项。始终先执行干运行。

如果您使用 DbSync 同步一个在源中有行删除操作,但没有使用 --delete 选项的表,DbSync 将在每次运行时发现任何有删除行的块中的不一致,但无法从目标中删除这些行。

安装

通过 composer - 在项目目录中运行以下命令

composer require mrjgreen/db-sync

或直接使用打包的存档

wget https://github.com/mrjgreen/db-sync/raw/v3/db-sync.phar -O db-sync.phar
chmod a+x db-sync.phar

可选:将命令设置为全局可用

sudo mv db-sync.phar /usr/bin/db-sync
Usage:
db-sync [options] <source> <target> <table>

Sync a mysql database table from one host to another using an efficient checksum algorithm to find differences.

Arguments:
  source                                     The source host ip to use.
  target                                     The target host ip to use.
  table                                      The fully qualified database table to sync.

Options:
  -b, --block-size=BLOCK-SIZE                The maximum block to use for when comparing. [default: 1024]
      --charset=CHARSET                      The charset to use for database connections. [default: "utf8"]
  -c, --columns=COLUMNS                      Columns to sync - all columns not "ignored" will be included....
  -C, --comparison=COMPARISON                Columns from the list of synced columns to use to create the...
  -f, --config-file=CONFIG-FILE              A path to a config.ini file from which to read values. [default: "dbsync.ini"]
      --delete                               Remove rows from the target table that do not exist in the source.
  -e, --execute                              Perform the data write on non-matching blocks.
  -h, --help                                 Show this usage information.
  -H, --hash                                 Specify the hash algorithm used to generate the comparison hash. [default: "md5"]
  -i, --ignore-columns=IGNORE-COLUMNS        Columns to ignore. Will not be copied or used to create the hash....
  -I, --ignore-comparison=IGNORE-COMPARISON  Columns to ignore from the hash. Columns will still be copied....
  -p, --password[=PASSWORD]                  The password for the specified user. Will be solicited on the tty if...
  -u, --user=USER                            The name of the user to connect with. [default: "USER"]
  -s, --transfer-size=TRANSFER-SIZE          The maximum copy size to use for when comparing. [default: 8]
      --target.user=TARGET.USER              The name of the user to connect to the target host with if different...
      --target.table=TARGET.TABLE            The name of the table on the target host if different to the source.
      --target.password=TARGET.PASSWORD      The password for the target host if the target user is specified....
      --where=WHERE                          A where clause to apply to the tables.
  -v, --verbose                              Enable verbose output.
  -q, --quiet                                Disable output, overrides "verbose" option.

示例

注意 - 所有这些命令都只执行“干运行”。要针对目标数据库执行插入/更新语句,您必须指定 --execute (-e) 选项

示例 1

从一台主机同步 web.customers 表到另一台主机(目标使用非标准端口)

db-sync --user root --password mypass 127.0.0.1 111.222.3.44:13306 web.customers
示例 2

从一台主机同步 web.customers 表到另一台主机,删除目标中不再存在的源行(使用 SHA1 哈希进行比较)

db-sync --user root --password mypass --hash sha1 --delete 127.0.0.1 111.222.3.44 web.customers
示例 3

使用不同的凭据从一台主机同步 web.customers 表到另一台主机

db-sync --user root --password mypass --target.user admin --target.password password 127.0.0.1 111.222.3.44 web.customers:
示例 4

仅同步 web.customers 表中的 emailname 字段

注意。主键将自动包含在列集中

db-sync --user root --password mypass 127.0.0.1 111.222.3.44 web.customers -c email -c name
示例 5

同步 web.customers 表中除 updated_at 字段外的所有列

db-sync --user root --password mypass 127.0.0.1 111.222.3.44 web.customers -i updated_at
示例 6

同步 web.customers 表中的所有列,但在计算哈希时仅使用 updated_at 字段

不会检测其他字段的不一致性。在包含的字段发生哈希不一致的情况下,仍会将排除的字段复制到目标主机。

db-sync --user root --password mypass 127.0.0.1 111.222.3.44 web.customers -C updated_at
示例 7

同步 web.customers 表中的所有列,并在计算哈希时使用所有字段,除了 notesinfo 字段

不会检测排除的字段的不一致性。在包含的字段发生哈希不一致的情况下,仍会将排除的字段复制到目标主机。

这对于具有长文本字段且在初始插入后不改变的表特别有用,或者与 on update CURRENT_TIMESTAMP 字段相关联的表。对于大型表,这可以提供很大的性能提升。

db-sync --user root --password mypass 127.0.0.1 111.222.3.44 web.customers -I notes -I info
示例 8

web.customers 表同步到不同数据库中不同名称的表 web_backup.customers_2

db-sync --user root --password mypass --target.table web_backup.customers_2 127.0.0.1 111.222.3.44 web.customers
示例 9

仅同步包含活动记录的表 web.customers,并删除目标表中的非活动记录

db-sync --user root --password mypass 127.0.0.1 111.222.3.44:13306 web.customers --delete --where="active = 1"

配置文件

为了避免重复指定选项,以及避免在tty上暴露您的密码,您可以指定一个配置文件。默认情况下,DbSync将在当前工作目录中查找名为dbsync.ini的文件。

示例

user=root
password=mypass
target.user=admin
target.password=myadminpass

在项目中使用库(非命令行)

您可以将库包含在您的项目中,并直接使用组件

use \DbSync\DbSync;
use \DbSync\Transfer\Transfer;
use \DbSync\Hash\ShaHash;
use \DbSync\Table;
use \DbSync\ColumnConfiguration;

$sync = new DbSync(new Transfer(new ShaHash(), $blockSize, $transferSize));

$sync->setLogger(new YourPsrLogger());

$sync->dryRun(false);

$sync->delete(true);

$sourceTable = new Table($sourceConnection, $sourceDb, $sourceTable);
$targetTable = new Table($targetConnection, $targetDb, $targetTable);

// if you only want specific columns 
$columnConfig = new ColumnConfiguration($syncColumns, $ignoreColumns);

// if you only want to use specific columns for the comparison
$compareConfig = new ColumnConfiguration($compareColumns, $ignoreCompareColumns);

// optionally apply a where clause - this can be useful when sync-ing large tables, where
// you can make use of a column to rule out large portions of the data
// that you know haven't changed, such as columns with "on update CURRENT_TIMESTAMP" etc..
$sourceTable->setWhereClause(new WhereClause("column_name = ?", ['value']));
$targetTable->setWhereClause(new WhereClause("column_name > ?", ['value']));

$sync->sync($sourceTable, $targetTable, $columnConfig, $compareConfig);

路线图

  • 通过全栈集成测试实现100%的测试覆盖率
  • 允许删除目标中不存在源数据的数据
  • 使用symfony控制台命令进行同步
  • 在锁定等待超时时,可以尝试重新尝试(带有退避策略)
  • 在目标中创建缺失的表
  • 跳过重复键错误
  • 加快空表的初始同步速度 - 可能会提供与其他工具结合使用以实现基于快速输出文件替换的组合

要求

PHP 5.4或更高版本的PDO MySQL扩展

许可证

DbSync受MIT许可证许可 - 有关详细信息,请参阅LICENSE文件

致谢

  • 本项目的灵感来源于Percona工具的pt-table-sync