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);
403 dict_index_copy_types(*ref, index, ref_len);
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(
469 ulint ext_len = btr_copy_externally_stored_field_prefix(
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) {
772 pos = dict_index_get_nth_col_pos(index,
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 ",
974 dict_index_name_print(stderr, trx, index);
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;
1050 dict_table_copy_types(*row, index->
table);
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);
1585 n_ext += btr_push_update_extern_fields(entry, update, heap);
1598 *old_vers =
rec_copy(buf, rec, offsets);
1599 rec_offs_make_valid(*old_vers, index, offsets);