Причина: мне было поручено запустить какой-то скрипт, который продвигает сайт, это фэнтезийный футбольный сайт, и есть несколько мгновений сайта, расположенного в разных доменах. В некоторых из них более 80 тыс. Пользователей, и каждый пользователь должен иметь команду, состоящую из 15 игроков. Следовательно, в некоторых таблицах есть строки Nousers x No.players.
Однако иногда скрипт терпит неудачу, и результат поврежден, поэтому я должен сделать резервную копию 10 таблиц, перед которыми я запускаю скрипт. Тем не менее, мне все еще нужно резервировать таблицы, чтобы сохранить историческую запись действий пользователей. Потому что футбольные матчи могут длиться более 50 игр.
Задача: дублировать таблицы db с помощью php-скрипта. Когда я начал, я использовал для резервного копирования таблицы с использованием sqlyog . это работает, но это требует много времени, так как я должен ждать, пока каждая таблица будет дублироваться. Кроме того, для больших таблиц приложение sqlyog вылетает во время дублирования больших таблиц, что может быть очень раздражающим.
Текущее решение: я создал простое приложение с интерфейсом, который выполняет эту работу, и он отлично работает. Он состоит из трех файлов, один для подключения к db, 2-й для манипуляции с db, 3-й для пользовательского интерфейса и для использования кода второго файла. Дело в том, что иногда оно застревает в середине процесса дублирования таблиц.
Цель: создать приложение, которое будет использоваться администратором для облегчения резервного копирования базы данных с использованием mysql + php.
Мой вопрос: как обеспечить, чтобы дублирующий скрипт полностью резервировал таблицу, не повесив сервер или не прерывая сценарий .
Здесь я буду включать мой код для дублирования функции, но в основном это две важные строки, которые, по моему мнению, находятся в них:
//duplicate tables structure $query = "CREATE TABLE $this->dbName.`$newTableName` LIKE $this->dbName.`$oldTable`"; //duplicate tables data $query = "INSERT INTO $this->dbName.`$newTableName` SELECT * FROM $this->dbName.`$oldTable`";
Остальная часть кода предназначена исключительно для проверки в случае возникновения ошибки. Если вы хотите взглянуть на весь код, будьте моим гостем. Вот функция:
private function duplicateTable($oldTable, $newTableName) { if ($this->isExistingTable($oldTable)) { $this->printLogger("Original Table is valid -table exists- : $oldTable "); } else { $this->printrR("Original Table is invalid -table does not exist- : $oldTable "); return false; } if (!$this->isExistingTable($newTableName))// make sure new table does not exist alrady { $this->printLogger("Distination Table name is valid -no table with this name- : $newTableName"); $query = "CREATE TABLE $this->dbName.`$newTableName` LIKE $this->dbName.`$oldTable`"; $result = mysql_query($query) or $this->printrR("Error in query. Query:\n $query\n Error: " . mysql_error()); } else { $this->printrR("Distination Table is invalid. -table already exists- $newTableName"); $this->printr("Now checking if tables actually match,: $oldTable => $newTableName \n"); $varifyStatus = $this->varifyDuplicatedTables($oldTable, $newTableName); if ($varifyStatus >= 0) { $this->printrG("Tables match, it seems they were duplicated before $oldTable => $newTableName"); } else { $this->printrR("The duplicate table exists, yet, doesn't match the original! $oldTable => $newTableName"); } return false; } if ($result) { $this->printLogger("Query executed 1/2"); } else { $this->printrR("Something went wrong duplicateTable\nQuery: $query\n\n\nMySql_Error: " . mysql_error()); return false; } if (!$this->isExistingTable($newTableName))//validate table has been created { $this->printrR("Attemp to duplicate table structure failed $newTableName table was not found after creating!"); return false; } else { $this->printLogger("Table created successfully: $newTableName"); //Now checking table structure $this->printLogger("Now comparing indexes ... "); $autoInc = $this->checkAutoInc($oldTable, $newTableName); if ($autoInc == 1) { $this->printLogger("Auto inc seems ok"); } elseif ($autoInc == 0) { $this->printLogger("No inc key for both tables. Continue anyways"); } elseif ($autoInc == -1) { $this->printLogger("No match inc key!"); } $time = $oldTable == 'team_details' ? 5 : 2; $msg = $oldTable == 'team_details' ? "This may take a while for team_details. Please wait." : "Please wait."; $this->printLogger("Sleep for $time ...\n"); sleep($time); $this->printLogger("Preparing for copying data ...\n"); $query = "INSERT INTO $this->dbName.`$newTableName` SELECT * FROM $this->dbName.`$oldTable`"; $this->printLogger("Processing copyign data query.$msg...\n\n\n"); $result = mysql_query($query) or $this->printrR("Error in query. Query:\n $query\n Error: " . mysql_error()); // ERROR usually happens here if large tables sleep($time); //to make db process current requeste. $this->printLogger("Query executed 2/2"); sleep($time); //to make db process current requeste. if ($result) { $this->printLogger("Table created ($newTableName) and data has been copied!"); $this->printLogger("Confirming number of rows ... "); ///////////////////////////////// // start checking count $numRows = $this->checkCountRows($oldTable, $newTableName); if ($numRows) { $this->printLogger("Table duplicated successfully "); return true; } else { $this->printLogger("Table duplicated, but, please check num rows $newTableName"); return -3; } // end of checking count ///////////////////////////////// }//end of if(!$result) query 2/2 else { $this->printrR("Something went wrong duplicate Table\nINSERT INTO $oldTable -> $newTableName\n\n$query\n mysql_error() \n " . mysql_error()); return false; } } }
Как вы заметили, функция только для дублирования одной таблицы, поэтому есть еще одна функция, которая берет массив таблиц от пользователя и передает массив имен таблиц один за другим для дублированияTable (). Любая другая функция должна быть включена для этого вопроса, пожалуйста, дайте мне знать.
Одно решение приходит мне на ум, дублирует таблицы по частям, добавляет какие-либо улучшения, я не уверен, как вставлять в работу, но, может быть, если бы я мог вставить, скажем, 25% за раз, это может помочь?