<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mehmet Firat KOMURCU</title>
    <description>The latest articles on DEV Community by Mehmet Firat KOMURCU (@mehmetfiratkomurcu).</description>
    <link>https://dev.to/mehmetfiratkomurcu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F561612%2F315db9f2-ecca-4bd6-a903-34d6499133e8.jpeg</url>
      <title>DEV Community: Mehmet Firat KOMURCU</title>
      <link>https://dev.to/mehmetfiratkomurcu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mehmetfiratkomurcu"/>
    <language>en</language>
    <item>
      <title>Couchbase: Failover and Recovery</title>
      <dc:creator>Mehmet Firat KOMURCU</dc:creator>
      <pubDate>Tue, 11 May 2021 06:58:47 +0000</pubDate>
      <link>https://dev.to/mehmetfiratkomurcu/couchbase-failover-and-recovery-36dn</link>
      <guid>https://dev.to/mehmetfiratkomurcu/couchbase-failover-and-recovery-36dn</guid>
      <description>&lt;p&gt;Note: In this blog post, I assume that you have basic knowledge about Couchbase.&lt;/p&gt;

&lt;p&gt;Hello everyone, welcome to another Couchbase blog post. I highly recommend reading my  &lt;a href="https://firatkomurcu.com/couchbase-rebalance"&gt;Couchbase: Rebalance&lt;/a&gt;  blog post before reading this post.&lt;/p&gt;

&lt;p&gt;There are scenarios that we have to remove our nodes from our cluster for maintenance issues, or some node could be unresponsive, and we or Couchbase itself have to remove the node from the cluster. &lt;/p&gt;

&lt;p&gt;Let's start with how node removal works. This is how Couchbase describes what removal is: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Node removal allows a node to be taken out of a cluster in a highly controlled fashion, using rebalance to redistribute data and indexes among available nodes."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So basically, we are taking out a node from the cluster. What is that mean? That means at the end of the removal process, the cluster will have fewer resources to maintain, remaining nodes could have to store more vBuckets. &lt;/p&gt;

&lt;p&gt;Buckets can have maximum of 3 replicas. For a Data Service, the minimum replica limit is n + 1 (n is the replica number). After removing the node that contains Data Service, if the replica number is still more than n + 1, Couchbase will still support the replica number after rebalance.&lt;/p&gt;

&lt;p&gt;Assume that we have a bucket with two replicas(n=2) and remove nodes sequentially. (Numbers are approximate for the sake of simplicity)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxifyah8zhb8cjwm60a7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foxifyah8zhb8cjwm60a7.gif" alt="Failover-2-v2 (1)" width="2056" height="2261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What happened here? &lt;br&gt;
At first, we have: 40.000 active vBuckets and 80.000 replica vBuckets (1:2).&lt;br&gt;
Four nodes, which satisfies our minimum n + 1 replica node limit. After removal of Node 2, this is what happened:&lt;br&gt;
We still have 40.000 active vBuckets and 80.000 replica vBuckets in total (1:2). The node number is still more significant than n + 1, so active and replica vBucket numbers are increased in the remaining nodes to satisfy the vBucket replica by rebalancing. The remaining nodes now have to maintain more vBuckets. Now let's remove Node 4 and see what happens now:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fepcvy6r2mxwlm076q3v9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fepcvy6r2mxwlm076q3v9.gif" alt="Failover-3-v2 (1)" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, things have changed. From now on, we can't satisfy the desired node replica number for Data Service. Active vBuckets and replica vBuckets are now 40.000 (1:1).&lt;/p&gt;

&lt;p&gt;This is what happens in node removals in a nutshell. Let's continue with failover.&lt;/p&gt;

&lt;h1&gt;
  
  
  Failover
&lt;/h1&gt;

&lt;p&gt;At the beginning of this blog post, we said that there could be scenarios that we have to remove a node from the cluster. That is what Failover is. Couchbase documents describe failover as: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Failover is a process whereby a node can be taken out of a Couchbase cluster with speed."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Failover has two types: &lt;strong&gt;graceful&lt;/strong&gt; and &lt;strong&gt;hard&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Let's start with graceful. Graceful is a failover type that specific to nodes that have Data Service. The type name is graceful because Couchbase removes the node in a controlled style, so there will be no downtime. If the service is a Data Service, the process makes replica vBuckets active and then removes the Data Service node. The cluster itself can't activate graceful failover. It has to be manually activated.&lt;/p&gt;

&lt;p&gt;Hard failover is necessary when a node becomes unreachable. If the service is a Data service, the process makes replica vBuckets active and removes the Data Service node like the graceful failover. Hard failover can be manually activated, but failover can be automatically triggered by Cluster Manager additionally. This process is called &lt;strong&gt;Automatic&lt;/strong&gt; failover. Automatic failover occurs on three kinds of failure: node failure, disk read/write failure, and group failure.&lt;/p&gt;

&lt;p&gt;If a failover has occurred, gracefully or hardly, there will be an imbalance in the ratio of active to replica vBuckets. So Rebalance should be triggered.&lt;/p&gt;

&lt;h1&gt;
  
  
  Recovery
&lt;/h1&gt;

&lt;p&gt;There are two possibilities after failover. First is eradicating the node from the cluster by Rebalance completely. The second is to Recover the node and add it back to the cluster by Rebalance.&lt;/p&gt;

&lt;p&gt;There are type types of Recover: &lt;strong&gt;Delta&lt;/strong&gt; and &lt;strong&gt;Full Recovery&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delta Recovery
&lt;/h2&gt;

&lt;p&gt;Delta Recovery takes all the data, takes it to memory, and resynchronizes. The recovery process does not delete any vBuckets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqc194585lnu3ok4hzhsv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqc194585lnu3ok4hzhsv.gif" alt="Recovery-2-v2" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Delta Recovery only works when the node and cluster are healthy, but the node is in a failed-over state. But even these conditions are satisfied, there could be problems while Delta Recovery is working. So instead of Delta Recovery, Full Recovery could take over. There are a lot of reasons why this operation could happen. For example, the node could be hard failed over and marked for removal, or there could be configuration changes while the recovery process was performing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full Recovery
&lt;/h2&gt;

&lt;p&gt;Full Recovery is far simpler than Delta Recovery. The process removes all vBuckets and documents from the node and elects a new collection of vBuckets and documents.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fskca0bvfjd91xe2ks837.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fskca0bvfjd91xe2ks837.gif" alt="Recovery-1-v2" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the node has GSI Indexes, they are left unmodified during the rebalance in both recovery processes.&lt;/p&gt;

&lt;p&gt;In the Delta Recovery, data is already in the node, so there is less network traffic than Full Recovery. But Delta Recovery could need significant memory, and it could exceed the bucket memory quota.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

&lt;p&gt;May the force be with you!&lt;/p&gt;

</description>
      <category>sql</category>
      <category>nosql</category>
      <category>database</category>
    </item>
    <item>
      <title>Couchbase: Rebalance</title>
      <dc:creator>Mehmet Firat KOMURCU</dc:creator>
      <pubDate>Mon, 15 Mar 2021 10:09:46 +0000</pubDate>
      <link>https://dev.to/mehmetfiratkomurcu/couchbase-rebalance-45e3</link>
      <guid>https://dev.to/mehmetfiratkomurcu/couchbase-rebalance-45e3</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In this article, I assume you have basic knowledge about Couchbase.&lt;/p&gt;

&lt;p&gt;A Couchbase cluster could contain one or more nodes. Each node can have various services. When a node is added to or removed from a cluster for some reason, data and indexes redistribute. This process is called &lt;strong&gt;Rebalance&lt;/strong&gt;. Rebalance is a major part of Failovers and Removals in Couchbase, so it is important to understand what is happening under the hood.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rebalance on Data Service
&lt;/h2&gt;

&lt;p&gt;vBuckets are distributed evenly on data service nodes. After adding or removing a Data Service node, rebalance will hold active vBuckets and create as many replicas as possible.  &lt;/p&gt;

&lt;p&gt;Rebalance process on Data Service proceeds sequentially, so if it closes for some reason, it can continue from the last carried vBucket.&lt;/p&gt;

&lt;p&gt;On Rebalance process, Data Services remain to work, so that applications can continue. Therefore, you don't have to concern about availability. &lt;/p&gt;

&lt;h3&gt;
  
  
  Data Service Rebalance Phases
&lt;/h3&gt;

&lt;p&gt;There are two main phases in Data Service Rebalance: Phases for active vBuckets and replica vBuckets. Now let's see step by step these phases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rebalance Phases for Replica vBuckets
&lt;/h3&gt;

&lt;p&gt;This phase contains two subphases which are Backfill and Book-keeping.&lt;br&gt;
In the Backfill phase, there are two subphases. In the first subphase, replica vBucket data moves from the source node to the destination node's memory. The time required for the Backfill phase is called &lt;strong&gt;Backfill Time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ew9cva4s8dg34fout4v.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ew9cva4s8dg34fout4v.gif" alt="Rebalance_Part_1 (2)" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the second subphase, data moves from the destination node's memory to the destination node's disk. The time required for this subphase is called &lt;strong&gt;Persistence Time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiae2wefw27v3ptzqkaqk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiae2wefw27v3ptzqkaqk.gif" alt="Rebalance_Part_2 (2)" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the Book-keeping phase, rebalance completes ancillary tasks such as updating the cluster map.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3o7l61zbmts4qcontp2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3o7l61zbmts4qcontp2.gif" alt="Rebalance_Part_3 (2)" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The time required for the entire process, Backfill Time and Book-keeping phase, is called &lt;strong&gt;Move Time&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Rebalance Phases for Active vBuckets
&lt;/h3&gt;

&lt;p&gt;There are four main phases. The first two phases are the same as the replica vBucket phases. There is a little difference, which is the second phase, Book-keeping, has additional Persistence Time.&lt;br&gt;
After completing the move operation, new vBuckets need to be assigned as a new active copy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyouioqv3t0w0fbjz64eb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyouioqv3t0w0fbjz64eb.gif" alt="Rebalance_Part_4__Active (3)" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The time required for this phase is called &lt;strong&gt;Takeover Time&lt;/strong&gt;.&lt;br&gt;
The final phase is called Book-keeping, like the second phase. The phase's purpose is to complete ancillary tasks. Master Services will update the cluster map, and client SDKs begin access to new vBuckets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7c1jojy3dinkqjhw5omj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7c1jojy3dinkqjhw5omj.gif" alt="Rebalance_Part_5__Active (2)" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The time required for the entire process is called &lt;strong&gt;Move Time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That is how the Rebalance works on Data Services. Rebalance occurs on the other services too. Let's check some of them out briefly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Index Service:&lt;/strong&gt; Rebalance does not move indexes or replicas; instead, it rebuilds them in their new nodes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eventing Service:&lt;/strong&gt; During Rebalance, Eventing Service stops. After the Rebalance process complete, the service continues to work. There are checkpoints, so there aren't any lost mutations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analytics Service:&lt;/strong&gt; Analytics Service uses shadowed data, a part of Data Service data. If a node is completely removed or replaced, all shadow data have to rebuild.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query Service:&lt;/strong&gt; When you add a Query Service, it automatically starts to receive queries. When you remove one, it becomes unavailable. If you have ongoing queries, they will be interrupted.&lt;/p&gt;

&lt;p&gt;In this article, I tried to explain how Rebalance works on Couchbase. You can check  &lt;a href="https://docs.couchbase.com/server/current/learn/clusters-and-availability/rebalance.html"&gt;official documents &lt;/a&gt; for more details. Thank you for reading.&lt;/p&gt;

&lt;p&gt;May the force be with you!   &lt;/p&gt;

</description>
      <category>database</category>
      <category>couchbase</category>
      <category>nosql</category>
    </item>
    <item>
      <title>Couchbase: Scans And Pushdowns</title>
      <dc:creator>Mehmet Firat KOMURCU</dc:creator>
      <pubDate>Fri, 22 Jan 2021 06:46:17 +0000</pubDate>
      <link>https://dev.to/mehmetfiratkomurcu/couchbase-scans-and-pushdowns-7lk</link>
      <guid>https://dev.to/mehmetfiratkomurcu/couchbase-scans-and-pushdowns-7lk</guid>
      <description>&lt;p&gt;Couchbase has numerous query optimizations, and the purpose is to get the query plan as much optimized as possible. Scans and pushdowns are one of these optimizations. Let's first start with scans.&lt;/p&gt;

&lt;p&gt;Note: Before we start, I assume that you have basic knowledge about Couchbase Index, Query and Data Services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scans
&lt;/h2&gt;

&lt;p&gt;When a query request hits the Query Service, the service will transform predicates to ranges and give these ranges to Index Service. These ranges are scans.&lt;br&gt;
If you explain a query plan that uses GSI(Global Secondary Index), you can see the scans section. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Explain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;From&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Users&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"spans"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"exact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"high"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"40"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"inclusion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"low"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"33"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see in the picture, spans have "ranges". In this range section, there are three properties. These are: "high", "inclusion" and "low". What is the meaning of these? Let's see together.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"&lt;strong&gt;High&lt;/strong&gt;" means upper bound. If it does not exist, it indicates that there is no upper bound.&lt;/li&gt;
&lt;li&gt;"&lt;strong&gt;Low&lt;/strong&gt;" means lower bound. If it does not exist, it indicates that there is no lower bound.&lt;/li&gt;
&lt;li&gt;"&lt;strong&gt;Inclusion&lt;/strong&gt;" intimates if High and Low fields are involved.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Neither&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Neither&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;high&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;nor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;low&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fields&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;involved&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Low&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;low&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fields&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;involved&lt;/span&gt;&lt;span class="w"&gt;  
&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;High&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;high&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fields&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;involved&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Both&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Both&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fields&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;involved&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scans are not just for numbers. It is an explanation for predicates. Let's see how scans behave in strings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Explain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;From&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Users&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Like&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'Bruce%'&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"spans"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"exact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"high"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Brucf&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"inclusion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"low"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Bruce&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our range starts with "Bruce" and goes until all combinations begin with the "Bruce" string. "f" is the next character after "e"(last character of the "Bruce" string), so that is our high upper bound.&lt;/p&gt;

&lt;p&gt;Scans have a lot of expressions like these examples. You can check &lt;a href="https://docs.couchbase.com/server/current/learn/services-and-indexes/indexes/index-scans.html"&gt;Couchbase's document&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;So we now know what scan is. Query service produces scans and passes them to Index Service. For what? What will Index Service do with it? That question directs us to our second topic, &lt;strong&gt;pushdowns&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pushdowns
&lt;/h2&gt;

&lt;p&gt;Query Service has a lot of responsibility, a lot of work to do.  Fortunately, it has a hero to run its business efficiently, and that is Index Service. Do not think that Index Service is just indexing data and sitting there. It has a lot of abilities like pagination, ordering, point, and range scans.&lt;/p&gt;

&lt;p&gt;When Query Service produces its predicates and selects which indexes to use, it tries to address Index Service work. In that way, Query Service does less job and fewer data transfers from Index Service to Query Service. This is what pushdown is.&lt;/p&gt;

&lt;p&gt;Index Service stores its index keys in sorted order. Let's perceive this from an example. Assume that we have data that holds superheroes' names and their heights. Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Captain America"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;188&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will create an index on height.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;Create&lt;/span&gt; &lt;span class="k"&gt;Index&lt;/span&gt; &lt;span class="n"&gt;heroes_height&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;superheroes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we create the index on height, Index Service will sort it as I said before. If we now select "id" from data with "height", Query Service will get the data from Index Service. It doesn't have to go Data Service next because Index Service has "height" and "id". You can say that we did not index the "id" field. That's because Couchbase implicitly indexes document id. &lt;/p&gt;

&lt;p&gt;We can imagine Index Service stores superheroes in sorted order by height like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UbxTWT-O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1610391452682/aXEIe7Sw5.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UbxTWT-O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1610391452682/aXEIe7Sw5.jpeg" alt="Marvel-Heroes-Height-Comparison-Chart.jpg" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: Captain America's Height: 188cm ~= 6'2" and image source: marvel.com&lt;/p&gt;

&lt;p&gt;Now let's explain our select query and see what it has.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Explain&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;meta().id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;superheroes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;height&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;188&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"covers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"cover ((`superheroes`.`height`))"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"cover ((meta(`superheroes`).`id`))"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"spans"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"exact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"range"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"high"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"188"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"inclusion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"low"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"188"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see that our index covers both height(1) and id(2).&lt;/p&gt;

&lt;p&gt;At the start of the Pushdown section, I said Index Service has abilities like pagination. If Index Service stores data in sorted order, we can get data with Limit, Offset, Max, Min, etc. If you want to go deeper about these functionalities, you can check out &lt;a href="https://docs.couchbase.com/server/current/learn/services-and-indexes/indexes/index_pushdowns.html"&gt;official documents&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we learned what Scans and Pushdowns are in Couchbase. This article is my first blog post. I am open to any advice and comments. &lt;/p&gt;

&lt;p&gt;Thank you for reading, May the force be with you!&lt;/p&gt;

</description>
      <category>couchbase</category>
      <category>nosql</category>
      <category>database</category>
    </item>
  </channel>
</rss>
