Postgres-XC, read/write-scalable multi-master symmetric cluster based on PostgreSQL, version 1.0.1 has been released today.

This minor release is based on the latest PostgreSQL 9.1.5+alpha, meaning that all the patches in PostgreSQL 9.1 stable branch have been merged up to commit d10ddf4 (3rd of September 2012).

You can download the source tarball directly from here.
Like PostgreSQL, this tarball contains all the HTML and man documentation.

The documentation of 1.0, including release notes, is available here.

Around 20 bugs have been fixed since 1.0.0, with in particular those fixes:

  • Applications like pgadmin had problems to connect to Postgres-XC server.
  • Drop of sequence was not managed correctly when its database was dropped

You can find all the details in the release notes here.

The project can be followed on Source Forge:
And a couple of GIT repositories are used for development:

  • SourceForge
  • Github
  • Twitter: @PostgresXCBot, bot giving tweets about the commits in Postgres-XC GIT repository

The project members are currently working hard on the next version of Postgres-XC that will include those features:

  • triggers (being implemented)
  • Merge with PostgreSQL 9.2 code (already committed)
  • RETURNING, WHERE CURRENT OF (being implemented)
  • Insure consistency of utilities that cannot run inside transaction block (ex: CREATE DATABASE safely insured in multiple nodes, being implemented)
  • Change table distribution type with ALTER TABLE (already committed)
  • Support for cursors (already committed)
  • Stuff related to node addition and deletion
  • and other things…

The project is under the same license as PostgreSQL, and is managed under a single entity called “Postgres-XC Development Group”.

Have fun with this stable release.

For the last couple of days I have been working on merging the code of Postgres-XC from 9.1 to 9.2. The release 1.0 of XC has been based on 9.1, but it is time to move forward and steal the latest PostgreSQL amazing features :) . The plan was to plug in the code of XC up to the intersection of PostgreSQL master branch and 9.2 stable branch, pretty interesting for two things:

  • Possibility to create stable branches of Postgres-XC based on the 9.2 stable branch of Postgres
  • Preserve the code for merges with future PostgreSQL releases

So the code stays in sync with the latest stable branch of Postgres and the master branch.

However, after this small regression… It has been honestly an interesting experience, allowing me to have a look at the latest evolutions inside PostgreSQL itself between 9.1 and 9.2, and I picked up a couple of items that changed since last year. This list is of course not a complete one, as it results from all the merge conflicts I have seen between Postgres-XC code and PostgreSQL code, so I might not have seen everything on board. More a memo than anything else, perhaps this will help some hackers when upgrading their own code and features not in core.

  • Separation of PGPROC into PGXACT and PGPROC. The new structure PGXACT contains information related to vacuum and snapshot. This really improves the performance for multi-core.
  • Removal of RecentGlobalXmin from snapshot data
  • Addition of clause IF EXISTS in several DDL. You should avoid to use missing_ok in RangeVarGetRelid to false in order to get correct error messages
  • Check if a table column has a dependency with a rule and do not drop it when it is the case
  • Return messages presenting details of tuple data back to client for tuples that failed to satisfy a constraint
  • Removal of inner_plan and outer_plan from deparse_namespace
  • Creation of a new utility command for CREATE TABLE AS, called CreateTableAsStmt. Before CTAS was included in Query with intoClause, this clause has been removed and now both SELECT INTO and CREATE TABLE AS are transformed into this utility at query analysis. Honestly this is cleaner like this
  • Management of cached plans largely modified. In short, the way plans cached have been changed in plancache.c has been really refactored
  • Management of tuple sorting in tuplesort.c. SortSupport is now used instead of ScanKeys
  • Use of PlannerInfo instead of PlannerGlobal when setting references in a plan
  • Setup of parameters in a planner path (see pathnode.c)
  • Modifications for RangeVarGetRelid functions in namespace.h. The calling protocol is extended with no-wait and callback options
  • New functionalities in var.c to pull out Var clauses for a given varno. Some of the APIs were already implemented in XC, but better to use the stuff from core
  • DROP of TRIGGER and RULES is now groupped with DropStmt, before it was under the banner DropPropertyStmt

Of course this list is far from showing all the things done in Postgres for 1 year… This is just the top of the iceberg.

Postgres-XC, as a sharding cluster (write-scalable, multi-master based on PostgreSQL) has currently a huge limitation related to the way tables are distributed.
Just to recall, tables can be either replicated, distributed by round robin, hash or modulo. For hash and modulo the distribution can be done based on the values of one column. Distribution type is defined thanks to an extension of CREATE TABLE.
CREATE TABLE...
[ DISTRIBUTE BY { REPLICATION | ROUND ROBIN | { [HASH | MODULO ] ( column_name ) } } ]
[ TO ( GROUP groupname | NODE nodename [, ... ] ) ]

However once defined it cannot be changed while a cluster is running. There is still the method consisting in using a CREATE TABLE AS consisting in fetching all the data of the table into an intermediate one, then dropping the old table and remaming the intermediate table as the old one. This is enough for 1.0 but the table Oid is definitely lost.

One of the features I have been working these days is to provide to the applications a simple SQL interface that would allow to change a table distribution on the fly, meaning that all the data is transferred automatically between nodes with a single SQL.
This feature uses an extension to ALTER TABLE as follows:
ALTER TABLE
DISTRIBUTE BY { REPLICATION | ROUND ROBIN | { [HASH | MODULO ] ( column_name ) } }
TO { GROUP groupname | NODE ( nodename [, ... ] ) }
ADD NODE ( nodename [, ... ] )
DELETE NODE ( nodename [, ... ] )

This basically means that you can change the distribution type of a table and the subset of nodes where data is located. The node list where data is distributed can be reset, increased or reduced at will.

The redistribution funcionality is still pretty basic, but what is simply does is:

  1. fetch all the data of the table to be redistributed on Coordinator
  2. Truncate the table
  3. Update the catalogs to the new distribution type
  4. Redistribute the data cached on Coordinator

A tuple store is used to cache the data on Coordinator at phase 1, which can be customized with work_mem. A COPY protocol is used to exchange the data between nodes as fastly as possible. This functionality also includes some new stuff to materialize in a tuple slot the data received with COPY protocol (reverse operation also implemented), essential when a tuple has to be redirected to a given node based on a hash value. And it looks that such a materialization mechanism would be a milestone to a more complex mechanism for global constraints and triggers in XC.
This is still a basic implementation, and the following improvements are planned once the basic stuff is committed:

  • Save materialization if it is not necessary (new distribution set to round robin, replication)
  • Truncate the table on a portion of nodes if a replicated table has its subset of nodes reduced
  • COPY only necessary data for a replicated table to new nodes if its subset of nodes is increased
  • And a couple of other things

So how does it work? Let’s take an example with this simple cluster, 1 Coordinator and 3 Datanodes:
postgres=# select node_name, node_type from pgxc_node;
node_name | node_type
-----------+-----------
coord1 | C
dn1 | D
dn2 | D
dn3 | D
(4 rows)

A table aa is created as replicated with 10,000 rows on all the nodes.
postgres=# CREATE TABLE aa (a int);
CREATE TABLE
postgres=# INSERT INTO aa VALUES (generate_series(1,10000));
INSERT 0 10000
postgres=# EXECUTE DIRECT ON (dn1) 'SELECT count(*) FROM aa';
count
-------
10000
(1 row)
postgres=# EXECUTE DIRECT ON (dn2) 'SELECT count(*) FROM aa';
count
-------
10000
(1 row)
postgres=# EXECUTE DIRECT ON (dn3) 'SELECT count(*) FROM aa';
count
-------
10000
(1 row)

So here there are 10,000 tuples on each nodes, nothing fancy for a replicated table.

Let’s change it to a hash-based distribution…
postgres=# ALTER TABLE aa DISTRIBUTE BY HASH(a);
NOTICE: Copying data for relation "public.aa"
NOTICE: Truncating data for relation "public.aa"
NOTICE: Redistributing data for relation "public.aa"
ALTER TABLE
postgres=# EXECUTE DIRECT ON (dn1) 'SELECT count(*) FROM aa';
count
-------
3235
(1 row)
postgres=# EXECUTE DIRECT ON (dn2) 'SELECT count(*) FROM aa';
count
-------
3375
(1 row)
postgres=# EXECUTE DIRECT ON (dn3) 'SELECT count(*) FROM aa';
count
-------
3390
(1 row)

Now one third of the data is on each node.

What happens if the set of nodes is reduced? Let’s now remove the data on node dn2.
postgres=# ALTER TABLE aa DELETE NODE (dn2);
NOTICE: Copying data for relation "public.aa"
NOTICE: Truncating data for relation "public.aa"
NOTICE: Redistributing data for relation "public.aa"
ALTER TABLE
postgres=# EXECUTE DIRECT ON (dn1) 'SELECT count(*) FROM aa';
count
-------
5039
(1 row)
postgres=# EXECUTE DIRECT ON (dn2) 'SELECT count(*) FROM aa';
count
-------
0
(1 row)
postgres=# EXECUTE DIRECT ON (dn3) 'SELECT count(*) FROM aa';
count
-------
4961
(1 row)

The data is now hashed on nodes dn1 and dn3. There is no more data on dn2.

This implementation is still pretty basic, but opens a couple of possibilities for clustering applications, no?

Postgres-XC, read&write-scalable multi-master symmetric cluster based on PostgreSQL, version 1.0.0 is released.
This project is seen as an open-source alternative to costly products such as OracleRAC. Postgres-XC is based on the code of PostgreSQL, so it can naturally use all its technologies, which are enhaunced to have a shared-nothing multi-master PostgreSQL-based database cluster.

This first stable version is based on PostgreSQL 9.1.4. All the patches in PostgreSQL 9.1 stable branch have been merged up to commit 873d1c1 (1st of June 2012).
This includes the security fix related to pg_crypto dated of 30th of May.
You can download the source tarball directly from here
This tarball contains all the HTML and man documentation.

30 bug fixes have been made since release of beta2, with some notable enhancements:

  • Support for EXTENSION is fixed
  • Stabilization of the use of slave nodes in cluster
  • Fix of a bug related to read-only transactions, improving performance by 15%
  • Support of compilation for MacOSX

About the scalability of this release, Postgres-XC 1.0.0 scales to a factor of 3 when compared to a standalone server PostgreSQL 9.1.3 on 5 nodes using a benchmark called DBT-1.

Compared to version Postgres-XC 0.9.7, the following features have been added:

  • Fast query shipping (FQS), quick identification of expressions in a query that can be pushed down to remote nodes
  • SERIAL types
  • TABLESPACE
  • Utility to clean up 2PC transactions in cluster (pgxc_clean)
  • Utility for initialization of GTM (global transaction manager, utility called initgtm)
  • Relation-size functions and locking functions
  • Regression stabilization

The documentation of 1.0, including release notes, is available here.

The project can be followed on SourceForge.
And a couple of GIT repositories are used for development:

The core team is currently working in the addition of new features for the next major release including:

  • Merge with PostgreSQL 9.2
  • Data redistribution functionality, changing table distribution in cluster with a simple ALTER TABLE
  • New functionalities related to online node addition and deletion for a better user experience
  • Triggers
  • Planner improvements
  • Global constraints

The roadmap of the project is located here in section Roadmap.

The project is under the same license as PostgreSQL, now managed under a single entity called “Postgres-XC Development Group”.
In order to keep in touch with the project, whose development follows the same model as PostgreSQL, you can register to the following mailing lists:

  • postgres-xc-general@lists.sourceforge.net, for general questions. Registration can be done here
  • postgres-xc-developers@lists.sourceforge.net. hachers mailing list. Registration can be done here

First you need to download the latest version of Postgres-XC from here.

Then open the tarball and install the binaries as you would do with a normal PostgresSQL.
configure --prefix=$INSTALL_FOLDER
make
make install

$INSTALL_FOLDER is the folder where to install the sources. In this post $PATH redirects to $INSTALL_FOLDER so no need to specify a folder when launching commands.

Next, the goal is to install a cluster when few simple commands. Once you are done, your cluster will have the same shape as picture below.
Simple 1 Coordinator/2Datanode cluster
Assuming that you are familiar with Postgres-XC architecture, this cluster is made with 1 Coordinator (to which your application connects), 2 Datanodes (meaning that your table data can be distributed up to 2 nodes) and a GTM, mandatory unique component distributing transaction ID and snapshot in the cluster.
If you are not familiar with the architecture, you can still refer to documents located here. Among the documents available, the tutorial done at PGCon 2012 is a good beginning.
For simplicity’s sake, all the nodes are installed on a local machine.

Like PostgreSQL, each node of Postgres-XC needs a data folder. All of them are located in $DATA_FOLDER.
So let’s move in and initialize each node.
cd $HOME/pgsql
initgtm -Z gtm -D gtm # Initialize GTM
initdb -D datanode1 --nodename dn1 # Initialize Datanode 1
initdb -D datanode2 --nodename dn2 # Initialize Datanode 2
initdb -D coord1 --nodename co1 # Initialize Coordinator 1

Then you need to modify manually the port value of Datanode 1 and Datanode 2 in each postgresql.conf.
cd datanode1 # or `cd datanode2`
vim postgresql.conf

Then change the line “#port = 5432″ by “port = 15432″ for Datanode 1, and “port = 15433″ for Datanode 2.

Then it is time to start up the cluster.
gtm -D gtm & # Start-up GTM
postgres -X -D datanode1 -i & # Start Datanode 1
postgres -X -D datanode2 -i & # Start Datanode 2
postgres -C -D coord1 -i & # Start Coordinator 1

What remains is to set up the Coordinator to make him know about Datanode 1 and 2.
So connect to coordinator 1.
psql postgres
Then launch that to finish setting up cluster:
CREATE NODE dn1 WITH (TYPE='datanode', PORT=15432);
CREATE NODE dn2 WITH (TYPE='datanode', PORT=15433);
select pgxc_pool_reload();

And you are done.
Now you can connect to Coordinator 1 and test your newly-made cluster.
12 short commands have been enough once binaries have been installed.

©2010-2013 Michael Paquier All content is ©Copyright of Otacoo.com 2010-2013. Privacy Policy - Terms of Use