Skip to content

Commit 75c1393

Browse files
committed
Version 0.1.0
0 parents  commit 75c1393

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+6626
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
**/*.so
2+
**/*.o
3+
**/.DS_Store

Makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
MODULE_big = pg_dtm
2+
OBJS = pg_dtm.o libdtm.o sockhub/sockhub.o
3+
4+
EXTENSION = pg_dtm
5+
DATA = pg_dtm--1.0.sql
6+
7+
ifndef USE_PGXS
8+
PG_CONFIG = pg_config
9+
PGXS := $(shell $(PG_CONFIG) --pgxs)
10+
include $(PGXS)
11+
else
12+
subdir = contrib/pg_dtm
13+
top_builddir = ../..
14+
include $(top_builddir)/src/Makefile.global
15+
include $(top_srcdir)/contrib/contrib-global.mk
16+
endif

README

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
===
2+
xtm
3+
===
4+
5+
Distributed transaction management tools for PostgreSQL.
6+
7+
--------------------
8+
Communication scheme
9+
--------------------
10+
┏━━━━━━━━━┓
11+
┌────────┨ Backend ┠──────────┐
12+
│ ┗━━━━━━━━━┛ │
13+
┏━━━━┷━━━━┓ ┏━━━━━━━━━┓ ┏━━━━━━┷━━━━━━┓
14+
┃ Arbiter ┠───┨ Backend ┠───┨ Coordinator ┃
15+
┗━━━━┯━━━━┛ ┗━━━━━━━━━┛ ┗━━━━━━┯━━━━━━┛
16+
│ ┏━━━━━━━━━┓ │
17+
└──┬─────┨ Backend ┠───────┬──┘
18+
┆ ┗━━━━━━━━━┛ ┆
19+
libdtm + libsockhub libpq + xtm procs
20+
21+
-----------------------
22+
Coordinator-Backend API
23+
-----------------------
24+
25+
This API includes a set of postgres procedures that
26+
the coordinator can call with "select" statement.
27+
28+
FIXME: actualize the API
29+
30+
------------------------
31+
Backend-Arbiter Protocol
32+
------------------------
33+
34+
The underlying protocol (libsockhub) also transmits the message length, so
35+
there is no need in 'argc'. Every command or reply is a series of int64
36+
numbers.
37+
38+
The format of all commands:
39+
[cmd, argv[0], argv[1], ...]
40+
41+
'cmd' is a command.
42+
'argv[i]' are the arguments.
43+
44+
The commands:
45+
46+
'r': reserve(minxid, minsize)
47+
Claims a sequence ≥ minsize of xids ≥ minxid for local usage. This will
48+
prevent the arbiter from using those values for global transactions.
49+
50+
The arbiter replies with:
51+
[RES_OK, min, max] if reserved a range [min, max]
52+
[RES_FAILED] on failure
53+
54+
'b': begin(size)
55+
Starts a global transaction and assign a 'xid' to it. 'size' is used
56+
for vote results calculation. The arbiter also creates and returns the
57+
snapshot.
58+
59+
The arbiter replies with:
60+
[RES_OK, xid, *snapshot] if transaction started successfully
61+
[RES_FAILED] on failure
62+
63+
See the 'snapshot' command description for the snapshot format.
64+
65+
's': status(xid, wait)
66+
Asks the arbiter about the status of the global transaction identified
67+
by the given 'xid'.
68+
69+
If 'wait' is 1, the arbiter will not reply until it considers the
70+
transaction finished (all nodes voted, or one dead).
71+
72+
The arbiter replies with:
73+
[RES_TRANSACTION_UNKNOWN] if not started
74+
[RES_TRANSACTION_COMMITTED] if committed
75+
[RES_TRANSACTION_ABORTED] if aborted
76+
[RES_TRANSACTION_INPROGRESS] if in progress
77+
[RES_FAILED] if failed
78+
79+
'y': for(xid, wait)
80+
Tells the arbiter that this node votes for commit of the global
81+
transaction identified by the given 'xid'.
82+
83+
The reply and 'wait' logic is the same as for the 'status' command.
84+
85+
'n': against(xid, wait)
86+
Tells the arbiter that this node votes againts commit of the global
87+
transaction identified by the given 'xid'.
88+
89+
The reply and 'wait' logic is the same as for the 'status' command.
90+
91+
'h': snapshot(xid)
92+
Tells the arbiter to generate a snapshot for the global transaction
93+
identified by the given 'xid'. The arbiter will create a snapshot for
94+
every participant, so when each of them asks for the snapshot it will
95+
reply with the same snapshot. The arbiter generates a fresh version if
96+
the same client asks for a snapshot again for the same transaction.
97+
98+
Joins the global transaction identified by the given 'xid', if not
99+
joined already.
100+
101+
The arbiter replies with [RES_OK, gxmin, xmin, xmax, xcnt, xip[0], xip[1]...],
102+
where 'gxmin' is the smallest xmin among all available snapshots.
103+
104+
In case of a failure, the arbiter replies with [RES_FAILED].

dtmd/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bin/*
2+
obj/*

dtmd/Makefile

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
CC=gcc
2+
CFLAGS=-g -O2 -Wall -Iinclude -D_LARGEFILE64_SOURCE # -DDEBUG
3+
SOCKHUB_PREFIX=../sockhub
4+
SOCKHUB_CFLAGS=-I"$(SOCKHUB_PREFIX)"
5+
SOCKHUB_LDFLAGS=-lsockhub -L"$(SOCKHUB_PREFIX)"
6+
7+
SYSTEM=$(shell uname -s)
8+
ifeq ($(SYSTEM),Darwin)
9+
CFLAGS += -D_DARWIN_C_SOURCE
10+
endif
11+
12+
.PHONY: all clean check bindir objdir
13+
14+
all: bin/dtmd
15+
@echo Done.
16+
@echo Feel free to run the tests with \'make check\'.
17+
18+
bin/dtmd: obj/server.o obj/main.o obj/clog.o obj/clogfile.o obj/util.o obj/transaction.o obj/snapshot.o | bindir objdir
19+
$(CC) -o bin/dtmd $(CFLAGS) \
20+
obj/server.o obj/main.o \
21+
obj/clog.o obj/clogfile.o obj/util.o obj/transaction.o \
22+
obj/snapshot.o \
23+
$(SOCKHUB_LDFLAGS)
24+
25+
obj/server.o: src/server.c | objdir
26+
$(CC) -c -o obj/server.o $(CFLAGS) $(SOCKHUB_CFLAGS) src/server.c
27+
28+
check: bin/util-test bin/clog-test
29+
./check.sh util clog
30+
31+
obj/%.o: src/%.c | objdir
32+
$(CC) $(CFLAGS) -c -o $@ $<
33+
34+
bin/util-test: obj/util-test.o obj/util.o | bindir
35+
$(CC) -o bin/util-test $(CFLAGS) obj/util-test.o obj/util.o
36+
37+
bin/clog-test: obj/clog-test.o obj/clog.o obj/clogfile.o obj/util.o | bindir
38+
$(CC) -o bin/clog-test $(CFLAGS) obj/clog-test.o obj/clog.o obj/clogfile.o obj/util.o
39+
40+
bindir:
41+
mkdir -p bin
42+
43+
objdir:
44+
mkdir -p obj
45+
46+
clean:
47+
rm -rfv bin obj test.log

dtmd/check.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/sh
2+
rm -rf test.log
3+
failed=0
4+
passed=0
5+
for testname in $@; do
6+
if bin/${testname}-test >> test.log 2>&1; then
7+
echo "${testname} ok"
8+
passed=$((passed + 1))
9+
else
10+
echo "${testname} FAILED"
11+
failed=$((failed + 1))
12+
fi
13+
done
14+
15+
echo "tests passed: $passed"
16+
echo "tests failed: $failed"
17+
if [ $failed -eq 0 ]; then
18+
rm -rf test.log
19+
else
20+
echo "see test.log for details"
21+
exit 1
22+
fi

dtmd/include/clog.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* This module provides a high-level API to access clog files.
3+
*/
4+
5+
#ifndef CLOG_H
6+
#define CLOG_H
7+
8+
#include <stdbool.h>
9+
#include "int.h"
10+
11+
#define INVALID_XID 0
12+
#define MIN_XID 42
13+
#define MAX_XID ~0
14+
15+
#define BLANK 0
16+
#define POSITIVE 1
17+
#define NEGATIVE 2
18+
#define DOUBT 3
19+
20+
typedef struct clog_data_t *clog_t;
21+
22+
// Open the clog at the specified path. Try not to open the same datadir twice
23+
// or in two different processes. Return a clog object on success, NULL
24+
// otherwise.
25+
clog_t clog_open(char *datadir);
26+
27+
// Get the status of the specified global commit.
28+
int clog_read(clog_t clog, xid_t xid);
29+
30+
// Set the status of the specified global commit. Return 'true' on success,
31+
// 'false' otherwise.
32+
bool clog_write(clog_t clog, xid_t xid, int status);
33+
34+
// Forget about the commits before the given one ('until'), and free the
35+
// occupied space if possible. Return 'true' on success, 'false' otherwise.
36+
bool clog_forget(clog_t clog, xid_t until);
37+
38+
// Close the specified clog. Do not use the clog object after closing. Return
39+
// 'true' on success, 'false' otherwise.
40+
bool clog_close(clog_t clog);
41+
42+
#endif

dtmd/include/clogfile.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* This module provides a low-level API to access clog files.
3+
*/
4+
5+
#include <stdbool.h>
6+
#include "int.h"
7+
8+
#ifndef CLOGFILE_H
9+
#define CLOGFILE_H
10+
11+
#define BITS_PER_COMMIT 2
12+
#define COMMIT_MASK ((1 << BITS_PER_COMMIT) - 1)
13+
#define COMMITS_PER_BYTE 4
14+
#define COMMITS_PER_FILE 0x10000000
15+
#define BYTES_PER_FILE ((COMMITS_PER_FILE) / (COMMITS_PER_BYTE))
16+
#define XID_TO_FILEID(XID) ((XID) / (COMMITS_PER_FILE))
17+
#define XID_TO_OFFSET(XID) (((XID) % (COMMITS_PER_FILE)) / (COMMITS_PER_BYTE))
18+
#define XID_TO_SUBOFFSET(XID) (((XID) % (COMMITS_PER_FILE)) % (COMMITS_PER_BYTE))
19+
20+
typedef struct clogfile_t {
21+
char *path;
22+
xid_t min;
23+
xid_t max;
24+
void *data; // ptr for mmap
25+
} clogfile_t;
26+
27+
// Open a clog file with the gived id. Create before opening if 'create' is
28+
// true. Return 'true' on success, 'false' otherwise.
29+
bool clogfile_open_by_id(clogfile_t *clogfile, char *datadir, int fileid, bool create);
30+
31+
// Close and remove the given clog file. Return 'true' on success, 'false'
32+
// otherwise.
33+
bool clogfile_remove(clogfile_t *clogfile);
34+
35+
// Close the specified clogfile. Return 'true' on success, 'false' otherwise.
36+
bool clogfile_close(clogfile_t *clogfile);
37+
38+
// Get the status of the specified global commit from the clog file.
39+
int clogfile_get_status(clogfile_t *clogfile, xid_t xid);
40+
41+
// Set the status of the specified global commit in the clog file. Return
42+
// 'true' on success, 'false' otherwise.
43+
bool clogfile_set_status(clogfile_t *clogfile, xid_t xid, int status);
44+
45+
#endif

dtmd/include/int.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef INT_H
2+
#define INT_H
3+
4+
typedef unsigned xid_t;
5+
6+
#endif

dtmd/include/limits.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef LIMITS_H
2+
#define LIMITS_H
3+
4+
#define MAX_TRANSACTIONS 4096
5+
6+
#define BUFFER_SIZE (64 * 1024)
7+
#define LISTEN_QUEUE_SIZE 100
8+
#define MAX_STREAMS 4096
9+
10+
#endif

dtmd/include/proto.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#ifndef PROTO_H
2+
#define PROTO_H
3+
4+
#define CMD_RESERVE 'r'
5+
#define CMD_BEGIN 'b'
6+
#define CMD_FOR 'y'
7+
#define CMD_AGAINST 'n'
8+
#define CMD_SNAPSHOT 'h'
9+
#define CMD_STATUS 's'
10+
11+
#define RES_FAILED 0xDEADBEEF
12+
#define RES_OK 0xC0FFEE
13+
#define RES_TRANSACTION_COMMITTED 1
14+
#define RES_TRANSACTION_ABORTED 2
15+
#define RES_TRANSACTION_INPROGRESS 3
16+
#define RES_TRANSACTION_UNKNOWN 4
17+
18+
#endif

0 commit comments

Comments
 (0)