You can follow steps 0-9 for a brief Narugn tour.

See also "PostgreSQL database server configuration" below.

Step 0: Prerequisites

A PostgreSQL 9.1+ database server, on which there is an "narugn" user which can connect seamlessly from the postgres system user and from any other user you wish to use (for instance you might want to set both ~postgres/.pgpass and your ~/.pgpass accordingly). You also need to set

search_path = narugn_logic, narugn, public

for the narugn PostgreSQL user.

The "plproxy" extension must be installed.

Step 1: Install Narugn

Narugn is a PostgreSQL 9.1 extension; hence it can be installed just like any PostgreSQL extension.


A "Narugn server" is a PostgreSQL database server where the "narugn" extension has been installed, i.e., where it is possible to successfully execute


on any of its databases.

Step 2: Design your Narugn server

Before we create the first Narugn cell, we need to choose sensible values for the following settings of our Narugn server:

  • polygon
  • short_name
  • full_name
  • local_connstr
  • connstr (i.e. the remote connection string)

"polygon" is a value of type "polygon", and must contain at least one point with integer coordinates. For instance, we choose the following:

polygon '1.8 , 1.8  ,  3.5 , 1.6  ,  2.5 , 3.6'

which contains points (2,2) and (3,2).

"short_name" is a text value, and must be a valid PostgreSQL identifier. We choose "test1".

"full_name" is any text value. We choose "Test Narugn server #1".

"local_connstr" and "connstr" are text values, and must be valid PostgreSQL connection strings. "local_connstr" will be used to connect from cells in the same Narugn server, while "connstr" will be used to connect to this server from cells in neighbouring Narugn servers.

Our choices:

local_connstr = 'host=localhost port=5432'
connstr = 'host=myhost.lan port=5432'

Step 3: Create the first Narugn cell

Now we can create a cell; we just need to decide at which coordinates. They must be integers and be included in the Narugn server polygon that we have chosen in the previous step.

Our choice will be (2,2); therefore the corresponding Narugn cell database name will be "narugn_cell_2_2".

Then, we connect to the "postgres" database and issue:

postgres=# CREATE DATABASE narugn_cell_2_2;
postgres=# \c narugn_cell_2_2 narugn
You are now connected to database "narugn_cell_2_2" as user "narugn".
narugn_cell_2_2=# CREATE EXTENSION plproxy;
narugn_cell_2_2=# CREATE EXTENSION narugn;
narugn_cell_2_2=# SELECT narugn.configure_cell(
  short_name := 'test1',
  full_name := 'Test Narugn server #1',
  polygon := polygon '1.8 , 1.8  ,  3.5 , 1.6  ,  2.5 , 3.6'
  local_connstr := 'host=localhost port=5432',
  connstr := 'host=myhost.lan port=5432');
(1 row)

Step 4: create subsequent Narugn cells

Once you have created a Narugn cell, you can clone it to create additional Narugn cells on the same Narugn server. The procedure is almost the same, except that when running narugn.configure_cell you only need to provide local_connstr and the coordinates for the existing cell that you are cloning from.

In our case, the coordinates for the new cell will be (3,2), hence:

postgres=# CREATE DATABASE narugn_cell_3_2;
postgres=# \c narugn_cell_3_2 narugn
You are now connected to database "narugn_cell_3_2" as user "narugn".
narugn_cell_3_2=# CREATE EXTENSION plproxy;
narugn_cell_3_2=# CREATE EXTENSION narugn;
narugn_cell_3_2=# SELECT configure_cell(
  cell := cds '(2,2)',
  local_connstr := 'host=localhost port=5432');
(1 row)

Note. Creating new Narugn cells by cloning existing ones ensures that the Narugn server configuration is consistent across all the Narugn cells in that server.

Step 5: Rescan

There are several ways to operate a Narugn cluster. Here we will only see the "execute_sync" function, which runs a given "cell function" on all the accessible cells, waits for all the functions to finish, and returns the combined output.

First, we connect to one of the Narugn cell databases that have been created (for instance "narugn_cell_2_2"), and run the "ping" cell function:

narugn_cell_2_2=# SELECT * FROM execute_sync('ping');
   c   | z |       dt        | output 
 (2,2) | 1 | 00:00:00.026046 | OK
(1 row)

Neighbouring cell (3,2) does not answer, because it is not yet visible from cell (2,2). Therefore we rescan the network from cell (2,2):

narugn_cell_2_2=# SELECT * FROM execute_sync('rescan');
   c   | z |       dt        |        output         
 (2,2) | 1 | 00:00:00.031397 | {.ok.,skip,skip,skip}
 (3,2) | 1 | 00:00:00.352463 | {skip,skip,.ok.,skip}
(2 rows)

If we ping again, we now see that both cells can be reached:

narugn_cell_2_2=# SELECT * FROM execute_sync('ping');
   c   | z |        dt       | output 
 (2,2) | 1 | 00:00:00.012543 | OK
 (3,2) | 1 | 00:00:00.027754 | OK
(2 rows)

Step 6: Loading Logic

Narugn code is divided in two parts, called "Extension" and "Logic".

This separation is motivated by the need to allow frequent and easy updates of one part of the code (Logic), while keeping the other part (Extension) small and stable.

The Extension code is loaded by the CREATE EXTENSION statement, which must be issued separately on each node.

The Logic code is loaded via a dedicated cell function, which propagates it to all the other cells via Narugn itself. The Logic code is passed as a base64 encoded string.

Example. If you have a SQL file named "base.sql" which contains the Logic that you want to load into an existing Narugn cluster, just issue

psql -c "SELECT * FROM execute_sync('logic','$(base64 mylogic.sql)');"

on one cell, and the new Logic will be propagated to all the cells in the Narugn cluster, replacing any pre-existing code (make sure the "base64" command line utility is installed).

Step 7: Other cell functions

The "version" cell function provides version information about the operating system, the PostgreSQL server and the installed Narugn extensions on each cell:

narugn_cell_2_2=# select * from execute_sync('version'); 
   c   | z |       dt        |                                         output                                         
 (2,2) | 1 | 00:00:00.177874 | PostgreSQL 9.3rc1 on i686-pc-linux-gnu, compiled by gcc (Debian 4.7.2-5) 4.7.2, 32-bit
 (2,2) | 2 | 00:00:00.177976 | Narugn 0.2.0
 (3,2) | 1 | 00:00:00.27331  | PostgreSQL 9.3rc1 on i686-pc-linux-gnu, compiled by gcc (Debian 4.7.2-5) 4.7.2, 32-bit
 (3,2) | 2 | 00:00:00.273416 | Narugn 0.2.0
(4 rows)

The "version" cell function can be used as an example to build other cell functions, put them in Logic and then load them into all the nodes via the "logic" cell function. It is defined as follows:

CREATE FUNCTION cell_version
( payload IN text[]
, walked IN cdt[]
, origin_tick IN bigint
, rpfp IN boolean DEFAULT false
, z OUT bigint
, t OUT timestamp with time zone
, output OUT text
LANGUAGE plpgsql
        IF rpfp THEN z := 0; output := 'true'; RETURN NEXT; RETURN; END IF;
        z := 1;
        t := clock_timestamp();
        output := version();
        RETURN NEXT;
        z := 2;
        t := clock_timestamp();
        output := 'Narugn ' || code_version();
        RETURN NEXT;
SET search_path TO narugn, public;

"rpfp" is an acronym of "request permission for propagation", and is used to implement partial propagation of cell functions, such as in the new_server cell function. The "version" cell function just returns 'true' because it always agrees to be propagated to its neighbours (if any).

Step 8: Empty the Narugn cluster

Cells in an Narugn server can be dropped just by dropping the related database, because there is no Narugn master database.

Step 9: Uninstall Narugn software

Since Narugn is packaged as a PostgreSQL extension, the Narugn software can be uninstalled just like any other extension.

PostgreSQL database server configuration

In order to connect two or more Narugn clusters, the underlying PostgreSQL database servers need to be allowed to talk to each other.

In Debian GNU/Linux systems, localhost is bound to the address while the hostname is bound to .

Incoming connections will be either directed to localhost or to the hostname; therefore the PostgreSQL server needs to listen on both addresses. It is also necessary to listen on the network interface that receives connections from neighbouring hosts. For instance, if your system is reachable by its neighbours at server.my.lan, whose IP is, you can set

listen_addresses = 'localhost,,'

in postgresql.conf and

local     all           narugn                                  md5
hostnossl all           narugn             md5
host      all           narugn         md5

in pg_hba.conf (since belongs to the class C network