Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bdb/bdb_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -2481,6 +2481,8 @@ int bdb_iam_master(bdb_state_type *bdb_state);

int32_t bdb_get_dbopen_gen(void);
int is_incoherent(bdb_state_type *, struct interned_string *);
int bdb_fetch_log(bdb_state_type *bdb_state, uint32_t lognum, void **payload, uint32_t *size);
int bdb_log_range(bdb_state_type *bdb_state, uint32_t *start_log, uint32_t *end_log);

void fill_dbinfo(CDB2DBINFORESPONSE *, bdb_state_type *);
void fill_ssl_info(CDB2DBINFORESPONSE *);
Expand Down
93 changes: 93 additions & 0 deletions bdb/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -8967,3 +8967,96 @@ int bdb_debug_log(bdb_state_type *bdb_state, tran_type *trans, int inop)
op.data = &endianized;
return bdb_state->dbenv->debug_log(bdb_state->dbenv, tid, &op, NULL, NULL);
}

#define MAX_LOG_SIZE 100 * 1024 * 1024
#define FAIL \
do { \
logmsg(LOGMSG_ERROR, "%s: failed at %d rc %d errno %d %s\n", __func__, __LINE__, rc, errno, strerror(errno)); \
goto done; \
} while (0)

int bdb_fetch_log(bdb_state_type *bdb_state, uint32_t lognum, void **payload, uint32_t *size)
{
char *name = NULL;
int fd = -1;
void *logfile_contents = NULL;
int rc = __log_name(bdb_state->dbenv->lg_handle, lognum, &name, NULL, 0);
if (rc)
FAIL;
char realname[1024];
if (bdb_trans(name, realname) == NULL) {
rc = -1;
FAIL;
}

printf("log %s -> %s\n", name, realname);
fd = open(realname, O_RDONLY);
if (fd == -1)
FAIL;
struct stat st;
rc = fstat(fd, &st);
if (rc)
FAIL;
logfile_contents = malloc(st.st_size);

// quick sanity check?
if (st.st_size > MAX_LOG_SIZE) {
rc = -1;
FAIL;
}

rc = read(fd, logfile_contents, st.st_size);
if (rc != st.st_size) {
rc = -1;
FAIL;
}
*payload = logfile_contents;
*size = st.st_size;
rc = 0;

done:
if (name)
free(name);
if (fd != -1)
close(fd);
if (rc) {
if (logfile_contents)
free(logfile_contents);
}
return rc;
}

int bdb_log_range(bdb_state_type *bdb_state, uint32_t *start_log, uint32_t *end_log)
{
DB_LOGC *logc = NULL;
int rc;
DB_LSN first = {0}, last = {0};
DBT ent = {0};
ent.flags = DB_DBT_REALLOC;

if ((rc = __log_cursor(bdb_state->dbenv, &logc)) != 0)
goto done;
rc = logc->get(logc, &first, &ent, DB_FIRST);
if (rc != 0) {
printf("logc get first %d\n", rc);
goto done;
}

rc = logc->get(logc, &last, &ent, DB_LAST);
if (rc != 0) {
printf("logc get last %d\n", rc);
goto done;
}
printf("%u:%u -> %u:%u\n", first.file, first.offset, last.file, last.offset);
*start_log = first.file;
*end_log = last.file;

done:
if (ent.data)
free(ent.data);
if (logc)
logc->close(logc, 0);
return rc;
}

#undef FAIL
4 changes: 4 additions & 0 deletions db/comdb2.h
Original file line number Diff line number Diff line change
Expand Up @@ -3742,6 +3742,10 @@ extern int gbl_server_admin_mode;
extern int gbl_epoch_time;
extern int gbl_watchdog_disable_at_start;

extern int gbl_recovery_timestamp;
extern int gbl_recovery_lsn_file;
extern int gbl_recovery_lsn_offset;

extern int64_t gbl_legacy_requests;

void csc2_free_all(void);
Expand Down
3 changes: 3 additions & 0 deletions db/db_tunables.c
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,9 @@ int ctrace_set_rollat(void *unused, void *value);
*/
int get_commit_lsn_map_switch_value()
{
if (gbl_recovery_timestamp || gbl_recovery_lsn_file) {
return 0;
}
const int dependencies_are_enabled = gbl_utxnid_log;
const int enabled_dependent_exists =
gbl_test_commit_lsn_map || gbl_use_modsnap_for_snapshot;
Expand Down
1 change: 1 addition & 0 deletions sqlite/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ add_library(sqlite
ext/comdb2/keys.c
ext/comdb2/keywords.c
ext/comdb2/limits.c
ext/comdb2/logfile.c
ext/comdb2/logicalops.c
ext/comdb2/memstats.c
ext/comdb2/metrics.c
Expand Down
1 change: 1 addition & 0 deletions sqlite/ext/comdb2/comdb2systblInt.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ int systblApiHistoryInit(sqlite3 *db);
int systblDbInfoInit(sqlite3 *db);
int systblUnusedFilesInit(sqlite3 *db);
int systblPhysrepAltmetadbInit(sqlite3 *db);
int systblLogfilesInit(sqlite3 *db);

/* Simple yes/no answer for booleans */
#define YESNO(x) ((x) ? "Y" : "N")
Expand Down
205 changes: 205 additions & 0 deletions sqlite/ext/comdb2/logfile.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/*
Copyright 2022, Bloomberg Finance L.P.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "comdb2systblInt.h"
#include "comdb2.h"
#include "bdb_api.h"
#include "sqliteInt.h"
#include "vdbeInt.h"

struct logfiles_systable {
const sqlite3_module *pModule; /* The module for this virtual table */
int nRef; /* Number of open cursors */
char *zErrMsg; /* Error message from sqlite3_mprintf() */
};

struct logfiles_systable_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
uint32_t rowid; // aka log file number
uint32_t maxrowid;
void *logfile;
uint32_t size;
};

// TODO: hold log deletion while this is active

int systblLogfilesConnect(sqlite3* db, void *pAux, int argc, const char* const *argv, sqlite3_vtab **ppVTab, char **pErrr) {
int rc = sqlite3_declare_vtab(db, "CREATE TABLE comdb2_logfiles(lognum, maxlognum, logfile)");
if( rc==SQLITE_OK ){
struct logfiles_systable *pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVTab = (sqlite3_vtab*) pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
}
return 0;
}

int systblLogfilesDisconnect(sqlite3_vtab *pVTab) {
sqlite3_free(pVTab);
return SQLITE_OK;
}

int systblLogfilesOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) {
struct logfiles_systable_cursor *cur = sqlite3_malloc(sizeof(struct logfiles_systable_cursor));
memset(cur, 0, sizeof(struct logfiles_systable_cursor));
*ppCursor = (sqlite3_vtab_cursor*) cur;
return 0;
}

int systblLogfilesClose(sqlite3_vtab_cursor *p) {
struct logfiles_systable_cursor *pCur = (struct logfiles_systable_cursor*) p;
if (pCur->logfile)
sqlite3_free(pCur->logfile);
sqlite3_free(p);
return 0;
}

int systblLogfilesNext(sqlite3_vtab_cursor *p) {
struct logfiles_systable_cursor *pCur = (struct logfiles_systable_cursor*) p;
if (pCur->logfile) {
free(pCur->logfile);
pCur->logfile = NULL;
}
pCur->rowid++;
return 0;
}

int systblLogfilesEof(sqlite3_vtab_cursor *p) {
struct logfiles_systable_cursor *pCur = (struct logfiles_systable_cursor*) p;

if (pCur->rowid > pCur->maxrowid)
return 1;

return 0;
}

int systblLogfilesColumn(sqlite3_vtab_cursor *p, sqlite3_context *ctx, int i) {
struct logfiles_systable_cursor *pCur = (struct logfiles_systable_cursor*) p;
if (pCur->logfile == NULL) {
int rc = bdb_fetch_log(thedb->bdb_env, pCur->rowid, &pCur->logfile, &pCur->size);
if (rc) {
// TODO: error string
return SQLITE_INTERNAL;
}
}
switch (i) {
case 0:
sqlite3_result_int(ctx, pCur->rowid);
break;
case 1: {
sqlite3_result_int(ctx, pCur->maxrowid);
break;
}
case 2: {
void *copy = malloc(pCur->size);
memcpy(copy, pCur->logfile, pCur->size);
sqlite3_result_blob(ctx, copy, pCur->size, free);
break;
}
default:
return SQLITE_INTERNAL;
}
return SQLITE_OK;
}

int systblLogfilesRowid(sqlite3_vtab_cursor *p, sqlite3_int64 *pRowid) {
struct logfiles_systable_cursor *pCur = (struct logfiles_systable_cursor*) p;
*pRowid = pCur->rowid;
return 0;
}

int systblLogfilesBestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *info) {
int argc = 0;
int return_ordered = 0;

if (info->nOrderBy == 1 && info->aOrderBy[0].iColumn == 0 && info->aOrderBy[0].desc == 0)
return_ordered = 1;

for (int i = 0; i < info->nConstraint; i++) {
if (!info->aConstraint[i].usable)
continue;
if (info->aConstraint[i].iColumn == 0 && (
info->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_EQ ||
info->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_GE ||
info->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_GT ||
info->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_IS))
{
info->aConstraintUsage[i].argvIndex = ++argc;
info->aConstraintUsage[i].omit = 0;
}
}
if (argc > 0) {
info->idxNum = 1;
info->orderByConsumed = return_ordered;
}
return 0;
}

extern char *print_mem(sqlite3_value *v);

int systblLogfilesFilter(sqlite3_vtab_cursor *p, int idxNum, const char *idxStr, int argc, sqlite3_value **argv) {
struct logfiles_systable_cursor *pCur = (struct logfiles_systable_cursor*) p;
uint32_t first_log = 0;

// int bdb_log_range(bdb_state_type *bdb_state, uint32_t *start_log, uint32_t *end_log);
int rc = bdb_log_range(thedb->bdb_env, &first_log, &pCur->maxrowid);
if (rc) {
// TODO: error
return SQLITE_INTERNAL;
}

if (idxNum == 1 && argc == 1 && argv[0]->flags & MEM_Int) {
pCur->rowid = sqlite3_value_int(argv[0]);
}
else {
pCur->rowid = first_log;
}

return SQLITE_OK;
}

static sqlite3_module systblLogfilesModule = {
0, /* iVersion */
0, /* xCreate */
systblLogfilesConnect, /* xConnect */
systblLogfilesBestIndex, /* xBestIndex */
systblLogfilesDisconnect, /* xDisconnect */
0, /* xDestroy */
systblLogfilesOpen, /* xOpen - open a cursor */
systblLogfilesClose, /* xClose - close a cursor */
systblLogfilesFilter, /* xFilter - configure scan constraints */
systblLogfilesNext, /* xNext - advance a cursor */
systblLogfilesEof, /* xEof - check for end of scan */
systblLogfilesColumn, /* xColumn - read data */
systblLogfilesRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
0, /* xShadowName */
.access_flag = CDB2_ALLOW_USER,
};

int systblLogfilesInit(sqlite3 *db) {
int rc = sqlite3_create_module(db, "comdb2_logfiles", &systblLogfilesModule, 0);
return rc;
}
2 changes: 2 additions & 0 deletions sqlite/ext/comdb2/tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ int comdb2SystblInit(
rc = systblUnusedFilesInit(db);
if (rc == SQLITE_OK)
rc = systblPhysrepAltmetadbInit(db);
if (rc == SQLITE_OK)
rc = systblLogfilesInit(db);
#endif
return rc;
}
Expand Down
3 changes: 2 additions & 1 deletion tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ basicops_nokey: init
basicops: basicops_nokey
$(shell TESTDIR="${TESTDIR}" CLUSTER="${CLUSTER}" SKIPSSL="${SKIPSSL}" $(TESTSROOTDIR)/tools/keygen.sh)
$(shell TOTAL="${TOTAL}" $(TESTSROOTDIR)/tools/smalldelay.sh)
$(shell TESTDIR="${TESTDIR}" CLUSTER="${CLUSTER}" TESTSROOTDIR="${TESTSROOTDIR}" COMDB2_EXE=${COMDB2_EXE} CDB2SQL_EXE=${CDB2SQL_EXE} COPYCOMDB2_EXE=${COPYCOMDB2_EXE} COMDB2AR_EXE=${COMDB2AR_EXE} CDB2VERIFY_EXE=${CDB2VERIFY_EXE} PMUX_EXE=${PMUX_EXE} PMUXPORT=${PMUXPORT} SKIP_COPY_EXE="${SKIP_COPY_EXE}" ${TESTSROOTDIR}/tools/copy_files_to_cluster.sh > ${TESTDIR}/copy_files_to_cluster.log 2>&1 || echo "exit 1 copy_files_to_cluster failed, see ${TESTDIR}/copy_files_to_cluster.log" )
$(shell TESTDIR="${TESTDIR}" CLUSTER="${CLUSTER}" TESTSROOTDIR="${TESTSROOTDIR}" COMDB2_EXE=${COMDB2_EXE} CDB2SQL_EXE=${CDB2SQL_EXE} COPYCOMDB2_EXE=${COPYCOMDB2_EXE} COMDB2AR_EXE=${COMDB2AR_EXE} CDB2VERIFY_EXE=${CDB2VERIFY_EXE} CDB2_COPYLOGS_START_EXE=${CDB2_COPYLOGS_START_EXE} PMUX_EXE=${PMUX_EXE} PMUXPORT=${PMUXPORT} SKIP_COPY_EXE="${SKIP_COPY_EXE}" ${TESTSROOTDIR}/tools/copy_files_to_cluster.sh > ${TESTDIR}/copy_files_to_cluster.log 2>&1 || echo "exit 1 copy_files_to_cluster failed, see ${TESTDIR}/copy_files_to_cluster.log" )

showparams:
@echo MAKECMDGOALS=${MAKECMDGOALS}
Expand All @@ -107,6 +107,7 @@ showparams:
@echo CLUSTER=${CLUSTER}
@echo BUILDDIR=${BUILDDIR}
@echo COMDB2AR_EXE=${COMDB2AR_EXE}
@echo CDB2_COPYLOGS_START_EXE=${CDB2_COPYLOGS_START_EXE}
@echo CDB2VERIFY_EXE=${CDB2VERIFY_EXE}
@echo COMDB2_EXE=${COMDB2_EXE}
@echo CDB2SQL_EXE=${CDB2SQL_EXE}
Expand Down
1 change: 1 addition & 0 deletions tests/Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export CDB2DUMP_EXE?=${BUILDDIR}/db/cdb2_dump
export CDB2VERIFY_EXE?=${BUILDDIR}/db/cdb2_verify
export CDB2_SQLREPLAY_EXE?=${BUILDDIR}/tools/cdb2_sqlreplay/cdb2_sqlreplay
export PMUX_EXE?=${BUILDDIR}/tools/pmux/pmux
export CDB2_COPYLOGS_START_EXE?=${BUILDDIR}/tools/cdb2_copylogs_start/cdb2_copylogs_start
export pmux_port?=5105
export MAKEFILE_COMMON_INCLUDED=1
endif
8 changes: 8 additions & 0 deletions tests/copylogs_start.test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ifeq ($(TESTSROOTDIR),)
include ../testcase.mk
else
include $(TESTSROOTDIR)/testcase.mk
endif
ifeq ($(TEST_TIMEOUT),)
export TEST_TIMEOUT=5m
endif
Loading