641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
1 |
/*****************************************************************************
|
2 |
||
1999.6.1
by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file |
3 |
Copyright (C) 2007, 2010, Innobase Oy. All Rights Reserved.
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
4 |
|
5 |
This program is free software; you can redistribute it and/or modify it under
|
|
6 |
the terms of the GNU General Public License as published by the Free Software
|
|
7 |
Foundation; version 2 of the License.
|
|
8 |
||
9 |
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
10 |
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
11 |
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
12 |
||
13 |
You should have received a copy of the GNU General Public License along with
|
|
1802.10.2
by Monty Taylor
Update all of the copyright headers to include the correct address. |
14 |
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
15 |
St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
16 |
|
17 |
*****************************************************************************/
|
|
18 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
19 |
/**************************************************//**
|
20 |
@file trx/trx0i_s.c
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
21 |
INFORMATION SCHEMA innodb_trx, innodb_locks and
|
22 |
innodb_lock_waits tables fetch code.
|
|
23 |
||
24 |
The code below fetches information needed to fill those
|
|
25 |
3 dynamic tables and uploads it into a "transactions
|
|
26 |
table cache" for later retrieval.
|
|
27 |
||
28 |
Created July 17, 2007 Vasil Dimov
|
|
29 |
*******************************************************/
|
|
30 |
||
1720.1.7
by Monty Taylor
Fixed the ICC missing header and the new config.h foo. |
31 |
#include "config.h" |
1819.5.252
by vdimov
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6861 from MySQL InnoDB |
32 |
/* Found during the build of 5.5.3 on Linux 2.4 and early 2.6 kernels:
|
33 |
The includes "univ.i" -> "my_global.h" cause a different path
|
|
34 |
to be taken further down with pthread functions and types,
|
|
35 |
so they must come first.
|
|
36 |
From the symptoms, this is related to bug#46587 in the MySQL bug DB.
|
|
37 |
*/
|
|
38 |
#include "univ.i" |
|
1720.1.7
by Monty Taylor
Fixed the ICC missing header and the new config.h foo. |
39 |
|
1114.1.1
by Monty Taylor
Merged InnoDB Plugin 1.0.4 |
40 |
#if !defined(BUILD_DRIZZLE)
|
41 |
# include <mysql/plugin.h>
|
|
42 |
#endif
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
43 |
|
44 |
#include "mysql_addons.h" |
|
45 |
||
46 |
#include "buf0buf.h" |
|
47 |
#include "dict0dict.h" |
|
48 |
#include "ha0storage.h" |
|
49 |
#include "ha_prototypes.h" |
|
50 |
#include "hash0hash.h" |
|
51 |
#include "lock0iter.h" |
|
52 |
#include "lock0lock.h" |
|
53 |
#include "mem0mem.h" |
|
54 |
#include "page0page.h" |
|
55 |
#include "rem0rec.h" |
|
56 |
#include "row0row.h" |
|
57 |
#include "srv0srv.h" |
|
58 |
#include "sync0rw.h" |
|
59 |
#include "sync0sync.h" |
|
60 |
#include "sync0types.h" |
|
61 |
#include "trx0i_s.h" |
|
62 |
#include "trx0sys.h" |
|
63 |
#include "trx0trx.h" |
|
64 |
#include "ut0mem.h" |
|
65 |
#include "ut0ut.h" |
|
66 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
67 |
/** Initial number of rows in the table cache */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
68 |
#define TABLE_CACHE_INITIAL_ROWSNUM 1024
|
69 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
70 |
/** @brief The maximum number of chunks to allocate for a table cache.
|
71 |
||
72 |
The rows of a table cache are stored in a set of chunks. When a new
|
|
1819.5.127
by stewart at flamingspork
[patch 127/129] Merge patch for revision 1945 from InnoDB SVN: |
73 |
row is added a new chunk is allocated if necessary. Assuming that the
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
74 |
first one is 1024 rows (TABLE_CACHE_INITIAL_ROWSNUM) and each
|
75 |
subsequent is N/2 where N is the number of rows we have allocated till
|
|
76 |
now, then 39th chunk would accommodate 1677416425 rows and all chunks
|
|
77 |
would accommodate 3354832851 rows. */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
78 |
#define MEM_CHUNKS_IN_TABLE_CACHE 39
|
79 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
80 |
/** The following are some testing auxiliary macros. Do not enable them
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
81 |
in a production environment. */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
82 |
/* @{ */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
83 |
|
84 |
#if 0
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
85 |
/** If this is enabled then lock folds will always be different
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
86 |
resulting in equal rows being put in a different cells of the hash
|
87 |
table. Checking for duplicates will be flawed because different
|
|
88 |
fold will be calculated when a row is searched in the hash table. */
|
|
89 |
#define TEST_LOCK_FOLD_ALWAYS_DIFFERENT
|
|
90 |
#endif
|
|
91 |
||
92 |
#if 0
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
93 |
/** This effectively kills the search-for-duplicate-before-adding-a-row
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
94 |
function, but searching in the hash is still performed. It will always
|
95 |
be assumed that lock is not present and insertion will be performed in
|
|
96 |
the hash table. */
|
|
97 |
#define TEST_NO_LOCKS_ROW_IS_EVER_EQUAL_TO_LOCK_T
|
|
98 |
#endif
|
|
99 |
||
100 |
#if 0
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
101 |
/** This aggressively repeats adding each row many times. Depending on
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
102 |
the above settings this may be noop or may result in lots of rows being
|
103 |
added. */
|
|
104 |
#define TEST_ADD_EACH_LOCKS_ROW_MANY_TIMES
|
|
105 |
#endif
|
|
106 |
||
107 |
#if 0
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
108 |
/** Very similar to TEST_NO_LOCKS_ROW_IS_EVER_EQUAL_TO_LOCK_T but hash
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
109 |
table search is not performed at all. */
|
110 |
#define TEST_DO_NOT_CHECK_FOR_DUPLICATE_ROWS
|
|
111 |
#endif
|
|
112 |
||
113 |
#if 0
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
114 |
/** Do not insert each row into the hash table, duplicates may appear
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
115 |
if this is enabled, also if this is enabled searching into the hash is
|
116 |
noop because it will be empty. */
|
|
117 |
#define TEST_DO_NOT_INSERT_INTO_THE_HASH_TABLE
|
|
118 |
#endif
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
119 |
/* @} */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
120 |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
121 |
/** Memory limit passed to ha_storage_put_memlim().
|
122 |
@param cache hash storage
|
|
123 |
@return maximum allowed allocation size */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
124 |
#define MAX_ALLOWED_FOR_STORAGE(cache) \
|
125 |
(TRX_I_S_MEM_LIMIT \
|
|
126 |
- (cache)->mem_allocd)
|
|
127 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
128 |
/** Memory limit in table_cache_create_empty_row().
|
129 |
@param cache hash storage
|
|
130 |
@return maximum allowed allocation size */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
131 |
#define MAX_ALLOWED_FOR_ALLOC(cache) \
|
132 |
(TRX_I_S_MEM_LIMIT \
|
|
133 |
- (cache)->mem_allocd \
|
|
134 |
- ha_storage_get_size((cache)->storage))
|
|
135 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
136 |
/** Memory for each table in the intermediate buffer is allocated in
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
137 |
separate chunks. These chunks are considered to be concatenated to
|
138 |
represent one flat array of rows. */
|
|
139 |
typedef struct i_s_mem_chunk_struct { |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
140 |
ulint offset; /*!< offset, in number of rows */ |
141 |
ulint rows_allocd; /*!< the size of this chunk, in number |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
142 |
of rows */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
143 |
void* base; /*!< start of the chunk */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
144 |
} i_s_mem_chunk_t; |
145 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
146 |
/** This represents one table's cache. */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
147 |
typedef struct i_s_table_cache_struct { |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
148 |
ulint rows_used; /*!< number of used rows */ |
149 |
ulint rows_allocd; /*!< number of allocated rows */ |
|
150 |
ulint row_size; /*!< size of a single row */ |
|
151 |
i_s_mem_chunk_t chunks[MEM_CHUNKS_IN_TABLE_CACHE]; /*!< array of |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
152 |
memory chunks that stores the
|
153 |
rows */
|
|
154 |
} i_s_table_cache_t; |
|
155 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
156 |
/** This structure describes the intermediate buffer */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
157 |
struct trx_i_s_cache_struct { |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
158 |
rw_lock_t rw_lock; /*!< read-write lock protecting |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
159 |
the rest of this structure */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
160 |
ullint last_read; /*!< last time the cache was read; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
161 |
measured in microseconds since
|
162 |
epoch */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
163 |
mutex_t last_read_mutex;/*!< mutex protecting the |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
164 |
last_read member - it is updated
|
165 |
inside a shared lock of the
|
|
166 |
rw_lock member */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
167 |
i_s_table_cache_t innodb_trx; /*!< innodb_trx table */ |
168 |
i_s_table_cache_t innodb_locks; /*!< innodb_locks table */ |
|
169 |
i_s_table_cache_t innodb_lock_waits;/*!< innodb_lock_waits table */ |
|
170 |
/** the hash table size is LOCKS_HASH_CELLS_NUM * sizeof(void*) bytes */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
171 |
#define LOCKS_HASH_CELLS_NUM 10000
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
172 |
hash_table_t* locks_hash; /*!< hash table used to eliminate |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
173 |
duplicate entries in the
|
174 |
innodb_locks table */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
175 |
/** Initial size of the cache storage */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
176 |
#define CACHE_STORAGE_INITIAL_SIZE 1024
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
177 |
/** Number of hash cells in the cache storage */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
178 |
#define CACHE_STORAGE_HASH_CELLS 2048
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
179 |
ha_storage_t* storage; /*!< storage for external volatile |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
180 |
data that can possibly not be
|
181 |
available later, when we release
|
|
182 |
the kernel mutex */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
183 |
ulint mem_allocd; /*!< the amount of memory |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
184 |
allocated with mem_alloc*() */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
185 |
ibool is_truncated; /*!< this is TRUE if the memory |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
186 |
limit was hit and thus the data
|
187 |
in the cache is truncated */
|
|
188 |
};
|
|
189 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
190 |
/** This is the intermediate buffer where data needed to fill the
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
191 |
INFORMATION SCHEMA tables is fetched and later retrieved by the C++
|
192 |
code in handler/i_s.cc. */
|
|
193 |
static trx_i_s_cache_t trx_i_s_cache_static; |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
194 |
/** This is the intermediate buffer where data needed to fill the
|
195 |
INFORMATION SCHEMA tables is fetched and later retrieved by the C++
|
|
196 |
code in handler/i_s.cc. */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
197 |
UNIV_INTERN trx_i_s_cache_t* trx_i_s_cache = &trx_i_s_cache_static; |
198 |
||
1819.7.68
by Stewart Smith
Merge initial InnoDB+ import. |
199 |
/* Key to register the lock/mutex with performance schema */
|
200 |
#ifdef UNIV_PFS_RWLOCK
|
|
201 |
UNIV_INTERN mysql_pfs_key_t trx_i_s_cache_lock_key; |
|
202 |
#endif /* UNIV_PFS_RWLOCK */ |
|
203 |
||
204 |
#ifdef UNIV_PFS_MUTEX
|
|
205 |
UNIV_INTERN mysql_pfs_key_t cache_last_read_mutex_key; |
|
206 |
#endif /* UNIV_PFS_MUTEX */ |
|
207 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
208 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
209 |
For a record lock that is in waiting state retrieves the only bit that
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
210 |
is set, for a table lock returns ULINT_UNDEFINED.
|
211 |
@return record number within the heap */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
212 |
static
|
213 |
ulint
|
|
214 |
wait_lock_get_heap_no( |
|
215 |
/*==================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
216 |
const lock_t* lock) /*!< in: lock */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
217 |
{
|
218 |
ulint ret; |
|
219 |
||
220 |
switch (lock_get_type(lock)) { |
|
221 |
case LOCK_REC: |
|
222 |
ret = lock_rec_find_set_bit(lock); |
|
223 |
ut_a(ret != ULINT_UNDEFINED); |
|
224 |
break; |
|
225 |
case LOCK_TABLE: |
|
226 |
ret = ULINT_UNDEFINED; |
|
227 |
break; |
|
228 |
default: |
|
229 |
ut_error; |
|
230 |
}
|
|
231 |
||
232 |
return(ret); |
|
233 |
}
|
|
234 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
235 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
236 |
Initializes the members of a table cache. */
|
237 |
static
|
|
238 |
void
|
|
239 |
table_cache_init( |
|
240 |
/*=============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
241 |
i_s_table_cache_t* table_cache, /*!< out: table cache */ |
242 |
size_t row_size) /*!< in: the size of a |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
243 |
row */
|
244 |
{
|
|
245 |
ulint i; |
|
246 |
||
247 |
table_cache->rows_used = 0; |
|
248 |
table_cache->rows_allocd = 0; |
|
249 |
table_cache->row_size = row_size; |
|
250 |
||
251 |
for (i = 0; i < MEM_CHUNKS_IN_TABLE_CACHE; i++) { |
|
252 |
||
253 |
/* the memory is actually allocated in
|
|
254 |
table_cache_create_empty_row() */
|
|
255 |
table_cache->chunks[i].base = NULL; |
|
256 |
}
|
|
257 |
}
|
|
258 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
259 |
/*******************************************************************//**
|
1819.5.106
by stewart at flamingspork
[patch 106/129] Merge patch for revision 1915 from InnoDB SVN: |
260 |
Frees a table cache. */
|
261 |
static
|
|
262 |
void
|
|
263 |
table_cache_free( |
|
264 |
/*=============*/
|
|
265 |
i_s_table_cache_t* table_cache) /*!< in/out: table cache */ |
|
266 |
{
|
|
267 |
ulint i; |
|
268 |
||
269 |
for (i = 0; i < MEM_CHUNKS_IN_TABLE_CACHE; i++) { |
|
270 |
||
271 |
/* the memory is actually allocated in
|
|
272 |
table_cache_create_empty_row() */
|
|
273 |
if (table_cache->chunks[i].base) { |
|
274 |
mem_free(table_cache->chunks[i].base); |
|
275 |
table_cache->chunks[i].base = NULL; |
|
276 |
}
|
|
277 |
}
|
|
278 |
}
|
|
279 |
||
280 |
/*******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
281 |
Returns an empty row from a table cache. The row is allocated if no more
|
282 |
empty rows are available. The number of used rows is incremented.
|
|
283 |
If the memory limit is hit then NULL is returned and nothing is
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
284 |
allocated.
|
285 |
@return empty row, or NULL if out of memory */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
286 |
static
|
287 |
void* |
|
288 |
table_cache_create_empty_row( |
|
289 |
/*=========================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
290 |
i_s_table_cache_t* table_cache, /*!< in/out: table cache */ |
291 |
trx_i_s_cache_t* cache) /*!< in/out: cache to record |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
292 |
how many bytes are
|
293 |
allocated */
|
|
294 |
{
|
|
295 |
ulint i; |
|
296 |
void* row; |
|
297 |
||
298 |
ut_a(table_cache->rows_used <= table_cache->rows_allocd); |
|
299 |
||
300 |
if (table_cache->rows_used == table_cache->rows_allocd) { |
|
301 |
||
302 |
/* rows_used == rows_allocd means that new chunk needs
|
|
303 |
to be allocated: either no more empty rows in the
|
|
304 |
last allocated chunk or nothing has been allocated yet
|
|
305 |
(rows_num == rows_allocd == 0); */
|
|
306 |
||
307 |
i_s_mem_chunk_t* chunk; |
|
308 |
ulint req_bytes; |
|
309 |
ulint got_bytes; |
|
310 |
ulint req_rows; |
|
311 |
ulint got_rows; |
|
312 |
||
313 |
/* find the first not allocated chunk */
|
|
314 |
for (i = 0; i < MEM_CHUNKS_IN_TABLE_CACHE; i++) { |
|
315 |
||
316 |
if (table_cache->chunks[i].base == NULL) { |
|
317 |
||
318 |
break; |
|
319 |
}
|
|
320 |
}
|
|
321 |
||
322 |
/* i == MEM_CHUNKS_IN_TABLE_CACHE means that all chunks
|
|
323 |
have been allocated :-X */
|
|
324 |
ut_a(i < MEM_CHUNKS_IN_TABLE_CACHE); |
|
325 |
||
326 |
/* allocate the chunk we just found */
|
|
327 |
||
328 |
if (i == 0) { |
|
329 |
||
330 |
/* first chunk, nothing is allocated yet */
|
|
331 |
req_rows = TABLE_CACHE_INITIAL_ROWSNUM; |
|
332 |
} else { |
|
333 |
||
334 |
/* Memory is increased by the formula
|
|
335 |
new = old + old / 2; We are trying not to be
|
|
336 |
aggressive here (= using the common new = old * 2)
|
|
337 |
because the allocated memory will not be freed
|
|
338 |
until InnoDB exit (it is reused). So it is better
|
|
339 |
to once allocate the memory in more steps, but
|
|
340 |
have less unused/wasted memory than to use less
|
|
341 |
steps in allocation (which is done once in a
|
|
342 |
lifetime) but end up with lots of unused/wasted
|
|
343 |
memory. */
|
|
344 |
req_rows = table_cache->rows_allocd / 2; |
|
345 |
}
|
|
346 |
req_bytes = req_rows * table_cache->row_size; |
|
347 |
||
348 |
if (req_bytes > MAX_ALLOWED_FOR_ALLOC(cache)) { |
|
349 |
||
350 |
return(NULL); |
|
351 |
}
|
|
352 |
||
353 |
chunk = &table_cache->chunks[i]; |
|
354 |
||
355 |
chunk->base = mem_alloc2(req_bytes, &got_bytes); |
|
356 |
||
357 |
got_rows = got_bytes / table_cache->row_size; |
|
358 |
||
359 |
cache->mem_allocd += got_bytes; |
|
360 |
||
361 |
#if 0
|
|
362 |
printf("allocating chunk %d req bytes=%lu, got bytes=%lu, "
|
|
363 |
"row size=%lu, "
|
|
364 |
"req rows=%lu, got rows=%lu\n",
|
|
365 |
i, req_bytes, got_bytes,
|
|
366 |
table_cache->row_size,
|
|
367 |
req_rows, got_rows);
|
|
368 |
#endif
|
|
369 |
||
370 |
chunk->rows_allocd = got_rows; |
|
371 |
||
372 |
table_cache->rows_allocd += got_rows; |
|
373 |
||
374 |
/* adjust the offset of the next chunk */
|
|
375 |
if (i < MEM_CHUNKS_IN_TABLE_CACHE - 1) { |
|
376 |
||
377 |
table_cache->chunks[i + 1].offset |
|
378 |
= chunk->offset + chunk->rows_allocd; |
|
379 |
}
|
|
380 |
||
381 |
/* return the first empty row in the newly allocated
|
|
382 |
chunk */
|
|
383 |
row = chunk->base; |
|
384 |
} else { |
|
385 |
||
386 |
char* chunk_start; |
|
387 |
ulint offset; |
|
388 |
||
389 |
/* there is an empty row, no need to allocate new
|
|
390 |
chunks */
|
|
391 |
||
392 |
/* find the first chunk that contains allocated but
|
|
393 |
empty/unused rows */
|
|
394 |
for (i = 0; i < MEM_CHUNKS_IN_TABLE_CACHE; i++) { |
|
395 |
||
396 |
if (table_cache->chunks[i].offset |
|
397 |
+ table_cache->chunks[i].rows_allocd |
|
398 |
> table_cache->rows_used) { |
|
399 |
||
400 |
break; |
|
401 |
}
|
|
402 |
}
|
|
403 |
||
404 |
/* i == MEM_CHUNKS_IN_TABLE_CACHE means that all chunks
|
|
405 |
are full, but
|
|
406 |
table_cache->rows_used != table_cache->rows_allocd means
|
|
407 |
exactly the opposite - there are allocated but
|
|
408 |
empty/unused rows :-X */
|
|
409 |
ut_a(i < MEM_CHUNKS_IN_TABLE_CACHE); |
|
410 |
||
411 |
chunk_start = (char*) table_cache->chunks[i].base; |
|
412 |
offset = table_cache->rows_used |
|
413 |
- table_cache->chunks[i].offset; |
|
414 |
||
415 |
row = chunk_start + offset * table_cache->row_size; |
|
416 |
}
|
|
417 |
||
418 |
table_cache->rows_used++; |
|
419 |
||
420 |
return(row); |
|
421 |
}
|
|
422 |
||
1819.9.204
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20101111095535-nmwbjfcenfjhdpg1 from MySQL InnoDB |
423 |
#ifdef UNIV_DEBUG
|
424 |
/*******************************************************************//**
|
|
425 |
Validates a row in the locks cache.
|
|
426 |
@return TRUE if valid */
|
|
427 |
static
|
|
428 |
ibool
|
|
429 |
i_s_locks_row_validate( |
|
430 |
/*===================*/
|
|
431 |
const i_s_locks_row_t* row) /*!< in: row to validate */ |
|
432 |
{
|
|
433 |
ut_ad(row->lock_trx_id != 0); |
|
434 |
ut_ad(row->lock_mode != NULL); |
|
435 |
ut_ad(row->lock_type != NULL); |
|
436 |
ut_ad(row->lock_table != NULL); |
|
437 |
ut_ad(row->lock_table_id != 0); |
|
438 |
||
439 |
if (row->lock_space == ULINT_UNDEFINED) { |
|
440 |
/* table lock */
|
|
441 |
ut_ad(!strcmp("TABLE", row->lock_type)); |
|
442 |
ut_ad(row->lock_index == NULL); |
|
443 |
ut_ad(row->lock_data == NULL); |
|
444 |
ut_ad(row->lock_page == ULINT_UNDEFINED); |
|
445 |
ut_ad(row->lock_rec == ULINT_UNDEFINED); |
|
446 |
} else { |
|
447 |
/* record lock */
|
|
448 |
ut_ad(!strcmp("RECORD", row->lock_type)); |
|
449 |
ut_ad(row->lock_index != NULL); |
|
450 |
ut_ad(row->lock_data != NULL); |
|
451 |
ut_ad(row->lock_page != ULINT_UNDEFINED); |
|
452 |
ut_ad(row->lock_rec != ULINT_UNDEFINED); |
|
453 |
}
|
|
454 |
||
455 |
return(TRUE); |
|
456 |
}
|
|
457 |
#endif /* UNIV_DEBUG */ |
|
458 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
459 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
460 |
Fills i_s_trx_row_t object.
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
461 |
If memory can not be allocated then FALSE is returned.
|
462 |
@return FALSE if allocation fails */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
463 |
static
|
464 |
ibool
|
|
465 |
fill_trx_row( |
|
466 |
/*=========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
467 |
i_s_trx_row_t* row, /*!< out: result object |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
468 |
that's filled */
|
1819.7.117
by Vasil Dimov
Merge Revision revid:vasil.dimov@oracle.com-20100512173700-byf8xntxjur1hqov from MySQL InnoDB |
469 |
const trx_t* trx, /*!< in: transaction to |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
470 |
get data from */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
471 |
const i_s_locks_row_t* requested_lock_row,/*!< in: pointer to the |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
472 |
corresponding row in
|
473 |
innodb_locks if trx is
|
|
474 |
waiting or NULL if trx
|
|
475 |
is not waiting */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
476 |
trx_i_s_cache_t* cache) /*!< in/out: cache into |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
477 |
which to copy volatile
|
478 |
strings */
|
|
479 |
{
|
|
1819.7.121
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu from MySQL InnoDB |
480 |
const char* stmt; |
481 |
size_t stmt_len; |
|
482 |
const char* s; |
|
483 |
||
1819.7.120
by Vasil Dimov
Merge Revision revid:vasil.dimov@oracle.com-20100514133832-unwj9x313jfvn5ev from MySQL InnoDB |
484 |
ut_ad(mutex_own(&kernel_mutex)); |
485 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
486 |
row->trx_id = trx->id; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
487 |
row->trx_started = (ib_time_t) trx->start_time; |
488 |
row->trx_state = trx_get_que_state_str(trx); |
|
1819.9.204
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20101111095535-nmwbjfcenfjhdpg1 from MySQL InnoDB |
489 |
row->requested_lock_row = requested_lock_row; |
490 |
ut_ad(requested_lock_row == NULL |
|
491 |
|| i_s_locks_row_validate(requested_lock_row)); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
492 |
|
493 |
if (trx->wait_lock != NULL) { |
|
494 |
ut_a(requested_lock_row != NULL); |
|
495 |
row->trx_wait_started = (ib_time_t) trx->wait_started; |
|
496 |
} else { |
|
497 |
ut_a(requested_lock_row == NULL); |
|
498 |
row->trx_wait_started = 0; |
|
499 |
}
|
|
500 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
501 |
row->trx_weight = (ullint) TRX_WEIGHT(trx); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
502 |
|
1819.7.121
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu from MySQL InnoDB |
503 |
if (trx->mysql_thd == NULL) { |
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
504 |
/* For internal transactions e.g., purge and transactions
|
505 |
being recovered at startup there is no associated MySQL
|
|
506 |
thread data structure. */
|
|
507 |
row->trx_mysql_thread_id = 0; |
|
1819.7.121
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu from MySQL InnoDB |
508 |
row->trx_query = NULL; |
509 |
goto thd_done; |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
510 |
}
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
511 |
|
1819.7.121
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu from MySQL InnoDB |
512 |
row->trx_mysql_thread_id = session_get_thread_id(trx->mysql_thd); |
513 |
stmt = innobase_get_stmt(trx->mysql_thd, &stmt_len); |
|
514 |
||
515 |
if (stmt != NULL) { |
|
516 |
||
517 |
char query[TRX_I_S_TRX_QUERY_MAX_LEN + 1]; |
|
518 |
||
519 |
if (stmt_len > TRX_I_S_TRX_QUERY_MAX_LEN) { |
|
520 |
stmt_len = TRX_I_S_TRX_QUERY_MAX_LEN; |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
521 |
}
|
522 |
||
1819.7.121
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu from MySQL InnoDB |
523 |
memcpy(query, stmt, stmt_len); |
524 |
query[stmt_len] = '\0'; |
|
525 |
||
526 |
row->trx_query = ha_storage_put_memlim( |
|
527 |
cache->storage, stmt, stmt_len + 1, |
|
528 |
MAX_ALLOWED_FOR_STORAGE(cache)); |
|
529 |
||
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
530 |
if (row->trx_query == NULL) { |
531 |
||
532 |
return(FALSE); |
|
533 |
}
|
|
534 |
} else { |
|
535 |
||
536 |
row->trx_query = NULL; |
|
537 |
}
|
|
538 |
||
1819.7.121
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu from MySQL InnoDB |
539 |
thd_done: |
540 |
s = trx->op_info; |
|
541 |
||
542 |
if (s != NULL && s[0] != '\0') { |
|
543 |
||
544 |
TRX_I_S_STRING_COPY(s, row->trx_operation_state, |
|
1819.7.114
by Jimmy Yang, Stewart Smith
Merge Revision revid:jimmy.yang@oracle.com-20100512153945-zg3suquj1ps6xn5z from MySQL InnoDB |
545 |
TRX_I_S_TRX_OP_STATE_MAX_LEN, cache); |
546 |
||
547 |
if (row->trx_operation_state == NULL) { |
|
548 |
||
549 |
return(FALSE); |
|
550 |
}
|
|
551 |
} else { |
|
552 |
||
553 |
row->trx_operation_state = NULL; |
|
554 |
}
|
|
555 |
||
556 |
// row->trx_tables_in_use = trx->n_mysql_tables_in_use;
|
|
557 |
||
558 |
row->trx_tables_locked = trx->mysql_n_tables_locked; |
|
559 |
||
560 |
row->trx_lock_structs = UT_LIST_GET_LEN(trx->trx_locks); |
|
561 |
||
562 |
row->trx_lock_memory_bytes = mem_heap_get_size(trx->lock_heap); |
|
563 |
||
564 |
row->trx_rows_locked = lock_number_of_rows_locked(trx); |
|
565 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
566 |
row->trx_rows_modified = trx->undo_no; |
1819.7.114
by Jimmy Yang, Stewart Smith
Merge Revision revid:jimmy.yang@oracle.com-20100512153945-zg3suquj1ps6xn5z from MySQL InnoDB |
567 |
|
568 |
row->trx_concurrency_tickets = trx->n_tickets_to_enter_innodb; |
|
569 |
||
570 |
switch (trx->isolation_level) { |
|
571 |
case TRX_ISO_READ_UNCOMMITTED: |
|
572 |
row->trx_isolation_level = "READ UNCOMMITTED"; |
|
573 |
break; |
|
574 |
case TRX_ISO_READ_COMMITTED: |
|
575 |
row->trx_isolation_level = "READ COMMITTED"; |
|
576 |
break; |
|
577 |
case TRX_ISO_REPEATABLE_READ: |
|
578 |
row->trx_isolation_level = "REPEATABLE READ"; |
|
579 |
break; |
|
580 |
case TRX_ISO_SERIALIZABLE: |
|
581 |
row->trx_isolation_level = "SERIALIZABLE"; |
|
582 |
break; |
|
583 |
/* Should not happen as TRX_ISO_READ_COMMITTED is default */
|
|
584 |
default: |
|
585 |
row->trx_isolation_level = "UNKNOWN"; |
|
586 |
}
|
|
587 |
||
588 |
row->trx_unique_checks = (ibool) trx->check_unique_secondary; |
|
589 |
||
590 |
row->trx_foreign_key_checks = (ibool) trx->check_foreigns; |
|
591 |
||
1819.7.121
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu from MySQL InnoDB |
592 |
s = trx->detailed_error; |
593 |
||
594 |
if (s != NULL && s[0] != '\0') { |
|
595 |
||
596 |
TRX_I_S_STRING_COPY(s, |
|
1819.7.114
by Jimmy Yang, Stewart Smith
Merge Revision revid:jimmy.yang@oracle.com-20100512153945-zg3suquj1ps6xn5z from MySQL InnoDB |
597 |
row->trx_foreign_key_error, |
598 |
TRX_I_S_TRX_FK_ERROR_MAX_LEN, cache); |
|
599 |
||
600 |
if (row->trx_foreign_key_error == NULL) { |
|
601 |
||
602 |
return(FALSE); |
|
603 |
}
|
|
604 |
} else { |
|
1819.7.121
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100514133144-fe0l0b89tea4x4uu from MySQL InnoDB |
605 |
row->trx_foreign_key_error = NULL; |
1819.7.114
by Jimmy Yang, Stewart Smith
Merge Revision revid:jimmy.yang@oracle.com-20100512153945-zg3suquj1ps6xn5z from MySQL InnoDB |
606 |
}
|
607 |
||
608 |
row->trx_has_search_latch = (ibool) trx->has_search_latch; |
|
609 |
||
610 |
row->trx_search_latch_timeout = trx->search_latch_timeout; |
|
611 |
||
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
612 |
return(TRUE); |
613 |
}
|
|
614 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
615 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
616 |
Format the nth field of "rec" and put it in "buf". The result is always
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
617 |
NUL-terminated. Returns the number of bytes that were written to "buf"
|
618 |
(including the terminating NUL).
|
|
619 |
@return end of the result */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
620 |
static
|
621 |
ulint
|
|
622 |
put_nth_field( |
|
623 |
/*==========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
624 |
char* buf, /*!< out: buffer */ |
625 |
ulint buf_size,/*!< in: buffer size in bytes */ |
|
626 |
ulint n, /*!< in: number of field */ |
|
627 |
const dict_index_t* index, /*!< in: index */ |
|
628 |
const rec_t* rec, /*!< in: record */ |
|
629 |
const ulint* offsets)/*!< in: record offsets, returned |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
630 |
by rec_get_offsets() */
|
631 |
{
|
|
632 |
const byte* data; |
|
633 |
ulint data_len; |
|
634 |
dict_field_t* dict_field; |
|
635 |
ulint ret; |
|
636 |
||
637 |
ut_ad(rec_offs_validate(rec, NULL, offsets)); |
|
638 |
||
639 |
if (buf_size == 0) { |
|
640 |
||
641 |
return(0); |
|
642 |
}
|
|
643 |
||
644 |
ret = 0; |
|
645 |
||
646 |
if (n > 0) { |
|
647 |
/* we must append ", " before the actual data */
|
|
648 |
||
649 |
if (buf_size < 3) { |
|
650 |
||
651 |
buf[0] = '\0'; |
|
652 |
return(1); |
|
653 |
}
|
|
654 |
||
655 |
memcpy(buf, ", ", 3); |
|
656 |
||
657 |
buf += 2; |
|
658 |
buf_size -= 2; |
|
659 |
ret += 2; |
|
660 |
}
|
|
661 |
||
662 |
/* now buf_size >= 1 */
|
|
663 |
||
664 |
data = rec_get_nth_field(rec, offsets, n, &data_len); |
|
665 |
||
666 |
dict_field = dict_index_get_nth_field(index, n); |
|
667 |
||
668 |
ret += row_raw_format((const char*) data, data_len, |
|
669 |
dict_field, buf, buf_size); |
|
670 |
||
671 |
return(ret); |
|
672 |
}
|
|
673 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
674 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
675 |
Fills the "lock_data" member of i_s_locks_row_t object.
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
676 |
If memory can not be allocated then FALSE is returned.
|
677 |
@return FALSE if allocation fails */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
678 |
static
|
679 |
ibool
|
|
680 |
fill_lock_data( |
|
681 |
/*===========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
682 |
const char** lock_data,/*!< out: "lock_data" to fill */ |
683 |
const lock_t* lock, /*!< in: lock used to find the data */ |
|
684 |
ulint heap_no,/*!< in: rec num used to find the data */ |
|
685 |
trx_i_s_cache_t* cache) /*!< in/out: cache where to store |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
686 |
volatile data */
|
687 |
{
|
|
688 |
mtr_t mtr; |
|
689 |
||
690 |
const buf_block_t* block; |
|
691 |
const page_t* page; |
|
692 |
const rec_t* rec; |
|
693 |
||
694 |
ut_a(lock_get_type(lock) == LOCK_REC); |
|
695 |
||
696 |
mtr_start(&mtr); |
|
697 |
||
698 |
block = buf_page_try_get(lock_rec_get_space_id(lock), |
|
699 |
lock_rec_get_page_no(lock), |
|
700 |
&mtr); |
|
701 |
||
702 |
if (block == NULL) { |
|
703 |
||
704 |
*lock_data = NULL; |
|
705 |
||
706 |
mtr_commit(&mtr); |
|
707 |
||
708 |
return(TRUE); |
|
709 |
}
|
|
710 |
||
711 |
page = (const page_t*) buf_block_get_frame(block); |
|
712 |
||
713 |
rec = page_find_rec_with_heap_no(page, heap_no); |
|
714 |
||
715 |
if (page_rec_is_infimum(rec)) { |
|
716 |
||
717 |
*lock_data = ha_storage_put_str_memlim( |
|
718 |
cache->storage, "infimum pseudo-record", |
|
719 |
MAX_ALLOWED_FOR_STORAGE(cache)); |
|
720 |
} else if (page_rec_is_supremum(rec)) { |
|
721 |
||
722 |
*lock_data = ha_storage_put_str_memlim( |
|
723 |
cache->storage, "supremum pseudo-record", |
|
724 |
MAX_ALLOWED_FOR_STORAGE(cache)); |
|
725 |
} else { |
|
726 |
||
727 |
const dict_index_t* index; |
|
728 |
ulint n_fields; |
|
729 |
mem_heap_t* heap; |
|
730 |
ulint offsets_onstack[REC_OFFS_NORMAL_SIZE]; |
|
731 |
ulint* offsets; |
|
732 |
char buf[TRX_I_S_LOCK_DATA_MAX_LEN]; |
|
733 |
ulint buf_used; |
|
734 |
ulint i; |
|
735 |
||
736 |
rec_offs_init(offsets_onstack); |
|
737 |
offsets = offsets_onstack; |
|
738 |
||
739 |
index = lock_rec_get_index(lock); |
|
740 |
||
741 |
n_fields = dict_index_get_n_unique(index); |
|
742 |
||
743 |
ut_a(n_fields > 0); |
|
744 |
||
745 |
heap = NULL; |
|
746 |
offsets = rec_get_offsets(rec, index, offsets, n_fields, |
|
747 |
&heap); |
|
748 |
||
749 |
/* format and store the data */
|
|
750 |
||
751 |
buf_used = 0; |
|
752 |
for (i = 0; i < n_fields; i++) { |
|
753 |
||
754 |
buf_used += put_nth_field( |
|
755 |
buf + buf_used, sizeof(buf) - buf_used, |
|
756 |
i, index, rec, offsets) - 1; |
|
757 |
}
|
|
758 |
||
759 |
*lock_data = (const char*) ha_storage_put_memlim( |
|
760 |
cache->storage, buf, buf_used + 1, |
|
761 |
MAX_ALLOWED_FOR_STORAGE(cache)); |
|
762 |
||
763 |
if (UNIV_UNLIKELY(heap != NULL)) { |
|
764 |
||
765 |
/* this means that rec_get_offsets() has created a new
|
|
766 |
heap and has stored offsets in it; check that this is
|
|
767 |
really the case and free the heap */
|
|
768 |
ut_a(offsets != offsets_onstack); |
|
769 |
mem_heap_free(heap); |
|
770 |
}
|
|
771 |
}
|
|
772 |
||
773 |
mtr_commit(&mtr); |
|
774 |
||
775 |
if (*lock_data == NULL) { |
|
776 |
||
777 |
return(FALSE); |
|
778 |
}
|
|
779 |
||
780 |
return(TRUE); |
|
781 |
}
|
|
782 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
783 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
784 |
Fills i_s_locks_row_t object. Returns its first argument.
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
785 |
If memory can not be allocated then FALSE is returned.
|
786 |
@return FALSE if allocation fails */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
787 |
static
|
788 |
ibool
|
|
789 |
fill_locks_row( |
|
790 |
/*===========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
791 |
i_s_locks_row_t* row, /*!< out: result object that's filled */ |
792 |
const lock_t* lock, /*!< in: lock to get data from */ |
|
793 |
ulint heap_no,/*!< in: lock's record number |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
794 |
or ULINT_UNDEFINED if the lock
|
795 |
is a table lock */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
796 |
trx_i_s_cache_t* cache) /*!< in/out: cache into which to copy |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
797 |
volatile strings */
|
798 |
{
|
|
799 |
row->lock_trx_id = lock_get_trx_id(lock); |
|
800 |
row->lock_mode = lock_get_mode_str(lock); |
|
801 |
row->lock_type = lock_get_type_str(lock); |
|
802 |
||
803 |
row->lock_table = ha_storage_put_str_memlim( |
|
804 |
cache->storage, lock_get_table_name(lock), |
|
805 |
MAX_ALLOWED_FOR_STORAGE(cache)); |
|
806 |
||
807 |
/* memory could not be allocated */
|
|
808 |
if (row->lock_table == NULL) { |
|
809 |
||
810 |
return(FALSE); |
|
811 |
}
|
|
812 |
||
813 |
switch (lock_get_type(lock)) { |
|
814 |
case LOCK_REC: |
|
815 |
row->lock_index = ha_storage_put_str_memlim( |
|
816 |
cache->storage, lock_rec_get_index_name(lock), |
|
817 |
MAX_ALLOWED_FOR_STORAGE(cache)); |
|
818 |
||
819 |
/* memory could not be allocated */
|
|
820 |
if (row->lock_index == NULL) { |
|
821 |
||
822 |
return(FALSE); |
|
823 |
}
|
|
824 |
||
825 |
row->lock_space = lock_rec_get_space_id(lock); |
|
826 |
row->lock_page = lock_rec_get_page_no(lock); |
|
827 |
row->lock_rec = heap_no; |
|
828 |
||
829 |
if (!fill_lock_data(&row->lock_data, lock, heap_no, cache)) { |
|
830 |
||
831 |
/* memory could not be allocated */
|
|
832 |
return(FALSE); |
|
833 |
}
|
|
834 |
||
835 |
break; |
|
836 |
case LOCK_TABLE: |
|
837 |
row->lock_index = NULL; |
|
838 |
||
839 |
row->lock_space = ULINT_UNDEFINED; |
|
840 |
row->lock_page = ULINT_UNDEFINED; |
|
841 |
row->lock_rec = ULINT_UNDEFINED; |
|
842 |
||
843 |
row->lock_data = NULL; |
|
844 |
||
845 |
break; |
|
846 |
default: |
|
847 |
ut_error; |
|
848 |
}
|
|
849 |
||
850 |
row->lock_table_id = lock_get_table_id(lock); |
|
851 |
||
852 |
row->hash_chain.value = row; |
|
1819.9.204
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20101111095535-nmwbjfcenfjhdpg1 from MySQL InnoDB |
853 |
ut_ad(i_s_locks_row_validate(row)); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
854 |
|
855 |
return(TRUE); |
|
856 |
}
|
|
857 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
858 |
/*******************************************************************//**
|
859 |
Fills i_s_lock_waits_row_t object. Returns its first argument.
|
|
860 |
@return result object that's filled */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
861 |
static
|
862 |
i_s_lock_waits_row_t* |
|
863 |
fill_lock_waits_row( |
|
864 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
865 |
i_s_lock_waits_row_t* row, /*!< out: result object |
866 |
that's filled */
|
|
867 |
const i_s_locks_row_t* requested_lock_row,/*!< in: pointer to the |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
868 |
relevant requested lock
|
869 |
row in innodb_locks */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
870 |
const i_s_locks_row_t* blocking_lock_row)/*!< in: pointer to the |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
871 |
relevant blocking lock
|
872 |
row in innodb_locks */
|
|
873 |
{
|
|
1819.9.204
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20101111095535-nmwbjfcenfjhdpg1 from MySQL InnoDB |
874 |
ut_ad(i_s_locks_row_validate(requested_lock_row)); |
875 |
ut_ad(i_s_locks_row_validate(blocking_lock_row)); |
|
876 |
||
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
877 |
row->requested_lock_row = requested_lock_row; |
878 |
row->blocking_lock_row = blocking_lock_row; |
|
879 |
||
880 |
return(row); |
|
881 |
}
|
|
882 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
883 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
884 |
Calculates a hash fold for a lock. For a record lock the fold is
|
885 |
calculated from 4 elements, which uniquely identify a lock at a given
|
|
886 |
point in time: transaction id, space id, page number, record number.
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
887 |
For a table lock the fold is table's id.
|
888 |
@return fold */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
889 |
static
|
890 |
ulint
|
|
891 |
fold_lock( |
|
892 |
/*======*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
893 |
const lock_t* lock, /*!< in: lock object to fold */ |
894 |
ulint heap_no)/*!< in: lock's record number |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
895 |
or ULINT_UNDEFINED if the lock
|
896 |
is a table lock */
|
|
897 |
{
|
|
898 |
#ifdef TEST_LOCK_FOLD_ALWAYS_DIFFERENT
|
|
899 |
static ulint fold = 0; |
|
900 |
||
901 |
return(fold++); |
|
902 |
#else
|
|
903 |
ulint ret; |
|
904 |
||
905 |
switch (lock_get_type(lock)) { |
|
906 |
case LOCK_REC: |
|
907 |
ut_a(heap_no != ULINT_UNDEFINED); |
|
908 |
||
909 |
ret = ut_fold_ulint_pair((ulint) lock_get_trx_id(lock), |
|
910 |
lock_rec_get_space_id(lock)); |
|
911 |
||
912 |
ret = ut_fold_ulint_pair(ret, |
|
913 |
lock_rec_get_page_no(lock)); |
|
914 |
||
915 |
ret = ut_fold_ulint_pair(ret, heap_no); |
|
916 |
||
917 |
break; |
|
918 |
case LOCK_TABLE: |
|
919 |
/* this check is actually not necessary for continuing
|
|
920 |
correct operation, but something must have gone wrong if
|
|
921 |
it fails. */
|
|
922 |
ut_a(heap_no == ULINT_UNDEFINED); |
|
923 |
||
924 |
ret = (ulint) lock_get_table_id(lock); |
|
925 |
||
926 |
break; |
|
927 |
default: |
|
928 |
ut_error; |
|
929 |
}
|
|
930 |
||
931 |
return(ret); |
|
932 |
#endif
|
|
933 |
}
|
|
934 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
935 |
/*******************************************************************//**
|
936 |
Checks whether i_s_locks_row_t object represents a lock_t object.
|
|
937 |
@return TRUE if they match */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
938 |
static
|
939 |
ibool
|
|
940 |
locks_row_eq_lock( |
|
941 |
/*==============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
942 |
const i_s_locks_row_t* row, /*!< in: innodb_locks row */ |
943 |
const lock_t* lock, /*!< in: lock object */ |
|
944 |
ulint heap_no)/*!< in: lock's record number |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
945 |
or ULINT_UNDEFINED if the lock
|
946 |
is a table lock */
|
|
947 |
{
|
|
1819.9.204
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20101111095535-nmwbjfcenfjhdpg1 from MySQL InnoDB |
948 |
ut_ad(i_s_locks_row_validate(row)); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
949 |
#ifdef TEST_NO_LOCKS_ROW_IS_EVER_EQUAL_TO_LOCK_T
|
950 |
return(0); |
|
951 |
#else
|
|
952 |
switch (lock_get_type(lock)) { |
|
953 |
case LOCK_REC: |
|
954 |
ut_a(heap_no != ULINT_UNDEFINED); |
|
955 |
||
956 |
return(row->lock_trx_id == lock_get_trx_id(lock) |
|
957 |
&& row->lock_space == lock_rec_get_space_id(lock) |
|
958 |
&& row->lock_page == lock_rec_get_page_no(lock) |
|
959 |
&& row->lock_rec == heap_no); |
|
960 |
||
961 |
case LOCK_TABLE: |
|
962 |
/* this check is actually not necessary for continuing
|
|
963 |
correct operation, but something must have gone wrong if
|
|
964 |
it fails. */
|
|
965 |
ut_a(heap_no == ULINT_UNDEFINED); |
|
966 |
||
967 |
return(row->lock_trx_id == lock_get_trx_id(lock) |
|
968 |
&& row->lock_table_id == lock_get_table_id(lock)); |
|
969 |
||
970 |
default: |
|
971 |
ut_error; |
|
972 |
return(FALSE); |
|
973 |
}
|
|
974 |
#endif
|
|
975 |
}
|
|
976 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
977 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
978 |
Searches for a row in the innodb_locks cache that has a specified id.
|
979 |
This happens in O(1) time since a hash table is used. Returns pointer to
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
980 |
the row or NULL if none is found.
|
981 |
@return row or NULL */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
982 |
static
|
983 |
i_s_locks_row_t* |
|
984 |
search_innodb_locks( |
|
985 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
986 |
trx_i_s_cache_t* cache, /*!< in: cache */ |
987 |
const lock_t* lock, /*!< in: lock to search for */ |
|
988 |
ulint heap_no)/*!< in: lock's record number |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
989 |
or ULINT_UNDEFINED if the lock
|
990 |
is a table lock */
|
|
991 |
{
|
|
992 |
i_s_hash_chain_t* hash_chain; |
|
993 |
||
994 |
HASH_SEARCH( |
|
995 |
/* hash_chain->"next" */
|
|
996 |
next, |
|
997 |
/* the hash table */
|
|
998 |
cache->locks_hash, |
|
999 |
/* fold */
|
|
1000 |
fold_lock(lock, heap_no), |
|
1001 |
/* the type of the next variable */
|
|
1002 |
i_s_hash_chain_t*, |
|
1003 |
/* auxiliary variable */
|
|
1004 |
hash_chain, |
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
1005 |
/* assertion on every traversed item */
|
1819.9.204
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20101111095535-nmwbjfcenfjhdpg1 from MySQL InnoDB |
1006 |
ut_ad(i_s_locks_row_validate(hash_chain->value)), |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1007 |
/* this determines if we have found the lock */
|
1008 |
locks_row_eq_lock(hash_chain->value, lock, heap_no)); |
|
1009 |
||
1010 |
if (hash_chain == NULL) { |
|
1011 |
||
1012 |
return(NULL); |
|
1013 |
}
|
|
1014 |
/* else */
|
|
1015 |
||
1016 |
return(hash_chain->value); |
|
1017 |
}
|
|
1018 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1019 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1020 |
Adds new element to the locks cache, enlarging it if necessary.
|
1021 |
Returns a pointer to the added row. If the row is already present then
|
|
1022 |
no row is added and a pointer to the existing row is returned.
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1023 |
If row can not be allocated then NULL is returned.
|
1024 |
@return row */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1025 |
static
|
1026 |
i_s_locks_row_t* |
|
1027 |
add_lock_to_cache( |
|
1028 |
/*==============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1029 |
trx_i_s_cache_t* cache, /*!< in/out: cache */ |
1030 |
const lock_t* lock, /*!< in: the element to add */ |
|
1031 |
ulint heap_no)/*!< in: lock's record number |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1032 |
or ULINT_UNDEFINED if the lock
|
1033 |
is a table lock */
|
|
1034 |
{
|
|
1035 |
i_s_locks_row_t* dst_row; |
|
1036 |
||
1037 |
#ifdef TEST_ADD_EACH_LOCKS_ROW_MANY_TIMES
|
|
1038 |
ulint i; |
|
1039 |
for (i = 0; i < 10000; i++) { |
|
1040 |
#endif
|
|
1041 |
#ifndef TEST_DO_NOT_CHECK_FOR_DUPLICATE_ROWS
|
|
1042 |
/* quit if this lock is already present */
|
|
1043 |
dst_row = search_innodb_locks(cache, lock, heap_no); |
|
1044 |
if (dst_row != NULL) { |
|
1045 |
||
1819.9.204
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20101111095535-nmwbjfcenfjhdpg1 from MySQL InnoDB |
1046 |
ut_ad(i_s_locks_row_validate(dst_row)); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1047 |
return(dst_row); |
1048 |
}
|
|
1049 |
#endif
|
|
1050 |
||
1051 |
dst_row = (i_s_locks_row_t*) |
|
1052 |
table_cache_create_empty_row(&cache->innodb_locks, cache); |
|
1053 |
||
1054 |
/* memory could not be allocated */
|
|
1055 |
if (dst_row == NULL) { |
|
1056 |
||
1057 |
return(NULL); |
|
1058 |
}
|
|
1059 |
||
1060 |
if (!fill_locks_row(dst_row, lock, heap_no, cache)) { |
|
1061 |
||
1062 |
/* memory could not be allocated */
|
|
1063 |
cache->innodb_locks.rows_used--; |
|
1064 |
return(NULL); |
|
1065 |
}
|
|
1066 |
||
1067 |
#ifndef TEST_DO_NOT_INSERT_INTO_THE_HASH_TABLE
|
|
1068 |
HASH_INSERT( |
|
1069 |
/* the type used in the hash chain */
|
|
1070 |
i_s_hash_chain_t, |
|
1071 |
/* hash_chain->"next" */
|
|
1072 |
next, |
|
1073 |
/* the hash table */
|
|
1074 |
cache->locks_hash, |
|
1075 |
/* fold */
|
|
1076 |
fold_lock(lock, heap_no), |
|
1077 |
/* add this data to the hash */
|
|
1078 |
&dst_row->hash_chain); |
|
1079 |
#endif
|
|
1080 |
#ifdef TEST_ADD_EACH_LOCKS_ROW_MANY_TIMES
|
|
1081 |
} /* for()-loop */ |
|
1082 |
#endif
|
|
1083 |
||
1819.9.204
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20101111095535-nmwbjfcenfjhdpg1 from MySQL InnoDB |
1084 |
ut_ad(i_s_locks_row_validate(dst_row)); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1085 |
return(dst_row); |
1086 |
}
|
|
1087 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1088 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1089 |
Adds new pair of locks to the lock waits cache.
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1090 |
If memory can not be allocated then FALSE is returned.
|
1091 |
@return FALSE if allocation fails */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1092 |
static
|
1093 |
ibool
|
|
1094 |
add_lock_wait_to_cache( |
|
1095 |
/*===================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1096 |
trx_i_s_cache_t* cache, /*!< in/out: cache */ |
1097 |
const i_s_locks_row_t* requested_lock_row,/*!< in: pointer to the |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1098 |
relevant requested lock
|
1099 |
row in innodb_locks */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1100 |
const i_s_locks_row_t* blocking_lock_row)/*!< in: pointer to the |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1101 |
relevant blocking lock
|
1102 |
row in innodb_locks */
|
|
1103 |
{
|
|
1104 |
i_s_lock_waits_row_t* dst_row; |
|
1105 |
||
1106 |
dst_row = (i_s_lock_waits_row_t*) |
|
1107 |
table_cache_create_empty_row(&cache->innodb_lock_waits, |
|
1108 |
cache); |
|
1109 |
||
1110 |
/* memory could not be allocated */
|
|
1111 |
if (dst_row == NULL) { |
|
1112 |
||
1113 |
return(FALSE); |
|
1114 |
}
|
|
1115 |
||
1116 |
fill_lock_waits_row(dst_row, requested_lock_row, blocking_lock_row); |
|
1117 |
||
1118 |
return(TRUE); |
|
1119 |
}
|
|
1120 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1121 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1122 |
Adds transaction's relevant (important) locks to cache.
|
1123 |
If the transaction is waiting, then the wait lock is added to
|
|
1124 |
innodb_locks and a pointer to the added row is returned in
|
|
1125 |
requested_lock_row, otherwise requested_lock_row is set to NULL.
|
|
1126 |
If rows can not be allocated then FALSE is returned and the value of
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1127 |
requested_lock_row is undefined.
|
1128 |
@return FALSE if allocation fails */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1129 |
static
|
1130 |
ibool
|
|
1131 |
add_trx_relevant_locks_to_cache( |
|
1132 |
/*============================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1133 |
trx_i_s_cache_t* cache, /*!< in/out: cache */ |
1134 |
const trx_t* trx, /*!< in: transaction */ |
|
1135 |
i_s_locks_row_t** requested_lock_row)/*!< out: pointer to the |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1136 |
requested lock row, or NULL or
|
1137 |
undefined */
|
|
1138 |
{
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
1139 |
ut_ad(mutex_own(&kernel_mutex)); |
1140 |
||
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1141 |
/* If transaction is waiting we add the wait lock and all locks
|
1142 |
from another transactions that are blocking the wait lock. */
|
|
1143 |
if (trx->que_state == TRX_QUE_LOCK_WAIT) { |
|
1144 |
||
1145 |
const lock_t* curr_lock; |
|
1146 |
ulint wait_lock_heap_no; |
|
1147 |
i_s_locks_row_t* blocking_lock_row; |
|
1148 |
lock_queue_iterator_t iter; |
|
1149 |
||
1150 |
ut_a(trx->wait_lock != NULL); |
|
1151 |
||
1152 |
wait_lock_heap_no
|
|
1153 |
= wait_lock_get_heap_no(trx->wait_lock); |
|
1154 |
||
1155 |
/* add the requested lock */
|
|
1156 |
*requested_lock_row |
|
1157 |
= add_lock_to_cache(cache, trx->wait_lock, |
|
1158 |
wait_lock_heap_no); |
|
1159 |
||
1160 |
/* memory could not be allocated */
|
|
1161 |
if (*requested_lock_row == NULL) { |
|
1162 |
||
1163 |
return(FALSE); |
|
1164 |
}
|
|
1165 |
||
1166 |
/* then iterate over the locks before the wait lock and
|
|
1167 |
add the ones that are blocking it */
|
|
1168 |
||
1169 |
lock_queue_iterator_reset(&iter, trx->wait_lock, |
|
1170 |
ULINT_UNDEFINED); |
|
1171 |
||
1172 |
curr_lock = lock_queue_iterator_get_prev(&iter); |
|
1173 |
while (curr_lock != NULL) { |
|
1174 |
||
1175 |
if (lock_has_to_wait(trx->wait_lock, |
|
1176 |
curr_lock)) { |
|
1177 |
||
1178 |
/* add the lock that is
|
|
1179 |
blocking trx->wait_lock */
|
|
1180 |
blocking_lock_row
|
|
1181 |
= add_lock_to_cache( |
|
1182 |
cache, curr_lock, |
|
1183 |
/* heap_no is the same
|
|
1184 |
for the wait and waited
|
|
1185 |
locks */
|
|
1186 |
wait_lock_heap_no); |
|
1187 |
||
1188 |
/* memory could not be allocated */
|
|
1189 |
if (blocking_lock_row == NULL) { |
|
1190 |
||
1191 |
return(FALSE); |
|
1192 |
}
|
|
1193 |
||
1194 |
/* add the relation between both locks
|
|
1195 |
to innodb_lock_waits */
|
|
1196 |
if (!add_lock_wait_to_cache( |
|
1197 |
cache, *requested_lock_row, |
|
1198 |
blocking_lock_row)) { |
|
1199 |
||
1200 |
/* memory could not be allocated */
|
|
1201 |
return(FALSE); |
|
1202 |
}
|
|
1203 |
}
|
|
1204 |
||
1205 |
curr_lock = lock_queue_iterator_get_prev(&iter); |
|
1206 |
}
|
|
1207 |
} else { |
|
1208 |
||
1209 |
*requested_lock_row = NULL; |
|
1210 |
}
|
|
1211 |
||
1212 |
return(TRUE); |
|
1213 |
}
|
|
1214 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1215 |
/** The minimum time that a cache must not be updated after it has been
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1216 |
read for the last time; measured in microseconds. We use this technique
|
1217 |
to ensure that SELECTs which join several INFORMATION SCHEMA tables read
|
|
1218 |
the same version of the cache. */
|
|
1219 |
#define CACHE_MIN_IDLE_TIME_US 100000 /* 0.1 sec */ |
|
1220 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1221 |
/*******************************************************************//**
|
1222 |
Checks if the cache can safely be updated.
|
|
1223 |
@return TRUE if can be updated */
|
|
1224 |
static
|
|
1225 |
ibool
|
|
1226 |
can_cache_be_updated( |
|
1227 |
/*=================*/
|
|
1228 |
trx_i_s_cache_t* cache) /*!< in: cache */ |
|
1229 |
{
|
|
1230 |
ullint now; |
|
1231 |
||
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1232 |
/* Here we read cache->last_read without acquiring its mutex
|
1233 |
because last_read is only updated when a shared rw lock on the
|
|
1234 |
whole cache is being held (see trx_i_s_cache_end_read()) and
|
|
1235 |
we are currently holding an exclusive rw lock on the cache.
|
|
1236 |
So it is not possible for last_read to be updated while we are
|
|
1237 |
reading it. */
|
|
1238 |
||
1239 |
#ifdef UNIV_SYNC_DEBUG
|
|
1240 |
ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX)); |
|
1241 |
#endif
|
|
1242 |
||
1243 |
now = ut_time_us(NULL); |
|
1244 |
if (now - cache->last_read > CACHE_MIN_IDLE_TIME_US) { |
|
1245 |
||
1246 |
return(TRUE); |
|
1247 |
}
|
|
1248 |
||
1249 |
return(FALSE); |
|
1250 |
}
|
|
1251 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1252 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1253 |
Declare a cache empty, preparing it to be filled up. Not all resources
|
1254 |
are freed because they can be reused. */
|
|
1255 |
static
|
|
1256 |
void
|
|
1257 |
trx_i_s_cache_clear( |
|
1258 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1259 |
trx_i_s_cache_t* cache) /*!< out: cache to clear */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1260 |
{
|
1261 |
cache->innodb_trx.rows_used = 0; |
|
1262 |
cache->innodb_locks.rows_used = 0; |
|
1263 |
cache->innodb_lock_waits.rows_used = 0; |
|
1264 |
||
1265 |
hash_table_clear(cache->locks_hash); |
|
1266 |
||
1267 |
ha_storage_empty(&cache->storage); |
|
1268 |
}
|
|
1269 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1270 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1271 |
Fetches the data needed to fill the 3 INFORMATION SCHEMA tables into the
|
1272 |
table cache buffer. Cache must be locked for write. */
|
|
1273 |
static
|
|
1274 |
void
|
|
1275 |
fetch_data_into_cache( |
|
1276 |
/*==================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1277 |
trx_i_s_cache_t* cache) /*!< in/out: cache */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1278 |
{
|
1279 |
trx_t* trx; |
|
1280 |
i_s_trx_row_t* trx_row; |
|
1281 |
i_s_locks_row_t* requested_lock_row; |
|
1282 |
||
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
1283 |
ut_ad(mutex_own(&kernel_mutex)); |
1284 |
||
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1285 |
trx_i_s_cache_clear(cache); |
1286 |
||
1287 |
/* We iterate over the list of all transactions and add each one
|
|
1288 |
to innodb_trx's cache. We also add all locks that are relevant
|
|
1289 |
to each transaction into innodb_locks' and innodb_lock_waits'
|
|
1290 |
caches. */
|
|
1291 |
||
1292 |
for (trx = UT_LIST_GET_FIRST(trx_sys->trx_list); |
|
1293 |
trx != NULL; |
|
1294 |
trx = UT_LIST_GET_NEXT(trx_list, trx)) { |
|
1295 |
||
1296 |
if (!add_trx_relevant_locks_to_cache(cache, trx, |
|
1297 |
&requested_lock_row)) { |
|
1298 |
||
1299 |
cache->is_truncated = TRUE; |
|
1300 |
return; |
|
1301 |
}
|
|
1302 |
||
1303 |
trx_row = (i_s_trx_row_t*) |
|
1304 |
table_cache_create_empty_row(&cache->innodb_trx, |
|
1305 |
cache); |
|
1306 |
||
1307 |
/* memory could not be allocated */
|
|
1308 |
if (trx_row == NULL) { |
|
1309 |
||
1310 |
cache->is_truncated = TRUE; |
|
1311 |
return; |
|
1312 |
}
|
|
1313 |
||
1314 |
if (!fill_trx_row(trx_row, trx, requested_lock_row, cache)) { |
|
1315 |
||
1316 |
/* memory could not be allocated */
|
|
1317 |
cache->innodb_trx.rows_used--; |
|
1318 |
cache->is_truncated = TRUE; |
|
1319 |
return; |
|
1320 |
}
|
|
1321 |
}
|
|
1322 |
||
1323 |
cache->is_truncated = FALSE; |
|
1324 |
}
|
|
1325 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1326 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1327 |
Update the transactions cache if it has not been read for some time.
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1328 |
Called from handler/i_s.cc.
|
1329 |
@return 0 - fetched, 1 - not */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1330 |
UNIV_INTERN
|
1331 |
int
|
|
1332 |
trx_i_s_possibly_fetch_data_into_cache( |
|
1333 |
/*===================================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1334 |
trx_i_s_cache_t* cache) /*!< in/out: cache */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1335 |
{
|
1336 |
if (!can_cache_be_updated(cache)) { |
|
1337 |
||
1338 |
return(1); |
|
1339 |
}
|
|
1340 |
||
1341 |
/* We need to read trx_sys and record/table lock queues */
|
|
1342 |
mutex_enter(&kernel_mutex); |
|
1343 |
||
1344 |
fetch_data_into_cache(cache); |
|
1345 |
||
1346 |
mutex_exit(&kernel_mutex); |
|
1347 |
||
1348 |
return(0); |
|
1349 |
}
|
|
1350 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1351 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1352 |
Returns TRUE if the data in the cache is truncated due to the memory
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1353 |
limit posed by TRX_I_S_MEM_LIMIT.
|
1354 |
@return TRUE if truncated */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1355 |
UNIV_INTERN
|
1356 |
ibool
|
|
1357 |
trx_i_s_cache_is_truncated( |
|
1358 |
/*=======================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1359 |
trx_i_s_cache_t* cache) /*!< in: cache */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1360 |
{
|
1361 |
return(cache->is_truncated); |
|
1362 |
}
|
|
1363 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1364 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1365 |
Initialize INFORMATION SCHEMA trx related cache. */
|
1366 |
UNIV_INTERN
|
|
1367 |
void
|
|
1368 |
trx_i_s_cache_init( |
|
1369 |
/*===============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1370 |
trx_i_s_cache_t* cache) /*!< out: cache to init */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1371 |
{
|
1372 |
/* The latching is done in the following order:
|
|
1373 |
acquire trx_i_s_cache_t::rw_lock, X
|
|
1374 |
acquire kernel_mutex
|
|
1375 |
release kernel_mutex
|
|
1376 |
release trx_i_s_cache_t::rw_lock
|
|
1377 |
acquire trx_i_s_cache_t::rw_lock, S
|
|
1378 |
acquire trx_i_s_cache_t::last_read_mutex
|
|
1379 |
release trx_i_s_cache_t::last_read_mutex
|
|
1380 |
release trx_i_s_cache_t::rw_lock */
|
|
1381 |
||
1819.7.68
by Stewart Smith
Merge initial InnoDB+ import. |
1382 |
rw_lock_create(trx_i_s_cache_lock_key, &cache->rw_lock, |
1383 |
SYNC_TRX_I_S_RWLOCK); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1384 |
|
1385 |
cache->last_read = 0; |
|
1386 |
||
1819.7.68
by Stewart Smith
Merge initial InnoDB+ import. |
1387 |
mutex_create(cache_last_read_mutex_key, |
1388 |
&cache->last_read_mutex, SYNC_TRX_I_S_LAST_READ); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1389 |
|
1390 |
table_cache_init(&cache->innodb_trx, sizeof(i_s_trx_row_t)); |
|
1391 |
table_cache_init(&cache->innodb_locks, sizeof(i_s_locks_row_t)); |
|
1392 |
table_cache_init(&cache->innodb_lock_waits, |
|
1393 |
sizeof(i_s_lock_waits_row_t)); |
|
1394 |
||
1395 |
cache->locks_hash = hash_create(LOCKS_HASH_CELLS_NUM); |
|
1396 |
||
1397 |
cache->storage = ha_storage_create(CACHE_STORAGE_INITIAL_SIZE, |
|
1398 |
CACHE_STORAGE_HASH_CELLS); |
|
1399 |
||
1400 |
cache->mem_allocd = 0; |
|
1401 |
||
1402 |
cache->is_truncated = FALSE; |
|
1403 |
}
|
|
1404 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1405 |
/*******************************************************************//**
|
1819.5.106
by stewart at flamingspork
[patch 106/129] Merge patch for revision 1915 from InnoDB SVN: |
1406 |
Free the INFORMATION SCHEMA trx related cache. */
|
1407 |
UNIV_INTERN
|
|
1408 |
void
|
|
1409 |
trx_i_s_cache_free( |
|
1410 |
/*===============*/
|
|
1411 |
trx_i_s_cache_t* cache) /*!< in, own: cache to free */ |
|
1412 |
{
|
|
1413 |
hash_table_free(cache->locks_hash); |
|
1414 |
ha_storage_free(cache->storage); |
|
1415 |
table_cache_free(&cache->innodb_trx); |
|
1416 |
table_cache_free(&cache->innodb_locks); |
|
1417 |
table_cache_free(&cache->innodb_lock_waits); |
|
1418 |
memset(cache, 0, sizeof *cache); |
|
1419 |
}
|
|
1420 |
||
1421 |
/*******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1422 |
Issue a shared/read lock on the tables cache. */
|
1423 |
UNIV_INTERN
|
|
1424 |
void
|
|
1425 |
trx_i_s_cache_start_read( |
|
1426 |
/*=====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1427 |
trx_i_s_cache_t* cache) /*!< in: cache */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1428 |
{
|
1429 |
rw_lock_s_lock(&cache->rw_lock); |
|
1430 |
}
|
|
1431 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1432 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1433 |
Release a shared/read lock on the tables cache. */
|
1434 |
UNIV_INTERN
|
|
1435 |
void
|
|
1436 |
trx_i_s_cache_end_read( |
|
1437 |
/*===================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1438 |
trx_i_s_cache_t* cache) /*!< in: cache */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1439 |
{
|
1440 |
ullint now; |
|
1441 |
||
1442 |
#ifdef UNIV_SYNC_DEBUG
|
|
1443 |
ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_SHARED)); |
|
1444 |
#endif
|
|
1445 |
||
1446 |
/* update cache last read time */
|
|
1447 |
now = ut_time_us(NULL); |
|
1448 |
mutex_enter(&cache->last_read_mutex); |
|
1449 |
cache->last_read = now; |
|
1450 |
mutex_exit(&cache->last_read_mutex); |
|
1451 |
||
1452 |
rw_lock_s_unlock(&cache->rw_lock); |
|
1453 |
}
|
|
1454 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1455 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1456 |
Issue an exclusive/write lock on the tables cache. */
|
1457 |
UNIV_INTERN
|
|
1458 |
void
|
|
1459 |
trx_i_s_cache_start_write( |
|
1460 |
/*======================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1461 |
trx_i_s_cache_t* cache) /*!< in: cache */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1462 |
{
|
1463 |
rw_lock_x_lock(&cache->rw_lock); |
|
1464 |
}
|
|
1465 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1466 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1467 |
Release an exclusive/write lock on the tables cache. */
|
1468 |
UNIV_INTERN
|
|
1469 |
void
|
|
1470 |
trx_i_s_cache_end_write( |
|
1471 |
/*====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1472 |
trx_i_s_cache_t* cache) /*!< in: cache */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1473 |
{
|
1474 |
#ifdef UNIV_SYNC_DEBUG
|
|
1475 |
ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX)); |
|
1476 |
#endif
|
|
1477 |
||
1478 |
rw_lock_x_unlock(&cache->rw_lock); |
|
1479 |
}
|
|
1480 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1481 |
/*******************************************************************//**
|
1482 |
Selects a INFORMATION SCHEMA table cache from the whole cache.
|
|
1483 |
@return table cache */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1484 |
static
|
1485 |
i_s_table_cache_t* |
|
1486 |
cache_select_table( |
|
1487 |
/*===============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1488 |
trx_i_s_cache_t* cache, /*!< in: whole cache */ |
1489 |
enum i_s_table table) /*!< in: which table */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1490 |
{
|
1491 |
i_s_table_cache_t* table_cache; |
|
1492 |
||
1493 |
#ifdef UNIV_SYNC_DEBUG
|
|
1494 |
ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_SHARED) |
|
1495 |
|| rw_lock_own(&cache->rw_lock, RW_LOCK_EX)); |
|
1496 |
#endif
|
|
1497 |
||
1498 |
switch (table) { |
|
1499 |
case I_S_INNODB_TRX: |
|
1500 |
table_cache = &cache->innodb_trx; |
|
1501 |
break; |
|
1502 |
case I_S_INNODB_LOCKS: |
|
1503 |
table_cache = &cache->innodb_locks; |
|
1504 |
break; |
|
1505 |
case I_S_INNODB_LOCK_WAITS: |
|
1506 |
table_cache = &cache->innodb_lock_waits; |
|
1507 |
break; |
|
1508 |
default: |
|
1509 |
ut_error; |
|
1510 |
}
|
|
1511 |
||
1512 |
return(table_cache); |
|
1513 |
}
|
|
1514 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1515 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1516 |
Retrieves the number of used rows in the cache for a given
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1517 |
INFORMATION SCHEMA table.
|
1518 |
@return number of rows */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1519 |
UNIV_INTERN
|
1520 |
ulint
|
|
1521 |
trx_i_s_cache_get_rows_used( |
|
1522 |
/*========================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1523 |
trx_i_s_cache_t* cache, /*!< in: cache */ |
1524 |
enum i_s_table table) /*!< in: which table */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1525 |
{
|
1526 |
i_s_table_cache_t* table_cache; |
|
1527 |
||
1528 |
table_cache = cache_select_table(cache, table); |
|
1529 |
||
1530 |
return(table_cache->rows_used); |
|
1531 |
}
|
|
1532 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1533 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1534 |
Retrieves the nth row (zero-based) in the cache for a given
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1535 |
INFORMATION SCHEMA table.
|
1536 |
@return row */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1537 |
UNIV_INTERN
|
1538 |
void* |
|
1539 |
trx_i_s_cache_get_nth_row( |
|
1540 |
/*======================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1541 |
trx_i_s_cache_t* cache, /*!< in: cache */ |
1542 |
enum i_s_table table, /*!< in: which table */ |
|
1543 |
ulint n) /*!< in: row number */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1544 |
{
|
1545 |
i_s_table_cache_t* table_cache; |
|
1546 |
ulint i; |
|
1547 |
void* row; |
|
1548 |
||
1549 |
table_cache = cache_select_table(cache, table); |
|
1550 |
||
1551 |
ut_a(n < table_cache->rows_used); |
|
1552 |
||
1553 |
row = NULL; |
|
1554 |
||
1555 |
for (i = 0; i < MEM_CHUNKS_IN_TABLE_CACHE; i++) { |
|
1556 |
||
1557 |
if (table_cache->chunks[i].offset |
|
1558 |
+ table_cache->chunks[i].rows_allocd > n) { |
|
1559 |
||
1560 |
row = (char*) table_cache->chunks[i].base |
|
1561 |
+ (n - table_cache->chunks[i].offset) |
|
1562 |
* table_cache->row_size; |
|
1563 |
break; |
|
1564 |
}
|
|
1565 |
}
|
|
1566 |
||
1567 |
ut_a(row != NULL); |
|
1568 |
||
1569 |
return(row); |
|
1570 |
}
|
|
1571 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1572 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1573 |
Crafts a lock id string from a i_s_locks_row_t object. Returns its
|
1574 |
second argument. This function aborts if there is not enough space in
|
|
1575 |
lock_id. Be sure to provide at least TRX_I_S_LOCK_ID_MAX_LEN + 1 if you
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1576 |
want to be 100% sure that it will not abort.
|
1577 |
@return resulting lock id */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1578 |
UNIV_INTERN
|
1579 |
char* |
|
1580 |
trx_i_s_create_lock_id( |
|
1581 |
/*===================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1582 |
const i_s_locks_row_t* row, /*!< in: innodb_locks row */ |
1583 |
char* lock_id,/*!< out: resulting lock_id */ |
|
1584 |
ulint lock_id_size)/*!< in: size of the lock id |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1585 |
buffer */
|
1586 |
{
|
|
1587 |
int res_len; |
|
1588 |
||
1589 |
/* please adjust TRX_I_S_LOCK_ID_MAX_LEN if you change this */
|
|
1590 |
||
1591 |
if (row->lock_space != ULINT_UNDEFINED) { |
|
1592 |
/* record lock */
|
|
1593 |
res_len = ut_snprintf(lock_id, lock_id_size, |
|
1594 |
TRX_ID_FMT ":%lu:%lu:%lu", |
|
1595 |
row->lock_trx_id, row->lock_space, |
|
1596 |
row->lock_page, row->lock_rec); |
|
1597 |
} else { |
|
1598 |
/* table lock */
|
|
1599 |
res_len = ut_snprintf(lock_id, lock_id_size, |
|
1819.9.78
by Stewart Smith
fix TRX_ID_FMT and associated printf() |
1600 |
TRX_ID_FMT ":" TRX_ID_FMT, |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1601 |
row->lock_trx_id, |
1602 |
row->lock_table_id); |
|
1603 |
}
|
|
1604 |
||
1605 |
/* the typecast is safe because snprintf(3) never returns
|
|
1606 |
negative result */
|
|
1607 |
ut_a(res_len >= 0); |
|
1608 |
ut_a((ulint) res_len < lock_id_size); |
|
1609 |
||
1610 |
return(lock_id); |
|
1611 |
}
|