Чиним MySQL-дамп (меньше чем за 30 строк)

от автора

Давным-давно (кажется, в прошлую среду) попался ко мне в руки дамп базы данных MySQL, который следовало немедленно развернуть на моей машине. Зачем это было нужно и откуда взялся дамп, рассказывать не буду, вряд ли это кому-то интересно. Важно то, что дамп был от MySQL 4.1.22 и снят он был при помощи одного широко известного инструмента (версии 5.23).
Разворачиваться у меня он решительно отказался… 
 

... Error occured at:2016-02-12 10:28:24 Line no.:65 Error Code: 2013 - Lost connection to MySQL server during query 

Ошибка, по обыкновению, была довольно невнятна, но поскольку предварялась она длинным (слишком длинным) SQL-запросом, её причина была очевидна. Дабы уменьшить количество insert-ов (бесспорно, благое начинание), SQLyog «склеивает» их, примерно следующим образом:

insert into abc(a, b, c) values (1,2,3),(4,5,6),(7,8,9),... 

Когда данных много, полученный гигантский запрос разбивается на куски, но как-то так получается, что размер этих кусков (~ 1 мегабайта) всё ещё остаётся слишком большим. Я не нашёл у SQLyog рукоятку управления, позволяющую сделать снятый дамп более вменяемым (возможно, плохо искал), да и в любом случае, исходный дамп (тот, о котором идёт речь в этой статье) снимал не я и с ним надо было что-то делать. В общем, долго сказка сказывается, но само дело делается значительно быстрее:

while (<>) {     chomp;     if (length($_) < 4096) {         print "$_\n";     } else {         if (/^(insert.*values\s+)\((.*)\);$/) {             my $hd = $1; my $tx = '';             my @bd = split(/\),\(/, $2);             foreach $st (@bd) {                if ($tx) {                    $tx .= ',(' . $st . ')';                } else {                    $tx = $hd . '(' . $st . ')';                }                if (length($tx) > 4096) {                    print "$tx;\n";                    $tx = '';                }             }             if ($tx) {                 print "$tx;\n";             }         }     } } 

Любимый Perl не подвёл меня и в этот раз. Возможно, код можно было написать и как-то поэлегантнее, но меня вполне устраивает, как он работает. Длинные insert-ы разбиваются на куски размером около 4 килобайт (возможно можно и больше, не экспериментировал). Кому надо — берите и пользуйтесь.

ссылка на оригинал статьи https://habrahabr.ru/post/277101/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *