You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2014/08/05 00:18:13 UTC

[11/20] couch commit: updated refs/heads/windsor-merge-102 to 944c542

Add uuid and epochs to couchdb database header

All .couch files now have a uuid value that is preserved during
compaction. This value can be used to distinguish one .couch file from
another. In addition, a list of {node(), non_neg_integer()} tuples is
recorded showing the highest update sequence used since the last time
that the value of node() changed. This allows us to know if the
database file has moved and received writes since the last time we saw it.

BugzID: 19133

Conflicts:
	include/couch_db.hrl
	src/couch_db.erl
	src/couch_db_updater.erl


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/b7b20c90
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/b7b20c90
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/b7b20c90

Branch: refs/heads/windsor-merge-102
Commit: b7b20c906e6041816ad1caf66e747c5be4882d0c
Parents: a2addb5
Author: Robert Newson <ro...@cloudant.com>
Authored: Mon Apr 29 22:39:52 2013 +0100
Committer: Robert Newson <rn...@apache.org>
Committed: Mon Aug 4 15:32:10 2014 +0100

----------------------------------------------------------------------
 include/couch_db.hrl     |  8 ++++--
 src/couch_db.erl         |  6 +++--
 src/couch_db_updater.erl | 57 ++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 64 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/b7b20c90/include/couch_db.hrl
----------------------------------------------------------------------
diff --git a/include/couch_db.hrl b/include/couch_db.hrl
index 90cc263..5c549ec 100644
--- a/include/couch_db.hrl
+++ b/include/couch_db.hrl
@@ -151,7 +151,9 @@
      purge_seq = 0,
      purged_docs = nil,
      security_ptr = nil,
-     revs_limit = 1000
+     revs_limit = 1000,
+     uuid = nil,
+     epochs = nil
     }).
 
 -record(db,
@@ -178,7 +180,9 @@
     options = [],
     compression,
     before_doc_update = nil, % nil | fun(Doc, Db) -> NewDoc
-    after_doc_read = nil     % nil | fun(Doc, Db) -> NewDoc
+    after_doc_read = nil,    % nil | fun(Doc, Db) -> NewDoc
+    uuid = nil,
+    epochs = nil
     }).
 
 -record(view_fold_helper_funs, {

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/b7b20c90/src/couch_db.erl
----------------------------------------------------------------------
diff --git a/src/couch_db.erl b/src/couch_db.erl
index 9d480a9..aaab19b 100644
--- a/src/couch_db.erl
+++ b/src/couch_db.erl
@@ -304,7 +304,8 @@ get_db_info(Db) ->
         committed_update_seq=CommittedUpdateSeq,
         id_tree = IdBtree,
         seq_tree = SeqBtree,
-        local_tree = LocalBtree
+        local_tree = LocalBtree,
+        uuid = Uuid
     } = Db,
     {ok, Size} = couch_file:bytes(Fd),
     {ok, DbReduction} = couch_btree:full_reduce(IdBtree),
@@ -319,7 +320,8 @@ get_db_info(Db) ->
         {data_size, db_data_size(DbReduction, [SeqBtree, IdBtree, LocalBtree])},
         {instance_start_time, StartTime},
         {disk_format_version, DiskVersion},
-        {committed_update_seq, CommittedUpdateSeq}
+        {committed_update_seq, CommittedUpdateSeq},
+        {uuid, Uuid}
         ],
     {ok, InfoList}.
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/b7b20c90/src/couch_db_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_db_updater.erl b/src/couch_db_updater.erl
index 4e72dac..f6276c5 100644
--- a/src/couch_db_updater.erl
+++ b/src/couch_db_updater.erl
@@ -227,7 +227,9 @@ handle_cast({compact_done, CompactFilepath}, #db{filepath=Filepath}=Db) ->
             main_pid = self(),
             filepath = Filepath,
             instance_start_time = Db#db.instance_start_time,
-            revs_limit = Db#db.revs_limit
+            revs_limit = Db#db.revs_limit,
+            uuid = Db#db.uuid,
+            epochs = Db#db.epochs
         }),
 
         ?LOG_DEBUG("CouchDB swapping files ~s and ~s.",
@@ -522,7 +524,9 @@ init_db(DbName, Filepath, Fd, Header0, Options) ->
         options = Options,
         compression = Compression,
         before_doc_update = couch_util:get_value(before_doc_update, Options, nil),
-        after_doc_read = couch_util:get_value(after_doc_read, Options, nil)
+        after_doc_read = couch_util:get_value(after_doc_read, Options, nil),
+        uuid = initialize_uuid(Header),
+        epochs = initialize_epochs(Header)
         }.
 
 
@@ -804,7 +808,9 @@ db_to_header(Db, Header) ->
         id_tree_state = couch_btree:get_state(Db#db.id_tree),
         local_tree_state = couch_btree:get_state(Db#db.local_tree),
         security_ptr = Db#db.security_ptr,
-        revs_limit = Db#db.revs_limit}.
+        revs_limit = Db#db.revs_limit,
+        uuid = Db#db.uuid,
+        epochs = update_epochs(Db)}.
 
 commit_data(Db) ->
     commit_data(Db, false).
@@ -1273,3 +1279,48 @@ make_doc_summary(#db{compression = Comp}, {Body0, Atts0}) ->
     end,
     SummaryBin = ?term_to_bin({Body, Atts}),
     couch_file:assemble_file_chunk(SummaryBin, couch_util:md5(SummaryBin)).
+
+initialize_uuid(#db_header{uuid=nil}) ->
+    couch_uuids:random();
+initialize_uuid(#db_header{uuid=Uuid}) ->
+    Uuid.
+
+initialize_epochs(#db_header{epochs=nil}=Db) ->
+    [{node(), Db#db_header.update_seq}];
+initialize_epochs(#db_header{epochs=Epochs}) ->
+    Epochs.
+
+update_epochs(Db) ->
+    case Db#db.epochs of
+        [{Node, _} | _] when Node =:= node() ->
+            Db#db.epochs;
+        Epochs when is_list(Epochs) ->
+            %% Mark the sequence where this node took over.
+            [{node(), Db#db.update_seq} | Epochs]
+    end.
+
+-ifdef(TEST).
+-include_lib("eunit/include/eunit.hrl").
+
+initialize_uuid_is_stable_test() ->
+    %% UUID was initialized.
+    ?assertMatch(<<_:32/binary>>, initialize_uuid(#db_header{})),
+    %% UUID was preserved.
+    ?assertEqual(foo, initialize_uuid(#db_header{uuid=foo})).
+
+initialize_epochs_is_stable_test() ->
+    %% Epochs were initialized.
+    ?assertMatch([{'nonode@nohost', 0}], initialize_epochs(#db_header{})),
+    %% Epochs are preserved.
+    ?assertMatch(foo, initialize_epochs(#db_header{epochs=foo})).
+
+update_epochs_test() ->
+    %% Epochs are not extended if node stays the same.
+    ?assertMatch([{'nonode@nohost', 0}],
+                 update_epochs(#db{epochs=[{'nonode@nohost', 0}]})),
+
+    %% Epochs are extended if node changes.
+    ?assertMatch([{'nonode@nohost', 1}, {foo, 0}],
+                 update_epochs(#db{update_seq=1, epochs=[{foo, 0}]})).
+
+-endif.