Как разделить вывод 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 может обрабатывать эти файлы с вашим конкретным ограничением.
Ответ 4
Поздний ответ, но он искал одно и то же решение и натолкнулся на следующий код ниже:
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
Ответ 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()