/* * 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; }
/* * 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; }
/* * 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; }
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; }
/* * 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"); }
/* * 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); }
/* * 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); }
/* * 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; }
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); }
/* * 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); }
/* * 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; } }
/* * 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); }
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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }