24
24
*****************************************************************************/
26
/******************************************************
26
/**************************************************//**
27
28
The database buffer buf_pool
29
30
Created 11/5/1995 Heikki Tuuri
235
239
the read requests for the whole area.
238
/* Value in microseconds */
242
#ifndef UNIV_HOTBACKUP
243
/** Value in microseconds */
239
244
static const int WAIT_FOR_READ = 5000;
241
/* The buffer buf_pool of the database */
246
/** The buffer buf_pool of the database */
242
247
UNIV_INTERN buf_pool_t* buf_pool = NULL;
244
/* mutex protecting the buffer pool struct and control blocks, except the
249
/** mutex protecting the buffer pool struct and control blocks, except the
245
250
read-write lock in them */
246
251
UNIV_INTERN mutex_t buf_pool_mutex;
247
/* mutex protecting the control blocks of compressed-only pages
252
/** mutex protecting the control blocks of compressed-only pages
248
253
(of type buf_page_t, not buf_block_t) */
249
254
UNIV_INTERN mutex_t buf_pool_zip_mutex;
251
256
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
252
static ulint buf_dbg_counter = 0; /* This is used to insert validation
257
static ulint buf_dbg_counter = 0; /*!< This is used to insert validation
253
258
operations in excution in the
255
260
/** Flag to forbid the release of the buffer pool mutex.
257
262
UNIV_INTERN ulint buf_pool_mutex_exit_forbidden = 0;
258
263
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
259
264
#ifdef UNIV_DEBUG
260
/* If this is set TRUE, the program prints info whenever
265
/** If this is set TRUE, the program prints info whenever
261
266
read-ahead or flush occurs */
262
267
UNIV_INTERN ibool buf_debug_prints = FALSE;
263
268
#endif /* UNIV_DEBUG */
265
/* A chunk of buffers. The buffer pool is allocated in chunks. */
270
/** A chunk of buffers. The buffer pool is allocated in chunks. */
266
271
struct buf_chunk_struct{
267
ulint mem_size; /* allocated size of the chunk */
268
ulint size; /* size of frames[] and blocks[] */
269
void* mem; /* pointer to the memory area which
272
ulint mem_size; /*!< allocated size of the chunk */
273
ulint size; /*!< size of frames[] and blocks[] */
274
void* mem; /*!< pointer to the memory area which
270
275
was allocated for the frames */
271
buf_block_t* blocks; /* array of buffer control blocks */
276
buf_block_t* blocks; /*!< array of buffer control blocks */
278
#endif /* !UNIV_HOTBACKUP */
274
/************************************************************************
280
/********************************************************************//**
275
281
Calculates a page checksum which is stored to the page when it is written
276
282
to a file. Note that we must be careful to calculate the same value on
277
32-bit and 64-bit architectures. */
283
32-bit and 64-bit architectures.
280
287
buf_calc_page_new_checksum(
281
288
/*=======================*/
283
const byte* page) /* in: buffer page */
289
const byte* page) /*!< in: buffer page */
302
308
return(checksum);
305
/************************************************************************
311
/********************************************************************//**
306
312
In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
307
313
looked at the first few bytes of the page. This calculates that old
309
315
NOTE: we must first store the new formula checksum to
310
316
FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
311
because this takes that field as an input! */
317
because this takes that field as an input!
314
321
buf_calc_page_old_checksum(
315
322
/*=======================*/
317
const byte* page) /* in: buffer page */
323
const byte* page) /*!< in: buffer page */
325
331
return(checksum);
328
/************************************************************************
329
Checks if a page is corrupt. */
334
/********************************************************************//**
335
Checks if a page is corrupt.
336
@return TRUE if corrupted */
332
339
buf_page_is_corrupted(
333
340
/*==================*/
334
/* out: TRUE if corrupted */
335
const byte* read_buf, /* in: a database page */
336
ulint zip_size) /* in: size of compressed page;
341
const byte* read_buf, /*!< in: a database page */
342
ulint zip_size) /*!< in: size of compressed page;
337
343
0 for uncompressed pages */
339
345
ulint checksum_field;
340
346
ulint old_checksum_field;
341
#ifndef UNIV_HOTBACKUP
342
ib_uint64_t current_lsn;
344
348
if (UNIV_LIKELY(!zip_size)
345
349
&& memcmp(read_buf + FIL_PAGE_LSN + 4,
346
350
read_buf + UNIV_PAGE_SIZE
355
359
#ifndef UNIV_HOTBACKUP
356
if (recv_lsn_checks_on && log_peek_lsn(¤t_lsn)) {
357
if (current_lsn < mach_read_ull(read_buf + FIL_PAGE_LSN)) {
360
if (recv_lsn_checks_on) {
361
ib_uint64_t current_lsn;
363
if (log_peek_lsn(¤t_lsn)
364
&& current_lsn < mach_read_ull(read_buf + FIL_PAGE_LSN)) {
358
365
ut_print_timestamp(stderr);
366
373
"you may have copied the InnoDB\n"
367
374
"InnoDB: tablespace but not the InnoDB "
368
375
"log files. See\n"
369
"InnoDB: http://dev.mysql.com/doc/refman/"
370
"5.1/en/forcing-recovery.html\n"
376
"InnoDB: " REFMAN "forcing-recovery.html\n"
371
377
"InnoDB: for more information.\n",
372
378
(ulong) mach_read_from_4(read_buf
373
379
+ FIL_PAGE_OFFSET),
431
/************************************************************************
437
/********************************************************************//**
432
438
Prints a page to stderr. */
437
const byte* read_buf, /* in: a database page */
438
ulint zip_size) /* in: compressed page size, or
443
const byte* read_buf, /*!< in: a database page */
444
ulint zip_size) /*!< in: compressed page size, or
439
445
0 for uncompressed pages */
447
#ifndef UNIV_HOTBACKUP
441
448
dict_index_t* index;
449
#endif /* !UNIV_HOTBACKUP */
443
451
ulint old_checksum;
444
452
ulint size = zip_size;
572
582
btr_page_get_index_id(read_buf)),
573
583
(ulong) ut_dulint_get_low(
574
584
btr_page_get_index_id(read_buf)));
576
#ifdef UNIV_HOTBACKUP
577
/* If the code is in ibbackup, dict_sys may be uninitialized,
580
if (dict_sys == NULL) {
583
#endif /* UNIV_HOTBACKUP */
585
#ifndef UNIV_HOTBACKUP
585
586
index = dict_index_find_on_id_low(
586
587
btr_page_get_index_id(read_buf));
636
/************************************************************************
638
#ifndef UNIV_HOTBACKUP
639
/********************************************************************//**
637
640
Initializes a buffer control block when the buf_pool is created. */
642
buf_block_t* block, /* in: pointer to control block */
643
byte* frame) /* in: pointer to buffer frame */
645
buf_block_t* block, /*!< in: pointer to control block */
646
byte* frame) /*!< in: pointer to buffer frame */
645
648
UNIV_MEM_DESC(frame, UNIV_PAGE_SIZE, block);
682
685
#endif /* UNIV_SYNC_DEBUG */
685
/************************************************************************
686
Allocates a chunk of buffer frames. */
688
/********************************************************************//**
689
Allocates a chunk of buffer frames.
690
@return chunk, or NULL on failure */
691
/* out: chunk, or NULL on failure */
692
buf_chunk_t* chunk, /* out: chunk of buffers */
693
ulint mem_size) /* in: requested size in bytes */
695
buf_chunk_t* chunk, /*!< out: chunk of buffers */
696
ulint mem_size) /*!< in: requested size in bytes */
695
698
buf_block_t* block;
764
767
#ifdef UNIV_DEBUG
765
/*************************************************************************
768
/*********************************************************************//**
766
769
Finds a block in the given buffer chunk that points to a
767
given compressed page. */
770
given compressed page.
771
@return buffer block pointing to the compressed page, or NULL */
770
774
buf_chunk_contains_zip(
771
775
/*===================*/
772
/* out: buffer block pointing to
773
the compressed page, or NULL */
774
buf_chunk_t* chunk, /* in: chunk being checked */
775
const void* data) /* in: pointer to compressed page */
776
buf_chunk_t* chunk, /*!< in: chunk being checked */
777
const void* data) /*!< in: pointer to compressed page */
777
779
buf_block_t* block;
795
/*************************************************************************
797
/*********************************************************************//**
796
798
Finds a block in the buffer pool that points to a
797
given compressed page. */
799
given compressed page.
800
@return buffer block pointing to the compressed page, or NULL */
800
803
buf_pool_contains_zip(
801
804
/*==================*/
802
/* out: buffer block pointing to
803
the compressed page, or NULL */
804
const void* data) /* in: pointer to compressed page */
805
const void* data) /*!< in: pointer to compressed page */
807
808
buf_chunk_t* chunk = buf_pool->chunks;
819
820
#endif /* UNIV_DEBUG */
821
/*************************************************************************
822
Checks that all file pages in the buffer chunk are in a replaceable state. */
822
/*********************************************************************//**
823
Checks that all file pages in the buffer chunk are in a replaceable state.
824
@return address of a non-free block, or NULL if all freed */
824
826
const buf_block_t*
825
827
buf_chunk_not_freed(
826
828
/*================*/
827
/* out: address of a non-free block,
828
or NULL if all freed */
829
buf_chunk_t* chunk) /* in: chunk being checked */
829
buf_chunk_t* chunk) /*!< in: chunk being checked */
831
831
buf_block_t* block;
855
/*************************************************************************
856
Checks that all blocks in the buffer chunk are in BUF_BLOCK_NOT_USED state. */
855
/*********************************************************************//**
856
Checks that all blocks in the buffer chunk are in BUF_BLOCK_NOT_USED state.
857
@return TRUE if all freed */
859
860
buf_chunk_all_free(
860
861
/*===============*/
861
/* out: TRUE if all freed */
862
const buf_chunk_t* chunk) /* in: chunk being checked */
862
const buf_chunk_t* chunk) /*!< in: chunk being checked */
864
864
const buf_block_t* block;
883
/************************************************************************
883
/********************************************************************//**
884
884
Frees a chunk of buffer frames. */
889
buf_chunk_t* chunk) /* out: chunk of buffers */
889
buf_chunk_t* chunk) /*!< out: chunk of buffers */
891
891
buf_block_t* block;
892
892
const buf_block_t* block_end;
918
918
os_mem_free_large(chunk->mem, chunk->mem_size);
921
/************************************************************************
922
Creates the buffer pool. */
921
/********************************************************************//**
922
Creates the buffer pool.
923
@return own: buf_pool object, NULL if not enough memory or error */
925
926
buf_pool_init(void)
926
927
/*===============*/
927
/* out, own: buf_pool object, NULL if not
928
enough memory or error */
930
929
buf_chunk_t* chunk;
1007
1006
buf_pool->n_chunks = 0;
1011
/************************************************************************
1009
/********************************************************************//**
1012
1010
Drops the adaptive hash index. To prevent a livelock, this function
1013
1011
is only to be called while holding btr_search_latch and while
1014
1012
btr_search_enabled == FALSE. */
1089
1087
} while (released_search_latch);
1092
/************************************************************************
1090
/********************************************************************//**
1093
1091
Relocate a buffer control block. Relocates the block on the LRU list
1094
1092
and in buf_pool->page_hash. Does not relocate bpage->list.
1095
1093
The caller must take care of relocating bpage->list. */
1100
buf_page_t* bpage, /* in/out: control block being relocated;
1098
buf_page_t* bpage, /*!< in/out: control block being relocated;
1101
1099
buf_page_get_state(bpage) must be
1102
1100
BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */
1103
buf_page_t* dpage) /* in/out: destination control block */
1101
buf_page_t* dpage) /*!< in/out: destination control block */
1155
1153
#endif /* UNIV_LRU_DEBUG */
1158
ut_d(UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU));
1156
ut_d(UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU,
1157
ut_ad(ut_list_node_313->in_LRU_list)));
1160
1159
/* relocate buf_pool->page_hash */
1161
1160
fold = buf_page_address_fold(bpage->space, bpage->offset);
1166
1165
UNIV_MEM_INVALID(bpage, sizeof *bpage);
1169
/************************************************************************
1168
/********************************************************************//**
1170
1169
Shrinks the buffer pool. */
1173
1172
buf_pool_shrink(
1174
1173
/*============*/
1175
/* out: TRUE if shrunk */
1176
ulint chunk_size) /* in: number of pages to remove */
1174
ulint chunk_size) /*!< in: number of pages to remove */
1178
1176
buf_chunk_t* chunks;
1179
1177
buf_chunk_t* chunk;
1472
1470
buf_pool_page_hash_rebuild();
1475
/************************************************************************
1476
Moves to the block to the start of the LRU list if there is a danger
1473
/********************************************************************//**
1474
Moves the block to the start of the LRU list if there is a danger
1477
1475
that the block would drift out of the buffer pool. */
1480
1478
buf_block_make_young(
1481
1479
/*=================*/
1482
buf_page_t* bpage) /* in: block to make younger */
1480
buf_page_t* bpage) /*!< in: block to make younger */
1484
1482
ut_ad(!buf_pool_mutex_own());
1500
/************************************************************************
1498
/********************************************************************//**
1501
1499
Moves a page to the start of the buffer pool LRU list. This high-level
1502
1500
function can be used to prevent an important page from from slipping out of
1503
1501
the buffer pool. */
1516
1514
buf_pool_mutex_exit();
1519
/************************************************************************
1517
/********************************************************************//**
1520
1518
Resets the check_index_page_at_flush field of a page if found in the buffer
1524
1522
buf_reset_check_index_page_at_flush(
1525
1523
/*================================*/
1526
ulint space, /* in: space id */
1527
ulint offset) /* in: page number */
1524
ulint space, /*!< in: space id */
1525
ulint offset) /*!< in: page number */
1529
1527
buf_block_t* block;
1539
1537
buf_pool_mutex_exit();
1542
/************************************************************************
1540
/********************************************************************//**
1543
1541
Returns the current state of is_hashed of a page. FALSE if the page is
1544
1542
not in the pool. NOTE that this operation does not fix the page in the
1545
pool if it is found there. */
1543
pool if it is found there.
1544
@return TRUE if page hash index is built in search system */
1548
1547
buf_page_peek_if_search_hashed(
1549
1548
/*===========================*/
1550
/* out: TRUE if page hash index is built in search
1552
ulint space, /* in: space id */
1553
ulint offset) /* in: page number */
1549
ulint space, /*!< in: space id */
1550
ulint offset) /*!< in: page number */
1555
1552
buf_block_t* block;
1556
1553
ibool is_hashed;
1573
1570
#ifdef UNIV_DEBUG_FILE_ACCESSES
1574
/************************************************************************
1571
/********************************************************************//**
1575
1572
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
1576
1573
This function should be called when we free a file page and want the
1577
1574
debug version to check that it is not accessed any more unless
1576
@return control block if found in page hash table, otherwise NULL */
1581
1579
buf_page_set_file_page_was_freed(
1582
1580
/*=============================*/
1583
/* out: control block if found in page hash table,
1585
ulint space, /* in: space id */
1586
ulint offset) /* in: page number */
1581
ulint space, /*!< in: space id */
1582
ulint offset) /*!< in: page number */
1588
1584
buf_page_t* bpage;
1603
/************************************************************************
1599
/********************************************************************//**
1604
1600
Sets file_page_was_freed FALSE if the page is found in the buffer pool.
1605
1601
This function should be called when we free a file page and want the
1606
1602
debug version to check that it is not accessed any more unless
1604
@return control block if found in page hash table, otherwise NULL */
1610
1607
buf_page_reset_file_page_was_freed(
1611
1608
/*===============================*/
1612
/* out: control block if found in page hash table,
1614
ulint space, /* in: space id */
1615
ulint offset) /* in: page number */
1609
ulint space, /*!< in: space id */
1610
ulint offset) /*!< in: page number */
1617
1612
buf_page_t* bpage;
1631
1626
#endif /* UNIV_DEBUG_FILE_ACCESSES */
1633
/************************************************************************
1628
/********************************************************************//**
1634
1629
Get read access to a compressed page (usually of type
1635
1630
FIL_PAGE_TYPE_ZBLOB or FIL_PAGE_TYPE_ZBLOB2).
1636
1631
The page must be released with buf_page_release_zip().
1637
1632
NOTE: the page is not protected by any latch. Mutual exclusion has to
1638
1633
be implemented at a higher level. In other words, all possible
1639
1634
accesses to a given page through this function must be protected by
1640
the same set of mutexes or latches. */
1635
the same set of mutexes or latches.
1636
@return pointer to the block */
1643
1639
buf_page_get_zip(
1644
1640
/*=============*/
1645
/* out: pointer to the block */
1646
ulint space, /* in: space id */
1647
ulint zip_size,/* in: compressed page size */
1648
ulint offset) /* in: page number */
1641
ulint space, /*!< in: space id */
1642
ulint zip_size,/*!< in: compressed page size */
1643
ulint offset) /*!< in: page number */
1650
1645
buf_page_t* bpage;
1651
1646
mutex_t* block_mutex;
1678
1673
if (UNIV_UNLIKELY(!bpage->zip.data)) {
1679
1674
/* There is no compressed page. */
1680
1676
buf_pool_mutex_exit();
1684
block_mutex = buf_page_get_mutex(bpage);
1685
mutex_enter(block_mutex);
1687
1680
switch (buf_page_get_state(bpage)) {
1688
1681
case BUF_BLOCK_NOT_USED:
1689
1682
case BUF_BLOCK_READY_FOR_USE:
1690
1683
case BUF_BLOCK_MEMORY:
1691
1684
case BUF_BLOCK_REMOVE_HASH:
1692
1685
case BUF_BLOCK_ZIP_FREE:
1695
1687
case BUF_BLOCK_ZIP_PAGE:
1696
1688
case BUF_BLOCK_ZIP_DIRTY:
1689
block_mutex = &buf_pool_zip_mutex;
1690
mutex_enter(block_mutex);
1697
1691
bpage->buf_fix_count++;
1699
1693
case BUF_BLOCK_FILE_PAGE:
1694
block_mutex = &((buf_block_t*) bpage)->mutex;
1695
mutex_enter(block_mutex);
1700
1697
/* Discard the uncompressed page frame if possible. */
1701
1698
if (buf_LRU_free_block(bpage, FALSE, NULL)
1702
1699
== BUF_LRU_FREED) {
1760
/************************************************************************
1761
/********************************************************************//**
1761
1762
Initialize some fields of a control block. */
1764
1765
buf_block_init_low(
1765
1766
/*===============*/
1766
buf_block_t* block) /* in: block to init */
1767
buf_block_t* block) /*!< in: block to init */
1768
1769
block->check_index_page_at_flush = FALSE;
1769
1770
block->index = NULL;
1774
1775
block->n_bytes = 0;
1775
1776
block->left_side = TRUE;
1778
#endif /* !UNIV_HOTBACKUP */
1778
/************************************************************************
1779
Decompress a block. */
1780
/********************************************************************//**
1782
@return TRUE if successful */
1782
1785
buf_zip_decompress(
1783
1786
/*===============*/
1784
/* out: TRUE if successful */
1785
buf_block_t* block, /* in/out: block */
1786
ibool check) /* in: TRUE=verify the page checksum */
1787
buf_block_t* block, /*!< in/out: block */
1788
ibool check) /*!< in: TRUE=verify the page checksum */
1788
1790
const byte* frame = block->page.zip.data;
1844
/***********************************************************************
1845
Gets the block to whose frame the pointer is pointing to. */
1846
#ifndef UNIV_HOTBACKUP
1847
/*******************************************************************//**
1848
Gets the block to whose frame the pointer is pointing to.
1849
@return pointer to block, never NULL */
1848
1852
buf_block_align(
1849
1853
/*============*/
1850
/* out: pointer to block, never NULL */
1851
const byte* ptr) /* in: pointer to a frame */
1854
const byte* ptr) /*!< in: pointer to a frame */
1853
1856
buf_chunk_t* chunk;
1931
/************************************************************************
1932
Find out if a buffer block was created by buf_chunk_init(). */
1934
/********************************************************************//**
1935
Find out if a pointer belongs to a buf_block_t. It can be a pointer to
1936
the buf_block_t itself or a member of it
1937
@return TRUE if ptr belongs to a buf_block_t struct */
1940
buf_pointer_is_block_field(
1941
/*=======================*/
1942
const void* ptr) /*!< in: pointer not
1945
const buf_chunk_t* chunk = buf_pool->chunks;
1946
const buf_chunk_t* const echunk = chunk + buf_pool->n_chunks;
1948
/* TODO: protect buf_pool->chunks with a mutex (it will
1949
currently remain constant after buf_pool_init()) */
1950
while (chunk < echunk) {
1951
if (ptr >= (void *)chunk->blocks
1952
&& ptr < (void *)(chunk->blocks + chunk->size)) {
1963
/********************************************************************//**
1964
Find out if a buffer block was created by buf_chunk_init().
1965
@return TRUE if "block" has been added to buf_pool->free by buf_chunk_init() */
1935
1968
buf_block_is_uncompressed(
1936
1969
/*======================*/
1937
/* out: TRUE if "block" has
1938
been added to buf_pool->free
1939
by buf_chunk_init() */
1940
const buf_block_t* block) /* in: pointer to block,
1970
const buf_block_t* block) /*!< in: pointer to block,
1941
1971
not dereferenced */
1943
const buf_chunk_t* chunk = buf_pool->chunks;
1944
const buf_chunk_t* const echunk = chunk + buf_pool->n_chunks;
1946
1973
ut_ad(buf_pool_mutex_own());
1948
1975
if (UNIV_UNLIKELY((((ulint) block) % sizeof *block) != 0)) {
1953
while (chunk < echunk) {
1954
if (block >= chunk->blocks
1955
&& block < chunk->blocks + chunk->size) {
1980
return(buf_pointer_is_block_field((void *)block));
1966
/************************************************************************
1967
This is the general function used to get access to a database page. */
1983
/********************************************************************//**
1984
This is the general function used to get access to a database page.
1985
@return pointer to the block or NULL */
1970
1988
buf_page_get_gen(
1971
1989
/*=============*/
1972
/* out: pointer to the block or NULL */
1973
ulint space, /* in: space id */
1974
ulint zip_size,/* in: compressed page size in bytes
1990
ulint space, /*!< in: space id */
1991
ulint zip_size,/*!< in: compressed page size in bytes
1975
1992
or 0 for uncompressed pages */
1976
ulint offset, /* in: page number */
1977
ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
1978
buf_block_t* guess, /* in: guessed block or NULL */
1979
ulint mode, /* in: BUF_GET, BUF_GET_IF_IN_POOL,
1993
ulint offset, /*!< in: page number */
1994
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
1995
buf_block_t* guess, /*!< in: guessed block or NULL */
1996
ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
1980
1997
BUF_GET_NO_LATCH */
1981
const char* file, /* in: file name */
1982
ulint line, /* in: line where called */
1983
mtr_t* mtr) /* in: mini-transaction */
1998
const char* file, /*!< in: file name */
1999
ulint line, /*!< in: line where called */
2000
mtr_t* mtr) /*!< in: mini-transaction */
1985
2002
buf_block_t* block;
1986
2003
ibool accessed;
1995
2012
ut_ad((mode == BUF_GET) || (mode == BUF_GET_IF_IN_POOL)
1996
2013
|| (mode == BUF_GET_NO_LATCH));
1997
2014
ut_ad(zip_size == fil_space_get_zip_size(space));
2015
ut_ad(ut_is_2pow(zip_size));
1998
2016
#ifndef UNIV_LOG_DEBUG
1999
2017
ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
2068
2086
case BUF_BLOCK_ZIP_PAGE:
2069
2087
case BUF_BLOCK_ZIP_DIRTY:
2070
2088
bpage = &block->page;
2089
/* Protect bpage->buf_fix_count. */
2090
mutex_enter(&buf_pool_zip_mutex);
2072
2092
if (bpage->buf_fix_count
2073
2093
|| buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
2074
2094
/* This condition often occurs when the buffer
2075
2095
is not buffer-fixed, but I/O-fixed by
2076
2096
buf_page_init_for_read(). */
2097
mutex_exit(&buf_pool_zip_mutex);
2077
2098
wait_until_unfixed:
2078
2099
/* The block is buffer-fixed or I/O-fixed.
2079
2100
Try again later. */
2172
2194
block->page.buf_fix_count = 1;
2173
2195
buf_block_set_io_fix(block, BUF_IO_READ);
2196
rw_lock_x_lock(&block->lock);
2197
mutex_exit(&block->mutex);
2198
mutex_exit(&buf_pool_zip_mutex);
2174
2199
buf_pool->n_pend_unzip++;
2175
rw_lock_x_lock(&block->lock);
2176
mutex_exit(&block->mutex);
2177
mutex_exit(&buf_pool_zip_mutex);
2179
2201
buf_buddy_free(bpage, sizeof *bpage);
2192
2214
/* Unfix and unlatch the block. */
2193
2215
buf_pool_mutex_enter();
2194
2216
mutex_enter(&block->mutex);
2195
buf_pool->n_pend_unzip--;
2196
2217
block->page.buf_fix_count--;
2197
2218
buf_block_set_io_fix(block, BUF_IO_NONE);
2198
2219
mutex_exit(&block->mutex);
2220
buf_pool->n_pend_unzip--;
2199
2221
rw_lock_x_unlock(&block->lock);
2201
2223
if (UNIV_UNLIKELY(!success)) {
2301
/************************************************************************
2323
/********************************************************************//**
2302
2324
This is the general function used to get optimistic access to a database
2326
@return TRUE if success */
2306
2329
buf_page_optimistic_get_func(
2307
2330
/*=========================*/
2308
/* out: TRUE if success */
2309
ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
2310
buf_block_t* block, /* in: guessed buffer block */
2311
ib_uint64_t modify_clock,/* in: modify clock value if mode is
2331
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
2332
buf_block_t* block, /*!< in: guessed buffer block */
2333
ib_uint64_t modify_clock,/*!< in: modify clock value if mode is
2312
2334
..._GUESS_ON_CLOCK */
2313
const char* file, /* in: file name */
2314
ulint line, /* in: line where called */
2315
mtr_t* mtr) /* in: mini-transaction */
2335
const char* file, /*!< in: file name */
2336
ulint line, /*!< in: line where called */
2337
mtr_t* mtr) /*!< in: mini-transaction */
2317
2339
ibool accessed;
2411
/************************************************************************
2433
/********************************************************************//**
2412
2434
This is used to get access to a known database page, when no waiting can be
2413
2435
done. For example, if a search in an adaptive hash index leads us to this
2437
@return TRUE if success */
2417
2440
buf_page_get_known_nowait(
2418
2441
/*======================*/
2419
/* out: TRUE if success */
2420
ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
2421
buf_block_t* block, /* in: the known page */
2422
ulint mode, /* in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
2423
const char* file, /* in: file name */
2424
ulint line, /* in: line where called */
2425
mtr_t* mtr) /* in: mini-transaction */
2442
ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
2443
buf_block_t* block, /*!< in: the known page */
2444
ulint mode, /*!< in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
2445
const char* file, /*!< in: file name */
2446
ulint line, /*!< in: line where called */
2447
mtr_t* mtr) /*!< in: mini-transaction */
2428
2450
ulint fix_type;
2499
/***********************************************************************
2521
/*******************************************************************//**
2500
2522
Given a tablespace id and page number tries to get that page. If the
2501
2523
page is not in the buffer pool it is not loaded and NULL is returned.
2502
Suitable for using when holding the kernel mutex. */
2524
Suitable for using when holding the kernel mutex.
2525
@return pointer to a page or NULL */
2504
2527
const buf_block_t*
2505
2528
buf_page_try_get_func(
2506
2529
/*==================*/
2507
/* out: pointer to a page or NULL */
2508
ulint space_id,/* in: tablespace id */
2509
ulint page_no,/* in: page number */
2510
const char* file, /* in: file name */
2511
ulint line, /* in: line where called */
2512
mtr_t* mtr) /* in: mini-transaction */
2530
ulint space_id,/*!< in: tablespace id */
2531
ulint page_no,/*!< in: page number */
2532
const char* file, /*!< in: file name */
2533
ulint line, /*!< in: line where called */
2534
mtr_t* mtr) /*!< in: mini-transaction */
2514
2536
buf_block_t* block;
2580
/************************************************************************
2602
/********************************************************************//**
2581
2603
Initialize some fields of a control block. */
2584
2606
buf_page_init_low(
2585
2607
/*==============*/
2586
buf_page_t* bpage) /* in: block to init */
2608
buf_page_t* bpage) /*!< in: block to init */
2588
2610
bpage->flush_type = BUF_FLUSH_LRU;
2589
2611
bpage->accessed = FALSE;
2598
2620
#endif /* UNIV_DEBUG_FILE_ACCESSES */
2601
#ifdef UNIV_HOTBACKUP
2602
/************************************************************************
2603
Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
2606
buf_page_init_for_backup_restore(
2607
/*=============================*/
2608
ulint space, /* in: space id */
2609
ulint offset, /* in: offset of the page within space
2610
in units of a page */
2611
ulint zip_size,/* in: compressed page size in bytes
2612
or 0 for uncompressed pages */
2613
buf_block_t* block) /* in: block to init */
2615
buf_block_init_low(block);
2617
block->lock_hash_val = 0;
2619
buf_page_init_low(&block->page);
2620
block->page.state = BUF_BLOCK_FILE_PAGE;
2621
block->page.space = space;
2622
block->page.offset = offset;
2624
page_zip_des_init(&block->page.zip);
2626
/* We assume that block->page.data has been allocated
2627
with zip_size == UNIV_PAGE_SIZE. */
2628
ut_ad(zip_size <= UNIV_PAGE_SIZE);
2629
ut_ad(ut_is_2pow(zip_size));
2630
page_zip_set_size(&block->page.zip, zip_size);
2632
#endif /* UNIV_HOTBACKUP */
2634
/************************************************************************
2623
/********************************************************************//**
2635
2624
Inits a page to the buffer buf_pool. */
2640
ulint space, /* in: space id */
2641
ulint offset, /* in: offset of the page within space
2629
ulint space, /*!< in: space id */
2630
ulint offset, /*!< in: offset of the page within space
2642
2631
in units of a page */
2643
buf_block_t* block) /* in: block to init */
2632
buf_block_t* block) /*!< in: block to init */
2645
2634
buf_page_t* hash_page;
2695
2684
buf_page_address_fold(space, offset), &block->page);
2698
/************************************************************************
2687
/********************************************************************//**
2699
2688
Function which inits a page for read to the buffer buf_pool. If the page is
2700
2689
(1) already in buf_pool, or
2701
2690
(2) if we specify to read only ibuf pages and the page is not an ibuf page, or
2703
2692
then this function does nothing.
2704
2693
Sets the io_fix flag to BUF_IO_READ and sets a non-recursive exclusive lock
2705
2694
on the buffer frame. The io-handler must take care that the flag is cleared
2706
and the lock released later. */
2695
and the lock released later.
2696
@return pointer to the block or NULL */
2709
2699
buf_page_init_for_read(
2710
2700
/*===================*/
2711
/* out: pointer to the block or NULL */
2712
ulint* err, /* out: DB_SUCCESS or DB_TABLESPACE_DELETED */
2713
ulint mode, /* in: BUF_READ_IBUF_PAGES_ONLY, ... */
2714
ulint space, /* in: space id */
2715
ulint zip_size,/* in: compressed page size, or 0 */
2716
ibool unzip, /* in: TRUE=request uncompressed page */
2717
ib_int64_t tablespace_version,/* in: prevents reading from a wrong
2701
ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED */
2702
ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ... */
2703
ulint space, /*!< in: space id */
2704
ulint zip_size,/*!< in: compressed page size, or 0 */
2705
ibool unzip, /*!< in: TRUE=request uncompressed page */
2706
ib_int64_t tablespace_version,/*!< in: prevents reading from a wrong
2718
2707
version of the tablespace in case we have done
2719
2708
DISCARD + IMPORT */
2720
ulint offset) /* in: page number */
2709
ulint offset) /*!< in: page number */
2722
2711
buf_block_t* block;
2723
2712
buf_page_t* bpage;
2902
/************************************************************************
2891
/********************************************************************//**
2903
2892
Initializes a page to the buffer buf_pool. The page is usually not read
2904
2893
from a file even if it cannot be found in the buffer buf_pool. This is one
2905
2894
of the functions which perform to a block a state transition NOT_USED =>
2906
FILE_PAGE (the other is buf_page_get_gen). */
2895
FILE_PAGE (the other is buf_page_get_gen).
2896
@return pointer to the block, page bufferfixed */
2909
2899
buf_page_create(
2910
2900
/*============*/
2911
/* out: pointer to the block, page bufferfixed */
2912
ulint space, /* in: space id */
2913
ulint offset, /* in: offset of the page within space in units of
2901
ulint space, /*!< in: space id */
2902
ulint offset, /*!< in: offset of the page within space in units of
2915
ulint zip_size,/* in: compressed page size, or 0 */
2916
mtr_t* mtr) /* in: mini-transaction handle */
2904
ulint zip_size,/*!< in: compressed page size, or 0 */
2905
mtr_t* mtr) /*!< in: mini-transaction handle */
2918
2907
buf_frame_t* frame;
2919
2908
buf_block_t* block;
3044
/************************************************************************
3033
/********************************************************************//**
3045
3034
Completes an asynchronous read or write request of a file page to or from
3046
3035
the buffer pool. */
3049
3038
buf_page_io_complete(
3050
3039
/*=================*/
3051
buf_page_t* bpage) /* in: pointer to the block in question */
3040
buf_page_t* bpage) /*!< in: pointer to the block in question */
3053
3042
enum buf_io_fix io_type;
3054
3043
const ibool uncompressed = (buf_page_get_state(bpage)
3160
3149
" You can use CHECK\n"
3161
3150
"InnoDB: TABLE to scan your"
3162
3151
" table for corruption.\n"
3164
" http://dev.mysql.com/doc/refman/5.1/en/"
3165
"forcing-recovery.html\n"
3153
REFMAN "forcing-recovery.html\n"
3166
3154
"InnoDB: about forcing recovery.\n", stderr);
3168
3156
if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
3176
3164
if (recv_recovery_is_on()) {
3177
3165
/* Pages must be uncompressed for crash recovery. */
3178
3166
ut_a(uncompressed);
3179
recv_recover_page(FALSE, TRUE, (buf_block_t*) bpage);
3167
recv_recover_page(TRUE, (buf_block_t*) bpage);
3182
3170
if (uncompressed && !recv_no_ibuf_operations) {
3254
3242
buf_pool_mutex_exit();
3257
/*************************************************************************
3245
/*********************************************************************//**
3258
3246
Invalidates the file pages in the buffer pool when an archive recovery is
3259
3247
completed. All the file pages buffered must be in a replaceable state when
3260
3248
this function is called: not latched and not modified. */
3284
3272
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
3285
/*************************************************************************
3286
Validates the buffer buf_pool data structure. */
3273
/*********************************************************************//**
3274
Validates the buffer buf_pool data structure.
3289
3278
buf_validate(void)
3505
3494
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
3507
3496
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
3508
/*************************************************************************
3497
/*********************************************************************//**
3509
3498
Prints info of the buffer buf_pool data structure. */
3618
3607
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
3620
3609
#ifdef UNIV_DEBUG
3621
/*************************************************************************
3622
Returns the number of latched pages in the buffer pool. */
3610
/*********************************************************************//**
3611
Returns the number of latched pages in the buffer pool.
3612
@return number of latched pages */
3625
3615
buf_get_latched_pages_number(void)
3707
3697
#endif /* UNIV_DEBUG */
3709
/*************************************************************************
3710
Returns the number of pending buf pool ios. */
3699
/*********************************************************************//**
3700
Returns the number of pending buf pool ios.
3701
@return number of pending I/O operations */
3713
3704
buf_get_n_pending_ios(void)
3719
3710
+ buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
3722
/*************************************************************************
3713
/*********************************************************************//**
3723
3714
Returns the ratio in percents of modified pages in the buffer pool /
3724
database pages in the buffer pool. */
3715
database pages in the buffer pool.
3716
@return modified page percentage ratio */
3727
3719
buf_get_modified_ratio_pct(void)
3745
/*************************************************************************
3737
/*********************************************************************//**
3746
3738
Prints info of the buffer i/o. */
3751
FILE* file) /* in/out: buffer where to print */
3743
FILE* file) /*!< in/out: buffer where to print */
3753
3745
time_t current_time;
3754
3746
double time_elapsed;
3839
3831
buf_pool->n_pages_written_old = buf_pool->n_pages_written;
3842
/*************************************************************************
3843
Checks that all file pages in the buffer are in a replaceable state. */
3834
/*********************************************************************//**
3835
Asserts that all file pages in the buffer are in a replaceable state.
3846
3839
buf_all_freed(void)
3876
/*************************************************************************
3869
/*********************************************************************//**
3877
3870
Checks that there currently are no pending i/o-operations for the buffer
3872
@return TRUE if there is no pending i/o */
3881
3875
buf_pool_check_no_pending_io(void)
3882
3876
/*==============================*/
3883
/* out: TRUE if there is no pending i/o */
3902
/*************************************************************************
3903
Gets the current length of the free list of buffer blocks. */
3895
/*********************************************************************//**
3896
Gets the current length of the free list of buffer blocks.
3897
@return length of the free list */
3906
3900
buf_get_free_list_len(void)
3913
#else /* !UNIV_HOTBACKUP */
3914
/********************************************************************//**
3915
Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
3918
buf_page_init_for_backup_restore(
3919
/*=============================*/
3920
ulint space, /*!< in: space id */
3921
ulint offset, /*!< in: offset of the page within space
3922
in units of a page */
3923
ulint zip_size,/*!< in: compressed page size in bytes
3924
or 0 for uncompressed pages */
3925
buf_block_t* block) /*!< in: block to init */
3927
block->page.state = BUF_BLOCK_FILE_PAGE;
3928
block->page.space = space;
3929
block->page.offset = offset;
3931
page_zip_des_init(&block->page.zip);
3933
/* We assume that block->page.data has been allocated
3934
with zip_size == UNIV_PAGE_SIZE. */
3935
ut_ad(zip_size <= UNIV_PAGE_SIZE);
3936
ut_ad(ut_is_2pow(zip_size));
3937
page_zip_set_size(&block->page.zip, zip_size);
3939
block->page.zip.data = block->frame + UNIV_PAGE_SIZE;
3942
#endif /* !UNIV_HOTBACKUP */