From c0065b542a347fdc7ffa3aa104ab824d7fc5ebad Mon Sep 17 00:00:00 2001 From: Rene Krenn Date: Wed, 13 Oct 2021 14:04:54 +0200 Subject: [PATCH] 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 12de9892f85ba306c09ba90f041b5d886c7e0d36) --- lib/NGCP/Cleanup.pm | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/NGCP/Cleanup.pm b/lib/NGCP/Cleanup.pm index bd0aa21..68fac1e 100644 --- a/lib/NGCP/Cleanup.pm +++ b/lib/NGCP/Cleanup.pm @@ -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; + } } } }