Как разделить вывод mysqldump на файлы меньшего размера?

StackOverflow https://stackoverflow.com/questions/132902

  •  02-07-2019
  •  | 
  •  

Вопрос

Мне нужно переместить целые таблицы из одной базы данных MySQL в другую.У меня нет полного доступа ко второму, только доступ phpMyAdmin.Я могу загружать только (сжатые) файлы sql размером менее 2 МБ.Но сжатый вывод mysqldump таблиц первой базы данных превышает 10 МБ.

Есть ли способ разделить вывод mysqldump на файлы меньшего размера?Я не могу использовать Split(1), так как не могу вернуть файлы на удаленный сервер с помощью Cat(1).

Или есть другое решение, которое я пропустил?

Редактировать

Опция --extended-insert=FALSE для mysqldump, предложенная первым автором, дает файл .sql, который затем можно разделить на импортируемые файлы, при условии, что функция Split(1) вызывается с подходящей опцией --lines.Методом проб и ошибок я обнаружил, что bzip2 сжимает файлы .sql в 20 раз, поэтому мне нужно было выяснить, сколько строк кода sql соответствует примерно 40 МБ.

Это было полезно?

Решение

Сначала сбросьте схему (она ведь умещается в 2Мб, нет?)

mysqldump -d --all-databases 

и восстановить его.

После этого выгружайте только данные в отдельные операторы вставки, чтобы вы могли разделить файлы и восстановить их без необходимости объединять их на удаленном сервере.

mysqldump --all-databases --extended-insert=FALSE --no-create-info=TRUE

Другие советы

Этот bash-скрипт разбивает файл дампа одной базы данных на отдельные файлы для каждой таблицы и имен с помощью csplit и называет их соответственно:

#!/bin/bash

####
# Split MySQL dump SQL file into one file per table
# based on https://gist.github.com/jasny/1608062
####

#adjust this to your case:
START="/-- Table structure for table/"
# or 
#START="/DROP TABLE IF EXISTS/"


if [ $# -lt 1 ] || [[ $1 == "--help" ]] || [[ $1 == "-h" ]] ; then
        echo "USAGE: extract all tables:"
        echo " $0 DUMP_FILE"
        echo "extract one table:"
        echo " $0 DUMP_FILE [TABLE]"
        exit
fi

if [ $# -ge 2 ] ; then
        #extract one table $2
        csplit -s -ftable $1 "/-- Table structure for table/" "%-- Table structure for table \`$2\`%" "/-- Table structure for table/" "%40103 SET TIME_ZONE=@OLD_TIME_ZONE%1"
else
        #extract all tables
        csplit -s -ftable $1 "$START" {*}
fi

[ $? -eq 0 ] || exit

mv table00 head

FILE=`ls -1 table* | tail -n 1`
if [ $# -ge 2 ] ; then
        mv $FILE foot
else
        csplit -b '%d' -s -f$FILE $FILE "/40103 SET TIME_ZONE=@OLD_TIME_ZONE/" {*}
        mv ${FILE}1 foot
fi

for FILE in `ls -1 table*`; do
        NAME=`head -n1 $FILE | cut -d$'\x60' -f2`
        cat head $FILE foot > "$NAME.sql"
done

rm head foot table*

на основе https://gist.github.com/jasny/1608062
и https://stackoverflow.com/a/16840625/1069083

Вы говорите, что у вас нет доступа ко второму серверу.Но если у вас есть доступ к первому серверу, где находятся таблицы, вы можете разделить дамп по таблицам:

for T in `mysql -N -B -e 'show tables from dbname'`; \
   do echo $T; \
   mysqldump [connecting_options] dbname $T \
   | gzip -c > dbname_$T.dump.gz ; \
   done

Это создаст файл gzip для каждой таблицы.

Другой способ разделения вывода mysqldump на отдельные файлы — использование опции --tab.

mysqldump [connecting options] --tab=directory_name dbname 

где имя_каталога это имя пустого каталога.Эта команда создает файл .sql для каждой таблицы, содержащий инструкцию CREATE TABLE, и файл .txt, содержащий данные, которые необходимо восстановить с помощью LOAD DATA INFILE.Однако я не уверен, сможет ли phpMyAdmin обрабатывать эти файлы с вашими конкретными ограничениями.

Поздний ответ, но искал то же решение и наткнулся на следующий код на веб-сайте ниже:

for I in $(mysql -e 'show databases' -s --skip-column-names); do mysqldump $I | gzip > "$I.sql.gz"; done

http://www.commandlinefu.com/commands/view/2916/backup-all-mysql-databases-to-individual-files

есть вот это отличное mysqldumpsplitter скрипт, который имеет массу возможностей для извлечения из mysqldump.

Я бы скопировал рецепт сюда, чтобы выбрать свой случай из:

1) Извлеките одну базу данных из mysqldump:

sh mysqldumpsplitter.sh --source filename --extract DB --match_str database-name

Приведенная выше команда создаст SQL для указанной базы данных из указанного файла SQL «FileName» и сохранить его в сжатом формате для базы данных name.sql.gz.

2) Извлеките одну таблицу из mysqldump:

sh mysqldumpsplitter.sh --source filename --extract TABLE --match_str table-name

Приведенная выше команда создаст SQL для указанной таблицы из указанного файла MySqldump «FileName» и сохранить его в сжатом формате для базы данных name.sql.gz.

3) Извлеките таблицы, соответствующие регулярному выражению, из mysqldump:

sh mysqldumpsplitter.sh --source filename --extract REGEXP --match_str regular-expression

Приведенная выше команда создаст SQLS для таблиц, соответствующих указанному регулярному выражению из указанного файла «Filename» MySQldump и хранить его в сжатом формате для отдельного таблицы name.sql.gz.

4) Извлеките все базы данных из mysqldump:

sh mysqldumpsplitter.sh --source filename --extract ALLDBS

Приведенная выше команда извлекает все базы данных из указанного файла MySqldump «FileName» и сохранит его в сжатом формате в отдельный базу данных name.sql.gz.

5) Извлеките всю таблицу из mysqldump:

sh mysqldumpsplitter.sh --source filename --extract ALLTABLES

Приведенная выше команда извлечет все таблицы из указанного файла MySqldump «FileName» и сохранить его в сжатом формате в отдельный Table-name.sql.gz.

6) Извлеките список таблиц из mysqldump:

sh mysqldumpsplitter.sh --source filename --extract REGEXP --match_str '(table1|table2|table3)'

Приведенная выше команда будет извлекать таблицы из указанного файла MySqldump «Filename» и хранить их в сжатом формате в отдельный Table-name.sql.gz.

7) Извлеките базу данных из сжатого mysqldump:

sh mysqldumpsplitter.sh --source filename.sql.gz --extract DB --match_str 'dbname' --decompression gzip

Приведенная выше команда будет распаковывать fileName.sql.gz с использованием gzip, извлечения базы данных с именем «dbname» из «filename.sql.gz» и сохранить ее как out/dbname.sql.gz

8) Извлеките базу данных из сжатого MySQldump в несжатом формате:

sh mysqldumpsplitter.sh --source filename.sql.gz --extract DB --match_str 'dbname' --decompression gzip --compression none

Приведенная выше команда будет декомпрессат filename.sql.gz с использованием базы данных GZIP и извлечения с именем «dbname» из «filename.sql.gz» и сохраните ее в виде простого sql Out/dbname.sql

9) Извлеките все таблицы из mysqldump в другую папку:

sh mysqldumpsplitter.sh --source filename --extract ALLTABLES --output_dir /path/to/extracts/

Приведенная выше команда извлекает все таблицы из указанного файла MySqldump «Filename» и извлечет таблицы в сжатый формат в отдельные файлы, Table-name.sql.gz, хранящийся в/path/to/extracts/.Сценарий создаст папку/path/to/извлекать/если нет.

10) Извлеките одну или несколько таблиц из одной базы данных в полный дамп:

Считайте, что у вас есть полный дамп с несколькими базами данных, и вы хотите извлечь несколько таблиц из одной базы данных.

Извлеките одну базу данных: sh mysqldumpsplitter.sh --source filename --extract DB --match_str DBNAME --compression none

Извлечь все таблицы sh mysqldumpsplitter.sh --source out/DBNAME.sql --extract REGEXP --match_str "(tbl1|tbl2)" хотя мы можем использовать другой вариант, чтобы сделать это с помощью одной команды, следующим образом:

sh mysqldumpsplitter.sh --source filename --extract DBTABLE --match_str "DBNAME.(tbl1|tbl2)" --compression none

Приведенная выше команда извлекает как TBL1, так и TBL2 из базы данных DBNAME в формате SQL в папке «Out» в текущем каталоге.

Вы можете извлечь одну таблицу следующим образом:

sh mysqldumpsplitter.sh --source filename --extract DBTABLE --match_str "DBNAME.(tbl1)" --compression none

11) Извлеките все таблицы из конкретной базы данных:

mysqldumpsplitter.sh --source filename --extract DBTABLE --match_str "DBNAME.*" --compression none

Приведенная выше команда извлечет все таблицы из базы данных DBNAME в формате SQL и сохранит их в каталоге «Out».

12) Перечислите содержимое файла mysqldump.

mysqldumpsplitter.sh --source filename --desc

Приведенная выше команда выведет список баз данных и таблиц из файла дампа.

Позже вы можете выбрать загрузку файлов:zcat filename.sql.gz | mysql -uuser -p -hhostname

  • Кроме того, как только вы извлечете одну таблицу, которая, по вашему мнению, все еще больше, вы можете использовать команду разделения Linux с количеством строк для дальнейшего разделения дампа.split -l 10000 filename.sql

  • Тем не менее, если вам это нужно (приходит чаще), вы можете рассмотреть возможность использования мой дампер который фактически создает отдельные дампы, которые вам не придется разделять!

Я недавно создал sqlsplit.com.Попробуйте это.

Вам не нужен доступ по SSH ни к одному из ваших серверов.Просто клиент mysql[dump] подойдет.С помощью mysql[dump] вы можете сбросить базу данных и снова импортировать ее.

На вашем компьютере вы можете сделать что-то вроде:

$ mysqldump -u OriginalUser -poriginalPassword -h OriginalHost OriginalDatabase | mysql -u newuser -pnewpassword -h newhost newdatabase

и вы сделали.:-)

надеюсь это поможет

Вы можете сбросить отдельные таблицы с помощью mysqldump, запустив mysqldump database table1 table2 ... tableN

Если ни одна из таблиц не слишком велика, этого будет достаточно.В противном случае вам придется начать разбивать данные на более крупные таблицы.

Я бы порекомендовал утилиту bigdump, ее можно скачать здесь. http://www.ozerov.de/bigdump.phpэто замедляет выполнение дампа, насколько это возможно, до вашего предела, выполняя целые строки за раз.

Разъяснение ответа @Vérace:

Мне особенно нравится интерактивный метод;вы можете разделить большой файл в Eclipse.Я успешно попробовал файл размером 105 ГБ в Windows:

Просто добавьте библиотеку MySQLDumpSplitter в свой проект:http://dl.bintray.com/verace/MySQLDumpSplitter/jar/

Краткое примечание о том, как импортировать:

- In Eclipse, Right click on your project --> Import
- Select "File System" and then "Next"
- Browse the path of the jar file and press "Ok"
- Select (thick) the "MySQLDumpSplitter.jar" file and then "Finish"
- It will be added to your project and shown in the project folder in Package Explorer in Eclipse
- Double click on the jar file in Eclipse (in Package Explorer)
- The "MySQL Dump file splitter" window opens which you can specify the address of your dump file and proceed with split.

Попробуйте csplit(1), чтобы разбить вывод на отдельные таблицы на основе регулярных выражений (я думаю, в соответствии с границей таблицы).

Этот сценарий должен сделать это:

#!/bin/sh

#edit these
USER=""
PASSWORD=""
MYSQLDIR="/path/to/backupdir"

MYSQLDUMP="/usr/bin/mysqldump"
MYSQL="/usr/bin/mysql"

echo - Dumping tables for each DB
databases=`$MYSQL --user=$USER --password=$PASSWORD -e "SHOW DATABASES;" | grep -Ev "(Database|information_schema)"`
for db in $databases; do
    echo - Creating "$db" DB
    mkdir $MYSQLDIR/$db
    chmod -R 777 $MYSQLDIR/$db
    for tb in `$MYSQL  --user=$USER --password=$PASSWORD -N -B -e "use $db ;show tables"`
        do 
            echo -- Creating table $tb
            $MYSQLDUMP --opt  --delayed-insert --insert-ignore --user=$USER --password=$PASSWORD $db $tb | bzip2 -c > $MYSQLDIR/$db/$tb.sql.bz2
    done
    echo
done

Посмотрите SQLDumpSplitter 2, я только что использовал его, чтобы успешно разделить дамп размером 40 МБ.Вы можете получить его по ссылке ниже:

sqldumpsplitter.com

Надеюсь, это поможет.

Я создал MySQLDumpSplitter.java, который, в отличие от сценариев Bash, работает в Windows.Это доступно здесь https://github.com/Verace/MySQLDumpSplitter.

Вы можете разделить существующий файл с помощью AWK.Это очень быстро и просто

Давайте разделим дамп таблицы по «таблицам»:

cat dump.sql | awk 'BEGIN {output = "comments"; }
$data ~ /^CREATE TABLE/ {close(output); output = substr($3,2,length($3)-2); }
{ print $data >> output }';

Или вы можете разделить дамп по «базе данных»

cat backup.sql | awk 'BEGIN {output="comments";} $data ~ /Current Database/ {close(output);output=$4;} {print $data>>output}';

Попробуй это: https://github.com/shenli/mysqldump-hugetableОн будет сбрасывать данные во множество небольших файлов.Каждый файл содержит меньше или равно MAX_RECORDS записей.Вы можете установить этот параметр в env.sh.

Я написал новую версию SQLDumpSplitter, на этот раз с подходящим парсером, позволяющим разбивать по файлам такие приятные вещи, как INSERT с множеством значений, и теперь это многоплатформенная версия: https://philiplb.de/sqldumpsplitter3/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top