36 #ifndef UNIV_HOTBACKUP
53 trx_undof_page_add_undo_rec_log(
64 log_ptr =
mlog_open(mtr, 11 + 13 + MLOG_BUF_MARGIN);
66 if (log_ptr == NULL) {
71 log_end = &log_ptr[11 + 13 + MLOG_BUF_MARGIN];
74 len = new_free - old_free - 4;
79 if (log_ptr + len <= log_end) {
80 memcpy(log_ptr, undo_page + old_free + 2, len);
104 if (end_ptr < ptr + 2) {
112 if (end_ptr < ptr + len) {
124 rec = page + first_free;
130 first_free + 4 + len);
136 #ifndef UNIV_HOTBACKUP
160 trx_undo_page_set_next_prev_and_add(
169 byte* ptr_to_first_free;
174 ut_ad(ptr > undo_page);
175 ut_ad(ptr < undo_page + UNIV_PAGE_SIZE);
177 if (UNIV_UNLIKELY(trx_undo_left(undo_page, ptr) < 2)) {
190 end_of_rec = ptr - undo_page;
199 trx_undof_page_add_undo_rec_log(undo_page, first_free,
210 trx_undo_page_report_insert(
228 + TRX_UNDO_PAGE_FREE);
229 ptr = undo_page + first_free;
231 ut_ad(first_free <= UNIV_PAGE_SIZE);
233 if (trx_undo_left(undo_page, ptr) < 2 + 1 + 11 + 11) {
244 *ptr++ = TRX_UNDO_INSERT_REC;
253 const dfield_t* field = dtuple_get_nth_field(clust_entry, i);
256 if (trx_undo_left(undo_page, ptr) < 5) {
263 if (flen != UNIV_SQL_NULL) {
264 if (trx_undo_left(undo_page, ptr) < flen) {
269 ut_memcpy(ptr, dfield_get_data(field), flen);
274 return(trx_undo_page_set_next_prev_and_add(undo_page, ptr, mtr));
289 ibool* updated_extern,
292 table_id_t* table_id)
302 if (type_cmpl & TRX_UNDO_UPD_EXTERN) {
303 *updated_extern = TRUE;
304 type_cmpl -= TRX_UNDO_UPD_EXTERN;
306 *updated_extern = FALSE;
309 *type = type_cmpl & (TRX_UNDO_CMPL_INFO_MULT - 1);
310 *cmpl_info = type_cmpl / TRX_UNDO_CMPL_INFO_MULT;
326 trx_undo_rec_get_col_val(
343 case UNIV_EXTERN_STORAGE_FIELD:
352 ut_ad(*len > *orig_len);
361 *len += UNIV_EXTERN_STORAGE_FIELD;
365 if (*len >= UNIV_EXTERN_STORAGE_FIELD) {
366 ptr += *len - UNIV_EXTERN_STORAGE_FIELD;
396 ut_ad(index && ptr && ref && heap);
405 for (i = 0; i < ref_len; i++) {
411 dfield = dtuple_get_nth_field(*ref, i);
413 ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
440 for (i = 0; i < ref_len; i++) {
445 ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
457 trx_undo_page_fetch_ext(
470 ext_buf, REC_MAX_INDEX_COL_LEN, zip_size, field, *len);
474 memcpy(ext_buf + ext_len,
486 trx_undo_page_report_modify_ext(
510 *field = trx_undo_page_fetch_ext(ext_buf, zip_size,
529 trx_undo_page_report_modify(
537 const ulint* offsets,
555 ibool ignore_prefix = FALSE;
556 byte ext_buf[REC_MAX_INDEX_COL_LEN
563 table = index->
table;
566 + TRX_UNDO_PAGE_FREE);
567 ptr = undo_page + first_free;
569 ut_ad(first_free <= UNIV_PAGE_SIZE);
571 if (trx_undo_left(undo_page, ptr) < 50) {
585 type_cmpl = TRX_UNDO_DEL_MARK_REC;
587 type_cmpl = TRX_UNDO_UPD_DEL_REC;
592 ignore_prefix = TRUE;
594 type_cmpl = TRX_UNDO_UPD_EXIST_REC;
597 type_cmpl |= cmpl_info * TRX_UNDO_CMPL_INFO_MULT;
600 *ptr++ = (byte) type_cmpl;
611 field = rec_get_nth_field(rec, offsets,
613 index, DATA_TRX_ID), &flen);
614 ut_ad(flen == DATA_TRX_ID_LEN);
623 ignore_prefix = (trx_id != trx->
id);
627 field = rec_get_nth_field(rec, offsets,
629 index, DATA_ROLL_PTR), &flen);
630 ut_ad(flen == DATA_ROLL_PTR_LEN);
640 field = rec_get_nth_field(rec, offsets, i, &flen);
646 if (trx_undo_left(undo_page, ptr) < 5) {
653 if (flen != UNIV_SQL_NULL) {
654 if (trx_undo_left(undo_page, ptr) < flen) {
668 if (trx_undo_left(undo_page, ptr) < 5) {
677 ulint pos = upd_get_nth_field(update, i)->field_no;
680 if (trx_undo_left(undo_page, ptr) < 5) {
688 field = rec_get_nth_field(rec, offsets, pos, &flen);
690 if (trx_undo_left(undo_page, ptr) < 15) {
696 ptr = trx_undo_page_report_modify_ext(
701 && flen < REC_MAX_INDEX_COL_LEN
711 *type_cmpl_ptr |= TRX_UNDO_UPD_EXTERN;
716 if (flen != UNIV_SQL_NULL) {
717 if (trx_undo_left(undo_page, ptr) < flen) {
742 if (!update || !(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
747 if (trx_undo_left(undo_page, ptr) < 5) {
761 = dict_table_get_nth_col(table, col_no);
767 if (trx_undo_left(undo_page, ptr) < 5 + 15) {
777 field = rec_get_nth_field(rec, offsets, pos,
781 ptr = trx_undo_page_report_modify_ext(
783 flen < REC_MAX_INDEX_COL_LEN
793 if (flen != UNIV_SQL_NULL) {
794 if (trx_undo_left(undo_page, ptr)
811 if (trx_undo_left(undo_page, ptr) < 2) {
825 trx_undof_page_add_undo_rec_log(undo_page, first_free,
826 ptr - undo_page, mtr);
865 trx_undo_update_rec_get_n_upd_fields(
881 trx_undo_update_rec_get_field_no(
928 if (type != TRX_UNDO_DEL_MARK_REC) {
929 ptr = trx_undo_update_rec_get_n_upd_fields(ptr, &n_fields);
940 upd_field = upd_get_nth_field(update, n_fields);
949 upd_field = upd_get_nth_field(update, n_fields + 1);
950 buf =
static_cast<byte *
>(
mem_heap_alloc(heap, DATA_ROLL_PTR_LEN));
960 for (i = 0; i < n_fields; i++) {
967 ptr = trx_undo_update_rec_get_field_no(ptr, &field_no);
971 "InnoDB: Error: trying to access"
972 " update undo rec field %lu in ",
976 "InnoDB: but index has only %lu fields\n"
977 "InnoDB: Submit a detailed bug report"
978 " to http://bugs.mysql.com\n"
979 "InnoDB: Run also CHECK TABLE ",
983 "InnoDB: n_fields = %lu, i = %lu, ptr %p\n",
984 (ulong) n_fields, (ulong) i, ptr);
989 upd_field = upd_get_nth_field(update, i);
993 ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
997 if (len == UNIV_SQL_NULL) {
999 }
else if (len < UNIV_EXTERN_STORAGE_FIELD) {
1002 len -= UNIV_EXTERN_STORAGE_FIELD;
1031 ibool ignore_prefix,
1037 const byte* end_ptr;
1055 while (ptr != end_ptr) {
1064 ptr = trx_undo_update_rec_get_field_no(ptr, &field_no);
1069 ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
1071 dfield = dtuple_get_nth_field(*row, col_no);
1075 if (len != UNIV_SQL_NULL
1076 && len >= UNIV_EXTERN_STORAGE_FIELD) {
1078 len - UNIV_EXTERN_STORAGE_FIELD);
1083 if (!ignore_prefix && col->
ord_part) {
1085 >= 2 * BTR_EXTERN_FIELD_REF_SIZE);
1089 >= REC_MAX_INDEX_COL_LEN
1090 + BTR_EXTERN_FIELD_REF_SIZE);
1103 trx_undo_erase_page_end(
1111 + TRX_UNDO_PAGE_FREE);
1112 memset(undo_page + first_free, 0xff,
1130 ut_ad(ptr && end_ptr);
1137 trx_undo_erase_page_end(page, mtr);
1142 #ifndef UNIV_HOTBACKUP
1162 const upd_t* update,
1179 ulint err = DB_SUCCESS;
1181 ulint offsets_[REC_OFFS_NORMAL_SIZE];
1182 ulint* offsets = offsets_;
1183 rec_offs_init(offsets_);
1187 if (flags & BTR_NO_UNDO_LOG_FLAG) {
1195 ut_ad((op_type != TRX_UNDO_INSERT_OP)
1196 || (clust_entry && !update && !rec));
1205 if (op_type == TRX_UNDO_INSERT_OP) {
1214 if (UNIV_UNLIKELY(!undo)) {
1221 ut_ad(op_type == TRX_UNDO_MODIFY_OP);
1231 if (UNIV_UNLIKELY(!undo)) {
1237 offsets = rec_get_offsets(rec, index, offsets,
1238 ULINT_UNDEFINED, &heap);
1251 page_no, RW_X_LATCH,
1253 __FILE__, __LINE__, &mtr);
1254 buf_block_dbg_add_level(undo_block, SYNC_TRX_UNDO_PAGE);
1256 undo_page = buf_block_get_frame(undo_block);
1258 if (op_type == TRX_UNDO_INSERT_OP) {
1259 offset = trx_undo_page_report_insert(
1260 undo_page, trx, index, clust_entry, &mtr);
1262 offset = trx_undo_page_report_modify(
1263 undo_page, trx, index, rec, offsets, update,
1267 if (UNIV_UNLIKELY(offset == 0)) {
1274 trx_undo_erase_page_end(undo_page, &mtr);
1281 undo->
empty = FALSE;
1292 op_type == TRX_UNDO_INSERT_OP,
1293 rseg->
id, page_no, offset);
1294 if (UNIV_LIKELY_NULL(heap)) {
1310 mutex_enter(&(rseg->
mutex));
1314 mutex_exit(&(rseg->
mutex));
1316 if (UNIV_UNLIKELY(page_no ==
FIL_NULL)) {
1321 if (UNIV_LIKELY_NULL(heap)) {
1324 return(DB_OUT_OF_FILE_SPACE);
1386 #ifdef UNIV_SYNC_DEBUG
1395 return(DB_MISSING_HISTORY);
1415 const rec_t* index_rec,
1436 table_id_t table_id;
1440 upd_t* update= NULL;
1447 #ifdef UNIV_SYNC_DEBUG
1450 ut_ad(mtr_memo_contains_page(index_mtr, index_rec, MTR_MEMO_PAGE_S_FIX)
1451 || mtr_memo_contains_page(index_mtr, index_rec,
1452 MTR_MEMO_PAGE_X_FIX));
1456 fprintf(stderr,
"InnoDB: Error: trying to access"
1457 " update undo rec for non-clustered index %s\n"
1458 "InnoDB: Submit a detailed bug report to"
1459 " http://bugs.mysql.com\n"
1460 "InnoDB: index record ", index->
name);
1463 "InnoDB: record version ", stderr);
1470 old_roll_ptr = roll_ptr;
1485 if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
1493 &dummy_extern, &undo_no, &table_id);
1523 roll_ptr, info_bits,
1524 NULL, heap, &update);
1526 if (UNIV_UNLIKELY(table_id != index->
table->
id)) {
1530 "InnoDB: Error: trying to access update undo rec"
1532 "InnoDB: but the table id in the"
1533 " undo record is wrong\n"
1534 "InnoDB: Submit a detailed bug report"
1535 " to http://bugs.mysql.com\n"
1536 "InnoDB: Run also CHECK TABLE %s\n",
1545 "InnoDB: table %s, index %s, n_uniq %lu\n"
1546 "InnoDB: undo rec address %p, type %lu cmpl_info %lu\n"
1547 "InnoDB: undo rec table id %llu,"
1548 " index table id %llu\n"
1549 "InnoDB: dump of 150 bytes in undo rec: ",
1552 undo_rec, (ulong) type, (ulong) cmpl_info,
1557 "InnoDB: index record ", stderr);
1560 "InnoDB: record version ", stderr);
1562 fprintf(stderr,
"\n"
1568 old_roll_ptr, roll_ptr);
1584 offsets, &n_ext, heap);
1598 *old_vers =
rec_copy(buf, rec, offsets);
1599 rec_offs_make_valid(*old_vers, index, offsets);
#define FIL_PAGE_DATA_END
UNIV_INTERN byte * trx_undo_rec_get_row_ref(byte *ptr, dict_index_t *index, dtuple_t **ref, mem_heap_t *heap)
UNIV_INTERN byte * trx_undo_parse_erase_page_end(byte *ptr, byte *end_ptr, page_t *page, mtr_t *mtr)
UNIV_INLINE ulint mach_ull_write_much_compressed(byte *b, ib_uint64_t n)
#define TRX_UNDO_PAGE_HDR
buf_block_t * guess_block
UNIV_INLINE trx_id_t row_get_rec_trx_id(const rec_t *rec, dict_index_t *index, const ulint *offsets)
UNIV_INLINE roll_ptr_t row_get_rec_roll_ptr(const rec_t *rec, dict_index_t *index, const ulint *offsets)
UNIV_INTERN byte * trx_undo_rec_get_partial_row(byte *ptr, dict_index_t *index, dtuple_t **row, ibool ignore_prefix, mem_heap_t *heap)
UNIV_INLINE void trx_write_trx_id(byte *ptr, trx_id_t id)
UNIV_INLINE ulint mach_get_compressed_size(ulint n) __attribute__((const ))
UNIV_INLINE ulint dict_index_get_n_fields(const dict_index_t *index)
UNIV_INTERN ulint trx_undo_get_undo_rec(roll_ptr_t roll_ptr, trx_id_t trx_id, trx_undo_rec_t **undo_rec, mem_heap_t *heap)
UNIV_INLINE void dfield_set_len(dfield_t *field, ulint len)
UNIV_INTERN trx_rseg_t * trx_rseg_get_on_id(ulint id)
UNIV_INLINE dtuple_t * dtuple_create(mem_heap_t *heap, ulint n_fields)
UNIV_INLINE ulint mach_read_compressed(const byte *b) __attribute__((nonnull
UNIV_INTERN ulint btr_copy_externally_stored_field_prefix(byte *buf, ulint len, ulint zip_size, const byte *data, ulint local_len)
UNIV_INTERN ulint trx_undo_add_page(trx_t *trx, trx_undo_t *undo, mtr_t *mtr)
UNIV_INLINE void * ut_memcpy(void *dest, const void *sour, ulint n)
UNIV_INLINE void mlog_close(mtr_t *mtr, byte *ptr)
UNIV_INTERN void ut_print_buf(FILE *file, const void *buf, ulint len)
UNIV_INTERN trx_undo_rec_t * trx_undo_get_undo_rec_low(roll_ptr_t roll_ptr, mem_heap_t *heap)
UNIV_INTERN void trx_purge_sys_print(void)
UNIV_INLINE ibool dict_table_is_comp(const dict_table_t *table)
UNIV_INLINE ulint rec_offs_nth_extern(const ulint *offsets, ulint n)
UNIV_INLINE ulint mach_ull_get_compressed_size(ib_uint64_t n)
UNIV_INTERN void rec_print_new(FILE *file, const rec_t *rec, const ulint *offsets)
UNIV_INLINE ulint mach_ull_write_compressed(byte *b, ib_uint64_t n)
UNIV_INTERN ulint dict_index_get_nth_col_pos(const dict_index_t *index, ulint n)
UNIV_INTERN byte * trx_undo_update_rec_get_update(byte *ptr, dict_index_t *index, ulint type, trx_id_t trx_id, roll_ptr_t roll_ptr, ulint info_bits, trx_t *trx, mem_heap_t *heap, upd_t **upd)
UNIV_INTERN void rec_print(FILE *file, const rec_t *rec, const dict_index_t *index)
UNIV_INLINE rec_t * rec_copy(void *buf, const rec_t *rec, const ulint *offsets)
#define DICT_TF_FORMAT_ZIP
#define mem_heap_free(heap)
UNIV_INTERN rec_t * rec_convert_dtuple_to_rec(byte *buf, const dict_index_t *index, const dtuple_t *dtuple, ulint n_ext)
UNIV_INLINE const dict_col_t * dict_index_get_nth_col(const dict_index_t *index, ulint pos)
UNIV_INTERN void dict_index_copy_types(dtuple_t *tuple, const dict_index_t *index, ulint n_fields)
UNIV_INLINE roll_ptr_t trx_read_roll_ptr(const byte *ptr)
UNIV_INTERN void dict_table_copy_types(dtuple_t *tuple, const dict_table_t *table)
UNIV_INTERN void row_upd_rec_in_place(rec_t *rec, dict_index_t *index, const ulint *offsets, const upd_t *update, page_zip_des_t *page_zip)
UNIV_INLINE ulint rec_get_deleted_flag(const rec_t *rec, ulint comp)
UNIV_INLINE ib_uint64_t mach_ull_read_much_compressed(const byte *b) __attribute__((nonnull
UNIV_INTERN ibool row_upd_changes_field_size_or_external(dict_index_t *index, const ulint *offsets, const upd_t *update)
UNIV_INTERN void mtr_commit(mtr_t *mtr) __attribute__((nonnull))
UNIV_INTERN void row_upd_index_replace_new_col_vals(dtuple_t *entry, dict_index_t *index, const upd_t *update, mem_heap_t *heap) __attribute__((nonnull))
UNIV_INLINE void dfield_set_data(dfield_t *field, const void *data, ulint len)
UNIV_INLINE ulint dict_table_zip_size(const dict_table_t *table)
UNIV_INLINE byte * mlog_write_initial_log_record_fast(const byte *ptr, byte type, byte *log_ptr, mtr_t *mtr)
UNIV_INLINE ulint dfield_get_len(const dfield_t *field)
UNIV_INLINE roll_ptr_t trx_undo_build_roll_ptr(ibool is_insert, ulint rseg_id, ulint page_no, ulint offset)
UNIV_INLINE ulint dict_table_get_format(const dict_table_t *table)
UNIV_INLINE void trx_write_roll_ptr(byte *ptr, roll_ptr_t roll_ptr)
UNIV_INLINE ulint dict_col_get_no(const dict_col_t *col)
UNIV_INLINE ulint dict_index_is_clust(const dict_index_t *index) __attribute__((pure))
UNIV_INTERN ulint trx_undo_report_row_operation(ulint flags, ulint op_type, que_thr_t *thr, dict_index_t *index, const dtuple_t *clust_entry, const upd_t *update, ulint cmpl_info, const rec_t *rec, roll_ptr_t *roll_ptr)
UNIV_INTERN ibool trx_purge_update_undo_must_exist(trx_id_t trx_id)
UNIV_INTERN void mlog_catenate_string(mtr_t *mtr, const byte *str, ulint len)
UNIV_INTERN void ut_print_name(FILE *f, struct trx_struct *trx, ibool table_id, const char *name)
UNIV_INLINE void * mem_heap_alloc(mem_heap_t *heap, ulint n)
UNIV_INTERN byte * trx_undo_parse_add_undo_rec(byte *ptr, byte *end_ptr, page_t *page)
UNIV_INLINE void trx_undo_decode_roll_ptr(roll_ptr_t roll_ptr, ibool *is_insert, ulint *rseg_id, ulint *page_no, ulint *offset)
UNIV_INTERN buf_block_t * buf_page_get_gen(ulint space, ulint zip_size, ulint offset, ulint rw_latch, buf_block_t *guess, ulint mode, const char *file, ulint line, mtr_t *mtr)
UNIV_INLINE byte * mlog_open(mtr_t *mtr, ulint size)
UNIV_INTERN void mlog_write_initial_log_record(const byte *ptr, byte type, mtr_t *mtr)
UNIV_INTERN byte * trx_undo_rec_skip_row_ref(byte *ptr, dict_index_t *index)
#define MLOG_UNDO_ERASE_END
UNIV_INLINE ulint rec_get_converted_size(dict_index_t *index, const dtuple_t *dtuple, ulint n_ext)
UNIV_INLINE void upd_field_set_field_no(upd_field_t *upd_field, ulint field_no, dict_index_t *index, trx_t *trx)
UNIV_INLINE ulint dict_table_get_n_cols(const dict_table_t *table)
UNIV_INLINE trx_id_t trx_read_trx_id(const byte *ptr)
UNIV_INTERN ulint btr_push_update_extern_fields(dtuple_t *tuple, const upd_t *update, mem_heap_t *heap) __attribute__((nonnull))
#define BTR_EXTERN_FIELD_REF_SIZE
UNIV_INLINE ulint dict_index_get_n_unique(const dict_index_t *index)
UNIV_INTERN byte * trx_undo_update_rec_get_sys_cols(byte *ptr, trx_id_t *trx_id, roll_ptr_t *roll_ptr, ulint *info_bits)
UNIV_INLINE trx_undo_rec_t * trx_undo_rec_copy(const trx_undo_rec_t *undo_rec, mem_heap_t *heap)
UNIV_INLINE ulint mach_ull_get_much_compressed_size(ib_uint64_t n) __attribute__((const ))
UNIV_INLINE void dfield_set_null(dfield_t *field)
UNIV_INLINE ulint dict_index_get_sys_col_pos(const dict_index_t *index, ulint type)
UNIV_INTERN ulint trx_undo_assign_undo(trx_t *trx, ulint type)
UNIV_INLINE ulint mach_write_compressed(byte *b, ulint n)
UNIV_INLINE void mach_write_to_2(byte *b, ulint n)
UNIV_INLINE trx_t * thr_get_trx(que_thr_t *thr)
#define TRX_UNDO_PAGE_TYPE
UNIV_INLINE void mtr_start(mtr_t *mtr) __attribute__((nonnull))
UNIV_INLINE ulint rec_get_info_bits(const rec_t *rec, ulint comp)
UNIV_INLINE ulint mach_read_from_1(const byte *b) __attribute__((nonnull
UNIV_INLINE ulint upd_get_n_fields(const upd_t *update)
#define TRX_UNDO_PAGE_FREE
UNIV_INTERN dtuple_t * row_rec_to_index_entry(ulint type, const rec_t *rec, const dict_index_t *index, ulint *offsets, ulint *n_ext, mem_heap_t *heap)
UNIV_INLINE ulint rec_offs_size(const ulint *offsets)
UNIV_INTERN ulint trx_undo_prev_version_build(const rec_t *index_rec, mtr_t *index_mtr, const rec_t *rec, dict_index_t *index, ulint *offsets, mem_heap_t *heap, rec_t **old_vers)
UNIV_INLINE ulint mach_read_from_2(const byte *b) __attribute__((nonnull
UNIV_INLINE void dfield_set_ext(dfield_t *field)
UNIV_INTERN void dict_index_name_print(FILE *file, trx_t *trx, const dict_index_t *index)
UNIV_INLINE ib_uint64_t mach_ull_read_compressed(const byte *b) __attribute__((nonnull
UNIV_INLINE upd_t * upd_create(ulint n, mem_heap_t *heap)
UNIV_INTERN byte * trx_undo_rec_get_pars(trx_undo_rec_t *undo_rec, ulint *type, ulint *cmpl_info, ibool *updated_extern, undo_no_t *undo_no, table_id_t *table_id)
UNIV_INLINE page_t * trx_undo_page_get_s_latched(ulint space, ulint zip_size, ulint page_no, mtr_t *mtr)
UNIV_INLINE ibool rec_offs_validate(const rec_t *rec, const dict_index_t *index, const ulint *offsets)
UNIV_INLINE ibool trx_undo_roll_ptr_is_insert(roll_ptr_t roll_ptr)