Context
Our current XDR rewind feature does not support a way to rewind specific sets. This KB covers a workaround to rewind specific sets using XDR Filter Expressions.
Method
The goal is to ship the desired sets without reshipping records from any of the sets.
Logical expression
(or (> (lut) T0)
(and (< (lut) T1)
(or (= (set-name) 'foo')
(= (set-name) 'bar')
...
)
)
)
T0: Time when applying the filter to the first set to the destination cluster.
T1: Time when applying the filter to the next set to the destination cluster
Write script filter to only send records from the first set (setRPL1) starting from time now (T0) and after. T0 and T1 would be the same.
// example java script if ONLY syncing 1 set
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Base64;
import com.aerospike.client.exp.Exp;
import com.aerospike.client.exp.Expression;
public class Option3 {
public static void main(String args[]) {
Calendar t0 = new GregorianCalendar(2022, 2, 26, 0, 5);
Calendar t1 = new GregorianCalendar(2022, 2, 26, 0, 5);
Expression filter = Exp.build(
Exp.or(
Exp.gt(
Exp.lastUpdate(),Exp.val(t1)
),
Exp.and(
Exp.le(
Exp.lastUpdate(),Exp.val(t0)
),
Exp.eq(Exp.setName(), Exp.val("setRPL1")
)
)
)
);
System.out.println(filter.getBase64());
}
}
// example java script if syncing MORE than 1 set
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Base64;
import com.aerospike.client.exp.Exp;
import com.aerospike.client.exp.Expression;
public class Option3 {
public static void main(String args[]) {
Calendar t0 = new GregorianCalendar(2022, 2, 26, 0, 5);
Calendar t1 = new GregorianCalendar(2022, 2, 25, 0, 5);
Expression filter = Exp.build(
Exp.or(
Exp.gt(
Exp.lastUpdate(), Exp.val(t1)
),
Exp.and(
Exp.le(
Exp.lastUpdate(), Exp.val(t0)
),
Exp.or(
Exp.eq(Exp.setName(), Exp.val("setRPL1”)),
Exp.eq(Exp.setName(), Exp.val(“setRPL2”)),
. . .
)
)
)
)
);
System.out.println(filter.getBase64());
}
}
Run the code and get base64 of the filter expression:
# javac -cp .:root/java/aerospike-client-java-5.1.11/benchmarks/target/aerospike-benchmarks-5.1.11.jar:/root/java/aerospike-client-java-5.1.11/benchmarks/target/aerospike-benchmarks-5.1.11-jar-with-dependencies.jar Option3.java
# java -cp .:root/java/aerospike-client-java-5.1.11/benchmarks/target/aerospike-benchmarks-5.1.11.jar:/root/java/aerospike-client-java-5.1.11/benchmarks/target/aerospike-benchmarks-5.1.11-jar-with-dependencies.jar Option3
kxGTA5FCzxbfxXYtb7gAkxCTBpFCzxbfxXYtb7gAkwGRRqgDc2V0UlBMMQ==
Run the asinfo command using the base64 output of the filter expression
asinfo -v "xdr-set-filter:dc=dc4;namespace=test;exp=kxGTA5FCzxbfxXYtb7gAkxCTBpFCzxbfxXYtb7gAkwGRRqgDc2V0UlBMMQ=="
ok
Do the rewind
asinfo -v "set-config:context=xdr;dc=dc4;namespace=test;action=remove";
ok
asinfo -v "set-config:context=xdr;dc=dc4;namespace=test;action=add;rewind=all";
ok
Between the rewind and the next set to sync would be the time between T0 and T1. Adjust T1 to the timestamp now, and keep T0 as the previous time so that you don’t reship anything between T0 and T1.
// syncing ONLY 1 set
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Base64;
import com.aerospike.client.exp.Exp;
import com.aerospike.client.exp.Expression;
public class Option3 {
public static void main(String args[]) {
Calendar t0 = new GregorianCalendar(2022, 2, 26, 0, 5);
Calendar t1 = new GregorianCalendar(2022, 2, 26, 0, 14);
Expression filter = Exp.build(
Exp.or(
Exp.gt(
Exp.lastUpdate(),Exp.val(t1)
),
Exp.and(
Exp.le(
Exp.lastUpdate(),Exp.val(t0)
),
Exp.eq(Exp.setName(), Exp.val("setRPL2”)
)
)
)
);
System.out.println(filter.getBase64());
}
}
// syncing MORE than 1 set
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Base64;
import com.aerospike.client.exp.Exp;
import com.aerospike.client.exp.Expression;
public class Option3 {
public static void main(String args[]) {
Calendar t0 = new GregorianCalendar(2022, 2, 26, 0, 5);
Calendar t1 = new GregorianCalendar(2022, 2, 25, 0, 14);
Expression filter = Exp.build(
Exp.or(
Exp.gt(
Exp.lastUpdate(), Exp.val(t1)
),
Exp.and(
Exp.le(
Exp.lastUpdate(), Exp.val(t0)
),
Exp.or(
Exp.eq(Exp.setName(), Exp.val("setRPL1”)),
Exp.eq(Exp.setName(), Exp.val(“setRPL2”)),
. . .
)
)
)
)
);
System.out.println(filter.getBase64());
}
}
Run the code and get base64 of filter expression
Run the asinfo command using the new base64 output of filter expression
Do the rewind
Repeat by adjusting T1 to now until all sets are finished rewinding from T0 without reshipping anything from between T0 and T1.