Нарезка дампа c mysql-базами на отдельные базы или таблицы: различия между версиями

Материал из Linux Wiki
Перейти к навигацииПерейти к поиску
(Новая: Cкрипт предназначен для разрезания MySQL-дампа с несколькими базами на отдельные базы. Файлы именуются ...)
 
м (для красоты :))
 
(не показано 18 промежуточных версий этого же участника)
Строка 1: Строка 1:
Cкрипт предназначен для разрезания MySQL-дампа с несколькими базами на отдельные базы. Файлы именуются по принципу название_базы.номер_в_общем_дампе.sql
== Разбивка дампа на базы ==
 
Cкрипт предназначен для разрезания MySQL-дампа с несколькими базами на отдельные базы. Файлы именуются по принципу '''название_базы.номер_в_общем_дампе.sql'''


; Использование: ./db_split.sh файл_дампа.sql каталог_куда_складывать_дампы
; Использование: ./db_split.sh файл_дампа.sql каталог_куда_складывать_дампы
Строка 5: Строка 7:
----
----
<source lang=bash>
<source lang=bash>
#!/bin/bash
#!/bin/bash                                                                                                                  
# By Rain ;)
# By Rain ;)


Строка 11: Строка 13:
# Изменен 2008-04-17: добавлено описание
# Изменен 2008-04-17: добавлено описание
# Изменен 2008-04-18: добавлено удаление "USE DATABASE" в начале дампов
# Изменен 2008-04-18: добавлено удаление "USE DATABASE" в начале дампов
# Изменен 2009-06-08: переписал с использованием awk


# Файл для резки
# Проверка передачи переменных (да-да, примитивно, но надо ж ему хоть что-то проверять? :))
inputfile="$1"
[ -z "$2" ]    &&      echo "Error: directory is not set" && exit 1
[ ! -d "$2" ]  &&      echo "Error: $2 not a directory" && exit 1


# Куда складывать файлы дампов
# Весь процесс
outdir="$2"
awk '/^CREATE DATABASE/{nodb+=1; print "Processing DB "nodb"..."}; {print >> "'$2'/"nodb".sql"}' "${1}"


# Проверка передачи переменных (да-да, примитивно, но надо ж ему хоть что-то проверять? :))
echo -e "Renaming dumps..."
[ -z "$2" ] && echo "Error: directory is not set" && exit 1
ls -1 ${2}/*.sql |
[ ! -d "$2" ] && echo "Error: $2 not a directory" && exit 1
while read file
        do     
                dumpname="$(head -n1 "${file}" |  sed -re "s/^CREATE DATABASE|[\` ;]//g" -e "s@/\\*[\!a-zA-Z0-9_ ]*\*\/@@g")"
                sed  -i -n '/^CREATE DATABASE/,/^USE/!p' "${file}"
# Конечно, вряд ли окажутся 2 базы с одним именем, но кто знает...
                [ ! -e "${file%/*}/${dumpname}.sql" ] && mv "${file}" "${file%/*}/${dumpname}.sql"
done
echo "All done"
</source>
----
 
Функция на AWK'e:
 
----
 
<source lang=bash>
dbsplit() {
type="$(file "${1}" | grep -oE 'gzip|bzip')"
case "${type}" in gzip) cmd='unpigz -c' ;; bzip) cmd='pbunzip2 -c' ;; *) cmd='cat' ;; esac
nice -n 19 ${cmd} "${1}" | pv -N 'Total' |
mawk 'BEGIN {f="_-_database_-_header_-_.sql"}; /DROP DATABASE IF EXIST/{close(f) ; print f ; f=$6".sql" ; gsub(/`|;|\*|\//, "", f)}; {print >> f} END {print f}' ; }
</source>
 
== Скрипт для параллельной заливки таблиц дампа ==
 
Этот скрипт делает параллельную заливку нескольких таблиц в дампе одной базы. Использование:
 
[THR=100500] [MYSQL_ADD_FLAGS='--default-character-set=latin1'] '''sqlpar-restore''' '''dump.sql''' '''host''' '''user''' '''password''' '''database'''
 
Опционально можно задавать следующие флаги:
 
'''THR''' - число параллельных тредов для заливки (по умолчанию - 25)
'''MYSQL_ADD_FLAGS''' - параметры, передаваемые напрямую MySQL (например, установка default charset)
При работе скрипт создает файлы с именем базы в каталоге, в котором происходил запуск команды, поэтому лучше выполнять ее в отдельном каталоге. После успешной заливки дамп таблицы удаляется.
 
Функция автоматом определяет тип файла - plaintext, bzip2 или gzip и использует соответствующие распаковщики. Для распаковки используются параллельные версии декомпрессоров - unpigz, pbunzip2. Для отображения прогресса заливки используется pv. Для обработки дампа используется mawk.
 
----


dbn=0
<source lang=bash>
# Собственно, процесс
sqlpar-restore() {
cutter() {
    [ -z "${THR}" ] && THR='25'
while [ ! -z $1 ] ;
    pwait() {
do
        while [ $(jobs | grep -c Run) -ge $1 ]
# Проверка конца дампа, задание конца дампа
            do
if [ -z "$2" ] ;
                sleep 1
then
            done
head="-0"
        }
else
        type="$(file "${1}" | grep -oE 'gzip|bzip')"
head=`echo $[$2-$1]`
        case "${type}" in gzip) cmd='unpigz -c' ;; bzip) cmd='pbunzip2 -c' ;; *) cmd='cat' ;; esac
fi
        nice -n 19 ${cmd} "${1}" | pv -N 'Total' |
# Вырезание имени дампа (вроде работает даже)
        mawk 'BEGIN {f="_-_database_-_header_-_.sql"}; /DROP TABLE IF EXIST/{close(f) ; print f ; f=$5".sql" ; gsub(/`|;/, "", f)}; {print >> f} END {print f}' |
dumpname=`tail -n+"$1" $inputfile | head -n1 | sed -re "s/^CREATE DATABASE//g" -e "s@/\\*[\!a-zA-Z0-9_ ]*\*\/@@g" -e "s/\;//g" -e 's/\`//g' -e "s/ //g"`
        grep -v '_-_database_-_header_-_.sql' | while read table
# Проверка существования дампа (в общем-то, если каталог назначения чистый, то использоваться не должно)
        do [ -z "${JUST_CUT}" ] && {
if [ -e "$outdir"/"$dumpname"."$dbn".sql ]
                {
then
                        sleep .1
echo -e "\e[5;31m$dumpname.$dbn.sql already exist\e[0m"
                        pv -N "${table}" '_-_database_-_header_-_.sql' "${table}" |
else
                        sed 's/^CHANGE MASTER TO/STOP SLAVE;\n&/g' |
echo -e "\e[36mCreating\t\e[35m$dumpname.\e[32m$dbn\e[0m.sql"
                        mysql $MYSQL_ADD_FLAGS -h"${2}" -u"${3}" -p"${4}" "${5}" 2>>/tmp/parrestore.log && rm "${table}"
# Собственно, процесс нарезки. По полученному первому числу отрезаем начало дампа,
                } & pwait "${THR}"
# по разнице между вторым и первым отрезается конец дампа.
        }
tail -n+"$1" $inputfile | head -n"$head" > "$outdir"/"$dumpname"."$dbn".sql
        done
# В полученных дампах обрезаются все промежутки от "CREATE DATABASE" до "USE DATABASE"
sed  -i -n '/^CREATE DATABASE/,/^USE/!p' "$outdir"/"$dumpname"."$dbn".sql
fi
# Выполнение сдвига полученных номеров и увеличение счетчика обработанных дампов
shift
let dbn+=1
done
echo -e "\e[31mTotal:\t\t\e[35m$dbn dumps\e[0m"
}
}
</source>
==Разное==
Пример ускоренного копирования ряда таблиц из одной базы в другую с использованием параллельной заливки таблиц:


# Выборка номеров строк начала дампа, передача их функции.
<source lang=bash>
cutter `grep -n "^CREATE DATABASE" $1 | awk -F':' '{print $1}' | tr ':\n' ' '`
mysqldump -h HOST -u USER -p'PASS' DB $(echo show tables | mysql -h HOST -u USER -p'PASS' DB | grep PATTERN | tr '\n' ' ') | sqlpar-restore /dev/stdin HOST2 USER2 'PASS2' NEWDB
</source>
</source>
----


[[Category:Bash]][[Category:Sed]][[Category:MySQL]][[Category:Скрипт]]
[[Category:Sed]][[Category:MySQL]][[Category:Bash-скрипт]][[Category:Скрипт]]

Текущая версия на 14:07, 30 августа 2012

Разбивка дампа на базы

Cкрипт предназначен для разрезания MySQL-дампа с несколькими базами на отдельные базы. Файлы именуются по принципу название_базы.номер_в_общем_дампе.sql

Использование
./db_split.sh файл_дампа.sql каталог_куда_складывать_дампы

#!/bin/bash                                                                                                                   
# By Rain ;)

# Создан 2008-04-01
# Изменен 2008-04-17: добавлено описание
# Изменен 2008-04-18: добавлено удаление "USE DATABASE" в начале дампов
# Изменен 2009-06-08: переписал с использованием awk

# Проверка передачи переменных (да-да, примитивно, но надо ж ему хоть что-то проверять? :))
[ -z "$2" ]     &&      echo "Error: directory is not set" && exit 1
[ ! -d "$2" ]   &&      echo "Error: $2 not a directory" && exit 1

# Весь процесс
awk '/^CREATE DATABASE/{nodb+=1; print "Processing DB "nodb"..."}; {print >> "'$2'/"nodb".sql"}' "${1}"

echo -e "Renaming dumps..."
ls -1 ${2}/*.sql |
while read file
        do      
                dumpname="$(head -n1 "${file}" |  sed -re "s/^CREATE DATABASE|[\` ;]//g" -e "s@/\\*[\!a-zA-Z0-9_ ]*\*\/@@g")"
                sed  -i -n '/^CREATE DATABASE/,/^USE/!p' "${file}"
# Конечно, вряд ли окажутся 2 базы с одним именем, но кто знает...
                [ ! -e "${file%/*}/${dumpname}.sql" ] && mv "${file}" "${file%/*}/${dumpname}.sql"
done
echo "All done"

Функция на AWK'e:


dbsplit() {
type="$(file "${1}" | grep -oE 'gzip|bzip')"
case "${type}" in gzip) cmd='unpigz -c' ;; bzip) cmd='pbunzip2 -c' ;; *) cmd='cat' ;; esac
nice -n 19 ${cmd} "${1}" | pv -N 'Total' |
mawk 'BEGIN {f="_-_database_-_header_-_.sql"}; /DROP DATABASE IF EXIST/{close(f) ; print f ; f=$6".sql" ; gsub(/`|;|\*|\//, "", f)}; {print >> f} END {print f}' ; }

Скрипт для параллельной заливки таблиц дампа

Этот скрипт делает параллельную заливку нескольких таблиц в дампе одной базы. Использование:

[THR=100500] [MYSQL_ADD_FLAGS='--default-character-set=latin1'] sqlpar-restore dump.sql host user password database

Опционально можно задавать следующие флаги:

THR - число параллельных тредов для заливки (по умолчанию - 25)
MYSQL_ADD_FLAGS - параметры, передаваемые напрямую MySQL (например, установка default charset)

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

Функция автоматом определяет тип файла - plaintext, bzip2 или gzip и использует соответствующие распаковщики. Для распаковки используются параллельные версии декомпрессоров - unpigz, pbunzip2. Для отображения прогресса заливки используется pv. Для обработки дампа используется mawk.


sqlpar-restore() {
    [ -z "${THR}" ] && THR='25'
    pwait() {
        while [ $(jobs | grep -c Run) -ge $1 ]
            do
                sleep 1
            done
        }
        type="$(file "${1}" | grep -oE 'gzip|bzip')"
        case "${type}" in gzip) cmd='unpigz -c' ;; bzip) cmd='pbunzip2 -c' ;; *) cmd='cat' ;; esac
        nice -n 19 ${cmd} "${1}" | pv -N 'Total' |
        mawk 'BEGIN {f="_-_database_-_header_-_.sql"}; /DROP TABLE IF EXIST/{close(f) ; print f ; f=$5".sql" ; gsub(/`|;/, "", f)}; {print >> f} END {print f}' |
        grep -v '_-_database_-_header_-_.sql' | while read table
        do [ -z "${JUST_CUT}" ] && {
                {
                        sleep .1
                        pv -N "${table}" '_-_database_-_header_-_.sql' "${table}" |
                        sed 's/^CHANGE MASTER TO/STOP SLAVE;\n&/g' |
                        mysql $MYSQL_ADD_FLAGS -h"${2}" -u"${3}" -p"${4}" "${5}" 2>>/tmp/parrestore.log && rm "${table}"
                } & pwait "${THR}"
        }
        done
}

Разное

Пример ускоренного копирования ряда таблиц из одной базы в другую с использованием параллельной заливки таблиц:

mysqldump -h HOST -u USER -p'PASS' DB $(echo show tables | mysql -h HOST -u USER -p'PASS' DB | grep PATTERN | tr '\n' ' ') | sqlpar-restore /dev/stdin HOST2 USER2 'PASS2' NEWDB