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_flush_list_mutex_own(buf_pool));
81	ut_ad(!mtr->made_dirty || log_flush_order_mutex_own());
82
83	ut_ad(mtr->start_lsn != 0);
84	ut_ad(mtr->modifications);
85
86	mutex_enter(&block->mutex);
87	ut_ad(block->page.newest_modification <= mtr->end_lsn);
88
89	block->page.newest_modification = mtr->end_lsn;
90
91	if (!block->page.oldest_modification) {
92		ut_a(mtr->made_dirty);
93		ut_ad(log_flush_order_mutex_own());
94		buf_flush_insert_into_flush_list(
95			buf_pool, block, mtr->start_lsn);
96	} else {
97		ut_ad(block->page.oldest_modification <= mtr->start_lsn);
98	}
99
100	mutex_exit(&block->mutex);
101
102	srv_stats.buf_pool_write_requests.inc();
103}
104
105/********************************************************************//**
106This function should be called when recovery has modified a buffer page. */
107UNIV_INLINE
108void
109buf_flush_recv_note_modification(
110/*=============================*/
111	buf_block_t*	block,		/*!< in: block which is modified */
112	lsn_t		start_lsn,	/*!< in: start lsn of the first mtr in a
113					set of mtr's */
114	lsn_t		end_lsn)	/*!< in: end lsn of the last mtr in the
115					set of mtr's */
116{
117	buf_pool_t*	buf_pool = buf_pool_from_block(block);
118
119	ut_ad(!srv_read_only_mode);
120	ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
121	ut_ad(block->page.buf_fix_count > 0);
122#ifdef UNIV_SYNC_DEBUG
123	ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
124#endif /* UNIV_SYNC_DEBUG */
125
126	ut_ad(!buf_flush_list_mutex_own(buf_pool));
127	ut_ad(log_flush_order_mutex_own());
128
129	ut_ad(start_lsn != 0);
130	ut_ad(block->page.newest_modification <= end_lsn);
131
132	mutex_enter(&block->mutex);
133	block->page.newest_modification = end_lsn;
134
135	if (!block->page.oldest_modification) {
136		buf_flush_insert_sorted_into_flush_list(
137			buf_pool, block, start_lsn);
138	} else {
139		ut_ad(block->page.oldest_modification <= start_lsn);
140	}
141
142	mutex_exit(&block->mutex);
143
144}
145#endif /* !UNIV_HOTBACKUP */
146
147/******************************************************************//**
148Check if a flush list flush is in progress for any buffer pool instance, or if
149all the instances are clean, for heuristic purposes.
150@return true if flush list flush is in progress or buffer pool is clean */
151UNIV_INLINE
152bool
153buf_flush_flush_list_in_progress(void)
154/*==================================*/
155{
156	bool	all_clean = true;
157
158	for (ulint i = 0; i < srv_buf_pool_instances; i++) {
159
160		const buf_pool_t* buf_pool = buf_pool_from_array(i);
161		if (buf_pool->init_flush[BUF_FLUSH_LIST]
162		    || buf_pool->n_flush[BUF_FLUSH_LIST]) {
163
164			return(true);
165		}
166
167		if (all_clean) {
168
169			all_clean = (UT_LIST_GET_LEN(buf_pool->flush_list)
170				     == 0);
171		}
172
173	}
174	return(all_clean);
175}
176