#php #mysql
#php #mysql
Вопрос:
У меня есть ДЕЙСТВУЮЩАЯ версия базы данных MySQL с 5 таблицами и ТЕСТОВАЯ версия.
Я постоянно использую phpMyAdmin, чтобы скопировать каждую таблицу из ТЕКУЩЕЙ версии в ТЕСТОВУЮ версию.
Есть ли у кого-нибудь инструкция mysql query для создания полной копии базы данных? Строка запроса должна учитывать структуру, данные, значения автоматического увеличения и любые другие вещи, связанные с таблицами, которые необходимо скопировать.
Спасибо.
Комментарии:
1. Из приведенных ниже комментариев следует, что это не может быть легко выполнено в инструкции запроса PHP / mysql из адресной строки браузера.
2. Все еще не похоже, что это выполнимо в PHP-скрипте, который можно запустить из адресной строки браузера.
3. Еще один комментарий… причина, по которой я хочу перенести моментальную копию ОПЕРАТИВНОЙ базы данных в ТЕСТОВУЮ базу данных, заключается в том, что когда мне нужно устранить проблему или реализовать расширенный код, я хочу протестировать его, прежде чем внедрять live. Итак, я хочу, чтобы top мог получать актуальную базу данных в любое время.
Ответ №1:
Хорошо, после долгих исследований, поиска в Google и прочтения комментариев всех присутствующих здесь, я создал следующий скрипт, который сейчас запускаю из адресной строки браузера. Протестировал его, и он делает именно то, что мне было нужно. Спасибо всем за помощь.
<?php
function duplicateTables($sourceDB=NULL, $targetDB=NULL) {
$link = mysql_connect('{server}', '{username}', '{password}') or die(mysql_error()); // connect to database
$result = mysql_query('SHOW TABLES FROM ' . $sourceDB) or die(mysql_error());
while($row = mysql_fetch_row($result)) {
mysql_query('DROP TABLE IF EXISTS `' . $targetDB . '`.`' . $row[0] . '`') or die(mysql_error());
mysql_query('CREATE TABLE `' . $targetDB . '`.`' . $row[0] . '` LIKE `' . $sourceDB . '`.`' . $row[0] . '`') or die(mysql_error());
mysql_query('INSERT INTO `' . $targetDB . '`.`' . $row[0] . '` SELECT * FROM `' . $sourceDB . '`.`' . $row[0] . '`') or die(mysql_error());
mysql_query('OPTIMIZE TABLE `' . $targetDB . '`.`' . $row[0] . '`') or die(mysql_error());
}
mysql_free_result($result);
mysql_close($link);
} // end duplicateTables()
duplicateTables('liveDB', 'testDB');
?>
Комментарии:
1. Внешний ключ не создается!
Ответ №2:
В зависимости от вашего доступа к серверу. Я предлагаю использовать прямые mysql
и mysqldump
команды. Это все, что phpMyAdmin делает под капотом.
Комментарии:
1. Но разве mysqldump не требует, чтобы вы подключались по telnet к серверу и запускали его из командной строки? Я делал это таким образом раньше, и в конечном итоге это требует таких же усилий вручную, как и использование phpMyAdmin. Я надеялся иметь скрипт, который я мог бы запустить из адресной строки браузера, чтобы сделать это быстрее.
2. Теоретически вы могли бы поместить эти команды в доступный через Интернет PHP-скрипт с помощью
exec()
. Однако я не рекомендую это из соображений безопасности.3. Спасибо, Джейсон. Я пытался делать некоторые другие сложные вещи в своих приложениях, используя exec (), и я никогда не мог заставить что-либо работать с exec () … есть много потоков stackoverflow для этого. Итак, я отказался от exec () — вероятно, в любом случае, это хорошая вещь.
Ответ №3:
Справочный материал для Mysqldump.
Комментарии:
1. У меня есть свой собственный набор документированных заметок и настроек, которым нужно следовать, используя mysqldump из командной строки. Я делал это таким образом много раз. Надеялся сделать это в PHP-скрипте. Если только mysqldump не может быть запущен через PHP…
2. вы можете запустить mysqldump через php, используя одну из функций выполнения системной программы
3. Спасибо @Xaade. Смотрите мой комментарий Джейсону ниже.
Ответ №4:
Для этого есть класс PHP, я его еще не тестировал.
Из описания:
This class can be used to backup a MySQL database.
It queries a database and generates a list of SQL statements that can be used later to restore the database **tables structure** and their contents.
Я думаю, это то, что вам нужно.
Комментарии:
1. Мне не нужна процедура «резервного копирования». Мне нужен скрипт, который берет всю базу данных и дублирует ее — как есть, со всеми ее данными, структурами и настройками одним нажатием кнопки. Мой www.domain.com сайт постоянно использует ТЕКУЩУЮ базу данных. Мой test.domain.com сайты постоянно используют ТЕСТОВУЮ базу данных. Итак, что я хочу сделать, это запустить duplicate_that_entire_db_as_is.php из адресной строки моего браузера. Я уже использую phpMyAdmin для ручного дублирования каждой таблицы при каждом использовании test.domain.com . Я просто пытаюсь устранить утомительность phpmyadmin
2. @Dr. Live db clone может привести к завершению работы вашего скрипта до того, как он завершит процесс копирования, плюс может зависнуть браузер (я запускаю в подобной ситуации), поэтому лучше сделать резервную копию базы данных в файле, затем восстановить ее в другой базе данных, наконец, удалить файл резервной копии, если в нем содержится конфиденциальная информация (электронная почта пользователя, пароль и т.д.).
3. Что каким-то образом и делает phpMyAdmin.
Ответ №5:
Привет, здесь вы можете использовать простой скрипт bash для резервного копирования всей базы данных.
######### SNIP BEGIN ##########
## Copy from here #############
#!/bin/bash
# to use the script do following:
# sh backup.sh DBNAME | sh
# where DBNAME is database name from alma016
# ex Backuping mydb data:
# sh backup.sh mydb hostname username pass| sh
echo "#sh backup.sh mydb hostname username pass| sh"
DB=$1
host=$2
user=$3
pass=$4
NOW=$(date "%m-%d-%Y")
FILE="$DB.backup.$NOW.gz"
# rest of script
#dump command:
cmd="mysqldump -h $host -u$user -p$pass $DB | gzip -9 > $FILE"
echo $cmd
############ END SNIP ###########
Редактировать
Если вы хотите клонировать резервную копию базы данных, просто отредактируйте дамп и измените имя базы данных, затем:
tar xzf yourdump.tar.gz| mysql -uusername -ppass
приветствую Армана.
Комментарии:
1. Просто для ясности, @Arman, «резервная копия» базы данных должна быть немедленно доступна как моя тестовая база данных. Итак, следуя вашему решению, будут ли мои PHP-скрипты работать с «резервной» базой данных? Кажется, вы создаете сжатую (архивированную) копию. Это не характер моего поста.
2. вы можете восстановить ее в другой database…it будет точно таким же, как ваша резервная копия.
3. Но опять же, если вам нужно скопировать таблицу, вы можете использовать инструкцию create table netab, подобную livetab; это также создаст indexss.
4. @Arman, я ищу что-нибудь, что я мог бы запустить из адресной строки браузера, чтобы обработать все это. Это выполнимо? Если, так на что это похоже?
5. Используйте простой php-скрипт, который вызывает bash-скрипт, например: sysexec («backup.sh «). где скрипт bash, например, передает выходные данные в mysql.
Ответ №6:
Что ж, в форме скрипта вы могли бы попробовать использовать
CREATE TABLE ... LIKE
синтаксис, перебирающий список таблиц, который вы можете получить из SHOW TABLES
.
Единственная проблема заключается в том, что индексы или внешние ключи не воссоздаются изначально. Таким образом, вам пришлось бы перечислить их и также создать. Затем несколько INSERT ... SELECT
вызовов для ввода данных.
Если ваша схема никогда не меняется, только данные. Затем создайте скрипт, который копирует структуру таблицы, а затем просто выполняйте INSERT ... SELECT
операции в транзакции.
В противном случае, mysqldump
как говорят другие, довольно легко заставить работать скрипт. У меня ежедневно запускается задание cron, которое выгружает всевозможные базы данных с серверов моего центра обработки данных, подключается через FTPS к моему местоположению и отправляет все выгрузки по всему. Это можно сделать, довольно эффективно. Очевидно, вы должны убедиться, что такие средства заблокированы, но опять же, не слишком сложно.
Согласно запросу кода
Код является собственностью, но я покажу вам критический раздел, который вам нужен. Это из середины foreach
цикла, отсюда continue
инструкции и $c..
переменные с префиксом (я использую это для указания переменных текущего цикла (или экземпляра)). echo
Команды могут быть любыми, какие вы хотите, это cron
скрипт, поэтому отображение текущего статуса было уместным. flush()
Строки полезны при запуске скрипта из браузера, поскольку выходные данные будут отправляться до этого момента, поэтому результаты браузера заполняются по мере выполнения, а не все отображаются в конце. ftp_fput()
Строка, очевидно, относится к моей ситуации с загрузкой дампа куда-либо и выгрузкой непосредственно из канала — вы могли бы использовать другой открытый процесс для передачи выходных данных в mysql
процесс для репликации базы данных. Предоставление подходящих поправок там, где они сделаны.
$cDumpCmd = $mysqlDumpPath . ' -h' . $dbServer . ' -u' . escapeshellarg($cDBUser) . ' -p' . escapeshellarg($cDBPassword) . ' ' . $cDatabase . (!empty($dumpCommandOptions) ? ' ' . $dumpCommandOptions : '');
$cPipeDesc = array(0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w'));
$cPipes = array();
$cStartTime = microtime(true);
$cDumpProc = proc_open($cDumpCmd, $cPipeDesc, $cPipes, '/tmp', array());
if (!is_resource($cDumpProc)) {
echo "failed.n";
continue;
} else {
echo "success.n";
}
echo "DB: " . $cDatabase . " - Uploading Database...";
flush();
$cUploadResult = ftp_fput($ftpConn, $dbFileName, $cPipes[1], FTP_BINARY);
$cStopTime = microtime(true);
if ($cUploadResult) {
echo "success (" . round($cStopTime - $cStartTime, 3) . " seconds).n";
$databaseCount ;
} else {
echo "failed.n";
continue;
}
$cErrorOutput = stream_get_contents($cPipes[2]);
foreach ($cPipes as $cFHandle) {
fclose($cFHandle);
}
$cDumpStatus = proc_close($cDumpProc);
if ($cDumpStatus != 0) {
echo "DB: " . $cDatabase . " - Dump process caused an error:n";
echo $cErrorOutput . "n";
continue;
}
flush();
Комментарии:
1. на что это похоже? Можете ли вы поделиться чем-нибудь о том, как это выглядит? Я знаю, как запускать задания crontab, но мне нужно что-то, что позволяет мне запускать его из адресной строки браузера, когда мне это нужно.
2. @Dr. DOT: Добавлен пример кода с объяснением, посмотрим, поможет ли это вам. Это часть скрипта, через который я запускаю
cron
— местоположение, в котором он находится, защищено обычными базовыми средствами аутентификации, и скрипт не взаимодействует с пользователем, поэтому на него нельзя повлиять, и он не выводит ничего с высоким уровнем безопасности, кроме имен баз данных, и нигде не связан, поэтому в любом случае вряд ли будет найден. В худшем случае кто-то может дважды запросить ежедневное резервное копирование, и он все равно обнаружит это и не выполнит.3. Я посмотрю на это и посмотрю, смогу ли я заставить это работать для меня — спасибо. К вашему сведению, я хочу иметь возможность запускать его в любое время, поэтому я не хочу обнаружения множественного выполнения. Еще раз спасибо.
4. @Dr. DOT: В этом конкретном фрагменте кода нет обнаружения множественного выполнения, так что не беспокойтесь об этом. Для вас особый интерес представляют элементы обработки процесса
proc_open()
и т.д.
Ответ №7:
Если вы используете Linux или Mac, вот одна строка для клонирования базы данных.
mysqldump -uUSER -pPASSWORD -hsample.host --single-transaction --quick test | mysql -uUSER -pPASSWORD -hqa.sample.host --database=test
«Преимущество» здесь в том, что он заблокирует базу данных во время ее создания копии.
Это означает, что в итоге вы получаете согласованную копию.
Это также означает, что ваша производственная база данных будет привязана на время копирования, что обычно не очень хорошо.
Без блокировок или транзакций, если что-то записывается в базу данных во время создания копии, вы могли бы в конечном итоге получить потерянные данные в вашей копии.
Чтобы получить хорошую копию без ущерба для производства, вам следует создать подчиненный сервер на другом сервере. Подчиненный сервер обновляется в режиме реального времени. Вы можете запустить ту же команду на подчиненном устройстве, не влияя на производительность.