|
Panu Matilainen |
e3501f |
commit 452553111b9929074bcbb77a49c041582daae0e8
|
|
Panu Matilainen |
e3501f |
Author: Panu Matilainen <pmatilai@redhat.com>
|
|
Panu Matilainen |
e3501f |
Date: Tue Feb 5 10:11:19 2013 +0200
|
|
Panu Matilainen |
e3501f |
|
|
Panu Matilainen |
e3501f |
Check for stale db locks when opening write-cursors
|
|
Panu Matilainen |
e3501f |
|
|
Panu Matilainen |
e3501f |
- During long-running transactions its entirely possible for some
|
|
Panu Matilainen |
e3501f |
other player to come and go leaving stale locks behind and cause
|
|
Panu Matilainen |
e3501f |
the transaction to get stuck until the cavalry comes along in the
|
|
Panu Matilainen |
e3501f |
form of somebody else opening the rpmdb, clearing the blockage.
|
|
Panu Matilainen |
e3501f |
- Presumably dbenv->failchk() is not entirely free of cost so we only
|
|
Panu Matilainen |
e3501f |
do this for writes which are way more critical and also more prone to
|
|
Panu Matilainen |
e3501f |
getting stuck.
|
|
Panu Matilainen |
e3501f |
- dbenv->failchk() could return DB_RUNRECOVER in which case we should
|
|
Panu Matilainen |
e3501f |
abort everything but we lack a mechanism to do it... just add
|
|
Panu Matilainen |
e3501f |
a reminder comment for now.
|
|
Panu Matilainen |
e3501f |
|
|
Panu Matilainen |
e3501f |
diff --git a/lib/backend/db3.c b/lib/backend/db3.c
|
|
Panu Matilainen |
e3501f |
index 656486b..de8071b 100644
|
|
Panu Matilainen |
e3501f |
--- a/lib/backend/db3.c
|
|
Panu Matilainen |
e3501f |
+++ b/lib/backend/db3.c
|
|
Panu Matilainen |
e3501f |
@@ -248,7 +248,7 @@ dbiCursor dbiCursorInit(dbiIndex dbi, unsigned int flags)
|
|
Panu Matilainen |
e3501f |
DB * db = dbi->dbi_db;
|
|
Panu Matilainen |
e3501f |
DBC * cursor;
|
|
Panu Matilainen |
e3501f |
int cflags;
|
|
Panu Matilainen |
e3501f |
- int rc;
|
|
Panu Matilainen |
e3501f |
+ int rc = 0;
|
|
Panu Matilainen |
e3501f |
uint32_t eflags = db_envflags(db);
|
|
Panu Matilainen |
e3501f |
|
|
Panu Matilainen |
e3501f |
/* DB_WRITECURSOR requires CDB and writable db */
|
|
Panu Matilainen |
e3501f |
@@ -259,8 +259,23 @@ dbiCursor dbiCursorInit(dbiIndex dbi, unsigned int flags)
|
|
Panu Matilainen |
e3501f |
} else
|
|
Panu Matilainen |
e3501f |
cflags = 0;
|
|
Panu Matilainen |
e3501f |
|
|
Panu Matilainen |
e3501f |
- rc = db->cursor(db, NULL, &cursor, cflags);
|
|
Panu Matilainen |
e3501f |
- rc = cvtdberr(dbi, "db->cursor", rc, _debug);
|
|
Panu Matilainen |
e3501f |
+ /*
|
|
Panu Matilainen |
e3501f |
+ * Check for stale locks which could block writes "forever".
|
|
Panu Matilainen |
e3501f |
+ * XXX: Should we also do this on reads? Reads are less likely
|
|
Panu Matilainen |
e3501f |
+ * to get blocked so it seems excessive...
|
|
Panu Matilainen |
e3501f |
+ * XXX: On DB_RUNRECOVER, we should abort everything. Now
|
|
Panu Matilainen |
e3501f |
+ * we'll just fail to open a cursor again and again and again.
|
|
Panu Matilainen |
e3501f |
+ */
|
|
Panu Matilainen |
e3501f |
+ if (cflags & DB_WRITECURSOR) {
|
|
Panu Matilainen |
e3501f |
+ DB_ENV *dbenv = db->get_env(db);
|
|
Panu Matilainen |
e3501f |
+ rc = dbenv->failchk(dbenv, 0);
|
|
Panu Matilainen |
e3501f |
+ rc = cvtdberr(dbi, "dbenv->failchk", rc, _debug);
|
|
Panu Matilainen |
e3501f |
+ }
|
|
Panu Matilainen |
e3501f |
+
|
|
Panu Matilainen |
e3501f |
+ if (rc == 0) {
|
|
Panu Matilainen |
e3501f |
+ rc = db->cursor(db, NULL, &cursor, cflags);
|
|
Panu Matilainen |
e3501f |
+ rc = cvtdberr(dbi, "db->cursor", rc, _debug);
|
|
Panu Matilainen |
e3501f |
+ }
|
|
Panu Matilainen |
e3501f |
|
|
Panu Matilainen |
e3501f |
if (rc == 0) {
|
|
Panu Matilainen |
e3501f |
dbc = xcalloc(1, sizeof(*dbc));
|