1#!/usr/bin/env python 2# 3# Public Domain 2014-2018 MongoDB, Inc. 4# Public Domain 2008-2014 WiredTiger, Inc. 5# 6# This is free and unencumbered software released into the public domain. 7# 8# Anyone is free to copy, modify, publish, use, compile, sell, or 9# distribute this software, either in source code form or as a compiled 10# binary, for any purpose, commercial or non-commercial, and by any 11# means. 12# 13# In jurisdictions that recognize copyright laws, the author or authors 14# of this software dedicate any and all copyright interest in the 15# software to the public domain. We make this dedication for the benefit 16# of the public at large and to the detriment of our heirs and 17# successors. We intend this dedication to be an overt act of 18# relinquishment in perpetuity of all present and future rights to this 19# software under copyright law. 20# 21# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 25# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 26# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27# OTHER DEALINGS IN THE SOFTWARE. 28 29import wiredtiger, wttest 30import os, shutil 31from helper import compare_files 32from suite_subprocess import suite_subprocess 33from wtdataset import simple_key 34from wtscenario import make_scenarios 35 36# test_backup07.py 37# Test cursor backup with target URIs, logging and create during backup 38 39class test_backup07(wttest.WiredTigerTestCase, suite_subprocess): 40 dir='backup.dir' # Backup directory name 41 logmax="100K" 42 newuri="table:newtable" 43 44 pfx = 'test_backup' 45 scenarios = make_scenarios([ 46 ('table', dict(uri='table:test',dsize=100,nops=100,nthreads=1)), 47 ]) 48 49 # Create a large cache, otherwise this test runs quite slowly. 50 def conn_config(self): 51 return 'cache_size=1G,log=(archive=false,enabled,file_max=%s)' % \ 52 self.logmax 53 54 # Run background inserts while running checkpoints and incremental backups 55 # repeatedly. 56 def test_backup07(self): 57 log2 = "WiredTigerLog.0000000002" 58 59 self.session.create(self.uri, "key_format=S,value_format=S") 60 61 # Insert small amounts of data at a time stopping just after we 62 # cross into log file 2. That way we can add more operations into 63 # log file 2 during the full backup. 64 loop = 0 65 c = self.session.open_cursor(self.uri) 66 while not os.path.exists(log2): 67 for i in range(0, self.nops): 68 num = i + (loop * self.nops) 69 key = 'key' + str(num) 70 val = 'value' + str(num) 71 c[key] = val 72 loop += 1 73 74 # Test a potential bug in full backups and creates. 75 # We allow creates during backup because the file doesn't exist 76 # when the backup metadata is created on cursor open and the newly 77 # created file is not in the cursor list. However, if using logging 78 # and the create and inserts/updates appear in a log file copied, 79 # then currently there will be an error opening the backup directory. 80 81 # Open up the backup cursor, create and add data to a new table 82 # and then copy the files. 83 os.mkdir(self.dir) 84 bkup_c = self.session.open_cursor('backup:', None, None) 85 86 # Now create and populate the new table. Make sure the log records 87 # are on disk and will be copied to the backup. 88 self.session.create(self.newuri, "key_format=S,value_format=S") 89 c = self.session.open_cursor(self.newuri) 90 for i in range(0, self.nops): 91 key = 'key' + str(i) 92 val = 'value' + str(i) 93 c[key] = val 94 c.close() 95 self.session.log_flush('sync=on') 96 97 # Now copy the files returned by the backup cursor. This will 98 # include the log file that has updates for the newly created table. 99 while True: 100 ret = bkup_c.next() 101 if ret != 0: 102 break 103 newfile = bkup_c.get_key() 104 sz = os.path.getsize(newfile) 105 self.pr('Copy from: ' + newfile + ' (' + str(sz) + ') to ' + self.dir) 106 shutil.copy(newfile, self.dir) 107 self.assertEqual(ret, wiredtiger.WT_NOTFOUND) 108 bkup_c.close() 109 110 # After the full backup, open and recover the backup database. 111 # Make sure we properly recover even though the log file will have 112 # records for the newly created table file id. 113 backup_conn = self.wiredtiger_open(self.dir) 114 backup_conn.close() 115 116if __name__ == '__main__': 117 wttest.run() 118