Merge lp:~laurynas-biveinis/percona-server/bug1417953 into lp:percona-server/5.6

Proposed by Laurynas Biveinis on 2015-02-04
Status: Merged
Approved by: Laurynas Biveinis on 2015-02-04
Approved revision: 734
Merged at revision: 734
Proposed branch: lp:~laurynas-biveinis/percona-server/bug1417953
Merge into: lp:percona-server/5.6
Diff against target: 191 lines (+14/-25)
8 files modified
storage/innobase/buf/buf0buf.cc (+2/-10)
storage/innobase/buf/buf0flu.cc (+4/-2)
storage/innobase/buf/buf0lru.cc (+1/-1)
storage/innobase/buf/buf0rea.cc (+5/-3)
storage/innobase/handler/ha_innodb.cc (+0/-1)
storage/innobase/handler/i_s.cc (+0/-5)
storage/innobase/include/buf0flu.h (+2/-2)
storage/innobase/include/sync0sync.h (+0/-1)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/bug1417953
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve on 2015-02-04
Review via email: mp+248530@code.launchpad.net

Description of the change

Fix bug 1417953 (buf_read_ahead_linear dereferences buffer page
pointer without protection).

Fix by protecting the bpage dereference with page hash S latch.

At the same time fix some other issues discovered while porting to
5.7:
- remove unused buf_pool_mutex_key PFS instrumentation variable;
- remove zip mutex locking from buf_pool_watch_set and
  buf_pool_watch_remove, as the watch pages are already protected by
  page hash X latch;
- fix some comments;
- fix some bool variables getting assigned TRUE instead of true.

http://jenkins.percona.com/job/percona-server-5.6-param/802/

To post a comment you must log in.
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'storage/innobase/buf/buf0buf.cc'
2--- storage/innobase/buf/buf0buf.cc 2014-12-30 14:14:11 +0000
3+++ storage/innobase/buf/buf0buf.cc 2015-02-04 11:23:44 +0000
4@@ -294,7 +294,6 @@
5
6 #ifdef UNIV_PFS_MUTEX
7 UNIV_INTERN mysql_pfs_key_t buffer_block_mutex_key;
8-UNIV_INTERN mysql_pfs_key_t buf_pool_mutex_key;
9 UNIV_INTERN mysql_pfs_key_t buf_pool_zip_mutex_key;
10 UNIV_INTERN mysql_pfs_key_t buf_pool_flush_state_mutex_key;
11 UNIV_INTERN mysql_pfs_key_t buf_pool_LRU_list_mutex_key;
12@@ -1735,16 +1734,12 @@
13 ut_ad(!bpage->in_page_hash);
14 ut_ad(bpage->buf_fix_count == 0);
15
16- mutex_enter(&buf_pool->zip_mutex);
17-
18 bpage->state = BUF_BLOCK_ZIP_PAGE;
19 bpage->space = static_cast<ib_uint32_t>(space);
20 bpage->offset = static_cast<ib_uint32_t>(offset);
21 bpage->buf_fix_count = 1;
22 bpage->buf_pool_index = buf_pool_index(buf_pool);
23
24- mutex_exit(&buf_pool->zip_mutex);
25-
26 ut_d(bpage->in_page_hash = TRUE);
27 HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
28 fold, bpage);
29@@ -1796,7 +1791,6 @@
30 #endif /* UNIV_SYNC_DEBUG */
31
32 ut_ad(buf_page_get_state(watch) == BUF_BLOCK_ZIP_PAGE);
33- ut_ad(buf_own_zip_mutex_for_page(watch));
34
35 HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, watch);
36 ut_d(watch->in_page_hash = FALSE);
37@@ -1839,9 +1833,7 @@
38 #endif /* PAGE_ATOMIC_REF_COUNT */
39
40 if (bpage->buf_fix_count == 0) {
41- mutex_enter(&buf_pool->zip_mutex);
42 buf_pool_watch_remove(buf_pool, fold, bpage);
43- mutex_exit(&buf_pool->zip_mutex);
44 }
45 }
46
47@@ -4421,7 +4413,7 @@
48 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
49 buf_page_get_flush_type(bpage) == BUF_FLUSH_LRU)) {
50
51- have_LRU_mutex = TRUE; /* optimistic */
52+ have_LRU_mutex = true; /* optimistic */
53 }
54 retry_mutex:
55 if (have_LRU_mutex) {
56@@ -4441,7 +4433,7 @@
57 && !have_LRU_mutex)) {
58
59 mutex_exit(block_mutex);
60- have_LRU_mutex = TRUE;
61+ have_LRU_mutex = true;
62 goto retry_mutex;
63 }
64
65
66=== modified file 'storage/innobase/buf/buf0flu.cc'
67--- storage/innobase/buf/buf0flu.cc 2014-12-16 06:00:17 +0000
68+++ storage/innobase/buf/buf0flu.cc 2015-02-04 11:23:44 +0000
69@@ -1098,8 +1098,8 @@
70 # if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
71 /********************************************************************//**
72 Writes a flushable page asynchronously from the buffer pool to a file.
73-NOTE: block->mutex must be held upon entering this function, and it will be
74-released by this function after flushing. This is loosely based on
75+NOTE: block and LRU list mutexes must be held upon entering this function, and
76+they will be released by this function after flushing. This is loosely based on
77 buf_flush_batch() and buf_flush_page().
78 @return TRUE if the page was flushed and the mutexes released */
79 UNIV_INTERN
80@@ -1653,6 +1653,8 @@
81 flush_counters_t* n) /*!< out: flushed/evicted page
82 counts */
83 {
84+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
85+
86 if (buf_LRU_evict_from_unzip_LRU(buf_pool)) {
87 n->unzip_LRU_evicted
88 = buf_free_from_unzip_LRU_list_batch(buf_pool, max);
89
90=== modified file 'storage/innobase/buf/buf0lru.cc'
91--- storage/innobase/buf/buf0lru.cc 2014-12-01 07:53:48 +0000
92+++ storage/innobase/buf/buf0lru.cc 2015-02-04 11:23:44 +0000
93@@ -526,7 +526,7 @@
94
95 mutex_exit(block_mutex);
96
97- *must_restart = TRUE;
98+ *must_restart = true;
99 processed = false;
100
101 } else if (!flush) {
102
103=== modified file 'storage/innobase/buf/buf0rea.cc'
104--- storage/innobase/buf/buf0rea.cc 2014-12-01 07:53:48 +0000
105+++ storage/innobase/buf/buf0rea.cc 2015-02-04 11:23:44 +0000
106@@ -640,10 +640,10 @@
107
108 fail_count = 0;
109
110+ prio_rw_lock_t* hash_lock;
111+
112 for (i = low; i < high; i++) {
113
114- prio_rw_lock_t* hash_lock;
115-
116 bpage = buf_page_hash_get_s_locked(buf_pool, space, i,
117 &hash_lock);
118
119@@ -691,7 +691,7 @@
120 /* If we got this far, we know that enough pages in the area have
121 been accessed in the right order: linear read-ahead can be sensible */
122
123- bpage = buf_page_hash_get(buf_pool, space, offset);
124+ bpage = buf_page_hash_get_s_locked(buf_pool, space, offset, &hash_lock);
125
126 if (bpage == NULL) {
127
128@@ -719,6 +719,8 @@
129 pred_offset = fil_page_get_prev(frame);
130 succ_offset = fil_page_get_next(frame);
131
132+ rw_lock_s_unlock(hash_lock);
133+
134 if ((offset == low) && (succ_offset == offset + 1)) {
135
136 /* This is ok, we can continue */
137
138=== modified file 'storage/innobase/handler/ha_innodb.cc'
139--- storage/innobase/handler/ha_innodb.cc 2014-12-16 06:00:17 +0000
140+++ storage/innobase/handler/ha_innodb.cc 2015-02-04 11:23:44 +0000
141@@ -340,7 +340,6 @@
142 # ifndef PFS_SKIP_BUFFER_MUTEX_RWLOCK
143 {&buffer_block_mutex_key, "buffer_block_mutex", 0},
144 # endif /* !PFS_SKIP_BUFFER_MUTEX_RWLOCK */
145- {&buf_pool_mutex_key, "buf_pool_mutex", 0},
146 {&buf_pool_zip_mutex_key, "buf_pool_zip_mutex", 0},
147 {&buf_pool_LRU_list_mutex_key, "buf_pool_LRU_list_mutex", 0},
148 {&buf_pool_free_list_mutex_key, "buf_pool_free_list_mutex", 0},
149
150=== modified file 'storage/innobase/handler/i_s.cc'
151--- storage/innobase/handler/i_s.cc 2014-12-01 07:53:48 +0000
152+++ storage/innobase/handler/i_s.cc 2015-02-04 11:23:44 +0000
153@@ -5279,11 +5279,6 @@
154 info_buffer = (buf_page_info_t*) mem_heap_zalloc(
155 heap, mem_size);
156
157- /* Obtain appropriate mutexes. Since this is diagnostic
158- buffer pool info printout, we are not required to
159- preserve the overall consistency, so we can
160- release mutex periodically */
161-
162 /* GO through each block in the chunk */
163 for (n_blocks = num_to_process; n_blocks--; block++) {
164 i_s_innodb_buffer_page_get_info(
165
166=== modified file 'storage/innobase/include/buf0flu.h'
167--- storage/innobase/include/buf0flu.h 2014-12-01 07:53:48 +0000
168+++ storage/innobase/include/buf0flu.h 2015-02-04 11:23:44 +0000
169@@ -78,8 +78,8 @@
170 # if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
171 /********************************************************************//**
172 Writes a flushable page asynchronously from the buffer pool to a file.
173-NOTE: block->mutex must be held upon entering this function, and they will be
174-released by this function after flushing. This is loosely based on
175+NOTE: block and LRU list mutexes must be held upon entering this function, and
176+they will be released by this function after flushing. This is loosely based on
177 buf_flush_batch() and buf_flush_page().
178 @return TRUE if the page was flushed and the mutexes released */
179 UNIV_INTERN
180
181=== modified file 'storage/innobase/include/sync0sync.h'
182--- storage/innobase/include/sync0sync.h 2014-12-01 07:53:48 +0000
183+++ storage/innobase/include/sync0sync.h 2015-02-04 11:23:44 +0000
184@@ -71,7 +71,6 @@
185 /* Key defines to register InnoDB mutexes with performance schema */
186 extern mysql_pfs_key_t autoinc_mutex_key;
187 extern mysql_pfs_key_t buffer_block_mutex_key;
188-extern mysql_pfs_key_t buf_pool_mutex_key;
189 extern mysql_pfs_key_t buf_pool_zip_mutex_key;
190 extern mysql_pfs_key_t buf_pool_LRU_list_mutex_key;
191 extern mysql_pfs_key_t buf_pool_free_list_mutex_key;

Subscribers

People subscribed via source and target branches