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

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

Есть ли способ разделить вывод mysqldump на более мелкие файлы? Я не могу использовать split (1), так как я не могу cat (1) восстановить файлы на удаленном сервере.

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

Edit

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

Ответ 1

Сначала выгрузите схему (она, безусловно, подходит для 2Mb, нет?)

mysqldump -d --all-databases 

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

Затем дамп только данные в отдельных инструкциях вставки, поэтому вы можете разделить файлы и восстановить их, не связывая их на удаленном сервере

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

Ответ 2

Этот сценарий 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 [email protected]_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 [email protected]_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
а также fooobar.com/questions/18939/...

Ответ 3

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

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 может обрабатывать эти файлы с вашим конкретным ограничением.

Ответ 5

Существует отличный сценарий 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 файл и сохранить его в сжатом формате базы данных name.sql.gz.

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

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

Выше команда создаст sqls для таблиц, соответствующих указанной регулярной Выражение из указанного файла "имя файла" mysqldump и сохранить его в сжатый формат для отдельной таблицы name.sql.gz.

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

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

Команда выше извлечет все базы данных из указанного "имени файла" MySQL файл и сохранить его в сжатом формате для отдельных базы данных name.sql.gz.

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

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

Команда выше извлечет все таблицы из указанного "имени файла" MySQL файл и сохранить его в сжатом формате для отдельных настольный name.sql.gz.

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

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

Команда выше извлечет таблицы из указанного "имени файла" MySQL файл и хранить их в сжатом формате для отдельных настольный name.sql.gz.

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

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

Команда выше распакует filename.sql.gz, используя gzip, extract база данных с именем "dbname" из "filename.sql.gz" & сохранить как из /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 из /dbname.sql

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

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

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

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

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

Extract single database: 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 с количеством строк для дальнейшего разделения дампа. split -l 10000 filename.sql

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

Ответ 6

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

Ответ 7

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

На вашем ПК вы можете сделать что-то вроде:

$mysqldump -u originaluser -poriginalpassword -h originalhost originaldatabase | mysql -u newuser -pnewpassword -h newhost newdatabase

и все готово.: -)

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

Ответ 8

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

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

Ответ 9

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

Ответ 10

Прояснение ответа @Vérace:

Мне особенно нравится интерактивный метод; вы можете разделить большой файл в Eclipse. Я пробовал 105GB файл в 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.

Ответ 11

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

Ответ 12

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

Ответ 13

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

sqldumpsplitter.com

Надеюсь на эту помощь.

Ответ 14

Этот script должен сделать это:

#!/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

Ответ 15

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

Ответ 16

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

Разрешить разбиение таблицы на "таблицы":

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}';

Ответ 17

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

Ответ 18

Я написал скрипт Python для разделения одного большого файла дампа sql на отдельные файлы, по одному для каждого оператора CREATE TABLE. Он записывает файлы в новую указанную вами папку. Если папка вывода не указана, в той же директории создается новая папка с тем же именем, что и у файла дампа. Он работает построчно, без предварительной записи файла в память, поэтому он отлично подходит для больших файлов.

https://github.com/kloddant/split_sql_dump_file

import sys, re, os

if sys.version_info[0] < 3:
    raise Exception("""Must be using Python 3.  Try running "C:\\Program Files (x86)\\Python37-32\\python.exe" split_sql_dump_file.py""")

sqldump_path = input("Enter the path to the sql dump file: ")

if not os.path.exists(sqldump_path):
    raise Exception("Invalid sql dump path.  {sqldump_path} does not exist.".format(sqldump_path=sqldump_path))

output_folder_path = input("Enter the path to the output folder: ") or sqldump_path.rstrip('.sql')

if not os.path.exists(output_folder_path):
    os.makedirs(output_folder_path)

table_name = None
output_file_path = None
smallfile = None

with open(sqldump_path, 'rb') as bigfile:
    for line_number, line in enumerate(bigfile):
        line_string = line.decode("utf-8")
        if 'CREATE TABLE' in line_string.upper():
            match = re.match(r"^CREATE TABLE (?:IF NOT EXISTS )?'(?P<table>\w+)' \($", line_string)
            if match:
                table_name = match.group('table')
                print(table_name)
                output_file_path = "{output_folder_path}/{table_name}.sql".format(output_folder_path=output_folder_path.rstrip('/'), table_name=table_name)
                if smallfile:
                    smallfile.close()
                smallfile = open(output_file_path, 'wb')
        if not table_name:
            continue
        smallfile.write(line)
    smallfile.close()