我正在尝试完成连接到两个数据库的脚本,每个数据库位于不同的服务器上,并执行更新。基本上,从中选择和插入的表是相同的:我前几天进行了转储/导入。该脚本需要保持我的本地表最新的一次,因为将有每日记录插入远程的,我需要在本地保持最新。
这里的关键是我通过查看表共享的自动递增的主键SESSIONID
来确定远程服务器上的新行。我试图让我的循环在下面说,如果id存在于远程服务器而不是本地,则将这些记录插入本地服务器。
我通过键入php' filename'在powershell中运行以下脚本,然后我获得了两条成功的连接消息,但随后它挂起。大约10分钟后,它出现了内存错误,因此我添加了ini_set('memory_limit', '256M');
。在此之后它仍然会挂起大约10分钟,然后说MySQL服务器已经消失并且找不到结果头,这两个错误发生在我检查$rowCount
是否失败的行上
注意:在这种情况下,复制和大型转储/导入/表重新创建不适合我们。我们有几个类似的脚本运行,我们希望在这里保持相同的过程。我只是想解决这些错误,或者有人给我一种更有效的方法来编写这个脚本,也许是使用max id或类似的东西。
这是脚本:
ini_set('memory_limit', '256M');
// Create connection
$conn = new mysqli($servername, $username, $password);
$conn2 = new mysqli($servername2, $username2, $password2);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
// Check connection2
if ($conn2->connect_error) {
die("Connection failed: " . $conn2->connect_error);
}
echo "Connected successfully";
//Start queries
//Select All rows from the source phone database
$source_data = mysqli_query($conn, "select * from cdrdb.session");
// Loop on the results
while($source_item = $source_data->fetch_assoc()) {
// Check if row exists in destination phone database
$row_exists = $conn2->query("SELECT SESSIONID FROM ambition.session WHERE SESSIONID = '".$source_item['SESSIONID']."' ");
//if query returns false, rows don't exist with that new ID.
if (!$row_exists){
//Insert new rows into ambition.session
$conn2->query("INSERT INTO ambition.session (SESSIONID,SESSIONTYPE,CALLINGPARTYNO,FINALLYCALLEDPARTYNO,DIALPLANNAME,TERMINATIONREASONCODE,ISCLEARINGLEGORIGINATING,CREATIONTIMESTAMP,ALERTINGTIMESTAMP,CONNECTTIMESTAMP,DISCONNECTTIMESTAMP,HOLDTIMESECS,LEGTYPE1,LEGTYPE2,INTERNALPARTYTYPE1,INTERNALPARTYTYPE2,SERVICETYPEID1,SERVICETYPEID2,EXTENSIONID1,EXTENSIONID2,LOCATION1,LOCATION2,TRUNKGROUPNAME1,TRUNKGROUPNAME2,SESSIONIDTRANSFEREDFROM,SESSIONIDTRANSFEREDTO,ISTRANSFERINITIATEDBYLEG1,SERVICEEXTENSION1,SERVICEEXTENSION2,SERVICENAME1,SERVICENAME2,MISSEDUSERID2,ISEMERGENCYCALL,NOTABLECALLID,RESPONSIBLEUSEREXTENSIONID,ORIGINALLYCALLEDPARTYNO,ACCOUNTCODE,ACCOUNTCLIENT,ORIGINATINGLEGID,SYSTEMRESTARTNO,PATTERN,HOLDCOUNT,AUXSESSIONTYPE,DEVICEID1,DEVICEID2,ISLEG1ORIGINATING,ISLEG2ORIGINATING,GLOBALCALLID,CADTEMPLATEID,CADTEMPLATEID2,ts,INITIATOR,ACCOUNTNAME,APPNAME,CALLID,CHRTYPE,CALLERNAME,serviceid1,serviceid2)
VALUES ('".$source['SESSIONID']."' ,
'".$source['SESSIONTYPE']."' ,
'".$source['CALLINGPARTYNO']."' ,
'".$source['FINALLYCALLEDPARTYNO']."',
'".$source['DIALPLANNAME']."',
'".$source['TERMINATIONREASONCODE']."',
'".$source['ISCLEARINGLEGORIGINATING']."',
'".$source['CREATIONTIMESTAMP']."',
'".$source['ALERTINGTIMESTAMP']."',
'".$source['CONNECTTIMESTAMP']."',
'".$source['DISCONNECTTIMESTAMP']."',
'".$source['HOLDTIMESECS']."',
'".$source['LEGTYPE1']."',
'".$source['LEGTYPE2']."',
'".$source['INTERNALPARTYTYPE1']."',
'".$source['INTERNALPARTYTYPE2']."',
'".$source['SERVICETYPEID1']."',
'".$source['SERVICETYPEID2']."',
'".$source['EXTENSIONID1']."',
'".$source['EXTENSIONID2']."',
'".$source['LOCATION1']."',
'".$source['LOCATION2']."',
'".$source['TRUNKGROUPNAME1']."',
'".$source['TRUNKGROUPNAME2']."',
'".$source['SESSIONIDTRANSFEREDFROM']."',
'".$source['SESSIONIDTRANSFEREDTO']."',
'".$source['ISTRANSFERINITIATEDBYLEG1']."',
'".$source['SERVICEEXTENSION1']."',
'".$source['SERVICEEXTENSION2']."',
'".$source['SERVICENAME1']."',
'".$source['SERVICENAME2']."',
'".$source['MISSEDUSERID2']."',
'".$source['ISEMERGENCYCALL']."',
'".$source['NOTABLECALLID']."',
'".$source['RESPONSIBLEUSEREXTENSIONID']."',
'".$source['ORIGINALLYCALLEDPARTYNO']."',
'".$source['ACCOUNTCODE']."',
'".$source['ACCOUNTCLIENT']."',
'".$source['ORIGINATINGLEGID']."',
'".$source['SYSTEMRESTARTNO']."',
'".$source['PATTERN']."',
'".$source['HOLDCOUNT']."',
'".$source['AUXSESSIONTYPE']."',
'".$source['DEVICEID1']."',
'".$source['DEVICEID2']."',
'".$source['ISLEG1ORIGINATING']."',
'".$source['ISLEG2ORIGINATING']."',
'".$source['GLOBALCALLID']."',
'".$source['CADTEMPLATEID']."',
'".$source['CADTEMPLATEID2']."',
'".$source['ts']."',
'".$source['INITIATOR']."',
'".$source['ACCOUNTNAME']."',
'".$source['APPNAME']."',
'".$source['CALLID']."',
'".$source['CHRTYPE']."',
'".$source['CALLERNAME']."',
'".$source['serviceid1']."',
'".$source['serviceid2']."')");
}
}
答案 0 :(得分:3)
// Check if row exists in destination phone database
$row_exists = $conn2->query("SELECT SESSIONID FROM ambition.session WHERE SESSIONID = '".$source_item['SESSIONID']."' ");
//if query returns false, rows don't exist with that new ID.
if (!$row_exists){
这是不正确的:如果查询返回false,则查询无法执行。您需要检查if ($row_exists->num_rows == 0)
。您的代码现在的方式,它将始终一次又一次地插入每个记录。由于您没有检查INSERT
查询中的错误,因此您没有注意到SESSIONID
列的重复条目所导致的失败(我认为这是您当地的主键列数据库)。
此外,如果您只选择尚未拥有的会话,则可能会快得多。由于您正在使用自动增量列,因此您可以假设远程数据库中具有SESSIONID的任何内容都来自本地数据库中的最新SESSIONID之后是新的:
//Start queries
$latest_result = $conn2->query("SELECT MAX(`SESSIONID`) FROM `ambition`.`session`");
$latest_row = $latest->fetch_row();
$latest_session_id = $latest_row[0];
//Select All rows from the source phone database
$source_data = mysqli_query($conn, "SELECT * FROM `cdrdb`.`session` WHERE `SESSIONID` > $latest_session_id");
默认情况下,MySQL中的表通常按主键列排序,但如果您担心在本地数据库中插入数据的顺序,以防脚本因某种原因而中断,您可以添加查询的显式ORDER BY `SESSIONID` ASC
。