Я хочу, чтобы все базы данных начинались со слова.
abc
xyz
cms_db1
cms_db2
cms_xyz
pqr
В приведенном выше примере я хотел бы отбросить все базы данных со слова "cms". Я думаю, maatkit или shell script могут это сделать. Каков наилучший подход?
Я хочу, чтобы все базы данных начинались со слова.
abc
xyz
cms_db1
cms_db2
cms_xyz
pqr
В приведенном выше примере я хотел бы отбросить все базы данных со слова "cms". Я думаю, maatkit или shell script могут это сделать. Каков наилучший подход?
Путь к Linux:
#!/bin/bash
DB_STARTS_WITH="cms"
MUSER="root"
MPWD="yourpass"
MYSQL="mysql"
DBS="$($MYSQL -u$MUSER -p$MPWD -Bse 'show databases')"
for db in $DBS; do
if [[ "$db" =~ "^${DB_STARTS_WITH}" ]]; then
echo "Deleting $db"
$MYSQL -u$MUSER -p$MPWD -Bse "drop database $db"
fi
done
Конечно, используйте drop
часть на свой страх и риск;)
Здесь чисто mySQL-решение в двух запросах:
SELECT CONCAT('DROP DATABASE `', SCHEMA_NAME, '`;')
FROM `information_schema`.`SCHEMATA`
WHERE SCHEMA_NAME LIKE 'cms_%';
Затем скопируйте и вставьте полученный набор записей и запустите
Мне пришлось улучшать neurinos script из-за специальных символов в моем пароле, отсутствовала "drop DATABASE..." и не работало сравнение для выражения DB_STARTS_WITH. На сервере Ubuntu работало следующее script:
#!/bin/bash
DB_STARTS_WITH="grp"
MUSER="root"
MPWD="YOUR_PASSWORD"
MYSQL="mysql"
DBS="$($MYSQL -u $MUSER -p"$MPWD" -Bse 'show databases')"
for db in $DBS; do
if [[ "$db" == $DB_STARTS_WITH* ]]; then
echo "Deleting $db"
$MYSQL -u $MUSER -p"$MPWD" -Bse "drop database $db"
fi
done
Я бы использовал что-то вроде:
echo "SHOW DATABASES LIKE 'cms_%'" \
| mysql \
| tail -n +2 \
| xargs -n1 mysqladmin -f drop
Если у вас нет имени пользователя и пароля по умолчанию, установленного внутри ~/my.cnf
, вам может потребоваться указать имя пользователя и пароль с помощью переключателей -u
и -p
для команд mysql/mysqladmin выше.
(Edit - добавлено -n arg to tail.)
Если вы хотите полностью оставаться в пределах MySQL/MariaDB (т.е. без использования сценариев bash и т.д.), вы можете сделать следующее:
DELIMITER //
CREATE PROCEDURE clean()
BEGIN
SET @query := (SELECT CONCAT('DROP DATABASE ', SCHEMA_NAME, ';') FROM `information_schema`.`SCHEMATA` WHERE SCHEMA_NAME LIKE 'dbtVDB%' LIMIT 1);
WHILE @query != '' DO
PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @query := (SELECT CONCAT('DROP DATABASE ', SCHEMA_NAME, ';') FROM `information_schema`.`SCHEMATA` WHERE SCHEMA_NAME LIKE 'cms%' LIMIT 1);
END WHILE;
DELETE FROM mysql.db WHERE mysql.db.Db LIKE 'cms%';
END;
//
DELIMITER ;
CALL clean();
DROP PROCEDURE clean;
Способ Linux:
for db_name in $(mysql -u USER -pPASS -e "show databases like 'cms_%'" -ss)
do
mysql -u USER -pPASS -e "drop database ${db_name}";
done
Мне понравился ответ, предлагающий цикл "for" из оболочки. В моем случае у меня были имена подкаталогов, соответствующие моим именам базы данных, поэтому я сделал массивы, а затем использовал их в команде.
(Я мог бы сделать это, используя каталог данных mysql, чтобы подумать об этом, даже если бы у меня не было настроек, которые у меня были. На моем bitnami VM это /Опт/BitNami/MySQL/данные).
созданный массив из подмножества файлов: tbtdirs = (tbt * 2015 *)
Протестировать потенциально жуковую команду сначала w/ "echo": для d в ${tbtdirs [@]}; do echo mysql -pPASS -e "удалить базу данных $d"; сделано
опустил все базы данных в массиве: для d в ${tbtdirs [@]}; do mysql -pPASS -e "удалить базу данных $d"; сделано
Работал как шарм! Также был изменен цикл для удаления подкаталогов. Я довольно долго использовал командную строку Linux, прежде чем узнал, насколько полезны команды bash.
Используя @léo-alves-de-araujo, я изменил его, чтобы спросить пользователя/пароль (более безопасный путь) из командной строки (с помощью linux)
#!/bin/bash
echo -n "Enter Mysql User:"
read user
echo -n "Enter Mysql Password:"
read -s password
for db_name in $(mysql -u $user --password=$password -e "SHOW DATABASES LIKE 'cms_%'" -ss 2>/dev/null)
do
mysql -u $user --password=$password -e "DROP DATABASE ${db_name}" 2>/dev/null;
done
Улучшено решение @neurino, чтобы избежать хранения учетных данных MySQL в script и передачи их через командную строку (возможно, она будет видна в списке процессов)
#!/bin/bash
DB_STARTS_WITH="cms"
MYSQL="mysql"
read -p "Enter MySQL user name: " MYSQL_USER
read -s -p "Enter password: " MYSQL_PASSWORD
CREDENTIALS_FILE="$(mktemp)"
chmod 600 $CREDENTIALS_FILE
cat > $CREDENTIALS_FILE <<- EOM
[client]
user=$MYSQL_USER
password=$MYSQL_PASSWORD
EOM
trap "{ rm -f $CREDENTIALS_FILE; }" EXIT
DATABASES="$(echo "show databases;" | $MYSQL --defaults-file=$CREDENTIALS_FILE)"
for DATABASE in $DATABASES; do
if [[ $DATABASE =~ ^${DB_STARTS_WITH} ]]; then
echo Removing $DATABASE...
echo "drop database $DATABASE" | $MYSQL --defaults-file=$CREDENTIALS_FILE
fi
done
Импровизация на превосходном ответе @cloakedninjas, для облегчения поиска всех запросов для выполнения в одной строке.
Во-первых, вы можете установить максимальное значение для group_concat_max_len
на максимально возможное значение для этого конкретного сеанса:
SET SESSION group_concat_max_len = @@max_allowed_packet;
Теперь вы можете подготовить строку запроса (выполнить позже), используя SQL. Используя information_schema
, мы можем получить имя всех баз данных, соответствующих шаблону. Теперь используйте Concat()
для подготовки одного запроса DROP DATABASE ..
, а затем используйте Group_Concat()
, чтобы объединить их все в одну строку, чтобы упростить поиск.
SELECT GROUP_CONCAT(CONCAT('DROP DATABASE '', SCHEMA_NAME, '';')
SEPARATOR ' ') AS query_to_execute
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME LIKE 'cms_%'
Теперь скопируйте строку в query_to_execute
и запустите ее отдельно.