Skip to content

Commit

Permalink
dbcheck: fixes for eliminate_orphaned_path_records and repair_bad_paths
Browse files Browse the repository at this point in the history
eliminate_orphaned_path_records:
  * will no longer remove paths that a subpaths of other paths.
  * will run even if bvfs is used, as the fix described above will prevent harm to the bvfs structures.

repair_bad_paths:
  * prevents modifying the empty path entry (""). This entry is used as parent directory, even parent of "/".
  • Loading branch information
joergsteffens committed Jan 13, 2018
1 parent f49af88 commit 957687e
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 20 deletions.
4 changes: 3 additions & 1 deletion src/cats/bdb_query_enum_class.h
Expand Up @@ -74,6 +74,8 @@ class B_DB_QUERY_ENUM_CLASS {
SQL_QUERY_list_volumes_by_poolid_count_1 = 68,
SQL_QUERY_list_joblog_2 = 69,
SQL_QUERY_list_joblog_count_1 = 70,
SQL_QUERY_NUMBER = 71
SQL_QUERY_get_orphaned_paths_0 = 71,
SQL_QUERY_get_bad_paths_0 = 72,
SQL_QUERY_NUMBER = 73
} SQL_QUERY_ENUM;
};
2 changes: 2 additions & 0 deletions src/cats/bdb_query_names.inc
Expand Up @@ -72,5 +72,7 @@ const char *B_DB::query_names[] = {
"list_volumes_by_poolid_count_1",
"list_joblog_2",
"list_joblog_count_1",
"get_orphaned_paths_0",
"get_bad_paths_0",
NULL
};
13 changes: 13 additions & 0 deletions src/cats/dml/0072_get_orphaned_paths_0
@@ -0,0 +1,13 @@
#
# dbcheck: eliminate_orphaned_path_records
#
# get all Paths not used by Files
# and are not substrings to others Paths.
#
# LIKE: _% wildcard, but at least one character
#
SELECT DISTINCT ParentPath.PathId,File.PathId,ParentPath.Path
FROM Path AS ParentPath LEFT OUTER JOIN File USING(PathId)
WHERE File.PathId IS NULL
AND NOT EXISTS (SELECT 1 FROM Path WHERE Path LIKE ParentPath.Path || '_%%')
LIMIT 300000
13 changes: 13 additions & 0 deletions src/cats/dml/0072_get_orphaned_paths_0.mysql
@@ -0,0 +1,13 @@
#
# dbcheck: eliminate_orphaned_path_records
#
# get all Paths not used by Files
# and are not substrings to others Paths.
#
# LIKE: _% wildcard, but at least one character
#
SELECT DISTINCT ParentPath.PathId,File.PathId,ParentPath.Path
FROM Path AS ParentPath LEFT OUTER JOIN File USING(PathId)
WHERE File.PathId IS NULL
AND NOT EXISTS (SELECT 1 FROM Path WHERE Path LIKE CONCAT(ParentPath.Path,'_%%'))
LIMIT 300000
7 changes: 7 additions & 0 deletions src/cats/dml/0073_get_bad_paths_0
@@ -0,0 +1,7 @@
#
# dbcheck: repair_bad_paths
#
SELECT PathId, Path FROM Path
WHERE Path != ''
AND Path NOT LIKE '%%/'

2 changes: 2 additions & 0 deletions src/cats/dml/README
Expand Up @@ -9,6 +9,8 @@ The .inc files only need to be updated when the queries
are altered or new ones are added.

NOTE:
* Naming: Number_Description_NumberOfArguments
* As % are used for replace variables, % in SQL LIKE statements must be escaped (% => %%).
* each query must consist of a single SQL statement,
as more statement, separated by columns (";") need special result handling for MySQL.

14 changes: 14 additions & 0 deletions src/cats/mysql_queries.inc
Expand Up @@ -912,5 +912,19 @@ const char *B_DB_MYSQL::query_definitions[] = {
"WHERE Log.JobId=%s "
,

/* 0072_get_orphaned_paths_0.mysql */
"SELECT DISTINCT ParentPath.PathId,File.PathId,ParentPath.Path "
"FROM Path AS ParentPath LEFT OUTER JOIN File USING(PathId) "
"WHERE File.PathId IS NULL "
"AND NOT EXISTS (SELECT 1 FROM Path WHERE Path LIKE CONCAT(ParentPath.Path,'_%%')) "
"LIMIT 300000 "
,

/* 0073_get_bad_paths_0 */
"SELECT PathId, Path FROM Path "
"WHERE Path != '' "
"AND Path NOT LIKE '%%/' "
,

NULL
};
14 changes: 14 additions & 0 deletions src/cats/postgresql_queries.inc
Expand Up @@ -888,5 +888,19 @@ const char *B_DB_POSTGRESQL::query_definitions[] = {
"WHERE Log.JobId=%s "
,

/* 0072_get_orphaned_paths_0 */
"SELECT DISTINCT ParentPath.PathId,File.PathId,ParentPath.Path "
"FROM Path AS ParentPath LEFT OUTER JOIN File USING(PathId) "
"WHERE File.PathId IS NULL "
"AND NOT EXISTS (SELECT 1 FROM Path WHERE Path LIKE ParentPath.Path || '_%%') "
"LIMIT 300000 "
,

/* 0073_get_bad_paths_0 */
"SELECT PathId, Path FROM Path "
"WHERE Path != '' "
"AND Path NOT LIKE '%%/' "
,

NULL
};
14 changes: 14 additions & 0 deletions src/cats/sqlite_queries.inc
Expand Up @@ -897,5 +897,19 @@ const char *B_DB_SQLITE::query_definitions[] = {
"WHERE Log.JobId=%s "
,

/* 0072_get_orphaned_paths_0 */
"SELECT DISTINCT ParentPath.PathId,File.PathId,ParentPath.Path "
"FROM Path AS ParentPath LEFT OUTER JOIN File USING(PathId) "
"WHERE File.PathId IS NULL "
"AND NOT EXISTS (SELECT 1 FROM Path WHERE Path LIKE ParentPath.Path || '_%%') "
"LIMIT 300000 "
,

/* 0073_get_bad_paths_0 */
"SELECT PathId, Path FROM Path "
"WHERE Path != '' "
"AND Path NOT LIKE '%%/' "
,

NULL
};
28 changes: 9 additions & 19 deletions src/dird/dbcheck.c
Expand Up @@ -710,15 +710,9 @@ static void eliminate_orphaned_file_records()
static void eliminate_orphaned_path_records()
{
db_int64_ctx lctx;
POOL_MEM query(PM_MESSAGE);

lctx.count = 0;
db->sql_query("SELECT 1 FROM Job WHERE HasCache=1 LIMIT 1", db_int64_handler, &lctx);
if (lctx.count > 0) {
printf(_("Pruning orphaned Path entries isn't possible when using BVFS.\n"));
fflush(stdout);
return;
}

idx_tmp_name = NULL;
/*
* Check the existence of the required "one column" index
Expand All @@ -732,16 +726,14 @@ static void eliminate_orphaned_path_records()
}
}

const char *query = "SELECT DISTINCT Path.PathId,File.PathId FROM Path "
"LEFT OUTER JOIN File USING(PathId) "
"WHERE File.PathId IS NULL LIMIT 300000";
db->fill_query(query, B_DB::SQL_QUERY_get_orphaned_paths_0);

printf(_("Checking for orphaned Path entries. This may take some time!\n"));
if (verbose > 1) {
printf("%s\n", query);
printf("%s\n", query.c_str());
}
fflush(stdout);
if (!make_id_list(query, &id_list)) {
if (!make_id_list(query.c_str(), &id_list)) {
exit(1);
}
/*
Expand Down Expand Up @@ -769,7 +761,7 @@ static void eliminate_orphaned_path_records()
} else {
break; /* get out if not updating db */
}
if (!make_id_list(query, &id_list)) {
if (!make_id_list(query.c_str(), &id_list)) {
exit(1);
}
}
Expand Down Expand Up @@ -1059,18 +1051,16 @@ static void repair_bad_filenames()

static void repair_bad_paths()
{
const char *query;
POOL_MEM query(PM_MESSAGE);
int i;

printf(_("Checking for Paths without a trailing slash\n"));
query = "SELECT PathId,Path from Path "
"WHERE Path != '' "
"AND Path NOT LIKE '%/'";
db->fill_query(query, B_DB::SQL_QUERY_get_bad_paths_0);
if (verbose > 1) {
printf("%s\n", query);
printf("%s\n", query.c_str());
}
fflush(stdout);
if (!make_id_list(query, &id_list)) {
if (!make_id_list(query.c_str(), &id_list)) {
exit(1);
}
printf(_("Found %d bad Path records.\n"), id_list.num_ids);
Expand Down

0 comments on commit 957687e

Please sign in to comment.