1
/* Innobase relational database engine; Copyright (C) 2001 Innobase Oy
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License 2
5
as published by the Free Software Foundation in June 1991.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License 2
13
along with this program (in file COPYING); if not, write to the Free
14
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
15
/******************************************************
16
The database buffer pool high-level routines
20
Created 11/5/1995 Heikki Tuuri
21
*******************************************************/
28
#include "mtr0types.h"
29
#include "buf0types.h"
31
#include "hash0hash.h"
34
/* Flags for flush types */
35
#define BUF_FLUSH_LRU 1
36
#define BUF_FLUSH_SINGLE_PAGE 2
37
#define BUF_FLUSH_LIST 3 /* An array in the pool struct
38
has size BUF_FLUSH_LIST + 1: if you
39
add more flush types, put them in
41
/* Modes for buf_page_get_gen */
42
#define BUF_GET 10 /* get always */
43
#define BUF_GET_IF_IN_POOL 11 /* get if in pool */
44
#define BUF_GET_NOWAIT 12 /* get if can set the latch without
46
#define BUF_GET_NO_LATCH 14 /* get and bufferfix, but set no latch;
47
we have separated this case, because
48
it is error-prone programming not to
49
set a latch, and it should be used
51
/* Modes for buf_page_get_known_nowait */
52
#define BUF_MAKE_YOUNG 51
53
#define BUF_KEEP_OLD 52
55
extern buf_pool_t* buf_pool; /* The buffer pool of the database */
56
extern ibool buf_debug_prints;/* If this is set TRUE, the program
57
prints info whenever read or flush
60
/************************************************************************
61
Initializes the buffer pool of the database. */
66
ulint max_size, /* in: maximum size of the pool in blocks */
67
ulint curr_size); /* in: current size to use, must be <=
69
/*************************************************************************
70
Gets the current size of buffer pool in bytes. */
73
buf_pool_get_curr_size(void);
74
/*========================*/
75
/* out: size in bytes */
76
/*************************************************************************
77
Gets the maximum size of buffer pool in bytes. */
80
buf_pool_get_max_size(void);
81
/*=======================*/
82
/* out: size in bytes */
83
/************************************************************************
84
Gets the smallest oldest_modification lsn for any page in the pool. Returns
85
ut_dulint_zero if all modified pages have been flushed to disk. */
88
buf_pool_get_oldest_modification(void);
89
/*==================================*/
90
/* out: oldest modification in pool,
91
ut_dulint_zero if none */
92
/*************************************************************************
93
Allocates a buffer frame. */
96
buf_frame_alloc(void);
97
/*==================*/
98
/* out: buffer frame */
99
/*************************************************************************
100
Frees a buffer frame which does not contain a file page. */
105
buf_frame_t* frame); /* in: buffer frame */
106
/*************************************************************************
107
Copies contents of a buffer frame to a given buffer. */
113
byte* buf, /* in: buffer to copy to */
114
buf_frame_t* frame); /* in: buffer frame */
115
/******************************************************************
116
NOTE! The following macros should be used instead of buf_page_get_gen,
117
to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed
119
#ifdef UNIV_SYNC_DEBUG
120
#define buf_page_get(SP, OF, LA, MTR) buf_page_get_gen(\
122
BUF_GET, __FILE__, __LINE__, MTR)
124
#define buf_page_get(SP, OF, LA, MTR) buf_page_get_gen(\
128
/******************************************************************
129
Use these macros to bufferfix a page with no latching. Remember not to
130
read the contents of the page unless you know it is safe. Do not modify
131
the contents of the page! We have separated this case, because it is
132
error-prone programming not to set a latch, and it should be used
134
#ifdef UNIV_SYNC_DEBUG
135
#define buf_page_get_with_no_latch(SP, OF, MTR) buf_page_get_gen(\
136
SP, OF, RW_NO_LATCH, NULL,\
137
BUF_GET_NO_LATCH, __FILE__, __LINE__, MTR)
139
#define buf_page_get_with_no_latch(SP, OF, MTR) buf_page_get_gen(\
140
SP, OF, RW_NO_LATCH, NULL,\
141
BUF_GET_NO_LATCH, MTR)
143
/******************************************************************
144
NOTE! The following macros should be used instead of buf_page_get_gen, to
145
improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed as LA! */
146
#ifdef UNIV_SYNC_DEBUG
147
#define buf_page_get_nowait(SP, OF, LA, MTR) buf_page_get_gen(\
149
BUF_GET_NOWAIT, __FILE__, __LINE__, MTR)
151
#define buf_page_get_nowait(SP, OF, LA, MTR) buf_page_get_gen(\
155
/******************************************************************
156
NOTE! The following macros should be used instead of
157
buf_page_optimistic_get_func, to improve debugging. Only values RW_S_LATCH and
158
RW_X_LATCH are allowed as LA! */
159
#ifdef UNIV_SYNC_DEBUG
160
#define buf_page_optimistic_get(LA, G, MC, MTR) buf_page_optimistic_get_func(\
161
LA, G, MC, __FILE__, __LINE__, MTR)
163
#define buf_page_optimistic_get(LA, G, MC, MTR) buf_page_optimistic_get_func(\
166
/************************************************************************
167
This is the general function used to get optimistic access to a database
171
buf_page_optimistic_get_func(
172
/*=========================*/
173
/* out: TRUE if success */
174
ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
175
buf_frame_t* guess, /* in: guessed frame */
176
dulint modify_clock,/* in: modify clock value if mode is
177
..._GUESS_ON_CLOCK */
178
#ifdef UNIV_SYNC_DEBUG
179
char* file, /* in: file name */
180
ulint line, /* in: line where called */
182
mtr_t* mtr); /* in: mini-transaction */
183
/************************************************************************
184
Tries to get the page, but if file io is required, releases all latches
185
in mtr down to the given savepoint. If io is required, this function
186
retrieves the page to buffer buf_pool, but does not bufferfix it or latch
190
buf_page_get_release_on_io(
191
/*=======================*/
192
/* out: pointer to the frame, or NULL
193
if not in buffer buf_pool */
194
ulint space, /* in: space id */
195
ulint offset, /* in: offset of the page within space
196
in units of a page */
197
buf_frame_t* guess, /* in: guessed frame or NULL */
198
ulint rw_latch, /* in: RW_X_LATCH, RW_S_LATCH,
200
ulint savepoint, /* in: mtr savepoint */
201
mtr_t* mtr); /* in: mtr */
202
/************************************************************************
203
This is used to get access to a known database page, when no waiting can be
207
buf_page_get_known_nowait(
208
/*======================*/
209
/* out: TRUE if success */
210
ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */
211
buf_frame_t* guess, /* in: the known page frame */
212
ulint mode, /* in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
213
#ifdef UNIV_SYNC_DEBUG
214
char* file, /* in: file name */
215
ulint line, /* in: line where called */
217
mtr_t* mtr); /* in: mini-transaction */
218
/************************************************************************
219
This is the general function used to get access to a database page. */
224
/* out: pointer to the frame or NULL */
225
ulint space, /* in: space id */
226
ulint offset, /* in: page number */
227
ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
228
buf_frame_t* guess, /* in: guessed frame or NULL */
229
ulint mode, /* in: BUF_GET, BUF_GET_IF_IN_POOL,
231
#ifdef UNIV_SYNC_DEBUG
232
char* file, /* in: file name */
233
ulint line, /* in: line where called */
235
mtr_t* mtr); /* in: mini-transaction */
236
/************************************************************************
237
Initializes a page to the buffer buf_pool. The page is usually not read
238
from a file even if it cannot be found in the buffer buf_pool. This is one
239
of the functions which perform to a block a state transition NOT_USED =>
240
FILE_PAGE (the other is buf_page_init_for_read above). */
245
/* out: pointer to the frame, page bufferfixed */
246
ulint space, /* in: space id */
247
ulint offset, /* in: offset of the page within space in units of
249
mtr_t* mtr); /* in: mini-transaction handle */
250
/************************************************************************
251
Decrements the bufferfix count of a buffer control block and releases
252
a latch, if specified. */
257
buf_block_t* block, /* in: buffer block */
258
ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH,
260
mtr_t* mtr); /* in: mtr */
261
/************************************************************************
262
Moves a page to the start of the buffer pool LRU list. This high-level
263
function can be used to prevent an important page from from slipping out of
268
/*=================*/
269
buf_frame_t* frame); /* in: buffer frame of a file page */
270
/************************************************************************
271
Returns TRUE if the page can be found in the buffer pool hash table. NOTE
272
that it is possible that the page is not yet read from disk, though. */
277
/* out: TRUE if found from page hash table,
278
NOTE that the page is not necessarily yet read
280
ulint space, /* in: space id */
281
ulint offset);/* in: page number */
282
/************************************************************************
283
Returns the buffer control block if the page can be found in the buffer
284
pool. NOTE that it is possible that the page is not yet read
285
from disk, though. This is a very low-level function: use with care! */
290
/* out: control block if found from page hash table,
291
otherwise NULL; NOTE that the page is not necessarily
292
yet read from disk! */
293
ulint space, /* in: space id */
294
ulint offset);/* in: page number */
295
/************************************************************************
296
Recommends a move of a block to the start of the LRU list if there is danger
297
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
301
buf_block_peek_if_too_old(
302
/*======================*/
303
/* out: TRUE if should be made younger */
304
buf_block_t* block); /* in: block to make younger */
305
/************************************************************************
306
Returns the current state of is_hashed of a page. FALSE if the page is
307
not in the pool. NOTE that this operation does not fix the page in the
308
pool if it is found there. */
311
buf_page_peek_if_search_hashed(
312
/*===========================*/
313
/* out: TRUE if page hash index is built in search
315
ulint space, /* in: space id */
316
ulint offset);/* in: page number */
317
/************************************************************************
318
Gets the youngest modification log sequence number for a frame.
319
Returns zero if not file page or no modification occurred yet. */
322
buf_frame_get_newest_modification(
323
/*==============================*/
324
/* out: newest modification to page */
325
buf_frame_t* frame); /* in: pointer to a frame */
326
/************************************************************************
327
Increments the modify clock of a frame by 1. The caller must (1) own the
328
pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
332
buf_frame_modify_clock_inc(
333
/*=======================*/
335
buf_frame_t* frame); /* in: pointer to a frame */
336
/************************************************************************
337
Returns the value of the modify clock. The caller must have an s-lock
338
or x-lock on the block. */
341
buf_frame_get_modify_clock(
342
/*=======================*/
344
buf_frame_t* frame); /* in: pointer to a frame */
345
/**************************************************************************
346
Gets the page number of a pointer pointing within a buffer frame containing
350
buf_frame_get_page_no(
351
/*==================*/
352
/* out: page number */
353
byte* ptr); /* in: pointer to within a buffer frame */
354
/**************************************************************************
355
Gets the space id of a pointer pointing within a buffer frame containing a
359
buf_frame_get_space_id(
360
/*===================*/
362
byte* ptr); /* in: pointer to within a buffer frame */
363
/**************************************************************************
364
Gets the space id, page offset, and byte offset within page of a
365
pointer pointing to a buffer frame containing a file page. */
368
buf_ptr_get_fsp_addr(
369
/*=================*/
370
byte* ptr, /* in: pointer to a buffer frame */
371
ulint* space, /* out: space id */
372
fil_addr_t* addr); /* out: page offset and byte offset */
373
/**************************************************************************
374
Gets the hash value of the page the pointer is pointing to. This can be used
375
in searches in the lock hash table. */
378
buf_frame_get_lock_hash_val(
379
/*========================*/
380
/* out: lock hash value */
381
byte* ptr); /* in: pointer to within a buffer frame */
382
/**************************************************************************
383
Gets the mutex number protecting the page record lock hash chain in the lock
387
buf_frame_get_lock_mutex(
388
/*=====================*/
390
byte* ptr); /* in: pointer to within a buffer frame */
391
/***********************************************************************
392
Gets the frame the pointer is pointing to. */
397
/* out: pointer to block */
398
byte* ptr); /* in: pointer to a frame */
399
/***********************************************************************
400
Checks if a pointer points to the block array of the buffer pool (blocks, not
406
/* out: TRUE if pointer to block */
407
void* ptr); /* in: pointer to memory */
408
/*************************************************************************
409
Validates the buffer pool data structure. */
414
/*************************************************************************
415
Prints info of the buffer pool data structure. */
420
/*************************************************************************
421
Prints info of the buffer i/o. */
426
/*************************************************************************
427
Checks that all file pages in the buffer are in a replaceable state. */
432
/*************************************************************************
433
Checks that there currently are no pending i/o-operations for the buffer
437
buf_pool_check_no_pending_io(void);
438
/*==============================*/
439
/* out: TRUE if there is no pending i/o */
440
/*************************************************************************
441
Invalidates the file pages in the buffer pool when an archive recovery is
442
completed. All the file pages buffered must be in a replaceable state when
443
this function is called: not latched and not modified. */
446
buf_pool_invalidate(void);
447
/*=====================*/
449
/*========================================================================
450
--------------------------- LOWER LEVEL ROUTINES -------------------------
451
=========================================================================*/
453
/*************************************************************************
454
Adds latch level info for the rw-lock protecting the buffer frame. This
455
should be called in the debug version after a successful latching of a
456
page if we know the latching order level of the acquired latch. If
457
UNIV_SYNC_DEBUG is not defined, compiles to an empty function. */
460
buf_page_dbg_add_level(
461
/*===================*/
462
buf_frame_t* frame, /* in: buffer page where we have acquired
464
ulint level); /* in: latching order level */
465
/*************************************************************************
466
Gets a pointer to the memory frame of a block. */
471
/* out: pointer to the frame */
472
buf_block_t* block); /* in: pointer to the control block */
473
/*************************************************************************
474
Gets the space id of a block. */
480
buf_block_t* block); /* in: pointer to the control block */
481
/*************************************************************************
482
Gets the page number of a block. */
485
buf_block_get_page_no(
486
/*==================*/
487
/* out: page number */
488
buf_block_t* block); /* in: pointer to the control block */
489
/***********************************************************************
490
Gets the block to whose frame the pointer is pointing to. */
495
/* out: pointer to block */
496
byte* ptr); /* in: pointer to a frame */
497
/************************************************************************
498
This function is used to get info if there is an io operation
499
going on on a buffer page. */
504
/* out: TRUE if io going on */
505
buf_block_t* block); /* in: pool block, must be bufferfixed */
506
/***********************************************************************
507
Accessor function for block array. */
510
buf_pool_get_nth_block(
511
/*===================*/
512
/* out: pointer to block */
513
buf_pool_t* pool, /* in: pool */
514
ulint i); /* in: index of the block */
515
/************************************************************************
516
Function which inits a page for read to the buffer buf_pool. If the page is
517
already in buf_pool, does nothing. Sets the io_fix flag to BUF_IO_READ and
518
sets a non-recursive exclusive lock on the buffer frame. The io-handler must
519
take care that the flag is cleared and the lock released later. This is one
520
of the functions which perform the state transition NOT_USED => FILE_PAGE to
521
a block (the other is buf_page_create). */
524
buf_page_init_for_read(
525
/*===================*/
526
/* out: pointer to the block */
527
ulint mode, /* in: BUF_READ_IBUF_PAGES_ONLY, ... */
528
ulint space, /* in: space id */
529
ulint offset);/* in: page number */
530
/************************************************************************
531
Completes an asynchronous read or write request of a file page to or from
535
buf_page_io_complete(
536
/*=================*/
537
buf_block_t* block); /* in: pointer to the block in question */
538
/************************************************************************
539
Calculates a folded value of a file page address to use in the page hash
543
buf_page_address_fold(
544
/*==================*/
545
/* out: the folded value */
546
ulint space, /* in: space id */
547
ulint offset);/* in: offset of the page within space */
548
/**********************************************************************
549
Returns the control block of a file page, NULL if not found. */
554
/* out: block, NULL if not found */
555
ulint space, /* in: space id */
556
ulint offset);/* in: offset of the page within space */
557
/***********************************************************************
558
Increments the pool clock by one and returns its new value. Remember that
559
in the 32 bit version the clock wraps around at 4 billion! */
562
buf_pool_clock_tic(void);
563
/*====================*/
564
/* out: new clock value */
565
/*************************************************************************
566
Gets the current length of the free list of buffer blocks. */
569
buf_get_free_list_len(void);
570
/*=======================*/
574
/* The buffer control block structure */
576
struct buf_block_struct{
578
/* 1. General fields */
580
ulint state; /* state of the control block:
581
BUF_BLOCK_NOT_USED, ... */
582
byte* frame; /* pointer to buffer frame which
583
is of size UNIV_PAGE_SIZE, and
584
aligned to an address divisible by
586
ulint space; /* space id of the page */
587
ulint offset; /* page number within the space */
588
ulint lock_hash_val; /* hashed value of the page address
589
in the record lock hash table */
590
mutex_t* lock_mutex; /* mutex protecting the chain in the
591
record lock hash table */
592
rw_lock_t lock; /* read-write lock of the buffer
594
rw_lock_t read_lock; /* rw-lock reserved when a page read
595
to the frame is requested; a thread
596
can wait for this rw-lock if it wants
597
to wait for the read to complete;
598
the usual way is to wait for lock,
599
but if the thread just wants a
600
bufferfix and no latch on the page,
601
then it can wait for this rw-lock */
602
buf_block_t* hash; /* node used in chaining to the page
604
/* 2. Page flushing fields */
606
UT_LIST_NODE_T(buf_block_t) flush_list;
607
/* node of the modified, not yet
608
flushed blocks list */
609
dulint newest_modification;
610
/* log sequence number of the youngest
611
modification to this block, zero if
613
dulint oldest_modification;
614
/* log sequence number of the START of
615
the log entry written of the oldest
616
modification to this block which has
617
not yet been flushed on disk; zero if
618
all modifications are on disk */
619
ulint flush_type; /* if this block is currently being
620
flushed to disk, this tells the
621
flush_type: BUF_FLUSH_LRU or
624
/* 3. LRU replacement algorithm fields */
626
UT_LIST_NODE_T(buf_block_t) free;
627
/* node of the free block list */
628
UT_LIST_NODE_T(buf_block_t) LRU;
629
/* node of the LRU list */
630
ulint LRU_position; /* value which monotonically
631
decreases (or may stay constant if
632
the block is in the old blocks) toward
633
the end of the LRU list, if the pool
634
ulint_clock has not wrapped around:
635
NOTE that this value can only be used
636
in heuristic algorithms, because of
637
the possibility of a wrap-around! */
638
ulint freed_page_clock;/* the value of freed_page_clock
639
buffer pool when this block was
640
last time put to the head of the
642
ibool old; /* TRUE if the block is in the old
643
blocks in the LRU list */
644
ibool accessed; /* TRUE if the page has been accessed
645
while in the buffer pool: read-ahead
646
may read in pages which have not been
648
ulint buf_fix_count; /* count of how manyfold this block
649
is currently bufferfixed */
650
ulint io_fix; /* if a read is pending to the frame,
651
io_fix is BUF_IO_READ, in the case
652
of a write BUF_IO_WRITE, otherwise 0 */
653
/* 4. Optimistic search field */
655
dulint modify_clock; /* this clock is incremented every
656
time a pointer to a record on the
657
page may become obsolete; this is
658
used in the optimistic cursor
659
positioning: if the modify clock has
660
not changed, we know that the pointer
661
is still valid; this field may be
662
changed if the thread (1) owns the
663
pool mutex and the page is not
664
bufferfixed, or (2) the thread has an
665
x-latch on the block */
667
/* 5. Hash search fields: NOTE that these fields are protected by
670
ulint n_hash_helps; /* counter which controls building
671
of a new hash index for the page */
672
ulint n_fields; /* recommended prefix length for hash
673
search: number of full fields */
674
ulint n_bytes; /* recommended prefix: number of bytes
675
in an incomplete field */
676
ulint side; /* BTR_SEARCH_LEFT_SIDE or
677
BTR_SEARCH_RIGHT_SIDE, depending on
678
whether the leftmost record of several
679
records with the same prefix should be
680
indexed in the hash index */
681
ibool is_hashed; /* TRUE if hash index has already been
682
built on this page; note that it does
683
not guarantee that the index is
684
complete, though: there may have been
685
hash collisions, record deletions,
687
ulint curr_n_fields; /* prefix length for hash indexing:
688
number of full fields */
689
ulint curr_n_bytes; /* number of bytes in hash indexing */
690
ulint curr_side; /* BTR_SEARCH_LEFT_SIDE or
691
BTR_SEARCH_RIGHT_SIDE in hash
693
/* 6. Debug fields */
695
rw_lock_t debug_latch; /* in the debug version, each thread
696
which bufferfixes the block acquires
697
an s-latch here; so we can use the
698
debug utilities in sync0rw */
701
/* The buffer pool structure. NOTE! The definition appears here only for
702
other modules of this directory (buf) to see it. Do not use from outside! */
704
struct buf_pool_struct{
706
/* 1. General fields */
708
mutex_t mutex; /* mutex protecting the buffer pool
709
struct and control blocks, except the
710
read-write lock in them */
711
byte* frame_mem; /* pointer to the memory area which
712
was allocated for the frames */
713
byte* frame_zero; /* pointer to the first buffer frame:
714
this may differ from frame_mem, because
715
this is aligned by the frame size */
716
buf_block_t* blocks; /* array of buffer control blocks */
717
ulint max_size; /* number of control blocks ==
718
maximum pool size in pages */
719
ulint curr_size; /* current pool size in pages */
720
hash_table_t* page_hash; /* hash table of the file pages */
722
ulint n_pend_reads; /* number of pending read operations */
723
ulint n_pages_read; /* number read operations */
724
ulint n_pages_written;/* number write operations */
725
ulint n_pages_created;/* number of pages created in the pool
727
/* 2. Page flushing algorithm fields */
729
UT_LIST_BASE_NODE_T(buf_block_t) flush_list;
730
/* base node of the modified block
732
ibool init_flush[BUF_FLUSH_LIST + 1];
733
/* this is TRUE when a flush of the
734
given type is being initialized */
735
ulint n_flush[BUF_FLUSH_LIST + 1];
736
/* this is the number of pending
737
writes in the given flush type */
738
os_event_t no_flush[BUF_FLUSH_LIST + 1];
739
/* this is in the set state when there
740
is no flush batch of the given type
742
ulint ulint_clock; /* a sequence number used to count
743
time. NOTE! This counter wraps
744
around at 4 billion (if ulint ==
746
ulint freed_page_clock;/* a sequence number used to count the
747
number of buffer blocks removed from
748
the end of the LRU list; NOTE that
749
this counter may wrap around at 4
751
ulint LRU_flush_ended;/* when an LRU flush ends for a page,
752
this is incremented by one; this is
753
set to zero when a buffer block is
756
/* 3. LRU replacement algorithm fields */
758
UT_LIST_BASE_NODE_T(buf_block_t) free;
759
/* base node of the free block list */
760
UT_LIST_BASE_NODE_T(buf_block_t) LRU;
761
/* base node of the LRU list */
762
buf_block_t* LRU_old; /* pointer to the about 3/8 oldest
763
blocks in the LRU list; NULL if LRU
764
length less than BUF_LRU_OLD_MIN_LEN */
765
ulint LRU_old_len; /* length of the LRU list from
766
the block to which LRU_old points
767
onward, including that block;
768
see buf0lru.c for the restrictions
769
on this value; not defined if
773
/* States of a control block */
774
#define BUF_BLOCK_NOT_USED 211 /* is in the free list */
775
#define BUF_BLOCK_READY_FOR_USE 212 /* when buf_get_free_block returns
776
a block, it is in this state */
777
#define BUF_BLOCK_FILE_PAGE 213 /* contains a buffered file page */
778
#define BUF_BLOCK_MEMORY 214 /* contains some main memory object */
779
#define BUF_BLOCK_REMOVE_HASH 215 /* hash index should be removed
780
before putting to the free list */
782
/* Io_fix states of a control block; these must be != 0 */
783
#define BUF_IO_READ 561
784
#define BUF_IO_WRITE 562
786
/************************************************************************
787
Let us list the consistency conditions for different control block states.
789
NOT_USED: is in free list, not in LRU list, not in flush list, nor
791
READY_FOR_USE: is not in free list, LRU list, or flush list, nor page
793
MEMORY: is not in free list, LRU list, or flush list, nor page
795
FILE_PAGE: space and offset are defined, is in page hash table
796
if io_fix == BUF_IO_WRITE,
797
pool: no_flush[block->flush_type] is in reset state,
798
pool: n_flush[block->flush_type] > 0
800
(1) if buf_fix_count == 0, then
801
is in LRU list, not in free list
803
if and only if oldest_modification > 0
805
if and only if io_fix == BUF_IO_READ
807
if and only if io_fix == BUF_IO_WRITE
809
(2) if buf_fix_count > 0, then
810
is not in LRU list, not in free list
812
if and only if oldest_modification > 0
813
if io_fix == BUF_IO_READ,
815
if io_fix == BUF_IO_WRITE,
820
NOT_USED => READY_FOR_USE
821
READY_FOR_USE => MEMORY
822
READY_FOR_USE => FILE_PAGE
824
FILE_PAGE => NOT_USED NOTE: This transition is allowed if and only if
825
(1) buf_fix_count == 0,
826
(2) oldest_modification == 0, and
831
#include "buf0buf.ic"