1/*****************************************************************************
2
3Copyright (c) 1995, 2009, Oracle and/or its affiliates. All Rights Reserved.
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License, version 2.0,
7as published by the Free Software Foundation.
8
9This program is also distributed with certain software (including
10but not limited to OpenSSL) that is licensed under separate terms,
11as designated in a particular file or component or in included license
12documentation.  The authors of MySQL hereby grant you an additional
13permission to link the program and your derivative works with the
14separately licensed software that they have included with MySQL.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU General Public License, version 2.0, for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24
25*****************************************************************************/
26
27/**************************************************//**
28@file include/buf0flu.ic
29The database buffer pool flush algorithm
30
31Created 11/5/1995 Heikki Tuuri
32*******************************************************/
33
34#ifndef UNIV_HOTBACKUP
35#include "buf0buf.h"
36#include "mtr0mtr.h"
37#include "srv0srv.h"
38
39/********************************************************************//**
40Inserts a modified block into the flush list. */
41UNIV_INTERN
42void
43buf_flush_insert_into_flush_list(
44/*=============================*/
45	buf_pool_t*	buf_pool,	/*!< buffer pool instance */
46	buf_block_t*	block,		/*!< in/out: block which is modified */
47	lsn_t		lsn);		/*!< in: oldest modification */
48/********************************************************************//**
49Inserts a modified block into the flush list in the right sorted position.
50This function is used by recovery, because there the modifications do not
51necessarily come in the order of lsn's. */
52UNIV_INTERN
53void
54buf_flush_insert_sorted_into_flush_list(
55/*====================================*/
56	buf_pool_t*	buf_pool,	/*!< buffer pool instance */
57	buf_block_t*	block,		/*!< in/out: block which is modified */
58	lsn_t		lsn);		/*!< in: oldest modification */
59
60/********************************************************************//**
61This function should be called at a mini-transaction commit, if a page was
62modified in it. Puts the block to the list of modified blocks, if it is not
63already in it. */
64UNIV_INLINE
65void
66buf_flush_note_modification(
67/*========================*/
68	buf_block_t*	block,	/*!< in: block which is modified */
69	mtr_t*		mtr)	/*!< in: mtr */
70{
71	buf_pool_t*	buf_pool = buf_pool_from_block(block);
72
73	ut_ad(!srv_read_only_mode);
74	ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
75	ut_ad(block->page.buf_fix_count > 0);
76#ifdef UNIV_SYNC_DEBUG
77	ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
78#endif /* UNIV_SYNC_DEBUG */
79
80	ut_ad(!buf_pool_mutex_own(buf_pool));
81	ut_ad(!buf_flush_list_mutex_own(buf_pool));
82	ut_ad(!mtr->made_dirty || log_flush_order_mutex_own());
83
84	ut_ad(mtr->start_lsn != 0);
85	ut_ad(mtr->modifications);
86
87	mutex_enter(&block->mutex);
88	ut_ad(block->page.newest_modification <= mtr->end_lsn);
89
90	block->page.newest_modification = mtr->end_lsn;
91
92	if (!block->page.oldest_modification) {
93		ut_a(mtr->made_dirty);
94		ut_ad(log_flush_order_mutex_own());
95		buf_flush_insert_into_flush_list(
96			buf_pool, block, mtr->start_lsn);
97	} else {
98		ut_ad(block->page.oldest_modification <= mtr->start_lsn);
99	}
100
101	mutex_exit(&block->mutex);
102
103	srv_stats.buf_pool_write_requests.inc();
104}
105
106/********************************************************************//**
107This function should be called when recovery has modified a buffer page. */
108UNIV_INLINE
109void
110buf_flush_recv_note_modification(
111/*=============================*/
112	buf_block_t*	block,		/*!< in: block which is modified */
113	lsn_t		start_lsn,	/*!< in: start lsn of the first mtr in a
114					set of mtr's */
115	lsn_t		end_lsn)	/*!< in: end lsn of the last mtr in the
116					set of mtr's */
117{
118	buf_pool_t*	buf_pool = buf_pool_from_block(block);
119
120	ut_ad(!srv_read_only_mode);
121	ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
122	ut_ad(block->page.buf_fix_count > 0);
123#ifdef UNIV_SYNC_DEBUG
124	ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
125#endif /* UNIV_SYNC_DEBUG */
126
127	ut_ad(!buf_pool_mutex_own(buf_pool));
128	ut_ad(!buf_flush_list_mutex_own(buf_pool));
129	ut_ad(log_flush_order_mutex_own());
130
131	ut_ad(start_lsn != 0);
132	ut_ad(block->page.newest_modification <= end_lsn);
133
134	mutex_enter(&block->mutex);
135	block->page.newest_modification = end_lsn;
136
137	if (!block->page.oldest_modification) {
138		buf_flush_insert_sorted_into_flush_list(
139			buf_pool, block, start_lsn);
140	} else {
141		ut_ad(block->page.oldest_modification <= start_lsn);
142	}
143
144	mutex_exit(&block->mutex);
145
146}
147#endif /* !UNIV_HOTBACKUP */
148