Exemple #1
0
/*
 * es_rename_file - rename a locator according to the metaname
 *
 * return: error code
 * in_uri(in):
 * metapath(in) : meta name combined with in_uri
 * out_uri(out):
 */
int
es_rename_file (const char *in_uri, const char *metaname, char *out_uri)
{
  int ret;
  ES_TYPE es_type;

  assert (in_uri != NULL);
  assert (out_uri != NULL);
  assert (metaname != NULL);

  if (es_initialized_type == ES_NONE)
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_NO_LOB_PATH, 0);
      return ER_ES_NO_LOB_PATH;
    }

  es_type = es_get_type (in_uri);
  if (es_type != es_initialized_type)
    {
      /* copy file operation is allowed only between same types */
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_COPY_TO_DIFFERENT_TYPE, 2, es_get_type_string (es_type),
	      es_get_type_string (es_initialized_type));
      return ER_ES_COPY_TO_DIFFERENT_TYPE;
    }

  if (es_type == ES_OWFS)
    {
#if defined(WINDOWS)
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_GENERAL, 2, "OwFS", "not supported");
      ret = ER_ES_GENERAL;
#else /* WINDOWS */
      strncpy (out_uri, ES_OWFS_PATH_PREFIX, sizeof (ES_OWFS_PATH_PREFIX));
      ret = es_owfs_rename_file (ES_OWFS_PATH_POS (in_uri), metaname, ES_OWFS_PATH_POS (out_uri));
      er_log_debug (ARG_FILE_LINE, "es_copy_file: es_owfs_copy_file(%s) -> %s: %d\n", in_uri, out_uri, ret);
#endif /* !WINDOWS */
    }
  else if (es_type == ES_POSIX)
    {
      strncpy (out_uri, ES_POSIX_PATH_PREFIX, sizeof (ES_POSIX_PATH_PREFIX));
#if defined (CS_MODE)
      ret = es_posix_rename_file (ES_POSIX_PATH_POS (in_uri), metaname, ES_POSIX_PATH_POS (out_uri));
      er_log_debug (ARG_FILE_LINE, "es_copy_file: es_posix_copy_file(%s) -> %s: %d\n", in_uri, out_uri, ret);
#else /* CS_MODE */
      ret = xes_posix_rename_file (ES_POSIX_PATH_POS (in_uri), metaname, ES_POSIX_PATH_POS (out_uri));
      er_log_debug (ARG_FILE_LINE, "es_copy_file: xes_posix_copy_file(%s) -> %s: %d\n", in_uri, out_uri, ret);
#endif /* SERVER_MODE || SA_MODE */
    }
  else
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_INVALID_PATH, 1, in_uri);
      return ER_ES_INVALID_PATH;
    }

  return ret;
}
Exemple #2
0
/*
 * es_read_file -
 *
 * return:
 * uri(in)
 * buf(out)
 * count(in)
 * offset(in)
 */
ssize_t
es_read_file (const char *uri, void *buf, size_t count, off_t offset)
{
  ssize_t ret;
  ES_TYPE es_type;

  assert (uri != NULL);
  assert (buf != NULL);
  assert (count > 0);
  assert (offset >= 0);

  if (es_initialized_type == ES_NONE)
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_NO_LOB_PATH, 0);
      return ER_ES_NO_LOB_PATH;
    }

  es_type = es_get_type (uri);
  if (es_type == ES_OWFS)
    {
#if defined(WINDOWS)
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_GENERAL, 2, "OwFS", "not supported");
      ret = ER_ES_GENERAL;
#else /* WINDOWS */
      ret = es_owfs_read_file (ES_OWFS_PATH_POS (uri), buf, count, offset);
      er_log_debug (ARG_FILE_LINE, "es_read_file: (es_owfs_read_file(%s, count %d, offset %ld) -> %d\n", uri, count,
		    offset, ret);
#endif /* !WINDOWS */
    }
  else if (es_type == ES_POSIX)
    {
#if defined (CS_MODE)
      ret = es_posix_read_file (ES_POSIX_PATH_POS (uri), buf, count, offset);
      er_log_debug (ARG_FILE_LINE, "es_read_file: es_posix_read_file(%s, count %d, offset %ld) -> %d\n", uri, count,
		    offset, ret);
#else /* CS_MODE */
      ret = xes_posix_read_file (ES_POSIX_PATH_POS (uri), buf, count, offset);
      er_log_debug (ARG_FILE_LINE, "es_read_file: xes_posix_read_file(%s, count %d, offset %ld) -> %d\n", uri, count,
		    offset, ret);
#endif /* SERVER_MODE || SA_MODE */
    }
  else if (es_type == ES_LOCAL)
    {
      ret = es_local_read_file (ES_LOCAL_PATH_POS (uri), buf, count, offset);
      er_log_debug (ARG_FILE_LINE, "es_read_file: es_local_read_file(%s, count %d, offset %ld) -> %d\n", uri, count,
		    offset, ret);
    }
  else
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_INVALID_PATH, 1, uri);
      return ER_ES_INVALID_PATH;
    }

  return ret;
}
Exemple #3
0
/*
 * es_get_file_size
 *
 * return: file size or -1 on error
 * uri(in):
*/
off_t
es_get_file_size (const char *uri)
{
  off_t ret;
  ES_TYPE es_type;

  assert (uri != NULL);

  if (es_initialized_type == ES_NONE)
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_NO_LOB_PATH, 0);
      return ER_ES_NO_LOB_PATH;
    }

  es_type = es_get_type (uri);
  if (es_type == ES_OWFS)
    {
#if defined(WINDOWS)
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_GENERAL, 2, "OwFS", "not supported");
      ret = ER_ES_GENERAL;
#else /* WINDOWS */
      ret = es_owfs_get_file_size (ES_OWFS_PATH_POS (uri));
      er_log_debug (ARG_FILE_LINE, "es_copy_file: es_owfs_get_file_size(%s) -> %d\n", uri, ret);
#endif /* !WINDOWS */
    }
  else if (es_type == ES_POSIX)
    {
#if defined (CS_MODE)
      ret = es_posix_get_file_size (ES_POSIX_PATH_POS (uri));
      er_log_debug (ARG_FILE_LINE, "es_copy_file: es_posix_get_file_size(%s) -> %d\n", uri, ret);
#else /* CS_MODE */
      ret = xes_posix_get_file_size (ES_POSIX_PATH_POS (uri));
      er_log_debug (ARG_FILE_LINE, "es_copy_file: xes_posix_get_file_size(%s) -> %d\n", uri, ret);
#endif /* SERVER_MODE || SA_MODE */
    }
  else if (es_type == ES_LOCAL)
    {
      ret = es_local_get_file_size (ES_LOCAL_PATH_POS (uri));
      er_log_debug (ARG_FILE_LINE, "es_copy_file: es_local_get_file_size(%s) -> %d\n", uri, ret);
    }
  else
    {
      ret = -1;
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_INVALID_PATH, 1, uri);
    }

  return ret;
}
Exemple #4
0
static FILE *
sl_log_open ()
{
  char cur_sql_log_path[PATH_MAX];
  FILE *fp;

  snprintf (cur_sql_log_path, PATH_MAX, "%s.%d", sql_log_base_path, sl_Info.curr_file_id);

  fp = fopen (cur_sql_log_path, "r+");
  if (fp != NULL)
    {
      fseek (fp, 0, SEEK_END);
      if (ftell (fp) >= SL_LOG_FILE_MAX_SIZE)
	{
	  fp = sl_open_next_file (fp);
	}
    }
  else
    {
      fp = fopen (cur_sql_log_path, "w");
    }

  if (fp == NULL)
    {
      er_log_debug (ARG_FILE_LINE, "Failed to open SQL log file (%s): %s", cur_sql_log_path, strerror (errno));
    }

  return fp;
}
Exemple #5
0
/*
 * logwr_flush_header_page -
 *
 * return:
 * Note:
 */
void
logwr_flush_header_page (void)
{
  PAGEID phy_pageid;
  PAGEID logical_pageid;
  int nbytes;

  if (logwr_Gl.loghdr_pgptr == NULL)
    {
      return;
    }

  /* flush current archiving status */
  logwr_Gl.hdr.nxarv_num = logwr_Gl.last_arv_num;
  logwr_Gl.hdr.last_deleted_arv_num = logwr_Gl.last_deleted_arv_num;
  logwr_Gl.hdr.nxarv_pageid = logwr_Gl.last_arv_fpageid;
  logwr_Gl.hdr.nxarv_phy_pageid
    = logwr_to_physical_pageid (logwr_Gl.last_arv_fpageid);

  memcpy (logwr_Gl.loghdr_pgptr->area, &logwr_Gl.hdr, sizeof (logwr_Gl.hdr));

  logical_pageid = LOGPB_HEADER_PAGE_ID;
  phy_pageid = logwr_to_physical_pageid (logical_pageid);

  /* logwr_Gl.append_vdes is only changed
   * while starting or finishing or recovering server.
   * So, log cs is not needed.
   */
  if (fileio_write (NULL, logwr_Gl.append_vdes, logwr_Gl.loghdr_pgptr,
		    phy_pageid, LOG_PAGESIZE) == NULL
      || (logwr_Gl.mode != LOGWR_MODE_ASYNC
	  && fileio_synchronize (NULL, logwr_Gl.append_vdes,
				 logwr_Gl.active_name)) == NULL_VOLDES)
    {

      if (er_errid () == ER_IO_WRITE_OUT_OF_SPACE)
	{
	  nbytes = ((logwr_Gl.hdr.npages + 1 - logical_pageid) *
		    logwr_Gl.hdr.db_logpagesize);
	  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE,
		  ER_LOG_WRITE_OUT_OF_SPACE, 4, logical_pageid, phy_pageid,
		  logwr_Gl.active_name, nbytes);
	}
      else
	{
	  er_set_with_oserror (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE,
			       ER_LOG_WRITE, 3, logical_pageid, phy_pageid,
			       logwr_Gl.active_name);
	}
    }

  /* save last checkpoint pageid */
  logwr_Gl.last_chkpt_pageid = logwr_Gl.hdr.chkpt_lsa.pageid;

  er_log_debug (ARG_FILE_LINE,
		"logwr_flush_header_page, ha_server_state=%s, ha_file_status=%s\n",
		css_ha_server_state_string (logwr_Gl.hdr.ha_server_state),
		logwr_Gl.hdr.ha_file_status ==
		LOG_HA_FILESTAT_SYNCHRONIZED ? "sync" : "unsync");
}
Exemple #6
0
/*    
* hb_process_init () - 
*   return: NO_ERROR or ER_FAILED
*
*   server_name(in):
*   log_path(in):
*   copylogdbyn(in):
*/
int
hb_process_init (const char *server_name, const char *log_path, HB_PROC_TYPE type)
{
  int error;
  static bool is_first = true;

#if !defined(SERVER_MODE)
  if (is_first == false)
    {
      return (NO_ERROR);
    }

  er_log_debug (ARG_FILE_LINE, "hb_process_init. (type:%s). \n", hb_type_to_str (type));

  if (hb_Exec_path[0] == '\0' || *(hb_Argv) == 0)
    {
      er_log_debug (ARG_FILE_LINE, "hb_Exec_path or hb_Argv is not set. \n");
      return (ER_FAILED);
    }

  hb_Conn = hb_connect_to_master (server_name, log_path, type);

  /* wait 1 sec */
  sleep (1);

  error = hb_register_to_master (hb_Conn, type);
  if (NO_ERROR != error)
    {
      er_log_debug (ARG_FILE_LINE, "hb_register_to_master failed. \n");
      return (error);
    }

  error = hb_create_master_reader ();
  if (NO_ERROR != error)
    {
      er_log_debug (ARG_FILE_LINE, "hb_create_master_reader failed. \n");
      return (error);
    }

  is_first = false;
  return (NO_ERROR);
#endif
  return (ER_FAILED);
}
Exemple #7
0
/*    
* hb_register_to_master () - 
*   return: NO_ERROR or ER_FAILED
*
*   conn(in):
*   type(in):
*/
int
hb_register_to_master (CSS_CONN_ENTRY * conn, int type)
{
  int error;
  HBP_PROC_REGISTER *hbp_register = NULL;

  if (NULL == conn)
    {
      er_log_debug (ARG_FILE_LINE, "invalid conn. (conn:NULL).\n");
      return (ER_FAILED);
    }

  hbp_register = hb_make_set_hbp_register (type);
  if (NULL == hbp_register)
    {
      er_log_debug (ARG_FILE_LINE, "hbp_register failed. \n");
      return (ER_FAILED);
    }

  if (!IS_INVALID_SOCKET (conn->fd))
    {
      error = css_send_heartbeat_request (conn, SERVER_REGISTER_HA_PROCESS);
      if (error != NO_ERRORS)
	{
	  goto error_return;
	}

      error = css_send_heartbeat_data (conn, (const char *) hbp_register, sizeof (*hbp_register));
      if (error != NO_ERRORS)
	{
	  goto error_return;
	}
    }
  free_and_init (hbp_register);
  return (NO_ERROR);

error_return:
  free_and_init (hbp_register);
  return (ER_FAILED);
}
Exemple #8
0
/*
 * es_create_file -
 *
 * return: error code
 * out_uri(out):
 */
int
es_create_file (char *out_uri)
{
  int ret;

  assert (out_uri != NULL);

  if (es_initialized_type == ES_OWFS)
    {
#if defined(WINDOWS)
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_GENERAL, 2, "OwFS", "not supported");
      ret = ER_ES_GENERAL;
#else /* WINDOWS */
      strncpy (out_uri, ES_OWFS_PATH_PREFIX, sizeof (ES_OWFS_PATH_PREFIX));
      ret = es_owfs_create_file (ES_OWFS_PATH_POS (out_uri));
      er_log_debug (ARG_FILE_LINE, "es_create_file: es_owfs_create_file() -> %s: %d\n", out_uri, ret);
#endif /* !WINDOWS */
    }
  else if (es_initialized_type == ES_POSIX)
    {
      strncpy (out_uri, ES_POSIX_PATH_PREFIX, sizeof (ES_POSIX_PATH_PREFIX));
#if defined (CS_MODE)
      ret = es_posix_create_file (ES_POSIX_PATH_POS (out_uri));
      er_log_debug (ARG_FILE_LINE, "es_create_file: es_posix_create_file() -> %s: %d\n", out_uri, ret);
#else /* CS_MODE */
      ret = xes_posix_create_file (ES_POSIX_PATH_POS (out_uri));
      er_log_debug (ARG_FILE_LINE, "es_create_file: xes_posix_create_file() -> %s: %d\n", out_uri, ret);
#endif /* SERVER_MODE || SA_MODE */
    }
  else
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ES_NO_LOB_PATH, 0);
      return ER_ES_NO_LOB_PATH;
    }

  return ret;
}
Exemple #9
0
static int
set_server_error (int error)
{
  int server_error;

  switch (error)
    {
    case CANT_ALLOC_BUFFER:
      server_error = ER_NET_CANT_ALLOC_BUFFER;
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, server_error, 0);
      break;
    case RECORD_TRUNCATED:
      server_error = ER_NET_DATA_TRUNCATED;
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, server_error, 0);
      break;
    case REQUEST_REFUSED:
      server_error = er_errid ();
      break;
    case SERVER_ABORTED:
      server_error = er_errid ();
      /* those errors are generated by the net_server_request()
       * so that do not fall to server crash handling */
      switch (server_error)
	{
	case ER_DB_NO_MODIFICATIONS:
	  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, server_error, 0);
	  return (server_error);
	case ER_AU_DBA_ONLY:
	  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, server_error, 1, "");
	  return (server_error);
	}
      /* no break; fall through */
    default:
      server_error = ER_NET_SERVER_CRASHED;
      er_set_with_oserror (ER_ERROR_SEVERITY, ARG_FILE_LINE, server_error, 0);
      break;
    }

  er_log_debug (ARG_FILE_LINE, "set_server_error(%d) server_error %d\n",
		error, server_error);

  db_Connect_status = DB_CONNECTION_STATUS_NOT_CONNECTED;

  return (server_error);
}
Exemple #10
0
/*    
* hb_process_to_master () - 
*   return: NO_ERROR or ER_FAILED
*
*   argv(in):
*/
int
hb_process_master_request (void)
{
  int error;
  int r, status = 0;
  struct pollfd po[1] = { {0, 0, 0} };

  if (NULL == hb_Conn)
    {
      er_log_debug (ARG_FILE_LINE, "hb_Conn did not allocated yet. \n");
      return (ER_FAILED);
    }

  while (false == hb_Proc_shutdown)
    {
      po[0].fd = hb_Conn->fd;
      po[0].events = POLLIN;
      r = poll (po, 1, (prm_get_integer_value (PRM_ID_TCP_CONNECTION_TIMEOUT) * 1000));

      switch (r)
	{
	case 0:
	  break;
	case -1:
	  if (!IS_INVALID_SOCKET (hb_Conn->fd)
#if defined(WINDOWS)
	      && ioctlsocket (hb_Conn->fd, FIONREAD, (u_long *) & status) == SOCKET_ERROR
#else /* WINDOWS */
	      && fcntl (hb_Conn->fd, F_GETFL, status) < 0
#endif /* WINDOWS */
	    )
	    hb_Proc_shutdown = true;
	  break;
	default:
	  error = hb_process_master_request_info (hb_Conn);
	  if (NO_ERROR != error)
	    {
	      hb_Proc_shutdown = true;
	    }
	  break;
	}
    }

  return (ER_FAILED);
}
Exemple #11
0
/*
 * rv_check_rvfuns - CHECK ORDERING OF RECOVERY FUNCTIONS
 *
 * return:
 *
 * NOTE:Check the ordering of recovery functions.
 *              This is a debugging function.
 */
void
rv_check_rvfuns (void)
{
  unsigned int i, num_indices;

  num_indices = DIM (RV_fun);

  for (i = 0; i < num_indices; i++)
    if (RV_fun[i].recv_index != i)
      {
	er_log_debug (ARG_FILE_LINE, "log_check_rvfuns: *** SYSTEM ERROR ***"
		      " Bad compilation... Recovery function %d is out of"
		      " sequence in index %d of recovery function array\n",
		      RV_fun[i].recv_index, i);
	er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_GENERIC_ERROR, 0);
	break;
      }

}
Exemple #12
0
/*    
* hb_process_master_request_info () - 
*   return: NO_ERROR or ER_FAILED
*
*   conn(in):
*/
static int
hb_process_master_request_info (CSS_CONN_ENTRY * conn)
{
  int rc;
  int command;

  if (NULL == conn)
    {
      er_log_debug (ARG_FILE_LINE, "invalid conn. (conn:NULL).\n");
      return (ER_FAILED);
    }

  rc = css_receive_heartbeat_request (conn, &command);
  if (rc == NO_ERRORS)
    {
      /* Ignore request, just check connection is alive or not */
      return (NO_ERROR);
    }

  return (ER_FAILED);
}
Exemple #13
0
static int
sl_write_catalog ()
{
  if (catalog_fp == NULL)
    {
      if ((catalog_fp = fopen (sql_catalog_path, "r+")) == NULL)
	{
	  catalog_fp = fopen (sql_catalog_path, "w");
	}
    }

  if (catalog_fp == NULL)
    {
      er_log_debug (ARG_FILE_LINE, "Cannot open SQL catalog file: %s", strerror (errno));
      return ER_FAILED;
    }
  fseek (catalog_fp, 0, SEEK_SET);
  fprintf (catalog_fp, CATALOG_FORMAT, sl_Info.curr_file_id, sl_Info.last_inserted_sql_id);

  fflush (catalog_fp);
  fsync (fileno (catalog_fp));

  return NO_ERROR;
}
Exemple #14
0
/*
 * overflow_insert () - Insert a multipage data in overflow
 *   return: ovf_vpid on success or NULL on failure
 *   ovf_vfid(in): File where the overflow data is going to be stored
 *   ovf_vpid(out): Overflow address
 *   recdes(in): Record descriptor
 *
 * Note: Data in overflow is composed of several pages. Pages in the overflow
 *       area are not shared among other pieces of overflow data.
 *
 *       --------------------------------         ------------------------
 *       |Next_vpid |Length|... data ...| ... --> |Next_vpid|... data ...|
 *       --------------------------------         ------------------------
 *
 *       Single link list of pages.
 *       The length of the multipage data is stored on its first overflow page
 *
 *       Overflow pages are not locked in any mode since they are not shared
 *       by other pieces of data and its address is only know by accessing the
 *       relocation overflow record data which has been appropriately locked.
 */
VPID *
overflow_insert (THREAD_ENTRY * thread_p, const VFID * ovf_vfid,
		 VPID * ovf_vpid, RECDES * recdes)
{
  PAGE_PTR vfid_fhdr_pgptr = NULL;
  OVERFLOW_FIRST_PART *first_part;
  OVERFLOW_REST_PART *rest_parts;
  OVERFLOW_RECV_LINKS undo_recv;
  char *copyto;
  int length, copy_length;
  INT32 npages = 0;
  char *data;
  int alloc_nth;
  LOG_DATA_ADDR addr;
  LOG_DATA_ADDR logical_undoaddr;
  int i;
  VPID *vpids, fhdr_vpid;
  VPID vpids_buffer[OVERFLOW_ALLOCVPID_ARRAY_SIZE + 1];
  FILE_ALLOC_VPIDS alloc_vpids;

  /*
   * We don't need to lock the overflow pages since these pages are not
   * shared among several pieces of overflow data. The overflow pages are
   * know by accessing the relocation-overflow record with the appropiate lock
   */

  addr.vfid = ovf_vfid;
  addr.offset = 0;

  logical_undoaddr.vfid = ovf_vfid;
  logical_undoaddr.offset = 0;
  logical_undoaddr.pgptr = NULL;

  undo_recv.ovf_vfid = *ovf_vfid;

  /*
   * Temporary:
   *   Lock the file header, so I am the only one changing the file table
   *   of allocated pages. This is needed since this function is using
   *   file_find_nthpages, which could give me not the expected page, if someone
   *   else remove pages, after the initial allocation.
   */

  fhdr_vpid.volid = ovf_vfid->volid;
  fhdr_vpid.pageid = ovf_vfid->fileid;

  vfid_fhdr_pgptr = pgbuf_fix (thread_p, &fhdr_vpid, OLD_PAGE,
			       PGBUF_LATCH_WRITE, PGBUF_UNCONDITIONAL_LATCH);
  if (vfid_fhdr_pgptr == NULL)
    {
      return NULL;
    }

  /*
   * Guess the number of pages. The total number of pages is found by
   * dividing length by pagesize - the smallest header. Then, we make sure
   * that this estimate is correct.
   */
  length = recdes->length - (DB_PAGESIZE -
			     (int) offsetof (OVERFLOW_FIRST_PART, data));
  if (length > 0)
    {
      i = DB_PAGESIZE - offsetof (OVERFLOW_REST_PART, data);
      npages = 1 + CEIL_PTVDIV (length, i);
    }
  else
    {
      npages = 1;
    }

  if (npages > OVERFLOW_ALLOCVPID_ARRAY_SIZE)
    {
      vpids = (VPID *) malloc ((npages + 1) * sizeof (VPID));
      if (vpids == NULL)
	{
	  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY,
		  1, (npages + 1) * sizeof (VPID));
	  pgbuf_unfix (thread_p, vfid_fhdr_pgptr);
	  return NULL;
	}
    }
  else
    {
      vpids = vpids_buffer;
    }

#if !defined(NDEBUG)
  for (i = 0; i < npages; i++)
    {
      VPID_SET_NULL (&vpids[i]);
    }
#endif

  VPID_SET_NULL (&vpids[npages]);

  alloc_vpids.vpids = vpids;
  alloc_vpids.index = 0;

  /*
   * We do not initialize the pages during allocation since they are not
   * pointed by anyone until we return from this function, at that point
   * they are initialized.
   */
  if (file_alloc_pages_as_noncontiguous (thread_p, ovf_vfid, vpids,
					 &alloc_nth, npages, NULL, NULL,
					 NULL, &alloc_vpids) == NULL)
    {
      if (vpids != vpids_buffer)
	{
	  free_and_init (vpids);
	}

      pgbuf_unfix (thread_p, vfid_fhdr_pgptr);
      return NULL;
    }

  assert (alloc_vpids.index == npages);

#if !defined(NDEBUG)
  for (i = 0; i < npages; i++)
    {
      assert (!VPID_ISNULL (&vpids[i]));
    }
#endif

  *ovf_vpid = vpids[0];

  /* Copy the content of the data */

  data = recdes->data;
  length = recdes->length;

  for (i = 0; i < npages; i++)
    {
      addr.pgptr = pgbuf_fix (thread_p, &vpids[i], NEW_PAGE,
			      PGBUF_LATCH_WRITE, PGBUF_UNCONDITIONAL_LATCH);
      if (addr.pgptr == NULL)
	{
	  goto exit_on_error;
	}

      /* Is this the first page ? */
      if (i == 0)
	{
	  /* This is the first part */
	  first_part = (OVERFLOW_FIRST_PART *) addr.pgptr;

	  first_part->next_vpid = vpids[i + 1];
	  first_part->length = length;
	  copyto = (char *) first_part->data;

	  copy_length = DB_PAGESIZE - offsetof (OVERFLOW_FIRST_PART, data);
	  if (length < copy_length)
	    {
	      copy_length = length;
	    }

	  /* notify the first part of overflow recdes */
	  log_append_empty_record (thread_p, LOG_DUMMY_OVF_RECORD);
	}
      else
	{
	  rest_parts = (OVERFLOW_REST_PART *) addr.pgptr;

	  rest_parts->next_vpid = vpids[i + 1];
	  copyto = (char *) rest_parts->data;

	  copy_length = DB_PAGESIZE - offsetof (OVERFLOW_REST_PART, data);
	  if (length < copy_length)
	    {
	      copy_length = length;
	    }
	}

      memcpy (copyto, data, copy_length);
      data += copy_length;
      length -= copy_length;

      pgbuf_get_vpid (addr.pgptr, &undo_recv.new_vpid);
      if (file_is_new_file (thread_p, ovf_vfid) == FILE_OLD_FILE)
	{
	  /* we don't do undo logging for new files */
	  log_append_undo_data (thread_p, RVOVF_NEWPAGE_LOGICAL_UNDO,
				&logical_undoaddr, sizeof (undo_recv),
				&undo_recv);
	}

      log_append_redo_data (thread_p, RVOVF_NEWPAGE_INSERT, &addr,
			    copy_length +
			    CAST_BUFLEN (copyto - (char *) addr.pgptr),
			    (char *) addr.pgptr);

      pgbuf_set_dirty (thread_p, addr.pgptr, FREE);
      addr.pgptr = NULL;
    }

  assert (length == 0);
#if defined (CUBRID_DEBUG)
  if (length > 0)
    {
      er_log_debug (ARG_FILE_LINE, "ovf_insert: ** SYSTEM ERROR calculation"
		    " of number of pages needed to store overflow data seems"
		    " incorrect. Need no more than %d pages", npages);
      goto exit_on_error;
    }
#endif

  /*
   * Temporary:
   *   Unlock the file header, so I am the only one changing the file table
   *   of allocated pages. This is needed since curently, I am using
   *   file_find_nthpages, which could give me not the expected page, if someone
   *   else remove pages.
   */

  if (vpids != vpids_buffer)
    {
      free_and_init (vpids);
    }

  pgbuf_unfix (thread_p, vfid_fhdr_pgptr);
  return ovf_vpid;

exit_on_error:

  for (i = 0; i < npages; i++)
    {
      (void) file_dealloc_page (thread_p, ovf_vfid, &vpids[i]);
    }

  if (vpids != vpids_buffer)
    {
      free_and_init (vpids);
    }

  pgbuf_unfix (thread_p, vfid_fhdr_pgptr);
  return NULL;
}
Exemple #15
0
/*
 * logwr_archive_active_log -
 *
 * return:
 * Note:
 */
static int
logwr_archive_active_log (void)
{
  char archive_name[PATH_MAX] = { '\0' }, archive_name_first[PATH_MAX];
  LOG_PAGE *arvhdr_pgptr = NULL;
  struct log_arv_header *arvhdr;
  char log_pgbuf[IO_MAX_PAGE_SIZE * LOGPB_IO_NPAGES + MAX_ALIGNMENT];
  char *aligned_log_pgbuf;
  LOG_PAGE *log_pgptr = NULL;
  LOG_PAGE *malloc_arv_hdr_pgptr = NULL;
  PAGEID pageid, ar_phy_pageid = NULL_PAGEID, phy_pageid = NULL_PAGEID;
  int vdes = NULL_VOLDES;
  int i, first_arv_num_to_delete, last_arv_num_to_delete;
  int error_code;
  int num_pages = 0;
  const char *info_reason, *catmsg;
  BACKGROUND_ARCHIVING_INFO *bg_arv_info;

  aligned_log_pgbuf = PTR_ALIGN (log_pgbuf, MAX_ALIGNMENT);

  if ((logwr_Gl.last_arv_num - logwr_Gl.last_deleted_arv_num)
      > PRM_LOG_MAX_ARCHIVES)
    {
      er_set (ER_WARNING_SEVERITY, ARG_FILE_LINE,
	      ER_LOG_MAX_ARCHIVES_HAS_BEEN_EXCEEDED, 1, PRM_LOG_MAX_ARCHIVES);

      /* Remove the log archives at this point */
      first_arv_num_to_delete = logwr_Gl.last_deleted_arv_num + 1;
      last_arv_num_to_delete = logwr_Gl.last_arv_num - PRM_LOG_MAX_ARCHIVES;
      last_arv_num_to_delete--;
      for (i = first_arv_num_to_delete; i <= last_arv_num_to_delete; i++)
	{
	  fileio_make_log_archive_name (archive_name, logwr_Gl.log_path,
					logwr_Gl.db_name, i);
	  fileio_unformat (NULL, archive_name);
	  logwr_Gl.last_deleted_arv_num = last_arv_num_to_delete;
	}
      info_reason = msgcat_message (MSGCAT_CATALOG_CUBRID,
				    MSGCAT_SET_LOG,
				    MSGCAT_LOG_MAX_ARCHIVES_HAS_BEEN_EXCEEDED);
      if (info_reason == NULL)
	{
	  info_reason = "Number of active log archives has been exceeded"
	    " the max desired number.";
	}
      catmsg = msgcat_message (MSGCAT_CATALOG_CUBRID,
			       MSGCAT_SET_LOG,
			       MSGCAT_LOG_LOGINFO_REMOVE_REASON);
      if (catmsg == NULL)
	{
	  catmsg = "REMOVE: %d %s to \n%d %s.\nREASON: %s\n";
	}
      if (first_arv_num_to_delete == last_arv_num_to_delete)
	{
	  log_dump_log_info (logwr_Gl.loginf_path, false, catmsg,
			     first_arv_num_to_delete, archive_name,
			     last_arv_num_to_delete, archive_name,
			     info_reason);
	}
      else
	{
	  fileio_make_log_archive_name (archive_name_first, logwr_Gl.log_path,
					logwr_Gl.db_name,
					first_arv_num_to_delete);
	  log_dump_log_info (logwr_Gl.loginf_path, false, catmsg,
			     first_arv_num_to_delete, archive_name_first,
			     last_arv_num_to_delete, archive_name,
			     info_reason);
	}
      /* ignore error from log_dump_log_info() */

      /* It will continue.... */
    }

  /* Create the archive header page */
  malloc_arv_hdr_pgptr = (LOG_PAGE *) malloc (LOG_PAGESIZE);
  if (malloc_arv_hdr_pgptr == NULL)
    {
      error_code = ER_OUT_OF_VIRTUAL_MEMORY;
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1,
	      LOG_PAGESIZE);
      goto error;
    }

  malloc_arv_hdr_pgptr->hdr.logical_pageid = LOGPB_HEADER_PAGE_ID;
  malloc_arv_hdr_pgptr->hdr.offset = NULL_OFFSET;

  /* Construct the archive log header */
  arvhdr = (struct log_arv_header *) malloc_arv_hdr_pgptr->area;
  strncpy (arvhdr->magic, CUBRID_MAGIC_LOG_ARCHIVE, CUBRID_MAGIC_MAX_LENGTH);
  arvhdr->db_creation = logwr_Gl.hdr.db_creation;
  arvhdr->next_trid = NULL_TRANID;
  arvhdr->fpageid = logwr_Gl.last_arv_fpageid;
  arvhdr->arv_num = logwr_Gl.last_arv_num;
  arvhdr->npages = logwr_Gl.last_arv_lpageid - arvhdr->fpageid + 1;

  /*
   * Now create the archive and start copying pages
   */

  fileio_make_log_archive_name (archive_name, logwr_Gl.log_path,
				logwr_Gl.db_name, arvhdr->arv_num);
  bg_arv_info = &logwr_Gl.bg_archive_info;
  if (PRM_LOG_BACKGROUND_ARCHIVING && bg_arv_info->vdes != NULL_VOLDES)
    {
      vdes = bg_arv_info->vdes;
    }
  else
    {
      if (fileio_is_volume_exist (archive_name) == true)
	{
	  vdes = fileio_mount (NULL, archive_name, archive_name,
			       LOG_DBLOG_ARCHIVE_VOLID, true, false);
	  if (vdes == NULL_VOLDES)
	    {
	      error_code = ER_IO_MOUNT_FAIL;
	      goto error;
	    }
	}
      else
	{
	  vdes = fileio_format (NULL, logwr_Gl.db_name, archive_name,
				LOG_DBLOG_ARCHIVE_VOLID, arvhdr->npages + 1,
				false, false, false, LOG_PAGESIZE);
	  if (vdes == NULL_VOLDES)
	    {
	      /* Unable to create archive log to archive */
	      error_code = ER_LOG_CREATE_LOGARCHIVE_FAIL;
	      er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE,
		      ER_LOG_CREATE_LOGARCHIVE_FAIL, 3,
		      archive_name, arvhdr->fpageid,
		      arvhdr->fpageid + arvhdr->npages - 1);
	      goto error;
	    }
	}
    }

  if (fileio_write (NULL, vdes, malloc_arv_hdr_pgptr, 0, LOG_PAGESIZE) ==
      NULL)
    {
      /* Error archiving header page into archive */
      error_code = ER_LOG_WRITE;
      er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_WRITE, 3,
	      0, 0, archive_name);
      goto error;
    }

  if (PRM_LOG_BACKGROUND_ARCHIVING
      && bg_arv_info->vdes != NULL_VOLDES
      && logwr_Gl.last_arv_fpageid == bg_arv_info->start_page_id)
    {
      pageid = bg_arv_info->current_page_id;
      ar_phy_pageid = (bg_arv_info->current_page_id
		       - bg_arv_info->start_page_id + 1);
    }
  else
    {
      pageid = logwr_Gl.last_arv_fpageid;
      ar_phy_pageid = 1;
    }

  log_pgptr = (LOG_PAGE *) aligned_log_pgbuf;

  /* Now start dumping the current active pages to archive */
  for (; pageid <= logwr_Gl.last_arv_lpageid;
       pageid += num_pages, ar_phy_pageid += num_pages)
    {
      /*
       * Page is contained in the active log.
       * Find the corresponding physical page and read the page form disk.
       */
      num_pages = MIN (LOGPB_IO_NPAGES,
		       logwr_Gl.last_arv_lpageid - pageid + 1);

      phy_pageid = logwr_to_physical_pageid (pageid);
      num_pages = MIN (num_pages, logwr_Gl.hdr.npages - phy_pageid + 1);

      if (fileio_read_pages (NULL, logwr_Gl.append_vdes, (char *) log_pgptr,
			     phy_pageid, num_pages, LOG_PAGESIZE) == NULL)
	{
	  error_code = ER_LOG_READ;
	  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_READ, 3,
		  pageid, phy_pageid, logwr_Gl.active_name);
	  goto error;
	}
      else
	{
	  if (log_pgptr->hdr.logical_pageid != pageid)
	    {
	      /* Clean the buffer... since it may be corrupted */
	      error_code = ER_LOG_PAGE_CORRUPTED;
	      er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE,
		      ER_LOG_PAGE_CORRUPTED, 1, pageid);
	      goto error;
	    }
	}

      if (fileio_write_pages (NULL, vdes, (char *) log_pgptr,
			      ar_phy_pageid, num_pages, LOG_PAGESIZE) == NULL)
	{
	  error_code = ER_LOG_WRITE;
	  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_WRITE, 3,
		  pageid, ar_phy_pageid, archive_name);
	  goto error;
	}
    }

  fileio_dismount (NULL, vdes);
  vdes = NULL_VOLDES;

  if (PRM_LOG_BACKGROUND_ARCHIVING && bg_arv_info->vdes != NULL_VOLDES)
    {
      bg_arv_info->vdes = NULL_VOLDES;
      if (fileio_rename (NULL_VOLID, logwr_Gl.bg_archive_name, archive_name)
	  == NULL)
	{
	  goto error;
	}
      bg_arv_info->vdes = fileio_format (NULL, logwr_Gl.db_name,
					 logwr_Gl.bg_archive_name,
					 LOG_DBLOG_BG_ARCHIVE_VOLID,
					 logwr_Gl.hdr.npages, false, false,
					 false, LOG_PAGESIZE);
      if (bg_arv_info->vdes != NULL_VOLDES)
	{
	  bg_arv_info->start_page_id = logwr_Gl.hdr.nxarv_pageid;
	  bg_arv_info->current_page_id = logwr_Gl.hdr.nxarv_pageid;
	}
      else
	{
	  bg_arv_info->start_page_id = NULL_PAGEID;
	  bg_arv_info->current_page_id = NULL_PAGEID;
	  er_log_debug (ARG_FILE_LINE,
			"Unable to create temporary archive log %s\n",
			logwr_Gl.bg_archive_name);
	}
    }

  /* Update archive info */
  logwr_Gl.last_arv_num++;
  logwr_Gl.last_arv_fpageid = logwr_Gl.last_arv_lpageid + 1;

  /* Flush the log header to reflect the archive */
  logwr_flush_header_page ();

  er_set (ER_NOTIFICATION_SEVERITY, ARG_FILE_LINE, ER_LOG_ARCHIVE_CREATED, 3,
	  archive_name, arvhdr->fpageid,
	  arvhdr->fpageid + arvhdr->npages - 1);

  catmsg = msgcat_message (MSGCAT_CATALOG_CUBRID,
			   MSGCAT_SET_LOG, MSGCAT_LOG_LOGINFO_ARCHIVE);
  if (catmsg == NULL)
    {
      catmsg = "ARCHIVE: %d %s %d %d\n";
    }
  error_code = log_dump_log_info (logwr_Gl.loginf_path, false, catmsg,
				  arvhdr->arv_num, archive_name,
				  arvhdr->fpageid,
				  arvhdr->fpageid + arvhdr->npages - 1);
  er_log_debug (ARG_FILE_LINE,
		"logwr_archive_active_log, arv_num(%d), fpageid(%d) lpageid(%d)\n",
		arvhdr->arv_num, arvhdr->fpageid,
		arvhdr->fpageid + arvhdr->npages - 1);

  free_and_init (malloc_arv_hdr_pgptr);

  return NO_ERROR;

error:

  if (malloc_arv_hdr_pgptr != NULL)
    {
      free_and_init (malloc_arv_hdr_pgptr);
    }

  if (vdes != NULL_VOLDES)
    {
      fileio_dismount (NULL, vdes);
      fileio_unformat (NULL, archive_name);
    }

  return error_code;
}
Exemple #16
0
/*
 * logwr_flush_all_append_pages -
 *
 * return:
 * Note:
 */
static int
logwr_flush_all_append_pages (void)
{
  LOG_PAGE *pgptr, *prv_pgptr;
  PAGEID pageid, prv_pageid;
  int last_idxflush;
  int idxflush;
  bool need_sync;
  int flush_page_count;
  int i;

  idxflush = -1;
  last_idxflush = -1;
  prv_pgptr = NULL;
  need_sync = false;
  flush_page_count = 0;

  for (i = 0; i < logwr_Gl.num_toflush; i++)
    {
      pgptr = logwr_Gl.toflush[i];

      if (last_idxflush == -1)
	{
	  /* We have found the smallest dirty page */
	  last_idxflush = i;
	  prv_pgptr = pgptr;
	  continue;
	}

      if (idxflush != -1 && prv_pgptr != NULL)
	{
	  /*
	   * This append log page should be dirty and contiguous to previous
	   * append page. If it is not, we need to flush the accumulated pages
	   * up to this point, and then start accumulating pages again.
	   */
	  pageid = pgptr->hdr.logical_pageid;
	  prv_pageid = prv_pgptr->hdr.logical_pageid;

	  if ((pageid != prv_pageid + 1)
	      || (logwr_to_physical_pageid (pageid)
		  != logwr_to_physical_pageid (prv_pageid) + 1))
	    {
	      /*
	       * This page is not contiguous.
	       *
	       * Flush the accumulated contiguous pages
	       */
	      if (logwr_writev_append_pages (&logwr_Gl.toflush[idxflush],
					     i - idxflush) == NULL)
		{
		  return er_errid ();
		}
	      else
		{
		  need_sync = true;

		  /*
		   * Start over the accumulation of pages
		   */

		  flush_page_count += i - idxflush;
		  idxflush = -1;
		}
	    }
	}

      if (idxflush == -1)
	{
	  /*
	   * This page should be included in the flush
	   */
	  idxflush = i;
	}

      /* prv_pgptr was not pgptr's previous buffer.
       * prv_pgptr was the first buffer to flush,
       * so only 2 continous pages always were flushed together.
       */
      prv_pgptr = pgptr;
    }

  /*
   * If there are any accumulated pages, flush them at this point
   */

  if (idxflush != -1)
    {
      int page_toflush = logwr_Gl.num_toflush - idxflush;

      /* last countious pages */
      if (logwr_writev_append_pages (&logwr_Gl.toflush[idxflush],
				     page_toflush) == NULL)
	{
	  return er_errid ();
	}
      else
	{
	  need_sync = true;
	  flush_page_count += page_toflush;
	  pgptr = logwr_Gl.toflush[idxflush + page_toflush - 1];
	}
    }

  /*
   * Make sure that all of the above log writes are synchronized with any
   * future log writes. That is, the pages should be stored on physical disk.
   */
  if (logwr_Gl.mode == LOGWR_MODE_ASYNC)
    {
      need_sync = false;
    }
  if (need_sync == true
      && fileio_synchronize (NULL, logwr_Gl.append_vdes,
			     logwr_Gl.active_name) == NULL_VOLDES)
    {
      return er_errid ();
    }

  assert (last_idxflush != -1);
  if (last_idxflush != -1)
    {
      /*
       * Now flush and sync the first log append dirty page
       */
      ++flush_page_count;

      if (logwr_writev_append_pages (&logwr_Gl.toflush[last_idxflush], 1)
	  == NULL
	  || fileio_synchronize (NULL, logwr_Gl.append_vdes,
				 logwr_Gl.active_name) == NULL_VOLDES)
	{
	  PAGEID pageid = logwr_Gl.toflush[last_idxflush]->hdr.logical_pageid;
	  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE,
		  ER_LOG_WRITE, 3, pageid, logwr_to_physical_pageid (pageid),
		  logwr_Gl.active_name);
	  return ER_LOG_WRITE;
	}
    }

  /* Initialize flush info */
  for (i = 0; i < logwr_Gl.num_toflush; i++)
    {
      logwr_Gl.toflush[i] = NULL;
    }
  logwr_Gl.num_toflush = 0;

  er_log_debug (ARG_FILE_LINE,
		"logwr_write_log_pages, flush_page_count(%d)\n",
		flush_page_count);

  return NO_ERROR;
}
Exemple #17
0
/*
 * logwr_initialize - Initialize logwr_Gl structure
 *
 * return:
 *
 *   db_name(in):
 *   log_path(in):
 *   mode(in):
 *
 * Note:
 */
static int
logwr_initialize (const char *db_name, const char *log_path, int mode)
{
  char prm_buf[LINE_MAX], *prm_val;
  int log_nbuffers;
  int error;
  char *at_char = NULL;

  /* set the db name and log path */
  strncpy (logwr_Gl.db_name, db_name, PATH_MAX - 1);
  if ((at_char = strchr (logwr_Gl.db_name, '@')) != NULL)
    {
      *at_char = '\0';
    }
  strncpy (logwr_Gl.log_path, log_path, PATH_MAX - 1);
  /* set the mode */
  logwr_Gl.mode = mode;

  /* set the active log file path */
  fileio_make_log_active_name (logwr_Gl.active_name, log_path,
			       logwr_Gl.db_name);
  /* set the log info file path */
  fileio_make_log_info_name (logwr_Gl.loginf_path, log_path,
			     logwr_Gl.db_name);
  /* background archive file path */
  fileio_make_log_archive_temp_name (logwr_Gl.bg_archive_name, log_path,
				     logwr_Gl.db_name);


  strncpy (prm_buf, PRM_NAME_LOG_NBUFFERS, LINE_MAX - 1);
  if ((error = db_get_system_parameters (prm_buf, LINE_MAX)) != NO_ERROR)
    {
      return error;
    }
  prm_val = strchr (prm_buf, '=');
  if (prm_val == NULL)
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_PRM_BAD_VALUE, 1, prm_buf);
      return ER_PRM_BAD_VALUE;
    }
  log_nbuffers = atoi (prm_val + 1);
  if (log_nbuffers < 1 || INT_MAX <= log_nbuffers)
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_PRM_BAD_VALUE, 1, prm_buf);
      return ER_PRM_BAD_VALUE;
    }

  if (logwr_Gl.logpg_area == NULL)
    {
      logwr_Gl.logpg_area_size = log_nbuffers * LOG_PAGESIZE;
      logwr_Gl.logpg_area = malloc (logwr_Gl.logpg_area_size);
      if (logwr_Gl.logpg_area == NULL)
	{
	  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY,
		  1, logwr_Gl.logpg_area_size);
	  logwr_Gl.logpg_area_size = 0;
	  return ER_OUT_OF_VIRTUAL_MEMORY;
	}
    }

  if (logwr_Gl.toflush == NULL)
    {
      int i;

      logwr_Gl.max_toflush = log_nbuffers - 1;
      logwr_Gl.toflush = (LOG_PAGE **) calloc (logwr_Gl.max_toflush,
					       sizeof (logwr_Gl.toflush));
      if (logwr_Gl.toflush == NULL)
	{
	  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY,
		  1, logwr_Gl.max_toflush * sizeof (logwr_Gl.toflush));
	  logwr_Gl.max_toflush = 0;
	  return ER_OUT_OF_VIRTUAL_MEMORY;
	}
      for (i = 0; i < logwr_Gl.max_toflush; i++)
	{
	  logwr_Gl.toflush[i] = NULL;
	}
    }

  error = logwr_read_log_header ();
  if (error != NO_ERROR)
    {
      return error;
    }

  logwr_Gl.action = LOGWR_ACTION_NONE;

  logwr_Gl.last_arv_fpageid = logwr_Gl.hdr.nxarv_pageid;
  logwr_Gl.last_arv_num = logwr_Gl.hdr.nxarv_num;
  logwr_Gl.last_deleted_arv_num = logwr_Gl.hdr.last_deleted_arv_num;

  logwr_Gl.force_flush = false;
  logwr_Gl.last_flush_time.tv_sec = 0;
  logwr_Gl.last_flush_time.tv_usec = 0;

  if (PRM_LOG_BACKGROUND_ARCHIVING)
    {
      BACKGROUND_ARCHIVING_INFO *bg_arv_info;
      bg_arv_info = &logwr_Gl.bg_archive_info;

      bg_arv_info->start_page_id = NULL_PAGEID;
      bg_arv_info->current_page_id = NULL_PAGEID;
      bg_arv_info->vdes = fileio_format (NULL, logwr_Gl.db_name,
					 logwr_Gl.bg_archive_name,
					 LOG_DBLOG_BG_ARCHIVE_VOLID,
					 logwr_Gl.hdr.npages + 1,
					 false, false, false, LOG_PAGESIZE);
      if (bg_arv_info->vdes != NULL_VOLDES)
	{
	  bg_arv_info->start_page_id = logwr_Gl.hdr.nxarv_pageid;
	  bg_arv_info->current_page_id = logwr_Gl.hdr.nxarv_pageid;
	}
      else
	{
	  er_log_debug (ARG_FILE_LINE,
			"Unable to create temporary archive log %s\n",
			logwr_Gl.bg_archive_name);
	}
    }

  return NO_ERROR;
}
Exemple #18
0
/*
 * xlogwr_get_log_pages -
 *
 * return:
 *
 *   thread_p(in):
 *   first_pageid(in):
 *   mode(in):
 *
 * Note:
 */
int
xlogwr_get_log_pages (THREAD_ENTRY * thread_p, PAGEID first_pageid, int mode)
{
  LOGWR_ENTRY *entry;
  char *logpg_area;
  int logpg_used_size;
  PAGEID next_fpageid;
  LOGWR_MODE next_mode;
  int status;
  int rv;
  int error_code;
  bool check_cs_own = false;
  LOGWR_INFO *writer_info = &log_Gl.writer_info;

  logpg_used_size = 0;
  logpg_area = db_private_alloc (thread_p, PRM_LOG_NBUFFERS * LOG_PAGESIZE);
  if (logpg_area == NULL)
    {
      error_code = ER_OUT_OF_VIRTUAL_MEMORY;
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1,
	      PRM_LOG_NBUFFERS * LOG_PAGESIZE);
      return ER_OUT_OF_VIRTUAL_MEMORY;
    }

  if (thread_p->conn_entry)
    {
      thread_p->conn_entry->stop_phase = THREAD_WORKER_STOP_PHASE_1;
    }

  while (true)
    {
      er_log_debug (ARG_FILE_LINE,
		    "[tid:%ld] xlogwr_get_log_pages, fpageid(%d), mode(%s)\n",
		    thread_p->tid, first_pageid,
		    (mode == LOGWR_MODE_SYNC ? "sync" :
		     (mode == LOGWR_MODE_ASYNC ? "async" : "semisync")));

      /* Register the writer at the list and wait until LFT start to work */
      LOG_MUTEX_LOCK (rv, writer_info->flush_start_mutex);
      error_code = logwr_register_writer_entry (&entry, thread_p,
						first_pageid, mode);
      if (error_code != NO_ERROR)
	{
	  LOG_MUTEX_UNLOCK (writer_info->flush_start_mutex);
	  status = LOGWR_STATUS_ERROR;
	  goto error;
	}

      if (entry->status == LOGWR_STATUS_WAIT)
	{
	  bool continue_checking = true;

	  thread_suspend_with_other_mutex (thread_p,
					   &writer_info->flush_start_mutex,
					   INF_WAIT, NULL,
					   THREAD_LOGWR_SUSPENDED);

	  LOG_MUTEX_UNLOCK (writer_info->flush_start_mutex);

	  if (logtb_is_interrupted (thread_p, false, &continue_checking)
	      || thread_p->resume_status == THREAD_RESUME_DUE_TO_INTERRUPT)
	    {
	      /* interrupted, shutdown or connection has gone. */
	      error_code = ER_INTERRUPTED;
	      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
	      status = LOGWR_STATUS_ERROR;
	      goto error;
	    }
	  else if (thread_p->resume_status != THREAD_LOGWR_RESUMED)
	    {
	      error_code = ER_FAILED;
	      status = LOGWR_STATUS_ERROR;
	      goto error;
	    }
	}
      else
	{
	  assert (entry->status == LOGWR_STATUS_DELAY);
	  LOG_MUTEX_UNLOCK (writer_info->flush_start_mutex);
	  LOG_CS_ENTER (thread_p);
	  check_cs_own = true;
	}

      /* Send the log pages to be flushed until now */
      error_code = logwr_pack_log_pages (thread_p, logpg_area,
					 &logpg_used_size, &status, entry);
      if (error_code != NO_ERROR)
	{
	  status = LOGWR_STATUS_ERROR;
	  goto error;
	}

      error_code = xlog_send_log_pages_to_client (thread_p, logpg_area,
						  logpg_used_size, mode);
      if (error_code != NO_ERROR)
	{
	  status = LOGWR_STATUS_ERROR;
	  goto error;
	}

      /* In case of async mode, unregister the writer and wakeup LFT to finish */
      /*
         The result mode is the following.

         transition \ req mode |  req_sync   req_async
         -----------------------------------------
         delay -> delay    |  n/a        ASYNC
         delay -> done     |  n/a        SYNC
         wait -> delay     |  SYNC       ASYNC
         wait -> done      |  SYNC       ASYNC
       */

      if (mode == LOGWR_MODE_ASYNC
	  && (entry->status != LOGWR_STATUS_DELAY
	      || (entry->status == LOGWR_STATUS_DELAY
		  && status != LOGWR_STATUS_DONE)))
	{
	  if (check_cs_own)
	    {
	      check_cs_own = false;
	      LOG_CS_EXIT ();
	    }
	  LOG_MUTEX_LOCK (rv, writer_info->flush_end_mutex);
	  if (logwr_unregister_writer_entry (entry, status))
	    {
	      COND_SIGNAL (writer_info->flush_end_cond);
	    }
	  LOG_MUTEX_UNLOCK (writer_info->flush_end_mutex);
	}

      /* Get the next request from the client and reset the arguments */
      error_code = xlog_get_page_request_with_reply (thread_p, &next_fpageid,
						     &next_mode);
      if (error_code != NO_ERROR)
	{
	  status = LOGWR_STATUS_ERROR;
	  goto error;
	}

      /* In case of sync mode, unregister the writer and wakeup LFT to finish */
      if (mode != LOGWR_MODE_ASYNC
	  || (entry->status == LOGWR_STATUS_DELAY
	      && status == LOGWR_STATUS_DONE))
	{
	  if (check_cs_own)
	    {
	      check_cs_own = false;
	      LOG_CS_EXIT ();
	    }
	  LOG_MUTEX_LOCK (rv, writer_info->flush_end_mutex);
	  if (logwr_unregister_writer_entry (entry, status))
	    {
	      COND_SIGNAL (writer_info->flush_end_cond);
	    }
	  LOG_MUTEX_UNLOCK (writer_info->flush_end_mutex);
	}

      /* Reset the arguments for the next request */
      first_pageid = next_fpageid;
      mode = next_mode;
    }

  db_private_free_and_init (thread_p, logpg_area);

  return NO_ERROR;

error:

  er_log_debug (ARG_FILE_LINE,
		"[tid:%ld] xlogwr_get_log_pages, error(%d)\n",
		thread_p->tid, error_code);
  if (check_cs_own)
    {
      LOG_CS_EXIT ();
    }
  LOG_MUTEX_LOCK (rv, writer_info->flush_end_mutex);
  if (entry != NULL && logwr_unregister_writer_entry (entry, status))
    {
      COND_SIGNAL (writer_info->flush_end_cond);
    }
  LOG_MUTEX_UNLOCK (writer_info->flush_end_mutex);

  db_private_free_and_init (thread_p, logpg_area);

  return error_code;
}
Exemple #19
0
/*
 * logwr_pack_log_pages -
 *
 * return:
 *
 *   thread_p(in):
 *   logpg_area(in):
 *   logpg_used_size(out):
 *   status(out): LOGWR_STATUS_DONE, LOGWR_STATUS_DELAY or LOGWR_STATUS_ERROR
 *   entry(in):
 *
 * Note:
 */
static int
logwr_pack_log_pages (THREAD_ENTRY * thread_p,
		      char *logpg_area, int *logpg_used_size,
		      int *status, LOGWR_ENTRY * entry)
{
  PAGEID fpageid, lpageid, pageid;
  char *p;
  LOG_PAGE *log_pgptr;
  int num_logpgs;
  bool is_hdr_page_only;
  int ha_file_status;
  int error_code;

  fpageid = NULL_PAGEID;
  lpageid = NULL_PAGEID;
  ha_file_status = LOG_HA_FILESTAT_CLEAR;

  is_hdr_page_only = (entry->fpageid == LOGPB_HEADER_PAGE_ID);

  if (!is_hdr_page_only)
    {
      /* Find the first pageid to be packed */
      fpageid = entry->fpageid;
      if (fpageid == NULL_PAGEID)
	{
	  /* In case of first request from the log writer,
	     pack all active pages to be flushed until now */
	  fpageid = log_Gl.hdr.nxarv_pageid;
	}
      else if (fpageid > log_Gl.append.nxio_lsa.pageid)
	{
	  fpageid = log_Gl.append.nxio_lsa.pageid;
	}

      /* Find the last pageid which is bounded by several limitations */
      if (!logpb_is_page_in_archive (fpageid))
	{
	  lpageid = log_Gl.hdr.eof_lsa.pageid;
	}
      else
	{
	  struct log_arv_header arvhdr;

	  /* If the fpageid is in archive log,
	     fetch the page and the header page in the archive */
	  if (logpb_fetch_from_archive (thread_p, fpageid, NULL, NULL,
					&arvhdr) == NULL)
	    {
	      error_code = ER_FAILED;
	      goto error;
	    }
	  /* Reset the lpageid with the last pageid in the archive */
	  lpageid = arvhdr.fpageid + arvhdr.npages - 1;
	  if (fpageid == arvhdr.fpageid)
	    {
	      ha_file_status = LOG_HA_FILESTAT_ARCHIVED;
	    }
	}
      /* Pack the pages which can be in the page area of Log Writer */
      if ((lpageid - fpageid + 1) > (PRM_LOG_NBUFFERS - 1))
	{
	  lpageid = fpageid + (PRM_LOG_NBUFFERS - 1) - 1;
	}
      if (lpageid == log_Gl.hdr.eof_lsa.pageid)
	{
	  ha_file_status = LOG_HA_FILESTAT_SYNCHRONIZED;
	}
    }

  /* Set the server status on the header information */
  log_Gl.hdr.ha_server_state = css_ha_server_state ();
  log_Gl.hdr.ha_file_status = ha_file_status;

  /* Allocate the log page area */
  num_logpgs = (is_hdr_page_only) ? 1 : (lpageid - fpageid + 1) + 1;

  assert (lpageid >= fpageid);
  assert (num_logpgs <= PRM_LOG_NBUFFERS);

  p = logpg_area;

  /* Fill the header page */
  log_pgptr = (LOG_PAGE *) p;
  log_pgptr->hdr = log_Gl.loghdr_pgptr->hdr;
  memcpy (log_pgptr->area, &log_Gl.hdr, sizeof (log_Gl.hdr));
  p += LOG_PAGESIZE;

  /* Fill the page array with the pages to send */
  if (!is_hdr_page_only)
    {
      for (pageid = fpageid; pageid >= 0 && pageid <= lpageid; pageid++)
	{
	  log_pgptr = (LOG_PAGE *) p;
	  if (logpb_fetch_page (thread_p, pageid, log_pgptr) == NULL)
	    {
	      error_code = ER_FAILED;
	      goto error;
	    }
	  assert (pageid == (log_pgptr->hdr.logical_pageid));
	  p += LOG_PAGESIZE;
	}
    }

  *logpg_used_size = (int) (p - logpg_area);

  /* In case that EOL exists at lpageid */
  if (!is_hdr_page_only && (lpageid >= log_Gl.hdr.eof_lsa.pageid))
    {
      *status = LOGWR_STATUS_DONE;
    }
  else
    {
      *status = LOGWR_STATUS_DELAY;
    }

  er_log_debug (ARG_FILE_LINE,
		"logwr_pack_log_pages, fpageid(%d), lpageid(%d), num_pages(%d),"
		"\n status(%d), delayed_free_log_pgptr(%p)\n",
		fpageid, lpageid, num_logpgs, entry->status,
		log_Gl.append.delayed_free_log_pgptr);

  return NO_ERROR;

error:

  *logpg_used_size = 0;
  *status = LOGWR_STATUS_ERROR;

  return error_code;
}
Exemple #20
0
/*
 * logwr_background_archiving -
 *
 * return:
 *
 * NOTE:
 */
static int
logwr_background_archiving (void)
{
  char log_pgbuf[IO_MAX_PAGE_SIZE * LOGPB_IO_NPAGES + MAX_ALIGNMENT];
  char *aligned_log_pgbuf;
  LOG_PAGE *log_pgptr;
  PAGEID page_id, phy_pageid, last_page_id, bg_phy_pageid;
  int num_pages = 0, vdes;
  int error_code = NO_ERROR;
  BACKGROUND_ARCHIVING_INFO *bg_arv_info;

  assert (PRM_LOG_BACKGROUND_ARCHIVING);

  aligned_log_pgbuf = PTR_ALIGN (log_pgbuf, MAX_ALIGNMENT);
  log_pgptr = (LOG_PAGE *) aligned_log_pgbuf;

  bg_arv_info = &logwr_Gl.bg_archive_info;
  vdes = bg_arv_info->vdes;
  if (vdes == NULL_VOLDES)
    {
      return NO_ERROR;
    }

  last_page_id = logwr_Gl.hdr.chkpt_lsa.pageid - 1;
  page_id = bg_arv_info->current_page_id;
  bg_phy_pageid = page_id - bg_arv_info->start_page_id + 1;

  assert (last_page_id <= logwr_Gl.last_recv_pageid);

  /* Now start dumping the current active pages to archive */
  for (; page_id <= last_page_id;
       page_id += num_pages, bg_phy_pageid += num_pages)
    {
      phy_pageid = logwr_to_physical_pageid (page_id);

      num_pages = MIN (LOGPB_IO_NPAGES, last_page_id - page_id + 1);

      if (fileio_read_pages (NULL, logwr_Gl.append_vdes, (char *) log_pgptr,
			     phy_pageid, num_pages, LOG_PAGESIZE) == NULL)
	{
	  error_code = er_errid ();
	  goto error;
	}

      if (fileio_write_pages (NULL, vdes, (char *) log_pgptr,
			      bg_phy_pageid, num_pages, LOG_PAGESIZE) == NULL)
	{
	  error_code = ER_LOG_WRITE;
	  goto error;
	}

      bg_arv_info->current_page_id = page_id + num_pages;
    }

error:
  if (error_code == ER_LOG_WRITE || error_code == ER_LOG_READ)
    {
      fileio_dismount (NULL, bg_arv_info->vdes);
      bg_arv_info->vdes = NULL_VOLDES;
      bg_arv_info->start_page_id = NULL_PAGEID;
      bg_arv_info->current_page_id = NULL_PAGEID;

      er_log_debug (ARG_FILE_LINE,
		    "background archiving error, hdr->start_page_id = %d, "
		    "hdr->current_page_id = %d, error:%d\n",
		    bg_arv_info->start_page_id,
		    bg_arv_info->current_page_id, error_code);
    }

  er_log_debug (ARG_FILE_LINE,
		"logwr_background_archiving end, hdr->start_page_id = %d, "
		"hdr->current_page_id = %d\n",
		bg_arv_info->start_page_id, bg_arv_info->current_page_id);

  return error_code;
}