From: Eric Bollengier Date: Wed, 16 Dec 2020 09:36:21 +0000 (+0100) Subject: BEE Backport bacula/src/tools/dbcheck.c X-Git-Tag: Release-11.3.2~940 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c32798eedd8c2945736da2968054bd7fb2b0f6dc;p=thirdparty%2Fbacula.git BEE Backport bacula/src/tools/dbcheck.c This commit is the result of the squash of the following main commits: Author: Alain Spineux 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 Date: Mon Feb 4 12:37:05 2019 +0100 Implement eliminate verify records in dbcheck bug #2434 Author: Eric Bollengier Date: Mon Aug 26 13:57:34 2013 +0200 Merge Filename table to File --- diff --git a/bacula/src/tools/dbcheck.c b/bacula/src/tools/dbcheck.c old mode 100644 new mode 100755 index 00f769082..254034229 --- a/bacula/src/tools/dbcheck.c +++ b/bacula/src/tools/dbcheck.c @@ -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] [] [] [] [] [] [] []\n" +"Usage: dbcheck [-c config ] [-B] [-C catalog name] [-d debug_level] [] []\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 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 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); }