Лучшая практика для переноса таблицы MySQL на другой сервер? - PullRequest
2 голосов
/ 25 июня 2009

У меня есть система, расположенная на «Мастер-сервере», которая периодически передает довольно много кусков информации из БД MySQL на другой сервер в сети.

На обоих серверах работают MySQL и Apache. Я хотел бы получить простое в использовании решение для этого.

В настоящее время я изучаю:

  • XMLRPC
  • RestFul Services
  • простой POST к скрипту обработки
  • розетка передачи

Приложение на моем мастере - это приложение TurboGears, поэтому я бы предпочел «питонические», а не менее уродливые решения. Копирование дамп-таблицы на другой сервер через FTP / SCP или что-то в этом роде может быть быстрым, но на мой взгляд это тоже очень (быстро и) грязно, и я бы хотел иметь более удачное решение.

Может ли кто-нибудь вкратце описать, как бы вы делали это "наилучшим образом"?

Это не обязательно должно включать базы данных. Вывод таблицы на сервер Server1 и структурированная передача необработанных данных таким образом, чтобы сервер server2 мог обрабатывать их без слишком большого разбора, также хорош. Одно требование: как только данные поступят на сервер2, я хочу, чтобы они обрабатывались, поэтому должно быть какое-то уведомление, когда передача будет выполнена. Конечно, я мог бы просто написать весь свой собственный сервер, сидящий в сокете на втором компьютере и принимающий файл с собственным кодом, обрабатывать его и т. Д., Но это всего лишь очень маленький фрагмент очень большой системы, поэтому я не хочу потратить полдня на реализацию этого.

Спасибо

Tom

Ответы [ 5 ]

2 голосов
/ 25 июня 2009

Сервер 1: преобразование строк в JSON, вызов API RESTful секунды с данными JSON

Сервер 2: прослушивает URI, например POST / data, получить преобразование данных json обратно в словарь или объекты ORM, вставить в db

sqlalchemy / sqlobject и simplejson - это то, что вам нужно.

1 голос
/ 25 июня 2009

Если таблица небольшая, и вы можете отправить всю таблицу и просто удалить старые данные, а затем вставить новые данные на удаленный сервер - тогда может быть простое общее решение: вы можете создать длинную строку с данными таблицы и отправить его через веб-сервис. Вот как это можно реализовать. Обратите внимание, что это далеко не идеальное решение, просто пример того, как я перемещаю небольшие простые таблицы между сайтами:

function DumpTableIntoString($tableName, $includeFieldsHeader = true)
{
  global $adoConn;

  $recordSet = $adoConn->Execute("SELECT * FROM $tableName");
  if(!$recordSet) return false;

  $data = "";

  if($includeFieldsHeader)
  {
    // fetching fields
    $numFields = $recordSet->FieldCount();
    for($i = 0; $i < $numFields; $i++)
      $data .= $recordSet->FetchField($i)->name . ",";
    $data = substr($data, 0, -1) . "\n";
  }

  while(!$recordSet->EOF)
  {
    $row = $recordSet->GetRowAssoc();
    foreach ($row as &$value)
    {
      $value = str_replace("\r\n", "", $value);
      $value = str_replace('"', '\\"', $value);
      if($value == null) $value = "\\N";
      $value = "\"" . $value . "\"";
    }
    $data .= join(',', $row);

    $recordSet->MoveNext();

    if(!$recordSet->EOF)
      $data .= "\n";
  }

  return $data;
}

// NOTE: CURRENTLY FUNCTION DOESN'T SUPPORT HANDLING FIELDS HEADER, SO NOW IT JUST SKIPS IT
// IF NECESSARRY
function FillTableFromDumpString($tableName, $dumpString, $truncateTable = true, $fieldsHeaderIncluded = true)
{
  global $adoConn;

  if($truncateTable)
    if($adoConn->Execute("TRUNCATE TABLE $tableName") === false)
      return false;


  $rows = explode("\n", $dumpString);
  $startRowIndex = $fieldsHeaderIncluded ? 1 : 0;

  $query = "INSERT INTO $tableName VALUES ";
  $numRows = count($rows);

  for($i = $startRowIndex; $i < $numRows; $i++)
  {
    $row = explode(",", $rows[$i]);

    foreach($row as &$value)
    {
      if($value == "\"\\N\"")
        $value = "NULL";
    }

    $query .= "(". implode(",", $row) .")";
    if($i != $numRows - 1)
      $query .= ",";
  }

  if($adoConn->Execute($query) === false)
  {
    return false;
  }

  return true;
}

Если у вас большие таблицы, то я думаю, что вам нужно отправлять только новые данные. Спросите у своего удаленного сервера о последней отметке времени, а затем прочитайте все более новые данные с вашего основного сервера и отправьте данные либо общим способом (как я показал выше), либо неуниверсальным способом (в этом случае вы должны написать отдельный функции для каждой таблицы).

0 голосов
/ 25 июня 2009

Если вы используете таблицы MyISAM или Archive, я настоятельно рекомендую mysqlhotcopy

0 голосов
/ 25 июня 2009

Если у вас есть доступ к порту данных MySQL и вы не против постоянного сетевого трафика, вы можете использовать replication .

0 голосов
/ 25 июня 2009

Предполагая, что ваша ситуация позволяет это с точки зрения безопасности, вы забыли об одном механизме транспорта: просто открываете соединение mysql с одного сервера на другой.

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

То, как вы будете действовать дальше, зависит от данных (это просто вставки для обработки? Нужно ли зеркально удалять? Сколько вставок и обновлений?) обработал его немедленно на сервере записи.

Кроме того, будет ли работать репликация на сервере MySQL или это будет чрезмерное решение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...