mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / innobase / trx / trx0rseg.c
blob020f217c90bd9ffd1165dcaade4848c1da9cb849
1 /******************************************************
2 Rollback segment
4 (c) 1996 Innobase Oy
6 Created 3/26/1996 Heikki Tuuri
7 *******************************************************/
9 #include "trx0rseg.h"
11 #ifdef UNIV_NONINL
12 #include "trx0rseg.ic"
13 #endif
15 #include "trx0undo.h"
16 #include "fut0lst.h"
17 #include "srv0srv.h"
18 #include "trx0purge.h"
20 /**********************************************************************
21 Looks for a rollback segment, based on the rollback segment id. */
23 trx_rseg_t*
24 trx_rseg_get_on_id(
25 /*===============*/
26 /* out: rollback segment */
27 ulint id) /* in: rollback segment id */
29 trx_rseg_t* rseg;
31 rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
32 ut_ad(rseg);
34 while (rseg->id != id) {
35 rseg = UT_LIST_GET_NEXT(rseg_list, rseg);
36 ut_ad(rseg);
39 return(rseg);
42 /********************************************************************
43 Creates a rollback segment header. This function is called only when
44 a new rollback segment is created in the database. */
46 ulint
47 trx_rseg_header_create(
48 /*===================*/
49 /* out: page number of the created segment,
50 FIL_NULL if fail */
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 */
56 ulint page_no;
57 trx_rsegf_t* rsegf;
58 trx_sysf_t* sys_header;
59 ulint i;
60 page_t* page;
62 ut_ad(mtr);
63 ut_ad(mutex_own(&kernel_mutex));
64 ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space),
65 MTR_MEMO_X_LOCK));
66 sys_header = trx_sysf_get(mtr);
68 *slot_no = trx_sysf_rseg_find_free(mtr);
70 if (*slot_no == ULINT_UNDEFINED) {
72 return(FIL_NULL);
75 /* Allocate a new file segment for the rollback segment */
76 page = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr);
78 if (page == NULL) {
79 /* No space left */
81 return(FIL_NULL);
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,
95 MLOG_4BYTES, mtr);
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
109 header */
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);
114 return(page_no);
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. */
122 static
123 trx_rseg_t*
124 trx_rseg_mem_create(
125 /*================*/
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;
133 trx_rseg_t* rseg;
134 trx_ulogf_t* undo_log_hdr;
135 fil_addr_t node_addr;
136 ulint sum_of_undo_sizes;
137 ulint len;
139 ut_ad(mutex_own(&kernel_mutex));
141 rseg = mem_alloc(sizeof(trx_rseg_t));
143 rseg->id = id;
144 rseg->space = space;
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,
156 MLOG_4BYTES, mtr);
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,
163 MLOG_4BYTES, mtr)
164 + 1 + sum_of_undo_sizes;
166 len = flst_get_len(rseg_header + TRX_RSEG_HISTORY, mtr);
167 if (len > 0) {
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);
182 } else {
183 rseg->last_page_no = FIL_NULL;
186 return(rseg);
189 /*************************************************************************
190 Creates the memory copies for rollback segments and initializes the
191 rseg list and array in trx_sys at a database startup. */
193 void
194 trx_rseg_list_and_array_init(
195 /*=========================*/
196 trx_sysf_t* sys_header, /* in: trx system header */
197 mtr_t* mtr) /* in: mtr */
199 ulint i;
200 ulint page_no;
201 ulint space;
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);
214 } else {
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. */
225 trx_rseg_t*
226 trx_rseg_create(
227 /*============*/
228 /* out: the created segment object, NULL if
229 fail */
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 */
235 ulint page_no;
236 trx_rseg_t* rseg;
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);
246 return(NULL);
249 rseg = trx_rseg_mem_create(*id, space, page_no, mtr);
251 mutex_exit(&kernel_mutex);
253 return(rseg);