add support for OpenAsSecondary and TryCatchUpWithPrimary

This commit is contained in:
Jack Robison 2021-11-03 15:15:54 -04:00
parent f28b7e5a36
commit ee12fe9573
No known key found for this signature in database
GPG key ID: DF25C68FE0239BB2
3 changed files with 53 additions and 2 deletions

View file

@ -1722,8 +1722,9 @@ cdef class DB(object):
cdef db.DB* db cdef db.DB* db
cdef list cf_handles cdef list cf_handles
cdef list cf_options cdef list cf_options
cdef py_bool is_secondary
def __cinit__(self, db_name, Options opts, dict column_families=None, read_only=False): def __cinit__(self, db_name, Options opts, dict column_families=None, read_only=False, secondary_name=''):
cdef Status st cdef Status st
cdef string db_path cdef string db_path
cdef vector[db.ColumnFamilyDescriptor] column_family_descriptors cdef vector[db.ColumnFamilyDescriptor] column_family_descriptors
@ -1738,6 +1739,7 @@ cdef class DB(object):
raise Exception("Options object is already used by another DB") raise Exception("Options object is already used by another DB")
db_path = path_to_string(db_name) db_path = path_to_string(db_name)
if not column_families or default_cf_name not in column_families: if not column_families or default_cf_name not in column_families:
# Always add the default column family # Always add the default column family
column_family_descriptors.push_back( column_family_descriptors.push_back(
@ -1771,7 +1773,19 @@ cdef class DB(object):
) )
) )
self.cf_options.append(cf_options) self.cf_options.append(cf_options)
if read_only:
if secondary_name != '':
secondary_path = path_to_string(secondary_name)
self.is_secondary = True
with nogil:
st = db.DB_OpenAsSecondary_ColumnFamilies(
deref(opts.opts),
db_path,
secondary_path,
column_family_descriptors,
&column_family_handles,
&self.db)
elif read_only:
with nogil: with nogil:
st = db.DB_OpenForReadOnly_ColumnFamilies( st = db.DB_OpenForReadOnly_ColumnFamilies(
deref(opts.opts), deref(opts.opts),
@ -1847,6 +1861,11 @@ cdef class DB(object):
self.db.Close() self.db.Close()
self.db = NULL self.db = NULL
def try_catch_up_with_primary(self):
with nogil:
st = self.db.TryCatchUpWithPrimary()
check_status(st)
def __dealloc__(self): def __dealloc__(self):
self.close() self.close()

View file

@ -170,6 +170,7 @@ cdef extern from "rocksdb/db.h" namespace "rocksdb":
Status DisableFileDeletions() nogil except+ Status DisableFileDeletions() nogil except+
Status EnableFileDeletions() nogil except+ Status EnableFileDeletions() nogil except+
Status Close() nogil except+ Status Close() nogil except+
Status TryCatchUpWithPrimary() nogil except+
# TODO: Status GetSortedWalFiles(VectorLogPtr& files) # TODO: Status GetSortedWalFiles(VectorLogPtr& files)
# TODO: SequenceNumber GetLatestSequenceNumber() # TODO: SequenceNumber GetLatestSequenceNumber()
@ -209,6 +210,20 @@ cdef extern from "rocksdb/db.h" namespace "rocksdb":
DB**, DB**,
cpp_bool) nogil except+ cpp_bool) nogil except+
cdef Status DB_OpenAsSecondary "rocksdb::DB::OpenAsSecondary"(
const options.Options&,
const string&,
const string&,
DB**) nogil except+
cdef Status DB_OpenAsSecondary_ColumnFamilies "rocksdb::DB::OpenAsSecondary"(
const options.Options&,
const string&,
const string&,
const vector[ColumnFamilyDescriptor]&,
vector[ColumnFamilyHandle*]*,
DB**) nogil except+
cdef Status RepairDB(const string& dbname, const options.Options&) cdef Status RepairDB(const string& dbname, const options.Options&)
cdef Status ListColumnFamilies "rocksdb::DB::ListColumnFamilies" ( cdef Status ListColumnFamilies "rocksdb::DB::ListColumnFamilies" (

View file

@ -53,6 +53,23 @@ class TestDB(TestHelper):
self.db.put(b"a", b"b") self.db.put(b"a", b"b")
self.assertEqual(b"b", self.db.get(b"a")) self.assertEqual(b"b", self.db.get(b"a"))
def test_put_then_get_from_secondary(self):
secondary_location = os.path.join(self.db_loc, "secondary")
secondary = rocksdb.DB(
os.path.join(self.db_loc, "test"),
rocksdb.Options(create_if_missing=True, max_open_files=-1),
secondary_name=secondary_location
)
self.addCleanup(secondary.close)
self.assertIsNone(secondary.get(b"a"))
self.db.put(b"a", b"b")
self.assertEqual(b"b", self.db.get(b"a"))
self.assertIsNone(secondary.get(b"a"))
secondary.try_catch_up_with_primary()
self.assertEqual(b"b", secondary.get(b"a"))
def test_multi_get(self): def test_multi_get(self):
self.db.put(b"a", b"1") self.db.put(b"a", b"1")
self.db.put(b"b", b"2") self.db.put(b"b", b"2")