1
1
/*****************************************************************************
2
2
3
- Copyright (c) 1997, 2011 , Oracle and/or its affiliates. All Rights Reserved.
3
+ Copyright (c) 1997, 2015 , Oracle and/or its affiliates. All Rights Reserved.
4
4
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
@@ -43,6 +43,7 @@ Created 3/14/1997 Heikki Tuuri
43
43
#include "row0vers.h"
44
44
#include "row0mysql.h"
45
45
#include "log0log.h"
46
+ #include "rem0cmp.h"
46
47
47
48
/*************************************************************************
48
49
IMPORTANT NOTE: Any operation that generates redo MUST check that there
@@ -80,7 +81,7 @@ row_purge_node_create(
80
81
81
82
/***********************************************************/ /**
82
83
Repositions the pcur in the purge node on the clustered index record,
83
- if found.
84
+ if found. If the record is not found, close pcur.
84
85
@return TRUE if the record was found */
85
86
static
86
87
ibool
@@ -90,23 +91,28 @@ row_purge_reposition_pcur(
90
91
purge_node_t * node , /*!< in: row purge node */
91
92
mtr_t * mtr ) /*!< in: mtr */
92
93
{
93
- ibool found ;
94
-
95
94
if (node -> found_clust ) {
96
- found = btr_pcur_restore_position ( mode , & (node -> pcur ), mtr );
95
+ ut_ad ( row_purge_validate_pcur (node ) );
97
96
98
- return (found );
99
- }
97
+ node -> found_clust = btr_pcur_restore_position (
98
+ mode , & (node -> pcur ), mtr );
99
+
100
+ } else {
101
+
102
+ node -> found_clust = row_search_on_row_ref (
103
+ & (node -> pcur ), mode , node -> table , node -> ref , mtr );
100
104
101
- found = row_search_on_row_ref (& (node -> pcur ), mode , node -> table ,
102
- node -> ref , mtr );
103
- node -> found_clust = found ;
105
+ if (node -> found_clust ) {
106
+ btr_pcur_store_position (& (node -> pcur ), mtr );
107
+ }
108
+ }
104
109
105
- if (found ) {
106
- btr_pcur_store_position (& (node -> pcur ), mtr );
110
+ /* Close the current cursor if we fail to position it correctly. */
111
+ if (!node -> found_clust ) {
112
+ btr_pcur_close (& node -> pcur );
107
113
}
108
114
109
- return (found );
115
+ return (node -> found_clust );
110
116
}
111
117
112
118
/***********************************************************/ /**
@@ -143,8 +149,8 @@ row_purge_remove_clust_if_poss_low(
143
149
144
150
if (!success ) {
145
151
/* The record is already removed */
146
-
147
- btr_pcur_commit_specify_mtr ( pcur , & mtr );
152
+ /* Persistent cursor is closed if reposition fails. */
153
+ mtr_commit ( & mtr );
148
154
149
155
return (TRUE);
150
156
}
@@ -258,7 +264,12 @@ row_purge_poss_sec(
258
264
btr_pcur_get_rec (& node -> pcur ),
259
265
& mtr , index , entry );
260
266
261
- btr_pcur_commit_specify_mtr (& node -> pcur , & mtr );
267
+ /* Persistent cursor is closed if reposition fails. */
268
+ if (node -> found_clust ) {
269
+ btr_pcur_commit_specify_mtr (& node -> pcur , & mtr );
270
+ } else {
271
+ mtr_commit (& mtr );
272
+ }
262
273
263
274
return (can_delete );
264
275
}
@@ -806,3 +817,53 @@ row_purge_step(
806
817
807
818
return (thr );
808
819
}
820
+
821
+ #ifdef UNIV_DEBUG
822
+ /***********************************************************/ /**
823
+ Validate the persisent cursor in the purge node. The purge node has two
824
+ references to the clustered index record - one via the ref member, and the
825
+ other via the persistent cursor. These two references must match each
826
+ other if the found_clust flag is set.
827
+ @return true if the stored copy of persistent cursor is consistent
828
+ with the ref member.*/
829
+ ibool
830
+ row_purge_validate_pcur (
831
+ purge_node_t * node )
832
+ {
833
+ dict_index_t * clust_index ;
834
+ ulint * offsets ;
835
+ int st ;
836
+
837
+ if (!node -> found_clust ) {
838
+ return (TRUE);
839
+ }
840
+
841
+ if (node -> index == NULL ) {
842
+ return (TRUE);
843
+ }
844
+
845
+ if (node -> pcur .old_stored != BTR_PCUR_OLD_STORED ) {
846
+ return (TRUE);
847
+ }
848
+
849
+ clust_index = node -> pcur .btr_cur .index ;
850
+
851
+ offsets = rec_get_offsets (node -> pcur .old_rec , clust_index , NULL ,
852
+ node -> pcur .old_n_fields , & node -> heap );
853
+
854
+ /* Here we are comparing the purge ref record and the stored initial
855
+ part in persistent cursor. Both cases we store n_uniq fields of the
856
+ cluster index and so it is fine to do the comparison. We note this
857
+ dependency here as pcur and ref belong to different modules. */
858
+ st = cmp_dtuple_rec (node -> ref , node -> pcur .old_rec , offsets );
859
+
860
+ if (st != 0 ) {
861
+ fprintf (stderr , "Purge node pcur validation failed\n" );
862
+ dtuple_print (stderr , node -> ref );
863
+ rec_print (stderr , node -> pcur .old_rec , clust_index );
864
+ return (FALSE);
865
+ }
866
+
867
+ return (TRUE);
868
+ }
869
+ #endif /* UNIV_DEBUG */
0 commit comments