~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/******************************************************
2
Transaction undo log
3
4
(c) 1996 Innobase Oy
5
6
Created 3/26/1996 Heikki Tuuri
7
*******************************************************/
8
9
#include "data0type.h"
10
11
/***************************************************************************
12
Builds a roll pointer dulint. */
13
UNIV_INLINE
14
dulint
15
trx_undo_build_roll_ptr(
16
/*====================*/
17
				/* out: roll pointer */
18
	ibool	is_insert,	/* in: TRUE if insert undo log */
19
	ulint	rseg_id,	/* in: rollback segment id */
20
	ulint	page_no,	/* in: page number */
21
	ulint	offset)		/* in: offset of the undo entry within page */
22
{
23
#if DATA_ROLL_PTR_LEN != 7
24
# error "DATA_ROLL_PTR_LEN != 7"
25
#endif
26
	ut_ad(rseg_id < 128);
27
28
	return(ut_dulint_create(is_insert * 128 * 256 * 256
29
				+ rseg_id * 256 * 256
30
				+ (page_no / 256) / 256,
31
				(page_no % (256 * 256)) * 256 * 256
32
				+ offset));
33
}
34
35
/***************************************************************************
36
Decodes a roll pointer dulint. */
37
UNIV_INLINE
38
void
39
trx_undo_decode_roll_ptr(
40
/*=====================*/
41
	dulint	roll_ptr,	/* in: roll pointer */
42
	ibool*	is_insert,	/* out: TRUE if insert undo log */
43
	ulint*	rseg_id,	/* out: rollback segment id */
44
	ulint*	page_no,	/* out: page number */
45
	ulint*	offset)		/* out: offset of the undo entry within page */
46
{
47
	ulint	low;
48
	ulint	high;
49
#if DATA_ROLL_PTR_LEN != 7
50
# error "DATA_ROLL_PTR_LEN != 7"
51
#endif
52
#if TRUE != 1
53
# error "TRUE != 1"
54
#endif
55
	high = ut_dulint_get_high(roll_ptr);
56
	low = ut_dulint_get_low(roll_ptr);
57
58
	*offset = low % (256 * 256);
59
60
	*is_insert = high / (256 * 256 * 128);	/* TRUE == 1 */
61
	*rseg_id = (high / (256 * 256)) % 128;
62
63
	*page_no = (high % (256 * 256)) * 256 * 256
64
		+ (low / 256) / 256;
65
}
66
67
/***************************************************************************
68
Returns TRUE if the roll pointer is of the insert type. */
69
UNIV_INLINE
70
ibool
71
trx_undo_roll_ptr_is_insert(
72
/*========================*/
73
				/* out: TRUE if insert undo log */
74
	dulint	roll_ptr)	/* in: roll pointer */
75
{
76
	ulint	high;
77
#if DATA_ROLL_PTR_LEN != 7
78
# error "DATA_ROLL_PTR_LEN != 7"
79
#endif
80
#if TRUE != 1
81
# error "TRUE != 1"
82
#endif
83
	high = ut_dulint_get_high(roll_ptr);
84
85
	return(high / (256 * 256 * 128));
86
}
87
88
/*********************************************************************
89
Writes a roll ptr to an index page. In case that the size changes in
90
some future version, this function should be used instead of
91
mach_write_... */
92
UNIV_INLINE
93
void
94
trx_write_roll_ptr(
95
/*===============*/
96
	byte*	ptr,		/* in: pointer to memory where written */
97
	dulint	roll_ptr)	/* in: roll ptr */
98
{
99
	ut_ad(DATA_ROLL_PTR_LEN == 7);
100
101
	mach_write_to_7(ptr, roll_ptr);
102
}
103
104
/*********************************************************************
105
Reads a roll ptr from an index page. In case that the roll ptr size
106
changes in some future version, this function should be used instead of
107
mach_read_... */
108
UNIV_INLINE
109
dulint
110
trx_read_roll_ptr(
111
/*==============*/
112
			/* out: roll ptr */
113
	byte*	ptr)	/* in: pointer to memory from where to read */
114
{
115
#if DATA_ROLL_PTR_LEN != 7
116
# error "DATA_ROLL_PTR_LEN != 7"
117
#endif
118
	return(mach_read_from_7(ptr));
119
}
120
121
/**********************************************************************
122
Gets an undo log page and x-latches it. */
123
UNIV_INLINE
124
page_t*
125
trx_undo_page_get(
126
/*==============*/
127
				/* out: pointer to page x-latched */
128
	ulint	space,		/* in: space where placed */
129
	ulint	page_no,	/* in: page number */
130
	mtr_t*	mtr)		/* in: mtr */
131
{
132
	page_t*	page;
133
134
	page = buf_page_get(space, page_no, RW_X_LATCH, mtr);
135
136
#ifdef UNIV_SYNC_DEBUG
137
	buf_page_dbg_add_level(page, SYNC_TRX_UNDO_PAGE);
138
#endif /* UNIV_SYNC_DEBUG */
139
140
	return(page);
141
}
142
143
/**********************************************************************
144
Gets an undo log page and s-latches it. */
145
UNIV_INLINE
146
page_t*
147
trx_undo_page_get_s_latched(
148
/*========================*/
149
				/* out: pointer to page s-latched */
150
	ulint	space,		/* in: space where placed */
151
	ulint	page_no,	/* in: page number */
152
	mtr_t*	mtr)		/* in: mtr */
153
{
154
	page_t*	page;
155
156
	page = buf_page_get(space, page_no, RW_S_LATCH, mtr);
157
158
#ifdef UNIV_SYNC_DEBUG
159
	buf_page_dbg_add_level(page, SYNC_TRX_UNDO_PAGE);
160
#endif /* UNIV_SYNC_DEBUG */
161
162
	return(page);
163
}
164
165
/**********************************************************************
166
Returns the start offset of the undo log records of the specified undo
167
log on the page. */
168
UNIV_INLINE
169
ulint
170
trx_undo_page_get_start(
171
/*====================*/
172
			/* out: start offset */
173
	page_t*	undo_page,/* in: undo log page */
174
	ulint	page_no,/* in: undo log header page number */
175
	ulint	offset)	/* in: undo log header offset on page */
176
{
177
	ulint	start;
178
179
	if (page_no == buf_frame_get_page_no(undo_page)) {
180
181
		start = mach_read_from_2(offset + undo_page
182
					 + TRX_UNDO_LOG_START);
183
	} else {
184
		start = TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE;
185
	}
186
187
	return(start);
188
}
189
190
/**********************************************************************
191
Returns the end offset of the undo log records of the specified undo
192
log on the page. */
193
UNIV_INLINE
194
ulint
195
trx_undo_page_get_end(
196
/*==================*/
197
			/* out: end offset */
198
	page_t*	undo_page,/* in: undo log page */
199
	ulint	page_no,/* in: undo log header page number */
200
	ulint	offset)	/* in: undo log header offset on page */
201
{
202
	trx_ulogf_t*	log_hdr;
203
	ulint		end;
204
205
	if (page_no == buf_frame_get_page_no(undo_page)) {
206
207
		log_hdr = undo_page + offset;
208
209
		end = mach_read_from_2(log_hdr + TRX_UNDO_NEXT_LOG);
210
211
		if (end == 0) {
212
			end = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
213
					       + TRX_UNDO_PAGE_FREE);
214
		}
215
	} else {
216
		end = mach_read_from_2(undo_page + TRX_UNDO_PAGE_HDR
217
				       + TRX_UNDO_PAGE_FREE);
218
	}
219
220
	return(end);
221
}
222
223
/**********************************************************************
224
Returns the previous undo record on the page in the specified log, or
225
NULL if none exists. */
226
UNIV_INLINE
227
trx_undo_rec_t*
228
trx_undo_page_get_prev_rec(
229
/*=======================*/
230
				/* out: pointer to record, NULL if none */
231
	trx_undo_rec_t*	rec,	/* in: undo log record */
232
	ulint		page_no,/* in: undo log header page number */
233
	ulint		offset)	/* in: undo log header offset on page */
234
{
235
	page_t*	undo_page;
236
	ulint	start;
237
238
	undo_page = buf_frame_align(rec);
239
240
	start = trx_undo_page_get_start(undo_page, page_no, offset);
241
242
	if (start + undo_page == rec) {
243
244
		return(NULL);
245
	}
246
247
	return(undo_page + mach_read_from_2(rec - 2));
248
}
249
250
/**********************************************************************
251
Returns the next undo log record on the page in the specified log, or
252
NULL if none exists. */
253
UNIV_INLINE
254
trx_undo_rec_t*
255
trx_undo_page_get_next_rec(
256
/*=======================*/
257
				/* out: pointer to record, NULL if none */
258
	trx_undo_rec_t*	rec,	/* in: undo log record */
259
	ulint		page_no,/* in: undo log header page number */
260
	ulint		offset)	/* in: undo log header offset on page */
261
{
262
	page_t*	undo_page;
263
	ulint	end;
264
	ulint	next;
265
266
	undo_page = buf_frame_align(rec);
267
268
	end = trx_undo_page_get_end(undo_page, page_no, offset);
269
270
	next = mach_read_from_2(rec);
271
272
	if (next == end) {
273
274
		return(NULL);
275
	}
276
277
	return(undo_page + next);
278
}
279
280
/**********************************************************************
281
Returns the last undo record on the page in the specified undo log, or
282
NULL if none exists. */
283
UNIV_INLINE
284
trx_undo_rec_t*
285
trx_undo_page_get_last_rec(
286
/*=======================*/
287
			/* out: pointer to record, NULL if none */
288
	page_t*	undo_page,/* in: undo log page */
289
	ulint	page_no,/* in: undo log header page number */
290
	ulint	offset)	/* in: undo log header offset on page */
291
{
292
	ulint	start;
293
	ulint	end;
294
295
	start = trx_undo_page_get_start(undo_page, page_no, offset);
296
	end = trx_undo_page_get_end(undo_page, page_no, offset);
297
298
	if (start == end) {
299
300
		return(NULL);
301
	}
302
303
	return(undo_page + mach_read_from_2(undo_page + end - 2));
304
}
305
306
/**********************************************************************
307
Returns the first undo record on the page in the specified undo log, or
308
NULL if none exists. */
309
UNIV_INLINE
310
trx_undo_rec_t*
311
trx_undo_page_get_first_rec(
312
/*========================*/
313
			/* out: pointer to record, NULL if none */
314
	page_t*	undo_page,/* in: undo log page */
315
	ulint	page_no,/* in: undo log header page number */
316
	ulint	offset)	/* in: undo log header offset on page */
317
{
318
	ulint	start;
319
	ulint	end;
320
321
	start = trx_undo_page_get_start(undo_page, page_no, offset);
322
	end = trx_undo_page_get_end(undo_page, page_no, offset);
323
324
	if (start == end) {
325
326
		return(NULL);
327
	}
328
329
	return(undo_page + start);
330
}