Add fspgroup repair action to menu
This commit is contained in:
@@ -166,6 +166,18 @@ sub db_do {
|
|||||||
$db->do(@cmd) or die "Database command failed (@cmd): " . $db->errstr;
|
$db->do(@cmd) or die "Database command failed (@cmd): " . $db->errstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# db_do only reports affected rows, this one also reads the value back
|
||||||
|
sub db_selectrow {
|
||||||
|
my (@cmd) = @_;
|
||||||
|
|
||||||
|
my $db = db_connect();
|
||||||
|
|
||||||
|
my @row = $db->selectrow_array(@cmd);
|
||||||
|
die "Database query failed (@cmd): " . $db->errstr if $db->err;
|
||||||
|
|
||||||
|
return @row;
|
||||||
|
}
|
||||||
|
|
||||||
sub db_create {
|
sub db_create {
|
||||||
my ($db_name) = @_;
|
my ($db_name) = @_;
|
||||||
say " - Creating database $db_name...";
|
say " - Creating database $db_name...";
|
||||||
|
|||||||
+130
@@ -848,6 +848,136 @@ my %handlers = (
|
|||||||
'<', Util::shell_quote($dump_file) );
|
'<', Util::shell_quote($dump_file) );
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'33. Repair fspgroup Write Groups (Mars)' => sub {
|
||||||
|
|
||||||
|
# Retroactively fixes (hopefully) the missing equivalence class
|
||||||
|
# mappings (EC <-> Pilot) the BasicPruner misses (because it maps
|
||||||
|
# multiple classes to a single pilot, but uses the pilot as the
|
||||||
|
# primary key)
|
||||||
|
my @dbs = Mars::db_list();
|
||||||
|
my @dbs_with_notes;
|
||||||
|
foreach my $db (@dbs) {
|
||||||
|
my $info =
|
||||||
|
Util::read_experiment_info( $db =~ s/smchurla_//r =~ s/:/-/gr );
|
||||||
|
|
||||||
|
push @dbs_with_notes,
|
||||||
|
( defined $info && length($info) > 0 )
|
||||||
|
? sprintf( "%-60s (%s)", $db, $info )
|
||||||
|
: $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
my @selected_dbs = TUI::select_from_list( "Select Databases to Repair",
|
||||||
|
1, @dbs_with_notes );
|
||||||
|
die "No database selected" unless @selected_dbs;
|
||||||
|
|
||||||
|
@selected_dbs =
|
||||||
|
map { s/(.*?)\s+\(.+\)$/$1/r } @selected_dbs;
|
||||||
|
|
||||||
|
# The PRIMARY KEY gets dropped by the repair and replaced with a KEY.
|
||||||
|
# To not run this shit on already repaired DBs, check for the PRIMARY
|
||||||
|
# index as a determinant
|
||||||
|
my $index_exists = sub {
|
||||||
|
my ($index) = @_;
|
||||||
|
my ($count) = Mars::db_selectrow(
|
||||||
|
"SELECT COUNT(*) FROM information_schema.STATISTICS
|
||||||
|
WHERE TABLE_SCHEMA = DATABASE()
|
||||||
|
AND TABLE_NAME = 'fspgroup'
|
||||||
|
AND INDEX_NAME = '$index'"
|
||||||
|
);
|
||||||
|
return $count;
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach my $db (@selected_dbs) {
|
||||||
|
say "Repairing $db...";
|
||||||
|
|
||||||
|
# Select the DB so index_exists works
|
||||||
|
Mars::db_do("use `$db`");
|
||||||
|
|
||||||
|
# Update the variant names, so the queries still work
|
||||||
|
my $expected_variant = $db =~ s/^smchurla_//r;
|
||||||
|
my ($variant_count) =
|
||||||
|
Mars::db_selectrow("SELECT COUNT(DISTINCT variant) FROM variant");
|
||||||
|
my ($current_variant) =
|
||||||
|
Mars::db_selectrow("SELECT DISTINCT variant FROM variant");
|
||||||
|
|
||||||
|
if ( !defined $variant_count || $variant_count != 1 ) {
|
||||||
|
say " - WARNING: $variant_count distinct variants!";
|
||||||
|
}
|
||||||
|
elsif ( $current_variant ne $expected_variant ) {
|
||||||
|
say " - Variant is '$current_variant' but queries look up"
|
||||||
|
. " '$expected_variant' (from the database name), renaming...";
|
||||||
|
Mars::db_do("UPDATE variant SET variant = '$expected_variant'");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Drop the primary key
|
||||||
|
if ( $index_exists->('PRIMARY') ) {
|
||||||
|
say " - Dropping PRIMARY KEY (pilot_id)...";
|
||||||
|
Mars::db_do("ALTER TABLE fspgroup DROP PRIMARY KEY");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add an index for the columns we actually join on (mostly)
|
||||||
|
unless ( $index_exists->('eq_class') ) {
|
||||||
|
say " - Adding eq_class index...";
|
||||||
|
Mars::db_do(
|
||||||
|
"ALTER TABLE fspgroup
|
||||||
|
ADD KEY eq_class (variant_id, instr2, data_physical_address)"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
# I'm currently only using BasicPruner, but don't touch other
|
||||||
|
# pruning methods for now, for safety
|
||||||
|
my ($fspmethod_id) =
|
||||||
|
Mars::db_selectrow(
|
||||||
|
"SELECT id FROM fspmethod WHERE method = 'basic'");
|
||||||
|
die "No 'basic' fspmethod in $db" unless defined $fspmethod_id;
|
||||||
|
|
||||||
|
# The first row succeeded before the duplicate key error, remove it
|
||||||
|
Mars::db_do(
|
||||||
|
"DELETE g
|
||||||
|
FROM fspgroup g
|
||||||
|
JOIN fsppilot p ON p.id = g.pilot_id
|
||||||
|
WHERE p.known_outcome = 1 AND p.fspmethod_id = $fspmethod_id"
|
||||||
|
);
|
||||||
|
|
||||||
|
my ($expected) =
|
||||||
|
Mars::db_selectrow(
|
||||||
|
"SELECT COUNT(*) FROM trace WHERE accesstype = 'W'");
|
||||||
|
|
||||||
|
# Query from BasicPruner.cc, now ran against the updated DB
|
||||||
|
say " - Inserting $expected write groups...";
|
||||||
|
Mars::db_do(
|
||||||
|
"INSERT INTO
|
||||||
|
fspgroup (variant_id, instr2, data_physical_address, bit_pos, fspmethod_id, pilot_id)
|
||||||
|
SELECT STRAIGHT_JOIN t.variant_id, t.instr2, t.data_physical_address, p.bit_pos, p.fspmethod_id, p.id
|
||||||
|
FROM fsppilot p
|
||||||
|
JOIN trace t
|
||||||
|
ON t.variant_id = p.variant_id AND p.fspmethod_id = $fspmethod_id AND p.known_outcome = 1
|
||||||
|
WHERE t.accesstype = 'W'"
|
||||||
|
);
|
||||||
|
|
||||||
|
# We expect one row per write group/EC.
|
||||||
|
# Otherwise no idea what's going on :O
|
||||||
|
my ($actual) = Mars::db_selectrow(
|
||||||
|
"SELECT COUNT(*)
|
||||||
|
FROM fspgroup g
|
||||||
|
JOIN fsppilot p ON p.id = g.pilot_id
|
||||||
|
WHERE p.known_outcome = 1 AND p.fspmethod_id = $fspmethod_id"
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( $actual == $expected ) {
|
||||||
|
say " - OK: $actual write groups match the write ECs in trace";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
say " - WARNING: inserted $actual, expected $expected."
|
||||||
|
. " Check for duplicate known_outcome pilots:"
|
||||||
|
. " SELECT variant_id, COUNT(*) FROM fsppilot"
|
||||||
|
. " WHERE known_outcome = 1 GROUP BY variant_id;";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
say "Queries have to be re-run.";
|
||||||
|
},
|
||||||
|
|
||||||
'95. Delete Builds' => sub {
|
'95. Delete Builds' => sub {
|
||||||
|
|
||||||
# Delete old build files
|
# Delete old build files
|
||||||
|
|||||||
Reference in New Issue
Block a user