~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/include/buf0buf.ic

  • Committer: Monty Taylor
  • Date: 2011-02-13 17:26:39 UTC
  • mfrom: (2157.2.2 give-in-to-pkg-config)
  • mto: This revision was merged to the branch mainline in revision 2166.
  • Revision ID: mordred@inaugust.com-20110213172639-nhy7i72sfhoq13ms
Merged in pkg-config fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
4
 
Copyright (c) 2008, Google Inc.
 
3
Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
 
4
Copyright (C) 2008, Google Inc.
5
5
 
6
6
Portions of this file contain modifications contributed and copyrighted by
7
7
Google, Inc. Those modifications are gratefully acknowledged and are described
31
31
*******************************************************/
32
32
 
33
33
#include "mtr0mtr.h"
34
 
#ifndef UNIV_HOTBACKUP
35
34
#include "buf0flu.h"
36
35
#include "buf0lru.h"
37
36
#include "buf0rea.h"
 
37
#include "srv0srv.h"
 
38
 
 
39
/*********************************************************************//**
 
40
Gets the current size of buffer buf_pool in bytes.
 
41
@return size in bytes */
 
42
UNIV_INLINE
 
43
ulint
 
44
buf_pool_get_curr_size(void)
 
45
/*========================*/
 
46
{
 
47
        return(srv_buf_pool_curr_size);
 
48
}
 
49
 
 
50
/********************************************************************//**
 
51
Calculates the index of a buffer pool to the buf_pool[] array.
 
52
@return the position of the buffer pool in buf_pool[] */
 
53
UNIV_INLINE
 
54
ulint
 
55
buf_pool_index(
 
56
/*===========*/
 
57
        const buf_pool_t*       buf_pool)       /*!< in: buffer pool */
 
58
{
 
59
        ulint   i = buf_pool - buf_pool_ptr;
 
60
        ut_ad(i < MAX_BUFFER_POOLS);
 
61
        ut_ad(i < srv_buf_pool_instances);
 
62
        return(i);
 
63
}
 
64
 
 
65
/******************************************************************//**
 
66
Returns the buffer pool instance given a page instance
 
67
@return buf_pool */
 
68
UNIV_INLINE
 
69
buf_pool_t*
 
70
buf_pool_from_bpage(
 
71
/*================*/
 
72
        const buf_page_t*       bpage) /*!< in: buffer pool page */
 
73
{
 
74
        ulint   i;
 
75
        i = bpage->buf_pool_index;
 
76
        ut_ad(i < srv_buf_pool_instances);
 
77
        return(&buf_pool_ptr[i]);
 
78
}
 
79
 
 
80
/******************************************************************//**
 
81
Returns the buffer pool instance given a block instance
 
82
@return buf_pool */
 
83
UNIV_INLINE
 
84
buf_pool_t*
 
85
buf_pool_from_block(
 
86
/*================*/
 
87
        const buf_block_t*      block) /*!< in: block */
 
88
{
 
89
        return(buf_pool_from_bpage(&block->page));
 
90
}
 
91
 
 
92
/*********************************************************************//**
 
93
Gets the current size of buffer buf_pool in pages.
 
94
@return size in pages*/
 
95
UNIV_INLINE
 
96
ulint
 
97
buf_pool_get_n_pages(void)
 
98
/*======================*/
 
99
{
 
100
        return(buf_pool_get_curr_size() / UNIV_PAGE_SIZE);
 
101
}
38
102
 
39
103
/********************************************************************//**
40
104
Reads the freed_page_clock of a buffer block.
45
109
/*==========================*/
46
110
        const buf_page_t*       bpage)  /*!< in: block */
47
111
{
48
 
        /* This is sometimes read without holding buf_pool_mutex. */
 
112
        /* This is sometimes read without holding buf_pool->mutex. */
49
113
        return(bpage->freed_page_clock);
50
114
}
51
115
 
72
136
/*=====================*/
73
137
        const buf_page_t*       bpage)  /*!< in: block to make younger */
74
138
{
 
139
        buf_pool_t*             buf_pool = buf_pool_from_bpage(bpage);
 
140
 
75
141
        if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
76
142
                /* If eviction has not started yet, do not update the
77
143
                statistics or move blocks in the LRU list.  This is
93
159
                return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
94
160
                       > ((ulint) bpage->freed_page_clock
95
161
                          + (buf_pool->curr_size
96
 
                             * (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio)
 
162
                             * (BUF_LRU_OLD_RATIO_DIV - buf_pool->LRU_old_ratio)
97
163
                             / (BUF_LRU_OLD_RATIO_DIV * 4))));
98
164
        }
99
165
}
100
166
 
101
167
/*********************************************************************//**
102
 
Gets the current size of buffer buf_pool in bytes.
103
 
@return size in bytes */
104
 
UNIV_INLINE
105
 
ulint
106
 
buf_pool_get_curr_size(void)
107
 
/*========================*/
108
 
{
109
 
        return(buf_pool->curr_size * UNIV_PAGE_SIZE);
110
 
}
111
 
 
112
 
/********************************************************************//**
113
 
Gets the smallest oldest_modification lsn for any page in the pool. Returns
114
 
zero if all modified pages have been flushed to disk.
115
 
@return oldest modification in pool, zero if none */
116
 
UNIV_INLINE
117
 
ib_uint64_t
118
 
buf_pool_get_oldest_modification(void)
119
 
/*==================================*/
120
 
{
121
 
        buf_page_t*     bpage;
122
 
        ib_uint64_t     lsn;
123
 
 
124
 
        buf_pool_mutex_enter();
125
 
 
126
 
        bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
127
 
 
128
 
        if (bpage == NULL) {
129
 
                lsn = 0;
130
 
        } else {
131
 
                ut_ad(bpage->in_flush_list);
132
 
                lsn = bpage->oldest_modification;
133
 
        }
134
 
 
135
 
        buf_pool_mutex_exit();
136
 
 
137
 
        /* The returned answer may be out of date: the flush_list can
138
 
        change after the mutex has been released. */
139
 
 
140
 
        return(lsn);
141
 
}
142
 
#endif /* !UNIV_HOTBACKUP */
143
 
 
144
 
/*********************************************************************//**
145
168
Gets the state of a block.
146
169
@return state */
147
170
UNIV_INLINE
293
316
/*===============*/
294
317
        const buf_page_t*       bpage)  /*!< in: pointer to control block */
295
318
{
 
319
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
 
320
 
296
321
        switch (buf_page_get_state(bpage)) {
297
322
        case BUF_BLOCK_ZIP_FREE:
298
323
                ut_error;
299
324
                return(NULL);
300
325
        case BUF_BLOCK_ZIP_PAGE:
301
326
        case BUF_BLOCK_ZIP_DIRTY:
302
 
                return(&buf_pool_zip_mutex);
 
327
                return(&buf_pool->zip_mutex);
303
328
        default:
304
329
                return(&((buf_block_t*) bpage)->mutex);
305
330
        }
385
410
UNIV_INLINE
386
411
enum buf_io_fix
387
412
buf_block_get_io_fix(
388
 
/*================*/
 
413
/*=================*/
389
414
        const buf_block_t*      block)  /*!< in: pointer to the control block */
390
415
{
391
416
        return(buf_page_get_io_fix(&block->page));
400
425
        buf_page_t*     bpage,  /*!< in/out: control block */
401
426
        enum buf_io_fix io_fix) /*!< in: io_fix state */
402
427
{
403
 
        ut_ad(buf_pool_mutex_own());
 
428
#ifdef UNIV_DEBUG
 
429
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
 
430
        ut_ad(buf_pool_mutex_own(buf_pool));
 
431
#endif
404
432
        ut_ad(mutex_own(buf_page_get_mutex(bpage)));
405
433
 
406
434
        bpage->io_fix = io_fix;
428
456
/*==================*/
429
457
        const buf_page_t*       bpage)  /*!< control block being relocated */
430
458
{
431
 
        ut_ad(buf_pool_mutex_own());
 
459
#ifdef UNIV_DEBUG
 
460
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
 
461
        ut_ad(buf_pool_mutex_own(buf_pool));
 
462
#endif
432
463
        ut_ad(mutex_own(buf_page_get_mutex(bpage)));
433
464
        ut_ad(buf_page_in_file(bpage));
434
465
        ut_ad(bpage->in_LRU_list);
446
477
/*============*/
447
478
        const buf_page_t*       bpage)  /*!< in: control block */
448
479
{
 
480
#ifdef UNIV_DEBUG
 
481
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
 
482
        ut_ad(buf_pool_mutex_own(buf_pool));
 
483
#endif
449
484
        ut_ad(buf_page_in_file(bpage));
450
 
        ut_ad(buf_pool_mutex_own());
451
485
 
452
486
        return(bpage->old);
453
487
}
461
495
        buf_page_t*     bpage,  /*!< in/out: control block */
462
496
        ibool           old)    /*!< in: old */
463
497
{
 
498
#ifdef UNIV_DEBUG
 
499
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
 
500
#endif /* UNIV_DEBUG */
464
501
        ut_a(buf_page_in_file(bpage));
465
 
        ut_ad(buf_pool_mutex_own());
 
502
        ut_ad(buf_pool_mutex_own(buf_pool));
466
503
        ut_ad(bpage->in_LRU_list);
467
504
 
468
505
#ifdef UNIV_LRU_DEBUG
508
545
        buf_page_t*     bpage,          /*!< in/out: control block */
509
546
        ulint           time_ms)        /*!< in: ut_time_ms() */
510
547
{
 
548
#ifdef UNIV_DEBUG
 
549
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
 
550
        ut_ad(buf_pool_mutex_own(buf_pool));
 
551
#endif
511
552
        ut_a(buf_page_in_file(bpage));
512
 
        ut_ad(buf_pool_mutex_own());
513
553
 
514
554
        if (!bpage->access_time) {
515
555
                /* Make this the time of the first access. */
715
755
}
716
756
 
717
757
/********************************************************************//**
718
 
Allocates a buffer block.
719
 
@return own: the allocated block, in state BUF_BLOCK_MEMORY */
720
 
UNIV_INLINE
721
 
buf_block_t*
722
 
buf_block_alloc(
723
 
/*============*/
724
 
        ulint   zip_size)       /*!< in: compressed page size in bytes,
725
 
                                or 0 if uncompressed tablespace */
726
 
{
727
 
        buf_block_t*    block;
728
 
 
729
 
        block = buf_LRU_get_free_block(zip_size);
730
 
 
731
 
        buf_block_set_state(block, BUF_BLOCK_MEMORY);
732
 
 
733
 
        return(block);
734
 
}
735
 
 
736
 
/********************************************************************//**
737
758
Frees a buffer block which does not contain a file page. */
738
759
UNIV_INLINE
739
760
void
741
762
/*===========*/
742
763
        buf_block_t*    block)  /*!< in, own: block to be freed */
743
764
{
744
 
        buf_pool_mutex_enter();
 
765
        buf_pool_t*     buf_pool = buf_pool_from_bpage((buf_page_t*)block);
 
766
 
 
767
        buf_pool_mutex_enter(buf_pool);
745
768
 
746
769
        mutex_enter(&block->mutex);
747
770
 
751
774
 
752
775
        mutex_exit(&block->mutex);
753
776
 
754
 
        buf_pool_mutex_exit();
 
777
        buf_pool_mutex_exit(buf_pool);
755
778
}
756
779
#endif /* !UNIV_HOTBACKUP */
757
780
 
825
848
        buf_block_t*    block)  /*!< in: block */
826
849
{
827
850
#ifdef UNIV_SYNC_DEBUG
828
 
        ut_ad((buf_pool_mutex_own()
 
851
        buf_pool_t*     buf_pool = buf_pool_from_bpage((buf_page_t*)block);
 
852
 
 
853
        ut_ad((buf_pool_mutex_own(buf_pool)
829
854
               && (block->page.buf_fix_count == 0))
830
855
              || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
831
856
#endif /* UNIV_SYNC_DEBUG */
904
929
}
905
930
 
906
931
/******************************************************************//**
 
932
Returns the buffer pool instance given space and offset of page
 
933
@return buffer pool */
 
934
UNIV_INLINE
 
935
buf_pool_t*
 
936
buf_pool_get(
 
937
/*==========*/
 
938
        ulint   space,  /*!< in: space id */
 
939
        ulint   offset) /*!< in: offset of the page within space */
 
940
{
 
941
        ulint   fold;
 
942
        ulint   index;
 
943
        ulint   ignored_offset;
 
944
 
 
945
        ignored_offset = offset >> 6; /* 2log of BUF_READ_AHEAD_AREA (64)*/
 
946
        fold = buf_page_address_fold(space, ignored_offset);
 
947
        index = fold % srv_buf_pool_instances;
 
948
        return(&buf_pool_ptr[index]);
 
949
}
 
950
 
 
951
/******************************************************************//**
 
952
Returns the buffer pool instance given its array index
 
953
@return buffer pool */
 
954
UNIV_INLINE
 
955
buf_pool_t*
 
956
buf_pool_from_array(
 
957
/*================*/
 
958
        ulint   index)          /*!< in: array index to get
 
959
                                buffer pool instance from */
 
960
{
 
961
        ut_ad(index < MAX_BUFFER_POOLS);
 
962
        ut_ad(index < srv_buf_pool_instances);
 
963
        return(&buf_pool_ptr[index]);
 
964
}
 
965
 
 
966
/******************************************************************//**
907
967
Returns the control block of a file page, NULL if not found.
908
968
@return block, NULL if not found */
909
969
UNIV_INLINE
910
970
buf_page_t*
911
 
buf_page_hash_get(
912
 
/*==============*/
913
 
        ulint   space,  /*!< in: space id */
914
 
        ulint   offset) /*!< in: offset of the page within space */
 
971
buf_page_hash_get_low(
 
972
/*==================*/
 
973
        buf_pool_t*     buf_pool,       /*!< buffer pool instance */
 
974
        ulint           space,          /*!< in: space id */
 
975
        ulint           offset,         /*!< in: offset of the page
 
976
                                        within space */
 
977
        ulint           fold)           /*!< in: buf_page_address_fold(
 
978
                                        space, offset) */
915
979
{
916
980
        buf_page_t*     bpage;
917
 
        ulint           fold;
918
981
 
919
982
        ut_ad(buf_pool);
920
 
        ut_ad(buf_pool_mutex_own());
 
983
        ut_ad(buf_pool_mutex_own(buf_pool));
 
984
        ut_ad(fold == buf_page_address_fold(space, offset));
921
985
 
922
986
        /* Look for the page in the hash table */
923
987
 
924
 
        fold = buf_page_address_fold(space, offset);
925
 
 
926
988
        HASH_SEARCH(hash, buf_pool->page_hash, fold, buf_page_t*, bpage,
927
989
                    ut_ad(bpage->in_page_hash && !bpage->in_zip_hash
928
990
                          && buf_page_in_file(bpage)),
943
1005
}
944
1006
 
945
1007
/******************************************************************//**
 
1008
Returns the control block of a file page, NULL if not found.
 
1009
@return block, NULL if not found or not a real control block */
 
1010
UNIV_INLINE
 
1011
buf_page_t*
 
1012
buf_page_hash_get(
 
1013
/*==============*/
 
1014
        buf_pool_t*     buf_pool,       /*!< in: buffer pool instance */
 
1015
        ulint           space,          /*!< in: space id */
 
1016
        ulint           offset)         /*!< in: offset of the page
 
1017
                                        within space */
 
1018
{
 
1019
        buf_page_t*     bpage;
 
1020
        ulint           fold    = buf_page_address_fold(space, offset);
 
1021
 
 
1022
        bpage   = buf_page_hash_get_low(buf_pool, space, offset, fold);
 
1023
 
 
1024
        if (bpage && buf_pool_watch_is_sentinel(buf_pool, bpage)) {
 
1025
                bpage = NULL;
 
1026
        }
 
1027
 
 
1028
        return(bpage);
 
1029
}
 
1030
 
 
1031
/******************************************************************//**
946
1032
Returns the control block of a file page, NULL if not found
947
1033
or an uncompressed page frame does not exist.
948
1034
@return block, NULL if not found */
950
1036
buf_block_t*
951
1037
buf_block_hash_get(
952
1038
/*===============*/
953
 
        ulint   space,  /*!< in: space id */
954
 
        ulint   offset) /*!< in: offset of the page within space */
 
1039
        buf_pool_t*     buf_pool,       /*!< in: buffer pool instance */
 
1040
        ulint           space,          /*!< in: space id */
 
1041
        ulint           offset)         /*!< in: offset of the page
 
1042
                                        within space */
955
1043
{
956
 
        return(buf_page_get_block(buf_page_hash_get(space, offset)));
 
1044
        buf_block_t*    block;
 
1045
 
 
1046
        block = buf_page_get_block(buf_page_hash_get(buf_pool, space, offset));
 
1047
 
 
1048
        return(block);
957
1049
}
958
1050
 
959
1051
/********************************************************************//**
971
1063
        ulint   offset) /*!< in: page number */
972
1064
{
973
1065
        const buf_page_t*       bpage;
974
 
 
975
 
        buf_pool_mutex_enter();
976
 
 
977
 
        bpage = buf_page_hash_get(space, offset);
978
 
 
979
 
        buf_pool_mutex_exit();
 
1066
        buf_pool_t*             buf_pool = buf_pool_get(space, offset);
 
1067
 
 
1068
        buf_pool_mutex_enter(buf_pool);
 
1069
 
 
1070
        bpage = buf_page_hash_get(buf_pool, space, offset);
 
1071
 
 
1072
        buf_pool_mutex_exit(buf_pool);
980
1073
 
981
1074
        return(bpage != NULL);
982
1075
}
990
1083
        buf_page_t*     bpage)          /*!< in: buffer block */
991
1084
{
992
1085
        buf_block_t*    block;
 
1086
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
993
1087
 
994
1088
        ut_ad(bpage);
995
1089
        ut_a(bpage->buf_fix_count > 0);
997
1091
        switch (buf_page_get_state(bpage)) {
998
1092
        case BUF_BLOCK_ZIP_PAGE:
999
1093
        case BUF_BLOCK_ZIP_DIRTY:
1000
 
                mutex_enter(&buf_pool_zip_mutex);
 
1094
                mutex_enter(&buf_pool->zip_mutex);
1001
1095
                bpage->buf_fix_count--;
1002
 
                mutex_exit(&buf_pool_zip_mutex);
 
1096
                mutex_exit(&buf_pool->zip_mutex);
1003
1097
                return;
1004
1098
        case BUF_BLOCK_FILE_PAGE:
1005
1099
                block = (buf_block_t*) bpage;
1018
1112
                break;
1019
1113
        }
1020
1114
 
 
1115
        
1021
1116
        ut_error;
1022
1117
}
1023
1118
 
1029
1124
buf_page_release(
1030
1125
/*=============*/
1031
1126
        buf_block_t*    block,          /*!< in: buffer block */
1032
 
        ulint           rw_latch,       /*!< in: RW_S_LATCH, RW_X_LATCH,
 
1127
        ulint           rw_latch)       /*!< in: RW_S_LATCH, RW_X_LATCH,
1033
1128
                                        RW_NO_LATCH */
1034
 
        mtr_t*          mtr)            /*!< in: mtr */
1035
1129
{
1036
1130
        ut_ad(block);
1037
1131
 
1038
1132
        ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1039
1133
        ut_a(block->page.buf_fix_count > 0);
1040
1134
 
1041
 
        if (rw_latch == RW_X_LATCH && mtr->modifications) {
1042
 
                buf_pool_mutex_enter();
1043
 
                buf_flush_note_modification(block, mtr);
1044
 
                buf_pool_mutex_exit();
1045
 
        }
1046
 
 
1047
1135
        mutex_enter(&block->mutex);
1048
1136
 
1049
1137
#ifdef UNIV_SYNC_DEBUG
1076
1164
        sync_thread_add_level(&block->lock, level);
1077
1165
}
1078
1166
#endif /* UNIV_SYNC_DEBUG */
 
1167
/********************************************************************//**
 
1168
Acquire mutex on all buffer pool instances. */
 
1169
UNIV_INLINE
 
1170
void
 
1171
buf_pool_mutex_enter_all(void)
 
1172
/*==========================*/
 
1173
{
 
1174
        ulint   i;
 
1175
 
 
1176
        for (i = 0; i < srv_buf_pool_instances; i++) {
 
1177
                buf_pool_t*     buf_pool;
 
1178
 
 
1179
                buf_pool = buf_pool_from_array(i);
 
1180
                buf_pool_mutex_enter(buf_pool);
 
1181
        }
 
1182
}
 
1183
 
 
1184
/********************************************************************//**
 
1185
Release mutex on all buffer pool instances. */
 
1186
UNIV_INLINE
 
1187
void
 
1188
buf_pool_mutex_exit_all(void)
 
1189
/*=========================*/
 
1190
{
 
1191
        ulint   i;
 
1192
 
 
1193
        for (i = 0; i < srv_buf_pool_instances; i++) {
 
1194
                buf_pool_t*     buf_pool;
 
1195
 
 
1196
                buf_pool = buf_pool_from_array(i);
 
1197
                buf_pool_mutex_exit(buf_pool);
 
1198
        }
 
1199
}
1079
1200
#endif /* !UNIV_HOTBACKUP */