28

We have many databases in our MySQL and we want to shrink/purge ibdata1 file in MySQL.

How can we drop all the databases from the MySQL except information_schema and mysqld databases?

the
  • 21,007
  • 11
  • 68
  • 101
Sukhjinder Singh
  • 1,745
  • 2
  • 19
  • 26

5 Answers5

37

The following command drops all databases in the mysql dbms except mysql, information_schema and performance_schema dbs.

mysql -uroot -p<password> -e "show databases" | grep -v Database | grep -v mysql| grep -v information_schema| gawk '{print "drop database `" $1 "`;select sleep(0.1);"}' | mysql -uroot -p<password>

Thanks to Mohinish's Blog post

robrecord
  • 504
  • 5
  • 15
Sukhjinder Singh
  • 1,745
  • 2
  • 19
  • 26
  • there are 2 pipes one by one in the middle of the script, but yep, it's working when remove one – Vitali May 16 '17 at 13:13
  • or shorter: mysql -uroot -p -e "show databases" | egrep -v "Database|mysql|information_schema" |gawk '{print "drop database " $1 ";select sleep(0.1);"}' | mysql -uroot -p – johnjg12 1 hour ago – johnjg12 Jun 03 '17 at 00:05
  • 4
    If you have database names like "yyk2_db" the one-liner will fail. It this case just replace " $1 " with \`" $1 "\` – ivan133 Oct 25 '17 at 15:19
12

You can build a series of DROP DATABASE queries directly using MySQL :

-- Prevent truncation
SET SESSION group_concat_max_len = 1000000;

SELECT GROUP_CONCAT(
  DISTINCT CONCAT('DROP DATABASE ', table_schema, ';')
  SEPARATOR ''
)
FROM information_schema.tables
WHERE table_schema NOT IN ('mysql', 'information_schema');

Then execute the resulting string.

This solution has the virtue of not requiring a connection to the host serving the MySQL database.

Fabian Pijcke
  • 2,920
  • 25
  • 29
  • 3
    It looks like this fail is the DB name has dashes '-', thus backtick quoting might be needed, like `CONCAT('DROP DATABASE \`', table_schema, '\`;')` – sphakka Nov 30 '22 at 07:34
4

Both of these approaches remove all databases, besides mysql, information_schema and performance_schema.

Method 1. MYSQL Approach

Inspired by Fabian's answer, but lighter and catches empty databases. This approach generates the script via MYSQL query, then feeds it back to MYSQL. This method will likely be most compatible in terms of bash.

mysql -uroot -pMY_PASSWORD -s -N -e "SELECT GROUP_CONCAT(CONCAT('DROP DATABASE ', schema_name, ';') SEPARATOR ' ') FROM information_schema.schemata WHERE schema_name NOT IN ('mysql', 'information_schema', 'performance_schema');" | grep -v "NULL" | mysql -uroot -pMY_PASSWORD

Update. added -v "NULL" to avoid MYSQL errors in case there were no tables.


Method 2. Bash Approach

Inspired by Sukhjinder's answer, but tuned for better compatibility. This approach requests database names in raw format, does its bash magic, then feeds the code back to MYSQL. This method gives you more control over the code.

mysql -uroot -pMY_PASSWORD -e "show databases" -s -N | egrep -v "mysql|information_schema|performance_schema" | while read x ; do echo "DROP DATABASE $x;" ; done| tr '\n' ' ' | mysql -h"mysql" -uroot -pMY_PASSWORD
Timofey Drozhzhin
  • 4,416
  • 3
  • 28
  • 31
  • I like this bc, the other answer uses gawk, which I do not have installed. However, this fails for dbs with dashes in the name so, I had to modify it to use `"DROP DATABASE \\`$x\\`;"` instead of `"DROP DATABASE $x;"` – theannouncer Mar 16 '21 at 02:28
2

If you have cross-database foreign keys, or database names using MySQL reserved words such as 'order', this variation of Sukhjinder Singh's answer will work.

mysql -u<user> -p<password> -e "show databases" | grep -v Database | grep -v mysql | grep -v information_schema | gawk '{print "SET FOREIGN_KEY_CHECKS = 0;drop database" $1 ";select sleep(0.1);"}' | mysql -u<user> -p<password>

Sheldon Juncker
  • 587
  • 1
  • 5
  • 18
0

Follow this link - it demonstrate how to do this !

The used scrip is :

mysql -uroot -p -e "show databases" | grep -v Database |
grep -v mysql| grep -v information_schema| grep -v test |
grep -v OLD |gawk '{print "drop database " $1 ";select sleep(0.1);"}' |
mysql -uroot -ppassword
Up_One
  • 5,213
  • 3
  • 33
  • 65