@@ -135,21 +135,6 @@ static void notify_listeners(Transaction *t, int status) {
135135 }
136136}
137137
138- static void set_next_gxid (xid_t value ) {
139- assert (next_gxid < value );
140- if (use_raft && raft .role == ROLE_LEADER ) {
141- assert (value <= last_gxid );
142- if (inrange (next_gxid + 1 , threshold_gxid , value )) {
143- // Time to worry has come.
144- raft_start_next_term (& raft );
145- } else {
146- // It is either too early to worry,
147- // or we have already increased the term.
148- }
149- }
150- next_gxid = value ;
151- }
152-
153138static void apply_clog_update (int action , int argument ) {
154139 int status = action ;
155140 xid_t xid = argument ;
@@ -277,6 +262,37 @@ static void onhello(client_t client, int argc, xid_t *argv) {
277262 }
278263}
279264
265+ static void set_next_gxid (xid_t value ) {
266+ assert (next_gxid < value ); // The value should only grow.
267+
268+ if (use_raft && raft .role == ROLE_LEADER ) {
269+ assert (value <= last_gxid );
270+ if (inrange (next_gxid + 1 , threshold_gxid , value )) {
271+ // Time to worry has come.
272+ raft_start_next_term (& raft );
273+ } else {
274+ // It is either too early to worry,
275+ // or we have already increased the term.
276+ }
277+ }
278+
279+ // Check that old position is 'dirty'. It is used when dtmd restarts,
280+ // to find out a correct value for 'next_gxid'. If we do not remember
281+ // 'next_gxid' it will lead to reuse of xids, which is bad.
282+ assert ((next_gxid == MIN_XID ) || (clog_read (clg , next_gxid ) == NEGATIVE ));
283+ assert (clog_read (clg , value ) == BLANK ); // New position should be clean.
284+ if (!clog_write (clg , value , NEGATIVE )) { // Marked the new position as dirty.
285+ shout ("could not mark xid = %u dirty\n" , value );
286+ assert (false); // should not happen
287+ }
288+ if (!clog_write (clg , next_gxid , BLANK )) { // Cleaned the old position.
289+ shout ("could not clean clean xid = %u from dirty state\n" , next_gxid );
290+ assert (false); // should not happen
291+ }
292+
293+ next_gxid = value ;
294+ }
295+
280296static void onreserve (client_t client , int argc , xid_t * argv ) {
281297 CHECK (argc == 3 , client , "RESERVE: wrong number of arguments" );
282298
@@ -360,8 +376,8 @@ static void onbegin(client_t client, int argc, xid_t *argv) {
360376 client ,
361377 "not enought xids left in this term"
362378 );
363- set_next_gxid (next_gxid + 1 );
364379 prev_gxid = t -> xid = next_gxid ;
380+ set_next_gxid (next_gxid + 1 );
365381 t -> snapshots_count = 0 ;
366382 t -> size = 1 ;
367383
@@ -847,7 +863,12 @@ int main(int argc, char **argv) {
847863
848864 if (!redirect_output ()) return EXIT_FAILURE ;
849865
866+ next_gxid = MIN_XID ;
850867 clg = clog_open (datadir );
868+ set_next_gxid (clog_find_last_used (clg ) + 1 );
869+ prev_gxid = next_gxid - 1 ;
870+ last_gxid = INVALID_XID ;
871+ debug ("initial next_gxid = %u\n" , next_gxid );
851872 if (!clg ) {
852873 shout ("could not open clog at '%s'\n" , datadir );
853874 return EXIT_FAILURE ;
@@ -866,9 +887,6 @@ int main(int argc, char **argv) {
866887
867888 write_pid (pidpath , getpid ());
868889
869- prev_gxid = MIN_XID ;
870- next_gxid = MIN_XID ;
871- last_gxid = INVALID_XID ;
872890
873891 int raftsock = raft_create_udp_socket (& raft );
874892 if (raftsock == -1 ) {
0 commit comments