~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/include/ibuf0ibuf.ic

  • Committer: Monty Taylor
  • Date: 2008-09-23 14:19:48 UTC
  • mto: This revision was merged to the branch mainline in revision 419.
  • Revision ID: monty@inaugust.com-20080923141948-ktph2kg13addaxq1
Actually removed VOID() this time.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/******************************************************
2
 
Insert buffer
3
 
 
4
 
(c) 1997 Innobase Oy
5
 
 
6
 
Created 7/19/1997 Heikki Tuuri
7
 
*******************************************************/
8
 
 
9
 
#include "buf0lru.h"
10
 
#include "page0page.h"
11
 
#include "page0zip.h"
12
 
 
13
 
extern ulint    ibuf_flush_count;
14
 
 
15
 
/* If this number is n, an index page must contain at least the page size
16
 
per n bytes of free space for ibuf to try to buffer inserts to this page.
17
 
If there is this much of free space, the corresponding bits are set in the
18
 
ibuf bitmap. */
19
 
#define IBUF_PAGE_SIZE_PER_FREE_SPACE   32
20
 
 
21
 
/* Insert buffer data struct for a single tablespace */
22
 
struct ibuf_data_struct{
23
 
        ulint           space;  /* space id */
24
 
        ulint           seg_size;/* allocated pages if the file segment
25
 
                                containing ibuf header and tree */
26
 
        ulint           size;   /* size of the insert buffer tree in pages */
27
 
        ibool           empty;  /* after an insert to the ibuf tree is
28
 
                                performed, this is set to FALSE, and if a
29
 
                                contract operation finds the tree empty, this
30
 
                                is set to TRUE */
31
 
        ulint           free_list_len;
32
 
                                /* length of the free list */
33
 
        ulint           height; /* tree height */
34
 
        dict_index_t*   index;  /* insert buffer index */
35
 
        UT_LIST_NODE_T(ibuf_data_t) data_list;
36
 
                                /* list of ibuf data structs */
37
 
        ulint           n_inserts;/* number of inserts made to the insert
38
 
                                buffer */
39
 
        ulint           n_merges;/* number of pages merged */
40
 
        ulint           n_merged_recs;/* number of records merged */
41
 
};
42
 
 
43
 
struct ibuf_struct{
44
 
        ulint           size;           /* current size of the ibuf index
45
 
                                        trees in pages */
46
 
        ulint           max_size;       /* recommended maximum size in pages
47
 
                                        for the ibuf index tree */
48
 
        UT_LIST_BASE_NODE_T(ibuf_data_t) data_list;
49
 
                                        /* list of ibuf data structs for
50
 
                                        each tablespace */
51
 
};
52
 
 
53
 
/****************************************************************************
54
 
Sets the free bit of the page in the ibuf bitmap. This is done in a separate
55
 
mini-transaction, hence this operation does not restrict further work to only
56
 
ibuf bitmap operations, which would result if the latch to the bitmap page
57
 
were kept. */
58
 
UNIV_INTERN
59
 
void
60
 
ibuf_set_free_bits_func(
61
 
/*====================*/
62
 
        buf_block_t*    block,  /* in: index page of a non-clustered index;
63
 
                                free bit is reset if page level is 0 */
64
 
#ifdef UNIV_IBUF_DEBUG
65
 
        ulint           max_val,/* in: ULINT_UNDEFINED or a maximum
66
 
                                value which the bits must have before
67
 
                                setting; this is for debugging */
68
 
#endif /* UNIV_IBUF_DEBUG */
69
 
        ulint           val);   /* in: value to set: < 4 */
70
 
#ifdef UNIV_IBUF_DEBUG
71
 
# define ibuf_set_free_bits(b,v,max) ibuf_set_free_bits_func(b,max,v)
72
 
#else /* UNIV_IBUF_DEBUG */
73
 
# define ibuf_set_free_bits(b,v,max) ibuf_set_free_bits_func(b,v)
74
 
#endif /* UNIV_IBUF_DEBUG */
75
 
 
76
 
/**************************************************************************
77
 
A basic partial test if an insert to the insert buffer could be possible and
78
 
recommended. */
79
 
UNIV_INLINE
80
 
ibool
81
 
ibuf_should_try(
82
 
/*============*/
83
 
        dict_index_t*   index,                  /* in: index where to insert */
84
 
        ulint           ignore_sec_unique)      /* in: if != 0, we should
85
 
                                                ignore UNIQUE constraint on
86
 
                                                a secondary index when we
87
 
                                                decide */
88
 
{
89
 
        if (!dict_index_is_clust(index)
90
 
            && (ignore_sec_unique || !dict_index_is_unique(index))) {
91
 
 
92
 
                ibuf_flush_count++;
93
 
 
94
 
                if (ibuf_flush_count % 8 == 0) {
95
 
 
96
 
                        buf_LRU_try_free_flushed_blocks();
97
 
                }
98
 
 
99
 
                return(TRUE);
100
 
        }
101
 
 
102
 
        return(FALSE);
103
 
}
104
 
 
105
 
/***************************************************************************
106
 
Checks if a page address is an ibuf bitmap page address. */
107
 
UNIV_INLINE
108
 
ibool
109
 
ibuf_bitmap_page(
110
 
/*=============*/
111
 
                        /* out: TRUE if a bitmap page */
112
 
        ulint   zip_size,/* in: compressed page size in bytes;
113
 
                        0 for uncompressed pages */
114
 
        ulint   page_no)/* in: page number */
115
 
{
116
 
        ut_ad(ut_is_2pow(zip_size));
117
 
 
118
 
        if (!zip_size) {
119
 
                return(UNIV_UNLIKELY((page_no & (UNIV_PAGE_SIZE - 1))
120
 
                                     == FSP_IBUF_BITMAP_OFFSET));
121
 
        }
122
 
 
123
 
        return(UNIV_UNLIKELY((page_no & (zip_size - 1))
124
 
                             == FSP_IBUF_BITMAP_OFFSET));
125
 
}
126
 
 
127
 
/*************************************************************************
128
 
Translates the free space on a page to a value in the ibuf bitmap.*/
129
 
UNIV_INLINE
130
 
ulint
131
 
ibuf_index_page_calc_free_bits(
132
 
/*===========================*/
133
 
                                /* out: value for ibuf bitmap bits */
134
 
        ulint   zip_size,       /* in: compressed page size in bytes;
135
 
                                0 for uncompressed pages */
136
 
        ulint   max_ins_size)   /* in: maximum insert size after reorganize
137
 
                                for the page */
138
 
{
139
 
        ulint   n;
140
 
        ut_ad(ut_is_2pow(zip_size));
141
 
        ut_ad(!zip_size || zip_size > IBUF_PAGE_SIZE_PER_FREE_SPACE);
142
 
        ut_ad(zip_size <= UNIV_PAGE_SIZE);
143
 
 
144
 
        if (zip_size) {
145
 
                n = max_ins_size
146
 
                        / (zip_size / IBUF_PAGE_SIZE_PER_FREE_SPACE);
147
 
        } else {
148
 
                n = max_ins_size
149
 
                        / (UNIV_PAGE_SIZE / IBUF_PAGE_SIZE_PER_FREE_SPACE);
150
 
        }
151
 
 
152
 
        if (n == 3) {
153
 
                n = 2;
154
 
        }
155
 
 
156
 
        if (n > 3) {
157
 
                n = 3;
158
 
        }
159
 
 
160
 
        return(n);
161
 
}
162
 
 
163
 
/*************************************************************************
164
 
Translates the ibuf free bits to the free space on a page in bytes. */
165
 
UNIV_INLINE
166
 
ulint
167
 
ibuf_index_page_calc_free_from_bits(
168
 
/*================================*/
169
 
                        /* out: maximum insert size after reorganize for the
170
 
                        page */
171
 
        ulint   zip_size,/* in: compressed page size in bytes;
172
 
                        0 for uncompressed pages */
173
 
        ulint   bits)   /* in: value for ibuf bitmap bits */
174
 
{
175
 
        ut_ad(bits < 4);
176
 
        ut_ad(ut_is_2pow(zip_size));
177
 
        ut_ad(!zip_size || zip_size > IBUF_PAGE_SIZE_PER_FREE_SPACE);
178
 
        ut_ad(zip_size <= UNIV_PAGE_SIZE);
179
 
 
180
 
        if (zip_size) {
181
 
                if (bits == 3) {
182
 
                        return(4 * zip_size / IBUF_PAGE_SIZE_PER_FREE_SPACE);
183
 
                }
184
 
 
185
 
                return(bits * zip_size / IBUF_PAGE_SIZE_PER_FREE_SPACE);
186
 
        }
187
 
 
188
 
        if (bits == 3) {
189
 
                return(4 * UNIV_PAGE_SIZE / IBUF_PAGE_SIZE_PER_FREE_SPACE);
190
 
        }
191
 
 
192
 
        return(bits * (UNIV_PAGE_SIZE / IBUF_PAGE_SIZE_PER_FREE_SPACE));
193
 
}
194
 
 
195
 
/*************************************************************************
196
 
Translates the free space on a compressed page to a value in the ibuf bitmap.*/
197
 
UNIV_INLINE
198
 
ulint
199
 
ibuf_index_page_calc_free_zip(
200
 
/*==========================*/
201
 
                                        /* out: value for ibuf bitmap bits */
202
 
        ulint                   zip_size,
203
 
                                        /* in: compressed page size in bytes */
204
 
        const buf_block_t*      block)  /* in: buffer block */
205
 
{
206
 
        ulint                   max_ins_size;
207
 
        const page_zip_des_t*   page_zip;
208
 
        lint                    zip_max_ins;
209
 
 
210
 
        ut_ad(zip_size == buf_block_get_zip_size(block));
211
 
        ut_ad(zip_size);
212
 
 
213
 
        max_ins_size = page_get_max_insert_size_after_reorganize(
214
 
                buf_block_get_frame(block), 1);
215
 
 
216
 
        page_zip = buf_block_get_page_zip(block);
217
 
        zip_max_ins = page_zip_max_ins_size(page_zip,
218
 
                                            FALSE/* not clustered */);
219
 
 
220
 
        if (UNIV_UNLIKELY(zip_max_ins < 0)) {
221
 
                return(0);
222
 
        } else if (UNIV_LIKELY(max_ins_size > (ulint) zip_max_ins)) {
223
 
                max_ins_size = (ulint) zip_max_ins;
224
 
        }
225
 
 
226
 
        return(ibuf_index_page_calc_free_bits(zip_size, max_ins_size));
227
 
}
228
 
 
229
 
/*************************************************************************
230
 
Translates the free space on a page to a value in the ibuf bitmap.*/
231
 
UNIV_INLINE
232
 
ulint
233
 
ibuf_index_page_calc_free(
234
 
/*======================*/
235
 
                                        /* out: value for ibuf bitmap bits */
236
 
        ulint                   zip_size,/* in: compressed page size in bytes;
237
 
                                        0 for uncompressed pages */
238
 
        const buf_block_t*      block)  /* in: buffer block */
239
 
{
240
 
        ut_ad(zip_size == buf_block_get_zip_size(block));
241
 
 
242
 
        if (!zip_size) {
243
 
                ulint   max_ins_size;
244
 
 
245
 
                max_ins_size = page_get_max_insert_size_after_reorganize(
246
 
                        buf_block_get_frame(block), 1);
247
 
 
248
 
                return(ibuf_index_page_calc_free_bits(0, max_ins_size));
249
 
        } else {
250
 
                return(ibuf_index_page_calc_free_zip(zip_size, block));
251
 
        }
252
 
}
253
 
 
254
 
/****************************************************************************
255
 
Updates the free bits of an uncompressed page in the ibuf bitmap if
256
 
there is not enough free on the page any more.  This is done in a
257
 
separate mini-transaction, hence this operation does not restrict
258
 
further work to only ibuf bitmap operations, which would result if the
259
 
latch to the bitmap page were kept.  NOTE: The free bits in the insert
260
 
buffer bitmap must never exceed the free space on a page.  It is
261
 
unsafe to increment the bits in a separately committed
262
 
mini-transaction, because in crash recovery, the free bits could
263
 
momentarily be set too high.  It is only safe to use this function for
264
 
decrementing the free bits.  Should more free space become available,
265
 
we must not update the free bits here, because that would break crash
266
 
recovery. */
267
 
UNIV_INLINE
268
 
void
269
 
ibuf_update_free_bits_if_full(
270
 
/*==========================*/
271
 
        buf_block_t*    block,  /* in: index page to which we have added new
272
 
                                records; the free bits are updated if the
273
 
                                index is non-clustered and non-unique and
274
 
                                the page level is 0, and the page becomes
275
 
                                fuller */
276
 
        ulint           max_ins_size,/* in: value of maximum insert size with
277
 
                                reorganize before the latest operation
278
 
                                performed to the page */
279
 
        ulint           increase)/* in: upper limit for the additional space
280
 
                                used in the latest operation, if known, or
281
 
                                ULINT_UNDEFINED */
282
 
{
283
 
        ulint   before;
284
 
        ulint   after;
285
 
 
286
 
        ut_ad(!buf_block_get_page_zip(block));
287
 
 
288
 
        before = ibuf_index_page_calc_free_bits(0, max_ins_size);
289
 
 
290
 
        if (max_ins_size >= increase) {
291
 
#if ULINT32_UNDEFINED <= UNIV_PAGE_SIZE
292
 
# error "ULINT32_UNDEFINED <= UNIV_PAGE_SIZE"
293
 
#endif
294
 
                after = ibuf_index_page_calc_free_bits(0, max_ins_size
295
 
                                                       - increase);
296
 
#ifdef UNIV_IBUF_DEBUG
297
 
                ut_a(after <= ibuf_index_page_calc_free(0, block));
298
 
#endif
299
 
        } else {
300
 
                after = ibuf_index_page_calc_free(0, block);
301
 
        }
302
 
 
303
 
        if (after == 0) {
304
 
                /* We move the page to the front of the buffer pool LRU list:
305
 
                the purpose of this is to prevent those pages to which we
306
 
                cannot make inserts using the insert buffer from slipping
307
 
                out of the buffer pool */
308
 
 
309
 
                buf_page_make_young(&block->page);
310
 
        }
311
 
 
312
 
        if (before > after) {
313
 
                ibuf_set_free_bits(block, after, before);
314
 
        }
315
 
}