Давным-давно (кажется, в прошлую среду) попался ко мне в руки дамп базы данных MySQL, который следовало немедленно развернуть на моей машине. Зачем это было нужно и откуда взялся дамп, рассказывать не буду, вряд ли это кому-то интересно. Важно то, что дамп был от MySQL 4.1.22 и снят он был при помощи одного широко известного инструмента (версии 5.23).
Разворачиваться у меня он решительно отказался...
Ошибка, по обыкновению, была довольно невнятна, но поскольку предварялась она длинным (слишком длинным) SQL-запросом, её причина была очевидна. Дабы уменьшить количество insert-ов (бесспорно, благое начинание), SQLyog «склеивает» их, примерно следующим образом:
Когда данных много, полученный гигантский запрос разбивается на куски, но как-то так получается, что размер этих кусков (~ 1 мегабайта) всё ещё остаётся слишком большим. Я не нашёл у SQLyog рукоятку управления, позволяющую сделать снятый дамп более вменяемым (возможно, плохо искал), да и в любом случае, исходный дамп (тот, о котором идёт речь в этой статье) снимал не я и с ним надо было что-то делать. В общем, долго сказка сказывается, но само дело делается значительно быстрее:
Любимый Perl не подвёл меня и в этот раз. Возможно, код можно было написать и как-то поэлегантнее, но меня вполне устраивает, как он работает. Длинные insert-ы разбиваются на куски размером около 4 килобайт (возможно можно и больше, не экспериментировал). Кому надо — берите и пользуйтесь.
Разворачиваться у меня он решительно отказался...
...
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 килобайт (возможно можно и больше, не экспериментировал). Кому надо — берите и пользуйтесь.