Skip to content

Commit f70535f

Browse files
marc1ukMarcus O'Flahertysuperkanalysismarcus
authored
updates for middleman v2 (#99)
* DB and libpqxx updates * add lifetime field to RootPlots and PlotlyPlots tables. Default retention to last 5 * make postgres install directory general, add ordering to indices, add devices table, although referential integrity of device configs is not yet enabled --------- Co-authored-by: Marcus O'Flaherty <moflaherty1@sheffield.ac.uk> Co-authored-by: Marcus O'Flaherty <marcus.o-flaherty@warwick.ac.uk> Co-authored-by: marcus <root@dbServermoflaher@warwick.ac.uk>
1 parent 83310d1 commit f70535f

3 files changed

Lines changed: 106 additions & 42 deletions

File tree

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
*.a
55
*~
66
*.DS_Store
7+
# core dumps
8+
core
9+
# generated by container for debug
10+
.rclocal.log
11+
712
node_modules
813
include
914
lib
@@ -18,3 +23,4 @@ backgroundSD
1823
cgi-bin/sendcommand2.cgi
1924
cgi-bin/sendcommand2nopadding.cgi
2025
cgi-bin/getplot.cgi
26+
cgi-bin/command.cgi

Dockerfile.server

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ RUN yum install -y \
1616
&& rm -rf /var/cache/yum
1717

1818
RUN cd /opt \
19-
&& wget https://github.com/ToolDAQ/libpqxx/raw/master/libpqxx-6.4.5_fixed.tar.gz \
20-
&& tar zxvf libpqxx-6.4.5_fixed.tar.gz \
21-
&& rm libpqxx-6.4.5_fixed.tar.gz \
22-
&& cd libpqxx-6.4.5 \
19+
&& wget https://github.com/jtv/libpqxx/archive/refs/tags/7.10.4.tar.gz \
20+
&& tar zxvf 7.10.4.tar.gz \
21+
&& rm 7.10.4.tar.gz \
22+
&& cd libpqxx-7.10.4 \
2323
&& mkdir install \
24-
&& CXXFLAGS=-std=c++11 ./configure --disable-documentation --enable-shared --prefix=/opt/libpqxx-6.4.5/install \
24+
&& ./configure --disable-documentation --enable-shared --prefix=/opt/libpqxx-7.10.4/install CXXFLAGS=-O3 \
2525
&& if [ ! -f /usr/bin/python ]; then ln -s /usr/bin/python3 /usr/bin/python; fi \
2626
&& make -j`nproc --all` \
2727
&& make install

SetupDatabase.sh

Lines changed: 95 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ if [ ${USE_SYSTEMD} -eq 0 ]; then
88
else
99
echo "running database via pg_ctl"
1010
fi
11+
# get location of DB
12+
DEFAULT_LOCATION=0
13+
if [ -z "${PGROOT}" ]; then
14+
PGROOT=/var/lib/pgsql
15+
DEFAULT_LOCATION=1
16+
fi
17+
export PGDATA=${PGROOT}/data
18+
1119
# only take action on first run
1220
if [ -f /.DBSetupDone ]; then
1321

@@ -19,36 +27,48 @@ if [ -f /.DBSetupDone ]; then
1927
fi
2028
else
2129
# pg_ctl version for containers
22-
STATUS=$(sudo -u postgres pg_ctl -D /var/lib/pgsql/data status &> /dev/null; echo $?)
30+
STATUS=$(sudo -u postgres pg_ctl -D ${PGDATA} status &> /dev/null; echo $?)
2331
if [ ${STATUS} -eq 3 ]; then
2432
if [ -f /var/run/postgresql/.s.PGSQL.5432.lock ]; then
2533
echo "removing stale lockfile"
2634
sudo rm -f /var/run/postgresql/.s.PGSQL.5432.lock
2735
fi
2836
echo "running pg_ctl start"
29-
sudo -u postgres /usr/bin/pg_ctl start -D /var/lib/pgsql/data -s -o "-p 5432" -w -t 300
37+
sudo -u postgres /usr/bin/pg_ctl start -D ${PGDATA} -s -o "-p 5432" -w -t 300
3038
fi
3139
fi
3240
exit 0;
3341
fi
3442
export LC_ALL=C
3543
echo "Initialising postgresql cluster"
36-
chown -R postgres:postgres /var/lib/pgsql
37-
cd /var/lib/pgsql/
44+
if [ ! -d ${PGROOT} ]; then
45+
mkdir -p ${PGROOT}
46+
fi
47+
chown -R postgres:postgres ${PGROOT}
48+
cd ${PGROOT}
3849
# --waldir=/todo/replication
39-
sudo -u postgres /usr/bin/initdb --data-checksums /var/lib/pgsql/data/
50+
sudo -u postgres /usr/bin/initdb --data-checksums ${PGDATA}
4051

4152
# set it up to listen on all network interfaces, rather than (by default) localhost only
42-
echo "listen_addresses = '*'" | sudo -u postgres tee -a /var/lib/pgsql/data/postgresql.conf
53+
echo "listen_addresses = '*'" | sudo -u postgres tee -a ${PGDATA}/postgresql.conf
4354

4455
echo "Starting postgres server"
4556
if [ ${USE_SYSTEMD} -eq 0 ]; then
57+
# if not using the default install location, we need to modify the systemctl file
58+
if [ ${DEFAULT_LOCATION} -ne 1 ]; then
59+
#systemctl edit --stdin postgresql <<-EOF # requires systemd v256
60+
SYSTEMD_EDITOR=tee systemctl edit postgresql <<-EOF
61+
[Service]
62+
Environment=PGDATA=${PGDATA}
63+
EOF
64+
fi
65+
4666
# systemd version
4767
sudo systemctl enable --now postgresql
4868
else
4969
# container version
5070
sudo mkdir -p /var/run/postgresql && sudo chown -R postgres /var/run/postgresql
51-
sudo -u postgres /usr/bin/pg_ctl start -D /var/lib/pgsql/data -s -o "-p 5432" -w -t 300
71+
sudo -u postgres /usr/bin/pg_ctl start -D ${PGDATA} -s -o "-p 5432" -w -t 300
5272
fi
5373

5474
echo "creating root database user"
@@ -59,55 +79,93 @@ sudo -u postgres psql -c "create database daq with owner=root;"
5979
# set timezone to UTC
6080
psql -ddaq -c "ALTER DATABASE daq SET TIME ZONE 'UTC';"
6181

62-
echo "creating monitoring table"
63-
psql -ddaq -c "create table monitoring (time timestamp with time zone NOT NULL, device text NOT NULL, subject text NOT NULL, data JSONB NOT NULL);"
82+
# TODO FIXME To optimize storage and minimize wasted space due to alignment padding,
83+
# it's advisable to arrange columns in the table definition from largest to smallest data type.
6484

65-
echo "creating indices on device name and subject"
66-
psql -ddaq -c "CREATE INDEX ON monitoring (device) WITH (deduplicate_items = on);"
67-
# this may be more efficient as we're unlikely to search by subject alone...
68-
psql -ddaq -c "CREATE INDEX ON monitoring (device, subject) WITH (deduplicate_items = on);"
85+
echo "creating users table"
86+
psql -ddaq -c "create table users (user_id serial NOT NULL, username text NOT NULL, password_hash text NOT NULL, permissions jsonb, UNIQUE (user_id));"
87+
88+
echo "creating run_info table"
89+
psql -ddaq -c "create table run_info (run int NOT NULL, subrun int NOT NULL, start_time timestamp with time zone NOT NULL, stop_time timestamp with time zone, config_id int NOT NULL, comments text NOT NULL, UNIQUE (run, subrun));"
90+
91+
echo "creating index on run_info table"
92+
psql -ddaq -c "CREATE INDEX ON run_info (run DESC NULLS LAST)"
93+
94+
echo "creating run_config table"
95+
psql -ddaq -c "create table run_config (config_id serial NOT NULL primary key, time timestamp with time zone NOT NULL DEFAULT now(), name text NOT NULL, version int NOT NULL, description text NOT NULL, author text NOT NULL, data jsonb NOT NULL, UNIQUE (name, version) );"
96+
97+
echo "creating autoincrement function for run_config version"
98+
psql -ddaq -c 'create or replace function "fn_config_ver"() returns "pg_catalog"."trigger" as $BODY$ begin new.version = (select COALESCE(MAX(version)+1,0) from run_config where name=new.name); return NEW; end; $BODY$ LANGUAGE plpgsql VOLATILE COST 100;'
99+
psql -ddaq -c 'CREATE TRIGGER trig_config_ver BEFORE insert ON run_config FOR EACH ROW EXECUTE PROCEDURE fn_config_ver();'
100+
101+
echo "creating devices table"
102+
psql -ddaq -c "CREATE TABLE devices (name text not null);"
103+
psql -ddaq -c "CREATE UNIQUE INDEX dev_name_idx ON devices(LOWER(name));"
104+
105+
echo "creating device_config table"
106+
# TODO enable below to require device_configs reference a device in the devices table
107+
#psql -ddaq -c "create table device_config (time timestamp with time zone NOT NULL DEFAULT now(), device text references devices(name), version int NOT NULL, author text NOT NULL, description text NOT NULL, data jsonb NOT NULL, UNIQUE (device, version) );"
108+
psql -ddaq -c "create table device_config (time timestamp with time zone NOT NULL DEFAULT now(), device text NOT NULL, version int NOT NULL, author text NOT NULL, description text NOT NULL, data jsonb NOT NULL, UNIQUE (device, version) );"
109+
110+
echo "creating index on device_config table"
111+
psql -ddaq -c "CREATE INDEX ON device_config (device, version DESC NULLS LAST)"
112+
113+
echo "creating autoincrement function for device_config version"
114+
psql -ddaq -c 'create or replace function "fn_devconfig_ver"() returns "pg_catalog"."trigger" as $BODY$ begin new.version = (select COALESCE(MAX(version)+1,0) from device_config where device=new.device); return NEW; end; $BODY$ LANGUAGE plpgsql VOLATILE COST 100;'
115+
psql -ddaq -c 'CREATE TRIGGER trig_devconfig_ver BEFORE insert ON device_config FOR EACH ROW EXECUTE PROCEDURE fn_devconfig_ver();'
116+
117+
echo "creating calibration table"
118+
psql -ddaq -c "create table calibration (time timestamp with time zone NOT NULL DEFAULT now(), name text NOT NULL, version int NOT NULL, description text NOT NULL, data jsonb NOT NULL, UNIQUE (name, version) );"
119+
120+
echo "creating index on calibration table"
121+
psql -ddaq -c "CREATE INDEX ON calibration (name, version DESC NULLS LAST)"
122+
123+
echo "creating autoincrement function for calibration version"
124+
psql -ddaq -c 'create or replace function "fn_calibration_ver"() returns "pg_catalog"."trigger" as $BODY$ begin new.version = (select COALESCE(MAX(version)+1,0) from calibration where name=new.name); return NEW; end; $BODY$ LANGUAGE plpgsql VOLATILE COST 100;'
125+
psql -ddaq -c 'CREATE TRIGGER trig_calibration_ver BEFORE insert ON calibration FOR EACH ROW EXECUTE PROCEDURE fn_calibration_ver();'
69126

70127
echo "creating logging table"
71-
psql -ddaq -c "create table logging (time timestamp with time zone NOT NULL, device text NOT NULL, severity integer NOT NULL, message text NOT NULL);"
128+
psql -ddaq -c "create table logging (time timestamp with time zone NOT NULL DEFAULT now(), device text NOT NULL, severity integer NOT NULL, message text NOT NULL);"
72129

73-
echo "creating indices on device name and message severity"
130+
echo "creating indices on logging device name and message severity"
74131
psql -ddaq -c "CREATE INDEX ON logging (device) WITH (deduplicate_items = on);"
75-
# as above. is anyone really going to want 'high priority logs from any device'? i doubt it
76132
psql -ddaq -c "CREATE INDEX ON logging (device,severity) WITH (deduplicate_items = on);"
77133

134+
echo "creating monitoring table"
135+
psql -ddaq -c "create table monitoring (time timestamp with time zone NOT NULL DEFAULT now(), device text NOT NULL, subject text NOT NULL, data jsonb NOT NULL);"
136+
137+
echo "creating indices on monitoring device name and subject"
138+
psql -ddaq -c "CREATE INDEX ON monitoring (device) WITH (deduplicate_items = on);"
139+
psql -ddaq -c "CREATE INDEX ON monitoring (device, subject) WITH (deduplicate_items = on);"
140+
78141
echo "creating alarms table"
79-
psql -ddaq -c "create table alarms (time timestamp with time zone NOT NULL, device text NOT NULL, level integer NOT NULL, alarm text NOT NULL, silenced integer DEFAULT 0 );"
142+
psql -ddaq -c "create table alarms (time timestamp with time zone NOT NULL DEFAULT now(), device text NOT NULL, level integer NOT NULL, alarm text NOT NULL, silenced integer DEFAULT 0 );"
80143

81-
echo "creating device_config table"
82-
psql -ddaq -c "create table device_config (time timestamp with time zone NOT NULL, device text NOT NULL, version int NOT NULL, author text NOT NULL, description text NOT NULL, data JSONB NOT NULL, UNIQUE (device, version) );"
144+
echo "creating rootplots table"
145+
psql -ddaq -c "create table rootplots (time timestamp with time zone NOT NULL DEFAULT now(), name text NOT NULL, version int NOT NULL, data jsonb NOT NULL, draw_options text NOT NULL DEFAULT '', lifetime int NOT NULL DEFAULT 5, UNIQUE (name, version));"
83146

84-
echo "creating calibration table"
85-
psql -ddaq -c "create table calibration (time timestamp with time zone NOT NULL, device text NOT NULL, version int NOT NULL, description text NOT NULL, data JSONB NOT NULL, UNIQUE (device, version) );"
147+
echo "creating autoincrement function for rootplots version"
148+
psql -ddaq -c 'create or replace function "fn_rootplot_ver"() returns "pg_catalog"."trigger" as $BODY$ begin new.version = (select COALESCE(MAX(version)+1,0) from rootplots where name=new.name); return NEW; end; $BODY$ LANGUAGE plpgsql VOLATILE COST 100;'
149+
psql -ddaq -c 'CREATE TRIGGER trig_rootplot_ver BEFORE insert ON rootplots FOR EACH ROW EXECUTE PROCEDURE fn_rootplot_ver();'
86150

87-
echo "creating configurations table"
88-
psql -ddaq -c "create table configurations (config_id serial NOT NULL primary key, time timestamp with time zone NOT NULL, name text NOT NULL, version int NOT NULL, description text NOT NULL, author text NOT NULL, data JSONB NOT NULL, UNIQUE (name, version) );"
151+
echo "creating plotlyplots table"
152+
psql -ddaq -c "create table plotlyplots (time timestamp with time zone NOT NULL DEFAULT now(), name text NOT NULL, version int NOT NULL, data jsonb NOT NULL, layout jsonb NOT NULL DEFAULT '{}', lifetime int NOT NULL DEFAULT 5, UNIQUE (name, version));"
89153

90-
echo "creating run_info table"
91-
psql -ddaq -c "create table run_info (run int NOT NULL, subrun int NOT NULL, start_time timestamp with time zone NOT NULL, stop_time timestamp with time zone, config_id int NOT NULL, comments text NOT NULL, UNIQUE (run, subrun));"
154+
echo "creating autoincrement function for plotlyplots version"
155+
psql -ddaq -c 'create or replace function "fn_plotlyplot_ver"() returns "pg_catalog"."trigger" as $BODY$ begin new.version = (select COALESCE(MAX(version)+1,0) from plotlyplots where name=new.name); return NEW; end; $BODY$ LANGUAGE plpgsql VOLATILE COST 100;'
156+
psql -ddaq -c 'CREATE TRIGGER trig_plotlyplot_ver BEFORE insert ON plotlyplots FOR EACH ROW EXECUTE PROCEDURE fn_plotlyplot_ver();'
92157

93-
echo "creating rootplots table"
94-
psql -ddaq -c "create table rootplots (name text NOT NULL, draw_options text NOT NULL, time timestamp with time zone NOT NULL, data jsonb NOT NULL, version int NOT NULL, UNIQUE (name, version));"
158+
echo "creating event_display table"
159+
psql -ddaq -c "create table event_display (time timestamp with time zone NOT NULL DEFAULT now(), evnt bigint NOT NULL, data jsonb NOT NULL, UNIQUE (evnt));"
95160

96-
echo "creating users table"
97-
psql -ddaq -c "create table users (user_id serial NOT NULL, username text NOT NULL, password_hash text NOT NULL, permissions JSONB, UNIQUE (user_id));"
161+
psql -ddaq -c "CREATE INDEX ON event_display (evnt DESC NULLS LAST)"
98162

99163
echo "creating pmt table"
100164
psql -ddaq -c "create type pmt_location as enum ('bottom', 'barrel', 'top');"
101165
psql -ddaq -c "create table pmt (id int NOT NULL, x real NOT NULL, y real NOT NULL, z real, type text NOT NULL, size real NOT NULL, location pmt_location NOT NULL, UNIQUE (id));"
102166

103-
echo "creating event_display table"
104-
psql -ddaq -c "create table event_display (evnt bigint NOT NULL, time timestamp with time zone NOT NULL, data JSONB NOT NULL, UNIQUE (evnt));"
105-
106-
echo "creating plotlyplots table"
107-
psql -ddaq -c "create table plotlyplots (name text NOT NULL, time timestamp with time zone NOT NULL DEFAULT now(), version int NOT NULL, traces jsonb NOT NULL, layout jsonb NOT NULL DEFAULT '{}', UNIQUE (name, version));"
108-
109167
#echo "registering database to start on boot"
110-
#echo " sudo -u postgres /usr/bin/pg_ctl start -D /var/lib/pgsql/data -s -o \"-p 5432\" -w -t 300;" >> /etc/rc.local
168+
#echo " sudo -u postgres /usr/bin/pg_ctl start -D ${PGDATA} -s -o \"-p 5432\" -w -t 300;" >> /etc/rc.local
111169

112170
# Insert a default user for testing
113171
echo "Inserting a default user"
@@ -117,6 +175,6 @@ echo "Inserting example monitoring data"
117175
psql -ddaq -c "INSERT INTO monitoring (time, device, subject, data) SELECT now() - (i * INTERVAL '1 minute') AS time, 'test_device' AS device, 'general' AS subject, jsonb_build_object( 'temperature', round((random() * 50 + 10)::numeric, 2), 'humidity', round((random() * 100)::numeric, 2)) AS data FROM generate_series(1, 100) i;"
118176

119177
echo "Inserting example plotyplot data"
120-
psql -ddaq -c "INSERT INTO plotlyplots (name, time, version, traces, layout) VALUES ('plotly1', 'now()', 1, '[{\"x\": [1, 2, 3, 4, 5], \"y\": [10, 20, 15, 30, 25], \"type\": \"scatter\"}]', '{\"title\": \"plotly1\"}');"
178+
psql -ddaq -c "INSERT INTO plotlyplots (name, time, version, data, layout) VALUES ('plotly1', 'now()', 1, '[{\"x\": [1, 2, 3, 4, 5], \"y\": [10, 20, 15, 30, 25], \"type\": \"scatter\"}]', '{\"title\": \"plotly1\"}');"
121179

122180
touch /.DBSetupDone

0 commit comments

Comments
 (0)