29 #include "trx0undo.ic"
33 #ifndef UNIV_HOTBACKUP
108 #ifndef UNIV_HOTBACKUP
133 trx_undo_insert_header_reuse(
144 trx_undo_discard_latest_update_undo(
149 #ifndef UNIV_HOTBACKUP
155 trx_undo_get_prev_rec_from_prev_page(
180 zip_size = fil_space_get_zip_size(space);
212 return(trx_undo_get_prev_rec_from_prev_page(rec, page_no, offset,
221 trx_undo_get_next_rec_from_next_page(
239 log_hdr = undo_page + offset;
256 if (mode == RW_S_LATCH) {
260 ut_ad(mode == RW_X_LATCH);
291 zip_size = fil_space_get_zip_size(space);
293 return(trx_undo_get_next_rec_from_next_page(space, zip_size,
317 if (mode == RW_S_LATCH) {
330 return(trx_undo_get_next_rec_from_next_page(space, zip_size,
331 undo_page, page_no, offset,
341 trx_undo_page_init_log(
352 # define trx_undo_page_init_log(undo_page,type,mtr) ((void) 0)
377 trx_undo_page_init(page, type, mtr);
406 trx_undo_page_init_log(undo_page, type, mtr);
409 #ifndef UNIV_HOTBACKUP
436 ulint err = DB_SUCCESS;
438 ut_ad(mtr &&
id && rseg_hdr);
439 ut_ad(mutex_own(&(rseg->mutex)));
446 if (slot_no == ULINT_UNDEFINED) {
449 " InnoDB: Warning: cannot find a free slot for"
450 " an undo log. Do you have too\n"
451 "InnoDB: many active transactions"
452 " running concurrently?\n");
454 return(DB_TOO_MANY_CONCURRENT_TRXS);
459 success = fsp_reserve_free_extents(&n_reserved, space, 2, FSP_UNDO,
463 return(DB_OUT_OF_FILE_SPACE);
467 block = fseg_create_general(space, 0,
471 fil_space_release_free_extents(space, n_reserved);
476 return(DB_OUT_OF_FILE_SPACE);
479 buf_block_dbg_add_level(block, SYNC_TRX_UNDO_PAGE);
481 *undo_page = buf_block_get_frame(block);
486 trx_undo_page_init(*undo_page, type, mtr);
510 trx_undo_header_create_log(
521 # define trx_undo_header_create_log(undo_page,trx_id,mtr) ((void) 0)
531 trx_undo_header_create(
549 ut_ad(mtr && undo_page);
556 log_hdr = undo_page + free;
571 prev_log_hdr = undo_page + prev_log;
578 log_hdr = undo_page + free;
592 trx_undo_header_create_log(undo_page, trx_id, mtr);
597 #ifndef UNIV_HOTBACKUP
644 trx_undo_header_add_space_for_xid(
660 ut_a(free == (ulint)(log_hdr - undo_page) + TRX_UNDO_LOG_OLD_HDR_SIZE);
682 trx_undo_insert_header_reuse_log(
693 # define trx_undo_insert_header_reuse_log(undo_page,trx_id,mtr) ((void) 0)
715 UNIV_MEM_INVALID(&trx_id,
sizeof trx_id);
726 trx_undo_header_create(page, trx_id, mtr);
729 trx_undo_insert_header_reuse(page, trx_id, mtr);
743 trx_undo_insert_header_reuse(
756 ut_ad(mtr && undo_page);
765 log_hdr = undo_page + free;
782 log_hdr = undo_page + free;
791 trx_undo_insert_header_reuse_log(undo_page, trx_id, mtr);
796 #ifndef UNIV_HOTBACKUP
801 trx_undo_discard_latest_log(
809 # define trx_undo_discard_latest_log(undo_page, mtr) ((void) 0)
827 trx_undo_discard_latest_update_undo(page, mtr);
838 trx_undo_discard_latest_update_undo(
848 ulint prev_hdr_offset;
854 log_hdr = undo_page + free;
858 if (prev_hdr_offset != 0) {
859 prev_log_hdr = undo_page + prev_hdr_offset;
872 trx_undo_discard_latest_log(undo_page, mtr);
875 #ifndef UNIV_HOTBACKUP
897 ut_ad(!mutex_own(&kernel_mutex));
902 if (rseg->curr_size == rseg->max_size) {
910 success = fsp_reserve_free_extents(&n_reserved, undo->
space, 1,
917 page_no = fseg_alloc_free_page_general(header_page + TRX_UNDO_SEG_HDR
922 fil_space_release_free_extents(undo->
space, n_reserved);
936 trx_undo_page_init(new_page, undo->
type, mtr);
971 ut_a(hdr_page_no != page_no);
972 ut_ad(!mutex_own(&kernel_mutex));
975 zip_size = rseg->zip_size;
985 space, page_no, mtr);
997 ut_ad(hist_size > 0);
1002 return(last_addr.
page);
1010 trx_undo_free_page_in_rollback(
1023 ut_ad(mutex_own(&(trx->undo_mutex)));
1025 last_page_no = trx_undo_free_page(undo->
rseg, FALSE, undo->
space,
1037 trx_undo_empty_header_page(
1052 log_hdr = header_page + hdr_offset;
1054 end = trx_undo_page_get_end(header_page, hdr_page_no, hdr_offset);
1088 last_page_no, &mtr);
1099 trx_undo_free_page_in_rollback(
1100 trx, undo, last_page_no, &mtr);
1165 hdr_page_no, hdr_offset,
1188 if (page_no == hdr_page_no) {
1189 trx_undo_empty_header_page(space, rseg->zip_size,
1190 hdr_page_no, hdr_offset,
1193 trx_undo_free_page(rseg, TRUE, space, hdr_page_no,
1211 fseg_header_t* file_seg;
1223 ut_ad(!mutex_own(&kernel_mutex));
1225 mutex_enter(&(rseg->
mutex));
1233 finished = fseg_free_step(file_seg, &mtr);
1238 rseg->
space, rseg->zip_size, rseg->page_no,
1244 mutex_exit(&(rseg->
mutex));
1246 }
while (!finished);
1258 trx_undo_mem_create_at_db_start(
1278 ibool xid_exists = FALSE;
1280 if (
id >= TRX_RSEG_N_SLOTS) {
1282 "InnoDB: Error: undo->id is %lu\n", (ulong)
id);
1299 undo_header = undo_page + offset;
1309 memset(&xid, 0,
sizeof(xid));
1312 if (xid_exists == TRUE) {
1313 trx_undo_read_xid(undo_header, &xid);
1316 mutex_enter(&(rseg->
mutex));
1318 undo = trx_undo_mem_create(rseg,
id, type, trx_id, &xid,
1320 mutex_exit(&(rseg->
mutex));
1326 undo->
state = state;
1330 if (state == TRX_UNDO_TO_FREE) {
1348 undo->
empty = FALSE;
1353 if (type == TRX_UNDO_INSERT) {
1354 if (state != TRX_UNDO_CACHED) {
1362 ut_ad(type == TRX_UNDO_UPDATE);
1363 if (state != TRX_UNDO_CACHED) {
1401 rseg->page_no, &mtr);
1403 for (i = 0; i < TRX_RSEG_N_SLOTS; i++) {
1414 undo = trx_undo_mem_create_at_db_start(rseg, i,
1423 rseg->
space, rseg->zip_size, rseg->page_no,
1438 trx_undo_mem_create(
1454 if (
id >= TRX_RSEG_N_SLOTS) {
1456 "InnoDB: Error: undo->id is %lu\n", (ulong)
id);
1469 undo->
state = TRX_UNDO_ACTIVE;
1496 trx_undo_mem_init_for_reuse(
1504 ut_ad(mutex_own(&((undo->
rseg)->mutex)));
1506 if (UNIV_UNLIKELY(undo->
id >= TRX_RSEG_N_SLOTS)) {
1507 fprintf(stderr,
"InnoDB: Error: undo->id is %lu\n",
1514 undo->
state = TRX_UNDO_ACTIVE;
1533 if (undo->
id >= TRX_RSEG_N_SLOTS) {
1535 "InnoDB: Error: undo->id is %lu\n", (ulong) undo->
id);
1571 if (rseg->curr_size == rseg->max_size) {
1573 return(DB_OUT_OF_FILE_SPACE);
1581 err = trx_undo_seg_create(rseg, rseg_header, type, &
id,
1584 if (err != DB_SUCCESS) {
1594 offset = trx_undo_header_create(undo_page, trx_id, mtr);
1597 trx_undo_header_add_space_for_xid(undo_page,
1598 undo_page + offset, mtr);
1601 *undo = trx_undo_mem_create(rseg,
id, type, trx_id, xid,
1603 if (*undo == NULL) {
1605 err = DB_OUT_OF_MEMORY;
1618 trx_undo_reuse_cached(
1635 if (type == TRX_UNDO_INSERT) {
1645 ut_ad(type == TRX_UNDO_UPDATE);
1658 if (undo->
id >= TRX_RSEG_N_SLOTS) {
1659 fprintf(stderr,
"InnoDB: Error: undo->id is %lu\n",
1668 if (type == TRX_UNDO_INSERT) {
1669 offset = trx_undo_insert_header_reuse(undo_page, trx_id, mtr);
1672 trx_undo_header_add_space_for_xid(
1673 undo_page, undo_page + offset, mtr);
1678 == TRX_UNDO_UPDATE);
1680 offset = trx_undo_header_create(undo_page, trx_id, mtr);
1683 trx_undo_header_add_space_for_xid(
1684 undo_page, undo_page + offset, mtr);
1688 trx_undo_mem_init_for_reuse(undo, trx_id, xid, offset);
1698 trx_undo_mark_as_dict_operation(
1747 ulint err = DB_SUCCESS;
1758 ut_ad(!mutex_own(&kernel_mutex));
1760 mutex_enter(&(rseg->
mutex));
1762 undo = trx_undo_reuse_cached(trx, rseg, type, trx->
id, &trx->
xid,
1765 err = trx_undo_create(trx, rseg, type, trx->
id, &trx->
xid,
1767 if (err != DB_SUCCESS) {
1773 if (type == TRX_UNDO_INSERT) {
1784 trx_undo_mark_as_dict_operation(trx, undo, &mtr);
1788 mutex_exit(&(rseg->
mutex));
1812 if (undo->
id >= TRX_RSEG_N_SLOTS) {
1813 fprintf(stderr,
"InnoDB: Error: undo->id is %lu\n",
1829 state = TRX_UNDO_CACHED;
1831 }
else if (undo->
type == TRX_UNDO_INSERT) {
1833 state = TRX_UNDO_TO_FREE;
1835 state = TRX_UNDO_TO_PURGE;
1838 undo->
state = state;
1861 ut_ad(trx && undo && mtr);
1863 if (undo->
id >= TRX_RSEG_N_SLOTS) {
1864 fprintf(stderr,
"InnoDB: Error: undo->id is %lu\n",
1876 undo->
state = TRX_UNDO_PREPARED;
1884 undo_header = undo_page + offset;
1889 trx_undo_write_xid(undo_header, &undo->
xid, mtr);
1921 if (undo->
state == TRX_UNDO_CACHED) {
1926 || undo->
state == TRX_UNDO_TO_FREE);
1950 mutex_enter(&(rseg->
mutex));
1955 if (undo->
state == TRX_UNDO_CACHED) {
1963 mutex_exit(&(rseg->
mutex));
1965 trx_undo_seg_free(undo);
1967 mutex_enter(&(rseg->
mutex));
1971 rseg->curr_size -= undo->
size;
1976 mutex_exit(&(rseg->
mutex));