~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-11-06 05:47:12 UTC
  • mto: This revision was merged to the branch mainline in revision 1909.
  • Revision ID: brian@tangent.org-20101106054712-jwxd8e0s0s3nm7qn
Merge in encapsulations in filesort.

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.
 
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
4
Copyright (c) 2008, Google Inc.
5
5
 
6
6
Portions of this file contain modifications contributed and copyrighted by
31
31
*******************************************************/
32
32
 
33
33
#include "mtr0mtr.h"
 
34
#ifndef UNIV_HOTBACKUP
34
35
#include "buf0flu.h"
35
36
#include "buf0lru.h"
36
37
#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
 
Gets the current size of buffer buf_pool in pages.
52
 
@return size in pages*/
53
 
UNIV_INLINE
54
 
ulint
55
 
buf_pool_get_n_pages(void)
56
 
/*======================*/
57
 
{
58
 
        return(buf_pool_get_curr_size() / UNIV_PAGE_SIZE);
59
 
}
60
38
 
61
39
/********************************************************************//**
62
40
Reads the freed_page_clock of a buffer block.
67
45
/*==========================*/
68
46
        const buf_page_t*       bpage)  /*!< in: block */
69
47
{
70
 
        /* This is sometimes read without holding buf_pool->mutex. */
 
48
        /* This is sometimes read without holding buf_pool_mutex. */
71
49
        return(bpage->freed_page_clock);
72
50
}
73
51
 
94
72
/*=====================*/
95
73
        const buf_page_t*       bpage)  /*!< in: block to make younger */
96
74
{
97
 
        buf_pool_t*             buf_pool = buf_pool_from_bpage(bpage);
98
 
 
99
75
        if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
100
76
                /* If eviction has not started yet, do not update the
101
77
                statistics or move blocks in the LRU list.  This is
105
81
                unsigned        access_time = buf_page_is_accessed(bpage);
106
82
 
107
83
                if (access_time > 0
108
 
                    && ((ib_uint32_t) (ut_time_ms() - access_time))
 
84
                    && (ut_time_ms() - access_time)
109
85
                    >= buf_LRU_old_threshold_ms) {
110
86
                        return(TRUE);
111
87
                }
117
93
                return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
118
94
                       > ((ulint) bpage->freed_page_clock
119
95
                          + (buf_pool->curr_size
120
 
                             * (BUF_LRU_OLD_RATIO_DIV - buf_pool->LRU_old_ratio)
 
96
                             * (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio)
121
97
                             / (BUF_LRU_OLD_RATIO_DIV * 4))));
122
98
        }
123
99
}
124
100
 
125
101
/*********************************************************************//**
 
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
/*********************************************************************//**
126
145
Gets the state of a block.
127
146
@return state */
128
147
UNIV_INLINE
274
293
/*===============*/
275
294
        const buf_page_t*       bpage)  /*!< in: pointer to control block */
276
295
{
277
 
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
278
 
 
279
296
        switch (buf_page_get_state(bpage)) {
280
297
        case BUF_BLOCK_ZIP_FREE:
281
298
                ut_error;
282
299
                return(NULL);
283
300
        case BUF_BLOCK_ZIP_PAGE:
284
301
        case BUF_BLOCK_ZIP_DIRTY:
285
 
                return(&buf_pool->zip_mutex);
 
302
                return(&buf_pool_zip_mutex);
286
303
        default:
287
304
                return(&((buf_block_t*) bpage)->mutex);
288
305
        }
368
385
UNIV_INLINE
369
386
enum buf_io_fix
370
387
buf_block_get_io_fix(
371
 
/*=================*/
 
388
/*================*/
372
389
        const buf_block_t*      block)  /*!< in: pointer to the control block */
373
390
{
374
391
        return(buf_page_get_io_fix(&block->page));
383
400
        buf_page_t*     bpage,  /*!< in/out: control block */
384
401
        enum buf_io_fix io_fix) /*!< in: io_fix state */
385
402
{
386
 
#ifdef UNIV_DEBUG
387
 
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
388
 
        ut_ad(buf_pool_mutex_own(buf_pool));
389
 
#endif
 
403
        ut_ad(buf_pool_mutex_own());
390
404
        ut_ad(mutex_own(buf_page_get_mutex(bpage)));
391
405
 
392
406
        bpage->io_fix = io_fix;
414
428
/*==================*/
415
429
        const buf_page_t*       bpage)  /*!< control block being relocated */
416
430
{
417
 
#ifdef UNIV_DEBUG
418
 
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
419
 
        ut_ad(buf_pool_mutex_own(buf_pool));
420
 
#endif
 
431
        ut_ad(buf_pool_mutex_own());
421
432
        ut_ad(mutex_own(buf_page_get_mutex(bpage)));
422
433
        ut_ad(buf_page_in_file(bpage));
423
434
        ut_ad(bpage->in_LRU_list);
435
446
/*============*/
436
447
        const buf_page_t*       bpage)  /*!< in: control block */
437
448
{
438
 
#ifdef UNIV_DEBUG
439
 
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
440
 
        ut_ad(buf_pool_mutex_own(buf_pool));
441
 
#endif
442
449
        ut_ad(buf_page_in_file(bpage));
 
450
        ut_ad(buf_pool_mutex_own());
443
451
 
444
452
        return(bpage->old);
445
453
}
453
461
        buf_page_t*     bpage,  /*!< in/out: control block */
454
462
        ibool           old)    /*!< in: old */
455
463
{
456
 
#ifdef UNIV_DEBUG
457
 
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
458
 
#endif /* UNIV_DEBUG */
459
464
        ut_a(buf_page_in_file(bpage));
460
 
        ut_ad(buf_pool_mutex_own(buf_pool));
 
465
        ut_ad(buf_pool_mutex_own());
461
466
        ut_ad(bpage->in_LRU_list);
462
467
 
463
468
#ifdef UNIV_LRU_DEBUG
503
508
        buf_page_t*     bpage,          /*!< in/out: control block */
504
509
        ulint           time_ms)        /*!< in: ut_time_ms() */
505
510
{
506
 
#ifdef UNIV_DEBUG
507
 
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
508
 
        ut_ad(buf_pool_mutex_own(buf_pool));
509
 
#endif
510
511
        ut_a(buf_page_in_file(bpage));
 
512
        ut_ad(buf_pool_mutex_own());
511
513
 
512
514
        if (!bpage->access_time) {
513
515
                /* Make this the time of the first access. */
703
705
/*========================*/
704
706
        const buf_block_t*      block)  /*!< in: block */
705
707
{
706
 
        ut_ad(block);
707
 
        ut_ad(buf_page_in_file(&block->page));
708
 
#ifdef UNIV_SYNC_DEBUG
709
 
        ut_ad(rw_lock_own(&(((buf_block_t*) block)->lock), RW_LOCK_EXCLUSIVE)
710
 
              || rw_lock_own(&(((buf_block_t*) block)->lock), RW_LOCK_SHARED));
711
 
#endif /* UNIV_SYNC_DEBUG */
712
708
        return(block->lock_hash_val);
713
709
}
714
710
 
715
711
/********************************************************************//**
 
712
Allocates a buffer block.
 
713
@return own: the allocated block, in state BUF_BLOCK_MEMORY */
 
714
UNIV_INLINE
 
715
buf_block_t*
 
716
buf_block_alloc(
 
717
/*============*/
 
718
        ulint   zip_size)       /*!< in: compressed page size in bytes,
 
719
                                or 0 if uncompressed tablespace */
 
720
{
 
721
        buf_block_t*    block;
 
722
 
 
723
        block = buf_LRU_get_free_block(zip_size);
 
724
 
 
725
        buf_block_set_state(block, BUF_BLOCK_MEMORY);
 
726
 
 
727
        return(block);
 
728
}
 
729
 
 
730
/********************************************************************//**
716
731
Frees a buffer block which does not contain a file page. */
717
732
UNIV_INLINE
718
733
void
720
735
/*===========*/
721
736
        buf_block_t*    block)  /*!< in, own: block to be freed */
722
737
{
723
 
        buf_pool_t*     buf_pool = buf_pool_from_bpage((buf_page_t*)block);
724
 
 
725
 
        buf_pool_mutex_enter(buf_pool);
 
738
        buf_pool_mutex_enter();
726
739
 
727
740
        mutex_enter(&block->mutex);
728
741
 
732
745
 
733
746
        mutex_exit(&block->mutex);
734
747
 
735
 
        buf_pool_mutex_exit(buf_pool);
 
748
        buf_pool_mutex_exit();
736
749
}
737
750
#endif /* !UNIV_HOTBACKUP */
738
751
 
806
819
        buf_block_t*    block)  /*!< in: block */
807
820
{
808
821
#ifdef UNIV_SYNC_DEBUG
809
 
        buf_pool_t*     buf_pool = buf_pool_from_bpage((buf_page_t*)block);
810
 
 
811
 
        ut_ad((buf_pool_mutex_own(buf_pool)
 
822
        ut_ad((buf_pool_mutex_own()
812
823
               && (block->page.buf_fix_count == 0))
813
824
              || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
814
825
#endif /* UNIV_SYNC_DEBUG */
887
898
}
888
899
 
889
900
/******************************************************************//**
890
 
Returns the buffer pool instance given a page instance
891
 
@return buf_pool */
892
 
UNIV_INLINE
893
 
buf_pool_t*
894
 
buf_pool_from_bpage(
895
 
/*================*/
896
 
        const buf_page_t*       bpage) /*!< in: buffer pool page */
897
 
{
898
 
        /* Every page must be in some buffer pool. */
899
 
        ut_ad(bpage->buf_pool != NULL);
900
 
 
901
 
        return(bpage->buf_pool);
902
 
}
903
 
 
904
 
/******************************************************************//**
905
 
Returns the buffer pool instance given a block instance
906
 
@return buf_pool */
907
 
UNIV_INLINE
908
 
buf_pool_t*
909
 
buf_pool_from_block(
910
 
/*================*/
911
 
        const buf_block_t*      block) /*!< in: block */
912
 
{
913
 
        return(buf_pool_from_bpage(&block->page));
914
 
}
915
 
 
916
 
/******************************************************************//**
917
 
Returns the buffer pool instance given space and offset of page
918
 
@return buffer pool */
919
 
UNIV_INLINE
920
 
buf_pool_t*
921
 
buf_pool_get(
922
 
/*==========*/
923
 
        ulint   space,  /*!< in: space id */
924
 
        ulint   offset) /*!< in: offset of the page within space */
925
 
{
926
 
        ulint   fold;
927
 
        ulint   index;
928
 
        ulint   ignored_offset;
929
 
 
930
 
        ignored_offset = offset >> 6; /* 2log of BUF_READ_AHEAD_AREA (64)*/
931
 
        fold = buf_page_address_fold(space, ignored_offset);
932
 
        index = fold % srv_buf_pool_instances;
933
 
        return buf_pool_ptr[index];
934
 
}
935
 
 
936
 
/******************************************************************//**
937
 
Returns the buffer pool instance given its array index
938
 
@return buffer pool */
939
 
UNIV_INLINE
940
 
buf_pool_t*
941
 
buf_pool_from_array(
942
 
/*================*/
943
 
        ulint   index)          /*!< in: array index to get
944
 
                                buffer pool instance from */
945
 
{
946
 
        return buf_pool_ptr[index];
947
 
}
948
 
 
949
 
/******************************************************************//**
950
901
Returns the control block of a file page, NULL if not found.
951
902
@return block, NULL if not found */
952
903
UNIV_INLINE
953
904
buf_page_t*
954
 
buf_page_hash_get_low(
955
 
/*==================*/
956
 
        buf_pool_t*     buf_pool,       /*!< buffer pool instance */
957
 
        ulint           space,          /*!< in: space id */
958
 
        ulint           offset,         /*!< in: offset of the page
959
 
                                        within space */
960
 
        ulint           fold)           /*!< in: buf_page_address_fold(
961
 
                                        space, offset) */
 
905
buf_page_hash_get(
 
906
/*==============*/
 
907
        ulint   space,  /*!< in: space id */
 
908
        ulint   offset) /*!< in: offset of the page within space */
962
909
{
963
910
        buf_page_t*     bpage;
 
911
        ulint           fold;
964
912
 
965
913
        ut_ad(buf_pool);
966
 
        ut_ad(buf_pool_mutex_own(buf_pool));
967
 
        ut_ad(fold == buf_page_address_fold(space, offset));
 
914
        ut_ad(buf_pool_mutex_own());
968
915
 
969
916
        /* Look for the page in the hash table */
970
917
 
 
918
        fold = buf_page_address_fold(space, offset);
 
919
 
971
920
        HASH_SEARCH(hash, buf_pool->page_hash, fold, buf_page_t*, bpage,
972
921
                    ut_ad(bpage->in_page_hash && !bpage->in_zip_hash
973
922
                          && buf_page_in_file(bpage)),
976
925
                ut_a(buf_page_in_file(bpage));
977
926
                ut_ad(bpage->in_page_hash);
978
927
                ut_ad(!bpage->in_zip_hash);
979
 
#if UNIV_WORD_SIZE == 4
980
 
                /* On 32-bit systems, there is no padding in
981
 
                buf_page_t.  On other systems, Valgrind could complain
982
 
                about uninitialized pad bytes. */
983
928
                UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
984
 
#endif
985
 
        }
986
 
 
987
 
        return(bpage);
988
 
}
989
 
 
990
 
/******************************************************************//**
991
 
Returns the control block of a file page, NULL if not found.
992
 
@return block, NULL if not found or not a real control block */
993
 
UNIV_INLINE
994
 
buf_page_t*
995
 
buf_page_hash_get(
996
 
/*==============*/
997
 
        buf_pool_t*     buf_pool,       /*!< in: buffer pool instance */
998
 
        ulint           space,          /*!< in: space id */
999
 
        ulint           offset)         /*!< in: offset of the page
1000
 
                                        within space */
1001
 
{
1002
 
        buf_page_t*     bpage;
1003
 
        ulint           fold    = buf_page_address_fold(space, offset);
1004
 
 
1005
 
        bpage   = buf_page_hash_get_low(buf_pool, space, offset, fold);
1006
 
 
1007
 
        if (bpage && buf_pool_watch_is_sentinel(buf_pool, bpage)) {
1008
 
                bpage = NULL;
1009
929
        }
1010
930
 
1011
931
        return(bpage);
1019
939
buf_block_t*
1020
940
buf_block_hash_get(
1021
941
/*===============*/
1022
 
        buf_pool_t*     buf_pool,       /*!< in: buffer pool instance */
1023
 
        ulint           space,          /*!< in: space id */
1024
 
        ulint           offset)         /*!< in: offset of the page
1025
 
                                        within space */
 
942
        ulint   space,  /*!< in: space id */
 
943
        ulint   offset) /*!< in: offset of the page within space */
1026
944
{
1027
 
        buf_block_t*    block;
1028
 
 
1029
 
        block = buf_page_get_block(buf_page_hash_get(buf_pool, space, offset));
1030
 
 
1031
 
        return(block);
 
945
        return(buf_page_get_block(buf_page_hash_get(space, offset)));
1032
946
}
1033
947
 
1034
948
/********************************************************************//**
1046
960
        ulint   offset) /*!< in: page number */
1047
961
{
1048
962
        const buf_page_t*       bpage;
1049
 
        buf_pool_t*             buf_pool = buf_pool_get(space, offset);
1050
 
 
1051
 
        buf_pool_mutex_enter(buf_pool);
1052
 
 
1053
 
        bpage = buf_page_hash_get(buf_pool, space, offset);
1054
 
 
1055
 
        buf_pool_mutex_exit(buf_pool);
 
963
 
 
964
        buf_pool_mutex_enter();
 
965
 
 
966
        bpage = buf_page_hash_get(space, offset);
 
967
 
 
968
        buf_pool_mutex_exit();
1056
969
 
1057
970
        return(bpage != NULL);
1058
971
}
1066
979
        buf_page_t*     bpage)          /*!< in: buffer block */
1067
980
{
1068
981
        buf_block_t*    block;
1069
 
        buf_pool_t*     buf_pool = buf_pool_from_bpage(bpage);
1070
982
 
1071
983
        ut_ad(bpage);
1072
984
        ut_a(bpage->buf_fix_count > 0);
1074
986
        switch (buf_page_get_state(bpage)) {
1075
987
        case BUF_BLOCK_ZIP_PAGE:
1076
988
        case BUF_BLOCK_ZIP_DIRTY:
1077
 
                mutex_enter(&buf_pool->zip_mutex);
 
989
                mutex_enter(&buf_pool_zip_mutex);
1078
990
                bpage->buf_fix_count--;
1079
 
                mutex_exit(&buf_pool->zip_mutex);
 
991
                mutex_exit(&buf_pool_zip_mutex);
1080
992
                return;
1081
993
        case BUF_BLOCK_FILE_PAGE:
1082
994
                block = (buf_block_t*) bpage;
1095
1007
                break;
1096
1008
        }
1097
1009
 
1098
 
        
1099
1010
        ut_error;
1100
1011
}
1101
1012
 
1107
1018
buf_page_release(
1108
1019
/*=============*/
1109
1020
        buf_block_t*    block,          /*!< in: buffer block */
1110
 
        ulint           rw_latch)       /*!< in: RW_S_LATCH, RW_X_LATCH,
 
1021
        ulint           rw_latch,       /*!< in: RW_S_LATCH, RW_X_LATCH,
1111
1022
                                        RW_NO_LATCH */
 
1023
        mtr_t*          mtr)            /*!< in: mtr */
1112
1024
{
1113
1025
        ut_ad(block);
1114
1026
 
1115
1027
        ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1116
1028
        ut_a(block->page.buf_fix_count > 0);
1117
1029
 
 
1030
        if (rw_latch == RW_X_LATCH && mtr->modifications) {
 
1031
                buf_pool_mutex_enter();
 
1032
                buf_flush_note_modification(block, mtr);
 
1033
                buf_pool_mutex_exit();
 
1034
        }
 
1035
 
1118
1036
        mutex_enter(&block->mutex);
1119
1037
 
1120
1038
#ifdef UNIV_SYNC_DEBUG
1147
1065
        sync_thread_add_level(&block->lock, level);
1148
1066
}
1149
1067
#endif /* UNIV_SYNC_DEBUG */
1150
 
/********************************************************************//**
1151
 
Acquire mutex on all buffer pool instances. */
1152
 
UNIV_INLINE
1153
 
void
1154
 
buf_pool_mutex_enter_all(void)
1155
 
/*==========================*/
1156
 
{
1157
 
        ulint   i;
1158
 
 
1159
 
        for (i = 0; i < srv_buf_pool_instances; i++) {
1160
 
                buf_pool_t*     buf_pool;
1161
 
 
1162
 
                buf_pool = buf_pool_from_array(i);
1163
 
                buf_pool_mutex_enter(buf_pool);
1164
 
        }
1165
 
}
1166
 
 
1167
 
/********************************************************************//**
1168
 
Release mutex on all buffer pool instances. */
1169
 
UNIV_INLINE
1170
 
void
1171
 
buf_pool_mutex_exit_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_exit(buf_pool);
1181
 
        }
1182
 
}
1183
1068
#endif /* !UNIV_HOTBACKUP */