/********************************************************//** Writes the initial part of a log record consisting of one-byte item type and four-byte space and page numbers. Also pushes info to the mtr memo that a buffer page has been modified. */ UNIV_INTERN void mlog_write_initial_log_record( /*==========================*/ const byte* ptr, /*!< in: pointer to (inside) a buffer frame holding the file page where modification is made */ byte type, /*!< in: log item type: MLOG_1BYTE, ... */ mtr_t* mtr) /*!< in: mini-transaction handle */ { byte* log_ptr; ut_ad(type <= MLOG_BIGGEST_TYPE); ut_ad(type > MLOG_8BYTES); log_ptr = mlog_open(mtr, 11); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { return; } log_ptr = mlog_write_initial_log_record_fast(ptr, type, log_ptr, mtr); mlog_close(mtr, log_ptr); }
/********************************************************//** Logs a write of a string to a file page buffered in the buffer pool. Writes the corresponding log record to the mini-transaction log. */ UNIV_INTERN void mlog_log_string( /*============*/ byte* ptr, /*!< in: pointer written to */ ulint len, /*!< in: string length */ mtr_t* mtr) /*!< in: mini-transaction handle */ { byte* log_ptr; ut_ad(ptr && mtr); ut_ad(len <= UNIV_PAGE_SIZE); log_ptr = mlog_open(mtr, 30); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { return; } log_ptr = mlog_write_initial_log_record_fast(ptr, MLOG_WRITE_STRING, log_ptr, mtr); mach_write_to_2(log_ptr, page_offset(ptr)); log_ptr += 2; mach_write_to_2(log_ptr, len); log_ptr += 2; mlog_close(mtr, log_ptr); mlog_catenate_string(mtr, ptr, len); }
void mlog_write_initial_log_record( /*==========================*/ byte* ptr, /* in: pointer to (inside) a buffer frame holding the file page where modification is made */ byte type, /* in: log item type: MLOG_1BYTE, ... */ mtr_t* mtr) /* in: mini-transaction handle */ { byte* log_ptr; ut_ad(type <= MLOG_BIGGEST_TYPE); ut_ad(type > MLOG_8BYTES); if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) { fprintf(stderr, "InnoDB: Error: trying to write to a stray memory location %p\n", ptr); ut_error; } log_ptr = mlog_open(mtr, 11); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { return; } log_ptr = mlog_write_initial_log_record_fast(ptr, type, log_ptr, mtr); mlog_close(mtr, log_ptr); }
/********************************************************//** Writes 8 bytes to a file page buffered in the buffer pool. Writes the corresponding log record to the mini-transaction log. */ UNIV_INTERN void mlog_write_dulint( /*==============*/ byte* ptr, /*!< in: pointer where to write */ dulint val, /*!< in: value to write */ mtr_t* mtr) /*!< in: mini-transaction handle */ { byte* log_ptr; ut_ad(ptr && mtr); mach_write_to_8(ptr, val); log_ptr = mlog_open(mtr, 11 + 2 + 9); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { return; } log_ptr = mlog_write_initial_log_record_fast(ptr, MLOG_8BYTES, log_ptr, mtr); mach_write_to_2(log_ptr, page_offset(ptr)); log_ptr += 2; log_ptr += mach_dulint_write_compressed(log_ptr, val); mlog_close(mtr, log_ptr); }
/**********************************************************************//** Writes the mtr log entry of the inserted undo log record on the undo log page. */ UNIV_INLINE void trx_undof_page_add_undo_rec_log( /*============================*/ page_t* undo_page, /*!< in: undo log page */ ulint old_free, /*!< in: start offset of the inserted entry */ ulint new_free, /*!< in: end offset of the entry */ mtr_t* mtr) /*!< in: mtr */ { byte* log_ptr; const byte* log_end; ulint len; log_ptr = mlog_open(mtr, 11 + 13 + MLOG_BUF_MARGIN); if (log_ptr == NULL) { return; } log_end = &log_ptr[11 + 13 + MLOG_BUF_MARGIN]; log_ptr = mlog_write_initial_log_record_fast( undo_page, MLOG_UNDO_INSERT, log_ptr, mtr); len = new_free - old_free - 4; mach_write_to_2(log_ptr, len); log_ptr += 2; if (log_ptr + len <= log_end) { memcpy(log_ptr, undo_page + old_free + 2, len); mlog_close(mtr, log_ptr + len); } else { mlog_close(mtr, log_ptr); mlog_catenate_string(mtr, undo_page + old_free + 2, len); } }
void mlog_write_ulint( /*=============*/ byte* ptr, /* in: pointer where to write */ ulint val, /* in: value to write */ byte type, /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */ mtr_t* mtr) /* in: mini-transaction handle */ { byte* log_ptr; if (ptr < buf_pool->frame_zero || ptr >= buf_pool->high_end) { fprintf(stderr, "InnoDB: Error: trying to write to" " a stray memory location %p\n", (void*) ptr); ut_error; } if (type == MLOG_1BYTE) { mach_write_to_1(ptr, val); } else if (type == MLOG_2BYTES) { mach_write_to_2(ptr, val); } else { ut_ad(type == MLOG_4BYTES); mach_write_to_4(ptr, val); } log_ptr = mlog_open(mtr, 11 + 2 + 5); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { return; } log_ptr = mlog_write_initial_log_record_fast(ptr, type, log_ptr, mtr); mach_write_to_2(log_ptr, ptr - buf_frame_align(ptr)); log_ptr += 2; log_ptr += mach_write_compressed(log_ptr, val); mlog_close(mtr, log_ptr); }
/********************************************************//** Writes 1 - 4 bytes to a file page buffered in the buffer pool. Writes the corresponding log record to the mini-transaction log. */ UNIV_INTERN void mlog_write_ulint( /*=============*/ byte* ptr, /*!< in: pointer where to write */ ulint val, /*!< in: value to write */ byte type, /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */ mtr_t* mtr) /*!< in: mini-transaction handle */ { byte* log_ptr; switch (type) { case MLOG_1BYTE: mach_write_to_1(ptr, val); break; case MLOG_2BYTES: mach_write_to_2(ptr, val); break; case MLOG_4BYTES: mach_write_to_4(ptr, val); break; default: ut_error; } log_ptr = mlog_open(mtr, 11 + 2 + 5); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { return; } log_ptr = mlog_write_initial_log_record_fast(ptr, type, log_ptr, mtr); mach_write_to_2(log_ptr, page_offset(ptr)); log_ptr += 2; log_ptr += mach_write_compressed(log_ptr, val); mlog_close(mtr, log_ptr); }
void mlog_write_string( /*==============*/ byte* ptr, /* in: pointer where to write */ const byte* str, /* in: string to write */ ulint len, /* in: string length */ mtr_t* mtr) /* in: mini-transaction handle */ { byte* log_ptr; if (UNIV_UNLIKELY(ptr < buf_pool->frame_zero) || UNIV_UNLIKELY(ptr >= buf_pool->high_end)) { fprintf(stderr, "InnoDB: Error: trying to write to" " a stray memory location %p\n", (void*) ptr); ut_error; } ut_ad(ptr && mtr); ut_a(len < UNIV_PAGE_SIZE); ut_memcpy(ptr, str, len); log_ptr = mlog_open(mtr, 30); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { return; } log_ptr = mlog_write_initial_log_record_fast(ptr, MLOG_WRITE_STRING, log_ptr, mtr); mach_write_to_2(log_ptr, ptr - buf_frame_align(ptr)); log_ptr += 2; mach_write_to_2(log_ptr, len); log_ptr += 2; mlog_close(mtr, log_ptr); mlog_catenate_string(mtr, str, len); }
void mlog_write_dulint( /*==============*/ byte* ptr, /* in: pointer where to write */ dulint val, /* in: value to write */ mtr_t* mtr) /* in: mini-transaction handle */ { byte* log_ptr; if (UNIV_UNLIKELY(ptr < buf_pool->frame_zero) || UNIV_UNLIKELY(ptr >= buf_pool->high_end)) { fprintf(stderr, "InnoDB: Error: trying to write to" " a stray memory location %p\n", (void*) ptr); ut_error; } ut_ad(ptr && mtr); mach_write_to_8(ptr, val); log_ptr = mlog_open(mtr, 11 + 2 + 9); /* If no logging is requested, we may return now */ if (log_ptr == NULL) { return; } log_ptr = mlog_write_initial_log_record_fast(ptr, MLOG_8BYTES, log_ptr, mtr); mach_write_to_2(log_ptr, ptr - buf_frame_align(ptr)); log_ptr += 2; log_ptr += mach_dulint_write_compressed(log_ptr, val); mlog_close(mtr, log_ptr); }
/* name : exit_func */ void exit_func ( int signo ) { if ( signo ) mlogf( 0, "\n[%s] Got signo %d. Bye.\n\n", g_par.progname, signo ); /* export flows */ (void)export_ipflows( &g_probe, time(NULL), 1 ); /** clean up */ mlogf( 1, "[%s] clean up.\n", g_par.progname ); mpoll_fdrm( g_probe.fd ); if ( g_par.filter ) { free( g_par.filter ); #ifdef HAVE_PCAP_FREECODE pcap_freecode( &(g_probe.fprg) ); #endif } pcap_close( g_probe.pcap ); ipfix_delete_template( g_probe.ipfix, g_probe.templ ); ipfix_delete_template( g_probe.ipfix, g_probe.templ6 ); ipfix_close( g_probe.ipfix ); ipfix_cleanup(); if ( g_probe.device ) free( g_probe.device ); if ( export_tid ) mpoll_timerrm( export_tid ); flow_close( g_probe.ipflows ); mlog_close(); exit(0); }
void exit_func ( int retval ) { int i; if ( par.tcp && tcp_s ) { for( i=0; i<ntcp_s; i++ ) { ipfix_col_close( tcp_s[i] ); } free( tcp_s ); } if ( par.udp && udp_s ) { for( i=0; i<nudp_s; i++ ) { ipfix_col_close( udp_s[i] ); } free( udp_s ); } if ( par.sctp && sctp_s ) { for( i=0; i<nsctp_s; i++ ) { ipfix_col_close( sctp_s[i] ); } free( sctp_s ); } if ( par.ssl && scol ) { ipfix_col_close_ssl( scol ); } if ( par.datadir || par.datafile) ipfix_col_stop_fileexport(); #ifdef DBSUPPORT if ( par.dbexport ) ipfix_col_stop_mysqlexport(); #endif (void) ipfix_col_stop_msglog(); ipfix_col_cleanup(); ipfix_cleanup(); mlog_close(); exit( retval ); }
/********************************************************//** Opens a buffer for mlog, writes the initial log record and, if needed, the field lengths of an index. @return buffer, NULL if log mode MTR_LOG_NONE */ UNIV_INTERN byte* mlog_open_and_write_index( /*======================*/ mtr_t* mtr, /*!< in: mtr */ const byte* rec, /*!< in: index record or page */ dict_index_t* index, /*!< in: record descriptor */ byte type, /*!< in: log item type */ ulint size) /*!< in: requested buffer size in bytes (if 0, calls mlog_close() and returns NULL) */ { byte* log_ptr; const byte* log_start; const byte* log_end; ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); if (!page_rec_is_comp(rec)) { log_start = log_ptr = mlog_open(mtr, 11 + size); if (!log_ptr) { return(NULL); /* logging is disabled */ } log_ptr = mlog_write_initial_log_record_fast(rec, type, log_ptr, mtr); log_end = log_ptr + 11 + size; } else { ulint i; ulint n = dict_index_get_n_fields(index); /* total size needed */ ulint total = 11 + size + (n + 2) * 2; ulint alloc = total; /* allocate at most DYN_ARRAY_DATA_SIZE at a time */ if (alloc > DYN_ARRAY_DATA_SIZE) { alloc = DYN_ARRAY_DATA_SIZE; } log_start = log_ptr = mlog_open(mtr, alloc); if (!log_ptr) { return(NULL); /* logging is disabled */ } log_end = log_ptr + alloc; log_ptr = mlog_write_initial_log_record_fast(rec, type, log_ptr, mtr); mach_write_to_2(log_ptr, n); log_ptr += 2; mach_write_to_2(log_ptr, dict_index_get_n_unique_in_tree(index)); log_ptr += 2; for (i = 0; i < n; i++) { dict_field_t* field; const dict_col_t* col; ulint len; field = dict_index_get_nth_field(index, i); col = dict_field_get_col(field); len = field->fixed_len; ut_ad(len < 0x7fff); if (len == 0 && (col->len > 255 || col->mtype == DATA_BLOB)) { /* variable-length field with maximum length > 255 */ len = 0x7fff; } if (col->prtype & DATA_NOT_NULL) { len |= 0x8000; } if (log_ptr + 2 > log_end) { mlog_close(mtr, log_ptr); ut_a(total > (ulint) (log_ptr - log_start)); total -= log_ptr - log_start; alloc = total; if (alloc > DYN_ARRAY_DATA_SIZE) { alloc = DYN_ARRAY_DATA_SIZE; } log_start = log_ptr = mlog_open(mtr, alloc); if (!log_ptr) { return(NULL); /* logging is disabled */ } log_end = log_ptr + alloc; } mach_write_to_2(log_ptr, len); log_ptr += 2; } } if (size == 0) { mlog_close(mtr, log_ptr); log_ptr = NULL; } else if (log_ptr + size > log_end) { mlog_close(mtr, log_ptr); log_ptr = mlog_open(mtr, size); } return(log_ptr); }
void row_upd_index_write_log( /*====================*/ upd_t* update, /* in: update vector */ byte* log_ptr,/* in: pointer to mlog buffer: must contain at least MLOG_BUF_MARGIN bytes of free space; the buffer is closed within this function */ mtr_t* mtr) /* in: mtr into whose log to write */ { upd_field_t* upd_field; dfield_t* new_val; ulint len; ulint n_fields; byte* buf_end; ulint i; n_fields = upd_get_n_fields(update); buf_end = log_ptr + MLOG_BUF_MARGIN; mach_write_to_1(log_ptr, update->info_bits); log_ptr++; log_ptr += mach_write_compressed(log_ptr, n_fields); for (i = 0; i < n_fields; i++) { ut_ad(MLOG_BUF_MARGIN > 30); if (log_ptr + 30 > buf_end) { mlog_close(mtr, log_ptr); log_ptr = mlog_open(mtr, MLOG_BUF_MARGIN); buf_end = log_ptr + MLOG_BUF_MARGIN; } upd_field = upd_get_nth_field(update, i); new_val = &(upd_field->new_val); len = new_val->len; log_ptr += mach_write_compressed(log_ptr, upd_field->field_no); log_ptr += mach_write_compressed(log_ptr, len); if (len != UNIV_SQL_NULL) { if (log_ptr + len < buf_end) { ut_memcpy(log_ptr, new_val->data, len); log_ptr += len; } else { mlog_close(mtr, log_ptr); mlog_catenate_string(mtr, new_val->data, len); log_ptr = mlog_open(mtr, MLOG_BUF_MARGIN); buf_end = log_ptr + MLOG_BUF_MARGIN; } } } mlog_close(mtr, log_ptr); }
/********************************************************//** Opens a buffer for mlog, writes the initial log record and, if needed, the field lengths of an index. @return buffer, NULL if log mode MTR_LOG_NONE */ UNIV_INTERN byte* mlog_open_and_write_index( /*======================*/ mtr_t* mtr, /*!< in: mtr */ const byte* rec, /*!< in: index record or page */ dict_index_t* index, /*!< in: record descriptor */ byte type, /*!< in: log item type */ ulint size) /*!< in: requested buffer size in bytes (if 0, calls mlog_close() and returns NULL) */ { byte* log_ptr; const byte* log_start; const byte* log_end; ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); if (!page_rec_is_comp(rec)) { log_start = log_ptr = mlog_open(mtr, 11 + size); if (!log_ptr) { return(NULL); /* logging is disabled */ } log_ptr = mlog_write_initial_log_record_fast(rec, type, log_ptr, mtr); log_end = log_ptr + 11 + size; } else { ulint i; ulint n = dict_index_get_n_fields(index); ibool is_gcs_cluster = dict_index_is_gcs_clust_after_alter_table(index); /* total size needed */ /* redo日志有可能需要多两字节,total需要根据实际情况分配空间! */ ulint total = 11 + size + (n + 2 + (is_gcs_cluster ? 1 : 0)) * 2; ulint alloc = total; /* allocate at most DYN_ARRAY_DATA_SIZE at a time */ if (alloc > DYN_ARRAY_DATA_SIZE) { alloc = DYN_ARRAY_DATA_SIZE; } log_start = log_ptr = mlog_open(mtr, alloc); if (!log_ptr) { return(NULL); /* logging is disabled */ } log_end = log_ptr + alloc; log_ptr = mlog_write_initial_log_record_fast(rec, type, log_ptr, mtr); /* 在第一次alter table前,所有gcs表可以当成compact表,即使是redo过程,这样redo log也兼容! */ if (is_gcs_cluster) { //ut_ad(rec_is_gcs(rec) || rec == page_align(rec) || rec_get_status(rec) & REC_STATUS_NODE_PTR); /* rec有可能就是页头,如日志MLOG_COMP_LIST_END_COPY_CREATED */ mach_write_to_2(log_ptr, n | 0x8000); /* 标记是gcs表 */ } else { ut_ad(rec == page_align(rec) || !rec_is_gcs(rec)); mach_write_to_2(log_ptr, n); } /* 对于gcs聚集索引,记录第一次alter table前聚集索引的字段数 */ if (is_gcs_cluster) { log_ptr += 2; mach_write_to_2(log_ptr, (ulint)index->n_fields_before_alter); ut_ad(!index->n_fields_before_alter == !dict_index_is_gcs_clust_after_alter_table(index)); } log_ptr += 2; mach_write_to_2(log_ptr, dict_index_get_n_unique_in_tree(index)); log_ptr += 2; for (i = 0; i < n; i++) { dict_field_t* field; const dict_col_t* col; ulint len; field = dict_index_get_nth_field(index, i); col = dict_field_get_col(field); len = field->fixed_len; ut_ad(len < 0x7fff); if (len == 0 && (col->len > 255 || col->mtype == DATA_BLOB)) { /* variable-length field with maximum length > 255 */ len = 0x7fff; } if (col->prtype & DATA_NOT_NULL) { len |= 0x8000; } if (log_ptr + 2 > log_end) { mlog_close(mtr, log_ptr); ut_a(total > (ulint) (log_ptr - log_start)); total -= log_ptr - log_start; alloc = total; if (alloc > DYN_ARRAY_DATA_SIZE) { alloc = DYN_ARRAY_DATA_SIZE; } log_start = log_ptr = mlog_open(mtr, alloc); if (!log_ptr) { return(NULL); /* logging is disabled */ } log_end = log_ptr + alloc; } mach_write_to_2(log_ptr, len); log_ptr += 2; } } if (size == 0) { mlog_close(mtr, log_ptr); log_ptr = NULL; } else if (log_ptr + size > log_end) { mlog_close(mtr, log_ptr); log_ptr = mlog_open(mtr, size); } return(log_ptr); }