UDF Execution does not honour record_ttl


#1

UDF Execution does not update TTL

Problem Description

When calling a UDF from AQL in a namespace with no default TTL, where the aerospike:update(rec) function is invoked, the TTL for the record is set to 4294967295. An illustration of the issue is shown below.

UDF code

function touchRecords(rec) 
warn("Will update record: key=%s", tostring(record.key(rec)))
rec["EV_MAP"] = rec["EV_MAP"]
rc = aerospike:update(rec);
end

Example

aql>register module '/home/vagrant/udf/touchRecords.lua'
aql> set output JSON
aql> set record_print_metadata true
aql> set record_ttl = 1000


aql> insert into ns.udftest (PK, EV_MAP) values ('fb13a696-8e66-4db4-b901-9257cdaf708c', 'JSON{"0_dced5fda09e5d8cca141d6267275d0c1": 1453240532474}')


aql> select * from ns.udftest where Pk='fb13a696-8e66-4db4-b901-9257cdaf708c'
[
  {
    "digest": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
    "ttl": 996,
    "gen": 1,
    "bins": {
      "EV_MAP": {
        "0_dced5fda09e5d8cca141d6267275d0c1": 1453240532474
      }
    }
  }
]



aql> execute touchRecords.touchRecords() on ns.udftest where PK='fb13a696-8e66-4db4-b901-9257cdaf708c'
[
  {
    "digest": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
    "ttl": 0,
    "gen": 0,
    "bins": {
      "touchRecords": null
    }
  }
]


aql> select * from ns.udftest where Pk='fb13a696-8e66-4db4-b901-9257cdaf708c'
[
  {
    "digest": "AAAAAAAAAAAAAAAAAAAAAAAAAAA=",
    "ttl": 4294967295,
    "gen": 2,
    "bins": {
      "EV_MAP": {
        "0_dced5fda09e5d8cca141d6267275d0c1": 1453240532474
      }
    }
  }
]

Explanation

This is a new behaviour in AQL to bring it inline with other Aerospike clients. If there is a default-ttl specified for the namespace, the TTL will be set to that value. If there is no default-ttl and no max-ttl set, the void time (the time at which the record will be evicted) is set to 0xFFFFffff and the TTL (the difference between current time and void time) is set to 4294967295 these values represent records with a void time of 0 which will never expire.

The implications of this are important during eviction. Records with a void time of 0 will not be considered for eviction and so capacity management may be affected. In extreme cases the database could hit stop-writes if it is not able to evict sufficient numbers of records when disk high water marks are breached…

Solution

If this behaviour is not desired there are two approaches that can be taken. The default-ttl or max-ttl for the namespace can be set and the record would then use those values. An alternate approach would be to read in the TTL and set it explicitly in the record as shown in the illustration below.

function touchRecords(rec)
local currentTtl = record.ttl(rec)

rec["EV_MAP"] = rec["EV_MAP"]

record.set_ttl(rec, currentTtl)
rc = aerospike:update(rec);
if( rc ~= nil and rc ~= 0 ) then
warn("[ERROR] Record update failed: rc(%s)", tostring(rc));
end
end

Notes

This is specific to AQL. In other clients write-policy is used to control this behaviour.

Keywords

UDF TTL 4294967295 VOID 3.7.5.x EVICTION

Timestamp

4/13/16