-
Notifications
You must be signed in to change notification settings - Fork 10
Rename database file to sfs.db #245
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ | |
*/ | ||
#include "dbconn.h" | ||
|
||
#include <ceph_assert.h> | ||
#include <sqlite3.h> | ||
|
||
#include <filesystem> | ||
|
@@ -30,7 +31,7 @@ namespace rgw::sal::sfs::sqlite { | |
|
||
static std::string get_temporary_db_path(CephContext* ctt) { | ||
auto rgw_sfs_path = ctt->_conf.get_val<std::string>("rgw_sfs_data_path"); | ||
auto tmp_db_name = std::string(SCHEMA_DB_NAME) + "_tmp"; | ||
auto tmp_db_name = std::string(DB_FILENAME) + "_tmp"; | ||
auto db_path = std::filesystem::path(rgw_sfs_path) / std::string(tmp_db_name); | ||
return db_path.string(); | ||
} | ||
|
@@ -121,6 +122,7 @@ DBConn::DBConn(CephContext* _cct) | |
storage_pool_mutex(), | ||
cct(_cct), | ||
profile_enabled(_cct->_conf.get_val<bool>("rgw_sfs_sqlite_profile")) { | ||
maybe_rename_database_file(); | ||
sqlite3_config(SQLITE_CONFIG_LOG, &sqlite_error_callback, cct); | ||
// get_storage() relies on there already being an entry in the pool | ||
// for the main thread (i.e. the thread that created the DBConn). | ||
|
@@ -414,4 +416,65 @@ void DBConn::maybe_upgrade_metadata() { | |
} | ||
} | ||
|
||
void DBConn::maybe_rename_database_file() const { | ||
if (!std::filesystem::exists(getLegacyDBPath(cct))) { | ||
return; | ||
} | ||
if (std::filesystem::exists(getDBPath(cct))) { | ||
return; | ||
} | ||
Comment on lines
+420
to
+425
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could have been a single |
||
|
||
lsubdout(cct, rgw_sfs, SFS_LOG_STARTUP) | ||
<< fmt::format( | ||
"Migrating legacy database file {} -> {}", getLegacyDBPath(cct), | ||
getDBPath(cct) | ||
) | ||
<< dendl; | ||
|
||
dbapi::sqlite::database src_db(getLegacyDBPath(cct)); | ||
dbapi::sqlite::database dst_db(getDBPath(cct)); | ||
auto state = | ||
std::unique_ptr<sqlite3_backup, decltype(&sqlite3_backup_finish)>( | ||
sqlite3_backup_init( | ||
dst_db.connection().get(), "main", src_db.connection().get(), | ||
"main" | ||
), | ||
sqlite3_backup_finish | ||
); | ||
|
||
if (!state) { | ||
lsubdout(cct, rgw_sfs, SFS_LOG_ERROR) | ||
<< fmt::format( | ||
"Error opening legacy database file {} {}. Please migrate " | ||
"s3gw.db to sfs.db manually", | ||
getLegacyDBPath(cct), sqlite3_errmsg(dst_db.connection().get()) | ||
) | ||
<< dendl; | ||
ceph_abort_msg("sfs database file migration failed"); | ||
} | ||
|
||
int rc = sqlite3_backup_step(state.get(), -1); | ||
if (rc != SQLITE_DONE) { | ||
lsubdout(cct, rgw_sfs, SFS_LOG_ERROR) | ||
<< fmt::format( | ||
"Error migrating legacy database file {} {}. Please migrate " | ||
"s3gw.db to sfs.db manually", | ||
getLegacyDBPath(cct), sqlite3_errmsg(dst_db.connection().get()) | ||
) | ||
<< dendl; | ||
ceph_abort_msg("sfs database file migration failed"); | ||
} | ||
|
||
std::error_code ec; // ignore errors | ||
fs::remove(getLegacyDBPath(cct), ec); | ||
fs::remove(getLegacyDBPath(cct) + "-wal", ec); | ||
fs::remove(getLegacyDBPath(cct) + "-shm", ec); | ||
|
||
lsubdout(cct, rgw_sfs, SFS_LOG_STARTUP) | ||
<< fmt::format( | ||
"Done migrating legacy database. Continuing startup with {}", | ||
getDBPath(cct) | ||
) | ||
<< dendl; | ||
} | ||
} // namespace rgw::sal::sfs::sqlite |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,7 +41,9 @@ constexpr int SFS_METADATA_VERSION = 4; | |
/// minimum required version to upgrade db. | ||
constexpr int SFS_METADATA_MIN_VERSION = 4; | ||
|
||
constexpr std::string_view SCHEMA_DB_NAME = "s3gw.db"; | ||
constexpr std::string_view LEGACY_DB_FILENAME = "s3gw.db"; | ||
constexpr std::string_view DB_FILENAME = "sfs.db"; | ||
constexpr std::string_view DB_WAL_FILENAME = "sfs.db-wal"; | ||
|
||
constexpr std::string_view USERS_TABLE = "users"; | ||
constexpr std::string_view BUCKETS_TABLE = "buckets"; | ||
|
@@ -292,12 +294,20 @@ class DBConn { | |
static std::string getDBPath(CephContext* cct) { | ||
auto rgw_sfs_path = cct->_conf.get_val<std::string>("rgw_sfs_data_path"); | ||
auto db_path = | ||
std::filesystem::path(rgw_sfs_path) / std::string(SCHEMA_DB_NAME); | ||
std::filesystem::path(rgw_sfs_path) / std::string(DB_FILENAME); | ||
return db_path.string(); | ||
} | ||
|
||
static std::string getLegacyDBPath(CephContext* cct) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to be perfectly honest, I really dislike that we have this function as camelCase when all other functions are snake case. More of an itch for me than anything else. |
||
auto rgw_sfs_path = cct->_conf.get_val<std::string>("rgw_sfs_data_path"); | ||
auto db_path = | ||
std::filesystem::path(rgw_sfs_path) / std::string(LEGACY_DB_FILENAME); | ||
return db_path.string(); | ||
} | ||
|
||
void check_metadata_is_compatible() const; | ||
void maybe_upgrade_metadata(); | ||
void maybe_rename_database_file() const; | ||
}; | ||
|
||
using DBConnRef = std::shared_ptr<DBConn>; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
|
||
#include <gtest/gtest.h> | ||
|
||
#include "driver/sfs/sqlite/dbconn.h" | ||
#include "rgw/rgw_sal_sfs.h" | ||
|
||
using namespace rgw::sal::sfs; | ||
|
@@ -78,7 +79,7 @@ class TestSFSWALCheckpoint : public ::testing::Test { | |
size_t num_threads, size_t num_objects | ||
) { | ||
std::atomic<std::uintmax_t> max_wal_size{0}; | ||
fs::path wal(test_dir / "s3gw.db-wal"); | ||
fs::path wal(test_dir / sqlite::DB_WAL_FILENAME); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we maybe define this as a function of DB_FILENAME, instead of having to keep a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would leak an sqlite implementation detail that a reader does not need to know about. I'd rather have this |
||
|
||
std::vector<std::thread> threads; | ||
for (size_t i = 0; i < num_threads; ++i) { | ||
|
@@ -123,7 +124,7 @@ TEST_F(TestSFSWALCheckpoint, confirm_wal_explosion) { | |
// The fact that we have no size limit set means the WAL | ||
// won't be truncated even when the last writer completes, | ||
// so it should *still* be huge now. | ||
EXPECT_EQ(fs::file_size(test_dir / "s3gw.db-wal"), max_wal_size); | ||
EXPECT_EQ(fs::file_size(test_dir / sqlite::DB_WAL_FILENAME), max_wal_size); | ||
} | ||
|
||
// This test proves the WAL growth problem has been fixed | ||
|
@@ -142,5 +143,5 @@ TEST_F(TestSFSWALCheckpoint, test_wal_checkpoint) { | |
|
||
// Once the writes are all done, the WAL should be finally | ||
// truncated to something less than 16MB. | ||
EXPECT_LT(fs::file_size(test_dir / "s3gw.db-wal"), SIZE_1MB * 16); | ||
EXPECT_LT(fs::file_size(test_dir / sqlite::DB_WAL_FILENAME), SIZE_1MB * 16); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect we may also have to rename the
-wal
and-shm
files. I think those can be left behind if the database is not properly closed.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, if you
killall -9 radosgw
the-wal
and-shm
files will remain, then the next time you start it up, you'll see something like[SQLITE] (283) recovered 26 frames from WAL file /scratch/s3gw/qa/s3gw.db-wal
in the log. So if we keep the migration code, we'd need to migrate those two as well.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about it, the rename code is a bit naive. Perhaps too naive. Not only do we need to rename the extra files, there may also be temporary files (according to docs) that share the basename. If the database is still open renaming is also a big mistake.
A safer option would be the backup API - I think we should rather use that