/* * disk_reserve_instance - This is used to reserve space for an instance that * was referenced in the load file but has not yet been defined. * return: NO_ERROR if successful, error code otherwise * classop(in): class * oid(in): returned instance OID */ int disk_reserve_instance (MOP classop, OID * oid) { int error = NO_ERROR; SM_CLASS *class_; HFID *hfid; int expected; class_ = (SM_CLASS *) locator_fetch_class (classop, DB_FETCH_READ); if (class_ == NULL) { error = er_errid (); } else { expected = estimate_object_size (class_); hfid = get_class_heap (classop, class_); if (hfid == NULL) { error = er_errid (); } else { if (heap_assign_address_with_class_oid (NULL, hfid, oid, expected, ws_oid (classop)) != NO_ERROR) { error = ER_LDR_CANT_INSERT; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error, 0); } } } return error; }
/* * get_class_heap - This locates or creates a heap file for a class. * return: heap file of the class * classop(in): class object * class(in): class structure */ static HFID * get_class_heap (MOP classop, SM_CLASS * class_) { HFID *hfid; OID *class_oid; hfid = sm_ch_heap ((MOBJ) class_); if (HFID_IS_NULL (hfid)) { /* could also accomplish this by creating a single instance */ /* * make sure the class is fetched for update so that it will be * marked dirty and stored with the new heap */ if (au_fetch_class (classop, &class_, AU_FETCH_UPDATE, AU_INSERT) != NO_ERROR) { hfid = NULL; } else { const bool reuse_oid = (class_->flags & SM_CLASSFLAG_REUSE_OID) ? true : false; class_oid = ws_oid (classop); if (OID_ISTEMP (class_oid)) { /* not defined function */ class_oid = locator_assign_permanent_oid (classop); } if (xheap_create (NULL, hfid, class_oid, reuse_oid) != NO_ERROR) { hfid = NULL; } } } return (hfid); }
/* * compactdb_start - Compact classes * return: error code * verbose_flag(in): * delete_old_repr_flag(in): delete old class representations from catalog * input_filename(in): classes file name * input_class_names(in): classes list * input_class_length(in): classes list length * max_processed_space(in): maximum space to process for one iteration */ static int compactdb_start (bool verbose_flag, bool delete_old_repr_flag, char *input_filename, char **input_class_names, int input_class_length, int max_processed_space, int instance_lock_timeout, int class_lock_timeout, DB_TRAN_ISOLATION tran_isolation) { int status = NO_ERROR; OID **class_oids = NULL, *next_oid = NULL; int i, num_classes = 0; LIST_MOPS *class_table = NULL; OID last_processed_class_oid, last_processed_oid; int *total_objects = NULL, *iteration_total_objects = NULL; int *failed_objects = NULL, *iteration_failed_objects = NULL; int *modified_objects = NULL, *iteration_modified_objects = NULL; char *incomplete_processing = NULL; int *big_objects = NULL, *iteration_big_objects = NULL; int *initial_last_repr = NULL; MOP *class_mops = NULL; int last_completed_class_index, temp_index; int num_class_mops = 0; SM_CLASS *class_ptr = NULL; int num_classes_fully_compacted = 0; char *class_name = NULL; MOP *processed_class_mops = NULL; if (input_filename && input_class_names && input_class_length > 0) { return ER_FAILED; } status = compact_db_start (); if (status != NO_ERROR) { if (status == ER_COMPACTDB_ALREADY_STARTED) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_ALREADY_STARTED)); } return ER_FAILED; } tran_reset_wait_times ((float) class_lock_timeout); if (input_class_names && input_class_length > 0) { status = get_class_mops (input_class_names, input_class_length, &class_mops, &num_class_mops); if (status != NO_ERROR) { goto error; } } else if (input_filename) { status = get_class_mops_from_file (input_filename, &class_mops, &num_class_mops); if (status != NO_ERROR) { goto error; } } else { class_table = locator_get_all_mops (sm_Root_class_mop, DB_FETCH_QUERY_READ); if (!class_table) { status = ER_FAILED; goto error; } class_mops = class_table->mops; num_class_mops = class_table->num; } class_oids = (OID **) malloc (DB_SIZEOF (OID *) * (num_class_mops)); if (class_oids == NULL) { status = ER_FAILED; goto error; } for (i = 0; i < num_class_mops; i++) { class_oids[i] = NULL; } processed_class_mops = (DB_OBJECT **) malloc (DB_SIZEOF (DB_OBJECT *) * (num_class_mops)); if (processed_class_mops == NULL) { status = ER_FAILED; goto error; } for (i = 0; i < num_class_mops; i++) { processed_class_mops[i] = NULL; } num_classes = 0; for (i = 0; i < num_class_mops; i++) { ws_find (class_mops[i], (MOBJ *) & class_ptr); if (class_ptr == NULL) { continue; } if (class_ptr->class_type != SM_CLASS_CT) { continue; } class_oids[num_classes] = ws_oid (class_mops[i]); if (class_oids[num_classes] != NULL) { processed_class_mops[num_classes] = class_mops[i]; num_classes++; } } if (num_classes == 0) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_NOTHING_TO_PROCESS)); goto error; } total_objects = (int *) malloc (num_classes * sizeof (int)); if (total_objects == NULL) { status = ER_FAILED; goto error; } iteration_total_objects = (int *) malloc (num_classes * sizeof (int)); if (iteration_total_objects == NULL) { status = ER_FAILED; goto error; } failed_objects = (int *) malloc (num_classes * sizeof (int)); if (failed_objects == NULL) { status = ER_FAILED; goto error; } iteration_failed_objects = (int *) malloc (num_classes * sizeof (int)); if (iteration_failed_objects == NULL) { status = ER_FAILED; goto error; } modified_objects = (int *) malloc (num_classes * sizeof (int)); if (modified_objects == NULL) { status = ER_FAILED; goto error; } iteration_modified_objects = (int *) malloc (num_classes * sizeof (int)); if (iteration_modified_objects == NULL) { status = ER_FAILED; goto error; } big_objects = (int *) malloc (num_classes * sizeof (int)); if (big_objects == NULL) { status = ER_FAILED; goto error; } iteration_big_objects = (int *) malloc (num_classes * sizeof (int)); if (iteration_big_objects == NULL) { status = ER_FAILED; goto error; } initial_last_repr = (int *) malloc (num_classes * sizeof (int)); if (initial_last_repr == NULL) { status = ER_FAILED; goto error; } incomplete_processing = (char *) malloc (num_classes * sizeof (char)); if (incomplete_processing == NULL) { status = ER_FAILED; goto error; } for (i = 0; i < num_classes; i++) { total_objects[i] = 0; failed_objects[i] = 0; modified_objects[i] = 0; big_objects[i] = 0; incomplete_processing[i] = 0; initial_last_repr[i] = NULL_REPRID; } for (i = 0; i < num_class_mops; i++) { status = locator_flush_all_instances (class_mops[i], true); if (status != NO_ERROR) { goto error; } } status = db_commit_transaction (); if (status != NO_ERROR) { goto error; } COPY_OID (&last_processed_class_oid, class_oids[0]); OID_SET_NULL (&last_processed_oid); temp_index = -1; last_completed_class_index = -1; if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_PASS1)); } while (true) { status = db_set_isolation (tran_isolation); if (status != NO_ERROR) { if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE)); } status = ER_FAILED; goto error; } status = boot_compact_classes (class_oids, num_classes, max_processed_space, instance_lock_timeout * 1000, class_lock_timeout * 1000, delete_old_repr_flag, &last_processed_class_oid, &last_processed_oid, iteration_total_objects, iteration_failed_objects, iteration_modified_objects, iteration_big_objects, initial_last_repr); if (OID_ISNULL (&last_processed_class_oid)) { temp_index = num_classes; } else { temp_index = find_oid (&last_processed_class_oid, class_oids, num_classes); } switch (status) { case NO_ERROR: if (delete_old_repr_flag && temp_index - 1 > last_completed_class_index) { for (i = last_completed_class_index + 1; i < temp_index; i++) { if (initial_last_repr[i] == COMPACTDB_REPR_DELETED) { sm_destroy_representations (processed_class_mops[i]); } } } status = db_commit_transaction (); if (status != NO_ERROR) { goto error; } break; case ER_LK_UNILATERALLY_ABORTED: status = tran_abort_only_client (false); if (status != NO_ERROR) { goto error; } break; case ER_FAILED: status = db_abort_transaction (); if (status != NO_ERROR) { goto error; } break; default: db_abort_transaction (); status = ER_FAILED; goto error; } for (i = 0; i < num_classes; i++) { if (iteration_total_objects[i] >= 0) { total_objects[i] += iteration_total_objects[i]; failed_objects[i] += iteration_failed_objects[i]; modified_objects[i] += iteration_modified_objects[i]; big_objects[i] += iteration_big_objects[i]; } else { incomplete_processing[i] = iteration_total_objects[i]; } } if (temp_index - 1 > last_completed_class_index) { for (i = last_completed_class_index + 1; i < temp_index; i++) { status = db_set_isolation (tran_isolation); if (status != NO_ERROR) { if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE)); } status = ER_FAILED; goto error; } tran_reset_wait_times ((float) class_lock_timeout); show_statistics (class_oids[i], incomplete_processing[i] != COMPACTDB_LOCKED_CLASS, incomplete_processing[i] != COMPACTDB_INVALID_CLASS, incomplete_processing[i] != COMPACTDB_UNPROCESSED_CLASS, total_objects[i], failed_objects[i], modified_objects[i], big_objects[i], delete_old_repr_flag, initial_last_repr[i] == COMPACTDB_REPR_DELETED); db_commit_transaction (); } last_completed_class_index = temp_index - 1; } if (OID_ISNULL (&last_processed_class_oid)) { break; } } if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_PASS2)); } status = do_reclaim_addresses (class_oids, num_classes, &num_classes_fully_compacted, verbose_flag, (float) class_lock_timeout); if (status != NO_ERROR) { goto error; } if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_PASS3)); } for (i = 0; i < num_classes; i++) { status = db_set_isolation (tran_isolation); if (status != NO_ERROR) { if (verbose_flag) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_ISOLATION_LEVEL_FAILURE)); } status = ER_FAILED; goto error; } tran_reset_wait_times ((float) class_lock_timeout); status = boot_heap_compact (class_oids[i]); switch (status) { case NO_ERROR: status = db_commit_transaction (); if (status != NO_ERROR) { goto error; } break; case ER_LK_UNILATERALLY_ABORTED: status = tran_abort_only_client (false); if (status != NO_ERROR) { goto error; } break; default: status = db_abort_transaction (); if (status != NO_ERROR) { goto error; } break; } class_name = get_name_from_class_oid (class_oids[i]); if (class_name == NULL) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_UNKNOWN_CLASS_NAME)); } else { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_CLASS), class_name); } if (status != NO_ERROR) { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_HEAP_COMPACT_FAILED)); } else { printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_HEAP_COMPACT_SUCCEEDED)); } if (class_name) { free (class_name); class_name = NULL; } db_commit_transaction (); } error: if (class_oids) { free_and_init (class_oids); } if (processed_class_mops) { free_and_init (processed_class_mops); } if (total_objects) { free_and_init (total_objects); } if (iteration_total_objects) { free_and_init (iteration_total_objects); } if (failed_objects) { free_and_init (failed_objects); } if (iteration_failed_objects) { free_and_init (iteration_failed_objects); } if (modified_objects) { free_and_init (modified_objects); } if (iteration_modified_objects) { free_and_init (iteration_modified_objects); } if (big_objects) { free_and_init (big_objects); } if (iteration_big_objects) { free_and_init (iteration_big_objects); } if (initial_last_repr) { free_and_init (initial_last_repr); } if (incomplete_processing) { free_and_init (incomplete_processing); } if (class_table) { locator_free_list_mops (class_table); } else { if (class_mops) { for (i = 0; i < num_class_mops; i++) { class_mops[i] = NULL; } free_and_init (class_mops); } } compact_db_stop (); return status; }