Error at 32767 iteration of Read/Write routine


#1

Hi all

I try to move data from old mySQL base to aerospike namespace with some data processing and get strange result Connection to host was completed successfully, scan functionality works normally. But when I use this code almost completely copy - pasted for examples: (simplified as much as I can)

as_key key;
as_error err;
as_record rec;

as_policy_write wpol;
as_policy_write_init(&wpol);
wpol.exists = AS_POLICY_EXISTS_CREATE;

as_status aerospike_Error;
as_record *testRec = NULL;    
__int64_t keyCounter  = 0;
as_record_inita(&rec, 2);
while (1) {
	if (!as_key_init_int64(&key, AEROSPIKE_HITS_NAMESPACE, AEROSPIKE_HITS_SET, keyCounter)) {
		L(LOG_ERROR, "Can't initialize key %llu\n", keyCounter);
		return false;
	}
	if (!as_record_set_int64(&rec, "time", 1)) {
		L(LOG_ERROR, "Can't set time %llu\n", hitTime);
		return false;
	}
	as_record_set_int64(&rec, "keyCounter", keyCounter);
	++keyCounter;
	if ((aerospike_Error = aerospike_key_put(as.AeroPtr(), &err, &wpol, &key, &rec)) != AEROSPIKE_OK) {
		if (aerospike_Error == AEROSPIKE_ERR_RECORD_EXISTS) {
			L(LOG_WARNING, "Record with key %llu already exists\n", hitKey);
			continue;
		}
		L(LOG_ERROR,"aerospike_key_put() returned %d - %s\n", err.code, err.message);
		continue;
	}
	// Read the test record from the database.
	if (aerospike_key_get(as.AeroPtr(), &err, NULL, &key, &testRec) != AEROSPIKE_OK) {
		L(LOG_ERROR,"aerospike_key_get() returned %d - %s", err.code, err.message);
		continue;
	}
	as_key_destroy(&key);
	// If we didn't get an as_record object back, something's wrong.
	if (!testRec) {
		L(LOG_ERROR,"aerospike_key_get() retrieved null as_record object\n");
		continue;
	}
	// Log the result.
	if (int64_t  recTime = as_record_get_int64(testRec, "time", 0) != 1) {
		example_dump_record(testRec);
		example_dump_record(&rec);
		L(LOG_ERROR,"Time from database != time from code\n");
		as_record_destroy(testRec);
		exit(-1);
	}
			
	if (aerospike_key_remove(as.AeroPtr(), &err, NULL, &key) != AEROSPIKE_OK) {
		L(LOG_ERROR,"Can't remove record\n");
		continue;
	}
						
}
as_record_destroy(testRec);

/* Wrapper for connection*/

aerospike* AeroPtr()
{ 
    return _p_as;
}

I’d get following output

/received record/ 11.01 13:03:52 [W] generation 1, ttl 2592000, 0 bins /record that was written/ 11.01 13:03:52 [W] generation 0, ttl 0, 2 bins: 11.01 13:03:52 [W] time : 1 11.01 13:03:52 [W] keyCounter : 32767 11.01 13:05:37 [E] Time from database != time from code

What am I doing wrong?

Additional information:

  1. aerospike is in docker container at CentOS host. Code worked at same host.
  2. If I initialize keycounter with non zero value wrong record will get keyCounter exactly: initialValue + 32767
  3. If I use as_key_init_str with string key - situation keeps the same (32767 or 65535 iteration fail)

Update: if I make additional get after the error - I get record correctly.


#2

“as_record_destroy(testRec);” needs to be called each iteration just before “aerospike_key_remove()”.


#3

Inserted “as_record_destroy(testRec);” before “aerospike_key_remove()”. - nothing changes. still 32767 iteration suppose two reads for data retrieval. :frowning:


#4

There is a bug when aerospike_key_get() reuses an existing testRec. The workaround is to set testRec to NULL before calling aerospike_key_get() and call as_record_destroy(testRec) on each iteration.

The next C client release will allow you to reuse testRec in successive aerospike_key_get() calls. Then, as_record_destroy(testRec) could be called once after the loop completes like in your original code example.


#5

Thank you, Brian this magic :wink:

as_record_destroy(testRec);
testRec = NULL;

Before

aerospike_key_remove(...

did the trick. Everything works.