version 1.0.7.

This commit is contained in:
Takahiro Itagaki 2010-01-28 06:02:28 +00:00
parent 038c07523a
commit 7084ec6de9
18 changed files with 1648 additions and 345 deletions

View File

@ -1,4 +1,4 @@
Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
#
# pg_reorg: Makefile
#
# Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
# Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
#
ifdef USE_PGXS
PG_CONFIG = pg_config

View File

@ -1,7 +1,7 @@
#
# pg_reorg: bin/Makefile
#
# Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
# Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
#
SRCS = pg_reorg.c pgut/pgut.c
OBJS = $(SRCS:.c=.o)

View File

@ -1,14 +1,14 @@
/*
* pg_reorg.c: bin/pg_reorg.c
*
* Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
* Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
*/
/**
* @brief Client Modules
*/
const char *PROGRAM_VERSION = "1.0.6";
const char *PROGRAM_VERSION = "1.0.7";
const char *PROGRAM_URL = "http://reorg.projects.postgresql.org/";
const char *PROGRAM_EMAIL = "reorg-general@lists.pgfoundry.org";
@ -77,9 +77,10 @@ typedef struct reorg_index
const char *create_index; /* CREATE INDEX */
} reorg_index;
static void reorg_all_databases(const char *orderby);
static bool reorg_one_database(const char *orderby, const char *table);
static void reorg_one_table(const reorg_table *table, const char *orderby);
static void reorg_all_databases(const char *order_by);
static bool reorg_one_database(const char *order_by, const char *table);
static void reorg_one_table(const reorg_table *table, const char *order_by);
static void reorg_cleanup(bool fatal, void *userdata);
static char *getstr(PGresult *res, int row, int col);
static Oid getoid(PGresult *res, int row, int col);
@ -94,12 +95,10 @@ static bool sqlstate_equals(PGresult *res, const char *state)
static bool verbose = false;
static bool analyze = true;
/*
* The table begin re-organized. If not null, we need to cleanup temp
* objects before the program exits.
*/
static const reorg_table *current_table = NULL;
static bool alldb = false;
static bool noorder = false;
static char *table = NULL;
static char *orderby = NULL;
/* buffer should have at least 11 bytes */
static char *
@ -109,53 +108,31 @@ utoa(unsigned int value, char *buffer)
return buffer;
}
const struct option pgut_options[] = {
{"verbose", no_argument, NULL, 'v'},
{"all", no_argument, NULL, 'a'},
{"table", required_argument, NULL, 't'},
{"no-order", no_argument, NULL, 'n'},
{"order-by", required_argument, NULL, 'o'},
{"no-analyze", no_argument, NULL, 'Z'},
{NULL, 0, NULL, 0}
static pgut_option options[] =
{
{ 'b', 'v', "verbose", &verbose },
{ 'b', 'a', "all", &alldb },
{ 's', 't', "table", &table },
{ 'b', 'n', "no-order", &noorder },
{ 's', 'o', "order-by", &orderby },
{ 'B', 'Z', "no-analyze", &analyze },
{ 0 },
};
bool alldb = false;
const char *table = NULL;
const char *orderby = NULL;
bool
pgut_argument(int c, const char *arg)
{
switch (c)
{
case 'v':
verbose = true;
break;
case 'a':
alldb = true;
break;
case 't':
assign_option(&table, c, arg);
break;
case 'n':
assign_option(&orderby, c, "");
break;
case 'o':
assign_option(&orderby, c, arg);
break;
case 'Z':
analyze = false;
break;
default:
return false;
}
return true;
}
int
main(int argc, char *argv[])
{
parse_options(argc, argv);
int i;
i = pgut_getopt(argc, argv, options);
if (i == argc - 1)
dbname = argv[i];
else if (i < argc)
elog(ERROR_ARGS, "too many arguments");
if (noorder)
orderby = "";
if (alldb)
{
@ -443,7 +420,7 @@ reorg_one_table(const reorg_table *table, const char *orderby)
* an advisory lock. The registration should be done after
* the first command is succeeded.
*/
current_table = table;
pgut_atexit_push(&reorg_cleanup, (void *) table);
/*
* 2. Copy tuples into temp table.
@ -574,13 +551,13 @@ reorg_one_table(const reorg_table *table, const char *orderby)
command("SELECT reorg.reorg_drop($1)", 1, params);
command("COMMIT", 0, NULL);
current_table = NULL;
pgut_atexit_pop(&reorg_cleanup, (void *) table);
free(vxid);
/*
* 7. Analyze.
* Note that current_table is already set to NULL here because analyze
* is an unimportant operation; No clean up even if failed.
* Note that cleanup hook has been already uninstalled here because analyze
* is not an important operation; No clean up even if failed.
*/
if (analyze)
{
@ -597,12 +574,17 @@ reorg_one_table(const reorg_table *table, const char *orderby)
termStringInfo(&sql);
}
void
pgut_cleanup(bool fatal)
/*
* The userdata pointing a table being re-organized. We need to cleanup temp
* objects before the program exits.
*/
static void
reorg_cleanup(bool fatal, void *userdata)
{
const reorg_table *table = (const reorg_table *) userdata;
if (fatal)
{
if (current_table)
fprintf(stderr, "!!!FATAL ERROR!!! Please refer to a manual.\n\n");
}
else
@ -610,9 +592,6 @@ pgut_cleanup(bool fatal)
char buffer[12];
const char *params[1];
if (current_table == NULL)
return; /* no needs to cleanup */
/* Rollback current transaction */
if (connection)
command("ROLLBACK", 0, NULL);
@ -622,25 +601,26 @@ pgut_cleanup(bool fatal)
reconnect();
/* do cleanup */
params[0] = utoa(current_table->target_oid, buffer);
params[0] = utoa(table->target_oid, buffer);
command("SELECT reorg.reorg_drop($1)", 1, params);
current_table = NULL;
}
}
void
pgut_help(void)
pgut_help(bool details)
{
fprintf(stderr,
"%s re-organizes a PostgreSQL database.\n\n"
"Usage:\n"
" %s [OPTION]... [DBNAME]\n"
"\nOptions:\n"
" -a, --all reorg all databases\n"
" -t, --table=TABLE reorg specific table only\n"
" -n, --no-order do vacuum full instead of cluster\n"
" -o, --order-by=columns order by columns instead of cluster keys\n"
" -Z, --no-analyze don't analyze at end\n"
" -v, --verbose display detailed information during processing\n",
PROGRAM_NAME, PROGRAM_NAME);
printf("%s re-organizes a PostgreSQL database.\n\n", PROGRAM_NAME);
printf("Usage:\n");
printf(" %s [OPTION]... [DBNAME]\n", PROGRAM_NAME);
if (!details)
return;
printf("Options:\n");
printf(" -a, --all reorg all databases\n");
printf(" -t, --table=TABLE reorg specific table only\n");
printf(" -n, --no-order do vacuum full instead of cluster\n");
printf(" -o, --order-by=columns order by columns instead of cluster keys\n");
printf(" -Z, --no-analyze don't analyze at end\n");
printf(" -v, --verbose display detailed information during processing\n");
}

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
*
* pgut.h
*
* Copyright (c) 2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
* Copyright (c) 2009-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
*
*-------------------------------------------------------------------------
*/
@ -10,11 +10,12 @@
#ifndef PGUT_H
#define PGUT_H
#include "c.h"
#include "libpq-fe.h"
#include "pqexpbuffer.h"
#include <assert.h>
#include <getopt.h>
#include <sys/time.h>
#if !defined(C_H) && !defined(__cplusplus)
#ifndef bool
@ -28,38 +29,94 @@ typedef char bool;
#endif
#endif
#define INFINITE_STR "INFINITE"
typedef enum YesNo
{
DEFAULT,
NO,
YES
} YesNo;
typedef enum pgut_optsrc
{
SOURCE_DEFAULT,
SOURCE_ENV,
SOURCE_FILE,
SOURCE_CMDLINE,
SOURCE_CONST
} pgut_optsrc;
/*
* type:
* b: bool (true)
* B: bool (false)
* f: pgut_optfn
* i: 32bit signed integer
* u: 32bit unsigned integer
* I: 64bit signed integer
* U: 64bit unsigned integer
* s: string
* t: time_t
* y: YesNo (YES)
* Y: YesNo (NO)
*/
typedef struct pgut_option
{
char type;
char sname; /* short name */
const char *lname; /* long name */
void *var; /* pointer to variable */
pgut_optsrc allowed; /* allowed source */
pgut_optsrc source; /* actual source */
} pgut_option;
typedef void (*pgut_optfn) (pgut_option *opt, const char *arg);
typedef void (*pgut_atexit_callback)(bool fatal, void *userdata);
/*
* pgut client variables and functions
*/
extern const struct option pgut_options[];
extern bool pgut_argument(int c, const char *arg);
extern void pgut_help(void);
extern void pgut_cleanup(bool fatal);
/*
* pgut framework variables and functions
*/
extern const char *PROGRAM_NAME;
extern const char *PROGRAM_VERSION;
extern const char *PROGRAM_URL;
extern const char *PROGRAM_EMAIL;
extern void pgut_help(bool details);
/*
* pgut framework variables and functions
*/
extern const char *dbname;
extern const char *host;
extern const char *port;
extern const char *username;
extern bool password;
extern char *password;
extern bool debug;
extern bool quiet;
#ifndef PGUT_NO_PROMPT
extern YesNo prompt_password;
#endif
extern PGconn *connection;
extern bool interrupted;
extern void parse_options(int argc, char **argv);
extern bool assign_option(const char **value, int c, const char *arg);
extern void help(bool details);
extern int pgut_getopt(int argc, char **argv, pgut_option options[]);
extern void pgut_readopt(const char *path, pgut_option options[], int elevel);
extern void pgut_atexit_push(pgut_atexit_callback callback, void *userdata);
extern void pgut_atexit_pop(pgut_atexit_callback callback, void *userdata);
/*
* Database connections
*/
extern PGconn *pgut_connect(int elevel);
extern void pgut_disconnect(PGconn *conn);
extern PGresult *pgut_execute(PGconn* conn, const char *query, int nParams, const char **params, int elevel);
extern void pgut_command(PGconn* conn, const char *query, int nParams, const char **params, int elevel);
extern bool pgut_send(PGconn* conn, const char *query, int nParams, const char **params, int elevel);
extern int pgut_wait(int num, PGconn *connections[], struct timeval *timeout);
extern PGconn *reconnect_elevel(int elevel);
extern void reconnect(void);
@ -68,18 +125,23 @@ extern PGresult *execute_elevel(const char *query, int nParams, const char **par
extern PGresult *execute(const char *query, int nParams, const char **params);
extern void command(const char *query, int nParams, const char **params);
#ifdef WIN32
extern unsigned int sleep(unsigned int seconds);
#endif
/*
* memory allocators
*/
extern void *pgut_malloc(size_t size);
extern void *pgut_realloc(void *p, size_t size);
extern char *pgut_strdup(const char *str);
extern char *strdup_with_len(const char *str, size_t len);
extern char *strdup_trim(const char *str);
#define pgut_new(type) ((type *) pgut_malloc(sizeof(type)))
#define pgut_newarray(type, n) ((type *) pgut_malloc(sizeof(type) * (n)))
/*
* IsXXX
* file operations
*/
#define IsSpace(c) (isspace((unsigned char)(c)))
#define IsAlpha(c) (isalpha((unsigned char)(c)))
#define IsAlnum(c) (isalnum((unsigned char)(c)))
#define IsIdentHead(c) (IsAlpha(c) || (c) == '_')
#define IsIdentBody(c) (IsAlnum(c) || (c) == '_')
extern FILE *pgut_fopen(const char *path, const char *mode, bool missing_ok);
extern void pgut_mkdir(const char *path);
/*
* elog
@ -88,18 +150,42 @@ extern unsigned int sleep(unsigned int seconds);
#define INFO (-3)
#define NOTICE (-2)
#define WARNING (-1)
#define ERROR 1
#define HELP 2
#define HELP 1
#define ERROR 2
#define FATAL 3
#define PANIC 4
#define ERROR_SYSTEM 10 /* I/O or system error */
#define ERROR_NOMEM 11 /* memory exhausted */
#define ERROR_ARGS 12 /* some configurations are invalid */
#define ERROR_INTERRUPTED 13 /* interrupted by signal */
#define ERROR_PG_COMMAND 14 /* PostgreSQL query or command error */
#define ERROR_PG_CONNECT 15 /* PostgreSQL connection error */
#undef elog
extern void
elog(int elevel, const char *fmt, ...)
__attribute__((format(printf, 2, 3)));
/*
* StringInfo
* Assert
*/
#undef Assert
#undef AssertArg
#undef AssertMacro
#ifdef USE_ASSERT_CHECKING
#define Assert(x) assert(x)
#define AssertArg(x) assert(x)
#define AssertMacro(x) assert(x)
#else
#define Assert(x) ((void) 0)
#define AssertArg(x) ((void) 0)
#define AssertMacro(x) ((void) 0)
#endif
/*
* StringInfo and string operations
*/
#define STRINGINFO_H
@ -117,19 +203,30 @@ __attribute__((format(printf, 2, 3)));
#define appendStringInfoChar appendPQExpBufferChar
#define appendBinaryStringInfo appendBinaryPQExpBuffer
/*
* Assert
*/
#undef Assert
#undef AssertMacro
extern int appendStringInfoFile(StringInfo str, FILE *fp);
extern int appendStringInfoFd(StringInfo str, int fd);
#ifdef USE_ASSERT_CHECKING
#define Assert(x) assert(x)
#define AssertMacro(x) assert(x)
#else
#define Assert(x) ((void) 0)
#define AssertMacro(x) ((void) 0)
#endif
extern bool parse_bool(const char *value, bool *result);
extern bool parse_bool_with_len(const char *value, size_t len, bool *result);
extern bool parse_int32(const char *value, int32 *result);
extern bool parse_uint32(const char *value, uint32 *result);
extern bool parse_int64(const char *value, int64 *result);
extern bool parse_uint64(const char *value, uint64 *result);
extern bool parse_time(const char *value, time_t *time);
#define IsSpace(c) (isspace((unsigned char)(c)))
#define IsAlpha(c) (isalpha((unsigned char)(c)))
#define IsAlnum(c) (isalnum((unsigned char)(c)))
#define IsIdentHead(c) (IsAlpha(c) || (c) == '_')
#define IsIdentBody(c) (IsAlnum(c) || (c) == '_')
#define ToLower(c) (tolower((unsigned char)(c)))
#define ToUpper(c) (toupper((unsigned char)(c)))
/*
* socket operations
*/
extern int wait_for_socket(int sock, struct timeval *timeout);
extern int wait_for_sockets(int nfds, fd_set *fds, struct timeval *timeout);
/*
* import from postgres.h and catalog/genbki.h in 8.4
@ -150,5 +247,9 @@ typedef int aclitem;
#endif
#endif /* PGUT_H */
#ifdef WIN32
extern int sleep(unsigned int seconds);
extern int usleep(unsigned int usec);
#endif
#endif /* PGUT_H */

View File

@ -109,7 +109,7 @@ CREATE INDEX idx_rnd ON tbl (rndkey);</pre></code></td>
</div>
<hr />
<p class="footer">Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
<p class="footer">Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");

View File

@ -108,7 +108,7 @@ CREATE INDEX idx_rnd ON tbl (rndkey);</pre></code></td>
</center>
<hr />
<p class="footer">Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
<p class="footer">Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");

View File

@ -278,7 +278,7 @@ pg_reorg の実行中には、VACUUM と ANALYZE <STRONG>以外</STRONG> のDDL
<a href="http://www.postgresql.jp/document/current/html/app-vacuumdb.html">vacuumdb</a>
<hr />
<p class="footer">Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
<p class="footer">Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");

View File

@ -263,7 +263,7 @@ Then, it updates system catalog directly to swap the work table and the original
<a href="http://developer.postgresql.org/pgdocs/postgres/app-vacuumdb.html">vacuumdb</a>
<hr />
<p class="footer">Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
<p class="footer">Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");

View File

@ -1,7 +1,7 @@
#
# pg_reorg: lib/Makefile
#
# Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
# Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
#
SRCS = reorg.c pgut/pgut-be.c pgut/pgut-spi.c
OBJS = $(SRCS:.c=.o)

View File

@ -1,7 +1,7 @@
/*
* pg_reorg: lib/pg_reorg.sql.in
*
* Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
* Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
*/
-- Adjust this setting to control where the objects get created.

View File

@ -2,7 +2,7 @@
*
* pgut-be.c
*
* Copyright (c) 2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
* Copyright (c) 2009-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
*
*-------------------------------------------------------------------------
*/

View File

@ -2,7 +2,7 @@
*
* pgut-be.h
*
* Copyright (c) 2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
* Copyright (c) 2009-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
*
*-------------------------------------------------------------------------
*/
@ -55,6 +55,11 @@
heap_insert((relation), (tup), (cid), true, true)
#define GetBulkInsertState() (NULL)
#define FreeBulkInsertState(bistate) ((void)0)
#define FreeExprContext(econtext, isCommit) FreeExprContext((econtext))
#define FuncnameGetCandidates(names, nargs, argnames, variadic, defaults) \
FuncnameGetCandidates((names), (nargs))
#define pgstat_init_function_usage(fcinfo, fcu) ((void)0)
#define pgstat_end_function_usage(fcu, finalize) ((void)0)
typedef void *BulkInsertState;
@ -64,6 +69,19 @@ extern text *cstring_to_text(const char *s);
#define CStringGetTextDatum(s) PointerGetDatum(cstring_to_text(s))
#define TextDatumGetCString(d) text_to_cstring((text *) DatumGetPointer(d))
#elif PG_VERSION_NUM < 80500
#define FuncnameGetCandidates(names, nargs, argnames, variadic, defaults) \
FuncnameGetCandidates((names), (nargs), (variadic), (defaults))
#endif
#if PG_VERSION_NUM < 80500
#define func_signature_string(funcname, nargs, argnames, argtypes) \
func_signature_string((funcname), (nargs), (argtypes))
#define GetConfigOption(name, restrict_superuser) GetConfigOption((name))
#endif
#endif /* PGUT_BE_H */

View File

@ -2,7 +2,7 @@
*
* pgut-spi.c
*
* Copyright (c) 2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
* Copyright (c) 2009-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
*
*-------------------------------------------------------------------------
*/

View File

@ -2,7 +2,7 @@
*
* pgut-spi.h
*
* Copyright (c) 2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
* Copyright (c) 2009-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
*
*-------------------------------------------------------------------------
*/

View File

@ -1,7 +1,7 @@
/*
* pg_reorg: lib/reorg.c
*
* Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
* Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
*/
#include "postgres.h"
@ -75,7 +75,7 @@ static void RenameRelationInternal(Oid myrelid, const char *newrelname, Oid name
Datum
reorg_version(PG_FUNCTION_ARGS)
{
return CStringGetTextDatum("pg_reorg 1.0.6");
return CStringGetTextDatum("pg_reorg 1.0.7");
}
/**

View File

@ -1,7 +1,7 @@
/*
* pg_reorg: lib/uninstall_reorg.sql
*
* Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
* Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
*/
DROP SCHEMA IF EXISTS reorg CASCADE;