-
Fix potential races in updating checkpoint buffer counts that can
cause checkpoint calls to never finish.
*** mp/mp_bh.c.orig Wed Nov 25 10:46:58 1998
--- mp/mp_bh.c Thu Apr 15 21:19:17 1999
***************
*** 267,273 ****
MPOOL *mp;
MPOOLFILE *mfp;
ssize_t nw;
! int callpgin, ret, syncfail;
const char *fail;
dbmp = dbmfp->dbmp;
--- 267,273 ----
MPOOL *mp;
MPOOLFILE *mfp;
ssize_t nw;
! int callpgin, dosync, ret, syncfail;
const char *fail;
dbmp = dbmfp->dbmp;
***************
*** 386,425 ****
/*
* If we write a buffer for which a checkpoint is waiting, update
* the count of pending buffers (both in the mpool as a whole and
! * for this file). If the count for this file goes to zero, flush
! * the writes.
! *
! * XXX:
! * Don't lock the region around the sync, fsync(2) has no atomicity
! * issues.
! *
! * XXX:
! * We ignore errors from the sync -- it makes no sense to return an
! * error to the calling process, so set a flag causing the checkpoint
! * to be retried later.
*/
if (F_ISSET(bhp, BH_WRITE)) {
- if (mfp->lsn_cnt == 1) {
- UNLOCKREGION(dbmp);
- syncfail = __os_fsync(dbmfp->fd) != 0;
- LOCKREGION(dbmp);
- if (syncfail)
- F_SET(mp, MP_LSN_RETRY);
-
- }
-
F_CLR(bhp, BH_WRITE);
- /*
- * If the buffer just written has a larger LSN than the current
- * max LSN written for this checkpoint, update the saved value.
- */
- if (log_compare(&lsn, &mp->lsn) > 0)
- mp->lsn = lsn;
-
--mp->lsn_cnt;
! --mfp->lsn_cnt;
! }
/* Update the page clean/dirty statistics. */
++mp->stat.st_page_clean;
--- 386,401 ----
/*
* If we write a buffer for which a checkpoint is waiting, update
* the count of pending buffers (both in the mpool as a whole and
! * for this file). If the count for this file goes to zero, set a
! * flag so we flush the writes.
*/
if (F_ISSET(bhp, BH_WRITE)) {
F_CLR(bhp, BH_WRITE);
--mp->lsn_cnt;
! dosync = --mfp->lsn_cnt == 0 ? 1 : 0;
! } else
! dosync = 0;
/* Update the page clean/dirty statistics. */
++mp->stat.st_page_clean;
***************
*** 428,433 ****
--- 404,432 ----
/* Update I/O statistics. */
++mp->stat.st_page_out;
++mfp->stat.st_page_out;
+
+ /*
+ * Do the sync after everything else has been updated, so any incoming
+ * checkpoint doesn't see inconsistent information.
+ *
+ * XXX:
+ * Don't lock the region around the sync, fsync(2) has no atomicity
+ * issues.
+ *
+ * XXX:
+ * We ignore errors from the sync -- it makes no sense to return an
+ * error to the calling process, so set a flag causing the checkpoint
+ * to be retried later. There is a possibility, of course, that a
+ * subsequent checkpoint was started and that we're going to force it
+ * to fail. That should be unlikely, and fixing it would be difficult.
+ */
+ if (dosync) {
+ UNLOCKREGION(dbmp);
+ syncfail = __os_fsync(dbmfp->fd) != 0;
+ LOCKREGION(dbmp);
+ if (syncfail)
+ F_SET(mp, MP_LSN_RETRY);
+ }
return (0);
-
Fix for XA support, allows two-phase commit processing to work.
*** xa/xa.c.orig Sun Apr 18 21:19:43 1999
--- xa/xa.c Tue Apr 20 22:44:24 1999
***************
*** 195,201 ****
*/
if (is_known) {
td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off);
! if (td->xa_status == TXN_XA_SUSPENDED && !LF_SET(TMRESUME))
return (XAER_PROTO);
if (td->xa_status == TXN_XA_DEADLOCKED)
return (XA_RBDEADLOCK);
--- 195,201 ----
*/
if (is_known) {
td = (TXN_DETAIL *)((u_int8_t *)env->tx_info->region + off);
! if (td->xa_status == TXN_XA_SUSPENDED && !LF_ISSET(TMRESUME))
return (XAER_PROTO);
if (td->xa_status == TXN_XA_DEADLOCKED)
return (XA_RBDEADLOCK);
***************
*** 361,371 ****
if (td->xa_status == TXN_XA_ABORTED)
return (XA_RBOTHER);
! if (LF_SET(TMONEPHASE) &&
td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED)
return (XAER_PROTO);
! if (!LF_SET(TMONEPHASE) && td->xa_status != TXN_XA_PREPARED)
return (XAER_PROTO);
/* Now, fill in the global transaction structure. */
--- 361,371 ----
if (td->xa_status == TXN_XA_ABORTED)
return (XA_RBOTHER);
! if (LF_ISSET(TMONEPHASE) &&
td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED)
return (XAER_PROTO);
! if (!LF_ISSET(TMONEPHASE) && td->xa_status != TXN_XA_PREPARED)
return (XAER_PROTO);
/* Now, fill in the global transaction structure. */
***************
*** 572,582 ****
if (td->xa_status == TXN_XA_ABORTED)
return (XA_RBOTHER);
! if (LF_SET(TMONEPHASE) &&
td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED)
- return (XAER_PROTO);
-
- if (!LF_SET(TMONEPHASE) && td->xa_status != TXN_XA_PREPARED)
return (XAER_PROTO);
/* Now, fill in the global transaction structure. */
--- 572,579 ----
if (td->xa_status == TXN_XA_ABORTED)
return (XA_RBOTHER);
! if (LF_ISSET(TMONEPHASE) &&
td->xa_status != TXN_XA_ENDED && td->xa_status != TXN_XA_SUSPENDED)
return (XAER_PROTO);
/* Now, fill in the global transaction structure. */
-
Fix a recovery bug when database files are opened/closed multiple times in
the same session.
*** include/log.h.orig Tue Nov 10 11:50:03 1998
--- include/log.h Wed Aug 11 16:06:58 1999
***************
*** 51,56 ****
--- 51,57 ----
*/
typedef struct __db_entry {
DB *dbp; /* Associated DB structure. */
+ char *name; /* File name. */
u_int32_t refcount; /* Reference counted. */
int deleted; /* File was not found during open. */
} DB_ENTRY;
*** include/log_ext.h.orig Wed Aug 11 16:06:27 1999
--- include/log_ext.h Wed Aug 11 16:06:38 1999
***************
*** 19,25 ****
int __log_name __P((DB_LOG *, u_int32_t, char **, int *, u_int32_t));
int __log_register_recover
__P((DB_LOG *, DBT *, DB_LSN *, int, void *));
! int __log_add_logid __P((DB_LOG *, DB *, u_int32_t));
int __db_fileid_to_db __P((DB_LOG *, DB **, u_int32_t));
void __log_close_files __P((DB_LOG *));
void __log_rem_logid __P((DB_LOG *, u_int32_t));
--- 19,25 ----
int __log_name __P((DB_LOG *, u_int32_t, char **, int *, u_int32_t));
int __log_register_recover
__P((DB_LOG *, DBT *, DB_LSN *, int, void *));
! int __log_add_logid __P((DB_LOG *, DB *, const char *, u_int32_t));
int __db_fileid_to_db __P((DB_LOG *, DB **, u_int32_t));
void __log_close_files __P((DB_LOG *));
void __log_rem_logid __P((DB_LOG *, u_int32_t));
*** log/log.c.orig Mon Apr 12 12:07:38 1999
--- log/log.c Wed Aug 11 15:36:34 1999
***************
*** 432,437 ****
--- 432,438 ----
log_close(dblp)
DB_LOG *dblp;
{
+ u_int32_t i;
int ret, t_ret;
LOG_PANIC_CHECK(dblp);
***************
*** 457,465 ****
if (dblp->c_fd != -1 &&
(t_ret = __os_close(dblp->c_fd)) != 0 && ret == 0)
ret = t_ret;
! if (dblp->dbentry != NULL)
__os_free(dblp->dbentry,
(dblp->dbentry_cnt * sizeof(DB_ENTRY)));
if (dblp->dir != NULL)
__os_freestr(dblp->dir);
--- 458,471 ----
if (dblp->c_fd != -1 &&
(t_ret = __os_close(dblp->c_fd)) != 0 && ret == 0)
ret = t_ret;
! if (dblp->dbentry != NULL) {
! for (i = 0; i < dblp->dbentry_cnt; i++)
! if (dblp->dbentry[i].name != NULL)
! __os_freestr(dblp->dbentry[i].name);
__os_free(dblp->dbentry,
(dblp->dbentry_cnt * sizeof(DB_ENTRY)));
+ }
+
if (dblp->dir != NULL)
__os_freestr(dblp->dir);
*** log/log_rec.c.orig Mon Apr 12 12:07:38 1999
--- log/log_rec.c Fri Aug 13 16:30:27 1999
***************
*** 73,78 ****
--- 73,79 ----
int redo;
void *info;
{
+ DB_ENTRY *dbe;
__log_register_args *argp;
int ret;
***************
*** 104,113 ****
argp->name.data, strerror(ENOENT));
ret = 0;
}
! } else if (argp->opcode != LOG_CHECKPOINT) {
/*
! * If we are redoing a close or undoing an open, then we need
! * to close the file.
*
* If the file is deleted, then we can just ignore this close.
* Otherwise, we should usually have a valid dbp we should
--- 105,120 ----
argp->name.data, strerror(ENOENT));
ret = 0;
}
! } else if (argp->opcode != LOG_CHECKPOINT &&
! argp->opcode != LOG_CLOSE) {
/*
! * If we are undoing an open, then we need to close the file.
! * Note that we do *not* close the file if we are redoing a
! * close, because we do not log the reference counts on log
! * files and we may have had the file open multiple times,
! * and therefore, this close should just dec a reference
! * count. However, since we only do one open during a
! * checkpoint, this will inadvertently close the file.
*
* If the file is deleted, then we can just ignore this close.
* Otherwise, we should usually have a valid dbp we should
***************
*** 116,129 ****
* may, in fact, not have the file open, and that's OK.
*/
LOCK_LOGTHREAD(logp);
! if (logp->dbentry[argp->id].dbp != NULL &&
! --logp->dbentry[argp->id].refcount == 0) {
! ret = logp->dbentry[argp->id].dbp->close(
! logp->dbentry[argp->id].dbp, 0);
! logp->dbentry[argp->id].dbp = NULL;
}
UNLOCK_LOGTHREAD(logp);
! } else if (redo == TXN_UNDO &&
(argp->id >= logp->dbentry_cnt ||
(!logp->dbentry[argp->id].deleted &&
logp->dbentry[argp->id].dbp == NULL))) {
--- 123,141 ----
* may, in fact, not have the file open, and that's OK.
*/
LOCK_LOGTHREAD(logp);
! if (argp->id < logp->dbentry_cnt) {
! dbe = &logp->dbentry[argp->id];
! if (dbe->dbp != NULL && --dbe->refcount == 0) {
! ret = dbe->dbp->close(dbe->dbp, 0);
! if (dbe->name != NULL) {
! __os_freestr(dbe->name);
! dbe->name = NULL;
! }
! (void)__log_rem_logid(logp, argp->id);
! }
}
UNLOCK_LOGTHREAD(logp);
! } else if (argp->opcode == LOG_CHECKPOINT && redo == TXN_UNDO &&
(argp->id >= logp->dbentry_cnt ||
(!logp->dbentry[argp->id].deleted &&
logp->dbentry[argp->id].dbp == NULL))) {
***************
*** 160,176 ****
DB_LOG *lp;
__log_register_args *argp;
{
LOCK_LOGTHREAD(lp);
! if (argp->id < lp->dbentry_cnt &&
! (lp->dbentry[argp->id].deleted == 1 ||
! lp->dbentry[argp->id].dbp != NULL)) {
! if (argp->opcode != LOG_CHECKPOINT)
! lp->dbentry[argp->id].refcount++;
UNLOCK_LOGTHREAD(lp);
return (0);
}
! UNLOCK_LOGTHREAD(lp);
return (__log_do_open(lp,
argp->uid.data, argp->name.data, argp->ftype, argp->id));
}
--- 172,213 ----
DB_LOG *lp;
__log_register_args *argp;
{
+ DB_ENTRY *dbe;
+
+ if (argp->name.size == 0)
+ return(0);
+
+ /*
+ * Because of reference counting, we cannot automatically close files
+ * during recovery, so when we're opening, we have to check that the
+ * name we are opening is what we expect. If it's not, then we close
+ * the old file and open the new one.
+ */
LOCK_LOGTHREAD(lp);
! if (argp->id < lp->dbentry_cnt)
! dbe = &lp->dbentry[argp->id];
! else
! dbe = NULL;
!
! if (dbe != NULL && (dbe->deleted == 1 || dbe->dbp != NULL) &&
! dbe->name != NULL && argp->name.data != NULL &&
! strncmp(argp->name.data, dbe->name, argp->name.size) == 0) {
+ dbe->refcount++;
UNLOCK_LOGTHREAD(lp);
return (0);
}
! UNLOCK_LOGTHREAD(lp);
!
! if (dbe != NULL && dbe->dbp != NULL) {
! (void)dbe->dbp->close(dbe->dbp, 0);
! if (dbe->name != NULL)
! __os_freestr(dbe->name);
! dbe->name = NULL;
! (void)__log_rem_logid(lp, argp->id);
! }
!
!
return (__log_do_open(lp,
argp->uid.data, argp->name.data, argp->ftype, argp->id));
}
***************
*** 206,212 ****
}
if (ret == 0 || ret == ENOENT)
! (void)__log_add_logid(lp, dbp, ndx);
return (ret);
}
--- 243,249 ----
}
if (ret == 0 || ret == ENOENT)
! (void)__log_add_logid(lp, dbp, name, ndx);
return (ret);
}
***************
*** 215,226 ****
* __log_add_logid --
* Adds a DB entry to the log's DB entry table.
*
! * PUBLIC: int __log_add_logid __P((DB_LOG *, DB *, u_int32_t));
*/
int
! __log_add_logid(logp, dbp, ndx)
DB_LOG *logp;
DB *dbp;
u_int32_t ndx;
{
u_int32_t i;
--- 252,264 ----
* __log_add_logid --
* Adds a DB entry to the log's DB entry table.
*
! * PUBLIC: int __log_add_logid __P((DB_LOG *, DB *, const char *, u_int32_t));
*/
int
! __log_add_logid(logp, dbp, name, ndx)
DB_LOG *logp;
DB *dbp;
+ const char *name;
u_int32_t ndx;
{
u_int32_t i;
***************
*** 244,260 ****
--- 282,308 ----
for (i = logp->dbentry_cnt; i < ndx + DB_GROW_SIZE; i++) {
logp->dbentry[i].dbp = NULL;
logp->dbentry[i].deleted = 0;
+ logp->dbentry[i].name = NULL;
}
logp->dbentry_cnt = i;
}
+ /* Make space for the name and copy it in. */
+ if (name != NULL) {
+ if ((ret = __os_malloc(strlen(name) + 1,
+ NULL, &logp->dbentry[ndx].name)) != 0)
+ goto err;
+ strcpy(logp->dbentry[ndx].name, name);
+ }
+
if (logp->dbentry[ndx].deleted == 0 && logp->dbentry[ndx].dbp == NULL) {
logp->dbentry[ndx].dbp = dbp;
logp->dbentry[ndx].refcount = 1;
logp->dbentry[ndx].deleted = dbp == NULL;
} else
logp->dbentry[ndx].refcount++;
+
err: UNLOCK_LOGTHREAD(logp);
return (ret);
*** log/log_register.c.orig Mon Apr 12 12:07:24 1999
--- log/log_register.c Wed Aug 11 15:48:14 1999
***************
*** 117,123 ****
if ((ret = __log_register_log(dblp, NULL, &r_unused,
0, LOG_OPEN, &r_name, &fid_dbt, fnp->id, type)) != 0)
goto err;
! if ((ret = __log_add_logid(dblp, dbp, fnp->id)) != 0)
goto err;
}
--- 117,123 ----
if ((ret = __log_register_log(dblp, NULL, &r_unused,
0, LOG_OPEN, &r_name, &fid_dbt, fnp->id, type)) != 0)
goto err;
! if ((ret = __log_add_logid(dblp, dbp, name, fnp->id)) != 0)
goto err;
}
-
Change file descriptor usage to permit Sendmail's fcntl(2) locking scheme.
*** include/db.h.orig Mon Aug 2 13:13:13 1999
--- include/db.h Mon Aug 2 13:15:57 1999
***************
*** 199,204 ****
--- 199,205 ----
#define DB_SEQUENTIAL 0x008000 /* Sequential access (internal). */
#define DB_TEMPORARY 0x010000 /* Remove on last close (internal). */
#define DB_TRUNCATE 0x020000 /* O_TRUNCATE: replace existing DB. */
+ #define DB_FCNTL_LOCKING 0x040000 /* Undocumented: fcntl(2) locking. */
/*
* Deadlock detector modes; used in the DBENV structure to configure the
***************
*** 405,410 ****
--- 406,412 ----
/* Documented, returned information. */
DBTYPE type; /* DB access method. */
int byteswapped; /* Database byte order is swapped. */
+ int saved_open_fd; /* For fcntl lock preservation. */
DB_ENV *dbenv; /* DB_ENV structure. */
DB_ENV *mp_dbenv; /* DB_ENV for local mpool creation. */
*** build_win32/db.h.orig Tue Aug 31 13:40:16 1999
--- build_win32/db.h Tue Aug 31 13:40:26 1999
***************
*** 202,207 ****
--- 202,208 ----
#define DB_SEQUENTIAL 0x008000 /* Sequential access (internal). */
#define DB_TEMPORARY 0x010000 /* Remove on last close (internal). */
#define DB_TRUNCATE 0x020000 /* O_TRUNCATE: replace existing DB. */
+ #define DB_FCNTL_LOCKING 0x040000 /* Undocumented: fcntl(2) locking. */
/*
* Deadlock detector modes; used in the DBENV structure to configure the
***************
*** 408,413 ****
--- 409,415 ----
/* Documented, returned information. */
DBTYPE type; /* DB access method. */
int byteswapped; /* Database byte order is swapped. */
+ int saved_open_fd; /* For fcntl lock preservation. */
DB_ENV *dbenv; /* DB_ENV structure. */
DB_ENV *mp_dbenv; /* DB_ENV for local mpool creation. */
*** build_vms/db.h.orig Tue Aug 31 13:41:09 1999
--- build_vms/db.h Tue Aug 31 13:41:18 1999
***************
*** 196,201 ****
--- 196,202 ----
#define DB_SEQUENTIAL 0x008000 /* Sequential access (internal). */
#define DB_TEMPORARY 0x010000 /* Remove on last close (internal). */
#define DB_TRUNCATE 0x020000 /* O_TRUNCATE: replace existing DB. */
+ #define DB_FCNTL_LOCKING 0x040000 /* Undocumented: fcntl(2) locking. */
/*
* Deadlock detector modes; used in the DBENV structure to configure the
***************
*** 402,407 ****
--- 403,409 ----
/* Documented, returned information. */
DBTYPE type; /* DB access method. */
int byteswapped; /* Database byte order is swapped. */
+ int saved_open_fd; /* For fcntl lock preservation. */
DB_ENV *dbenv; /* DB_ENV structure. */
DB_ENV *mp_dbenv; /* DB_ENV for local mpool creation. */
*** build_win16/db.h.orig Tue Aug 31 13:41:58 1999
--- build_win16/db.h Tue Aug 31 13:42:03 1999
***************
*** 202,207 ****
--- 202,208 ----
#define DB_SEQUENTIAL 0x008000 /* Sequential access (internal). */
#define DB_TEMPORARY 0x010000 /* Remove on last close (internal). */
#define DB_TRUNCATE 0x020000 /* O_TRUNCATE: replace existing DB. */
+ #define DB_FCNTL_LOCKING 0x040000 /* Undocumented: fcntl(2) locking. */
/*
* Deadlock detector modes; used in the DBENV structure to configure the
***************
*** 408,413 ****
--- 409,415 ----
/* Documented, returned information. */
DBTYPE type; /* DB access method. */
int byteswapped; /* Database byte order is swapped. */
+ int saved_open_fd; /* For fcntl lock preservation. */
DB_ENV *dbenv; /* DB_ENV structure. */
DB_ENV *mp_dbenv; /* DB_ENV for local mpool creation. */
*** db/db.c.orig Wed Aug 18 13:05:35 1999
--- db/db.c Wed Aug 18 13:18:01 1999
***************
*** 113,121 ****
/* Validate arguments. */
#ifdef HAVE_SPINLOCKS
! #define OKFLAGS (DB_CREATE | DB_NOMMAP | DB_RDONLY | DB_THREAD | DB_TRUNCATE)
#else
! #define OKFLAGS (DB_CREATE | DB_NOMMAP | DB_RDONLY | DB_TRUNCATE)
#endif
if ((ret = __db_fchk(dbenv, "db_open", flags, OKFLAGS)) != 0)
return (ret);
--- 113,121 ----
/* Validate arguments. */
#ifdef HAVE_SPINLOCKS
! #define OKFLAGS (DB_CREATE | DB_FCNTL_LOCKING | DB_NOMMAP | DB_RDONLY | DB_THREAD | DB_TRUNCATE)
#else
! #define OKFLAGS (DB_CREATE | DB_FCNTL_LOCKING | DB_NOMMAP | DB_RDONLY | DB_TRUNCATE)
#endif
if ((ret = __db_fchk(dbenv, "db_open", flags, OKFLAGS)) != 0)
return (ret);
***************
*** 143,158 ****
}
}
- /* Initialize for error return. */
- fd = -1;
- need_fileid = 1;
- real_name = NULL;
-
/* Allocate the DB structure, reference the DB_ENV structure. */
if ((ret = __os_calloc(1, sizeof(DB), &dbp)) != 0)
return (ret);
dbp->dbenv = dbenv;
/* Random initialization. */
TAILQ_INIT(&dbp->free_queue);
TAILQ_INIT(&dbp->active_queue);
--- 143,158 ----
}
}
/* Allocate the DB structure, reference the DB_ENV structure. */
if ((ret = __os_calloc(1, sizeof(DB), &dbp)) != 0)
return (ret);
dbp->dbenv = dbenv;
+ /* Initialize for error return. */
+ dbp->saved_open_fd = fd = -1;
+ need_fileid = 1;
+ real_name = NULL;
+
/* Random initialization. */
TAILQ_INIT(&dbp->free_queue);
TAILQ_INIT(&dbp->active_queue);
***************
*** 330,337 ****
if ((ret = __os_read(fd, mbuf, sizeof(mbuf), &nr)) != 0)
goto err;
! /* The fd is no longer needed. */
! (void)__os_close(fd);
fd = -1;
if (nr != sizeof(mbuf)) {
--- 330,339 ----
if ((ret = __os_read(fd, mbuf, sizeof(mbuf), &nr)) != 0)
goto err;
! if (LF_ISSET(DB_FCNTL_LOCKING))
! dbp->saved_open_fd = fd;
! else
! (void)__os_close(fd);
fd = -1;
if (nr != sizeof(mbuf)) {
***************
*** 762,767 ****
--- 764,774 ----
if (F_ISSET(dbp, DB_AM_MLOCAL) &&
(t_ret = memp_close(dbp->mp)) != 0 && ret == 0)
ret = t_ret;
+
+ if (dbp->saved_open_fd != -1) {
+ (void)__os_close(dbp->saved_open_fd);
+ dbp->saved_open_fd = -1;
+ }
/* Discard the log file id. */
if (F_ISSET(dbp, DB_AM_LOGGING))
-
Fix ANSI C++ usage to avoid GNU gcc-2.95 warning messages.
*** include/db_cxx.h.orig Thu Aug 5 10:30:10 1999
--- include/db_cxx.h Thu Aug 5 10:30:14 1999
***************
*** 300,306 ****
// no copying
DbLog(const DbLog &);
! operator = (const DbLog &);
DEFINE_DB_CLASS(DbLog);
};
--- 300,306 ----
// no copying
DbLog(const DbLog &);
! DbLog &operator = (const DbLog &);
DEFINE_DB_CLASS(DbLog);
};
***************
*** 345,351 ****
private:
// no copying
DbMpoolFile(const DbMpoolFile &);
! operator = (const DbMpoolFile &);
DEFINE_DB_CLASS(DbMpoolFile);
};
--- 345,351 ----
private:
// no copying
DbMpoolFile(const DbMpoolFile &);
! DbMpoolFile &operator = (const DbMpoolFile &);
DEFINE_DB_CLASS(DbMpoolFile);
};
***************
*** 432,438 ****
// no copying
DbTxnMgr(const DbTxnMgr &);
! operator = (const DbTxnMgr &);
DEFINE_DB_CLASS(DbTxnMgr);
};
--- 432,438 ----
// no copying
DbTxnMgr(const DbTxnMgr &);
! DbTxnMgr &operator = (const DbTxnMgr &);
DEFINE_DB_CLASS(DbTxnMgr);
};
***************
*** 461,467 ****
// no copying
DbTxn(const DbTxn &);
! operator = (const DbTxn &);
DEFINE_DB_CLASS(DbTxn);
};
--- 461,467 ----
// no copying
DbTxn(const DbTxn &);
! DbTxn &operator = (const DbTxn &);
DEFINE_DB_CLASS(DbTxn);
};
***************
*** 730,736 ****
// no copying
DbEnv(const DbEnv &);
! operator = (const DbEnv &);
ErrorModel error_model_;
static void stream_error_function(const char *, char *);
--- 730,736 ----
// no copying
DbEnv(const DbEnv &);
! DbEnv &operator = (const DbEnv &);
ErrorModel error_model_;
static void stream_error_function(const char *, char *);
-
If there are a sufficient number of threads competing for limited numbers
of pages, it's possible to split Btree pages too many times, and cause a
core dump.
*** btree/bt_split.c.orig Wed Apr 14 18:23:16 1999
--- btree/bt_split.c Wed Apr 14 18:23:16 1999
***************
*** 77,82 ****
--- 79,85 ----
DBC *dbc;
void *arg;
{
+ BTREE *t;
CURSOR *cp;
DB *dbp;
enum { UP, DOWN } dir;
***************
*** 112,117 ****
--- 115,121 ----
* split. This would be an easy change for this code, but I have no
* numbers that indicate it's worthwhile.
*/
+ t = dbp->internal;
for (dir = UP, level = LEAFLEVEL;; dir == UP ? ++level : --level) {
/*
* Acquire a page and its parent, locked.
***************
*** 122,128 ****
(db_recno_t *)arg, S_WRPAIR, level, &exact))) != 0)
return (ret);
! /* Split the page. */
ret = cp->csp[0].page->pgno == PGNO_ROOT ?
__bam_root(dbc, &cp->csp[0]) :
__bam_page(dbc, &cp->csp[-1], &cp->csp[0]);
--- 126,142 ----
(db_recno_t *)arg, S_WRPAIR, level, &exact))) != 0)
return (ret);
! /*
! * Split the page if it still needs it (it's possible another
! * thread of control has already split the page). If we are
! * guaranteed that two items will fit on the page, the split
! * is no longer necessary.
! */
! if (t->bt_ovflsize * 2 <=
! (db_indx_t)P_FREESPACE(cp->csp[0].page)) {
! __bam_stkrel(dbc, 1);
! return (0);
! }
ret = cp->csp[0].page->pgno == PGNO_ROOT ?
__bam_root(dbc, &cp->csp[0]) :
__bam_page(dbc, &cp->csp[-1], &cp->csp[0]);
-
Fix a case where it was possible for EAGAIN to not be returned from the
database get-by-key interface.
*** db/db_am.c.orig Tue May 18 14:09:25 1999
--- db/db_am.c Fri May 21 11:14:09 1999
***************
*** 388,394 ****
F_SET(&tdata, DB_DBT_USERMEM | DB_DBT_PARTIAL);
if ((ret = dbc->c_get(dbc, key, &tdata, DB_SET | DB_RMW)) == 0)
ret = DB_KEYEXIST;
! else
ret = 0;
}
if (ret == 0)
--- 388,394 ----
F_SET(&tdata, DB_DBT_USERMEM | DB_DBT_PARTIAL);
if ((ret = dbc->c_get(dbc, key, &tdata, DB_SET | DB_RMW)) == 0)
ret = DB_KEYEXIST;
! else if (ret == DB_NOTFOUND)
ret = 0;
}
if (ret == 0)
-
Ignore log records not involved in transactions so that actions taken
outside of transactions are not undone during recovery.
*** db/db_dispatch.orig Mon May 24 21:37:48 1999
--- db/db_dispatch.c Mon May 24 21:40:43 1999
***************
*** 117,123 ****
* in "abort mode".
*/
if (rectype == DB_log_register || rectype == DB_txn_ckp ||
! __db_txnlist_find(info, txnid) == DB_NOTFOUND)
return ((dispatch_table[rectype])(logp,
db, lsnp, TXN_UNDO, info));
break;
--- 117,124 ----
* in "abort mode".
*/
if (rectype == DB_log_register || rectype == DB_txn_ckp ||
! (__db_txnlist_find(info, txnid) == DB_NOTFOUND &&
! txnid != 0))
return ((dispatch_table[rectype])(logp,
db, lsnp, TXN_UNDO, info));
break;
-
Fix a memory pool race during buffer discard in memory tight environments.
*** mp/mp_fput.c.orig Tue Dec 15 09:57:18 1998
--- mp/mp_fput.c Fri Aug 27 17:37:03 1999
***************
*** 119,124 ****
--- 119,131 ----
return (0);
}
+ /* Move the buffer to the head/tail of the LRU chain. */
+ SH_TAILQ_REMOVE(&mp->bhq, bhp, q, __bh);
+ if (F_ISSET(bhp, BH_DISCARD))
+ SH_TAILQ_INSERT_HEAD(&mp->bhq, bhp, q, __bh);
+ else
+ SH_TAILQ_INSERT_TAIL(&mp->bhq, bhp, q);
+
/*
* If this buffer is scheduled for writing because of a checkpoint, we
* need to write it (if we marked it dirty), or update the checkpoint
***************
*** 138,151 ****
--dbmfp->mfp->lsn_cnt;
--mp->lsn_cnt;
}
-
- /* Move the buffer to the head/tail of the LRU chain. */
- SH_TAILQ_REMOVE(&mp->bhq, bhp, q, __bh);
- if (F_ISSET(bhp, BH_DISCARD))
- SH_TAILQ_INSERT_HEAD(&mp->bhq, bhp, q, __bh);
- else
- SH_TAILQ_INSERT_TAIL(&mp->bhq, bhp, q);
-
UNLOCKREGION(dbmp);
return (0);
--- 145,150 ----
*** mp/mp_region.c.orig Fri Dec 11 14:29:42 1998
--- mp/mp_region.c Fri Aug 27 17:37:03 1999
***************
*** 137,145 ****
--- 137,147 ----
* the buffer list.
*/
if (F_ISSET(bhp, BH_DIRTY)) {
+ ++bhp->ref;
if ((ret = __memp_bhwrite(dbmp,
mfp, bhp, &restart, &wrote)) != 0)
return (ret);
+ --bhp->ref;
/*
* It's possible that another process wants this buffer
*** mp/mp_sync.c.orig Mon Apr 12 12:07:38 1999
--- mp/mp_sync.c Fri Aug 27 17:37:03 1999
***************
*** 446,451 ****
--- 446,452 ----
BH *bhp;
MPOOL *mp;
MPOOLFILE *mfp;
+ db_pgno_t pgno;
u_long total;
int ret, wrote;
***************
*** 493,498 ****
--- 494,500 ----
if (F_ISSET(mfp, MP_TEMP))
continue;
+ pgno = bhp->pgno;
if ((ret = __memp_bhwrite(dbmp, mfp, bhp, NULL, &wrote)) != 0)
goto err;
***************
*** 503,509 ****
*/
if (!wrote) {
__db_err(dbmp->dbenv, "%s: unable to flush page: %lu",
! __memp_fns(dbmp, mfp), (u_long)bhp->pgno);
ret = EPERM;
goto err;
}
--- 505,511 ----
*/
if (!wrote) {
__db_err(dbmp->dbenv, "%s: unable to flush page: %lu",
! __memp_fns(dbmp, mfp), (u_long)pgno);
ret = EPERM;
goto err;
}
-
Update the Berkeley DB release version numbers from 2.7.5 to 2.7.7.
diff -r -c db-2.7.5/README db-2.7.7/README
*** README Sun Apr 18 21:21:03 1999
--- README Fri Aug 20 12:12:23 1999
***************
*** 1,8 ****
# @(#)README 10.72 (Sleepycat) 1/3/99
! This is version 2.7.5 (04/18/99) of Sleepycat Software's Berkeley DB
product. To view the documentation for this release, point your web
! browser at the distribution file db-2.7.5/docs/index.html.
Sleepycat Software db@sleepycat.com
394 E. Riding Dr. +1-510-526-3972
--- 1,8 ----
# @(#)README 10.72 (Sleepycat) 1/3/99
! This is version 2.7.7 (08/20/99) of Sleepycat Software's Berkeley DB
product. To view the documentation for this release, point your web
! browser at the distribution file db-2.7.7/docs/index.html.
Sleepycat Software db@sleepycat.com
394 E. Riding Dr. +1-510-526-3972
diff -r -c db-2.7.5/build_vms/db.h db-2.7.7/build_vms/db.h
*** build_vms/db.h Sun Apr 18 21:21:42 1999
--- build_vms/db.h Fri Aug 20 12:12:37 1999
***************
*** 69,76 ****
#define DB_VERSION_MAJOR 2
#define DB_VERSION_MINOR 7
! #define DB_VERSION_PATCH 5
! #define DB_VERSION_STRING "Sleepycat Software: Berkeley DB 2.7.5: (04/18/99)"
typedef u_int32_t db_pgno_t; /* Page number type. */
typedef u_int16_t db_indx_t; /* Page offset type. */
--- 69,76 ----
#define DB_VERSION_MAJOR 2
#define DB_VERSION_MINOR 7
! #define DB_VERSION_PATCH 7
! #define DB_VERSION_STRING "Sleepycat Software: Berkeley DB 2.7.7: (08/20/99)"
typedef u_int32_t db_pgno_t; /* Page number type. */
typedef u_int16_t db_indx_t; /* Page offset type. */
diff -r -c db-2.7.5/build_win16/db.h db-2.7.7/build_win16/db.h
*** build_win16/db.h Sun Apr 18 21:21:42 1999
--- build_win16/db.h Fri Aug 20 12:12:44 1999
***************
*** 75,82 ****
#define DB_VERSION_MAJOR 2
#define DB_VERSION_MINOR 7
! #define DB_VERSION_PATCH 5
! #define DB_VERSION_STRING "Sleepycat Software: Berkeley DB 2.7.5: (04/18/99)"
typedef u_int32_t db_pgno_t; /* Page number type. */
typedef u_int16_t db_indx_t; /* Page offset type. */
--- 75,82 ----
#define DB_VERSION_MAJOR 2
#define DB_VERSION_MINOR 7
! #define DB_VERSION_PATCH 7
! #define DB_VERSION_STRING "Sleepycat Software: Berkeley DB 2.7.7: (08/20/99)"
typedef u_int32_t db_pgno_t; /* Page number type. */
typedef u_int16_t db_indx_t; /* Page offset type. */
diff -r -c db-2.7.5/build_win32/db.h db-2.7.7/build_win32/db.h
*** build_win32/db.h Sun Apr 18 21:21:42 1999
--- build_win32/db.h Fri Aug 20 12:12:50 1999
***************
*** 75,82 ****
#define DB_VERSION_MAJOR 2
#define DB_VERSION_MINOR 7
! #define DB_VERSION_PATCH 5
! #define DB_VERSION_STRING "Sleepycat Software: Berkeley DB 2.7.5: (04/18/99)"
typedef u_int32_t db_pgno_t; /* Page number type. */
typedef u_int16_t db_indx_t; /* Page offset type. */
--- 75,82 ----
#define DB_VERSION_MAJOR 2
#define DB_VERSION_MINOR 7
! #define DB_VERSION_PATCH 7
! #define DB_VERSION_STRING "Sleepycat Software: Berkeley DB 2.7.7: (08/20/99)"
typedef u_int32_t db_pgno_t; /* Page number type. */
typedef u_int16_t db_indx_t; /* Page offset type. */
diff -r -c db-2.7.5/build_win32/libdb.rc db-2.7.7/build_win32/libdb.rc
*** build_win32/libdb.rc Sun Apr 18 21:21:42 1999
--- build_win32/libdb.rc Fri Aug 20 12:12:30 1999
***************
*** 1,6 ****
1 VERSIONINFO
! FILEVERSION 2,0,7,5
! PRODUCTVERSION 2,0,7,5
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
--- 1,6 ----
1 VERSIONINFO
! FILEVERSION 2,0,7,7
! PRODUCTVERSION 2,0,7,7
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
***************
*** 18,29 ****
BEGIN
VALUE "CompanyName", "Sleepycat Software\0"
VALUE "FileDescription", "Berkeley DB 2.0 DLL\0"
! VALUE "FileVersion", "2.7.5\0"
VALUE "InternalName", "libdb.dll\0"
VALUE "LegalCopyright", "Copyright © Sleepycat Software Inc. 1997, 1998\0"
VALUE "OriginalFilename", "libdb.dll\0"
VALUE "ProductName", "Sleepycat Software libdb\0"
! VALUE "ProductVersion", "2.7.5\0"
END
END
BLOCK "VarFileInfo"
--- 18,29 ----
BEGIN
VALUE "CompanyName", "Sleepycat Software\0"
VALUE "FileDescription", "Berkeley DB 2.0 DLL\0"
! VALUE "FileVersion", "2.7.7\0"
VALUE "InternalName", "libdb.dll\0"
VALUE "LegalCopyright", "Copyright © Sleepycat Software Inc. 1997, 1998\0"
VALUE "OriginalFilename", "libdb.dll\0"
VALUE "ProductName", "Sleepycat Software libdb\0"
! VALUE "ProductVersion", "2.7.7\0"
END
END
BLOCK "VarFileInfo"
diff -r -c db-2.7.5/docs/index.html db-2.7.7/docs/index.html
*** docs/index.html Sun Apr 18 21:20:14 1999
--- docs/index.html Fri Aug 20 12:12:05 1999
***************
*** 10,16 ****
<p><br><p>
! <h1><b>Berkeley DB: version 2.7.5, 04/18/99</b></h1>
<hr size=1 noshade>
--- 10,16 ----
<p><br><p>
! <h1><b>Berkeley DB: version 2.7.7, 08/20/99</b></h1>
<hr size=1 noshade>
diff -r -c db-2.7.5/include/db.h db-2.7.7/include/db.h
*** include/db.h Sun Apr 18 21:20:41 1999
--- include/db.h Fri Aug 20 12:12:11 1999
***************
*** 72,79 ****
#define DB_VERSION_MAJOR 2
#define DB_VERSION_MINOR 7
! #define DB_VERSION_PATCH 5
! #define DB_VERSION_STRING "Sleepycat Software: Berkeley DB 2.7.5: (04/18/99)"
typedef u_int32_t db_pgno_t; /* Page number type. */
typedef u_int16_t db_indx_t; /* Page offset type. */
--- 72,79 ----
#define DB_VERSION_MAJOR 2
#define DB_VERSION_MINOR 7
! #define DB_VERSION_PATCH 7
! #define DB_VERSION_STRING "Sleepycat Software: Berkeley DB 2.7.7: (08/20/99)"
typedef u_int32_t db_pgno_t; /* Page number type. */
typedef u_int16_t db_indx_t; /* Page offset type. */