1 /******************************************************
6 Created 3/26/1996 Heikki Tuuri
7 *******************************************************/
12 #include "trx0rseg.ic"
18 #include "trx0purge.h"
20 /**********************************************************************
21 Looks for a rollback segment, based on the rollback segment id. */
26 /* out: rollback segment */
27 ulint id
) /* in: rollback segment id */
31 rseg
= UT_LIST_GET_FIRST(trx_sys
->rseg_list
);
34 while (rseg
->id
!= id
) {
35 rseg
= UT_LIST_GET_NEXT(rseg_list
, rseg
);
42 /********************************************************************
43 Creates a rollback segment header. This function is called only when
44 a new rollback segment is created in the database. */
47 trx_rseg_header_create(
48 /*===================*/
49 /* out: page number of the created segment,
51 ulint space
, /* in: space id */
52 ulint max_size
, /* in: max size in pages */
53 ulint
* slot_no
, /* out: rseg id == slot number in trx sys */
54 mtr_t
* mtr
) /* in: mtr */
58 trx_sysf_t
* sys_header
;
63 ut_ad(mutex_own(&kernel_mutex
));
64 ut_ad(mtr_memo_contains(mtr
, fil_space_get_latch(space
),
66 sys_header
= trx_sysf_get(mtr
);
68 *slot_no
= trx_sysf_rseg_find_free(mtr
);
70 if (*slot_no
== ULINT_UNDEFINED
) {
75 /* Allocate a new file segment for the rollback segment */
76 page
= fseg_create(space
, 0, TRX_RSEG
+ TRX_RSEG_FSEG_HEADER
, mtr
);
84 #ifdef UNIV_SYNC_DEBUG
85 buf_page_dbg_add_level(page
, SYNC_RSEG_HEADER_NEW
);
86 #endif /* UNIV_SYNC_DEBUG */
88 page_no
= buf_frame_get_page_no(page
);
90 /* Get the rollback segment file page */
91 rsegf
= trx_rsegf_get_new(space
, page_no
, mtr
);
93 /* Initialize max size field */
94 mlog_write_ulint(rsegf
+ TRX_RSEG_MAX_SIZE
, max_size
,
97 /* Initialize the history list */
99 mlog_write_ulint(rsegf
+ TRX_RSEG_HISTORY_SIZE
, 0, MLOG_4BYTES
, mtr
);
100 flst_init(rsegf
+ TRX_RSEG_HISTORY
, mtr
);
102 /* Reset the undo log slots */
103 for (i
= 0; i
< TRX_RSEG_N_SLOTS
; i
++) {
105 trx_rsegf_set_nth_undo(rsegf
, i
, FIL_NULL
, mtr
);
108 /* Add the rollback segment info to the free slot in the trx system
111 trx_sysf_rseg_set_space(sys_header
, *slot_no
, space
, mtr
);
112 trx_sysf_rseg_set_page_no(sys_header
, *slot_no
, page_no
, mtr
);
117 /***************************************************************************
118 Creates and initializes a rollback segment object. The values for the
119 fields are read from the header. The object is inserted to the rseg
120 list of the trx system object and a pointer is inserted in the rseg
121 array in the trx system object. */
126 /* out, own: rollback segment object */
127 ulint id
, /* in: rollback segment id */
128 ulint space
, /* in: space where the segment placed */
129 ulint page_no
, /* in: page number of the segment header */
130 mtr_t
* mtr
) /* in: mtr */
132 trx_rsegf_t
* rseg_header
;
134 trx_ulogf_t
* undo_log_hdr
;
135 fil_addr_t node_addr
;
136 ulint sum_of_undo_sizes
;
139 ut_ad(mutex_own(&kernel_mutex
));
141 rseg
= mem_alloc(sizeof(trx_rseg_t
));
145 rseg
->page_no
= page_no
;
147 mutex_create(&rseg
->mutex
, SYNC_RSEG
);
149 UT_LIST_ADD_LAST(rseg_list
, trx_sys
->rseg_list
, rseg
);
151 trx_sys_set_nth_rseg(trx_sys
, id
, rseg
);
153 rseg_header
= trx_rsegf_get_new(space
, page_no
, mtr
);
155 rseg
->max_size
= mtr_read_ulint(rseg_header
+ TRX_RSEG_MAX_SIZE
,
158 /* Initialize the undo log lists according to the rseg header */
160 sum_of_undo_sizes
= trx_undo_lists_init(rseg
);
162 rseg
->curr_size
= mtr_read_ulint(rseg_header
+ TRX_RSEG_HISTORY_SIZE
,
164 + 1 + sum_of_undo_sizes
;
166 len
= flst_get_len(rseg_header
+ TRX_RSEG_HISTORY
, mtr
);
168 trx_sys
->rseg_history_len
+= len
;
170 node_addr
= trx_purge_get_log_from_hist(
171 flst_get_last(rseg_header
+ TRX_RSEG_HISTORY
, mtr
));
172 rseg
->last_page_no
= node_addr
.page
;
173 rseg
->last_offset
= node_addr
.boffset
;
175 undo_log_hdr
= trx_undo_page_get(rseg
->space
, node_addr
.page
,
176 mtr
) + node_addr
.boffset
;
178 rseg
->last_trx_no
= mtr_read_dulint(
179 undo_log_hdr
+ TRX_UNDO_TRX_NO
, mtr
);
180 rseg
->last_del_marks
= mtr_read_ulint(
181 undo_log_hdr
+ TRX_UNDO_DEL_MARKS
, MLOG_2BYTES
, mtr
);
183 rseg
->last_page_no
= FIL_NULL
;
189 /*************************************************************************
190 Creates the memory copies for rollback segments and initializes the
191 rseg list and array in trx_sys at a database startup. */
194 trx_rseg_list_and_array_init(
195 /*=========================*/
196 trx_sysf_t
* sys_header
, /* in: trx system header */
197 mtr_t
* mtr
) /* in: mtr */
203 UT_LIST_INIT(trx_sys
->rseg_list
);
205 trx_sys
->rseg_history_len
= 0;
207 for (i
= 0; i
< TRX_SYS_N_RSEGS
; i
++) {
209 page_no
= trx_sysf_rseg_get_page_no(sys_header
, i
, mtr
);
211 if (page_no
== FIL_NULL
) {
213 trx_sys_set_nth_rseg(trx_sys
, i
, NULL
);
215 space
= trx_sysf_rseg_get_space(sys_header
, i
, mtr
);
217 trx_rseg_mem_create(i
, space
, page_no
, mtr
);
222 /********************************************************************
223 Creates a new rollback segment to the database. */
228 /* out: the created segment object, NULL if
230 ulint space
, /* in: space id */
231 ulint max_size
, /* in: max size in pages */
232 ulint
* id
, /* out: rseg id */
233 mtr_t
* mtr
) /* in: mtr */
238 mtr_x_lock(fil_space_get_latch(space
), mtr
);
239 mutex_enter(&kernel_mutex
);
241 page_no
= trx_rseg_header_create(space
, max_size
, id
, mtr
);
243 if (page_no
== FIL_NULL
) {
245 mutex_exit(&kernel_mutex
);
249 rseg
= trx_rseg_mem_create(*id
, space
, page_no
, mtr
);
251 mutex_exit(&kernel_mutex
);