]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
BEE Backport bacula/src/tools/dbcheck.c
authorEric Bollengier <eric@baculasystems.com>
Wed, 16 Dec 2020 09:36:21 +0000 (10:36 +0100)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:02:58 +0000 (09:02 +0100)
This commit is the result of the squash of the following main commits:

Author: Alain Spineux <alain@baculasystems.com>
Date:   Wed Jul 3 09:28:39 2019 +0200

    fix #5131 dbcheck was removing the "empty" path entry in the Path table

    - this "empty" entry is required for query like
      * .bvfs_lsdirs jobid=1 path=
      used by both BMR recovery ISO

Author: Wanderlei Hüttel <wanderlei.huttel@gmail.com>
Date:   Mon Feb 4 12:37:05 2019 +0100

    Implement eliminate verify records in dbcheck bug #2434

Author: Eric Bollengier <eric@baculasystems.com>
Date:   Mon Aug 26 13:57:34 2013 +0200

    Merge Filename table to File

bacula/src/tools/dbcheck.c [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index 00f7690..2540342
@@ -70,12 +70,10 @@ static int make_name_list(const char *query, NAME_LIST *name_list);
 static void print_name_list(NAME_LIST *name_list);
 static void free_name_list(NAME_LIST *name_list);
 static char *get_cmd(const char *prompt);
-static void eliminate_duplicate_filenames();
 static void eliminate_duplicate_paths();
 static void eliminate_orphaned_jobmedia_records();
 static void eliminate_orphaned_file_records();
 static void eliminate_orphaned_path_records();
-static void eliminate_orphaned_filename_records();
 static void eliminate_orphaned_fileset_records();
 static void eliminate_orphaned_client_records();
 static void eliminate_orphaned_job_records();
@@ -83,7 +81,6 @@ static void eliminate_admin_records();
 static void eliminate_restore_records();
 static void eliminate_verify_records();
 static void repair_bad_paths();
-static void repair_bad_filenames();
 static void do_interactive_mode();
 static bool yes_no(const char *prompt);
 static bool check_idx(const char *col_name);
@@ -97,7 +94,7 @@ static void usage()
    fprintf(stderr,
 PROG_COPYRIGHT
 "\n%sVersion: %s (%s)\n\n"
-"Usage: dbcheck [-c config ] [-B] [-C catalog name] [-d debug_level] <working-directory> <bacula-database> <user> <password> [<dbhost>] [<dbport>] [<dbport>] [<dbsslmode>] [<dbsslkey>] [<dbsslcert>] [<dbsslca>]\n"
+"Usage: dbcheck [-c config ] [-B] [-C catalog name] [-d debug_level] <working-directory> <bacula-database> <user> <password> [<dbhost>] [<dbport>]\n"
 "       -b              batch mode\n"
 "       -C              catalog name in the director conf file\n"
 "       -c              Director conf filename\n"
@@ -108,7 +105,7 @@ PROG_COPYRIGHT
 "       -f              fix inconsistencies\n"
 "       -v              verbose\n"
 "       -?              print this message\n"
-"\n", 2002, "", VERSION, BDATE);
+"\n", 2002, BDEMO, VERSION, BDATE);
 
    exit(1);
 }
@@ -218,7 +215,6 @@ int main (int argc, char *argv[])
 
          /* Print catalog information and exit (-B) */
          if (print_catalog) {
-
             POOLMEM *catalog_details = get_pool_memory(PM_MESSAGE);
             db = db_init_database(NULL, catalog->db_driver, catalog->db_name, catalog->db_user,
                     catalog->db_password, catalog->db_address,
@@ -254,7 +250,7 @@ int main (int argc, char *argv[])
          dbsslcipher = catalog->db_ssl_cipher;
       }
    } else {
-      if (argc > 10) {
+      if (argc > 6) {
          Pmsg0(0, _("Wrong number of arguments.\n"));
          usage();
       }
@@ -309,8 +305,8 @@ int main (int argc, char *argv[])
 
    /* Open database */
    db = db_init_database(NULL, NULL, db_name, user, password, dbhost,
-          dbport, NULL, dbsslmode, dbsslkey, dbsslcert, dbsslca,
-           dbsslcapath, dbsslcipher, false, false);
+                         dbport, NULL, dbsslmode, dbsslkey, dbsslcert, dbsslca,
+                         dbsslcapath, dbsslcipher, false, false);
 
    if (!db || !db_open_database(NULL, db)) {
       Emsg1(M_FATAL, 0, "%s", db_strerror(db));
@@ -322,13 +318,10 @@ int main (int argc, char *argv[])
 
    if (batch) {
       repair_bad_paths();
-      repair_bad_filenames();
-      eliminate_duplicate_filenames();
       eliminate_duplicate_paths();
       eliminate_orphaned_jobmedia_records();
       eliminate_orphaned_file_records();
       eliminate_orphaned_path_records();
-      eliminate_orphaned_filename_records();
       eliminate_orphaned_fileset_records();
       eliminate_orphaned_client_records();
       eliminate_orphaned_job_records();
@@ -348,29 +341,6 @@ int main (int argc, char *argv[])
    return 0;
 }
 
-void print_catalog_details(CAT *catalog, const char *working_dir)
-{
-   POOLMEM *catalog_details = get_pool_memory(PM_MESSAGE);
-
-   /*
-    * Instantiate a BDB class and see what db_type gets assigned to it.
-    */
-   db = db_init_database(NULL, catalog->db_driver, catalog->db_name, catalog->db_user,
-                         catalog->db_password, catalog->db_address,
-                         catalog->db_port, catalog->db_socket,
-                         catalog->db_ssl_mode, catalog->db_ssl_key, 
-                         catalog->db_ssl_cert, catalog->db_ssl_ca,
-                         catalog->db_ssl_capath, catalog->db_ssl_cipher,
-                         catalog->mult_db_connections,
-                         catalog->disable_batch_insert);
-   if (db) {
-      printf("%sdb_type=%s\nworking_dir=%s\n", catalog->display(catalog_details),
-             db_get_engine_name(db), working_directory);
-      db_close_database(NULL, db);
-   }
-   free_pool_memory(catalog_details);
-}
-
 static void do_interactive_mode()
 {
    const char *cmd;
@@ -392,42 +362,36 @@ static void do_interactive_mode()
          printf(_("\n"
 "     1) Toggle modify database flag\n"
 "     2) Toggle verbose flag\n"
-"     3) Repair bad Filename records\n"
-"     4) Repair bad Path records\n"
-"     5) Eliminate duplicate Filename records\n"
-"     6) Eliminate duplicate Path records\n"
-"     7) Eliminate orphaned Jobmedia records\n"
-"     8) Eliminate orphaned File records\n"
-"     9) Eliminate orphaned Path records\n"
-"    10) Eliminate orphaned Filename records\n"
-"    11) Eliminate orphaned FileSet records\n"
-"    12) Eliminate orphaned Client records\n"
-"    13) Eliminate orphaned Job records\n"
-"    14) Eliminate all Admin records\n"
-"    15) Eliminate all Restore records\n"
-"    16) Eliminate all Verify records\n"
-"    17) All (3-16)\n"
-"    18) Quit\n"));
+"     3) Repair bad Path records\n"
+"     4) Eliminate duplicate Path records\n"
+"     5) Eliminate orphaned Jobmedia records\n"
+"     6) Eliminate orphaned File records\n"
+"     7) Eliminate orphaned Path records\n"
+"     8) Eliminate orphaned FileSet records\n"
+"     9) Eliminate orphaned Client records\n"
+"    10) Eliminate orphaned Job records\n"
+"    11) Eliminate all Admin records\n"
+"    12) Eliminate all Restore records\n"
+"    13) Eliminate all Verify records\n"
+"    14) All (3-13)\n"
+"    15) Quit\n"));
        } else {
          printf(_("\n"
 "     1) Toggle modify database flag\n"
 "     2) Toggle verbose flag\n"
-"     3) Check for bad Filename records\n"
-"     4) Check for bad Path records\n"
-"     5) Check for duplicate Filename records\n"
-"     6) Check for duplicate Path records\n"
-"     7) Check for orphaned Jobmedia records\n"
-"     8) Check for orphaned File records\n"
-"     9) Check for orphaned Path records\n"
-"    10) Check for orphaned Filename records\n"
-"    11) Check for orphaned FileSet records\n"
-"    12) Check for orphaned Client records\n"
-"    13) Check for orphaned Job records\n"
-"    14) Check for all Admin records\n"
-"    15) Check for all Restore records\n"
-"    16) Check for all Verify records\n"
-"    17) All (3-16)\n"
-"    18) Quit\n"));
+"     3) Check for bad Path records\n"
+"     4) Check for duplicate Path records\n"
+"     5) Check for orphaned Jobmedia records\n"
+"     6) Check for orphaned File records\n"
+"     7) Check for orphaned Path records\n"
+"     8) Check for orphaned FileSet records\n"
+"     9) Check for orphaned Client records\n"
+"    10) Check for orphaned Job records\n"
+"    11) Check for all Admin records\n"
+"    12) Check for all Restore records\n"
+"    13) Eliminate all Verify records\n"
+"    14) All (3-13)\n"
+"    15) Quit\n"));
        }
 
       cmd = get_cmd(_("Select function number: "));
@@ -449,56 +413,44 @@ static void do_interactive_mode()
                printf(_(" Verbose is off.\n"));
             break;
          case 3:
-            repair_bad_filenames();
-            break;
-         case 4:
             repair_bad_paths();
             break;
-         case 5:
-            eliminate_duplicate_filenames();
-            break;
-         case 6:
+         case 4:
             eliminate_duplicate_paths();
             break;
-         case 7:
+         case 5:
             eliminate_orphaned_jobmedia_records();
             break;
-         case 8:
+         case 6:
             eliminate_orphaned_file_records();
             break;
-         case 9:
+         case 7:
             eliminate_orphaned_path_records();
             break;
-         case 10:
-            eliminate_orphaned_filename_records();
-            break;
-         case 11:
+         case 8:
             eliminate_orphaned_fileset_records();
             break;
-         case 12:
+         case 9:
             eliminate_orphaned_client_records();
             break;
-         case 13:
+         case 10:
             eliminate_orphaned_job_records();
             break;
-         case 14:
+         case 11:
             eliminate_admin_records();
             break;
-         case 15:
+         case 12:
             eliminate_restore_records();
             break;
-         case 16:
+         case 13:
             eliminate_verify_records();
             break;
-         case 17:
-            repair_bad_filenames();
+         case 14:
             repair_bad_paths();
-            eliminate_duplicate_filenames();
             eliminate_duplicate_paths();
             eliminate_orphaned_jobmedia_records();
             eliminate_orphaned_file_records();
             eliminate_orphaned_path_records();
-            eliminate_orphaned_filename_records();
             eliminate_orphaned_fileset_records();
             eliminate_orphaned_client_records();
             eliminate_orphaned_job_records();
@@ -506,7 +458,7 @@ static void do_interactive_mode()
             eliminate_restore_records();
             eliminate_verify_records();
             break;
-         case 18:
+         case 15:
             quit = true;
             break;
          }
@@ -683,63 +635,6 @@ static void free_name_list(NAME_LIST *name_list)
    name_list->num_ids = 0;
 }
 
-static void eliminate_duplicate_filenames()
-{
-   const char *query;
-   char esc_name[5000];
-
-   printf(_("Checking for duplicate Filename entries.\n"));
-
-   /* Make list of duplicated names */
-   query = "SELECT Name, count(Name) as Count FROM Filename GROUP BY  Name "
-           "HAVING count(Name) > 1";
-
-   if (!make_name_list(query, &name_list)) {
-      exit(1);
-   }
-   printf(_("Found %d duplicate Filename records.\n"), name_list.num_ids);
-   if (name_list.num_ids && verbose && yes_no(_("Print the list? (yes/no): "))) {
-      print_name_list(&name_list);
-   }
-   if (quit) {
-      return;
-   }
-   if (fix) {
-      /* Loop through list of duplicate names */
-      for (int i=0; i<name_list.num_ids; i++) {
-         /* Get all the Ids of each name */
-         db_escape_string(NULL, db, esc_name, name_list.name[i], strlen(name_list.name[i]));
-         bsnprintf(buf, sizeof(buf), "SELECT FilenameId FROM Filename WHERE Name='%s'", esc_name);
-         if (verbose > 1) {
-            printf("%s\n", buf);
-         }
-         if (!make_id_list(buf, &id_list)) {
-            exit(1);
-         }
-         if (verbose) {
-            printf(_("Found %d for: %s\n"), id_list.num_ids, name_list.name[i]);
-         }
-         /* Force all records to use the first id then delete the other ids */
-         for (int j=1; j<id_list.num_ids; j++) {
-            char ed1[50], ed2[50];
-            bsnprintf(buf, sizeof(buf), "UPDATE File SET FilenameId=%s WHERE FilenameId=%s",
-               edit_int64(id_list.Id[0], ed1), edit_int64(id_list.Id[j], ed2));
-            if (verbose > 1) {
-               printf("%s\n", buf);
-            }
-            db_sql_query(db, buf, NULL, NULL);
-            bsnprintf(buf, sizeof(buf), "DELETE FROM Filename WHERE FilenameId=%s",
-               ed2);
-            if (verbose > 2) {
-               printf("%s\n", buf);
-            }
-            db_sql_query(db, buf, NULL, NULL);
-         }
-      }
-   }
-   free_name_list(&name_list);
-}
-
 static void eliminate_duplicate_paths()
 {
    const char *query;
@@ -861,8 +756,8 @@ static void eliminate_orphaned_file_records()
          for (int i=0; i < id_list.num_ids; i++) {
             char ed1[50];
             bsnprintf(buf, sizeof(buf),
-"SELECT File.FileId,File.JobId,Filename.Name FROM File,Filename "
-   "WHERE File.FileId=%s AND File.FilenameId=Filename.FilenameId",
+"SELECT File.FileId,File.JobId,File.Filename FROM File "
+"WHERE File.FileId=%s",
                edit_int64(id_list.Id[i], ed1));
             if (!db_sql_query(db, buf, print_file_handler, NULL)) {
                printf("%s\n", db_strerror(db));
@@ -950,57 +845,6 @@ static void eliminate_orphaned_path_records()
    drop_tmp_idx("idxPIchk", "File");
 }
 
-static void eliminate_orphaned_filename_records()
-{
-   idx_tmp_name = NULL;
-   /* Check the existence of the required "one column" index */
-   if (!check_idx("FilenameId") )      {
-      if (yes_no(_("Create temporary index? (yes/no): "))) {
-         /* Create temporary index FilenameId */
-         create_tmp_idx("idxFIchk", "File", "FilenameId");
-      }
-   }
-
-   const char *query = "SELECT Filename.FilenameId,File.FilenameId FROM Filename "
-                "LEFT OUTER JOIN File ON (Filename.FilenameId=File.FilenameId) "
-                "WHERE File.FilenameId IS NULL LIMIT 300000";
-
-   printf(_("Checking for orphaned Filename entries. This may take some time!\n"));
-   if (verbose > 1) {
-      printf("%s\n", query);
-   }
-   if (!make_id_list(query, &id_list)) {
-      exit(1);
-   }
-   /* Loop doing 300000 at a time */
-   while (id_list.num_ids != 0) {
-      printf(_("Found %d orphaned Filename records.\n"), id_list.num_ids);
-      if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) {
-         for (int i=0; i < id_list.num_ids; i++) {
-            char ed1[50];
-            bsnprintf(buf, sizeof(buf), "SELECT Name FROM Filename WHERE FilenameId=%s", 
-               edit_int64(id_list.Id[i], ed1));
-            db_sql_query(db, buf, print_name_handler, NULL);
-         }
-      }
-      if (quit) {
-         return;
-      }
-      if (fix && id_list.num_ids > 0) {
-         printf(_("Deleting %d orphaned Filename records.\n"), id_list.num_ids);
-         delete_id_list("DELETE FROM Filename WHERE FilenameId=%s", &id_list);
-      } else {
-         break;                       /* get out if not updating db */
-      }
-      if (!make_id_list(query, &id_list)) {
-         exit(1);
-      }
-   }
-   /* Drop temporary index idx_tmp_name */
-   drop_tmp_idx("idxFIchk", "File");
-
-}
-
 static void eliminate_orphaned_fileset_records()
 {
    const char *query;
@@ -1220,71 +1064,6 @@ static void eliminate_verify_records()
    }
 }
 
-static void repair_bad_filenames()
-{
-   const char *query;
-   int i;
-
-   printf(_("Checking for Filenames with a trailing slash\n"));
-   query = "SELECT FilenameId,Name from Filename "
-           "WHERE Name LIKE '%/'";
-   if (verbose > 1) {
-      printf("%s\n", query);
-   }
-   if (!make_id_list(query, &id_list)) {
-      exit(1);
-   }
-   printf(_("Found %d bad Filename records.\n"), id_list.num_ids);
-   if (id_list.num_ids && verbose && yes_no(_("Print them? (yes/no): "))) {
-      for (i=0; i < id_list.num_ids; i++) {
-         char ed1[50];
-         bsnprintf(buf, sizeof(buf),
-            "SELECT Name FROM Filename WHERE FilenameId=%s", 
-                edit_int64(id_list.Id[i], ed1));
-         if (!db_sql_query(db, buf, print_name_handler, NULL)) {
-            printf("%s\n", db_strerror(db));
-         }
-      }
-   }
-   if (quit) {
-      return;
-   }
-   if (fix && id_list.num_ids > 0) {
-      POOLMEM *name = get_pool_memory(PM_FNAME);
-      char esc_name[5000];
-      printf(_("Reparing %d bad Filename records.\n"), id_list.num_ids);
-      for (i=0; i < id_list.num_ids; i++) {
-         int len;
-         char ed1[50];
-         bsnprintf(buf, sizeof(buf),
-            "SELECT Name FROM Filename WHERE FilenameId=%s", 
-               edit_int64(id_list.Id[i], ed1));
-         if (!db_sql_query(db, buf, get_name_handler, name)) {
-            printf("%s\n", db_strerror(db));
-         }
-         /* Strip trailing slash(es) */
-         for (len=strlen(name); len > 0 && IsPathSeparator(name[len-1]); len--)
-            {  }
-         if (len == 0) {
-            len = 1;
-            esc_name[0] = ' ';
-            esc_name[1] = 0;
-         } else {
-            name[len-1] = 0;
-            db_escape_string(NULL, db, esc_name, name, len);
-         }
-         bsnprintf(buf, sizeof(buf),
-            "UPDATE Filename SET Name='%s' WHERE FilenameId=%s",
-            esc_name, edit_int64(id_list.Id[i], ed1));
-         if (verbose > 1) {
-            printf("%s\n", buf);
-         }
-         db_sql_query(db, buf, NULL, NULL);
-      }
-      free_pool_memory(name); 
-   }
-}
-
 static void repair_bad_paths()
 {
    const char *query;
@@ -1292,7 +1071,7 @@ static void repair_bad_paths()
 
    printf(_("Checking for Paths without a trailing slash\n"));
    query = "SELECT PathId,Path from Path "
-           "WHERE Path NOT LIKE '%/'";
+           "WHERE Path NOT LIKE '%/' and Path != ''";
    if (verbose > 1) {
       printf("%s\n", query);
    }