Fixed database corruption when target tables have dropped columns, and
there are views or functions depending on columns after dropped ones. The issue was reported by depesz, and original patch by Denish Patel. Improved documentation how to build binaries from source. COPYRIGHT updated.
This commit is contained in:
@ -1,7 +1,8 @@
|
||||
#
|
||||
# pg_reorg: bin/Makefile
|
||||
#
|
||||
# Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
# Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
# Portions Copyright (c) 2011, Itagaki Takahiro
|
||||
#
|
||||
SRCS = pg_reorg.c pgut/pgut.c pgut/pgut-fe.c
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
@ -66,6 +66,8 @@ ALTER TABLE tbl_with_dropped_column DROP COLUMN d1;
|
||||
ALTER TABLE tbl_with_dropped_column DROP COLUMN d2;
|
||||
ALTER TABLE tbl_with_dropped_column DROP COLUMN d3;
|
||||
ALTER TABLE tbl_with_dropped_column ADD COLUMN c3 text;
|
||||
CREATE VIEW view_for_dropped_column AS
|
||||
SELECT * FROM tbl_with_dropped_column;
|
||||
INSERT INTO tbl_with_dropped_toast VALUES(1, 10, 'abc');
|
||||
INSERT INTO tbl_with_dropped_toast VALUES(2, 20, sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text);
|
||||
ALTER TABLE tbl_with_dropped_toast DROP COLUMN t;
|
||||
@ -79,6 +81,13 @@ SELECT * FROM tbl_with_dropped_column;
|
||||
c1 | 1 | c2 |
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM view_for_dropped_column;
|
||||
c1 | id | c2 | c3
|
||||
----+----+----+----
|
||||
c1 | 2 | c2 |
|
||||
c1 | 1 | c2 |
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM tbl_with_dropped_toast;
|
||||
i | j
|
||||
---+----
|
||||
@ -188,6 +197,8 @@ SELECT * FROM tbl_gistkey ORDER BY 1;
|
||||
2 | <(4,5),6>
|
||||
(2 rows)
|
||||
|
||||
SET enable_seqscan = on;
|
||||
SET enable_indexscan = off;
|
||||
SELECT * FROM tbl_with_dropped_column;
|
||||
c1 | id | c2 | c3
|
||||
----+----+----+----
|
||||
@ -195,6 +206,13 @@ SELECT * FROM tbl_with_dropped_column;
|
||||
c1 | 2 | c2 |
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM view_for_dropped_column;
|
||||
c1 | id | c2 | c3
|
||||
----+----+----+----
|
||||
c1 | 1 | c2 |
|
||||
c1 | 2 | c2 |
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM tbl_with_dropped_toast;
|
||||
i | j
|
||||
---+----
|
||||
@ -202,6 +220,31 @@ SELECT * FROM tbl_with_dropped_toast;
|
||||
2 | 20
|
||||
(2 rows)
|
||||
|
||||
SET enable_seqscan = off;
|
||||
SET enable_indexscan = on;
|
||||
SELECT * FROM tbl_with_dropped_column;
|
||||
c1 | id | c2 | c3
|
||||
----+----+----+----
|
||||
c1 | 1 | c2 |
|
||||
c1 | 2 | c2 |
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM view_for_dropped_column;
|
||||
c1 | id | c2 | c3
|
||||
----+----+----+----
|
||||
c1 | 1 | c2 |
|
||||
c1 | 2 | c2 |
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM tbl_with_dropped_toast;
|
||||
i | j
|
||||
---+----
|
||||
1 | 10
|
||||
2 | 20
|
||||
(2 rows)
|
||||
|
||||
RESET enable_seqscan;
|
||||
RESET enable_indexscan;
|
||||
--
|
||||
-- check broken links or orphan toast relations
|
||||
--
|
||||
|
@ -1,14 +1,15 @@
|
||||
/*
|
||||
* pg_reorg.c: bin/pg_reorg.c
|
||||
*
|
||||
* Copyright (c) 2008-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
* Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
* Portions Copyright (c) 2011, Itagaki Takahiro
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Client Modules
|
||||
*/
|
||||
|
||||
const char *PROGRAM_VERSION = "1.1.5";
|
||||
const char *PROGRAM_VERSION = "1.1.6";
|
||||
const char *PROGRAM_URL = "http://reorg.projects.postgresql.org/";
|
||||
const char *PROGRAM_EMAIL = "reorg-general@lists.pgfoundry.org";
|
||||
|
||||
@ -19,6 +20,10 @@ const char *PROGRAM_EMAIL = "reorg-general@lists.pgfoundry.org";
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
/*
|
||||
* APPLY_COUNT: Number of applied logs per transaction. Larger values
|
||||
* could be faster, but will be long transactions in the REDO phase.
|
||||
*/
|
||||
#define APPLY_COUNT 1000
|
||||
|
||||
#define SQL_XID_SNAPSHOT_80300 \
|
||||
@ -60,6 +65,7 @@ typedef struct reorg_table
|
||||
const char *create_log; /* CREATE TABLE log */
|
||||
const char *create_trigger; /* CREATE TRIGGER z_reorg_trigger */
|
||||
const char *create_table; /* CREATE TABLE table AS SELECT */
|
||||
const char *drop_columns; /* ALTER TABLE DROP COLUMNs */
|
||||
const char *delete_log; /* DELETE FROM log */
|
||||
const char *lock_table; /* LOCK TABLE table */
|
||||
const char *sql_peek; /* SQL used in flush */
|
||||
@ -300,6 +306,7 @@ reorg_one_database(const char *orderby, const char *table)
|
||||
table.create_trigger = getstr(res, i, c++);
|
||||
|
||||
create_table = getstr(res, i, c++);
|
||||
table.drop_columns = getstr(res, i, c++);
|
||||
table.delete_log = getstr(res, i, c++);
|
||||
table.lock_table = getstr(res, i, c++);
|
||||
ckey = getstr(res, i, c++);
|
||||
@ -393,6 +400,7 @@ reorg_one_table(const reorg_table *table, const char *orderby)
|
||||
elog(DEBUG2, "create_log : %s", table->create_log);
|
||||
elog(DEBUG2, "create_trigger : %s", table->create_trigger);
|
||||
elog(DEBUG2, "create_table : %s", table->create_table);
|
||||
elog(DEBUG2, "drop_columns : %s", table->drop_columns ? table->drop_columns : "(skipped)");
|
||||
elog(DEBUG2, "delete_log : %s", table->delete_log);
|
||||
elog(DEBUG2, "lock_table : %s", table->lock_table);
|
||||
elog(DEBUG2, "sql_peek : %s", table->sql_peek);
|
||||
@ -450,6 +458,8 @@ reorg_one_table(const reorg_table *table, const char *orderby)
|
||||
command(table->delete_log, 0, NULL);
|
||||
command(table->create_table, 0, NULL);
|
||||
printfStringInfo(&sql, "SELECT reorg.disable_autovacuum('reorg.table_%u')", table->target_oid);
|
||||
if (table->drop_columns)
|
||||
command(table->drop_columns, 0, NULL);
|
||||
command(sql.data, 0, NULL);
|
||||
command("COMMIT", 0, NULL);
|
||||
|
||||
@ -635,7 +645,7 @@ reorg_cleanup(bool fatal, void *userdata)
|
||||
|
||||
if (fatal)
|
||||
{
|
||||
fprintf(stderr, "!!!FATAL ERROR!!! Please refer to a manual.\n\n");
|
||||
fprintf(stderr, "!!!FATAL ERROR!!! Please refer to the manual.\n\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -671,6 +681,6 @@ pgut_help(bool details)
|
||||
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(" -T, --wait-timeout=secs timeout to cancel other backends on conflict.\n");
|
||||
printf(" -T, --wait-timeout=secs timeout to cancel other backends on conflict\n");
|
||||
printf(" -Z, --no-analyze don't analyze at end\n");
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pgut-fe.c
|
||||
*
|
||||
* Copyright (c) 2009-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
*
|
||||
* Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
* Portions Copyright (c) 2011, Itagaki Takahiro
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pgut-fe.h
|
||||
*
|
||||
* Copyright (c) 2009-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
*
|
||||
* Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
* Portions Copyright (c) 2011, Itagaki Takahiro
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pgut.c
|
||||
*
|
||||
* Copyright (c) 2009-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
*
|
||||
* Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
* Portions Copyright (c) 2011, Itagaki Takahiro
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* pgut.h
|
||||
*
|
||||
* Copyright (c) 2009-2010, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
*
|
||||
* Portions Copyright (c) 2008-2011, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
|
||||
* Portions Copyright (c) 2011, Itagaki Takahiro
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
@ -80,6 +80,8 @@ ALTER TABLE tbl_with_dropped_column DROP COLUMN d1;
|
||||
ALTER TABLE tbl_with_dropped_column DROP COLUMN d2;
|
||||
ALTER TABLE tbl_with_dropped_column DROP COLUMN d3;
|
||||
ALTER TABLE tbl_with_dropped_column ADD COLUMN c3 text;
|
||||
CREATE VIEW view_for_dropped_column AS
|
||||
SELECT * FROM tbl_with_dropped_column;
|
||||
|
||||
INSERT INTO tbl_with_dropped_toast VALUES(1, 10, 'abc');
|
||||
INSERT INTO tbl_with_dropped_toast VALUES(2, 20, sqrt(2::numeric(1000,999))::text || sqrt(3::numeric(1000,999))::text);
|
||||
@ -89,6 +91,7 @@ ALTER TABLE tbl_with_dropped_toast DROP COLUMN t;
|
||||
--
|
||||
|
||||
SELECT * FROM tbl_with_dropped_column;
|
||||
SELECT * FROM view_for_dropped_column;
|
||||
SELECT * FROM tbl_with_dropped_toast;
|
||||
|
||||
--
|
||||
@ -114,8 +117,19 @@ SELECT col1, to_char("time", 'YYYY-MM-DD HH24:MI:SS'), ","")" FROM tbl_cluster;
|
||||
SELECT * FROM tbl_only_ckey ORDER BY 1;
|
||||
SELECT * FROM tbl_only_pkey ORDER BY 1;
|
||||
SELECT * FROM tbl_gistkey ORDER BY 1;
|
||||
|
||||
SET enable_seqscan = on;
|
||||
SET enable_indexscan = off;
|
||||
SELECT * FROM tbl_with_dropped_column;
|
||||
SELECT * FROM view_for_dropped_column;
|
||||
SELECT * FROM tbl_with_dropped_toast;
|
||||
SET enable_seqscan = off;
|
||||
SET enable_indexscan = on;
|
||||
SELECT * FROM tbl_with_dropped_column;
|
||||
SELECT * FROM view_for_dropped_column;
|
||||
SELECT * FROM tbl_with_dropped_toast;
|
||||
RESET enable_seqscan;
|
||||
RESET enable_indexscan;
|
||||
|
||||
--
|
||||
-- check broken links or orphan toast relations
|
||||
|
Reference in New Issue
Block a user