将MySQL表转移到另一个服务器的最佳实践是什么?
我有一个系统在一个“主服务器”上,定期将很多信息从MySQL数据库传输到网络上的另一台服务器。
这两台服务器上都运行着MySQL和Apache。我希望能找到一个简单易用的解决方案。
目前我在考虑:
- XMLRPC
- RestFul服务
- 一个简单的POST请求到处理脚本
- 套接字传输
我主服务器上的应用是一个TurboGears应用,所以我更喜欢“python风格”的,也就是看起来不那么复杂的解决方案。通过FTP或SCP将一个转储的表复制到另一台服务器可能很快,但在我看来,这种方法既快又脏,我希望能有一个更好的解决方案。
有没有人能简单描述一下你们会如何以“最佳实践”的方式来做这件事?
这不一定要涉及数据库。在服务器1上转储表格,并以结构化的方式传输原始数据,这样服务器2就可以处理,而不需要解析太多,也是可以的。不过有一个要求:一旦数据到达服务器2,我希望它能被立即处理,所以在传输完成时必须有某种通知。当然,我可以自己写一个服务器,放在第二台机器上,接受文件并处理等等,但这只是一个非常大的系统中的一小部分,所以我不想花半天时间来实现这个。
谢谢,
汤姆
5 个回答
如果你能访问MySQL的数据端口,并且不介意网络上不断传输的数据流量,你可以使用复制功能。
如果你的表格很小,可以把整个表格发过去,然后在远程服务器上删除旧数据,再插入新数据,这样就有一个简单的通用解决方案:你可以把表格的数据拼成一个长字符串,通过网络服务发送过去。下面是一个实现的例子。需要注意的是,这并不是完美的解决方案,只是我在不同网站之间传输小型简单表格的一种方法:
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;
}
如果你的表格很大,那我觉得你只需要发送新增的数据。你可以先询问远程服务器最新的数据时间戳,然后从你的主服务器读取所有更新的数据,再以通用的方式(就像我上面展示的那样)或者非通用的方式发送这些数据(在这种情况下,你需要为每个表格写单独的函数)。
服务器1:把数据行转换成JSON格式,然后用这些JSON数据去调用第二个服务器的RESTful API。
服务器2:监听一个网址,比如说POST /data,接收JSON数据,然后把它转换回字典或者ORM对象,再插入到数据库里。
你需要用到sqlalchemy/sqlobject和simplejson这两个工具。