/* * realloc_instance_table - Extends the instance array within a CLASS_TABLE. * return: NO_ERROR if successful, error code otherwise * table(in/out): class table to extend * newcount(in): new size of the instance table */ static int realloc_instance_table (CLASS_TABLE * table, int newcount) { INST_INFO *tmp_inst_info; int i; /* * only do this if the new count is larger than the existing * table, shouldn't see this */ if (newcount > table->count) { tmp_inst_info = (INST_INFO *) realloc (table->instances, newcount * sizeof (INST_INFO)); if (tmp_inst_info == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_LDR_MEMORY_ERROR, 0); return er_errid (); } for (i = table->count; i < newcount; i++) { tmp_inst_info[i].flags = 0; OID_SET_NULL (&(tmp_inst_info[i].oid)); } table->instances = tmp_inst_info; table->count = newcount; } return NO_ERROR; }
/* * init_instance_table - Initialized the contents of an instance array * within a class table. * return: none * table(out): class table */ static void init_instance_table (CLASS_TABLE * table) { int i; for (i = 0; i < table->count; i++) { table->instances[i].flags = 0; OID_SET_NULL (&(table->instances[i].oid)); } }
/* * 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; }
/* * process_value () - process a value * * return : error status * value(in,out) - the processed value * */ static int process_value (DB_VALUE * value) { int return_value = 0; switch (DB_VALUE_TYPE (value)) { case DB_TYPE_OID: { OID *ref_oid; OID ref_class_oid; ref_oid = DB_GET_OID (value); if (OID_ISNULL (ref_oid)) { break; } if (!heap_get_class_oid (NULL, ref_oid, &ref_class_oid)) { OID_SET_NULL (ref_oid); return_value = 1; break; } if (is_class (ref_oid, &ref_class_oid)) { break; } #if defined(CUBRID_DEBUG) printf (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COMPACTDB, COMPACTDB_MSG_REFOID), ref_oid->volid, ref_oid->pageid, ref_oid->slotid, ref_class_oid.volid, ref_class_oid.pageid, ref_class_oid.slotid); #endif if (!heap_does_exist (NULL, ref_oid, &ref_class_oid)) { OID_SET_NULL (ref_oid); return_value = 1; } break; } case DB_TYPE_POINTER: case DB_TYPE_MULTISET: case DB_TYPE_SEQUENCE: case DB_TYPE_SET: { return_value = process_set (DB_GET_SET (value)); break; } default: break; } return return_value; }
/* * boot_compact_db - compact specified classes * HEAP_CACHE_ATTRINFO structure * return: error status * class_oids(in): the classes list * n_classes(in): the class_oids length * hfids(in): the hfid list * space_to_process(in): the space to process * instance_lock_timeout(in): the lock timeout for instances * class_lock_timeout(in): the lock timeout for instances * delete_old_repr(in): whether to delete the old class representation * last_processed_class_oid(in,out): last processed class oid * last_processed_oid(in,out): last processed oid * total_objects(out): count processed objects for each class * failed_objects(out): count failed objects for each class * modified_objects(out): count modified objects for each class * big_objects(out): count big objects for each class * initial_last_repr_id(in, out): the list of initial last class * representation */ int boot_compact_db (THREAD_ENTRY * thread_p, OID * class_oids, int n_classes, int space_to_process, int instance_lock_timeout, int class_lock_timeout, bool delete_old_repr, OID * last_processed_class_oid, OID * last_processed_oid, int *total_objects, int *failed_objects, int *modified_objects, int *big_objects, int *initial_last_repr_id) { int result = NO_ERROR; int i, j, start_index = -1; int max_space_to_process, current_tran_index = -1; int lock_ret; HFID hfid; if (boot_can_compact (thread_p) == false) { return ER_COMPACTDB_ALREADY_STARTED; } if (class_oids == NULL || n_classes <= 0 || space_to_process <= 0 || last_processed_class_oid == NULL || last_processed_oid == NULL || total_objects == NULL || failed_objects == NULL || modified_objects == NULL || big_objects == NULL || initial_last_repr_id == NULL) { return ER_QPROC_INVALID_PARAMETER; } for (start_index = 0; start_index < n_classes; start_index++) { if (OID_EQ (class_oids + start_index, last_processed_class_oid)) { break; } } if (start_index == n_classes) { return ER_QPROC_INVALID_PARAMETER; } for (i = 0; i < n_classes; i++) { total_objects[i] = 0; failed_objects[i] = 0; modified_objects[i] = 0; big_objects[i] = 0; } max_space_to_process = space_to_process; for (i = start_index; i < n_classes; i++) { lock_ret = lock_object_waitsecs (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, LK_UNCOND_LOCK, class_lock_timeout); if (lock_ret != LK_GRANTED) { total_objects[i] = COMPACTDB_LOCKED_CLASS; OID_SET_NULL (last_processed_oid); continue; } if (heap_get_hfid_from_class_oid (thread_p, class_oids + i, &hfid) != NO_ERROR) { lock_unlock_object (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, true); OID_SET_NULL (last_processed_oid); total_objects[i] = COMPACTDB_INVALID_CLASS; continue; } if (HFID_IS_NULL (&hfid)) { lock_unlock_object (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, true); OID_SET_NULL (last_processed_oid); total_objects[i] = COMPACTDB_INVALID_CLASS; continue; } if (OID_ISNULL (last_processed_oid)) { initial_last_repr_id[i] = heap_get_class_repr_id (thread_p, class_oids + i); if (initial_last_repr_id[i] <= 0) { lock_unlock_object (thread_p, class_oids + i, oid_Root_class_oid, IX_LOCK, true); total_objects[i] = COMPACTDB_INVALID_CLASS; continue; } } if (process_class (thread_p, class_oids + i, &hfid, max_space_to_process, &instance_lock_timeout, &space_to_process, last_processed_oid, total_objects + i, failed_objects + i, modified_objects + i, big_objects + i) != NO_ERROR) { OID_SET_NULL (last_processed_oid); for (j = start_index; j <= i; j++) { total_objects[j] = COMPACTDB_UNPROCESSED_CLASS; failed_objects[j] = 0; modified_objects[j] = 0; big_objects[j] = 0; } result = ER_FAILED; break; } if (delete_old_repr && OID_ISNULL (last_processed_oid) && failed_objects[i] == 0 && heap_get_class_repr_id (thread_p, class_oids + i) == initial_last_repr_id[i]) { lock_ret = lock_object_waitsecs (thread_p, class_oids + i, oid_Root_class_oid, X_LOCK, LK_UNCOND_LOCK, class_lock_timeout); if (lock_ret == LK_GRANTED) { if (catalog_drop_old_representations (thread_p, class_oids + i) != NO_ERROR) { for (j = start_index; j <= i; j++) { total_objects[j] = COMPACTDB_UNPROCESSED_CLASS; failed_objects[j] = 0; modified_objects[j] = 0; big_objects[j] = 0; } result = ER_FAILED; } else { initial_last_repr_id[i] = COMPACTDB_REPR_DELETED; } break; } } if (space_to_process == 0) { break; } } if (OID_ISNULL (last_processed_oid)) { if (i < n_classes - 1) { COPY_OID (last_processed_class_oid, class_oids + i + 1); } else { OID_SET_NULL (last_processed_class_oid); } } else { COPY_OID (last_processed_class_oid, class_oids + i); } return result; }