36 #ifndef UNIV_HOTBACKUP
65 log_ptr =
mlog_open(mtr, 11 + 13 + MLOG_BUF_MARGIN);
67 if (log_ptr == NULL) {
72 log_end = &log_ptr[11 + 13 + MLOG_BUF_MARGIN];
75 len = new_free - old_free - 4;
80 if (log_ptr + len <= log_end) {
81 memcpy(log_ptr, undo_page + old_free + 2, len);
105 if (end_ptr < ptr + 2) {
113 if (end_ptr < ptr + len) {
125 rec = page + first_free;
131 first_free + 4 + len);
137 #ifndef UNIV_HOTBACKUP
161 trx_undo_page_set_next_prev_and_add(
170 byte* ptr_to_first_free;
175 ut_ad(ptr > undo_page);
176 ut_ad(ptr < undo_page + UNIV_PAGE_SIZE);
211 trx_undo_page_report_insert(
229 + TRX_UNDO_PAGE_FREE);
230 ptr = undo_page + first_free;
232 ut_ad(first_free <= UNIV_PAGE_SIZE);
245 *ptr++ = TRX_UNDO_INSERT_REC;
254 const dfield_t* field = dtuple_get_nth_field(clust_entry, i);
264 if (flen != UNIV_SQL_NULL) {
270 ut_memcpy(ptr, dfield_get_data(field), flen);
275 return(trx_undo_page_set_next_prev_and_add(undo_page, ptr, mtr));
290 bool* updated_extern,
293 table_id_t* table_id)
303 *updated_extern = !!(type_cmpl & TRX_UNDO_UPD_EXTERN);
304 type_cmpl &= ~TRX_UNDO_UPD_EXTERN;
306 *type = type_cmpl & (TRX_UNDO_CMPL_INFO_MULT - 1);
307 *cmpl_info = type_cmpl / TRX_UNDO_CMPL_INFO_MULT;
323 trx_undo_rec_get_col_val(
340 case UNIV_EXTERN_STORAGE_FIELD:
349 ut_ad(*len > *orig_len);
359 *len += UNIV_EXTERN_STORAGE_FIELD;
363 if (*len >= UNIV_EXTERN_STORAGE_FIELD) {
364 ptr += *len - UNIV_EXTERN_STORAGE_FIELD;
394 ut_ad(index && ptr && ref && heap);
403 for (i = 0; i < ref_len; i++) {
409 dfield = dtuple_get_nth_field(*ref, i);
411 ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
438 for (i = 0; i < ref_len; i++) {
443 ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
455 trx_undo_page_fetch_ext(
469 ext_buf, prefix_len, zip_size, field, *len);
473 memcpy(ext_buf + ext_len,
485 trx_undo_page_report_modify_ext(
502 ut_a(prefix_len > 0);
512 *field = trx_undo_page_fetch_ext(ext_buf, prefix_len, zip_size,
531 trx_undo_page_report_modify(
557 ibool ignore_prefix = FALSE;
562 ut_ad(rec_offs_validate(rec, index, offsets));
565 table = index->
table;
568 + TRX_UNDO_PAGE_FREE);
569 ptr = undo_page + first_free;
571 ut_ad(first_free <= UNIV_PAGE_SIZE);
588 type_cmpl = TRX_UNDO_DEL_MARK_REC;
590 type_cmpl = TRX_UNDO_UPD_DEL_REC;
595 ignore_prefix = TRUE;
597 type_cmpl = TRX_UNDO_UPD_EXIST_REC;
600 type_cmpl |= cmpl_info * TRX_UNDO_CMPL_INFO_MULT;
603 *ptr++ = (byte) type_cmpl;
614 field = rec_get_nth_field(rec, offsets,
616 index, DATA_TRX_ID), &flen);
617 ut_ad(flen == DATA_TRX_ID_LEN);
626 ignore_prefix = (trx_id != trx->
id);
630 field = rec_get_nth_field(rec, offsets,
632 index, DATA_ROLL_PTR), &flen);
633 ut_ad(flen == DATA_ROLL_PTR_LEN);
643 field = rec_get_nth_field(rec, offsets, i, &flen);
656 if (flen != UNIV_SQL_NULL) {
680 ulint pos = upd_get_nth_field(update, i)->field_no;
691 field = rec_get_nth_field(rec, offsets, pos, &flen);
705 ut_ad(prefix_len + BTR_EXTERN_FIELD_REF_SIZE
708 ptr = trx_undo_page_report_modify_ext(
712 && flen < REC_ANTELOPE_MAX_INDEX_COL_LEN
713 ? ext_buf : NULL, prefix_len,
722 *type_cmpl_ptr |= TRX_UNDO_UPD_EXTERN;
727 if (flen != UNIV_SQL_NULL) {
753 if (!update || !(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
772 = dict_table_get_nth_col(table, col_no);
788 field = rec_get_nth_field(rec, offsets, pos,
799 ut_a(prefix_len <
sizeof ext_buf);
801 ptr = trx_undo_page_report_modify_ext(
803 flen < REC_ANTELOPE_MAX_INDEX_COL_LEN
805 ? ext_buf : NULL, prefix_len,
813 if (flen != UNIV_SQL_NULL) {
846 ptr - undo_page, mtr);
948 if (type != TRX_UNDO_DEL_MARK_REC) {
960 upd_field = upd_get_nth_field(update, n_fields);
971 upd_field = upd_get_nth_field(update, n_fields + 1);
973 buf =
static_cast<byte*
>(
mem_heap_alloc(heap, DATA_ROLL_PTR_LEN));
984 for (i = 0; i < n_fields; i++) {
995 "InnoDB: Error: trying to access"
996 " update undo rec field %lu in ",
1000 "InnoDB: but index has only %lu fields\n"
1001 "InnoDB: Submit a detailed bug report"
1002 " to http://bugs.mysql.com\n"
1003 "InnoDB: Run also CHECK TABLE ",
1006 fprintf(stderr,
"\n"
1007 "InnoDB: n_fields = %lu, i = %lu, ptr %p\n",
1008 (ulong) n_fields, (ulong) i, ptr);
1014 upd_field = upd_get_nth_field(update, i);
1018 ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
1022 if (len == UNIV_SQL_NULL) {
1024 }
else if (len < UNIV_EXTERN_STORAGE_FIELD) {
1027 len -= UNIV_EXTERN_STORAGE_FIELD;
1057 ibool ignore_prefix,
1063 const byte* end_ptr;
1078 for (ulint i = 0; i < row_len; i++) {
1079 dfield_get_type(dtuple_get_nth_field(*row, i))
1080 ->mtype = DATA_MISSING;
1086 while (ptr != end_ptr) {
1100 ptr = trx_undo_rec_get_col_val(ptr, &field, &len, &orig_len);
1102 dfield = dtuple_get_nth_field(*row, col_no);
1104 dict_table_get_nth_col(index->
table, col_no),
1105 dfield_get_type(dfield));
1108 if (len != UNIV_SQL_NULL
1109 && len >= UNIV_EXTERN_STORAGE_FIELD) {
1111 len - UNIV_EXTERN_STORAGE_FIELD);
1116 if (!ignore_prefix && col->
ord_part) {
1118 >= BTR_EXTERN_FIELD_REF_SIZE);
1122 >= REC_ANTELOPE_MAX_INDEX_COL_LEN
1123 + BTR_EXTERN_FIELD_REF_SIZE);
1135 static __attribute__((nonnull))
1137 trx_undo_erase_page_end(
1145 + TRX_UNDO_PAGE_FREE);
1146 memset(undo_page + first_free, 0xff,
1161 byte* end_ptr __attribute__((unused)),
1165 ut_ad(ptr && end_ptr);
1172 trx_undo_erase_page_end(page, mtr);
1177 #ifndef UNIV_HOTBACKUP
1197 const upd_t* update,
1204 const ulint* offsets,
1223 ut_ad(!rec || rec_offs_validate(rec, index, offsets));
1233 ut_ad((op_type != TRX_UNDO_INSERT_OP)
1234 || (clust_entry && !update && !rec));
1243 if (trx->
rseg == 0) {
1256 case TRX_UNDO_INSERT_OP:
1266 ut_ad(err != DB_SUCCESS);
1270 ut_ad(err == DB_SUCCESS);
1274 ut_ad(op_type == TRX_UNDO_MODIFY_OP);
1284 ut_ad(err != DB_SUCCESS);
1289 ut_ad(err == DB_SUCCESS);
1296 buf_block_dbg_add_level(undo_block, SYNC_TRX_UNDO_PAGE);
1302 undo_page = buf_block_get_frame(undo_block);
1306 case TRX_UNDO_INSERT_OP:
1307 offset = trx_undo_page_report_insert(
1308 undo_page, trx, index, clust_entry, &mtr);
1311 ut_ad(op_type == TRX_UNDO_MODIFY_OP);
1312 offset = trx_undo_page_report_modify(
1313 undo_page, trx, index, rec, offsets, update,
1317 if (UNIV_UNLIKELY(offset == 0)) {
1324 if (!trx_undo_erase_page_end(undo_page, &mtr)) {
1341 mutex_enter(&rseg->
mutex);
1342 trx_undo_free_last_page(trx, undo, &mtr);
1343 mutex_exit(&rseg->
mutex);
1355 undo->
empty = FALSE;
1366 op_type == TRX_UNDO_INSERT_OP,
1367 rseg->
id, page_no, offset);
1375 ut_ad(++loop_count < 2);
1382 mutex_enter(&rseg->
mutex);
1384 mutex_exit(&rseg->
mutex);
1387 }
while (undo_block != NULL);
1390 err = DB_OUT_OF_FILE_SPACE;
1444 static __attribute__((nonnull, warn_unused_result))
1446 trx_undo_get_undo_rec(
1455 bool missing_history;
1460 if (!missing_history) {
1466 return(missing_history);
1470 #define ATTRIB_USED_ONLY_IN_DEBUG
1472 #define ATTRIB_USED_ONLY_IN_DEBUG __attribute__((unused))
1486 const rec_t* index_rec ATTRIB_USED_ONLY_IN_DEBUG,
1489 mtr_t* index_mtr ATTRIB_USED_ONLY_IN_DEBUG,
1508 table_id_t table_id;
1517 #ifdef UNIV_SYNC_DEBUG
1520 ut_ad(mtr_memo_contains_page(index_mtr, index_rec, MTR_MEMO_PAGE_S_FIX)
1521 || mtr_memo_contains_page(index_mtr, index_rec,
1522 MTR_MEMO_PAGE_X_FIX));
1523 ut_ad(rec_offs_validate(rec, index, offsets));
1537 if (trx_undo_get_undo_rec(roll_ptr, rec_trx_id, &undo_rec, heap)) {
1544 &dummy_extern, &undo_no, &table_id);
1546 if (table_id != index->
table->
id) {
1581 roll_ptr, info_bits,
1582 NULL, heap, &update);
1585 # if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
1608 if ((update->
info_bits & REC_INFO_DELETED_FLAG)
1610 bool missing_extern;
1617 if (missing_extern) {
1631 rec, index, offsets, &n_ext, heap);
1638 buf =
static_cast<byte*
>(
1646 buf =
static_cast<byte*
>(
1649 *old_vers =
rec_copy(buf, rec, offsets);
1650 rec_offs_make_valid(*old_vers, index, offsets);