couchbase Posts

Changing Couchbase Data Directory Location

Usually Couchbase put its data on default location (/opt/couchbase/var/lib/couchbase/data). But because my disk’s space is full, i have to move Couchbase data to other location. In my case, /data folder which is mounted to an empty 100GB SSD disk. Below is how i change it,

First, i have to change the content of below file,

vi /opt/couchbase/etc/couchdb/default.d/capi.ini 

Changing database_dir and view_index_dir on below Couchbase configuration file, to my new location folder

max_dbs_open = 10000
database_dir = /data
view_index_dir = /data

db_frontend = capi_frontend
ip4_bind_address =
ip6_bind_address = ::
port = 8092

Next is move the content of old folder (/opt/couchbase/var/lib/couchbase/data), to our new folder (/data). And restart our Couchbase service to implement our changes.

  sudo service couchbase-server stop
  sudo service couchbase-server start

We can see the result on our Couchbase web console, hopefully it helps (H)

ps. My Couchbase version is “Enterprise Edition 6.0.0 build 1693”.


How to do a Simple Query Analysis and Optimization in Couchbase

I’ve joined an Indonesian Startup named Mapan since this September, leaving my previous role at a multinational consulting company. And to be honest, in here there are so many things to learn and a whole new playground to play with, and let me share one of new thing i’ve learn during my one month service here.

After im spending some time with mandatory company induction and way of working, i started with some technical matters and found a quite interesting issue regarding slow queries to Couchbase database, thats why im share step by step on how to analyze and gives workarond so that perhaps it wont happen again.

Dislaimer : on the time this writing is created, im working with Couchbase for less than 1 month. This writing is still open for discussion and improvement :-D .

Study Case #1

SELECT inventory.*
FROM inventory
WHERE inventory.`key` LIKE "ih:RUMA_0101_AABY12349%"
limit 1000

With almost 1 million data, it took more than 30seconds to fetch 1000 data which have key that starts with “ih:RUMA_0101_AABY12349”.

First analysis is that corresponding query despite hitting on an index, it still gives a quite amount of time of fetching as you can see on below image. It is happen mostly due to fetching is done first with all the data (85% of time is used for this, around 38 seconds) and do the filtering later on.

First thing that i see is that query is done on “key” field which have a common format, like “key”: “ih:RUMA_0101_AABY12349:1534087762346131”. So, instead of searching based on wildcard, better do searching on split string of “key” field, and create and index based on it.

CREATE INDEX key02_split ON inventory ( split(inventory.`key`, ":")[1] )   
PARTITION BY HASH (split(inventory.`key`, ":")[1]) where split(inventory.`key`, ":")[1] is not null

And change the query needed into below,

SELECT inventory.*
FROM inventory
WHERE split(inventory.`key`, ":")[1] = 'RUMA_0101_AABY12349'
limit 1000

Drastically reducing the query time into 80ms, as on below screenshot.

Study Case #2

SELECT `inventory_trx`.* FROM `inventory_trx` 
WHERE client = "RUMA" 
and movement_type in ["IB001", "IB002", "IB003", "OB001", "OB002", "TF001", "TF002", 
"IA001", "IA003", "IA005", "IA007", "IA002", "IA004"] 
and transaction_timestamp between 1525107600 and 1537808399 and  
(origin.code = "0101" or destination.code = "0101")  
order by transaction_timestamp desc offset 0 limit 1000

Again, same issue happen here. Despite hitting get_stock_mutation index, it still takes some time for fetching. On below screenshot, it shows almost 36 seconds only for fetching.

Again, almost the same approach is used for this case. We can see which field is used on WHERE parameter, and start indexing it. The only difference is that it have range query on transaction_timestamp field and also order by criteria, which will make it a little bit complicated.

It took not only query optimization, but also some negotiation to implements some changes on User Interface. On previous query, transaction_timestamp parameter doesnt have any limitation on start and end date, therefore make it harder to do indexing. After consulting with user, they are agree that there should be a one month limitation for doing range query.

After user agree with changes on UI, next is to create an Index on Couchbase for corresponding query.

CREATE INDEX inventory_trx_ix01 
ON inventory_trx ( client, movement_type, DATE_PART_MILLIS(transaction_timestamp * 1000, "month"), 
origin.code, destination.code, DATE_PART_MILLIS(transaction_timestamp * 1000, "year"))

Tweaking the query into below,

SELECT `inventory_trx`.* FROM `inventory_trx` 
WHERE client = "RUMA" 
and movement_type in ["IB001", "IB002", "IB003", "OB001", "OB002", 
"TF001", "TF002", "IA001", "IA003", "IA005", "IA007", "IA002", "IA004"] 
and DATE_PART_MILLIS(transaction_timestamp * 1000, "month") = 9
and DATE_PART_MILLIS(transaction_timestamp * 1000, "year") = 2018
and  (origin.code = "0101" or destination.code = "0101")
limit 1000

Reducing query time needed significantly,