私は1日に一度自動的に更新されているmysqlテーブルがあります。このアップデートを行うスクリプトは、以下のPHPコードのようになります。基本的には、同じ構造の一時テーブルを作成し、最初にすべてのデータを挿入してから、実際のテーブルを切り捨てて一時テーブルからデータを挿入します。最後に一時テーブルが破棄されます。この方法は、実際の表の停止時間を大幅に短縮したために使用されます。ベーステーブルまたはビューが見つかりません - それは
これは、かなりの間、正常に動作していました。最近まで、Debianのアップグレード(Debian 8からDebian 9へ、これはMySQLからMariaDBへの切り替えも意味します)。ログファイルに次のエラーメッセージが表示されることがよくあります。
[Wed Sep 27 06:03:04.903652 2017] [:error] [pid 27393] [client 127.0.0.1:36794] PHP Fatal error: Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'database.table_temp' doesn't exist in /someFile.php:50\nStack trace:\n#0 /someFile.php(50): PDOStatement->execute()\n#1 {main}\n thrown in /someFile.php on line 50
このエラーは最終的に一部のデータが失われる原因となります。私が正しく理解していれば、挿入が完了する前に一時テーブルが破棄されたと言われます。これは実際にはTEMPORARY TABLE
ではないことを考慮して、どうやってこれを行うことができます、私はちょうど実際のテーブルを使用し、それをtemp
と名付けます。 MariaDBはINSERTを遅延させるので、PHPスクリプトはINSERTが完了する前にDROPを実行できますか?
スクリプトは本当に唯一の1日1回実行されるようにこれは、cron.dエントリです:
1 6 * * * root /usr/bin/wget -q http://www.example.com/someFile.php -O /dev/null
また、スクリプトは1時間か2時間、そうからの実行中に実行が完了していることは注目に値します前日は長く終わり、妨げにならない。
これは基本的にコードされ:
$dataArray = []; // much data
$db->query("DROP TABLE IF EXISTS `table_temp`;");
$db->query("CREATE TABLE `table_temp` LIKE `table`;");
$tres = $db->prepare("
INSERT INTO `table_temp`
(`field1`, `field2`)
VALUES
(:field1, :field2)
");
foreach($dataArray as $data){
$db->beginTransaction();
$res->execute();
foreach($data as $item){
$tres->bindParam('field1', $item['field1'], PDO::PARAM_INT);
$tres->bindParam('field2', $item['field2']);
$tres->execute(); // line 50
}
$db->commit();
}
$db->query("RENAME TABLE `table` TO `table_old`, `table_temp` TO `table`");
$db->query("DROP TABLE `table_old`");
'$ table-> query(" CREATE TABLE 'table_temp' LIKE')を待たなければならないので、 'table_temp'はprepare関数の前に作成されていませんでした。テーブル;; ");'それは正常に実行されました.. –
あなたのコードでWhats line 50? –
行50がコードにコメントされています。それは挿入クエリの実行です – user2015253