自动将所有mysql表转储到单独的文件中?

use*_*841 64 mysqldump

我想将每个mysql表转储到单独的文件中.手册指出了这个的语法

mysqldump [options] db_name [tbl_name ...]
Run Code Online (Sandbox Code Playgroud)

这表示您事先知道了表名.我现在可以设置知道每个表名的脚本,但是说我在路上添加一个新表并忘记更新转储脚本.然后我错过了一个或多个表的转储.

有没有办法将每个现有表自动转储到单独的文件中?或者我将不得不做一些剧本; 查询数据库,获取所有表名,并按名称转储它们.

如果我使用script-fu路由,哪些脚本语言可以访问mysql数据库?

小智 59

mysqldump命令行程序为您完成此操作 - 尽管文档对此非常不清楚.

需要注意的一点是〜/ output/dir必须由拥有mysqld的用户写入.在Mac OS X上:

sudo chown -R _mysqld:_mysqld ~/output/dir
mysqldump --user=dbuser --password --tab=~/output/dir dbname
Run Code Online (Sandbox Code Playgroud)

运行上面的内容后,您将拥有一个tablename.sql文件,其中包含每个表的架构(create table statement)和包含该数据的tablename.txt文件.

如果只需要具有模式的转储,请添加--no-data标志:

mysqldump --user=dbuser --password --no-data --tab=~/output/dir dbname
Run Code Online (Sandbox Code Playgroud)

  • 好吧,我真的希望表格数据转储也是SQL插入:Þ (7认同)
  • mysqlimport可以用来导入结果数据txt文件。同样,任何包含句点(。)的表名,例如:my.table,都只会产生相同名称的数据文件(不带.txt扩展名)。http://dev.mysql.com/doc/refman/5.0/en/reloading-delimited-text-dumps.html另外,这似乎是每个文件转储执行`--single-transaction`表的唯一方法。 (2认同)
  • 请注意,此解决方案需要服务器具有[`FILE`](http://dev.mysql.com/doc/refman/5.7/en/privileges-provided.html#priv_file)权限,*并且*将写入文件放入服务器的磁盘中。 (2认同)
  • --tab 不会生成插入,例如,如果您想手动连接两台计算机上的数据库,则需要生成插入 (2认同)

Tru*_*ane 59

这是一个脚本,它将表数据作为SQL命令转储到单独的压缩文件中.它不需要在MySQL服务器主机上,也不需要在脚本中硬编码密码,而只是针对特定的数据库,而不是服务器上的所有数据库:

#!/bin/bash

# dump-tables-mysql.sh
# Descr: Dump MySQL table data into separate SQL files for a specified database.
# Usage: Run without args for usage info.
# Author: @Trutane
# Ref: http://stackoverflow.com/q/3669121/138325
# Notes:
#  * Script will prompt for password for db access.
#  * Output files are compressed and saved in the current working dir, unless DIR is
#    specified on command-line.

[ $# -lt 3 ] && echo "Usage: $(basename $0) <DB_HOST> <DB_USER> <DB_NAME> [<DIR>]" && exit 1

DB_host=$1
DB_user=$2
DB=$3
DIR=$4

[ -n "$DIR" ] || DIR=.
test -d $DIR || mkdir -p $DIR

echo -n "DB password: "
read -s DB_pass
echo
echo "Dumping tables into separate SQL command files for database '$DB' into dir=$DIR"

tbl_count=0

for t in $(mysql -NBA -h $DB_host -u $DB_user -p$DB_pass -D $DB -e 'show tables') 
do 
    echo "DUMPING TABLE: $DB.$t"
    mysqldump -h $DB_host -u $DB_user -p$DB_pass $DB $t | gzip > $DIR/$DB.$t.sql.gz
    tbl_count=$(( tbl_count + 1 ))
done

echo "$tbl_count tables dumped from database '$DB' into dir=$DIR"
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,这不能作为单个事务完成,因此您不一定会获得一系列可以在没有任何FK错误的情况下重新加载的文件. (6认同)

Eli*_*oyo 17

你可以通过以下方式完成

  1. 获取mysql中的数据库列表
  2. 转储每个数据库 mysqldump
# Optional variables for a backup script
MYSQL_USER="root"
MYSQL_PASS="something"
BACKUP_DIR=/srv/backup/$(date +%Y-%m-%dT%H_%M_%S);
test -d "$BACKUP_DIR" || mkdir -p "$BACKUP_DIR"
# Get the database list, exclude information_schema
for db in $(mysql -B -s -u $MYSQL_USER --password=$MYSQL_PASS -e 'show databases' | grep -v information_schema)
do
  # dump each database in a separate file
  mysqldump -u $MYSQL_USER --password=$MYSQL_PASS "$db" | gzip > "$BACKUP_DIR/$db.sql.gz"
done
Run Code Online (Sandbox Code Playgroud)

  • 问题是将每个*table*放在一个单独的文件中,而不是将每个数据库放在一个单独的文件中. (8认同)
  • 不完全是什么被质疑,但*确切*我正在寻找:-) (3认同)
  • @IgorLadela我在"$ db"附近添加了引号,试试看. (2认同)

Fra*_*bla 9

我最近需要备份一个大数据库(超过 250GB 的未压缩转储文件),我发现这个问题的答案非常有帮助。

我开始使用@Trutane 方法,它很有魅力。但我担心在不同的 mysql 会话中转储表,因为这可能在某些时刻导致备份不一致。

经过一些研究和测试,我开发了一种基于gawk. mysqldump基本思想是使用with创建整个数据库的转储--single-transaction=true,然后处理输出gawk,为每个表生成不同的文件。

所以我可以打电话:

mysqldump --single-transaction=true -u DBUSERNAME -p DBNAME | \
  gawk -v 'database=DBNAME' -f 'backup.awk' -
Run Code Online (Sandbox Code Playgroud)

它在当前文件夹中生成一堆$database.$table.sql包含每个表的架构的文件和$database.$table.sql.gz包含每个表的内容的文件。由于 param --single-transaction=true,所有转储都发生在单个事务中,并且确保了数据一致性。

其内容为backup.awk

# Split mysqldump output in different files, two per table:
# * First file is named $database.$table.sql and it contains the table schema
# * Second file is named $database.$table.sql.gz and it contains the table data 

# The 'database' variable is expected to be provided in command-line
BEGIN {
    insert=0
    filename=sprintf("%s.header.sql", database);
}

# A line starting with "INSERT INTO" activates inserting mode
/^INSERT INTO/      { insert=1 }

# A line containing "-- Table structure for table `name-of-table`" finishes inserting mode
# It is also used to detect table name and change file names accordingly
match($0, /-- Table structure for table `(.*)`/, m) {
    insert=0;
    table=m[1];
    filename=sprintf("%s.%s.sql", database, table);
    print sprintf("Dumping table %s", table);
}

# If in inserting mode, line is piped to a gzipped file,
# if it is not, it is redirected to an uncompressed schema file
{
    if (insert == 1) {
       output = sprintf("gzip > %s.gz", filename);
       print | output
    } else {
       print > filename;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 事实上,这是在单个事务中完成的,应该保证干净的备份,并且值得比迄今为止获得的更多荣誉(在我看来,还有另一个更笨拙的解决方案可以做到这一点) (2认同)

dja*_*adk 6

#!/bin/bash

for i in $(mysql -uUser -pPASSWORD DATABASE -e "show tables;"|grep -v Tables_in_);do mysqldump -uUSER -pPASSWORD DATABASE $i > /backup/dir/$i".sql";done

tar -cjf "backup_mysql_"$(date +'%Y%m%d')".tar.bz2" /backup/dir/*.sql
Run Code Online (Sandbox Code Playgroud)

  • 添加 -B 键以无边框的非表格输出格式打印表格 (3认同)

小智 5

这是相应的导入.

#!/bin/bash

# import-files-mysql.sh
# Descr: Import separate SQL files for a specified database.
# Usage: Run without args for usage info.
# Author: Will Rubel
# Notes:
#  * Script will prompt for password for db access.

[ $# -lt 3 ] && echo "Usage: $(basename $0) <DB_HOST> <DB_USER> <DB_NAME> [<DIR>]" && exit 1

DB_host=$1
DB_user=$2
DB=$3
DIR=$4

DIR=$DIR/*


echo -n "DB password: "
read -s DB_pass
echo
echo "Importing separate SQL command files for database '$DB' into '$DB'"

file_count=0


for f in $DIR

do 
    echo "IMPORTING FILE: $f"

    gunzip -c $f | mysql -h $DB_host -u $DB_user -p$DB_pass $DB

    (( file_count++ ))
done

echo "$file_count files importing to database '$DB'"
Run Code Online (Sandbox Code Playgroud)

  • 不要只是代码转储;请提供一些关于该代码的作用的解释。 (3认同)