]> git.sur5r.net Git - openldap/commitdiff
Add mdb_reader_list()
authorHoward Chu <hyc@symas.com>
Thu, 18 Jul 2013 14:41:11 +0000 (07:41 -0700)
committerHoward Chu <hyc@symas.com>
Thu, 18 Jul 2013 14:45:12 +0000 (07:45 -0700)
Dump the active slots in the reader table.

libraries/liblmdb/lmdb.h
libraries/liblmdb/mdb.c
libraries/liblmdb/mdb_stat.1
libraries/liblmdb/mdb_stat.c

index c38c7dbf8fc7923722209112898de9b4399f88b4..af046d19c8c7d5574952be11e80acc0744370fa1 100644 (file)
@@ -1298,6 +1298,23 @@ int  mdb_cmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b);
         * @return < 0 if a < b, 0 if a == b, > 0 if a > b
         */
 int  mdb_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b);
+
+       /** @brief A callback function used to print a message from the library.
+        *
+        * @param[in] msg The string to be printed.
+        * @param[in] ctx An arbitrary context pointer for the callback.
+        * @return < 0 on failure, 0 on success.
+        */
+typedef int (MDB_msg_func)(const char *msg, void *ctx);
+
+       /** @brief Dump the entries in the reader lock table.
+        *
+        * @param[in] env An environment handle returned by #mdb_env_create()
+        * @param[in] func A #MDB_msg_func function
+        * @param[in] ctx Anything the message function needs
+        * @return < 0 on failure, 0 on success.
+        */
+int    mdb_reader_list(MDB_env *env, MDB_msg_func *func, void *ctx);
 /**    @} */
 
 #ifdef __cplusplus
index f895c0fb5e2529e0a940747d5db132f3be38dda0..f86ec356b6f6845c3a2de0d8c261dac6c42de1e5 100644 (file)
@@ -7916,4 +7916,39 @@ int mdb_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx)
        return MDB_SUCCESS;
 }
 
+int mdb_reader_list(MDB_env *env, MDB_msg_func *func, void *ctx)
+{
+       unsigned int i, rdrs;
+       MDB_reader *mr;
+       char buf[128];
+       int first = 1;
+
+       if (!env || !func)
+               return -1;
+       if (!env->me_txns) {
+               return func("No reader locks\n", ctx);
+       }
+       rdrs = env->me_numreaders;
+       mr = env->me_txns->mti_readers;
+       for (i=0; i<rdrs; i++) {
+               if (mr[i].mr_pid) {
+                       size_t tid;
+                       int rc;
+                       tid = mr[i].mr_tid;
+                       if (mr[i].mr_txnid == (txnid_t)-1) {
+                               sprintf(buf, "%10d %zx -\n", mr[i].mr_pid, tid);
+                       } else {
+                               sprintf(buf, "%10d %zx %zu\n", mr[i].mr_pid, tid, mr[i].mr_txnid);
+                       }
+                       if (first) {
+                               first = 0;
+                               func("    pid     thread     txnid\n", ctx);
+                       }
+                       rc = func(buf, ctx);
+                       if (rc < 0)
+                               return rc;
+               }
+       }
+       return 0;
+}
 /** @} */
index 1307c39d09fee383706ead72ba6b4f93766ac03f..f3431922ec743ed9fabebe44f1f4580d4d69075e 100644 (file)
@@ -13,6 +13,8 @@ mdb_stat \- LMDB environment status tool
 [\c
 .BR \-n ]
 [\c
+.BR \-r ]
+[\c
 .BR \-a \ |
 .BI \-s \ subdb\fR]
 .SH DESCRIPTION
@@ -32,6 +34,13 @@ If \fB\-fff\fP is given, display the full list of page IDs in the freelist.
 .BR \-n
 Display the status of an LMDB database which does not use subdirectories.
 .TP
+.BR \-r
+Display information about the environment reader table.
+Shows the process ID, thread ID, and transaction ID for each active
+reader slot. The process ID and transaction ID are in decimal, the
+thread ID is in hexadecimal. The transaction ID is displayed as "-"
+if the reader does not currently have a read transaction open.
+.TP
 .BR \-a
 Display the status of all of the subdatabases in the environment.
 .TP
index 3e6be21597ed36de0e7bf0f600bfca4f8dca9bea..5a0946683df1abc1678e4a6f6fd261425d42a6bd 100644 (file)
@@ -31,7 +31,7 @@ static void prstat(MDB_stat *ms)
 
 static void usage(char *prog)
 {
-       fprintf(stderr, "usage: %s dbpath [-e] [-f[f[f]]] [-n] [-a|-s subdb]\n", prog);
+       fprintf(stderr, "usage: %s dbpath [-e] [-f[f[f]]] [-n] [-a|-s subdb] [-r]\n", prog);
        exit(EXIT_FAILURE);
 }
 
@@ -46,7 +46,7 @@ int main(int argc, char *argv[])
        char *prog = argv[0];
        char *envname;
        char *subname = NULL;
-       int alldbs = 0, envinfo = 0, envflags = 0, freinfo = 0;
+       int alldbs = 0, envinfo = 0, envflags = 0, freinfo = 0, rdrinfo = 0;
 
        if (argc < 2) {
                usage(prog);
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
         * -n: use NOSUBDIR flag on env_open
         * (default) print stat of only the main DB
         */
-       while ((i = getopt(argc, argv, "aefns:")) != EOF) {
+       while ((i = getopt(argc, argv, "aefnrs:")) != EOF) {
                switch(i) {
                case 'a':
                        if (subname)
@@ -75,6 +75,9 @@ int main(int argc, char *argv[])
                case 'n':
                        envflags |= MDB_NOSUBDIR;
                        break;
+               case 'r':
+                       rdrinfo++;
+                       break;
                case 's':
                        if (alldbs)
                                usage(prog);
@@ -120,6 +123,11 @@ int main(int argc, char *argv[])
                printf("  Number of readers used: %u\n", mei.me_numreaders);
        }
 
+       if (rdrinfo) {
+               printf("Reader Table Status\n");
+               rc = mdb_reader_list(env, (MDB_msg_func *)fputs, stdout);
+       }
+
        if (freinfo) {
                MDB_cursor *cursor;
                MDB_val key, data;