CONSISTENCY_REQUEST after flush() gives stale results

I’m new to Couchbase, but the code below is showing unexpected results from an indexed query after a flush:

import time

import couchbase
from couchbase.cluster import Cluster
from couchbase.cluster import PasswordAuthenticator
from couchbase.n1ql import N1QLQuery, CONSISTENCY_REQUEST
from couchbase.admin import Admin

from hamcrest import equal_to, assert_that

CONN_SPEC = "couchbase://localhost"
USER = "Administrator"
PASSWORD = "Administrator"
BUCKET = "my_bucket"


def get_count_matches(b, i):
    q = N1QLQuery("SELECT * FROM my_bucket WHERE my_int > $1", i)
    q.consistency = CONSISTENCY_REQUEST
    rows = b.n1ql_query(q)
    return sum(1 for _ in rows)


admin = Admin(USER, PASSWORD)

try:
    admin.bucket_remove(BUCKET)
    time.sleep(10)
except couchbase.exceptions.HTTPError:
    pass

admin.bucket_create(BUCKET,
                    bucket_type='couchbase',
                    bucket_password=PASSWORD,
                    replicas=1,
                    ram_quota=100,
                    flush_enabled=True)
admin.wait_ready(BUCKET,
                 timeout=10.0,
                 sleep_interval=0.2)

cluster = Cluster(CONN_SPEC)
authenticator = PasswordAuthenticator(USER, PASSWORD)
cluster.authenticate(authenticator)

bucket = cluster.open_bucket(BUCKET)

manager = bucket.bucket_manager()
manager.create_n1ql_primary_index()
manager.create_n1ql_index("my_index", fields=['my_int'])

bucket.upsert('my_key', { 'my_int': 42})
assert_that(get_count_matches(bucket, 41), equal_to(1))
assert_that(get_count_matches(bucket, 42), equal_to(0))

bucket.flush()
#bucket.n1ql_query("DELETE FROM my_bucket").execute()

bucket.upsert('my_key', {'my_int': 45})
assert_that(get_count_matches(bucket, 41), equal_to(1))
assert_that(get_count_matches(bucket, 42), equal_to(1)) # Fails with flush()
assert_that(get_count_matches(bucket, 45), equal_to(0))

The same issue is also seen with the Go SDK. Tested against the current Couchbase Docker image - “Enterprise Edition 5.1.0 build 5552”

It gives the expected result if any of the following changes are made:

  • Use DELETE instead of flush()
  • Remove the index
  • Use a different key on the second upsert

Is this a bug, or just something to be aware of when using flush()?

Hi @RhysParry,

From what I’ve seen, the FLUSH operation takes time and the bucket will be in warmup stage (or some stage) for sometime after FLUSH.

FLUSH shouldn’t be taken EXACTLY as TRUNCATE in RDBMS.
Expect some warmup time after the flush operation.

@drigby – any comments?

Indeed - a flush is essentially a delete of all vBuckets (shards) and a re-create with them empty.

I expect it takes the indexer some time to update to the new state.