about summary refs log tree commit diff
path: root/db2/progs/db_printlog
diff options
context:
space:
mode:
Diffstat (limited to 'db2/progs/db_printlog')
-rw-r--r--db2/progs/db_printlog/README22
-rw-r--r--db2/progs/db_printlog/commit.awk7
-rw-r--r--db2/progs/db_printlog/count.awk9
-rw-r--r--db2/progs/db_printlog/db_printlog.c83
-rw-r--r--db2/progs/db_printlog/pgno.awk43
-rw-r--r--db2/progs/db_printlog/range.awk27
-rw-r--r--db2/progs/db_printlog/status.awk26
-rw-r--r--db2/progs/db_printlog/txn.awk30
8 files changed, 220 insertions, 27 deletions
diff --git a/db2/progs/db_printlog/README b/db2/progs/db_printlog/README
new file mode 100644
index 0000000000..05051f33cd
--- /dev/null
+++ b/db2/progs/db_printlog/README
@@ -0,0 +1,22 @@
+# @(#)README	10.3 (Sleepycat) 11/1/98
+
+Berkeley DB log dump utility.  This utility dumps out a DB log in human
+readable form, a record at a time, to assist in recovery and transaction
+abort debugging.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+commit.awk	Output transaction ID of committed transactions.
+
+count.awk	Print out the number of log records for transactions
+		that we encountered.
+
+pgno.awk	Take a comma-separated list of page numbers and spit
+		out all the log records that affect those page numbers.
+
+range.awk	Print out a range of the log.
+
+status.awk	Read through db_printlog output and list the transactions
+		encountered, and whether they commited or aborted.
+
+txn.awk		Print out all the records for a comma-separated list of
+		transaction IDs.
diff --git a/db2/progs/db_printlog/commit.awk b/db2/progs/db_printlog/commit.awk
new file mode 100644
index 0000000000..711064bb00
--- /dev/null
+++ b/db2/progs/db_printlog/commit.awk
@@ -0,0 +1,7 @@
+# @(#)commit.awk	10.1 (Sleepycat) 11/1/98
+#
+# Output tid of committed transactions.
+
+/txn_regop/ {
+	print $5
+}
diff --git a/db2/progs/db_printlog/count.awk b/db2/progs/db_printlog/count.awk
new file mode 100644
index 0000000000..a0b214a6ff
--- /dev/null
+++ b/db2/progs/db_printlog/count.awk
@@ -0,0 +1,9 @@
+# @(#)count.awk	10.1 (Sleepycat) 11/1/98
+#
+# Print out the number of log records for transactions that we
+# encountered.
+
+/^\[/{
+	if ($5 != 0)
+		print $5
+}
diff --git a/db2/progs/db_printlog/db_printlog.c b/db2/progs/db_printlog/db_printlog.c
index 3b48ad9643..5a0c2ebd9f 100644
--- a/db2/progs/db_printlog/db_printlog.c
+++ b/db2/progs/db_printlog/db_printlog.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1996, 1997, 1998\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_printlog.c	10.12 (Sleepycat) 4/10/98";
+static const char sccsid[] = "@(#)db_printlog.c	10.17 (Sleepycat) 11/1/98";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -19,6 +19,7 @@ static const char sccsid[] = "@(#)db_printlog.c	10.12 (Sleepycat) 4/10/98";
 
 #include <errno.h>
 #include <signal.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -37,6 +38,7 @@ static const char sccsid[] = "@(#)db_printlog.c	10.12 (Sleepycat) 4/10/98";
 DB_ENV *db_init __P((char *));
 int	main __P((int, char *[]));
 void	onint __P((int));
+void	siginit __P((void));
 void	usage __P((void));
 
 int	 interrupted;
@@ -53,15 +55,19 @@ main(argc, argv)
 	DB_ENV *dbenv;
 	DBT data;
 	DB_LSN key;
-	int ch, eval;
+	int ch, ret;
 	char *home;
 
+	ret = 0;
 	home = NULL;
-	while ((ch = getopt(argc, argv, "h:")) != EOF)
+	while ((ch = getopt(argc, argv, "h:N")) != EOF)
 		switch (ch) {
 		case 'h':
 			home = optarg;
 			break;
+		case 'N':
+			(void)db_value_set(0, DB_MUTEXLOCKS);
+			break;
 		case '?':
 		default:
 			usage();
@@ -69,54 +75,62 @@ main(argc, argv)
 	argc -= optind;
 	argv += optind;
 
-	if ((home != NULL && argc > 0) || argc > 1)
+	if (argc > 0)
 		usage();
 
-	/* XXX: backward compatibility, first argument is home. */
-	if (argc == 1)
-		home = argv[0];
-
+	/* Initialize the environment. */
+	siginit();
 	dbenv = db_init(home);
 
-	eval = 0;
 	if ((errno = __bam_init_print(dbenv)) != 0 ||
 	    (errno = __db_init_print(dbenv)) != 0 ||
 	    (errno = __ham_init_print(dbenv)) != 0 ||
 	    (errno = __log_init_print(dbenv)) != 0 ||
 	    (errno = __txn_init_print(dbenv)) != 0) {
 		warn("initialization");
-		eval = 1;
 		(void)db_appexit(dbenv);
+		return (1);
 	}
 
-	(void)signal(SIGINT, onint);
-
 	memset(&data, 0, sizeof(data));
 	while (!interrupted) {
 		if ((errno =
 		    log_get(dbenv->lg_info, &key, &data, DB_NEXT)) != 0) {
 			if (errno == DB_NOTFOUND)
 				break;
-			eval = 1;
 			warn("log_get");
-			break;
+			goto err;
 		}
-		if ((errno =
-		    __db_dispatch(dbenv->lg_info, &data, &key, 0, NULL)) != 0) {
-			eval = 1;
+		if (dbenv->tx_recover != NULL)
+			errno = dbenv->tx_recover(dbenv->lg_info,
+			    &data, &key, 0, NULL);
+		else
+			errno = __db_dispatch(dbenv->lg_info,
+			    &data, &key, 0, NULL);
+
+		fflush(stdout);
+		if (errno != 0) {
 			warn("dispatch");
-			break;
+			goto err;
 		}
 	}
 
-	(void)db_appexit(dbenv);
+	if (0) {
+err:		ret = 1;
+	}
+
+	if (dbenv != NULL && (errno = db_appexit(dbenv)) != 0) {
+		ret = 1;
+		warn(NULL);
+	}
 
 	if (interrupted) {
-		(void)signal(SIGINT, SIG_DFL);
-		(void)raise(SIGINT);
+		(void)signal(interrupted, SIG_DFL);
+		(void)raise(interrupted);
 		/* NOTREACHED */
 	}
-	return (eval);
+
+	return (ret);
 }
 
 /*
@@ -143,21 +157,36 @@ db_init(home)
 }
 
 /*
- * oninit --
+ * siginit --
+ *	Initialize the set of signals for which we want to clean up.
+ *	Generally, we try not to leave the shared regions locked if
+ *	we can.
+ */
+void
+siginit()
+{
+#ifdef SIGHUP
+	(void)signal(SIGHUP, onint);
+#endif
+	(void)signal(SIGINT, onint);
+	(void)signal(SIGTERM, onint);
+}
+
+/*
+ * onint --
  *	Interrupt signal handler.
  */
 void
 onint(signo)
 	int signo;
 {
-	COMPQUIET(signo, 0);
-
-	interrupted = 1;
+	if ((interrupted = signo) == 0)
+		interrupted = SIGINT;
 }
 
 void
 usage()
 {
-	fprintf(stderr, "usage: db_printlog [-h home]\n");
+	fprintf(stderr, "usage: db_printlog [-N] [-h home]\n");
 	exit (1);
 }
diff --git a/db2/progs/db_printlog/pgno.awk b/db2/progs/db_printlog/pgno.awk
new file mode 100644
index 0000000000..99aa38f2b9
--- /dev/null
+++ b/db2/progs/db_printlog/pgno.awk
@@ -0,0 +1,43 @@
+# @(#)pgno.awk	10.1 (Sleepycat) 11/1/98
+#
+# Take a comma-separated list of page numbers and spit out all the
+# log records that affect those page numbers.
+
+{
+	if (NR == 1) {
+		npages = 0
+		while ((ndx = index(PGNO, ",")) != 0) {
+			pgno[npages] = substr(PGNO, 1, ndx - 1);
+			PGNO = substr(PGNO, ndx + 1, length(PGNO) - ndx);
+			npages++
+		}
+		pgno[npages] = PGNO;
+	}
+}
+/^\[/{
+	if (printme == 1) {
+		printf("%s\n", rec);
+		printme = 0
+	}
+	rec = "";
+
+	rec = $0
+}
+/^	/{
+	rec = sprintf("%s\n%s", rec, $0);
+}
+/pgno/{
+	for (i = 0; i <= npages; i++)
+		if ($2 == pgno[i])
+			printme = 1
+}
+/right/{
+	for (i = 0; i <= npages; i++)
+		if ($2 == pgno[i])
+			printme = 1
+}
+/left/{
+	for (i = 0; i <= npages; i++)
+		if ($2 == pgno[i])
+			printme = 1
+}
diff --git a/db2/progs/db_printlog/range.awk b/db2/progs/db_printlog/range.awk
new file mode 100644
index 0000000000..89c56eae52
--- /dev/null
+++ b/db2/progs/db_printlog/range.awk
@@ -0,0 +1,27 @@
+# @(#)range.awk	10.1 (Sleepycat) 11/1/98
+#
+# Print out a range of the log
+
+/^\[/{
+	l = length($1) - 1;
+	i = index($1, "]");
+	file = substr($1, 2, i - 2);
+	file += 0;
+	start = i + 2;
+	offset = substr($1, start, l - start + 1);
+	i = index(offset, "]");
+	offset = substr($1, start, i - 1);
+	offset += 0;
+
+	if ((file == START_FILE && offset >= START_OFFSET || file > START_FILE)\
+	    && (file < END_FILE || (file == END_FILE && offset < END_OFFSET)))
+		printme = 1
+	else if (file == END_FILE && offset > END_OFFSET || file > END_FILE)
+		exit
+	else
+		printme = 0
+}
+{
+	if (printme == 1)
+		print $0
+}
diff --git a/db2/progs/db_printlog/status.awk b/db2/progs/db_printlog/status.awk
new file mode 100644
index 0000000000..d97e9357b7
--- /dev/null
+++ b/db2/progs/db_printlog/status.awk
@@ -0,0 +1,26 @@
+# @(#)status.awk	10.1 (Sleepycat) 11/1/98
+#
+# Read through db_printlog output and list all the transactions encountered
+# and whether they commited or aborted.
+#
+# 1 = started
+# 2 = commited
+BEGIN {
+	cur_txn = 0
+}
+/^\[/{
+	if (status[$5] == 0) {
+		status[$5] = 1;
+		txns[cur_txn] = $5;
+		cur_txn++;
+	}
+}
+/txn_regop/ {
+	status[$5] = 2
+}
+END {
+	for (i = 0; i < cur_txn; i++) {
+		printf("%s\t%s\n",
+		    txns[i], status[txns[i]] == 1 ? "ABORT" : "COMMIT");
+	}
+}
diff --git a/db2/progs/db_printlog/txn.awk b/db2/progs/db_printlog/txn.awk
new file mode 100644
index 0000000000..c8d3bd36c8
--- /dev/null
+++ b/db2/progs/db_printlog/txn.awk
@@ -0,0 +1,30 @@
+# @(#)txn.awk	10.1 (Sleepycat) 11/1/98
+#
+# Print out all the records for a comma-separated list of transaction ids.
+{
+	if (NR == 1) {
+		ntxns = 0
+		while ((ndx = index(TXN, ",")) != 0) {
+			txn[ntxns] = substr(TXN, 1, ndx - 1);
+			TXN = substr(TXN, ndx + 1, length(TXN) - ndx);
+			ntxns++
+		}
+		txn[ntxns] = TXN;
+	}
+}
+/^\[/{
+	if (printme == 1) {
+		printf("%s\n", rec);
+		printme = 0
+	}
+	rec = "";
+
+	for (i = 0; i <= ntxns; i++)
+		if (txn[i] == $5) {
+			rec = $0
+			printme = 1
+		}
+}
+/^	/{
+	rec = sprintf("%s\n%s", rec, $0);
+}