1
/******************************************************
2
The database buffer buf_pool
6
Created 11/5/1995 Heikki Tuuri
7
*******************************************************/
14
/************************************************************************
15
Reads the freed_page_clock of a buffer block. */
18
buf_page_get_freed_page_clock(
19
/*==========================*/
20
/* out: freed_page_clock */
21
const buf_page_t* bpage) /* in: block */
23
return(bpage->freed_page_clock);
26
/************************************************************************
27
Reads the freed_page_clock of a buffer block. */
30
buf_block_get_freed_page_clock(
31
/*===========================*/
32
/* out: freed_page_clock */
33
const buf_block_t* block) /* in: block */
35
return(buf_page_get_freed_page_clock(&block->page));
38
/************************************************************************
39
Recommends a move of a block to the start of the LRU list if there is danger
40
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
44
buf_page_peek_if_too_old(
45
/*=====================*/
46
/* out: TRUE if should be made
48
const buf_page_t* bpage) /* in: block to make younger */
50
return(buf_pool->freed_page_clock
51
>= buf_page_get_freed_page_clock(bpage)
52
+ 1 + (buf_pool->curr_size / 4));
55
/*************************************************************************
56
Gets the current size of buffer buf_pool in bytes. */
59
buf_pool_get_curr_size(void)
60
/*========================*/
61
/* out: size in bytes */
63
return(buf_pool->curr_size * UNIV_PAGE_SIZE);
66
/************************************************************************
67
Gets the smallest oldest_modification lsn for any page in the pool. Returns
68
zero if all modified pages have been flushed to disk. */
71
buf_pool_get_oldest_modification(void)
72
/*==================================*/
73
/* out: oldest modification in pool,
79
buf_pool_mutex_enter();
81
bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
86
ut_ad(bpage->in_flush_list);
87
lsn = bpage->oldest_modification;
90
buf_pool_mutex_exit();
95
/***********************************************************************
96
Increments the buf_pool clock by one and returns its new value. Remember
97
that in the 32 bit version the clock wraps around at 4 billion! */
100
buf_pool_clock_tic(void)
101
/*====================*/
102
/* out: new clock value */
104
ut_ad(buf_pool_mutex_own());
106
buf_pool->ulint_clock++;
108
return(buf_pool->ulint_clock);
111
/*************************************************************************
112
Gets the state of a block. */
118
const buf_page_t* bpage) /* in: pointer to the control block */
120
enum buf_page_state state = (enum buf_page_state) bpage->state;
124
case BUF_BLOCK_ZIP_FREE:
125
case BUF_BLOCK_ZIP_PAGE:
126
case BUF_BLOCK_ZIP_DIRTY:
127
case BUF_BLOCK_NOT_USED:
128
case BUF_BLOCK_READY_FOR_USE:
129
case BUF_BLOCK_FILE_PAGE:
130
case BUF_BLOCK_MEMORY:
131
case BUF_BLOCK_REMOVE_HASH:
136
#endif /* UNIV_DEBUG */
140
/*************************************************************************
141
Gets the state of a block. */
147
const buf_block_t* block) /* in: pointer to the control block */
149
return(buf_page_get_state(&block->page));
151
/*************************************************************************
152
Sets the state of a block. */
157
buf_page_t* bpage, /* in/out: pointer to control block */
158
enum buf_page_state state) /* in: state */
161
enum buf_page_state old_state = buf_page_get_state(bpage);
164
case BUF_BLOCK_ZIP_FREE:
167
case BUF_BLOCK_ZIP_PAGE:
168
ut_a(state == BUF_BLOCK_ZIP_DIRTY);
170
case BUF_BLOCK_ZIP_DIRTY:
171
ut_a(state == BUF_BLOCK_ZIP_PAGE);
173
case BUF_BLOCK_NOT_USED:
174
ut_a(state == BUF_BLOCK_READY_FOR_USE);
176
case BUF_BLOCK_READY_FOR_USE:
177
ut_a(state == BUF_BLOCK_MEMORY
178
|| state == BUF_BLOCK_FILE_PAGE
179
|| state == BUF_BLOCK_NOT_USED);
181
case BUF_BLOCK_MEMORY:
182
ut_a(state == BUF_BLOCK_NOT_USED);
184
case BUF_BLOCK_FILE_PAGE:
185
ut_a(state == BUF_BLOCK_NOT_USED
186
|| state == BUF_BLOCK_REMOVE_HASH);
188
case BUF_BLOCK_REMOVE_HASH:
189
ut_a(state == BUF_BLOCK_MEMORY);
192
#endif /* UNIV_DEBUG */
193
bpage->state = state;
194
ut_ad(buf_page_get_state(bpage) == state);
197
/*************************************************************************
198
Sets the state of a block. */
203
buf_block_t* block, /* in/out: pointer to control block */
204
enum buf_page_state state) /* in: state */
206
buf_page_set_state(&block->page, state);
209
/*************************************************************************
210
Determines if a block is mapped to a tablespace. */
215
/* out: TRUE if mapped */
216
const buf_page_t* bpage) /* in: pointer to control block */
218
switch (buf_page_get_state(bpage)) {
219
case BUF_BLOCK_ZIP_FREE:
220
/* This is a free page in buf_pool->zip_free[].
221
Such pages should only be accessed by the buddy allocator. */
224
case BUF_BLOCK_ZIP_PAGE:
225
case BUF_BLOCK_ZIP_DIRTY:
226
case BUF_BLOCK_FILE_PAGE:
228
case BUF_BLOCK_NOT_USED:
229
case BUF_BLOCK_READY_FOR_USE:
230
case BUF_BLOCK_MEMORY:
231
case BUF_BLOCK_REMOVE_HASH:
238
/*************************************************************************
239
Determines if a block should be on unzip_LRU list. */
242
buf_page_belongs_to_unzip_LRU(
243
/*==========================*/
244
/* out: TRUE if block belongs
246
const buf_page_t* bpage) /* in: pointer to control block */
248
ut_ad(buf_page_in_file(bpage));
250
return(bpage->zip.data
251
&& buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
254
/*************************************************************************
255
Determine the approximate LRU list position of a block. */
258
buf_page_get_LRU_position(
259
/*======================*/
260
/* out: LRU list position */
261
const buf_page_t* bpage) /* in: control block */
263
ut_ad(buf_page_in_file(bpage));
265
return(bpage->LRU_position);
268
/*************************************************************************
269
Gets the mutex of a block. */
274
/* out: pointer to mutex
276
const buf_page_t* bpage) /* in: pointer to control block */
278
switch (buf_page_get_state(bpage)) {
279
case BUF_BLOCK_ZIP_FREE:
282
case BUF_BLOCK_ZIP_PAGE:
283
case BUF_BLOCK_ZIP_DIRTY:
284
return(&buf_pool_zip_mutex);
286
return(&((buf_block_t*) bpage)->mutex);
290
/*************************************************************************
291
Get the flush type of a page. */
294
buf_page_get_flush_type(
295
/*====================*/
296
/* out: flush type */
297
const buf_page_t* bpage) /* in: buffer page */
299
enum buf_flush flush_type = (enum buf_flush) bpage->flush_type;
302
switch (flush_type) {
304
case BUF_FLUSH_SINGLE_PAGE:
307
case BUF_FLUSH_N_TYPES:
311
#endif /* UNIV_DEBUG */
314
/*************************************************************************
315
Set the flush type of a page. */
318
buf_page_set_flush_type(
319
/*====================*/
320
buf_page_t* bpage, /* in: buffer page */
321
enum buf_flush flush_type) /* in: flush type */
323
bpage->flush_type = flush_type;
324
ut_ad(buf_page_get_flush_type(bpage) == flush_type);
327
/*************************************************************************
328
Map a block to a file page. */
331
buf_block_set_file_page(
332
/*====================*/
333
buf_block_t* block, /* in/out: pointer to control block */
334
ulint space, /* in: tablespace id */
335
ulint page_no)/* in: page number */
337
buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
338
block->page.space = space;
339
block->page.offset = page_no;
342
/*************************************************************************
343
Gets the io_fix state of a block. */
348
/* out: io_fix state */
349
const buf_page_t* bpage) /* in: pointer to the control block */
351
enum buf_io_fix io_fix = (enum buf_io_fix) bpage->io_fix;
360
#endif /* UNIV_DEBUG */
364
/*************************************************************************
365
Gets the io_fix state of a block. */
368
buf_block_get_io_fix(
370
/* out: io_fix state */
371
const buf_block_t* block) /* in: pointer to the control block */
373
return(buf_page_get_io_fix(&block->page));
376
/*************************************************************************
377
Sets the io_fix state of a block. */
382
buf_page_t* bpage, /* in/out: control block */
383
enum buf_io_fix io_fix) /* in: io_fix state */
385
ut_ad(buf_pool_mutex_own());
386
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
388
bpage->io_fix = io_fix;
389
ut_ad(buf_page_get_io_fix(bpage) == io_fix);
392
/*************************************************************************
393
Sets the io_fix state of a block. */
396
buf_block_set_io_fix(
397
/*=================*/
398
buf_block_t* block, /* in/out: control block */
399
enum buf_io_fix io_fix) /* in: io_fix state */
401
buf_page_set_io_fix(&block->page, io_fix);
404
/************************************************************************
405
Determine if a buffer block can be relocated in memory. The block
406
can be dirty, but it must not be I/O-fixed or bufferfixed. */
409
buf_page_can_relocate(
410
/*==================*/
411
const buf_page_t* bpage) /* control block being relocated */
413
ut_ad(buf_pool_mutex_own());
414
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
415
ut_ad(buf_page_in_file(bpage));
416
ut_ad(bpage->in_LRU_list);
418
return(buf_page_get_io_fix(bpage) == BUF_IO_NONE
419
&& bpage->buf_fix_count == 0);
422
/*************************************************************************
423
Determine if a block has been flagged old. */
428
/* out: TRUE if old */
429
const buf_page_t* bpage) /* in: control block */
431
ut_ad(buf_page_in_file(bpage));
436
/*************************************************************************
442
buf_page_t* bpage, /* in/out: control block */
443
ibool old) /* in: old */
445
ut_a(buf_page_in_file(bpage));
446
ut_ad(buf_pool_mutex_own());
451
/*************************************************************************
452
Determine if a block has been accessed in the buffer pool. */
455
buf_page_is_accessed(
456
/*=================*/
457
/* out: TRUE if accessed */
458
const buf_page_t* bpage) /* in: control block */
460
ut_ad(buf_page_in_file(bpage));
462
return(bpage->accessed);
465
/*************************************************************************
466
Flag a block accessed. */
469
buf_page_set_accessed(
470
/*==================*/
471
buf_page_t* bpage, /* in/out: control block */
472
ibool accessed) /* in: accessed */
474
ut_a(buf_page_in_file(bpage));
475
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
477
bpage->accessed = accessed;
480
/*************************************************************************
481
Gets the buf_block_t handle of a buffered file block if an uncompressed
482
page frame exists, or NULL. */
487
/* out: control block, or NULL */
488
buf_page_t* bpage) /* in: control block, or NULL */
490
if (UNIV_LIKELY(bpage != NULL)) {
491
ut_ad(buf_page_in_file(bpage));
493
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
494
return((buf_block_t*) bpage);
502
/*************************************************************************
503
Gets a pointer to the memory frame of a block. */
508
/* out: pointer to the frame */
509
const buf_block_t* block) /* in: pointer to the control block */
513
switch (buf_block_get_state(block)) {
514
case BUF_BLOCK_ZIP_FREE:
515
case BUF_BLOCK_ZIP_PAGE:
516
case BUF_BLOCK_ZIP_DIRTY:
517
case BUF_BLOCK_NOT_USED:
520
case BUF_BLOCK_FILE_PAGE:
521
ut_a(block->page.buf_fix_count > 0);
523
case BUF_BLOCK_READY_FOR_USE:
524
case BUF_BLOCK_MEMORY:
525
case BUF_BLOCK_REMOVE_HASH:
530
return((buf_frame_t*) block->frame);
532
#endif /* UNIV_DEBUG */
534
/*************************************************************************
535
Gets the space id of a block. */
541
const buf_page_t* bpage) /* in: pointer to the control block */
544
ut_a(buf_page_in_file(bpage));
546
return(bpage->space);
549
/*************************************************************************
550
Gets the space id of a block. */
556
const buf_block_t* block) /* in: pointer to the control block */
559
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
561
return(block->page.space);
564
/*************************************************************************
565
Gets the page number of a block. */
568
buf_page_get_page_no(
569
/*=================*/
570
/* out: page number */
571
const buf_page_t* bpage) /* in: pointer to the control block */
574
ut_a(buf_page_in_file(bpage));
576
return(bpage->offset);
579
/*************************************************************************
580
Gets the page number of a block. */
583
buf_block_get_page_no(
584
/*==================*/
585
/* out: page number */
586
const buf_block_t* block) /* in: pointer to the control block */
589
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
591
return(block->page.offset);
594
/*************************************************************************
595
Gets the compressed page size of a block. */
598
buf_page_get_zip_size(
599
/*==================*/
600
/* out: compressed page size, or 0 */
601
const buf_page_t* bpage) /* in: pointer to the control block */
603
return(bpage->zip.ssize ? 512 << bpage->zip.ssize : 0);
606
/*************************************************************************
607
Gets the compressed page size of a block. */
610
buf_block_get_zip_size(
611
/*===================*/
612
/* out: compressed page size, or 0 */
613
const buf_block_t* block) /* in: pointer to the control block */
615
return(block->page.zip.ssize ? 512 << block->page.zip.ssize : 0);
618
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
619
/***********************************************************************
620
Gets the block to whose frame the pointer is pointing to. */
625
/* out: pointer to block */
626
const byte* ptr) /* in: pointer to a frame */
628
const buf_block_t* block;
629
ulint space_id, page_no;
631
ptr = (const byte*) ut_align_down(ptr, UNIV_PAGE_SIZE);
632
page_no = mach_read_from_4(ptr + FIL_PAGE_OFFSET);
633
space_id = mach_read_from_4(ptr + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
635
block = (const buf_block_t*) buf_page_hash_get(space_id, page_no);
637
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
638
ut_ad(block->frame == ptr);
642
/*************************************************************************
643
Gets the compressed page descriptor corresponding to an uncompressed page
646
const page_zip_des_t*
647
buf_frame_get_page_zip(
648
/*===================*/
649
/* out: compressed page descriptor, or NULL */
650
const byte* ptr) /* in: pointer to the page */
652
const page_zip_des_t* page_zip;
653
buf_pool_mutex_enter();
654
page_zip = buf_block_get_page_zip(buf_block_align(ptr));
655
buf_pool_mutex_exit();
658
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
660
/**************************************************************************
661
Gets the space id, page offset, and byte offset within page of a
662
pointer pointing to a buffer frame containing a file page. */
665
buf_ptr_get_fsp_addr(
666
/*=================*/
667
const void* ptr, /* in: pointer to a buffer frame */
668
ulint* space, /* out: space id */
669
fil_addr_t* addr) /* out: page offset and byte offset */
671
const page_t* page = (const page_t*) ut_align_down(ptr,
674
*space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
675
addr->page = mach_read_from_4(page + FIL_PAGE_OFFSET);
676
addr->boffset = ut_align_offset(ptr, UNIV_PAGE_SIZE);
679
/**************************************************************************
680
Gets the hash value of the page the pointer is pointing to. This can be used
681
in searches in the lock hash table. */
684
buf_block_get_lock_hash_val(
685
/*========================*/
686
/* out: lock hash value */
687
const buf_block_t* block) /* in: block */
689
return(block->lock_hash_val);
692
/************************************************************************
693
Allocates a buffer block. */
698
/* out, own: the allocated block,
699
in state BUF_BLOCK_MEMORY */
700
ulint zip_size) /* in: compressed page size in bytes,
701
or 0 if uncompressed tablespace */
705
block = buf_LRU_get_free_block(zip_size);
707
buf_block_set_state(block, BUF_BLOCK_MEMORY);
712
/************************************************************************
713
Frees a buffer block which does not contain a file page. */
718
buf_block_t* block) /* in, own: block to be freed */
720
buf_pool_mutex_enter();
722
mutex_enter(&block->mutex);
724
ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
726
buf_LRU_block_free_non_file_page(block);
728
mutex_exit(&block->mutex);
730
buf_pool_mutex_exit();
733
/*************************************************************************
734
Copies contents of a buffer frame to a given buffer. */
740
byte* buf, /* in: buffer to copy to */
741
const buf_frame_t* frame) /* in: buffer frame */
745
ut_memcpy(buf, frame, UNIV_PAGE_SIZE);
750
/************************************************************************
751
Calculates a folded value of a file page address to use in the page hash
755
buf_page_address_fold(
756
/*==================*/
757
/* out: the folded value */
758
ulint space, /* in: space id */
759
ulint offset) /* in: offset of the page within space */
761
return((space << 20) + space + offset);
764
/************************************************************************
765
This function is used to get info if there is an io operation
766
going on on a buffer page. */
771
/* out: TRUE if io going on */
772
buf_page_t* bpage) /* in: buf_pool block, must be bufferfixed */
776
buf_pool_mutex_enter();
778
ut_ad(buf_page_in_file(bpage));
779
ut_ad(bpage->buf_fix_count > 0);
781
io_fixed = buf_page_get_io_fix(bpage) != BUF_IO_NONE;
782
buf_pool_mutex_exit();
787
/************************************************************************
788
Gets the youngest modification log sequence number for a frame.
789
Returns zero if not file page or no modification occurred yet. */
792
buf_page_get_newest_modification(
793
/*=============================*/
794
/* out: newest modification to page */
795
const buf_page_t* bpage) /* in: block containing the
800
buf_pool_mutex_enter();
802
if (buf_page_in_file(bpage)) {
803
lsn = bpage->newest_modification;
808
buf_pool_mutex_exit();
813
/************************************************************************
814
Increments the modify clock of a frame by 1. The caller must (1) own the
815
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
819
buf_block_modify_clock_inc(
820
/*=======================*/
821
buf_block_t* block) /* in: block */
823
#ifdef UNIV_SYNC_DEBUG
824
ut_ad((buf_pool_mutex_own()
825
&& (block->page.buf_fix_count == 0))
826
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
827
#endif /* UNIV_SYNC_DEBUG */
829
block->modify_clock++;
832
/************************************************************************
833
Returns the value of the modify clock. The caller must have an s-lock
834
or x-lock on the block. */
837
buf_block_get_modify_clock(
838
/*=======================*/
840
buf_block_t* block) /* in: block */
842
#ifdef UNIV_SYNC_DEBUG
843
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
844
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
845
#endif /* UNIV_SYNC_DEBUG */
847
return(block->modify_clock);
850
/***********************************************************************
851
Increments the bufferfix count. */
854
buf_block_buf_fix_inc_func(
855
/*=======================*/
856
#ifdef UNIV_SYNC_DEBUG
857
const char* file, /* in: file name */
858
ulint line, /* in: line */
859
#endif /* UNIV_SYNC_DEBUG */
860
buf_block_t* block) /* in: block to bufferfix */
862
#ifdef UNIV_SYNC_DEBUG
865
ret = rw_lock_s_lock_func_nowait(&(block->debug_latch), file, line);
867
#endif /* UNIV_SYNC_DEBUG */
868
ut_ad(mutex_own(&block->mutex));
870
block->page.buf_fix_count++;
872
#ifdef UNIV_SYNC_DEBUG
873
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
874
#else /* UNIV_SYNC_DEBUG */
875
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
876
#endif /* UNIV_SYNC_DEBUG */
878
/***********************************************************************
879
Decrements the bufferfix count. */
882
buf_block_buf_fix_dec(
883
/*==================*/
884
buf_block_t* block) /* in: block to bufferunfix */
886
ut_ad(mutex_own(&block->mutex));
888
block->page.buf_fix_count--;
889
#ifdef UNIV_SYNC_DEBUG
890
rw_lock_s_unlock(&block->debug_latch);
894
/**********************************************************************
895
Returns the control block of a file page, NULL if not found. */
900
/* out: block, NULL if not found */
901
ulint space, /* in: space id */
902
ulint offset) /* in: offset of the page within space */
908
ut_ad(buf_pool_mutex_own());
910
/* Look for the page in the hash table */
912
fold = buf_page_address_fold(space, offset);
914
HASH_SEARCH(hash, buf_pool->page_hash, fold, buf_page_t*, bpage,
915
bpage->space == space && bpage->offset == offset);
917
ut_a(buf_page_in_file(bpage));
918
ut_ad(bpage->in_page_hash);
919
ut_ad(!bpage->in_zip_hash);
920
UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
926
/**********************************************************************
927
Returns the control block of a file page, NULL if not found
928
or an uncompressed page frame does not exist. */
933
/* out: block, NULL if not found */
934
ulint space, /* in: space id */
935
ulint offset) /* in: offset of the page within space */
937
return(buf_page_get_block(buf_page_hash_get(space, offset)));
940
/************************************************************************
941
Returns TRUE if the page can be found in the buffer pool hash table. NOTE
942
that it is possible that the page is not yet read from disk, though. */
947
/* out: TRUE if found from page hash table,
948
NOTE that the page is not necessarily yet read
950
ulint space, /* in: space id */
951
ulint offset) /* in: page number */
953
const buf_page_t* bpage;
955
buf_pool_mutex_enter();
957
bpage = buf_page_hash_get(space, offset);
959
buf_pool_mutex_exit();
961
return(bpage != NULL);
964
/************************************************************************
965
Releases a compressed-only page acquired with buf_page_get_zip(). */
968
buf_page_release_zip(
969
/*=================*/
970
buf_page_t* bpage) /* in: buffer block */
975
ut_a(bpage->buf_fix_count > 0);
977
switch (buf_page_get_state(bpage)) {
978
case BUF_BLOCK_ZIP_PAGE:
979
case BUF_BLOCK_ZIP_DIRTY:
980
mutex_enter(&buf_pool_zip_mutex);
981
bpage->buf_fix_count--;
982
mutex_exit(&buf_pool_zip_mutex);
984
case BUF_BLOCK_FILE_PAGE:
985
block = (buf_block_t*) bpage;
986
mutex_enter(&block->mutex);
987
#ifdef UNIV_SYNC_DEBUG
988
rw_lock_s_unlock(&block->debug_latch);
990
bpage->buf_fix_count--;
991
mutex_exit(&block->mutex);
993
case BUF_BLOCK_ZIP_FREE:
994
case BUF_BLOCK_NOT_USED:
995
case BUF_BLOCK_READY_FOR_USE:
996
case BUF_BLOCK_MEMORY:
997
case BUF_BLOCK_REMOVE_HASH:
1004
/************************************************************************
1005
Decrements the bufferfix count of a buffer control block and releases
1006
a latch, if specified. */
1011
buf_block_t* block, /* in: buffer block */
1012
ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH,
1014
mtr_t* mtr) /* in: mtr */
1018
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1019
ut_a(block->page.buf_fix_count > 0);
1021
if (rw_latch == RW_X_LATCH && mtr->modifications) {
1022
buf_pool_mutex_enter();
1023
buf_flush_note_modification(block, mtr);
1024
buf_pool_mutex_exit();
1027
mutex_enter(&block->mutex);
1029
#ifdef UNIV_SYNC_DEBUG
1030
rw_lock_s_unlock(&(block->debug_latch));
1032
block->page.buf_fix_count--;
1034
mutex_exit(&block->mutex);
1036
if (rw_latch == RW_S_LATCH) {
1037
rw_lock_s_unlock(&(block->lock));
1038
} else if (rw_latch == RW_X_LATCH) {
1039
rw_lock_x_unlock(&(block->lock));
1043
#ifdef UNIV_SYNC_DEBUG
1044
/*************************************************************************
1045
Adds latch level info for the rw-lock protecting the buffer frame. This
1046
should be called in the debug version after a successful latching of a
1047
page if we know the latching order level of the acquired latch. */
1050
buf_block_dbg_add_level(
1051
/*====================*/
1052
buf_block_t* block, /* in: buffer page
1053
where we have acquired latch */
1054
ulint level) /* in: latching order level */
1056
sync_thread_add_level(&block->lock, level);
1058
#endif /* UNIV_SYNC_DEBUG */