| <!DOCTYPE html> |
| <!-- |
| | Generated by Apache Maven Doxia Site Renderer 1.8.1 from src/site/xdoc/acid-semantics.xml |
| | Rendered using Apache Maven Fluido Skin 1.7.1-HBase |
| --> |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <meta http-equiv="Content-Language" content="en" /> |
| <title>Apache HBase – |
| Apache HBase (TM) ACID Properties |
| </title> |
| <link rel="stylesheet" href="./css/apache-maven-fluido-1.7.1-HBase.min.css" /> |
| <link rel="stylesheet" href="./css/site.css" /> |
| <link rel="stylesheet" href="./css/print.css" media="print" /> |
| <script type="text/javascript" src="./js/apache-maven-fluido-1.7.1-HBase.min.js"></script> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"></meta> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap-responsive.min.css"/> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/styles/github.min.css"/> |
| <link rel="stylesheet" href="css/site.css"/> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"></script> |
| </head> |
| <body class="topBarEnabled"> |
| <div id="topbar" class="navbar navbar-fixed-top "> |
| <div class="navbar-inner"> |
| <div class="container"> |
| <a data-target=".nav-collapse" data-toggle="collapse" class="btn btn-navbar"> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| <span class="icon-bar"></span> |
| </a> |
| <div class="nav-collapse"> |
| <ul class="nav"> |
| <li class="dropdown"> |
| <a href="#" class="dropdown-toggle" data-toggle="dropdown">Apache HBase Project <b class="caret"></b></a> |
| <ul class="dropdown-menu"> |
| <li><a href="index.html" title="Overview">Overview</a></li> |
| <li><a href="licenses.html" title="License">License</a></li> |
| <li><a href="http://www.apache.org/dyn/closer.cgi/hbase/" title="Downloads">Downloads</a></li> |
| <li><a href="https://issues.apache.org/jira/browse/HBASE?report=com.atlassian.jira.plugin.system.project:changelog-panel#selectedTab=com.atlassian.jira.plugin.system.project%3Achangelog-panel" title="Release Notes">Release Notes</a></li> |
| <li><a href="coc.html" title="Code Of Conduct">Code Of Conduct</a></li> |
| <li><a href="http://blogs.apache.org/hbase/" title="Blog">Blog</a></li> |
| <li><a href="mailing-lists.html" title="Mailing Lists">Mailing Lists</a></li> |
| <li><a href="team.html" title="Team">Team</a></li> |
| <li><a href="https://reviews.apache.org/" title="ReviewBoard">ReviewBoard</a></li> |
| <li><a href="sponsors.html" title="Thanks">Thanks</a></li> |
| <li><a href="poweredbyhbase.html" title="Powered by HBase">Powered by HBase</a></li> |
| <li><a href="resources.html" title="Other resources">Other resources</a></li> |
| </ul> |
| </li> |
| <li class="dropdown"> |
| <a href="#" class="dropdown-toggle" data-toggle="dropdown">Project Information <b class="caret"></b></a> |
| <ul class="dropdown-menu"> |
| <li><a href="summary.html" title="Project Summary">Project Summary</a></li> |
| <li><a href="dependency-info.html" title="Dependency Information">Dependency Information</a></li> |
| <li><a href="scm.html" title="Source Repository">Source Repository</a></li> |
| <li><a href="issue-management.html" title="Issue Tracking">Issue Tracking</a></li> |
| <li><a href="dependency-management.html" title="Dependency Management">Dependency Management</a></li> |
| <li><a href="dependencies.html" title="Dependencies">Dependencies</a></li> |
| <li><a href="dependency-convergence.html" title="Dependency Convergence">Dependency Convergence</a></li> |
| <li><a href="plugin-management.html" title="Plugin Management">Plugin Management</a></li> |
| <li><a href="plugins.html" title="Plugins">Plugins</a></li> |
| </ul> |
| </li> |
| <li class="dropdown"> |
| <a href="#" class="dropdown-toggle" data-toggle="dropdown">Documentation and API <b class="caret"></b></a> |
| <ul class="dropdown-menu"> |
| <li><a href="book.html" target="_blank" title="Reference Guide">Reference Guide</a></li> |
| <li><a href="apache_hbase_reference_guide.pdf" target="_blank" title="Reference Guide (PDF)">Reference Guide (PDF)</a></li> |
| <li><a href="book.html#quickstart" target="_blank" title="Getting Started">Getting Started</a></li> |
| <li><a href="apidocs/index.html" target="_blank" title="User API">User API</a></li> |
| <li><a href="testapidocs/index.html" target="_blank" title="User API (Test)">User API (Test)</a></li> |
| <li><a href="2.0/devapidocs/index.html" target="_blank" title="Developer API">Developer API</a></li> |
| <li><a href="2.0/testdevapidocs/index.html" target="_blank" title="Developer API (Test)">Developer API (Test)</a></li> |
| <li><a href="http://abloz.com/hbase/book.html" target="_blank" title="中文参考指南(单页)">中文参考指南(单页)</a></li> |
| <li><a href="book.html#faq" target="_blank" title="FAQ">FAQ</a></li> |
| <li><a href="book.html#other.info" target="_blank" title="Videos/Presentations">Videos/Presentations</a></li> |
| <li><a href="http://wiki.apache.org/hadoop/Hbase" target="_blank" title="Wiki">Wiki</a></li> |
| <li><a href="acid-semantics.html" target="_blank" title="ACID Semantics">ACID Semantics</a></li> |
| <li><a href="book.html#arch.bulk.load" target="_blank" title="Bulk Loads">Bulk Loads</a></li> |
| <li><a href="metrics.html" target="_blank" title="Metrics">Metrics</a></li> |
| <li><a href="cygwin.html" target="_blank" title="HBase on Windows">HBase on Windows</a></li> |
| <li><a href="book.html#replication" target="_blank" title="Cluster replication">Cluster replication</a></li> |
| <li class="dropdown-submenu"> |
| <a href="" title="1.2 Documentation">1.2 Documentation</a> |
| <ul class="dropdown-menu"> |
| <li><a href="1.2/apidocs/index.html" target="_blank" title="API">API</a></li> |
| <li><a href="1.2/xref/index.html" target="_blank" title="X-Ref">X-Ref</a></li> |
| <li><a href="1.2/book.html" target="_blank" title="Ref Guide (single-page)">Ref Guide (single-page)</a></li> |
| </ul> |
| </li> |
| <li class="dropdown-submenu"> |
| <a href="" title="1.1 Documentation">1.1 Documentation</a> |
| <ul class="dropdown-menu"> |
| <li><a href="1.1/apidocs/index.html" target="_blank" title="API">API</a></li> |
| <li><a href="1.1/xref/index.html" target="_blank" title="X-Ref">X-Ref</a></li> |
| <li><a href="1.1/book.html" target="_blank" title="Ref Guide (single-page)">Ref Guide (single-page)</a></li> |
| </ul> |
| </li> |
| </ul> |
| </li> |
| <li class="dropdown"> |
| <a href="#" class="dropdown-toggle" data-toggle="dropdown">ASF <b class="caret"></b></a> |
| <ul class="dropdown-menu"> |
| <li><a href="http://www.apache.org/foundation/" target="_blank" title="Apache Software Foundation">Apache Software Foundation</a></li> |
| <li><a href="http://www.apache.org/foundation/how-it-works.html" target="_blank" title="How Apache Works">How Apache Works</a></li> |
| <li><a href="http://www.apache.org/foundation/sponsorship.html" target="_blank" title="Sponsoring Apache">Sponsoring Apache</a></li> |
| </ul> |
| </li> |
| </ul> |
| <div id="search-form" class="navbar-search pull-right"> |
| <script type="text/javascript"> |
| var cx = '000385458301414556862:sq1bb0xugjg'; |
| |
| (function() { |
| var gcse = document.createElement('script'); |
| gcse.type = 'text/javascript'; |
| gcse.async = true; |
| gcse.src = 'https://cse.google.com/cse.js?cx=' + cx; |
| var s = document.getElementsByTagName('script')[0]; |
| s.parentNode.insertBefore(gcse, s); |
| })(); |
| |
| </script> |
| <gcse:search></gcse:search> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="container"> |
| <div id="banner"> |
| <div class="pull-left"><a href="./" id="bannerLeft"><img src="" alt=""/></a></div> |
| <div class="pull-right"><a href="http://hbase.apache.org/" id="bannerRight"><img src="images/hbase_logo_with_orca_large.png" alt="Apache HBase"/></a></div> |
| <div class="clear"><hr/></div> |
| </div> |
| |
| <div id="breadcrumbs"> |
| <ul class="breadcrumb"> |
| </ul> |
| </div> |
| <div id="bodyColumn" > |
| |
| |
| <div class="section"> |
| <h2><a name="About_this_Document"></a>About this Document</h2> |
| |
| <p>Apache HBase (TM) is not an ACID compliant database. However, it does guarantee certain specific |
| properties.</p> |
| |
| <p>This specification enumerates the ACID properties of HBase.</p> |
| </div> |
| |
| <div class="section"> |
| <h2><a name="Definitions"></a>Definitions</h2> |
| |
| <p>For the sake of common vocabulary, we define the following terms:</p> |
| |
| <dl> |
| |
| <dt>Atomicity</dt> |
| |
| <dd>an operation is atomic if it either completes entirely or not at all</dd> |
| |
| |
| <dt>Consistency</dt> |
| |
| <dd> |
| all actions cause the table to transition from one valid state directly to another |
| (eg a row will not disappear during an update, etc) |
| </dd> |
| |
| |
| <dt>Isolation</dt> |
| |
| <dd> |
| an operation is isolated if it appears to complete independently of any other concurrent transaction |
| </dd> |
| |
| |
| <dt>Durability</dt> |
| |
| <dd>any update that reports "successful" to the client will not be lost</dd> |
| |
| |
| <dt>Visibility</dt> |
| |
| <dd>an update is considered visible if any subsequent read will see the update as having been committed</dd> |
| </dl> |
| |
| <p> |
| The terms <i>must</i> and <i>may</i> are used as specified by RFC 2119. |
| In short, the word "must" implies that, if some case exists where the statement |
| is not true, it is a bug. The word "may" implies that, even if the guarantee |
| is provided in a current release, users should not rely on it. |
| </p> |
| </div> |
| |
| <div class="section"> |
| <h2><a name="APIs_to_consider"></a>APIs to consider</h2> |
| |
| <ul> |
| |
| <li>Read APIs |
| |
| <ul> |
| |
| <li>get</li> |
| |
| <li>scan</li> |
| </ul> |
| </li> |
| |
| <li>Write APIs</li> |
| |
| <ul> |
| |
| <li>put</li> |
| |
| <li>batch put</li> |
| |
| <li>delete</li> |
| </ul> |
| |
| <li>Combination (read-modify-write) APIs</li> |
| |
| <ul> |
| |
| <li>incrementColumnValue</li> |
| |
| <li>checkAndPut</li> |
| </ul> |
| </ul> |
| </div> |
| |
| |
| <div class="section"> |
| <h2><a name="Guarantees_Provided"></a>Guarantees Provided</h2> |
| |
| |
| <div class="section"> |
| <h2><a name="Atomicity"></a>Atomicity</h2> |
| |
| |
| <ol style="list-style-type: decimal"> |
| |
| <li>All mutations are atomic within a row. Any put will either wholly succeed or wholly fail.[3]</li> |
| |
| <ol style="list-style-type: decimal"> |
| |
| <li>An operation that returns a "success" code has completely succeeded.</li> |
| |
| <li>An operation that returns a "failure" code has completely failed.</li> |
| |
| <li>An operation that times out may have succeeded and may have failed. However, |
| it will not have partially succeeded or failed.</li> |
| </ol> |
| |
| <li> This is true even if the mutation crosses multiple column families within a row.</li> |
| |
| <li> APIs that mutate several rows will _not_ be atomic across the multiple rows. |
| For example, a multiput that operates on rows 'a','b', and 'c' may return having |
| mutated some but not all of the rows. In such cases, these APIs will return a list |
| of success codes, each of which may be succeeded, failed, or timed out as described above.</li> |
| |
| <li> The checkAndPut API happens atomically like the typical compareAndSet (CAS) operation |
| found in many hardware architectures.</li> |
| |
| <li> The order of mutations is seen to happen in a well-defined order for each row, with no |
| interleaving. For example, if one writer issues the mutation "a=1,b=1,c=1" and |
| another writer issues the mutation "a=2,b=2,c=2", the row must either |
| be "a=1,b=1,c=1" or "a=2,b=2,c=2" and must <i>not</i> be something |
| like "a=1,b=2,c=1".</li> |
| |
| <ol style="list-style-type: decimal"> |
| |
| <li>Please note that this is not true _across rows_ for multirow batch mutations.</li> |
| </ol> |
| </ol> |
| </div> |
| |
| <div class="section"> |
| <h2><a name="Consistency_and_Isolation"></a>Consistency and Isolation</h2> |
| |
| <ol style="list-style-type: decimal"> |
| |
| <li>All rows returned via any access API will consist of a complete row that existed at |
| some point in the table's history.</li> |
| |
| <li>This is true across column families - i.e a get of a full row that occurs concurrent |
| with some mutations 1,2,3,4,5 will return a complete row that existed at some point in time |
| between mutation i and i+1 for some i between 1 and 5.</li> |
| |
| <li>The state of a row will only move forward through the history of edits to it.</li> |
| </ol> |
| |
| |
| <div class="section"> |
| <h2><a name="Consistency_of_Scans"></a>Consistency of Scans</h2> |
| |
| <p> |
| A scan is <b>not</b> a consistent view of a table. Scans do |
| <b>not</b> exhibit <i>snapshot isolation</i>. |
| </p> |
| |
| <p> |
| Rather, scans have the following properties: |
| </p> |
| |
| |
| <ol style="list-style-type: decimal"> |
| |
| <li> |
| Any row returned by the scan will be a consistent view (i.e. that version |
| of the complete row existed at some point in time) [1] |
| </li> |
| |
| <li> |
| A scan will always reflect a view of the data <i>at least as new as</i> |
| the beginning of the scan. This satisfies the visibility guarantees |
| enumerated below.</li> |
| |
| <ol style="list-style-type: decimal"> |
| |
| <li>For example, if client A writes data X and then communicates via a side |
| channel to client B, any scans started by client B will contain data at least |
| as new as X.</li> |
| |
| <li>A scan _must_ reflect all mutations committed prior to the construction |
| of the scanner, and _may_ reflect some mutations committed subsequent to the |
| construction of the scanner.</li> |
| |
| <li>Scans must include <i>all</i> data written prior to the scan (except in |
| the case where data is subsequently mutated, in which case it _may_ reflect |
| the mutation)</li> |
| </ol> |
| </ol> |
| |
| <p> |
| Those familiar with relational databases will recognize this isolation level as "read committed". |
| </p> |
| |
| <p> |
| Please note that the guarantees listed above regarding scanner consistency |
| are referring to "transaction commit time", not the "timestamp" |
| field of each cell. That is to say, a scanner started at time <i>t</i> may see edits |
| with a timestamp value greater than <i>t</i>, if those edits were committed with a |
| "forward dated" timestamp before the scanner was constructed. |
| </p> |
| </div> |
| </div> |
| |
| <div class="section"> |
| <h2><a name="Visibility"></a>Visibility</h2> |
| |
| <ol style="list-style-type: decimal"> |
| |
| <li> When a client receives a "success" response for any mutation, that |
| mutation is immediately visible to both that client and any client with whom it |
| later communicates through side channels. [3]</li> |
| |
| <li> A row must never exhibit so-called "time-travel" properties. That |
| is to say, if a series of mutations moves a row sequentially through a series of |
| states, any sequence of concurrent reads will return a subsequence of those states.</li> |
| |
| <ol style="list-style-type: decimal"> |
| |
| <li>For example, if a row's cells are mutated using the "incrementColumnValue" |
| API, a client must never see the value of any cell decrease.</li> |
| |
| <li>This is true regardless of which read API is used to read back the mutation.</li> |
| </ol> |
| |
| <li> Any version of a cell that has been returned to a read operation is guaranteed to |
| be durably stored.</li> |
| </ol> |
| |
| </div> |
| |
| <div class="section"> |
| <h2><a name="Durability"></a>Durability</h2> |
| |
| <ol style="list-style-type: decimal"> |
| |
| <li> All visible data is also durable data. That is to say, a read will never return |
| data that has not been made durable on disk[2]</li> |
| |
| <li> Any operation that returns a "success" code (eg does not throw an exception) |
| will be made durable.[3]</li> |
| |
| <li> Any operation that returns a "failure" code will not be made durable |
| (subject to the Atomicity guarantees above)</li> |
| |
| <li> All reasonable failure scenarios will not affect any of the guarantees of this document.</li> |
| |
| </ol> |
| </div> |
| |
| <div class="section"> |
| <h2><a name="Tunability"></a>Tunability</h2> |
| |
| <p>All of the above guarantees must be possible within Apache HBase. For users who would like to trade |
| off some guarantees for performance, HBase may offer several tuning options. For example:</p> |
| |
| <ul> |
| |
| <li>Visibility may be tuned on a per-read basis to allow stale reads or time travel.</li> |
| |
| <li>Durability may be tuned to only flush data to disk on a periodic basis</li> |
| </ul> |
| </div> |
| </div> |
| |
| <div class="section"> |
| <h2><a name="More_Information"></a>More Information</h2> |
| |
| <p> |
| For more information, see the <a href="book.html#client">client architecture</a> or <a href="book.html#datamodel">data model</a> sections in the Apache HBase Reference Guide. |
| </p> |
| </div> |
| |
| |
| <div class="section"> |
| <h2><a name="Footnotes"></a>Footnotes</h2> |
| |
| <p>[1] A consistent view is not guaranteed intra-row scanning -- i.e. fetching a portion of |
| a row in one RPC then going back to fetch another portion of the row in a subsequent RPC. |
| Intra-row scanning happens when you set a limit on how many values to return per Scan#next |
| (See <a class="externalLink" href="http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/Scan.html#setBatch(int)">Scan#setBatch(int)</a>). |
| </p> |
| |
| |
| <p>[2] In the context of Apache HBase, "durably on disk" implies an hflush() call on the transaction |
| log. This does not actually imply an fsync() to magnetic media, but rather just that the data has been |
| written to the OS cache on all replicas of the log. In the case of a full datacenter power loss, it is |
| possible that the edits are not truly durable.</p> |
| |
| <p>[3] Puts will either wholly succeed or wholly fail, provided that they are actually sent |
| to the RegionServer. If the writebuffer is used, Puts will not be sent until the writebuffer is filled |
| or it is explicitly flushed.</p> |
| |
| </div> |
| |
| |
| |
| </div> |
| </div> |
| <hr/> |
| <footer> |
| <div class="container"> |
| <div class="row"> |
| <p>Copyright ©2007–2020 |
| <a href="https://www.apache.org/">The Apache Software Foundation</a>. |
| All rights reserved. <li id="publishDate" class="pull-right">Last Published: 2020-02-11</li> |
| </p> |
| </div> |
| <p id="poweredBy" class="pull-right"><a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"><img class="builtBy" alt="Built by Maven" src="./images/logos/maven-feather.png" /></a> |
| </p> |
| </div> |
| </footer> |
| </body> |
| </html> |