Incompatible API changes
Version 7.0.0
Value.UseBoolBin now defaults to true
Previous client versions wrote a boolean value to a bin by default, using the Aerospike integer particle type.
Client versions 7.0.0+ write a boolean value to a bin by default, using the Aerospike boolean particle type.
The client can read boolean values from either integer or boolean particle types via Record.GetBool()
.
To restore old behavior, set Value.UseBoolBin
to false. This stores the Aerospike integer particle type for booleans.
Set this value once at the beginning of the program and before instantiating any AerospikeClient instances.
This applies to all AerospikeClient
instances.
This guarantees it occurs before any write commands:
using Aerospike.Client;
Value.UseBoolBin = false;AerospikeClient client = new AerospikeClient(policy, hosts);
Version 6.2.0
Add returnType argument to MapExp.RemoveBy()
and ListExp.RemoveBy()
.
A new returnType argument has been added to relevant MapExp.RemoveBy()
and ListExp.RemoveBy()
methods. To upgrade existing MapExp.RemoveBy()
methods, pass in MapReturnType.NONE
. To upgrade existing ListExp.RemoveBy()
methods, pass in ListReturnType.NONE
.
Old behavior
MapExp.RemoveByKeyList(keys, bin);ListExp.RemoveByValue(value, bin);
New behavior
MapExp.RemoveByKeyList(MapReturnType.NONE, keys, bin);ListExp.RemoveByValue(ListReturnType.NONE, value, bin);
Version 6.1.0 - Remove auto-serialization and auto-deserialization
Auto serialization and deserilization has been removed from the C# client because of the CWE-502 vulnerability.
Old behavior
The C# client previously used BinaryFormatter to format object types that are not directly supported by the Aerospike server. In version 6.0.0, some support for processing these objects was removed, see below for more detail. When these methods were used, an exeception was thrown.
New behavior
The C# client now returns a raw byte[] instead of throwing an exception or deserializing the csharp blob.
Course of action
If your application uses csharp blobs, you must perform the following steps:
Step 1: Replace csharp blobs with byte[]
Use an older version of the client to convert all of your csharp blob bins with byte[] bins.
The byte[] can be deserialized by the user using BinaryFormatter:
using (MemoryStream ms = new MemoryStream()){ ms.Write(bytes, 0, bytes.length); ms.Seek(0, 0); BinaryFormatter formatter = new BinaryFormatter(); var deserialized = formatter.Deserialize(ms);}
Or use whatever other serilization/deserilization method you prefer.
Step 2: Update application code to use new client version
After updating to 6.1.0, auto serialization is still disallowed and should still result in a exception. Only derserialization was changed to return byte[] instead of throwing an exception.
Version 6.0.0 - Remove BinaryFormatter
The C# client previously used Microsoft’s BinaryFormatter to format object types that are not directly supported by the Aerospike server. BinaryFormatter has been declared insecure and deprecated by Microsoft. See https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2300?view=vs-2019
Therefore, the following bin constructors/methods that use BinaryFormatter have been disabled by default:
Binpublic Bin(string name, object value);public static Bin AsBlob(string name, object value);
Valuepublic static Value GetAsBlob(object value);
BlobValuepublic BlobValue(object value)
Users are encouraged to replace all BinaryFormatter bins with byte[] bins. Other serialization formats (like protobuf) can be used to format these objects into byte[] bins. During this transition period, an older client version can be used. Alternatively, the preprocessor directive “BINARY_FORMATTER” can be defined in the AerospikeClient project file that enables BinaryFormatter in a custom client build.
Version 5.0.0 - Remove old PredExp
The old deprecated PredExp functionality has been removed. Code using old PredExp must be converted to the new expression syntax. See Version 4.0.0 - Replace PredExp with Expressions
Version 4.2.0 - Remove scan fields
The following scan fields have been removed since they are no longer supported by the server.
Policy.priority
: UseScanPolicy.recordsPerSecond
instead to limit throughput.ScanPolicy.scanPercent
: UseScanPolicy.maxRecords
instead to limit records returned.ScanPolicy.failOnClusterChange
: This field is not used with partition scans.
Version 4.0.0 - Replace PredExp with Expressions
The old PredExp functionality has been replaced by Expressions. Expressions include all previous predicate expression functionality (with a different, improved syntax) plus support for record metadata expressions and list/map/bit/hyperloglog expression methods analogous to those used in operations.
- Removed PredExp class.
- Added Exp (expression builder) class.
- Added Expression (expression byte code) class.
- Added ListExp, MapExp, BitExp and HLLExp classes.
Client 4.0.0 requires server 5.2.0.4+. Client 4.0.3 restored old PredExp functionality for a period of one year in order to ease the burden of converting from old PredExp to Expressions. Client 4.0.3+ requires server 4.9+ until the year is up. At that time, old PredExp will be permanently removed.
Code using old PredExp should be converted to the new syntax. Here is an example:
OLD:
Statement stmt = new Statement();stmt.SetNamespace("test");stmt.SetSetName("set");stmt.SetFilter(Filter.Range(binName, 0, 100));
// ! (bin2 >= 15 && bin2 <= 42)stmt.SetPredExp( PredExp.IntegerBin("bin2"), PredExp.IntegerValue(15), PredExp.IntegerGreaterEq(), PredExp.IntegerBin("bin2"), PredExp.IntegerValue(42), PredExp.IntegerLessEq(), PredExp.And(2), PredExp.Not() );
RecordSet rs = client.Query(null, stmt);
NEW:
Statement stmt = new Statement();stmt.SetNamespace("test");stmt.SetSetName("set");stmt.SetFilter(Filter.Range(binName, 0, 100));
// ! (bin2 >= 15 && bin2 <= 42)QueryPolicy policy = new QueryPolicy();policy.filterExp = Exp.Build( Exp.Not( Exp.And( Exp.GE(Exp.IntBin("bin2"), Exp.Val(15)), Exp.LE(Exp.IntBin("bin2"), Exp.Val(42)))));
RecordSet rs = client.Query(policy, stmt);
Version 3.8.0 - Read consistency level changes
Read policy changes for commands involving AP (availability) namespaces
- Policy variable
ConsistencyLevel consistencyLevel
moved toReadModeAP readModeAP
.
Read policy changes for commands involving SC (strong consistency) namespaces
- Policy variable
bool linearizeRead
moved toReadModeSC readModeSC
. - Add
ReadModeSC
enum below:
/// <summary>/// Read policy for SC (strong consistency) namespaces./// <para>/// Determines SC read consistency options./// </para>/// </summary>public enum ReadModeSC{ /// <summary> /// Ensures this client will only see an increasing sequence of record versions. /// Server only reads from master. This is the default. /// </summary> SESSION,
/// <summary> /// Ensures ALL clients will only see an increasing sequence of record versions. /// Server only reads from master. /// </summary> LINEARIZE,
/// <summary> /// Server may read from master or any full (non-migrating) replica. /// Increasing sequence of record versions is not guaranteed. /// </summary> ALLOW_REPLICA,
/// <summary> /// Server may read from master or any full (non-migrating) replica or from unavailable /// partitions. Increasing sequence of record versions is not guaranteed. /// </summary> ALLOW_UNAVAILABLE}
Version 3.7.0 - Remove obsolete code
The following old obsoleted code has been removed.
-
Statement.Filters
property: This property was replaced by theStatement.Filter
property. The server accepts only one filter. -
Value.UseDoubleType
: This configuration variable is no longer necessary because all server versions that this client supports also support the double type. This client supports server versions >= 3.6.0. -
ClientPolicy.requestProleReplicas
: This configuration variable is no longer necessary because prole replicas are now always requested. -
Batch direct protocol code: This old batch direct protocol code was replaced by the batch index functionality. This code was no longer accessible by the external API.
Version 3.6.8 - Remove BatchPolicy.useBatchDirect
BatchPolicy.useBatchDirect
was removed because the server has removed support for the old batch direct protocol. Remove any references to this policy field.
Version 3.5.0 - Policy Changes, LDT Removal and Index Changes
Policy Changes
The Policy class has been redefined to support greater control on timeout behavior and provide defaults that improve retry success.
Split timeout
into socketTimeout
and totalTimeout
socketTimeout is the socket idle timeout in milliseconds. For synchronous methods, socketTimeout is the socket’s SendTimeout and ReceiveTimeout. For asynchronous methods, the socketTimeout is implemented using an AsyncTimeoutQueue and socketTimeout is only used if totalTimeout is not defined.
If socketTimeout is not zero and the socket has been idle for at least socketTimeout, both maxRetries and totalTimeout are checked. If maxRetries is not exceeded and totalTimeout is not reached, the command is retried. If both socketTimeout and totalTimeout are non-zero and socketTimeout > totalTimeout, then socketTimeout will be set to totalTimeout. If socketTimeout is zero, there will be no socket idle limit.
totalTimeout is the maximum time allowed in milliseconds to process a command. totalTimeout is tracked on the client and sent to the server along with the command in the wire protocol. The client will most likely timeout first, but the server also has the capability to timeout the command. If totalTimeout is zero, there will be no total time limit.
To keep old timeout behavior, set socketTimeout equal to totalTimeout.
Removed retryOnTimeout
retryOnTimeout has been removed because it is no longer necessary. If a command timed out on socketTimeout, retries will now occur until maxRetries is exceeded or totalTimeout is reached.
Changed Policy replica
default to Replica.SEQUENCE
The sequence replica algorithm starts with the node containing the key’s master partition. If a connection error occurs, the node containing the key’s replicated partition is used on retry. Writes now switch to replicated nodes on connection errors because the replicated node is most likely to become the new master when the old master goes down.
Reads also switch to replicated nodes on timeouts, but writes do not switch nodes on timeouts. Timeouts are not a good indicator of downed nodes.
Changed Policy maxRetries
default to 2
maxRetries now defaults to 2 to give a better chance of retry success.
Changed Policy sleepBetweenRetries
default to zero for reads
Reads do not have to sleep when a node goes down because the cluster does not shut out reads during cluster reformation.
The sleepBetweenRetries default for writes remains at 500ms. Writes need to wait for the cluster to reform when a node goes down. Immediate write retries on node failure have been shown to consistently result in errors.
Changed ClientPolicy requestProleReplicas
default to true.
Prole replica maps are required when using Replica.SEQUENCE
algorithm.
LDT Removal
LDT methods have been removed on client because large data types are no longer supported by Aerospike Server.
Index Changes
Index exception handling has changed on the client. In the past, the client swallowed INDEX_ALREADY_EXISTS errors on CreateIndex(). The client now throws an AerospikeException when an index already exists on CreateIndex().
The client also used to swallow INDEX_NOTFOUND errors on DropIndex(). The client now throws an AerospikeException when an index does not already exist on DropIndex().
To preserve old behavior, calling code can be changed to:
try { IndexTask task = client.CreateIndex(policy, ns, set, indexName, binName, indexType); task.Wait();}catch (AerospikeException ae) { if (ae.getResultCode() != ResultCode.INDEX_ALREADY_EXISTS) { throw ae; }}
try { client.DropIndex(policy, ns, set, indexName);}catch (AerospikeException ae) { if (ae.getResultCode() != ResultCode.INDEX_NOTFOUND) { throw ae; }}
Version 3.2.0 - Max connections is a now a hard limit
Past versions used to create new connections when a node’s outstanding connections exceeded ClientPolicy.maxThreads
. This connection would then be closed (not put back into connection pool) when the command finished. This could handle unexpected bursts of commands (with a performance penalty), but it also resulted in excessive socket opens/closes and too many sockets in a CLOSED/WAIT state.
Version 3.2.0 renames ClientPolicy.maxThreads
to ClientPolicy.maxConnsPerNode
and enforces a strict limit on maximum number of connections allowed per server node. Synchronous commands will now fail with ResultCode.NO_MORE_CONNECTIONS
(after going through retry logic) if the maximum number of connections would be exceeded.
The number of connections used per node depends on how many concurrent threads issue database commands plus sub-threads used for parallel multi-node commands (batch, scan, and query). One connection will be used for each thread.
ClientPolicy.maxConnsPerNode
is ignored by asynchronous commands since these commands are already bound by asyncMaxCommands by default. Each async command has a one-to-one relationship with a connection.
Version 3.1.4 - New Aerospike Server double type
The Aerospike server version 3.6.0 and later can store 64-bit double floating point values natively.
Previous server versions did not recognize the double data type, so clients sent doubles as long bits. The client can now send double as the new server double type when the following flag is set:
Value.UseDoubleType = true;
If Value.UseDoubleType = false
(default), double values are sent as long bits. Value.UseDoubleType
defaults to false because the Aerospike server and XDR (if used) must both upgrade to version 3.6.0 or later before the client can use the double data type.
The client can handle both return types (double or long) when receiving data from the server using Record.GetDouble()
:
double val = record.GetDouble("bin");
Version 3.1.1 - Bin Constructors for list
/map
Two bin constructors were added:
public Bin(string name, IList value)public Bin(string name, IDictionary value)
These constructors serialize list
/map
using a custom format supported natively by the Aerospike server. These constructors duplicate old static initializers, which are deprecated.
// Deprecatedpublic static Bin AsList(string name, IList value)// Deprecatedpublic static Bin AsMap(string name, IDictionary value)
Previous code that wrote list
/map
may have used the default Bin
object constructor:
public Bin(string name, object value)
This object constructor serializes list
/map
using the C# default serializer format. The custom format is faster and can be introspected by the server, but to preserve the old default C# serialization (for example, if you’re running with Aerospike 2 servers), modify the code:
Old
new Bin(name, list)new Bin(name, map)
New
new Bin(name, (object)list)new Bin(name, (object)map)
Finally, the underlying list
/map
value methods were also modified:
public static Value Get(IList value)public static Value Get(IDictionary value)
// Deprecatedpublic static Value GetAsList(IList value)// Deprecatedpublic static Value GetAsMap(IDictionary value)
Version 3.1.0 - NeoLua Replacement
NeoLua uses the Lua 5.3 specification and, since Database 7.0, Aerospike Database uses Lua 5.4. Prior to 7.0, Aerospike Database used LuaJIT 2.1, which is compatible with Lua 5.1.
Scripts must be compatible with both Lua 5.3 and 5.4 when connecting to Database 7.0 and later. Prior to Database 7.0, the scripts must be compatible with Lua 5.1 and 5.3.