byte* row_upd_parse_sys_vals( /*===================*/ /* out: log data end or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ ulint* pos, /* out: TRX_ID position in record */ dulint* trx_id, /* out: trx id */ dulint* roll_ptr)/* out: roll ptr */ { ptr = mach_parse_compressed(ptr, end_ptr, pos); if (ptr == NULL) { return(NULL); } if (end_ptr < ptr + DATA_ROLL_PTR_LEN) { return(NULL); } *roll_ptr = trx_read_roll_ptr(ptr); ptr += DATA_ROLL_PTR_LEN; ptr = mach_dulint_parse_compressed(ptr, end_ptr, trx_id); return(ptr); }
byte* mlog_parse_initial_log_record( /*==========================*/ /* out: parsed record end, NULL if not a complete record */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ byte* type, /* out: log record type: MLOG_1BYTE, ... */ ulint* space, /* out: space id */ ulint* page_no)/* out: page number */ { if (end_ptr < ptr + 1) { return(NULL); } *type = (byte)((ulint)*ptr & ~MLOG_SINGLE_REC_FLAG); ut_ad(*type <= MLOG_BIGGEST_TYPE); ptr++; if (end_ptr < ptr + 2) { return(NULL); } ptr = mach_parse_compressed(ptr, end_ptr, space); if (ptr == NULL) { return(NULL); } ptr = mach_parse_compressed(ptr, end_ptr, page_no); return(ptr); }
byte* trx_undo_parse_page_init( /*======================*/ /* out: end of log record or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ page_t* page, /* in: page or NULL */ mtr_t* mtr) /* in: mtr or NULL */ { ulint type; ptr = mach_parse_compressed(ptr, end_ptr, &type); if (ptr == NULL) { return(NULL); } if (page) { trx_undo_page_init(page, type, mtr); } return(ptr); }
/********************************************************//** Parses a log record written by mlog_write_ulint or mlog_write_dulint. @return parsed record end, NULL if not a complete record or a corrupt record */ UNIV_INTERN byte* mlog_parse_nbytes( /*==============*/ ulint type, /*!< in: log record type: MLOG_1BYTE, ... */ byte* ptr, /*!< in: buffer */ byte* end_ptr,/*!< in: buffer end */ byte* page, /*!< in: page where to apply the log record, or NULL */ void* page_zip)/*!< in/out: compressed page, or NULL */ { ulint offset; ulint val; dulint dval; ut_a(type <= MLOG_8BYTES); ut_a(!page || !page_zip || fil_page_get_type(page) != FIL_PAGE_INDEX); if (end_ptr < ptr + 2) { return(NULL); } offset = mach_read_from_2(ptr); ptr += 2; if (offset >= UNIV_PAGE_SIZE) { recv_sys->found_corrupt_log = TRUE; return(NULL); } if (type == MLOG_8BYTES) { ptr = mach_dulint_parse_compressed(ptr, end_ptr, &dval); if (ptr == NULL) { return(NULL); } if (page) { if (UNIV_LIKELY_NULL(page_zip)) { mach_write_to_8 (((page_zip_des_t*) page_zip)->data + offset, dval); } mach_write_to_8(page + offset, dval); } return(ptr); } ptr = mach_parse_compressed(ptr, end_ptr, &val); if (ptr == NULL) { return(NULL); } switch (type) { case MLOG_1BYTE: if (UNIV_UNLIKELY(val > 0xFFUL)) { goto corrupt; } if (page) { if (UNIV_LIKELY_NULL(page_zip)) { mach_write_to_1 (((page_zip_des_t*) page_zip)->data + offset, val); } mach_write_to_1(page + offset, val); } break; case MLOG_2BYTES: if (UNIV_UNLIKELY(val > 0xFFFFUL)) { goto corrupt; } if (page) { if (UNIV_LIKELY_NULL(page_zip)) { mach_write_to_2 (((page_zip_des_t*) page_zip)->data + offset, val); } mach_write_to_2(page + offset, val); } break; case MLOG_4BYTES: if (page) { if (UNIV_LIKELY_NULL(page_zip)) { mach_write_to_4 (((page_zip_des_t*) page_zip)->data + offset, val); } mach_write_to_4(page + offset, val); } break; default: corrupt: recv_sys->found_corrupt_log = TRUE; ptr = NULL; } return(ptr); }
byte* row_upd_index_parse( /*================*/ /* out: log data end or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ mem_heap_t* heap, /* in: memory heap where update vector is built */ upd_t** update_out)/* out: update vector */ { upd_t* update; upd_field_t* upd_field; dfield_t* new_val; ulint len; ulint n_fields; byte* buf; ulint info_bits; ulint i; if (end_ptr < ptr + 1) { return(NULL); } info_bits = mach_read_from_1(ptr); ptr++; ptr = mach_parse_compressed(ptr, end_ptr, &n_fields); if (ptr == NULL) { return(NULL); } update = upd_create(n_fields, heap); update->info_bits = info_bits; for (i = 0; i < n_fields; i++) { upd_field = upd_get_nth_field(update, i); new_val = &(upd_field->new_val); ptr = mach_parse_compressed(ptr, end_ptr, &(upd_field->field_no)); if (ptr == NULL) { return(NULL); } ptr = mach_parse_compressed(ptr, end_ptr, &len); if (ptr == NULL) { return(NULL); } new_val->len = len; if (len != UNIV_SQL_NULL) { if (end_ptr < ptr + len) { return(NULL); } else { buf = mem_heap_alloc(heap, len); ut_memcpy(buf, ptr, len); ptr += len; new_val->data = buf; } } } *update_out = update; return(ptr); }
byte* mlog_parse_nbytes( /*==============*/ /* out: parsed record end, NULL if not a complete record or a corrupt record */ ulint type, /* in: log record type: MLOG_1BYTE, ... */ byte* ptr, /* in: buffer */ byte* end_ptr,/* in: buffer end */ byte* page) /* in: page where to apply the log record, or NULL */ { ulint offset; ulint val; dulint dval; ut_a(type <= MLOG_8BYTES); if (end_ptr < ptr + 2) { return(NULL); } offset = mach_read_from_2(ptr); ptr += 2; if (offset >= UNIV_PAGE_SIZE) { recv_sys->found_corrupt_log = TRUE; return(NULL); } if (type == MLOG_8BYTES) { ptr = mach_dulint_parse_compressed(ptr, end_ptr, &dval); if (ptr == NULL) { return(NULL); } if (page) { mach_write_to_8(page + offset, dval); } return(ptr); } ptr = mach_parse_compressed(ptr, end_ptr, &val); if (ptr == NULL) { return(NULL); } if (type == MLOG_1BYTE) { if (val > 0xFFUL) { recv_sys->found_corrupt_log = TRUE; return(NULL); } } else if (type == MLOG_2BYTES) { if (val > 0xFFFFUL) { recv_sys->found_corrupt_log = TRUE; return(NULL); } } else { if (type != MLOG_4BYTES) { recv_sys->found_corrupt_log = TRUE; return(NULL); } } if (page) { if (type == MLOG_1BYTE) { mach_write_to_1(page + offset, val); } else if (type == MLOG_2BYTES) { mach_write_to_2(page + offset, val); } else { ut_a(type == MLOG_4BYTES); mach_write_to_4(page + offset, val); } } return(ptr); }