Commit 639ed4e8 authored by Alvaro Herrera's avatar Alvaro Herrera

Add pg_xlogdump contrib program

This program relies on rm_desc backend routines and the xlogreader
infrastructure to emit human-readable rendering of WAL records.

Author: Andres Freund, with many reworks by Álvaro
Reviewed (in a much earlier version) by Peter Eisentraut
parent c0c6acdf
# contrib/pg_xlogdump/Makefile
PGFILEDESC = "pg_xlogdump"
PGAPPICON=win32
PROGRAM = pg_xlogdump
OBJS = pg_xlogdump.o compat.o xlogreader.o rmgrdesc.o \
$(RMGRDESCOBJS) $(WIN32RES)
RMGRDESCSOURCES = $(notdir $(wildcard $(top_srcdir)/src/backend/access/rmgrdesc/*desc.c))
RMGRDESCOBJS = $(patsubst %.c,%.o,$(RMGRDESCSOURCES))
EXTRA_CLEAN = $(RMGRDESCSOURCES) xlogreader.c rmgrdesc.c
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/pg_xlogdump
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
override CPPFLAGS := -DFRONTEND $(CPPFLAGS)
rmgrdesc.c xlogreader.c: % : $(top_srcdir)/src/backend/access/transam/%
rm -f $@ && $(LN_S) $< .
$(RMGRDESCSOURCES): % : $(top_srcdir)/src/backend/access/rmgrdesc/%
rm -f $@ && $(LN_S) $< .
/*-------------------------------------------------------------------------
*
* compat.c
* Reimplementations of various backend functions.
*
* Portions Copyright (c) 2012, PostgreSQL Global Development Group
*
* IDENTIFICATION
* contrib/pg_xlogdump/compat.c
*
* This file contains client-side implementations for various backend
* functions that the rm_desc functions in *desc.c files rely on.
*
*-------------------------------------------------------------------------
*/
/* ugly hack, same as in e.g pg_controldata */
#define FRONTEND 1
#include "postgres.h"
#include <time.h>
#include "utils/datetime.h"
#include "lib/stringinfo.h"
/* copied from timestamp.c */
pg_time_t
timestamptz_to_time_t(TimestampTz t)
{
pg_time_t result;
#ifdef HAVE_INT64_TIMESTAMP
result = (pg_time_t) (t / USECS_PER_SEC +
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY));
#else
result = (pg_time_t) (t +
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY));
#endif
return result;
}
/*
* Stopgap implementation of timestamptz_to_str that doesn't depend on backend
* infrastructure.
*
* XXX: The backend timestamp infrastructure should instead be split out and
* moved into src/common.
*/
const char *
timestamptz_to_str(TimestampTz dt)
{
static char buf[MAXDATELEN + 1];
static char ts[MAXDATELEN + 1];
static char zone[MAXDATELEN + 1];
pg_time_t result = timestamptz_to_time_t(dt);
struct tm *ltime = localtime(&result);
strftime(ts, sizeof(zone), "%Y-%m-%d %H:%M:%S", ltime);
strftime(zone, sizeof(zone), "%Z", ltime);
#ifdef HAVE_INT64_TIMESTAMP
sprintf(buf, "%s.%06d %s", ts, (int)(dt % USECS_PER_SEC), zone);
#else
sprintf(buf, "%s.%.6f %s", ts, fabs(dt - floor(dt)), zone);
#endif
return buf;
}
/*
* Provide a hacked up compat layer for StringInfos so xlog desc functions can
* be linked/called.
*/
void
appendStringInfo(StringInfo str, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
void
appendStringInfoString(StringInfo str, const char *string)
{
appendStringInfo(str, "%s", string);
}
void
appendStringInfoChar(StringInfo str, char ch)
{
appendStringInfo(str, "%c", ch);
}
This diff is collapsed.
/*
* rmgrdesc.c
*
* pg_xlogdump resource managers definition
*
* contrib/pg_xlogdump/rmgrdesc.c
*/
#define FRONTEND 1
#include "postgres.h"
#include "access/clog.h"
#include "access/gin.h"
#include "access/gist_private.h"
#include "access/hash.h"
#include "access/heapam_xlog.h"
#include "access/multixact.h"
#include "access/nbtree.h"
#include "access/rmgr.h"
#include "access/spgist.h"
#include "access/xact.h"
#include "access/xlog_internal.h"
#include "catalog/storage_xlog.h"
#include "commands/dbcommands.h"
#include "commands/sequence.h"
#include "commands/tablespace.h"
#include "rmgrdesc.h"
#include "storage/standby.h"
#include "utils/relmapper.h"
#define PG_RMGR(symname,name,redo,desc,startup,cleanup,restartpoint) \
{ name, desc, },
const RmgrDescData RmgrDescTable[RM_MAX_ID + 1] = {
#include "access/rmgrlist.h"
};
/*
* rmgrdesc.h
*
* pg_xlogdump resource managers declaration
*
* contrib/pg_xlogdump/rmgrdesc.h
*/
#ifndef RMGRDESC_H
#define RMGRDESC_H
#include "lib/stringinfo.h"
typedef struct RmgrDescData
{
const char *rm_name;
void (*rm_desc) (StringInfo buf, uint8 xl_info, char *rec);
} RmgrDescData;
extern const RmgrDescData RmgrDescTable[];
#endif /* RMGRDESC_H */
...@@ -207,5 +207,6 @@ pages. ...@@ -207,5 +207,6 @@ pages.
&pgtestfsync; &pgtestfsync;
&pgtesttiming; &pgtesttiming;
&pgupgrade; &pgupgrade;
&pgxlogdump;
</sect1> </sect1>
</appendix> </appendix>
...@@ -134,6 +134,7 @@ ...@@ -134,6 +134,7 @@
<!ENTITY pgtesttiming SYSTEM "pgtesttiming.sgml"> <!ENTITY pgtesttiming SYSTEM "pgtesttiming.sgml">
<!ENTITY pgtrgm SYSTEM "pgtrgm.sgml"> <!ENTITY pgtrgm SYSTEM "pgtrgm.sgml">
<!ENTITY pgupgrade SYSTEM "pgupgrade.sgml"> <!ENTITY pgupgrade SYSTEM "pgupgrade.sgml">
<!ENTITY pgxlogdump SYSTEM "pg_xlogdump.sgml">
<!ENTITY postgres-fdw SYSTEM "postgres-fdw.sgml"> <!ENTITY postgres-fdw SYSTEM "postgres-fdw.sgml">
<!ENTITY seg SYSTEM "seg.sgml"> <!ENTITY seg SYSTEM "seg.sgml">
<!ENTITY contrib-spi SYSTEM "contrib-spi.sgml"> <!ENTITY contrib-spi SYSTEM "contrib-spi.sgml">
......
<!--
doc/src/sgml/ref/pg_xlogdump.sgml
PostgreSQL documentation
-->
<refentry id="pg_xlogdump">
<refmeta>
<refentrytitle><application>pg_xlogdump</application></refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo>Application</refmiscinfo>
</refmeta>
<refnamediv>
<refname>pg_xlogdump</refname>
<refpurpose>Display a human-readable rendering of the write-ahead log of a <productname>PostgreSQL</productname> database cluster</refpurpose>
</refnamediv>
<indexterm zone="pg_xlogdump">
<primary>pg_xlogdump</primary>
</indexterm>
<refsynopsisdiv>
<cmdsynopsis>
<command>pg_xlogdump</command>
<arg rep="repeat" choice="opt"><option>option</option></arg>
<arg choice="opt"><option>startseg</option>
<arg choice="opt"><option>endseg</option></arg>
</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1 id="R1-APP-PGXLOGDUMP-1">
<title>Description</title>
<para>
<command>pg_xlogdump</command> display the write-ahead log (WAL) and is mainly
useful for debugging or educational purposes.
</para>
<para>
This utility can only be run by the user who installed the server, because
it requires read-only access to the data directory.
</para>
</refsect1>
<refsect1>
<title>Options</title>
<para>
The following command-line options control the location and format of the
output:
<variablelist>
<varlistentry>
<term><replaceable class="parameter">startseg</replaceable></term>
<listitem>
<para>
Start reading at the specified log segment file. This implicitly determines
the path in which files will be searched for, and the timeline to use.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">endseg</replaceable></term>
<listitem>
<para>
Stop after reading the specified log segment file.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-b</option></term>
<term><option>--bkp-details</option></term>
<listitem>
<para>
Output detailed information about backup blocks.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-e <replaceable>end</replaceable></option></term>
<term><option>--end=<replaceable>end</replaceable></option></term>
<listitem>
<para>
Stop reading at the specified log position, instead of reading to the
end of the log stream.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-n <replaceable>limit</replaceable></option></term>
<term><option>--limit=<replaceable>limit</replaceable></option></term>
<listitem>
<para>
Display the specified number of records, then stop.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-p <replaceable>path</replaceable></option></term>
<term><option>--path=<replaceable>path</replaceable></option></term>
<listitem>
<para>
Directory in which to find log segment files. The default is to search
for them in the <literal>pg_xlog</literal> subdirectory of the current
directory.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-r <replaceable>rmgr</replaceable></option></term>
<term><option>--rmgr=<replaceable>rmgr</replaceable></option></term>
<listitem>
<para>
Only display records generated by the specified resource manager.
If <literal>list</> is passed as name, print a list of valid resource manager
names, and exit.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-s <replaceable>start</replaceable></option></term>
<term><option>--start=<replaceable>start</replaceable></option></term>
<listitem>
<para>
Log position at which to start reading. The default is to start reading
the first valid log record found in the earliest file found.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-t <replaceable>timeline</replaceable></option></term>
<term><option>--timelime=<replaceable>timeline</replaceable></option></term>
<listitem>
<para>
Timeline from which to read log records. The default is to use the
value in <literal>startseg</>, if that is specified; otherwise, the
default is 1.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-V</></term>
<term><option>--version</></term>
<listitem>
<para>
Print the <application>pg_xlogdump</application> version and exit.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-x <replaceable>xid</replaceable></option></term>
<term><option>--xid=<replaceable>xid</replaceable></option></term>
<listitem>
<para>
Only display records marked with the given TransactionId.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-?</></term>
<term><option>--help</></term>
<listitem>
<para>
Show help about <application>pg_xlogdump</application> command line
arguments, and exit.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1>
<title>Notes</title>
<para>
Can give wrong results when the server is running.
</para>
<para>
Only the specified timeline is displayed (or the default, if none is
specified). Records in other timelines are ignored.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="wal"></member>
</simplelist>
</rfsect1>
</refentry>
...@@ -12,7 +12,7 @@ PostgreSQL documentation ...@@ -12,7 +12,7 @@ PostgreSQL documentation
<refnamediv> <refnamediv>
<refname>pg_isready</refname> <refname>pg_isready</refname>
<refpurpose>checks the connection status of a <productname>PostgreSQL</productname> server</refpurpose> <refpurpose>check the connection status of a <productname>PostgreSQL</productname> server</refpurpose>
</refnamediv> </refnamediv>
<indexterm zone="app-pg-isready"> <indexterm zone="app-pg-isready">
......
...@@ -28,8 +28,6 @@ ...@@ -28,8 +28,6 @@
#ifndef PALLOC_H #ifndef PALLOC_H
#define PALLOC_H #define PALLOC_H
#ifndef FRONTEND
/* /*
* Type MemoryContextData is declared in nodes/memnodes.h. Most users * Type MemoryContextData is declared in nodes/memnodes.h. Most users
* of memory allocation should just treat it as an abstract type, so we * of memory allocation should just treat it as an abstract type, so we
...@@ -37,6 +35,8 @@ ...@@ -37,6 +35,8 @@
*/ */
typedef struct MemoryContextData *MemoryContext; typedef struct MemoryContextData *MemoryContext;
#ifndef FRONTEND
/* /*
* CurrentMemoryContext is the default allocation context for palloc(). * CurrentMemoryContext is the default allocation context for palloc().
* We declare it here so that palloc() can be a macro. Avoid accessing it * We declare it here so that palloc() can be a macro. Avoid accessing it
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment