diff options
author | Luke Chen <luke.chen@mongodb.com> | 2022-01-11 16:22:33 +1100 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-01-11 05:52:02 +0000 |
commit | 938a73213e7f62d8547ed6c49f0efe6f338b0516 (patch) | |
tree | 4762d580d43f1778a30942bd321864a292d5bdfa | |
parent | 9e51dd0d383ed86b08540418dee372db6cfb5dfe (diff) | |
download | mongo-938a73213e7f62d8547ed6c49f0efe6f338b0516.tar.gz |
Import wiredtiger: c6ae92c1623d9e87e2b1aff8cfe9eab204717c08 from branch mongodb-5.2
ref: e5af17e911..c6ae92c162
for: 5.2.0-rc5
WT-7922 Handle missing WiredTiger version file
-rw-r--r-- | src/third_party/wiredtiger/import.data | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/conn/conn_api.c | 52 | ||||
-rw-r--r-- | src/third_party/wiredtiger/test/suite/test_config10.py | 72 | ||||
-rwxr-xr-x | src/third_party/wiredtiger/test/suite/test_txn19.py | 4 |
4 files changed, 117 insertions, 13 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index 07f4920db37..c5e01bafed3 100644 --- a/src/third_party/wiredtiger/import.data +++ b/src/third_party/wiredtiger/import.data @@ -2,5 +2,5 @@ "vendor": "wiredtiger", "github": "wiredtiger/wiredtiger.git", "branch": "mongodb-5.2", - "commit": "e5af17e9111138938f8d3ac0e928321a35cae91b" + "commit": "c6ae92c1623d9e87e2b1aff8cfe9eab204717c08" } diff --git a/src/third_party/wiredtiger/src/conn/conn_api.c b/src/third_party/wiredtiger/src/conn/conn_api.c index 75bdf8c6466..f36bbc8cb2d 100644 --- a/src/third_party/wiredtiger/src/conn/conn_api.c +++ b/src/third_party/wiredtiger/src/conn/conn_api.c @@ -1695,7 +1695,7 @@ __conn_single(WT_SESSION_IMPL *session, const char *cfg[]) wt_off_t size; size_t len; char buf[256]; - bool bytelock, exist, is_create, match; + bool bytelock, empty, exist, is_create, is_salvage, match; conn = S2C(session); fh = NULL; @@ -1817,9 +1817,33 @@ __conn_single(WT_SESSION_IMPL *session, const char *cfg[]) WT_SINGLETHREAD_STRING)); } + /* + * We own the database home, figure out if we're creating it. There are a few files created when + * initializing the database home and we could crash in-between any of them, so there's no + * simple test. The last thing we do during initialization is rename a turtle file into place, + * and there's never a database home after that point without a turtle file. If the turtle file + * doesn't exist, it's a create. + */ + WT_ERR(__wt_turtle_exists(session, &exist)); + conn->is_new = exist ? 0 : 1; + + /* + * Unless we are salvaging, if the turtle file exists then the WiredTiger file should exist as + * well. + */ + WT_ERR(__wt_config_gets(session, cfg, "salvage", &cval)); + is_salvage = cval.val != 0; + if (!is_salvage && !conn->is_new) { + WT_ERR(__wt_fs_exist(session, WT_WIREDTIGER, &exist)); + if (!exist) { + F_SET(conn, WT_CONN_DATA_CORRUPTION); + WT_ERR_MSG(session, WT_TRY_SALVAGE, "WiredTiger version file cannot be found"); + } + } + /* We own the lock file, optionally create the WiredTiger file. */ - ret = __wt_open( - session, WT_WIREDTIGER, WT_FS_OPEN_FILE_TYPE_REGULAR, is_create ? WT_FS_OPEN_CREATE : 0, &fh); + ret = __wt_open(session, WT_WIREDTIGER, WT_FS_OPEN_FILE_TYPE_REGULAR, + is_create || is_salvage ? WT_FS_OPEN_CREATE : 0, &fh); /* * If we're read-only, check for handled errors. Even if able to open the WiredTiger file @@ -1848,16 +1872,22 @@ __conn_single(WT_SESSION_IMPL *session, const char *cfg[]) } /* - * We own the database home, figure out if we're creating it. There are a few files created when - * initializing the database home and we could crash in-between any of them, so there's no - * simple test. The last thing we do during initialization is rename a turtle file into place, - * and there's never a database home after that point without a turtle file. If the turtle file - * doesn't exist, it's a create. + * If WiredTiger file exists but is size zero when it is not supposed to be (the turtle file + * exists and we are not salvaging), write a message but don't fail. */ - WT_ERR(__wt_turtle_exists(session, &exist)); - conn->is_new = exist ? 0 : 1; + empty = false; + if (fh != NULL) { + WT_ERR(__wt_filesize(session, fh, &size)); + empty = size == 0; + if (!is_salvage && !conn->is_new && empty) + WT_ERR(__wt_msg(session, "WiredTiger version file is empty")); + } - if (conn->is_new) { + /* + * Populate the WiredTiger file if this is a new connection or if the WiredTiger file is empty + * and we are salvaging. + */ + if (conn->is_new || (is_salvage && empty)) { if (F_ISSET(conn, WT_CONN_READONLY)) WT_ERR_MSG(session, EINVAL, "The database directory is empty or needs recovery, cannot continue with a read only " diff --git a/src/third_party/wiredtiger/test/suite/test_config10.py b/src/third_party/wiredtiger/test/suite/test_config10.py new file mode 100644 index 00000000000..6ae7860ffa3 --- /dev/null +++ b/src/third_party/wiredtiger/test/suite/test_config10.py @@ -0,0 +1,72 @@ +#!/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. +# +# test_config10.py +# Test valid behaviour when starting WiredTiger with missing or empty +# WiredTiger version file. + +import wiredtiger, wttest +from wiredtiger import stat +import os + +class test_config10(wttest.WiredTigerTestCase): + uri = 'table:config10.' + + def test_missing_version_file(self): + self.conn.close() + os.remove('WiredTiger') + # Ensure error occurs when WiredTiger file is missing. + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: self.setUpConnectionOpen('.'), '/WT_TRY_SALVAGE: database corruption detected/') + + def test_empty_version_file(self): + self.conn.close() + # Ensure returns message when WiredTiger file is empty. + open('WiredTiger','w').close() + expectMessage = 'WiredTiger version file is empty' + with self.expectedStdoutPattern(expectMessage): + self.setUpConnectionOpen('.') + + def test_missing_version_file_with_salvage(self): + self.conn.close() + os.remove('WiredTiger') + salvage_config = 'salvage=true' + self.conn = self.wiredtiger_open('.', salvage_config) + # Check salvage creates and populates file. + self.assertNotEqual(os.stat('WiredTiger').st_size, 0) + + def test_empty_version_file_with_salvage(self): + self.conn.close() + open('WiredTiger','w').close() + salvage_config = 'salvage=true' + self.conn = self.wiredtiger_open('.', salvage_config) + # Check salvage populates file. + self.assertNotEqual(os.stat('WiredTiger').st_size, 0) + +if __name__ == '__main__': + wttest.run() diff --git a/src/third_party/wiredtiger/test/suite/test_txn19.py b/src/third_party/wiredtiger/test/suite/test_txn19.py index d975dc43a7c..5585f38d3fe 100755 --- a/src/third_party/wiredtiger/test/suite/test_txn19.py +++ b/src/third_party/wiredtiger/test/suite/test_txn19.py @@ -401,7 +401,6 @@ class test_txn19_meta(wttest.WiredTigerTestCase, suite_subprocess): openable = [ "removal:WiredTiger.basecfg", "removal:WiredTiger.turtle", - "removal:WiredTiger", "truncate:WiredTiger", "truncate:WiredTiger.basecfg", "truncate-middle:WiredTiger", @@ -509,6 +508,9 @@ class test_txn19_meta(wttest.WiredTigerTestCase, suite_subprocess): self.reopen_conn(dir, self.conn_config) self.captureout.checkAdditionalPattern(self, 'unexpected file WiredTiger.wt found, renamed to WiredTiger.wt.1') + elif self.filename == 'WiredTiger' and self.kind == 'truncate': + with self.expectedStdoutPattern("WiredTiger version file is empty"): + self.reopen_conn(dir, self.conn_config) else: self.reopen_conn(dir, self.conn_config) self.close_conn() |