每天同步不同机器上的两个 SQL 服务器数据库有什么好方法吗?
Is there a good way having two SQL Server Databases on Different machines synched daily?
我想要实现的是有两个不同的 SQL 服务器数据库,在两个 不同的 服务器上 运行 与 相同 SQL 服务器版本 ( SQL Server 2008 R2 RTM - 10.50.1600.1 ) 每天同步。同步意味着只是将新数据(甚至所有数据)从两个("parent" 数据库)之一传输到另一个("child" 数据库)。我们希望父级将其 shema 及其所有数据强制传递给其子级。
我已经尝试过的
知道 windows 服务器 2012 R2 上的两台机器 运行 我已经尝试实施解决方案(虽然我 不是专家 当它来到 SQL 服务器 ) 使用以下工具。
- PHP v7.2
- ExeOutputforPHP ( https://www.exeoutput.com/ )
- WinSCP(内置 ftp 方法 https://winscp.net )
- Schemazen ( https://github.com/sethreno/schemazen )
所以我会这样做:
- 使用PHP(服务器、用户、密码、数据库等)读取配置文件
- 当 PHP 不会产生任何错误时,我会触发 schemazen 脚本方法。
- 当一切顺利时,我会触发 winscp 的 ftp 方法到远程服务器
那将是出口方
现在是导入端
- 我会找到 ftp 目录并使用 Schemazen 创建方法,我会通过读取配置文件再次导入数据。
导出端代码
$iniConfig = parse_ini_file('..\conf.ini', true);
if ($iniConfig) {
echo PHP_EOL.'Configuration file found in '.realpath('..\conf.ini').PHP_EOL;
define('EXPORT_HOST', $iniConfig['export']['host']);
define('EXPORT_DB', $iniConfig['export']['db']);
define('EXPORT_DIR', $iniConfig['export']['dir']);
define('FTP_HOST', $iniConfig['ftp']['host']);
define('FTP_PATH_TO_SAVE', $iniConfig['ftp']['path']);
define('FTP_USERNAME', $iniConfig['ftp']['user']);
define('FTP_PASS', $iniConfig['ftp']['pass']);
define('PATH_TO_SAVE', $iniConfig['ftp']['path']);
$output = [];
$return_var = 0;
$credsFlag = '';
if ($iniConfig['export']['user'] && $iniConfig['export']['pass']) {
define('EXPORT_USER', $iniConfig['export']['user']);
define('EXPORT_PASS', $iniConfig['export']['pass']);
$credsFlag = ' -u '.EXPORT_USER.' -p '.EXPORT_PASS;
} else {
echo PHP_EOL.'Please Define the Username and Password for connection to the Database!'.PHP_EOL;
die();
}
$connArray = [
'Database' => EXPORT_DB,
'UID' => EXPORT_USER,
'PWD' => EXPORT_PASS,
];
$connection = sqlsrv_connect(EXPORT_HOST, $connArray);
if (!$connection) {
echo PHP_EOL.'Could not Connect to the Database!' . PHP_EOL . 'We received the following tried to connect:' . PHP_EOL;
print_r(sqlsrv_errors());
die();
}
$query = "select table_name from information_schema.tables where table_catalog = '" . EXPORT_DB . "'";
$tables = [];
$rs = sqlsrv_query($connection, $query);
while (($rd = sqlsrv_fetch_array($rs, SQLSRV_FETCH_ASSOC)) !== false) {
if ($rd) {
array_push($tables, $rd);
}
}
sqlsrv_close($connection);
$dataTablesString = '--dataTables=';
foreach ($tables as $table) {
$dataTablesString .= $table['table_name'].',';
}
exec('scriptor\SchemaZen.exe script -s '.EXPORT_HOST.' -b '.EXPORT_DB.$credsFlag.' -d '.EXPORT_DIR.' -o '.$dataTablesString, $output, $return_var);
if (-1 === $return_var) {
$file = fopen('ftp_script.txt', 'w+');
if ($file) {
$ftpStringToWrite = 'open ftp://'.FTP_USERNAME.':'.FTP_PASS.'@'.FTP_HOST.'/'.PHP_EOL.'cd '.FTP_PATH_TO_SAVE.PHP_EOL.'put '.EXPORT_DIR.'\*'.PHP_EOL.'exit';
$writer = fwrite($file, $ftpStringToWrite);
if ($writer) {
fclose($file);
unset($output);
exec('ftp\WinSCP.com /script=ftp_script.txt', $output, $return_var);
if (0 === $return_var) {
echo PHP_EOL.'Backup Exported and Transfered via FTP.'.PHP_EOL;
}
}
}
}
}
导入端代码
<?php
if ($iniConfig = parse_ini_file('../conf.ini', true)) {
define('IMPORT_HOST', $iniConfig['import']['host']);
define('IMPORT_DB', $iniConfig['import']['db']);
define('IMPORT_DB_AFTER', $iniConfig['settings']['databaseAfterFix']);
$credsFlags = '';
if ($iniConfig['import']['user'] && $iniConfig['import']['pass']) {
define('IMPORT_USER', $iniConfig['import']['user']);
define('IMPORT_PASS', $iniConfig['import']['pass']);
$credsFlags = ' -u '.IMPORT_USER.' -p '.IMPORT_PASS;
} else {
echo PHP_EOL.'Please Define the Username and Password for connection to the Database!'.PHP_EOL;
die();
}
$output = [];
$return_var = 0;
exec('scriptor\SchemaZen.exe create -s '.IMPORT_HOST.$credsFlags.' -o -b '.IMPORT_DB. ' -d ../../DBMigrate/'.$iniConfig['ftp']['path'].'', $output, $return_var);
foreach ($output as $message) {
echo $message.PHP_EOL;
}
if (0 !== $return_var) {
$error_log = fopen($iniConfig['settings']['errorlog'], 'a+');
if ($error_log) {
foreach ($output as $error) {
$writer = fwrite($error_log, '['.date('Y-m-d h:i:s').']'.$error.PHP_EOL);
}
$notify = mail($iniConfig['settings']['mail'], 'Import Error Encoutered!', 'Errors in Import of the Server.Please Check an error log should have been Created inside the folder /Data of the importer!');
if ($notify) {
echo PHP_EOL.'Mail sent about errors!'.PHP_EOL;
}
if ($writer) {
echo PHP_EOL.'Created Error LOg Please Check!'.PHP_EOL;
}
}
}
}
问题
最大的问题是我在我的本地环境中开发了这个测试,我 运行 宁一个不同的 SQL 服务器版本,当我试图在现场的暂存环境中进行测试时服务器我遇到了以下问题 https://github.com/sethreno/schemazen/issues/141
我真的很感激任何好的替代方案(特别是 SQL Server Managing Studio 中的内置工具,但我需要一些指导),或者任何可以应用于 Schemazen 的更正,因为它是开源的解决问题的项目。
根据您的要求,您可以简单地尝试 backup and restore which seems to satisfy your requirement. Alternatively try Replication,但这会大大增加复杂性。
也有多种工具可以做到这一点。如果你能付钱给他们 Redgate 工作得很好。我敢肯定也有免费的,但我没有使用它们的经验。
我不建议自己滚动。
有很多选择,我从最简单到最复杂列举了这些
- 备份并进一步还原
- 日志传送
- 快照或事务复制
- 数据库镜像
第一个选项的自动化可以使用命令 shell 完成:
https://blog.sqlauthority.com/2013/02/08/sql-server-backup-and-restore-database-using-command-prompt-sqlcmd/
其他一些引人注目的事情:
您 运行 服务器上 SQL Server 2008 R2 的 RTM 版本:
- 未打补丁,Microsoft 发布了 4 个服务包。 RTM 版本存在严重错误
- 此版本不支持
我想要实现的是有两个不同的 SQL 服务器数据库,在两个 不同的 服务器上 运行 与 相同 SQL 服务器版本 ( SQL Server 2008 R2 RTM - 10.50.1600.1 ) 每天同步。同步意味着只是将新数据(甚至所有数据)从两个("parent" 数据库)之一传输到另一个("child" 数据库)。我们希望父级将其 shema 及其所有数据强制传递给其子级。
我已经尝试过的
知道 windows 服务器 2012 R2 上的两台机器 运行 我已经尝试实施解决方案(虽然我 不是专家 当它来到 SQL 服务器 ) 使用以下工具。
- PHP v7.2
- ExeOutputforPHP ( https://www.exeoutput.com/ )
- WinSCP(内置 ftp 方法 https://winscp.net )
- Schemazen ( https://github.com/sethreno/schemazen )
所以我会这样做:
- 使用PHP(服务器、用户、密码、数据库等)读取配置文件
- 当 PHP 不会产生任何错误时,我会触发 schemazen 脚本方法。
- 当一切顺利时,我会触发 winscp 的 ftp 方法到远程服务器
那将是出口方
现在是导入端
- 我会找到 ftp 目录并使用 Schemazen 创建方法,我会通过读取配置文件再次导入数据。
导出端代码
$iniConfig = parse_ini_file('..\conf.ini', true);
if ($iniConfig) {
echo PHP_EOL.'Configuration file found in '.realpath('..\conf.ini').PHP_EOL;
define('EXPORT_HOST', $iniConfig['export']['host']);
define('EXPORT_DB', $iniConfig['export']['db']);
define('EXPORT_DIR', $iniConfig['export']['dir']);
define('FTP_HOST', $iniConfig['ftp']['host']);
define('FTP_PATH_TO_SAVE', $iniConfig['ftp']['path']);
define('FTP_USERNAME', $iniConfig['ftp']['user']);
define('FTP_PASS', $iniConfig['ftp']['pass']);
define('PATH_TO_SAVE', $iniConfig['ftp']['path']);
$output = [];
$return_var = 0;
$credsFlag = '';
if ($iniConfig['export']['user'] && $iniConfig['export']['pass']) {
define('EXPORT_USER', $iniConfig['export']['user']);
define('EXPORT_PASS', $iniConfig['export']['pass']);
$credsFlag = ' -u '.EXPORT_USER.' -p '.EXPORT_PASS;
} else {
echo PHP_EOL.'Please Define the Username and Password for connection to the Database!'.PHP_EOL;
die();
}
$connArray = [
'Database' => EXPORT_DB,
'UID' => EXPORT_USER,
'PWD' => EXPORT_PASS,
];
$connection = sqlsrv_connect(EXPORT_HOST, $connArray);
if (!$connection) {
echo PHP_EOL.'Could not Connect to the Database!' . PHP_EOL . 'We received the following tried to connect:' . PHP_EOL;
print_r(sqlsrv_errors());
die();
}
$query = "select table_name from information_schema.tables where table_catalog = '" . EXPORT_DB . "'";
$tables = [];
$rs = sqlsrv_query($connection, $query);
while (($rd = sqlsrv_fetch_array($rs, SQLSRV_FETCH_ASSOC)) !== false) {
if ($rd) {
array_push($tables, $rd);
}
}
sqlsrv_close($connection);
$dataTablesString = '--dataTables=';
foreach ($tables as $table) {
$dataTablesString .= $table['table_name'].',';
}
exec('scriptor\SchemaZen.exe script -s '.EXPORT_HOST.' -b '.EXPORT_DB.$credsFlag.' -d '.EXPORT_DIR.' -o '.$dataTablesString, $output, $return_var);
if (-1 === $return_var) {
$file = fopen('ftp_script.txt', 'w+');
if ($file) {
$ftpStringToWrite = 'open ftp://'.FTP_USERNAME.':'.FTP_PASS.'@'.FTP_HOST.'/'.PHP_EOL.'cd '.FTP_PATH_TO_SAVE.PHP_EOL.'put '.EXPORT_DIR.'\*'.PHP_EOL.'exit';
$writer = fwrite($file, $ftpStringToWrite);
if ($writer) {
fclose($file);
unset($output);
exec('ftp\WinSCP.com /script=ftp_script.txt', $output, $return_var);
if (0 === $return_var) {
echo PHP_EOL.'Backup Exported and Transfered via FTP.'.PHP_EOL;
}
}
}
}
}
导入端代码
<?php
if ($iniConfig = parse_ini_file('../conf.ini', true)) {
define('IMPORT_HOST', $iniConfig['import']['host']);
define('IMPORT_DB', $iniConfig['import']['db']);
define('IMPORT_DB_AFTER', $iniConfig['settings']['databaseAfterFix']);
$credsFlags = '';
if ($iniConfig['import']['user'] && $iniConfig['import']['pass']) {
define('IMPORT_USER', $iniConfig['import']['user']);
define('IMPORT_PASS', $iniConfig['import']['pass']);
$credsFlags = ' -u '.IMPORT_USER.' -p '.IMPORT_PASS;
} else {
echo PHP_EOL.'Please Define the Username and Password for connection to the Database!'.PHP_EOL;
die();
}
$output = [];
$return_var = 0;
exec('scriptor\SchemaZen.exe create -s '.IMPORT_HOST.$credsFlags.' -o -b '.IMPORT_DB. ' -d ../../DBMigrate/'.$iniConfig['ftp']['path'].'', $output, $return_var);
foreach ($output as $message) {
echo $message.PHP_EOL;
}
if (0 !== $return_var) {
$error_log = fopen($iniConfig['settings']['errorlog'], 'a+');
if ($error_log) {
foreach ($output as $error) {
$writer = fwrite($error_log, '['.date('Y-m-d h:i:s').']'.$error.PHP_EOL);
}
$notify = mail($iniConfig['settings']['mail'], 'Import Error Encoutered!', 'Errors in Import of the Server.Please Check an error log should have been Created inside the folder /Data of the importer!');
if ($notify) {
echo PHP_EOL.'Mail sent about errors!'.PHP_EOL;
}
if ($writer) {
echo PHP_EOL.'Created Error LOg Please Check!'.PHP_EOL;
}
}
}
}
问题
最大的问题是我在我的本地环境中开发了这个测试,我 运行 宁一个不同的 SQL 服务器版本,当我试图在现场的暂存环境中进行测试时服务器我遇到了以下问题 https://github.com/sethreno/schemazen/issues/141
我真的很感激任何好的替代方案(特别是 SQL Server Managing Studio 中的内置工具,但我需要一些指导),或者任何可以应用于 Schemazen 的更正,因为它是开源的解决问题的项目。
根据您的要求,您可以简单地尝试 backup and restore which seems to satisfy your requirement. Alternatively try Replication,但这会大大增加复杂性。
也有多种工具可以做到这一点。如果你能付钱给他们 Redgate 工作得很好。我敢肯定也有免费的,但我没有使用它们的经验。
我不建议自己滚动。
有很多选择,我从最简单到最复杂列举了这些
- 备份并进一步还原
- 日志传送
- 快照或事务复制
- 数据库镜像
第一个选项的自动化可以使用命令 shell 完成: https://blog.sqlauthority.com/2013/02/08/sql-server-backup-and-restore-database-using-command-prompt-sqlcmd/
其他一些引人注目的事情: 您 运行 服务器上 SQL Server 2008 R2 的 RTM 版本:
- 未打补丁,Microsoft 发布了 4 个服务包。 RTM 版本存在严重错误
- 此版本不支持