Example #1
0
/*
 * 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;
}
Example #2
0
/*
 * 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);
}
Example #3
0
/*
 * 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;
}