1
/******************************************************
1
/*****************************************************************************
3
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
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.
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.
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
17
*****************************************************************************/
19
/**************************************************//**
2
21
Transaction undo log record
6
23
Created 3/26/1996 Heikki Tuuri
7
24
*******************************************************/
15
32
#include "fsp0fsp.h"
16
33
#include "mach0data.h"
19
34
#include "trx0undo.h"
36
#ifndef UNIV_HOTBACKUP
20
37
#include "dict0dict.h"
21
38
#include "ut0mem.h"
22
39
#include "row0ext.h"
23
40
#include "row0upd.h"
24
41
#include "que0que.h"
25
42
#include "trx0purge.h"
26
44
#include "row0row.h"
28
46
/*=========== UNDO LOG RECORD CREATION AND DECODING ====================*/
30
/**************************************************************************
48
/**********************************************************************//**
31
49
Writes the mtr log entry of the inserted undo log record on the undo log
35
53
trx_undof_page_add_undo_rec_log(
36
54
/*============================*/
37
page_t* undo_page, /* in: undo log page */
38
ulint old_free, /* in: start offset of the inserted entry */
39
ulint new_free, /* in: end offset of the entry */
40
mtr_t* mtr) /* in: mtr */
55
page_t* undo_page, /*!< in: undo log page */
56
ulint old_free, /*!< in: start offset of the inserted entry */
57
ulint new_free, /*!< in: end offset of the entry */
58
mtr_t* mtr) /*!< in: mtr */
43
61
const byte* log_end;
66
84
mlog_catenate_string(mtr, undo_page + old_free + 2, len);
87
#endif /* !UNIV_HOTBACKUP */
70
/***************************************************************
71
Parses a redo log record of adding an undo log record. */
89
/***********************************************************//**
90
Parses a redo log record of adding an undo log record.
91
@return end of log record or NULL */
74
94
trx_undo_parse_add_undo_rec(
75
95
/*========================*/
76
/* out: end of log record or NULL */
77
byte* ptr, /* in: buffer */
78
byte* end_ptr,/* in: buffer end */
79
page_t* page) /* in: page or NULL */
96
byte* ptr, /*!< in: buffer */
97
byte* end_ptr,/*!< in: buffer end */
98
page_t* page) /*!< in: page or NULL */
114
133
return(ptr + len);
117
/**************************************************************************
118
Calculates the free space left for extending an undo log record. */
136
#ifndef UNIV_HOTBACKUP
137
/**********************************************************************//**
138
Calculates the free space left for extending an undo log record.
139
@return bytes left */
123
/* out: bytes left */
124
const page_t* page, /* in: undo log page */
125
const byte* ptr) /* in: pointer to page */
144
const page_t* page, /*!< in: undo log page */
145
const byte* ptr) /*!< in: pointer to page */
127
147
/* The '- 10' is a safety margin, in case we have some small
128
148
calculation error below */
130
150
return(UNIV_PAGE_SIZE - (ptr - page) - 10 - FIL_PAGE_DATA_END);
133
/**************************************************************************
153
/**********************************************************************//**
134
154
Set the next and previous pointers in the undo page for the undo record
135
155
that was written to ptr. Update the first free value by the number of bytes
136
written for this undo record.*/
156
written for this undo record.
157
@return offset of the inserted entry on the page if succeeded, 0 if fail */
139
160
trx_undo_page_set_next_prev_and_add(
140
161
/*================================*/
141
/* out: offset of the inserted entry
142
on the page if succeeded, 0 if fail */
143
page_t* undo_page, /* in/out: undo log page */
144
byte* ptr, /* in: ptr up to where data has been
162
page_t* undo_page, /*!< in/out: undo log page */
163
byte* ptr, /*!< in: ptr up to where data has been
145
164
written on this undo page. */
146
mtr_t* mtr) /* in: mtr */
165
mtr_t* mtr) /*!< in: mtr */
148
ulint first_free; /* offset within undo_page */
149
ulint end_of_rec; /* offset within undo_page */
167
ulint first_free; /*!< offset within undo_page */
168
ulint end_of_rec; /*!< offset within undo_page */
150
169
byte* ptr_to_first_free;
151
170
/* pointer within undo_page
152
171
that points to the next free
183
202
return(first_free);
186
/**************************************************************************
187
Reports in the undo log of an insert of a clustered index record. */
205
/**********************************************************************//**
206
Reports in the undo log of an insert of a clustered index record.
207
@return offset of the inserted entry on the page if succeed, 0 if fail */
190
210
trx_undo_page_report_insert(
191
211
/*========================*/
192
/* out: offset of the inserted entry
193
on the page if succeed, 0 if fail */
194
page_t* undo_page, /* in: undo log page */
195
trx_t* trx, /* in: transaction */
196
dict_index_t* index, /* in: clustered index */
197
const dtuple_t* clust_entry, /* in: index entry which will be
212
page_t* undo_page, /*!< in: undo log page */
213
trx_t* trx, /*!< in: transaction */
214
dict_index_t* index, /*!< in: clustered index */
215
const dtuple_t* clust_entry, /*!< in: index entry which will be
198
216
inserted to the clustered index */
199
mtr_t* mtr) /* in: mtr */
217
mtr_t* mtr) /*!< in: mtr */
201
219
ulint first_free;
256
274
return(trx_undo_page_set_next_prev_and_add(undo_page, ptr, mtr));
259
/**************************************************************************
260
Reads from an undo log record the general parameters. */
277
/**********************************************************************//**
278
Reads from an undo log record the general parameters.
279
@return remaining part of undo log record after reading these values */
263
282
trx_undo_rec_get_pars(
264
283
/*==================*/
265
/* out: remaining part of undo log
266
record after reading these values */
267
trx_undo_rec_t* undo_rec, /* in: undo log record */
268
ulint* type, /* out: undo record type:
284
trx_undo_rec_t* undo_rec, /*!< in: undo log record */
285
ulint* type, /*!< out: undo record type:
269
286
TRX_UNDO_INSERT_REC, ... */
270
ulint* cmpl_info, /* out: compiler info, relevant only
287
ulint* cmpl_info, /*!< out: compiler info, relevant only
271
288
for update type records */
272
ibool* updated_extern, /* out: TRUE if we updated an
289
ibool* updated_extern, /*!< out: TRUE if we updated an
273
290
externally stored fild */
274
dulint* undo_no, /* out: undo log record number */
275
dulint* table_id) /* out: table id */
291
undo_no_t* undo_no, /*!< out: undo log record number */
292
dulint* table_id) /*!< out: table id */
304
/**************************************************************************
305
Reads from an undo log record a stored column value. */
321
/**********************************************************************//**
322
Reads from an undo log record a stored column value.
323
@return remaining part of undo log record after reading these values */
308
326
trx_undo_rec_get_col_val(
309
327
/*=====================*/
310
/* out: remaining part of undo log record after
311
reading these values */
312
byte* ptr, /* in: pointer to remaining part of undo log record */
313
byte** field, /* out: pointer to stored field */
314
ulint* len, /* out: length of the field, or UNIV_SQL_NULL */
315
ulint* orig_len)/* out: original length of the locally
328
byte* ptr, /*!< in: pointer to remaining part of undo log record */
329
byte** field, /*!< out: pointer to stored field */
330
ulint* len, /*!< out: length of the field, or UNIV_SQL_NULL */
331
ulint* orig_len)/*!< out: original length of the locally
316
332
stored part of an externally stored column, or 0 */
318
334
*len = mach_read_compressed(ptr);
354
/***********************************************************************
355
Builds a row reference from an undo log record. */
370
/*******************************************************************//**
371
Builds a row reference from an undo log record.
372
@return pointer to remaining part of undo record */
358
375
trx_undo_rec_get_row_ref(
359
376
/*=====================*/
360
/* out: pointer to remaining part of undo
362
byte* ptr, /* in: remaining part of a copy of an undo log
377
byte* ptr, /*!< in: remaining part of a copy of an undo log
363
378
record, at the start of the row reference;
364
379
NOTE that this copy of the undo log record must
365
380
be preserved as long as the row reference is
366
381
used, as we do NOT copy the data in the
368
dict_index_t* index, /* in: clustered index */
369
dtuple_t** ref, /* out, own: row reference */
370
mem_heap_t* heap) /* in: memory heap from which the memory
383
dict_index_t* index, /*!< in: clustered index */
384
dtuple_t** ref, /*!< out, own: row reference */
385
mem_heap_t* heap) /*!< in: memory heap from which the memory
371
386
needed is allocated */
401
/***********************************************************************
402
Skips a row reference from an undo log record. */
416
/*******************************************************************//**
417
Skips a row reference from an undo log record.
418
@return pointer to remaining part of undo record */
405
421
trx_undo_rec_skip_row_ref(
406
422
/*======================*/
407
/* out: pointer to remaining part of undo
409
byte* ptr, /* in: remaining part in update undo log
423
byte* ptr, /*!< in: remaining part in update undo log
410
424
record, at the start of the row reference */
411
dict_index_t* index) /* in: clustered index */
425
dict_index_t* index) /*!< in: clustered index */
432
/**************************************************************************
446
/**********************************************************************//**
433
447
Fetch a prefix of an externally stored column, for writing to the undo log
434
of an update or delete marking of a clustered index record. */
448
of an update or delete marking of a clustered index record.
437
452
trx_undo_page_fetch_ext(
438
453
/*====================*/
440
byte* ext_buf, /* in: a buffer of
454
byte* ext_buf, /*!< in: a buffer of
441
455
REC_MAX_INDEX_COL_LEN
442
456
+ BTR_EXTERN_FIELD_REF_SIZE */
443
ulint zip_size, /* compressed page size in bytes,
457
ulint zip_size, /*!< compressed page size in bytes,
444
458
or 0 for uncompressed BLOB */
445
const byte* field, /* in: an externally stored column */
446
ulint* len) /* in: length of field;
459
const byte* field, /*!< in: an externally stored column */
460
ulint* len) /*!< in: length of field;
447
461
out: used length of ext_buf */
449
463
/* Fetch the BLOB. */
462
/**************************************************************************
463
Writes to the undo log a prefix of an externally stored column. */
476
/**********************************************************************//**
477
Writes to the undo log a prefix of an externally stored column.
478
@return undo log position */
466
481
trx_undo_page_report_modify_ext(
467
482
/*============================*/
468
/* out: undo log position */
469
byte* ptr, /* in: undo log position,
483
byte* ptr, /*!< in: undo log position,
470
484
at least 15 bytes must be available */
471
byte* ext_buf, /* in: a buffer of
485
byte* ext_buf, /*!< in: a buffer of
472
486
REC_MAX_INDEX_COL_LEN
473
487
+ BTR_EXTERN_FIELD_REF_SIZE,
474
488
or NULL when should not fetch
475
489
a longer prefix */
476
ulint zip_size, /* compressed page size in bytes,
490
ulint zip_size, /*!< compressed page size in bytes,
477
491
or 0 for uncompressed BLOB */
478
const byte** field, /* in/out: the locally stored part of
492
const byte** field, /*!< in/out: the locally stored part of
479
493
the externally stored column */
480
ulint* len) /* in/out: length of field, in bytes */
494
ulint* len) /*!< in/out: length of field, in bytes */
483
497
/* If an ordering column is externally stored, we will
503
/**************************************************************************
517
/**********************************************************************//**
504
518
Reports in the undo log of an update or delete marking of a clustered index
520
@return byte offset of the inserted undo log entry on the page if
521
succeed, 0 if fail */
508
524
trx_undo_page_report_modify(
509
525
/*========================*/
510
/* out: byte offset of the inserted
511
undo log entry on the page if succeed,
513
page_t* undo_page, /* in: undo log page */
514
trx_t* trx, /* in: transaction */
515
dict_index_t* index, /* in: clustered index where update or
526
page_t* undo_page, /*!< in: undo log page */
527
trx_t* trx, /*!< in: transaction */
528
dict_index_t* index, /*!< in: clustered index where update or
516
529
delete marking is done */
517
const rec_t* rec, /* in: clustered index record which
530
const rec_t* rec, /*!< in: clustered index record which
518
531
has NOT yet been modified */
519
const ulint* offsets, /* in: rec_get_offsets(rec, index) */
520
const upd_t* update, /* in: update vector which tells the
532
const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
533
const upd_t* update, /*!< in: update vector which tells the
521
534
columns to be updated; in the case of
522
535
a delete, this should be set to NULL */
523
ulint cmpl_info, /* in: compiler info on secondary
536
ulint cmpl_info, /*!< in: compiler info on secondary
525
mtr_t* mtr) /* in: mtr */
538
mtr_t* mtr) /*!< in: mtr */
527
540
dict_table_t* table;
528
541
ulint first_free;
809
822
return(first_free);
812
/**************************************************************************
825
/**********************************************************************//**
813
826
Reads from an undo log update record the system field values of the old
828
@return remaining part of undo log record after reading these values */
817
831
trx_undo_update_rec_get_sys_cols(
818
832
/*=============================*/
819
/* out: remaining part of undo log
820
record after reading these values */
821
byte* ptr, /* in: remaining part of undo log
822
record after reading general
824
dulint* trx_id, /* out: trx id */
825
dulint* roll_ptr, /* out: roll ptr */
826
ulint* info_bits) /* out: info bits state */
833
byte* ptr, /*!< in: remaining part of undo
834
log record after reading
835
general parameters */
836
trx_id_t* trx_id, /*!< out: trx id */
837
roll_ptr_t* roll_ptr, /*!< out: roll ptr */
838
ulint* info_bits) /*!< out: info bits state */
828
840
/* Read the state of the info bits */
829
841
*info_bits = mach_read_from_1(ptr);
843
/**************************************************************************
844
Reads from an update undo log record the number of updated fields. */
855
/**********************************************************************//**
856
Reads from an update undo log record the number of updated fields.
857
@return remaining part of undo log record after reading this value */
847
860
trx_undo_update_rec_get_n_upd_fields(
848
861
/*=================================*/
849
/* out: remaining part of undo log record after
850
reading this value */
851
byte* ptr, /* in: pointer to remaining part of undo log record */
852
ulint* n) /* out: number of fields */
862
byte* ptr, /*!< in: pointer to remaining part of undo log record */
863
ulint* n) /*!< out: number of fields */
854
865
*n = mach_read_compressed(ptr);
855
866
ptr += mach_get_compressed_size(*n);
860
/**************************************************************************
861
Reads from an update undo log record a stored field number. */
871
/**********************************************************************//**
872
Reads from an update undo log record a stored field number.
873
@return remaining part of undo log record after reading this value */
864
876
trx_undo_update_rec_get_field_no(
865
877
/*=============================*/
866
/* out: remaining part of undo log record after
867
reading this value */
868
byte* ptr, /* in: pointer to remaining part of undo log record */
869
ulint* field_no)/* out: field number */
878
byte* ptr, /*!< in: pointer to remaining part of undo log record */
879
ulint* field_no)/*!< out: field number */
871
881
*field_no = mach_read_compressed(ptr);
872
882
ptr += mach_get_compressed_size(*field_no);
877
/***********************************************************************
878
Builds an update vector based on a remaining part of an undo log record. */
887
/*******************************************************************//**
888
Builds an update vector based on a remaining part of an undo log record.
889
@return remaining part of the record, NULL if an error detected, which
890
means that the record is corrupted */
881
893
trx_undo_update_rec_get_update(
882
894
/*===========================*/
883
/* out: remaining part of the record,
884
NULL if an error detected, which means that
885
the record is corrupted */
886
byte* ptr, /* in: remaining part in update undo log
895
byte* ptr, /*!< in: remaining part in update undo log
887
896
record, after reading the row reference
888
897
NOTE that this copy of the undo log record must
889
898
be preserved as long as the update vector is
890
899
used, as we do NOT copy the data in the
892
dict_index_t* index, /* in: clustered index */
893
ulint type, /* in: TRX_UNDO_UPD_EXIST_REC,
901
dict_index_t* index, /*!< in: clustered index */
902
ulint type, /*!< in: TRX_UNDO_UPD_EXIST_REC,
894
903
TRX_UNDO_UPD_DEL_REC, or
895
904
TRX_UNDO_DEL_MARK_REC; in the last case,
896
905
only trx id and roll ptr fields are added to
897
906
the update vector */
898
dulint trx_id, /* in: transaction id from this undo record */
899
dulint roll_ptr,/* in: roll pointer from this undo record */
900
ulint info_bits,/* in: info bits from this undo record */
901
trx_t* trx, /* in: transaction */
902
mem_heap_t* heap, /* in: memory heap from which the memory
907
trx_id_t trx_id, /*!< in: transaction id from this undo record */
908
roll_ptr_t roll_ptr,/*!< in: roll pointer from this undo record */
909
ulint info_bits,/*!< in: info bits from this undo record */
910
trx_t* trx, /*!< in: transaction */
911
mem_heap_t* heap, /*!< in: memory heap from which the memory
903
912
needed is allocated */
904
upd_t** upd) /* out, own: update vector */
913
upd_t** upd) /*!< out, own: update vector */
906
915
upd_field_t* upd_field;
999
/***********************************************************************
1008
/*******************************************************************//**
1000
1009
Builds a partial row from an update undo log record. It contains the
1001
columns which occur as ordering in any index of the table. */
1010
columns which occur as ordering in any index of the table.
1011
@return pointer to remaining part of undo record */
1004
1014
trx_undo_rec_get_partial_row(
1005
1015
/*=========================*/
1006
/* out: pointer to remaining part of undo
1008
byte* ptr, /* in: remaining part in update undo log
1016
byte* ptr, /*!< in: remaining part in update undo log
1009
1017
record of a suitable type, at the start of
1010
1018
the stored index columns;
1011
1019
NOTE that this copy of the undo log record must
1012
1020
be preserved as long as the partial row is
1013
1021
used, as we do NOT copy the data in the
1015
dict_index_t* index, /* in: clustered index */
1016
dtuple_t** row, /* out, own: partial row */
1017
ibool ignore_prefix, /* in: flag to indicate if we
1023
dict_index_t* index, /*!< in: clustered index */
1024
dtuple_t** row, /*!< out, own: partial row */
1025
ibool ignore_prefix, /*!< in: flag to indicate if we
1018
1026
expect blob prefixes in undo. Used
1019
1027
only in the assertion. */
1020
mem_heap_t* heap) /* in: memory heap from which the memory
1028
mem_heap_t* heap) /*!< in: memory heap from which the memory
1021
1029
needed is allocated */
1023
1031
const byte* end_ptr;
1087
#endif /* !UNIV_HOTBACKUP */
1080
/***************************************************************************
1089
/***********************************************************************//**
1081
1090
Erases the unused undo log page end. */
1084
1093
trx_undo_erase_page_end(
1085
1094
/*====================*/
1086
page_t* undo_page, /* in: undo page whose end to erase */
1087
mtr_t* mtr) /* in: mtr */
1095
page_t* undo_page, /*!< in: undo page whose end to erase */
1096
mtr_t* mtr) /*!< in: mtr */
1089
1098
ulint first_free;
1096
1105
mlog_write_initial_log_record(undo_page, MLOG_UNDO_ERASE_END, mtr);
1099
/***************************************************************
1100
Parses a redo log record of erasing of an undo page end. */
1108
/***********************************************************//**
1109
Parses a redo log record of erasing of an undo page end.
1110
@return end of log record or NULL */
1103
1113
trx_undo_parse_erase_page_end(
1104
1114
/*==========================*/
1105
/* out: end of log record or NULL */
1106
byte* ptr, /* in: buffer */
1107
byte* end_ptr __attribute__((unused)), /* in: buffer end */
1108
page_t* page, /* in: page or NULL */
1109
mtr_t* mtr) /* in: mtr or NULL */
1115
byte* ptr, /*!< in: buffer */
1116
byte* end_ptr __attribute__((unused)), /*!< in: buffer end */
1117
page_t* page, /*!< in: page or NULL */
1118
mtr_t* mtr) /*!< in: mtr or NULL */
1111
1120
ut_ad(ptr && end_ptr);
1123
/***************************************************************************
1132
#ifndef UNIV_HOTBACKUP
1133
/***********************************************************************//**
1124
1134
Writes information to an undo log about an insert, update, or a delete marking
1125
1135
of a clustered index record. This information is used in a rollback of the
1126
1136
transaction and in consistent reads that must look to the history of this
1138
@return DB_SUCCESS or error code */
1130
1141
trx_undo_report_row_operation(
1131
1142
/*==========================*/
1132
/* out: DB_SUCCESS or error code */
1133
ulint flags, /* in: if BTR_NO_UNDO_LOG_FLAG bit is
1143
ulint flags, /*!< in: if BTR_NO_UNDO_LOG_FLAG bit is
1134
1144
set, does nothing */
1135
ulint op_type, /* in: TRX_UNDO_INSERT_OP or
1145
ulint op_type, /*!< in: TRX_UNDO_INSERT_OP or
1136
1146
TRX_UNDO_MODIFY_OP */
1137
que_thr_t* thr, /* in: query thread */
1138
dict_index_t* index, /* in: clustered index */
1139
const dtuple_t* clust_entry, /* in: in the case of an insert,
1147
que_thr_t* thr, /*!< in: query thread */
1148
dict_index_t* index, /*!< in: clustered index */
1149
const dtuple_t* clust_entry, /*!< in: in the case of an insert,
1140
1150
index entry to insert into the
1141
1151
clustered index, otherwise NULL */
1142
const upd_t* update, /* in: in the case of an update,
1152
const upd_t* update, /*!< in: in the case of an update,
1143
1153
the update vector, otherwise NULL */
1144
ulint cmpl_info, /* in: compiler info on secondary
1154
ulint cmpl_info, /*!< in: compiler info on secondary
1145
1155
index updates */
1146
const rec_t* rec, /* in: in case of an update or delete
1156
const rec_t* rec, /*!< in: in case of an update or delete
1147
1157
marking, the record in the clustered
1148
1158
index, otherwise NULL */
1149
dulint* roll_ptr) /* out: rollback pointer to the
1159
roll_ptr_t* roll_ptr) /*!< out: rollback pointer to the
1150
1160
inserted undo log record,
1151
1161
ut_dulint_zero if BTR_NO_UNDO_LOG
1152
1162
flag was specified */
1309
1319
/*============== BUILDING PREVIOUS VERSION OF A RECORD ===============*/
1311
/**********************************************************************
1321
/******************************************************************//**
1312
1322
Copies an undo record to heap. This function can be called if we know that
1313
the undo log record exists. */
1323
the undo log record exists.
1324
@return own: copy of the record */
1315
1326
trx_undo_rec_t*
1316
1327
trx_undo_get_undo_rec_low(
1317
1328
/*======================*/
1318
/* out, own: copy of the record */
1319
dulint roll_ptr, /* in: roll pointer to record */
1320
mem_heap_t* heap) /* in: memory heap where copied */
1329
roll_ptr_t roll_ptr, /*!< in: roll pointer to record */
1330
mem_heap_t* heap) /*!< in: memory heap where copied */
1322
1332
trx_undo_rec_t* undo_rec;
1344
1354
return(undo_rec);
1347
/**********************************************************************
1348
Copies an undo record to heap. */
1357
/******************************************************************//**
1358
Copies an undo record to heap.
1360
NOTE: the caller must have latches on the clustered index page and
1363
@return DB_SUCCESS, or DB_MISSING_HISTORY if the undo log has been
1364
truncated and we cannot fetch the old version */
1351
1367
trx_undo_get_undo_rec(
1352
1368
/*==================*/
1353
/* out: DB_SUCCESS, or
1354
DB_MISSING_HISTORY if the undo log
1355
has been truncated and we cannot
1356
fetch the old version; NOTE: the
1357
caller must have latches on the
1358
clustered index page and purge_view */
1359
dulint roll_ptr, /* in: roll pointer to record */
1360
dulint trx_id, /* in: id of the trx that generated
1369
roll_ptr_t roll_ptr, /*!< in: roll pointer to record */
1370
trx_id_t trx_id, /*!< in: id of the trx that generated
1361
1371
the roll pointer: it points to an
1362
1372
undo log of this transaction */
1363
trx_undo_rec_t** undo_rec, /* out, own: copy of the record */
1364
mem_heap_t* heap) /* in: memory heap where copied */
1373
trx_undo_rec_t** undo_rec, /*!< out, own: copy of the record */
1374
mem_heap_t* heap) /*!< in: memory heap where copied */
1366
1376
#ifdef UNIV_SYNC_DEBUG
1367
1377
ut_ad(rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
1380
1390
return(DB_SUCCESS);
1383
/***********************************************************************
1393
/*******************************************************************//**
1384
1394
Build a previous version of a clustered index record. This function checks
1385
1395
that the caller has a latch on the index page of the clustered index record
1386
1396
and an s-latch on the purge_view. This guarantees that the stack of versions
1387
is locked all the way down to the purge_view. */
1397
is locked all the way down to the purge_view.
1398
@return DB_SUCCESS, or DB_MISSING_HISTORY if the previous version is
1399
earlier than purge_view, which means that it may have been removed,
1400
DB_ERROR if corrupted record */
1390
1403
trx_undo_prev_version_build(
1391
1404
/*========================*/
1392
/* out: DB_SUCCESS, or DB_MISSING_HISTORY if
1393
the previous version is not >= purge_view,
1394
which means that it may have been removed,
1395
DB_ERROR if corrupted record */
1396
const rec_t* index_rec,/* in: clustered index record in the
1405
const rec_t* index_rec,/*!< in: clustered index record in the
1398
1407
mtr_t* index_mtr __attribute__((unused)),
1399
/* in: mtr which contains the latch to
1408
/*!< in: mtr which contains the latch to
1400
1409
index_rec page and purge_view */
1401
const rec_t* rec, /* in: version of a clustered index record */
1402
dict_index_t* index, /* in: clustered index */
1403
ulint* offsets,/* in: rec_get_offsets(rec, index) */
1404
mem_heap_t* heap, /* in: memory heap from which the memory
1410
const rec_t* rec, /*!< in: version of a clustered index record */
1411
dict_index_t* index, /*!< in: clustered index */
1412
ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
1413
mem_heap_t* heap, /*!< in: memory heap from which the memory
1405
1414
needed is allocated */
1406
rec_t** old_vers)/* out, own: previous version, or NULL if
1415
rec_t** old_vers)/*!< out, own: previous version, or NULL if
1407
1416
rec is the first inserted version, or if
1408
1417
history data has been deleted (an error),
1409
1418
or if the purge COULD have removed the version