Есть ли хороший способ синхронизировать две базы данных SQL Server на разных компьютерах ежедневно? - PullRequest
0 голосов
/ 28 января 2019

Чего я хотел бы добиться, так это иметь две разные базы данных SQL Server на двух разных серверах, на которых установлена ​​ одинаковая версия SQL Server ( SQL Server 2008 R2 RTM - 10.50.1600.1 ) для ежедневной синхронизации.Синхронизированное значение означает просто передачу новых данных (или даже всех данных) из одной из двух («родительская» база данных) в другую («дочерняя» база данных).Мы хотим, чтобы родитель передал свою shema, а также все свои данные своему дочернему элементу.

Что я уже пробовал

Зная, что две машины работают на Windows Server 2012 R2, я уже пыталсяреализовать решение (хотя я не эксперт , когда дело доходит до SQL Server), используя следующие инструменты.

Так что я бы сделал следующее:

  1. Чтение файла конфигурации с использованием PHP (сервер, пользователь, пароль, база данных и т. Д.)
  2. Когда PHP не выдаст никаких ошибокя бы вызвал метод сценария schemazen.
  3. Когда все прошло бы гладко, я бы запустил метод ftp winscp на удаленный сервер

Это было бы стороной экспорта

Теперь для импорта стороны

  1. Я бы найти каталог FTP и с помощьюСхема создания метода я бы импортировал данные снова, прочитав файл конфигурации.

Экспорт кода стороны

$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 Server, и когда я попытался провести тестирование в промежуточной среде на живых серверах, я столкнулся со следующей проблемой https://github.com/sethreno/schemazen/issues/141

Я был бы очень признателен за любую хорошую альтернативу (особенно встроенные инструменты в SQL Server Managing Studio, но мне потребовались бы некоторые рекомендации) или любое исправление, которое можно было бы применить к Schemazen с момента его открытия.Исходный проект для исправления проблемы.

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Существует множество опций, которые я перечислил от самых простых до самых сложных

  1. Резервное копирование с дальнейшим восстановлением
  2. Доставка журналов
  3. Репликация моментальных снимков или транзакций
  4. Зеркальное отображение базы данных

Автоматизация первого варианта может быть выполнена с помощью командной оболочки: https://blog.sqlauthority.com/2013/02/08/sql-server-backup-and-restore-database-using-command-prompt-sqlcmd/

Еще одна поразительная вещь: вы запускаете RTM-версию SQL Server 2008R2 на серверах:

  • Это исправлено, Microsoft выпустила 4 пакета обновления.RTM-версия имеет серьезные ошибки
  • Эта версия не поддерживает
0 голосов
/ 28 января 2019

В зависимости от ваших требований вы можете просто попробовать сделать резервную копию и восстановить , которая, кажется, удовлетворяет вашим требованиям.В качестве альтернативы попробуйте Репликация , но это значительно увеличивает сложность.

Существуют также различные инструменты, которые могут сделать это.Если вы можете заплатить за них, Redgate работают довольно хорошо.Я уверен, что есть и бесплатные, но у меня нет опыта работы с ними.

Я бы не советовал кататься самостоятельно.

...