~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/row/row0vers.c

Tags: innodb-plugin-1.0.3
InnoDB Plugin 1.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
 
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
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
 
16
 
 
17
*****************************************************************************/
 
18
 
1
19
/******************************************************
2
20
Row versions
3
21
 
4
 
(c) 1997 Innobase Oy
5
 
 
6
22
Created 2/6/1997 Heikki Tuuri
7
23
*******************************************************/
8
24
 
48
64
        rec_t*          clust_rec;
49
65
        ulint*          clust_offsets;
50
66
        rec_t*          version;
51
 
        rec_t*          prev_version;
52
67
        dulint          trx_id;
53
 
        dulint          prev_trx_id;
54
68
        mem_heap_t*     heap;
55
69
        mem_heap_t*     heap2;
56
70
        dtuple_t*       row;
57
71
        dtuple_t*       entry   = NULL; /* assignment to eliminate compiler
58
72
                                        warning */
59
73
        trx_t*          trx;
60
 
        ulint           vers_del;
61
74
        ulint           rec_del;
62
75
        ulint           err;
63
76
        mtr_t           mtr;
141
154
        version = clust_rec;
142
155
 
143
156
        for (;;) {
 
157
                rec_t*          prev_version;
 
158
                ulint           vers_del;
 
159
                row_ext_t*      ext;
 
160
                dulint          prev_trx_id;
 
161
 
144
162
                mutex_exit(&kernel_mutex);
145
163
 
146
164
                /* While we retrieve an earlier version of clust_rec, we
157
175
                                                  heap, &prev_version);
158
176
                mem_heap_free(heap2); /* free version and clust_offsets */
159
177
 
160
 
                if (prev_version) {
161
 
                        row_ext_t*      ext;
162
 
 
163
 
                        clust_offsets = rec_get_offsets(
164
 
                                prev_version, clust_index, NULL,
165
 
                                ULINT_UNDEFINED, &heap);
166
 
 
167
 
                        vers_del = rec_get_deleted_flag(prev_version,
168
 
                                                        comp);
169
 
                        prev_trx_id = row_get_rec_trx_id(prev_version,
170
 
                                                         clust_index,
171
 
                                                         clust_offsets);
172
 
 
173
 
                        /* If the trx_id and prev_trx_id are
174
 
                        different and if the prev_version is marked
175
 
                        deleted then the prev_trx_id must have
176
 
                        already committed for the trx_id to be able to
177
 
                        modify the row. Therefore, prev_trx_id cannot
178
 
                        hold any implicit lock. */
179
 
                        if (0 != ut_dulint_cmp(trx_id, prev_trx_id)
180
 
                            && vers_del) {
181
 
        
182
 
                                mutex_enter(&kernel_mutex);
 
178
                if (prev_version == NULL) {
 
179
                        mutex_enter(&kernel_mutex);
 
180
 
 
181
                        if (!trx_is_active(trx_id)) {
 
182
                                /* Transaction no longer active: no
 
183
                                implicit x-lock */
 
184
 
183
185
                                break;
184
186
                        }
185
187
 
186
 
                        /* The stack of versions is locked by mtr.
187
 
                        Thus, it is safe to fetch the prefixes for
188
 
                        externally stored columns. */
189
 
                        row = row_build(ROW_COPY_POINTERS, clust_index,
190
 
                                        prev_version, clust_offsets,
191
 
                                        NULL, &ext, heap);
192
 
                        entry = row_build_index_entry(row, ext, index, heap);
193
 
                        /* entry may be NULL if a record was inserted
194
 
                        in place of a deleted record, and the BLOB
195
 
                        pointers of the new record were not
196
 
                        initialized yet.  But in that case,
197
 
                        prev_version should be NULL. */
198
 
                        ut_a(entry);
199
 
                }
 
188
                        /* If the transaction is still active,
 
189
                        clust_rec must be a fresh insert, because no
 
190
                        previous version was found. */
 
191
                        ut_ad(err == DB_SUCCESS);
 
192
 
 
193
                        /* It was a freshly inserted version: there is an
 
194
                        implicit x-lock on rec */
 
195
 
 
196
                        trx = trx_get_on_id(trx_id);
 
197
 
 
198
                        break;
 
199
                }
 
200
 
 
201
                clust_offsets = rec_get_offsets(prev_version, clust_index,
 
202
                                                NULL, ULINT_UNDEFINED, &heap);
 
203
 
 
204
                vers_del = rec_get_deleted_flag(prev_version, comp);
 
205
                prev_trx_id = row_get_rec_trx_id(prev_version, clust_index,
 
206
                                                 clust_offsets);
 
207
 
 
208
                /* If the trx_id and prev_trx_id are different and if
 
209
                the prev_version is marked deleted then the
 
210
                prev_trx_id must have already committed for the trx_id
 
211
                to be able to modify the row. Therefore, prev_trx_id
 
212
                cannot hold any implicit lock. */
 
213
                if (vers_del && 0 != ut_dulint_cmp(trx_id, prev_trx_id)) {
 
214
 
 
215
                        mutex_enter(&kernel_mutex);
 
216
                        break;
 
217
                }
 
218
 
 
219
                /* The stack of versions is locked by mtr.  Thus, it
 
220
                is safe to fetch the prefixes for externally stored
 
221
                columns. */
 
222
                row = row_build(ROW_COPY_POINTERS, clust_index, prev_version,
 
223
                                clust_offsets, NULL, &ext, heap);
 
224
                entry = row_build_index_entry(row, ext, index, heap);
 
225
                /* entry may be NULL if a record was inserted in place
 
226
                of a deleted record, and the BLOB pointers of the new
 
227
                record were not initialized yet.  But in that case,
 
228
                prev_version should be NULL. */
 
229
                ut_a(entry);
200
230
 
201
231
                mutex_enter(&kernel_mutex);
202
232
 
206
236
                        break;
207
237
                }
208
238
 
209
 
                /* If the transaction is still active, the previous version
210
 
                of clust_rec must be accessible if not a fresh insert; we
211
 
                may assert the following: */
212
 
 
213
 
                ut_ad(err == DB_SUCCESS);
214
 
 
215
 
                if (prev_version == NULL) {
216
 
                        /* It was a freshly inserted version: there is an
217
 
                        implicit x-lock on rec */
218
 
 
219
 
                        trx = trx_get_on_id(trx_id);
220
 
 
221
 
                        break;
222
 
                }
223
 
 
224
239
                /* If we get here, we know that the trx_id transaction is
225
240
                still active and it has modified prev_version. Let us check
226
241
                if prev_version would require rec to be in a different
227
242
                state. */
228
243
 
 
244
                /* The previous version of clust_rec must be
 
245
                accessible, because the transaction is still active
 
246
                and clust_rec was not a fresh insert. */
 
247
                ut_ad(err == DB_SUCCESS);
 
248
 
229
249
                /* We check if entry and rec are identified in the alphabetical
230
250
                ordering */
231
251
                if (0 == cmp_dtuple_rec(entry, rec, offsets)) {