diff options
author | Garren Smith <garren.smith@gmail.com> | 2018-10-23 16:35:29 +0200 |
---|---|---|
committer | garren smith <garren.smith@gmail.com> | 2018-11-21 08:31:17 +0200 |
commit | 854f3d9fcbd8db91ab208e27038c252d91841fcf (patch) | |
tree | f097a000b416add9b116758d45fb5a59c1eaa03b | |
parent | 1008d9710145d7f5742cd0a02dfc7272ed473849 (diff) | |
download | couchdb-854f3d9fcbd8db91ab208e27038c252d91841fcf.tar.gz |
This adds in downgrade code for Database partitions work. We add an
extra field in the header.
-rw-r--r-- | src/couch/src/couch_bt_engine_header.erl | 53 | ||||
-rw-r--r-- | src/couch/test/couch_bt_engine_partition_downgrade_tests.erl | 86 | ||||
-rw-r--r-- | src/couch/test/fixtures/db_non_partitioned.couch | bin | 0 -> 12479 bytes |
3 files changed, 139 insertions, 0 deletions
diff --git a/src/couch/src/couch_bt_engine_header.erl b/src/couch/src/couch_bt_engine_header.erl index 9c8e7adb3..619264a0d 100644 --- a/src/couch/src/couch_bt_engine_header.erl +++ b/src/couch/src/couch_bt_engine_header.erl @@ -26,6 +26,7 @@ -export([ disk_version/1, + latest_disk_version/0, update_seq/1, id_tree_state/1, seq_tree_state/1, @@ -72,6 +73,9 @@ }). +-define(PARTITION_DISK_VERSION, 8). + + new() -> #db_header{ uuid = couch_uuids:random(), @@ -99,6 +103,7 @@ is_header(Header) -> upgrade(Header) -> Funs = [ + fun downgrade_partition_header/1, fun upgrade_tuple/1, fun upgrade_disk_version/1, fun upgrade_uuid/1, @@ -136,6 +141,10 @@ disk_version(Header) -> get_field(Header, disk_version). +latest_disk_version() -> + ?LATEST_DISK_VERSION. + + update_seq(Header) -> get_field(Header, update_seq). @@ -210,6 +219,50 @@ indexes() -> lists:zip(Fields, Indexes). +downgrade_partition_header(Header) -> + DiskVersion = disk_version(Header), + Latest = latest_disk_version(), + case DiskVersion of + N when N =< Latest -> + Header; + ?PARTITION_DISK_VERSION -> + { + db_header, + _DiskVer, + UpSeq, + _Unused, + IdTreeState, + SeqTreeState, + LocalTreeState, + PurgeTreeState, + PurgeSeqTreeState, + SecurityPtr, + RevsLimit, + Uuid, + Epochs, + CompactedSeq, + PurgeInfosLimit, + _PropsPtr + } = Header, + + NewHeader = new(), + set(NewHeader, [ + {update_seq, UpSeq}, + {id_tree_state, IdTreeState}, + {seq_tree_state, SeqTreeState}, + {local_tree_state, LocalTreeState}, + {purge_tree_state, PurgeTreeState}, + {purge_seq_tree_state, PurgeSeqTreeState}, + {security_ptr, SecurityPtr}, + {revs_limit, RevsLimit}, + {uuid, Uuid}, + {epochs, Epochs}, + {compacted_seq, CompactedSeq}, + {purge_infos_limit, PurgeInfosLimit} + ]) + end. + + upgrade_tuple(Old) when is_record(Old, db_header) -> Old; upgrade_tuple(Old) when is_tuple(Old) -> diff --git a/src/couch/test/couch_bt_engine_partition_downgrade_tests.erl b/src/couch/test/couch_bt_engine_partition_downgrade_tests.erl new file mode 100644 index 000000000..f0839a411 --- /dev/null +++ b/src/couch/test/couch_bt_engine_partition_downgrade_tests.erl @@ -0,0 +1,86 @@ +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +-module(couch_bt_engine_partition_downgrade_tests). + +-include_lib("couch/include/couch_eunit.hrl"). +-include_lib("couch/include/couch_db.hrl"). + + +setup() -> + Ctx = test_util:start_couch(), + DbDir = config:get("couchdb", "database_dir"), + DbFileNames = [ + "db_non_partitioned.couch" + ], + NewPaths = lists:map(fun(DbFileName) -> + OldDbFilePath = filename:join([?FIXTURESDIR, DbFileName]), + NewDbFilePath = filename:join([DbDir, DbFileName]), + ok = filelib:ensure_dir(NewDbFilePath), + file:delete(NewDbFilePath), + {ok, _} = file:copy(OldDbFilePath, NewDbFilePath), + NewDbFilePath + end, DbFileNames), + {Ctx, NewPaths}. + + +teardown({Ctx, Paths}) -> + test_util:stop_couch(Ctx), + lists:foreach(fun(Path) -> + file:delete(Path) + end, Paths). + + +downgrade_test_() -> + { + "Couch Bt Engine partition downgrade tests", + { + setup, + fun setup/0, + fun teardown/1, + [ + t_downgrade_non_partitioned_db() + ] + } + }. + + +t_downgrade_non_partitioned_db() -> + ?_test(begin + % There are 13 documents in the fixture with 1 conflicted + DbName = <<"db_non_partitioned">>, + ?assertEqual(8, get_disk_version_from_header(DbName)), + + {ok, _} = save_doc(DbName, {[{<<"_id">>, <<"doc4">>}, {<<"v">>, 1}]}), + {ok, _} = save_doc(DbName, {[{<<"_id">>, <<"doc5">>}, {<<"v">>, 2}]}), + + couch_util:with_db(DbName, fun(Db) -> + ?assertEqual(7, couch_db_engine:get_disk_version(Db)) + end) + end). + + +get_disk_version_from_header(DbFileName) -> + DbDir = config:get("couchdb", "database_dir"), + DbFilePath = filename:join([DbDir, ?l2b(?b2l(DbFileName) ++ ".couch")]), + {ok, Fd} = couch_file:open(DbFilePath, []), + {ok, Header} = couch_file:read_header(Fd), + DiskVerison = couch_bt_engine_header:disk_version(Header), + couch_file:close(Fd), + DiskVerison. + + +save_doc(DbName, Json) -> + Doc = couch_doc:from_json_obj(Json), + couch_util:with_db(DbName, fun(Db) -> + couch_db:update_doc(Db, Doc, []) + end). diff --git a/src/couch/test/fixtures/db_non_partitioned.couch b/src/couch/test/fixtures/db_non_partitioned.couch Binary files differnew file mode 100644 index 000000000..327d9bb5d --- /dev/null +++ b/src/couch/test/fixtures/db_non_partitioned.couch |