The ovsdb-server compaction timing logic is written assuming monotonic
time at milliscond resolution but it calculated the next compaction time
based on the oldest commit in the database. This was a problem because
commit timestamps are written in wall-clock time to second resolution.
This commit calculates the next compaction time based on the time when
the database was first loaded or the last compaction was done, both in
monotonic time at millisecond resolution.
Signed-off-by: Paul Ingram <pingram@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
-/* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
+/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
bool read_only, struct ovsdb **,
struct ovsdb_file **);
static struct ovsdb_error *ovsdb_file_txn_from_json(
bool read_only, struct ovsdb **,
struct ovsdb_file **);
static struct ovsdb_error *ovsdb_file_txn_from_json(
- struct ovsdb *, const struct json *, bool converting,
- long long int *date, struct ovsdb_txn **);
+ struct ovsdb *, const struct json *, bool converting, struct ovsdb_txn **);
static struct ovsdb_error *ovsdb_file_create(struct ovsdb *,
struct ovsdb_log *,
const char *file_name,
static struct ovsdb_error *ovsdb_file_create(struct ovsdb *,
struct ovsdb_log *,
const char *file_name,
- long long int oldest_commit,
unsigned int n_transactions,
struct ovsdb_file **filep);
unsigned int n_transactions,
struct ovsdb_file **filep);
struct ovsdb_file **filep)
{
enum ovsdb_log_open_mode open_mode;
struct ovsdb_file **filep)
{
enum ovsdb_log_open_mode open_mode;
- long long int oldest_commit;
unsigned int n_transactions;
struct ovsdb_schema *schema = NULL;
struct ovsdb_error *error;
unsigned int n_transactions;
struct ovsdb_schema *schema = NULL;
struct ovsdb_error *error;
db = ovsdb_create(schema ? schema : ovsdb_schema_clone(alternate_schema));
db = ovsdb_create(schema ? schema : ovsdb_schema_clone(alternate_schema));
- oldest_commit = LLONG_MAX;
n_transactions = 0;
while ((error = ovsdb_log_read(log, &json)) == NULL && json) {
struct ovsdb_txn *txn;
n_transactions = 0;
while ((error = ovsdb_log_read(log, &json)) == NULL && json) {
struct ovsdb_txn *txn;
error = ovsdb_file_txn_from_json(db, json, alternate_schema != NULL,
error = ovsdb_file_txn_from_json(db, json, alternate_schema != NULL,
json_destroy(json);
if (error) {
ovsdb_log_unread(log);
json_destroy(json);
if (error) {
ovsdb_log_unread(log);
- if (date < oldest_commit) {
- oldest_commit = date;
- }
-
error = ovsdb_txn_commit(txn, false);
if (error) {
ovsdb_log_unread(log);
error = ovsdb_txn_commit(txn, false);
if (error) {
ovsdb_log_unread(log);
if (!read_only) {
struct ovsdb_file *file;
if (!read_only) {
struct ovsdb_file *file;
- error = ovsdb_file_create(db, log, file_name, oldest_commit,
- n_transactions, &file);
+ error = ovsdb_file_create(db, log, file_name, n_transactions, &file);
if (error) {
goto error;
}
if (error) {
goto error;
}
*
* If 'converting' is true, then unknown table and column names are ignored
* (which can ease upgrading and downgrading schemas); otherwise, they are
*
* If 'converting' is true, then unknown table and column names are ignored
* (which can ease upgrading and downgrading schemas); otherwise, they are
- * treated as errors.
- *
- * If successful, the date associated with the transaction, as the number of
- * milliseconds since the epoch, is stored in '*date'. If the transaction does
- * not include a date, LLONG_MAX is stored. */
+ * treated as errors. */
static struct ovsdb_error *
ovsdb_file_txn_from_json(struct ovsdb *db, const struct json *json,
static struct ovsdb_error *
ovsdb_file_txn_from_json(struct ovsdb *db, const struct json *json,
- bool converting, long long int *date,
- struct ovsdb_txn **txnp)
+ bool converting, struct ovsdb_txn **txnp)
{
struct ovsdb_error *error;
struct shash_node *node;
struct ovsdb_txn *txn;
*txnp = NULL;
{
struct ovsdb_error *error;
struct shash_node *node;
struct ovsdb_txn *txn;
*txnp = NULL;
if (json->type != JSON_OBJECT) {
return ovsdb_syntax_error(json, NULL, "object expected");
if (json->type != JSON_OBJECT) {
return ovsdb_syntax_error(json, NULL, "object expected");
if (!table) {
if (!strcmp(table_name, "_date")
&& node_json->type == JSON_INTEGER) {
if (!table) {
if (!strcmp(table_name, "_date")
&& node_json->type == JSON_INTEGER) {
- *date = json_integer(node_json);
continue;
} else if (!strcmp(table_name, "_comment") || converting) {
continue;
continue;
} else if (!strcmp(table_name, "_comment") || converting) {
continue;
struct ovsdb *db;
struct ovsdb_log *log;
char *file_name;
struct ovsdb *db;
struct ovsdb_log *log;
char *file_name;
- long long int oldest_commit;
+ long long int last_compact;
long long int next_compact;
unsigned int n_transactions;
};
long long int next_compact;
unsigned int n_transactions;
};
static struct ovsdb_error *
ovsdb_file_create(struct ovsdb *db, struct ovsdb_log *log,
const char *file_name,
static struct ovsdb_error *
ovsdb_file_create(struct ovsdb *db, struct ovsdb_log *log,
const char *file_name,
- long long int oldest_commit,
unsigned int n_transactions,
struct ovsdb_file **filep)
{
unsigned int n_transactions,
struct ovsdb_file **filep)
{
- long long int now = time_msec();
struct ovsdb_file *file;
char *deref_name;
char *abs_name;
struct ovsdb_file *file;
char *deref_name;
char *abs_name;
file->db = db;
file->log = log;
file->file_name = abs_name;
file->db = db;
file->log = log;
file->file_name = abs_name;
- file->oldest_commit = MIN(oldest_commit, now);
- file->next_compact = file->oldest_commit + COMPACT_MIN_MSEC;
+ file->last_compact = time_msec();
+ file->next_compact = file->last_compact + COMPACT_MIN_MSEC;
file->n_transactions = n_transactions;
ovsdb_add_replica(db, &file->replica);
file->n_transactions = n_transactions;
ovsdb_add_replica(db, &file->replica);
comment = xasprintf("compacting database online "
"(%.3f seconds old, %u transactions, %llu bytes)",
comment = xasprintf("compacting database online "
"(%.3f seconds old, %u transactions, %llu bytes)",
- (time_msec() - file->oldest_commit) / 1000.0,
+ (time_wall_msec() - file->last_compact) / 1000.0,
file->n_transactions,
(unsigned long long) ovsdb_log_get_offset(file->log));
VLOG_INFO("%s: %s", file->file_name, comment);
file->n_transactions,
(unsigned long long) ovsdb_log_get_offset(file->log));
VLOG_INFO("%s: %s", file->file_name, comment);
if (!error) {
ovsdb_log_close(file->log);
file->log = new_log;
if (!error) {
ovsdb_log_close(file->log);
file->log = new_log;
- file->oldest_commit = time_msec();
- file->next_compact = file->oldest_commit + COMPACT_MIN_MSEC;
+ file->last_compact = time_msec();
+ file->next_compact = file->last_compact + COMPACT_MIN_MSEC;
file->n_transactions = 1;
} else {
ovsdb_log_close(new_log);
file->n_transactions = 1;
} else {
ovsdb_log_close(new_log);