~ubuntu-branches/ubuntu/natty/mysql-5.1/natty-proposed

« back to all changes in this revision

Viewing changes to storage/innodb_plugin/buf/buf0rea.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 08:30:45 UTC
  • mfrom: (1.4.1)
  • Revision ID: package-import@ubuntu.com-20120222083045-2rd53r4bnyx7qus4
Tags: 5.1.61-0ubuntu0.11.04.1
* SECURITY UPDATE: Update to 5.1.61 to fix multiple security issues
  (LP: #937869)
  - http://www.oracle.com/technetwork/topics/security/cpujan2012-366304.html
  - CVE-2011-2262
  - CVE-2012-0075
  - CVE-2012-0112
  - CVE-2012-0113
  - CVE-2012-0114
  - CVE-2012-0115
  - CVE-2012-0116
  - CVE-2012-0117
  - CVE-2012-0118
  - CVE-2012-0119
  - CVE-2012-0120
  - CVE-2012-0484
  - CVE-2012-0485
  - CVE-2012-0486
  - CVE-2012-0487
  - CVE-2012-0488
  - CVE-2012-0489
  - CVE-2012-0490
  - CVE-2012-0491
  - CVE-2012-0492
  - CVE-2012-0493
  - CVE-2012-0494
  - CVE-2012-0495
  - CVE-2012-0496

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#include "srv0start.h"
39
39
#include "srv0srv.h"
40
40
 
 
41
/** The size in blocks of the area where the random read-ahead algorithm counts
 
42
the accessed pages when deciding whether to read-ahead */
 
43
#define BUF_READ_AHEAD_RANDOM_AREA      BUF_READ_AHEAD_AREA
 
44
 
 
45
/** There must be at least this many pages in buf_pool in the area to start
 
46
a random read-ahead */
 
47
#define BUF_READ_AHEAD_RANDOM_THRESHOLD (5 + BUF_READ_AHEAD_RANDOM_AREA / 8)
 
48
 
41
49
/** The linear read-ahead area size */
42
50
#define BUF_READ_AHEAD_LINEAR_AREA      BUF_READ_AHEAD_AREA
43
51
 
158
166
}
159
167
 
160
168
/********************************************************************//**
 
169
Applies a random read-ahead in buf_pool if there are at least a threshold
 
170
value of accessed pages from the random read-ahead area. Does not read any
 
171
page, not even the one at the position (space, offset), if the read-ahead
 
172
mechanism is not activated. NOTE 1: the calling thread may own latches on
 
173
pages: to avoid deadlocks this function must be written such that it cannot
 
174
end up waiting for these latches! NOTE 2: the calling thread must want
 
175
access to the page given: this rule is set to prevent unintended read-aheads
 
176
performed by ibuf routines, a situation which could result in a deadlock if
 
177
the OS does not support asynchronous i/o.
 
178
@return number of page read requests issued; NOTE that if we read ibuf
 
179
pages, it may happen that the page at the given page number does not
 
180
get read even if we return a positive value! */
 
181
static
 
182
ulint
 
183
buf_read_ahead_random(
 
184
/*==================*/
 
185
        ulint   space,  /*!< in: space id */
 
186
        ulint   zip_size,/*!< in: compressed page size in bytes, or 0 */
 
187
        ulint   offset) /*!< in: page number of a page which the current thread
 
188
                        wants to access */
 
189
{
 
190
        ib_int64_t      tablespace_version;
 
191
        ulint           recent_blocks   = 0;
 
192
        ulint           count;
 
193
        ulint           ibuf_mode;
 
194
        ulint           low, high;
 
195
        ulint           err;
 
196
        ulint           i;
 
197
        ulint           buf_read_ahead_random_area;
 
198
 
 
199
        if (!srv_random_read_ahead) {
 
200
                /* Disabled by user */
 
201
                return(0);
 
202
        }
 
203
 
 
204
        if (srv_startup_is_before_trx_rollback_phase) {
 
205
                /* No read-ahead to avoid thread deadlocks */
 
206
                return(0);
 
207
        }
 
208
 
 
209
        if (ibuf_bitmap_page(zip_size, offset)
 
210
            || trx_sys_hdr_page(space, offset)) {
 
211
 
 
212
                /* If it is an ibuf bitmap page or trx sys hdr, we do
 
213
                no read-ahead, as that could break the ibuf page access
 
214
                order */
 
215
 
 
216
                return(0);
 
217
        }
 
218
 
 
219
        /* Remember the tablespace version before we ask the tablespace size
 
220
        below: if DISCARD + IMPORT changes the actual .ibd file meanwhile, we
 
221
        do not try to read outside the bounds of the tablespace! */
 
222
 
 
223
        tablespace_version = fil_space_get_version(space);
 
224
 
 
225
        buf_read_ahead_random_area = BUF_READ_AHEAD_RANDOM_AREA;
 
226
 
 
227
        low  = (offset / buf_read_ahead_random_area)
 
228
                * buf_read_ahead_random_area;
 
229
        high = (offset / buf_read_ahead_random_area + 1)
 
230
                * buf_read_ahead_random_area;
 
231
        if (high > fil_space_get_size(space)) {
 
232
 
 
233
                high = fil_space_get_size(space);
 
234
        }
 
235
 
 
236
        buf_pool_mutex_enter();
 
237
 
 
238
        if (buf_pool->n_pend_reads
 
239
            > buf_pool->curr_size / BUF_READ_AHEAD_PEND_LIMIT) {
 
240
                buf_pool_mutex_exit();
 
241
 
 
242
                return(0);
 
243
        }
 
244
 
 
245
        /* Count how many blocks in the area have been recently accessed,
 
246
        that is, reside near the start of the LRU list. */
 
247
 
 
248
        for (i = low; i < high; i++) {
 
249
                const buf_page_t*       bpage = buf_page_hash_get(space, i);
 
250
 
 
251
                if (bpage
 
252
                    && buf_page_is_accessed(bpage)
 
253
                    && buf_page_peek_if_young(bpage)) {
 
254
 
 
255
                        recent_blocks++;
 
256
 
 
257
                        if (recent_blocks >= BUF_READ_AHEAD_RANDOM_THRESHOLD) {
 
258
 
 
259
                                buf_pool_mutex_exit();
 
260
                                goto read_ahead;
 
261
                        }
 
262
                }
 
263
        }
 
264
 
 
265
        buf_pool_mutex_exit();
 
266
        /* Do nothing */
 
267
        return(0);
 
268
 
 
269
read_ahead:
 
270
        /* Read all the suitable blocks within the area */
 
271
 
 
272
        if (ibuf_inside()) {
 
273
                ibuf_mode = BUF_READ_IBUF_PAGES_ONLY;
 
274
        } else {
 
275
                ibuf_mode = BUF_READ_ANY_PAGE;
 
276
        }
 
277
 
 
278
        count = 0;
 
279
 
 
280
        for (i = low; i < high; i++) {
 
281
                /* It is only sensible to do read-ahead in the non-sync aio
 
282
                mode: hence FALSE as the first parameter */
 
283
 
 
284
                if (!ibuf_bitmap_page(zip_size, i)) {
 
285
                        count += buf_read_page_low(
 
286
                                &err, FALSE,
 
287
                                ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
 
288
                                space, zip_size, FALSE,
 
289
                                tablespace_version, i);
 
290
                        if (err == DB_TABLESPACE_DELETED) {
 
291
                                ut_print_timestamp(stderr);
 
292
                                fprintf(stderr,
 
293
                                        "  InnoDB: Warning: in random"
 
294
                                        " readahead trying to access\n"
 
295
                                        "InnoDB: tablespace %lu page %lu,\n"
 
296
                                        "InnoDB: but the tablespace does not"
 
297
                                        " exist or is just being dropped.\n",
 
298
                                        (ulong) space, (ulong) i);
 
299
                        }
 
300
                }
 
301
        }
 
302
 
 
303
        /* In simulated aio we wake the aio handler threads only after
 
304
        queuing all aio requests, in native aio the following call does
 
305
        nothing: */
 
306
 
 
307
        os_aio_simulated_wake_handler_threads();
 
308
 
 
309
#ifdef UNIV_DEBUG
 
310
        if (buf_debug_prints && (count > 0)) {
 
311
                fprintf(stderr,
 
312
                        "Random read-ahead space %lu offset %lu pages %lu\n",
 
313
                        (ulong) space, (ulong) offset,
 
314
                        (ulong) count);
 
315
        }
 
316
#endif /* UNIV_DEBUG */
 
317
 
 
318
        /* Read ahead is considered one I/O operation for the purpose of
 
319
        LRU policy decision. */
 
320
        buf_LRU_stat_inc_io();
 
321
 
 
322
        buf_pool->stat.n_ra_pages_read_rnd += count;
 
323
        return(count);
 
324
}
 
325
 
 
326
 
 
327
/********************************************************************//**
161
328
High-level function which reads a page asynchronously from a file to the
162
329
buffer buf_pool if it is not already there. Sets the io_fix flag and sets
163
330
an exclusive lock on the buffer frame. The flag is cleared and the x-lock
175
342
        ulint           count;
176
343
        ulint           err;
177
344
 
 
345
        count = buf_read_ahead_random(space, zip_size, offset);
 
346
        srv_buf_pool_reads += count;
 
347
 
178
348
        tablespace_version = fil_space_get_version(space);
179
349
 
180
350
        /* We do the i/o in the synchronous aio mode to save thread