TT#145102 handle row_format mismatch (table/partition)

mariadb version > 10.1 changed the default row_format
from COMPACT to DYNAMIC. system upgraded to 7.5 therefore
end up with table partitions with different row_format, since
creating tables do not honour row_format (mysql bug 95478).

this in turn causes "ALTER TABLE .. EXCHANGE PARTITION .."
statements to fail with an error 1731 ("non matching attribute
ROW_FORMAT between table and partition", see MDEV-26027).

a manual mitigation would mean to align the row_formats
using "ALTER TABLE .. ROW_FORMAT = ..". But this in turn can
result fail with erro 1118 ("row size too large") for tables
with many&long columns (ie. accounting.cdr).

this fix will now mitigate the situation by falling back to
the built-in rowcopy method, if it detects mismatching
row_format.

Change-Id: Ief220be41b2350fa1437b6f35d46d1811facb57f
(cherry picked from commit 12de9892f8)
mr9.5.5
Rene Krenn 4 years ago
parent 485ac6f494
commit 61cb4cc85f

@ -256,6 +256,16 @@ sub check_table_exists {
return $pvalue;
}
sub get_table_row_format {
my ($self, $table) = @_;
my ($row_format) = $self->fetch_row(
'information_schema', 'tables', 'row_format',
"where table_schema = 'accounting' and table_name = '$table'");
return $row_format;
}
sub check_partition_exists {
my ($self, $table, $pname) = @_;
@ -266,6 +276,16 @@ sub check_partition_exists {
return $pvalue;
}
sub get_partition_row_format {
my ($self, $table, $pname) = @_;
my ($row_format) = $self->fetch_row(
'information_schema', 'innodb_sys_tables', 'row_format',
"where name = 'accounting/$table#P#$pname'");
return $row_format;
}
sub check_table_partitioned {
my ($self, $table) = @_;
@ -449,8 +469,15 @@ sub backup_partition {
# drop partitioning layout inherited from copied table creation
$dbh->do("alter table $mtable remove partitioning");
}
$dbh->do("alter table $table exchange partition $pname with table $mtable");
die "Cannot exchange partition $table -> $mtable: ".$DBI::errstr if $DBI::err;
my $mtable_row_format = lc($self->get_table_row_format($mtable));
my $partition_row_format = lc($self->get_partition_row_format($table,$pname));
if ($mtable_row_format ne $partition_row_format) {
$self->info("table $mtable row_format ($mtable_row_format) differs from table $table partition $pname row_format ($partition_row_format), fallback to the table backup method");
$self->delete_loop($table, $bm);
} else {
$dbh->do("alter table $table exchange partition $pname with table $mtable");
die "Cannot exchange partition $table -> $mtable: ".$DBI::errstr if $DBI::err;
}
}
}
}

Loading…
Cancel
Save