Compare commits
8 Commits
r5.3.0-alp
...
server-623
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76d67ea903 | ||
|
|
b3a66de850 | ||
|
|
2ea564e147 | ||
|
|
107fe227b5 | ||
|
|
285766aa03 | ||
|
|
c2f14164ba | ||
|
|
ae47c18fa3 | ||
|
|
38d13a91b4 |
@@ -8851,6 +8851,60 @@ buildvariants:
|
||||
distros:
|
||||
- rhel70-small
|
||||
|
||||
- name: enterprise-windows-msvs2022-experimental
|
||||
display_name: "~ Enterprise Windows MSVS 2022"
|
||||
cron: "0 12 * * *" # Every day starting at 12:00
|
||||
modules:
|
||||
- enterprise
|
||||
run_on:
|
||||
- windows-vsCurrent-2022-small
|
||||
expansions:
|
||||
exe: ".exe"
|
||||
additional_package_targets: archive-mongocryptd archive-mongocryptd-debug msi archive-mh archive-mh-debug
|
||||
content_type: application/zip
|
||||
compile_flags: --ssl MONGO_DISTMOD=windows CPPPATH="c:/sasl/include c:/snmp/include" LIBPATH="c:/sasl/lib c:/snmp/lib" -j$(bc <<< "$(grep -c '^processor' /proc/cpuinfo) / 1.5") --win-version-min=win10 MSVC_VERSION=14.3
|
||||
num_scons_link_jobs_available: 0.25
|
||||
python: '/cygdrive/c/python/python37/python.exe'
|
||||
ext: zip
|
||||
scons_cache_scope: shared
|
||||
jstestfuzz_num_generated_files: 35
|
||||
target_resmoke_time: 20
|
||||
max_sub_suites: 3
|
||||
large_distro_name: windows-vsCurrent-2022-large
|
||||
test_flags: *windows_common_test_excludes
|
||||
exec_timeout_secs: 14400 # 3 hour timeout
|
||||
tasks:
|
||||
- name: compile_test_and_package_serial_TG
|
||||
distros:
|
||||
- windows-vsCurrent-2022-large
|
||||
- name: build_variant_gen
|
||||
# - name: .aggfuzzer # Disabled for FCV 5.3
|
||||
- name: .aggregation !.auth !.encrypt !.unwind
|
||||
- name: auth_gen
|
||||
- name: causally_consistent_jscore_txns_passthrough
|
||||
- name: .misc_js
|
||||
# Some concurrency workloads require a lot of memory, so we use machines
|
||||
# with more RAM for these suites.
|
||||
- name: .concurrency !.ubsan !.no_txns !.kill_terminate !.common !.debug_only
|
||||
distros:
|
||||
- windows-vsCurrent-2022-large
|
||||
- name: .concurrency .common
|
||||
- name: disk_wiredtiger
|
||||
- name: .jscore .common !.auth
|
||||
- name: json_schema
|
||||
- name: .jstestfuzz !.initsync !.flow_control !.stepdowns
|
||||
- name: powercycle_gen
|
||||
- name: .query_fuzzer
|
||||
- name: .read_write_concern
|
||||
- name: replica_sets_gen
|
||||
- name: replica_sets_jscore_passthrough
|
||||
- name: .sharding .jscore !.wo_snapshot !.multi_stmt !.multiversion
|
||||
- name: .sharding .txns !.multiversion
|
||||
- name: .sharding .common !.csrs !.multiversion
|
||||
- name: .ssl
|
||||
- name: .stitch
|
||||
- name: .updatefuzzer !.multiversion
|
||||
|
||||
- name: enterprise-windows-debug-unoptimized
|
||||
display_name: Enterprise Windows DEBUG (Unoptimized)
|
||||
cron: "0 12 * * *" # Every day starting at 12:00
|
||||
|
||||
@@ -213,8 +213,7 @@ assert.commandWorked(run({
|
||||
}));
|
||||
|
||||
// Not every accumulator is automatically a window function.
|
||||
|
||||
var err = assert.commandFailedWithCode(run({$setWindowFields: {output: {a: {b: {$sum: "$a"}}}}}),
|
||||
let err = assert.commandFailedWithCode(run({$setWindowFields: {output: {a: {b: {$sum: "$a"}}}}}),
|
||||
ErrorCodes.FailedToParse);
|
||||
assert.includes(err.errmsg, 'Expected a $-prefixed window function, b');
|
||||
|
||||
@@ -250,4 +249,14 @@ err = assert.commandFailedWithCode(
|
||||
}),
|
||||
ErrorCodes.FailedToParse);
|
||||
assert.includes(err.errmsg, 'Unrecognized window function, $summ');
|
||||
|
||||
// Test that an empty object is a valid projected field.
|
||||
assert.commandWorked(coll.insert({}));
|
||||
assert.commandWorked(run({$setWindowFields: {output: {v: {$max: {mergeObjects: {}}}}}}));
|
||||
|
||||
// However conflicting field paths is always an error.
|
||||
err = assert.commandFailedWithCode(
|
||||
run({$setWindowFields: {output: {a: {$sum: 1}, 'a.b': {$sum: 1}}}}), 40176);
|
||||
assert.includes(err.errmsg, 'specification contains two conflicting paths');
|
||||
|
||||
})();
|
||||
|
||||
@@ -461,10 +461,12 @@ DocumentSource::GetNextResult DocumentSourceInternalSetWindowFields::doGetNext()
|
||||
MutableDocument addFieldsSpec;
|
||||
for (auto&& [fieldName, function] : _executableOutputs) {
|
||||
try {
|
||||
// Wrap the projected value in a $literal since there are limitations on a user-facing
|
||||
// $addFields that we don't want to enforce here (e.g. empty object).
|
||||
addFieldsSpec.addField(fieldName, Value(DOC("$literal" << function->getNext())));
|
||||
} catch (const DBException&) {
|
||||
// If we hit a uassert while evaluating expressions on user data, delete the temporary
|
||||
// table before aborting the operation.
|
||||
addFieldsSpec.addField(fieldName, function->getNext());
|
||||
} catch (const DBException&) {
|
||||
_iterator.finalize();
|
||||
throw;
|
||||
}
|
||||
@@ -506,6 +508,7 @@ DocumentSource::GetNextResult DocumentSourceInternalSetWindowFields::doGetNext()
|
||||
_iterator.finalize();
|
||||
break;
|
||||
}
|
||||
|
||||
auto projExec = projection_executor::AddFieldsProjectionExecutor::create(
|
||||
pExpCtx, addFieldsSpec.freeze().toBson());
|
||||
|
||||
|
||||
3
src/third_party/wiredtiger/dist/api_data.py
vendored
3
src/third_party/wiredtiger/dist/api_data.py
vendored
@@ -1287,7 +1287,8 @@ wiredtiger_open_common =\
|
||||
choices=['dsync', 'fsync', 'none']),
|
||||
]),
|
||||
Config('verify_metadata', 'false', r'''
|
||||
open connection and verify any WiredTiger metadata. This API
|
||||
open connection and verify any WiredTiger metadata. Not compatible when
|
||||
opening a connection from a backup. This API
|
||||
allows verification and detection of corruption in WiredTiger metadata.''',
|
||||
type='boolean'),
|
||||
Config('write_through', '', r'''
|
||||
|
||||
8
src/third_party/wiredtiger/dist/s_version
vendored
8
src/third_party/wiredtiger/dist/s_version
vendored
@@ -55,6 +55,10 @@ GenAutoconfVersion(){
|
||||
VERSION_NOPATCH=${WIREDTIGER_VERSION_MAJOR}.${WIREDTIGER_VERSION_MINOR}
|
||||
AC_SUBST(VERSION_NOPATCH)
|
||||
END
|
||||
|
||||
echo "Building $rpmspec"
|
||||
sed -e "s/Version: .*/Version: ${dotted_version}/" $rpmspec \
|
||||
> $tmp_file && mv $tmp_file $rpmspec
|
||||
}
|
||||
|
||||
GenCmakeVersion(){
|
||||
@@ -79,7 +83,3 @@ GenCmakeVersion(){
|
||||
|
||||
GenAutoconfVersion
|
||||
GenCmakeVersion
|
||||
|
||||
echo "Building $rpmspec"
|
||||
sed -e "s/Version: .*/Version: ${dotted_version}/" $rpmspec \
|
||||
> $tmp_file && mv $tmp_file $rpmspec
|
||||
|
||||
2
src/third_party/wiredtiger/import.data
vendored
2
src/third_party/wiredtiger/import.data
vendored
@@ -2,5 +2,5 @@
|
||||
"vendor": "wiredtiger",
|
||||
"github": "wiredtiger/wiredtiger.git",
|
||||
"branch": "mongodb-master",
|
||||
"commit": "c5db3e1d6752826db91c41026bd4eed3c04e32a0"
|
||||
"commit": "aab21d5814193dc1943d9f5e62fd40ad6973475a"
|
||||
}
|
||||
|
||||
@@ -2949,9 +2949,9 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler, const char *c
|
||||
* THE TURTLE FILE MUST BE THE LAST FILE CREATED WHEN INITIALIZING THE DATABASE HOME, IT'S WHAT
|
||||
* WE USE TO DECIDE IF WE'RE CREATING OR NOT.
|
||||
*/
|
||||
WT_ERR(__wt_turtle_init(session));
|
||||
WT_ERR(__wt_config_gets(session, cfg, "verify_metadata", &cval));
|
||||
verify_meta = cval.val;
|
||||
WT_ERR(__wt_turtle_init(session, verify_meta));
|
||||
|
||||
/* Verify the metadata file. */
|
||||
if (verify_meta) {
|
||||
|
||||
@@ -1537,7 +1537,7 @@ extern int __wt_try_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *l)
|
||||
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
|
||||
extern int __wt_turtle_exists(WT_SESSION_IMPL *session, bool *existp)
|
||||
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
|
||||
extern int __wt_turtle_init(WT_SESSION_IMPL *session)
|
||||
extern int __wt_turtle_init(WT_SESSION_IMPL *session, bool verify_meta)
|
||||
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
|
||||
extern int __wt_turtle_read(WT_SESSION_IMPL *session, const char *key, char **valuep)
|
||||
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
@@ -3138,9 +3138,9 @@ struct __wt_connection {
|
||||
* "read"\, \c "reconcile"\, \c "recovery"\, \c "recovery_progress"\, \c "rts"\, \c "salvage"\, \c
|
||||
* "shared_cache"\, \c "split"\, \c "temporary"\, \c "thread_group"\, \c "tiered"\, \c "timestamp"\,
|
||||
* \c "transaction"\, \c "verify"\, \c "version"\, \c "write"; default \c [].}
|
||||
* @config{verify_metadata, open connection and verify any WiredTiger metadata. This API allows
|
||||
* verification and detection of corruption in WiredTiger metadata., a boolean flag; default \c
|
||||
* false.}
|
||||
* @config{verify_metadata, open connection and verify any WiredTiger metadata. Not compatible when
|
||||
* opening a connection from a backup. This API allows verification and detection of corruption in
|
||||
* WiredTiger metadata., a boolean flag; default \c false.}
|
||||
* @config{write_through, Use \c FILE_FLAG_WRITE_THROUGH on Windows to write to files. Ignored on
|
||||
* non-Windows systems. Options are given as a list\, such as <code>"write_through=[data]"</code>.
|
||||
* Configuring \c write_through requires care\, see @ref tuning_system_buffer_cache_direct_io for
|
||||
|
||||
@@ -223,7 +223,7 @@ __wt_turtle_exists(WT_SESSION_IMPL *session, bool *existp)
|
||||
* Check the turtle file and create if necessary.
|
||||
*/
|
||||
int
|
||||
__wt_turtle_init(WT_SESSION_IMPL *session)
|
||||
__wt_turtle_init(WT_SESSION_IMPL *session, bool verify_meta)
|
||||
{
|
||||
WT_DECL_RET;
|
||||
char *metaconf, *unused_value;
|
||||
@@ -307,6 +307,15 @@ __wt_turtle_init(WT_SESSION_IMPL *session)
|
||||
if (exist_incr)
|
||||
F_SET(S2C(session), WT_CONN_WAS_BACKUP);
|
||||
|
||||
/*
|
||||
* Verifying the metadata is incompatible with restarting from a backup because the verify
|
||||
* call will rewrite the metadata's checkpoint and could lead to skipping recovery. Test
|
||||
* here before creating the metadata file and reading in the backup file.
|
||||
*/
|
||||
if (verify_meta && exist_backup)
|
||||
WT_RET_MSG(
|
||||
session, EINVAL, "restoring a backup is incompatible with metadata verification");
|
||||
|
||||
/* Create the metadata file. */
|
||||
WT_RET(__metadata_init(session));
|
||||
|
||||
|
||||
@@ -398,8 +398,6 @@ int
|
||||
__wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, WT_ROW *rip,
|
||||
WT_CELL_UNPACK_KV *vpack, WT_UPDATE_SELECT *upd_select)
|
||||
{
|
||||
WT_DECL_ITEM(tmp);
|
||||
WT_DECL_RET;
|
||||
WT_PAGE *page;
|
||||
WT_TIME_WINDOW *select_tw;
|
||||
WT_UPDATE *first_txn_upd, *first_upd, *onpage_upd, *upd, *last_upd, *tombstone;
|
||||
@@ -651,7 +649,7 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W
|
||||
* freed when it is written to the disk image in the previous eviction.
|
||||
*/
|
||||
if (!F_ISSET(tombstone, WT_UPDATE_RESTORED_FROM_DS | WT_UPDATE_RESTORED_FROM_HS)) {
|
||||
WT_ERR(__rec_append_orig_value(session, page, tombstone, vpack));
|
||||
WT_RET(__rec_append_orig_value(session, page, tombstone, vpack));
|
||||
|
||||
/*
|
||||
* We may have updated the global transaction concurrently and the tombstone is now
|
||||
@@ -710,7 +708,7 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W
|
||||
upd_select->upd;
|
||||
|
||||
/* Check the update chain for conditions that could prevent it's eviction. */
|
||||
WT_ERR(__rec_validate_upd_chain(session, r, onpage_upd, select_tw, vpack));
|
||||
WT_RET(__rec_validate_upd_chain(session, r, onpage_upd, select_tw, vpack));
|
||||
|
||||
/*
|
||||
* Fixup any out of order timestamps, assert that checkpoint wasn't running when this round of
|
||||
@@ -724,7 +722,7 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W
|
||||
/* Catch this case in diagnostic builds. */
|
||||
WT_STAT_CONN_DATA_INCR(session, cache_eviction_blocked_ooo_checkpoint_race_3);
|
||||
WT_ASSERT(session, false);
|
||||
WT_ERR(EBUSY);
|
||||
WT_RET(EBUSY);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -742,7 +740,7 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W
|
||||
supd_restore = F_ISSET(r, WT_REC_EVICT) &&
|
||||
(has_newer_updates || F_ISSET(S2C(session), WT_CONN_IN_MEMORY));
|
||||
|
||||
WT_ERR(__rec_update_save(session, r, ins, rip, onpage_upd, supd_restore, upd_memsize));
|
||||
WT_RET(__rec_update_save(session, r, ins, rip, onpage_upd, supd_restore, upd_memsize));
|
||||
|
||||
/*
|
||||
* Mark the selected update (and potentially the tombstone preceding it) as being destined
|
||||
@@ -788,10 +786,9 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W
|
||||
*/
|
||||
if (upd_select->upd != NULL && vpack != NULL && vpack->type != WT_CELL_DEL &&
|
||||
!vpack->tw.prepare && (upd_saved || F_ISSET(vpack, WT_CELL_UNPACK_OVERFLOW)))
|
||||
WT_ERR(__rec_append_orig_value(session, page, upd_select->upd, vpack));
|
||||
WT_RET(__rec_append_orig_value(session, page, upd_select->upd, vpack));
|
||||
|
||||
__wt_rec_time_window_clear_obsolete(session, upd_select, NULL, r);
|
||||
err:
|
||||
__wt_scr_free(session, &tmp);
|
||||
return (ret);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -1438,9 +1438,15 @@ __rollback_to_stable_hs_final_pass(WT_SESSION_IMPL *session, wt_timestamp_t roll
|
||||
|
||||
/*
|
||||
* The rollback operation should be performed on the history store file when the checkpoint
|
||||
* durable start/stop timestamp is greater than the rollback timestamp.
|
||||
* durable start/stop timestamp is greater than the rollback timestamp. But skip if there is no
|
||||
* stable timestamp.
|
||||
*
|
||||
* Note that the corresponding code in __rollback_to_stable_btree_apply also checks whether
|
||||
* there _are_ timestamped updates by checking max_durable_ts; that check is redundant here for
|
||||
* several reasons, the most immediate being that max_durable_ts cannot be none (zero) because
|
||||
* it's greater than rollback_timestamp, which is itself greater than zero.
|
||||
*/
|
||||
if (max_durable_ts > rollback_timestamp) {
|
||||
if (max_durable_ts > rollback_timestamp && rollback_timestamp != WT_TS_NONE) {
|
||||
__wt_verbose_multi(session, WT_VERB_RECOVERY_RTS(session),
|
||||
"tree rolled back with durable timestamp: %s",
|
||||
__wt_timestamp_to_string(max_durable_ts, ts_string[0]));
|
||||
@@ -1494,7 +1500,6 @@ __rollback_to_stable_btree_apply(
|
||||
WT_CONFIG ckptconf;
|
||||
WT_CONFIG_ITEM cval, value, key;
|
||||
WT_DECL_RET;
|
||||
WT_TXN_GLOBAL *txn_global;
|
||||
wt_timestamp_t max_durable_ts, newest_start_durable_ts, newest_stop_durable_ts;
|
||||
size_t addr_size;
|
||||
uint64_t rollback_txnid, write_gen;
|
||||
@@ -1507,7 +1512,6 @@ __rollback_to_stable_btree_apply(
|
||||
if (!WT_BTREE_PREFIX(uri) || strcmp(uri, WT_HS_URI) == 0 || strcmp(uri, WT_METAFILE_URI) == 0)
|
||||
return (0);
|
||||
|
||||
txn_global = &S2C(session)->txn_global;
|
||||
addr_size = 0;
|
||||
rollback_txnid = 0;
|
||||
write_gen = 0;
|
||||
@@ -1574,8 +1578,7 @@ __rollback_to_stable_btree_apply(
|
||||
*/
|
||||
if ((F_ISSET(S2C(session), WT_CONN_RECOVERING) ||
|
||||
F_ISSET(S2C(session), WT_CONN_CLOSING_TIMESTAMP)) &&
|
||||
(addr_size == 0 ||
|
||||
(txn_global->stable_timestamp == WT_TS_NONE && max_durable_ts != WT_TS_NONE))) {
|
||||
(addr_size == 0 || (rollback_timestamp == WT_TS_NONE && max_durable_ts != WT_TS_NONE))) {
|
||||
__wt_verbose_multi(session, WT_VERB_RECOVERY_RTS(session),
|
||||
"skip rollback to stable on file %s because %s", uri,
|
||||
addr_size == 0 ? "its checkpoint address length is 0" :
|
||||
|
||||
@@ -243,7 +243,7 @@ thread_flush_run(void *arg)
|
||||
*/
|
||||
(void)unlink(sentinel_file);
|
||||
testutil_check(td->conn->open_session(td->conn, NULL, NULL, &session));
|
||||
for (i = 0;; ++i) {
|
||||
for (i = 0;;) {
|
||||
sleep_time = __wt_random(&rnd) % MAX_FLUSH_INVL;
|
||||
sleep(sleep_time);
|
||||
testutil_check(td->conn->query_timestamp(td->conn, ts_string, "get=last_checkpoint"));
|
||||
@@ -264,7 +264,7 @@ thread_flush_run(void *arg)
|
||||
* Create the sentinel file so that the parent process knows the desired number of
|
||||
* flush_tier calls have finished and can start its timer.
|
||||
*/
|
||||
if (i == flush_calls) {
|
||||
if (++i == flush_calls) {
|
||||
testutil_assert_errno((fp = fopen(sentinel_file, "w")) != NULL);
|
||||
testutil_assert_errno(fclose(fp) == 0);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ post:
|
||||
- func: "cleanup"
|
||||
timeout:
|
||||
- func: "run wt hang analyzer"
|
||||
exec_timeout_secs: 21600 # 6 hrs
|
||||
|
||||
#######################################
|
||||
# Functions #
|
||||
|
||||
@@ -65,7 +65,7 @@ check_copy(void)
|
||||
|
||||
/* Now setup and open the path for real. */
|
||||
testutil_check(__wt_snprintf(path, len, "%s/BACKUP", g.home));
|
||||
wts_open(path, &conn, &session, true);
|
||||
wts_open(path, &conn, &session, false);
|
||||
|
||||
/* Verify the objects. */
|
||||
tables_apply(wts_verify, conn);
|
||||
|
||||
101
src/third_party/wiredtiger/test/suite/test_backup23.py
vendored
Executable file
101
src/third_party/wiredtiger/test/suite/test_backup23.py
vendored
Executable file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Public Domain 2014-present MongoDB, Inc.
|
||||
# Public Domain 2008-2014 WiredTiger, Inc.
|
||||
#
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
#
|
||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
# distribute this software, either in source code form or as a compiled
|
||||
# binary, for any purpose, commercial or non-commercial, and by any
|
||||
# means.
|
||||
#
|
||||
# In jurisdictions that recognize copyright laws, the author or authors
|
||||
# of this software dedicate any and all copyright interest in the
|
||||
# software to the public domain. We make this dedication for the benefit
|
||||
# of the public at large and to the detriment of our heirs and
|
||||
# successors. We intend this dedication to be an overt act of
|
||||
# relinquishment in perpetuity of all present and future rights to this
|
||||
# software under copyright law.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
# OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from helper import copy_wiredtiger_home
|
||||
from suite_subprocess import suite_subprocess
|
||||
import os
|
||||
import shutil
|
||||
import wiredtiger, wttest
|
||||
|
||||
# test_backup.py
|
||||
# Test error message if verifying metadata on a backup restore.
|
||||
class test_backup23(wttest.WiredTigerTestCase, suite_subprocess):
|
||||
'''Test backup, verifying metadata and an error opening the backup'''
|
||||
|
||||
#conn_config = 'config_base=false,log=(archive=false,enabled),verbose=(recovery,log)'
|
||||
conn_config = 'config_base=false,log=(archive=false,enabled)'
|
||||
conn_config_err = 'config_base=false,log=(archive=false,enabled),verify_metadata=true'
|
||||
#conn_config_err = 'config_base=false,log=(archive=false,enabled),verify_metadata=true,verbose=(recovery,log)'
|
||||
dir='backup.dir'
|
||||
nentries = 10
|
||||
uri = 'file:backup.wt'
|
||||
|
||||
def take_full_backup(self, dir):
|
||||
# Open up the backup cursor, and copy the files. Do a full backup.
|
||||
cursor = self.session.open_cursor('backup:', None, None)
|
||||
self.pr('Full backup to ' + dir + ': ')
|
||||
os.mkdir(dir)
|
||||
while True:
|
||||
ret = cursor.next()
|
||||
if ret != 0:
|
||||
break
|
||||
bkup_file = cursor.get_key()
|
||||
sz = os.path.getsize(bkup_file)
|
||||
self.pr('Copy from: ' + bkup_file + ' (' + str(sz) + ') to ' + dir)
|
||||
shutil.copy(bkup_file, dir)
|
||||
self.assertEqual(ret, wiredtiger.WT_NOTFOUND)
|
||||
cursor.close()
|
||||
|
||||
def test_backup23(self):
|
||||
'''Test backup, verifying metadata and an error opening the backup'''
|
||||
self.session.create(self.uri, 'key_format=i,value_format=i')
|
||||
c = self.session.open_cursor(self.uri)
|
||||
|
||||
self.session.begin_transaction()
|
||||
for i in range(self.nentries):
|
||||
c[i] = i
|
||||
self.session.commit_transaction()
|
||||
self.session.checkpoint()
|
||||
|
||||
# Add more entries after the check point. They should be recovered.
|
||||
self.session.begin_transaction()
|
||||
for i in range(self.nentries):
|
||||
c[i + self.nentries] = i
|
||||
self.session.commit_transaction()
|
||||
c.close()
|
||||
orig_data = list(self.session.open_cursor(self.uri))
|
||||
|
||||
# Take a full backup.
|
||||
self.take_full_backup(self.dir)
|
||||
self.close_conn()
|
||||
|
||||
msg = '/restoring a backup is incompatible/'
|
||||
self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
|
||||
lambda: self.wiredtiger_open(self.dir, self.conn_config_err), msg)
|
||||
|
||||
self.pr('try opening error directory with correct config')
|
||||
# After getting the error we should be able to open the error backup directory with the
|
||||
# correct setting and then also see our data.
|
||||
self.conn = self.wiredtiger_open(self.dir, self.conn_config)
|
||||
session = self.conn.open_session()
|
||||
bkup_data = list(session.open_cursor(self.uri))
|
||||
|
||||
self.assertEqual(orig_data, bkup_data)
|
||||
|
||||
if __name__ == '__main__':
|
||||
wttest.run()
|
||||
118
src/third_party/wiredtiger/test/suite/test_rollback_to_stable31.py
vendored
Normal file
118
src/third_party/wiredtiger/test/suite/test_rollback_to_stable31.py
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Public Domain 2014-present MongoDB, Inc.
|
||||
# Public Domain 2008-2014 WiredTiger, Inc.
|
||||
#
|
||||
# This is free and unencumbered software released into the public domain.
|
||||
#
|
||||
# Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
# distribute this software, either in source code form or as a compiled
|
||||
# binary, for any purpose, commercial or non-commercial, and by any
|
||||
# means.
|
||||
#
|
||||
# In jurisdictions that recognize copyright laws, the author or authors
|
||||
# of this software dedicate any and all copyright interest in the
|
||||
# software to the public domain. We make this dedication for the benefit
|
||||
# of the public at large and to the detriment of our heirs and
|
||||
# successors. We intend this dedication to be an overt act of
|
||||
# relinquishment in perpetuity of all present and future rights to this
|
||||
# software under copyright law.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
# OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from test_rollback_to_stable01 import test_rollback_to_stable_base
|
||||
from helper import simulate_crash_restart
|
||||
from wtdataset import SimpleDataSet
|
||||
from wtscenario import make_scenarios
|
||||
|
||||
# test_rollback_to_stable31.py
|
||||
# Check what happens with RTS if you never set the stable timestamp.
|
||||
|
||||
class test_rollback_to_stable31(test_rollback_to_stable_base):
|
||||
session_config = 'isolation=snapshot'
|
||||
|
||||
format_values = [
|
||||
('column', dict(key_format='r', value_format='S')),
|
||||
('column_fix', dict(key_format='r', value_format='8t')),
|
||||
('integer_row', dict(key_format='i', value_format='S')),
|
||||
]
|
||||
checkpoint_modes = [
|
||||
('no-checkpoint', dict(checkpoint=False)),
|
||||
('checkpoint', dict(checkpoint=True)),
|
||||
]
|
||||
rollback_modes = [
|
||||
('runtime', dict(crash=False)),
|
||||
('recovery', dict(crash=True)),
|
||||
]
|
||||
|
||||
scenarios = make_scenarios(format_values, checkpoint_modes, rollback_modes)
|
||||
|
||||
def test_rollback_to_stable(self):
|
||||
nrows = 10
|
||||
|
||||
# Create a table without logging.
|
||||
uri = "table:rollback_to_stable31"
|
||||
ds = SimpleDataSet(
|
||||
self, uri, 0, key_format=self.key_format, value_format=self.value_format,
|
||||
config='log=(enabled=false)')
|
||||
ds.populate()
|
||||
|
||||
if self.value_format == '8t':
|
||||
value_a = 97
|
||||
value_b = 98
|
||||
value_c = 99
|
||||
else:
|
||||
value_a = "aaaaa" * 10
|
||||
value_b = "bbbbb" * 10
|
||||
value_c = "ccccc" * 10
|
||||
|
||||
# Do not set stable. (Don't set oldest either as it can't be later than stable.)
|
||||
|
||||
# Write aaaaaa to all the keys at time 10.
|
||||
self.large_updates(uri, value_a, ds, nrows, False, 10)
|
||||
|
||||
# Write bbbbbb to all the keys at time 20.
|
||||
self.large_updates(uri, value_b, ds, nrows, False, 20)
|
||||
|
||||
# Write cccccc to all the keys at time 30.
|
||||
self.large_updates(uri, value_c, ds, nrows, False, 30)
|
||||
|
||||
# Optionally checkpoint.
|
||||
if self.checkpoint:
|
||||
self.session.checkpoint()
|
||||
|
||||
# Roll back, either via crashing or by explicit RTS.
|
||||
if self.crash:
|
||||
simulate_crash_restart(self, ".", "RESTART")
|
||||
else:
|
||||
self.conn.rollback_to_stable()
|
||||
|
||||
if self.crash:
|
||||
if self.checkpoint:
|
||||
# Recovery-time RTS does nothing when no stable timestamp is set.
|
||||
self.check(0, uri, 0, nrows, 5)
|
||||
self.check(value_a, uri, nrows, 0, 15)
|
||||
self.check(value_b, uri, nrows, 0, 25)
|
||||
self.check(value_c, uri, nrows, 0, 35)
|
||||
else:
|
||||
# If we crashed without a checkpoint, everything should disappear entirely.
|
||||
self.check(0, uri, 0, 0, 5)
|
||||
self.check(value_a, uri, 0, 0, 15)
|
||||
self.check(value_b, uri, 0, 0, 25)
|
||||
self.check(value_c, uri, 0, 0, 35)
|
||||
else:
|
||||
# With an explicit runtime RTS we roll back to 0, but the end of the FLCS table
|
||||
# still moves forward.
|
||||
self.check(0, uri, 0, nrows, 5)
|
||||
self.check(value_a, uri, 0, nrows, 15)
|
||||
self.check(value_b, uri, 0, nrows, 25)
|
||||
self.check(value_c, uri, 0, nrows, 35)
|
||||
|
||||
if __name__ == '__main__':
|
||||
wttest.run()
|
||||
Reference in New Issue
Block a user