Coverage report: /development/source/library/org/datagraph/spocq-shard/src/odbc/statistics.lisp
| Kind | Covered | All | % |
| expression | 250 | 464 | 53.9 |
| branch | 20 | 28 | 71.4 |
Key
Not instrumented
Conditionalized out
Executed
Not executed
Both branches taken
One branch taken
Neither branch taken
1
;;; -*- Mode: lisp; Syntax: ansi-common-lisp; Base: 10; Package: org.datagraph.spocq.implementation; -*-
3
;;; materialized operations repositories
4
;;; - accounts : direct access to the mysql table
5
;;; - import_events : a view of the mysql repository_import_logs
6
;;; - query_events : direct access to the postgresql table maintained by spocq
7
;;; - transaction_events : direct access to the postrresql table maintained by spocq
10
;;; sudo -u postgres psql "${RAILS_ENV}" < /srv/dydra/backups/event-schema.sql
11
;;; mysql "${RAILS_ENV}" < /srv/dydra/backups/imports-view.sql
13
(in-package :org.datagraph.spocq.implementation)
16
(defmethod clsql-sys:database-get-type-specifier ((type (eql 'uuid)) args database
17
(db-type (eql :postgresql)))
19
(defmethod clsql-sys:read-sql-value ((val string) (type (eql 'uuid)) database (db-type (eql :postgresql)))
21
(defmethod clsql-sys:database-output-sql-as-type ((type (eql 'uuid)) (val string) database (db-type (eql :postgresql)))
24
(deftype uuid () 'string)
26
(defmethod clsql-sys:database-get-type-specifier ((type (eql 'clsql-sys::timestamp)) args database
27
(db-type (eql :postgresql)))
29
(defmethod clsql-sys:read-sql-value ((val string) (type (eql 'clsql-sys::timestamp)) database (db-type (eql :postgresql)))
31
(defmethod clsql-sys:database-output-sql-as-type ((type (eql 'clsql-sys::timestamp)) (val string) database (db-type (eql :postgresql)))
33
(deftype clsql-sys::timestamp () 'string)
35
(defmethod clsql-sys:database-get-type-specifier ((type (eql 'query_form)) args database
36
(db-type (eql :postgresql)))
38
(defmethod clsql-sys:read-sql-value ((val string) (type (eql 'query_form)) database (db-type (eql :postgresql)))
39
(intern (string-upcase val) :keyword))
40
(defmethod clsql-sys:database-output-sql-as-type ((type (eql 'query_form)) (val symbol) database (db-type (eql :postgresql)))
42
(deftype query_form () 'keyword)
45
(defmethod clsql-sys:database-get-type-specifier ((type (eql 'bytea)) args database
46
(db-type (eql :postgresql)))
48
(defmethod clsql-sys:read-sql-value ((val integer) (type (eql 'bytea)) database (db-type (eql :postgresql)))
50
(defmethod clsql-sys:database-output-sql-as-type ((type (eql 'query_form)) (val integer) database (db-type (eql :postgresql)))
52
(deftype bytea () 'integer)
55
;; even though it is a read-only view
56
(clsql:def-view-class import-event ()
58
:type clsql-sys:bigint
59
:reader transaction-event-id)
62
:db-constraints :not-null
65
:accessor import-event-job-id)
69
:accessor import-event-created-at)
71
:db-constraints :not-null
74
:accessor import-event-account-key)
76
:db-constraints :not-null
78
:initarg :repository-uuid
79
:accessor import-event-repository-uuid)
81
:db-constraints :not-null
83
:initarg :repository-key
84
:accessor import-event-repository-key)
87
:initarg :agent-key :initform nil
88
:accessor import-event-agent-key)
91
:initarg :url :initform nil
92
:accessor import-event-url)
95
:initarg :context initform 0
96
:accessor import-event-context)
99
:initarg :triples :initform 0
100
:accessor transaction-event-triples)
103
:initarg :success :initform 0
104
:accessor transaction-event-success))
105
(:base-table import_events))
108
(clsql:def-view-class query-event ()
110
:type clsql-sys:bigint
111
;; not null default nextval('accounting.query_statistics_id_seq'::regclass)
112
:db-constraint :auto-increment
113
:reader query-event-id)
116
:db-constraints :not-null
118
:accessor query-event-uuid)
120
:type clsql-sys::timestamp
121
:db-constraints :not-null
123
:reader query-event-timestamp)
127
:reader query-event-state)
131
:reader query-event-form)
134
:db-constraints :not-null
136
:reader query-event-sha1)
140
:reader query-event-view-name)
143
:db-constraints :not-null
144
:initarg :account-uuid
145
:reader query-event-account-uuid)
147
:db-constraints :not-null
149
:initarg :account-key
150
:accessor query-event-account-key)
153
:db-constraints :not-null
154
:initarg :repository-uuid
155
:reader query-event-repository-uuid)
157
:db-constraints :not-null
159
:initarg :repository-key
160
:accessor query-event-repository-key)
163
:db-constraints :not-null
164
:initarg :revision-uuid
165
:reader query-event-revision-uuid)
169
:reader query-event-agent-name)
175
:initarg :agent-location)
177
:type clsql-sys:bigint
178
:initarg :elapsed-time :initform 0
179
:reader query-event-elapsed-time
180
:documentation "time in milliseconds")
182
:type clsql-sys:bigint
183
:initarg :process-time :initform 0
184
:reader query-event-process-time
185
:documentation "time in milliseconds")
188
:initarg :compile-time :initform 0
189
:reader query-event-compile-time
190
:documentation "time in milliseconds")
193
:initarg :algebra-operations
194
:reader query-event-algepra-operations)
197
:initarg :match-requests
198
:reader query-event-match-requests)
201
:initarg :match-responses :initform 0
202
:reader query-event-match-responses)
203
(solutions_constructed
204
:type integer :initform 0
205
:initarg :solutions-constructed
206
:reader query-event-solutions-constructed)
208
:type integer :initform 0
209
:initarg :solutions-processed
210
:reader query-event-solutions-processed)
212
:type integer :initform 0
213
:initarg :solutions-returned
214
:reader query-event-solutions-processed)
216
:type clsql-sys:bigint :initform 0
217
:initarg :bytes-allocated
218
:reader query-event-solutions-returned)
220
:type integer :initform 0
222
:reader query-event-bytes-read)
224
:type integer :initform 0
225
:initarg :bytes-written
226
:reader query-event-bytes-written))
227
(:base-table query_events))
230
(clsql:def-view-class transaction-event ()
232
:type clsql-sys:bigint
233
:reader transaction-event-id)
236
:db-constraints :not-null
239
:accessor transaction-event-uuid)
243
:accessor transaction-event-task-uuid)
245
:db-constraints :not-null
247
:initarg :account-uuid
248
:accessor transaction-event-account-uuid)
250
:db-constraints :not-null
252
:initarg :account-key
253
:accessor transaction-event-account-key)
255
:db-constraints :not-null
257
:initarg :repository-uuid
258
:accessor transaction-event-repository-uuid)
260
:db-constraints :not-null
262
:initarg :repository-key
263
:accessor transaction-event-repository-key)
266
:initarg :agent-name :initform nil
267
:accessor transaction-event-agent-name)
270
:initarg :agent-tag :initform nil
271
:accessor transaction-event-agent-tag)
273
:type clsql-sys::timestamp
274
:initarg :timestamp-start initform 0
275
:accessor transaction-event-timestamp-start)
277
:type clsql-sys::timestamp
278
:initarg :timestamp-end :initform 0
279
:accessor transaction-event-timestamp-end)
280
;; an unrevisioned repository does not track update counts
282
:type clsql-sys:bigint
283
:initarg :insert-count :initform nil
284
:accessor transaction-event-insert-count
285
:documentation "number of new statements inserted. null if un-revisioned")
287
:type clsql-sys:bigint
288
:initarg :remove-count :initform nil
289
:accessor transaction-event-remove-count
290
:documentation "number of statements deleted. null if un-revisioned"))
291
(:base-table transaction_events))
293
;;; record query and graph store statistics
295
(defparameter *system-account-names*
296
'("jhacker" "system" "operations" "statistics"))
298
(defparameter *system-repository-names*
299
'("system" "operations" "statistics" "monitoring"))
301
(defparameter *system-agent-names*
304
(defparameter *store-event-lock* nil)
305
(defun store-event-lock ()
306
(or *store-event-lock*
307
(setf *store-event-lock* (bt:make-lock "statistics"))))
308
(defun event-database-definition (&optional (db-name *MYSQL-DATABASE*))
309
;; both postgres and mysql follow the same naming convention
310
`("localhost" ,db-name "postgres" "postgres"))
312
(defun postgres-timestamp (date-time)
315
(integer (date:|yyyyMMddTHHmmssZZ| date-time nil))
316
(spocq:date-time (term-lexical-form date-time))
317
(null (term-lexical-form (spocq.e::now)))))
320
(defun make-transaction-event (&rest args)
321
(declare (dynamic-extent args))
322
(apply #'make-instance 'transaction-event args))
325
;;; no import events : those are a mysql view
327
(defun make-query-event (&rest args)
328
(declare (dynamic-extent args))
329
(apply #'make-instance 'query-event args))
331
(defmethod store-query-event ((task query) &key
332
(task-id (task-id task)) (uuid task-id)
333
start-time query-time
334
(form (task-operation task))
335
((:|signature| sha1) (query-signature task))
336
(view-name (task-name task))
337
(repository (task-repository task))
338
(repository-uuid (repository-uuid repository))
339
(repository-name (repository-name repository))
340
(account (repository-account repository))
341
(account-uuid (account-uuid account))
342
(account-name (account-name account))
343
(revision-uuid (repository-revision-id repository))
344
(agent (task-agent task))
345
((:|agent_id| agent-name) (agent-name agent))
346
((:|user_id| agent-tag) (task-user-id task))
347
((:|agent_location| agent-location) nil)
348
((:|algebra_operations| algebra-operations) 0)
349
((:|bytes_allocated| bytes-allocated) 0)
350
((:|bytes_read| bytes-read) 0)
351
((:|bytes_written| bytes-written) 0)
352
((:|match_requests| match-requests) 0)
353
((:|match_responses| match-responses) 0)
354
((:|run_time| run-time) 0)
355
((:|real_time| real-time) 0)
356
((:|solutions_constructed| solutions-constructed) 0)
357
((:|solutions_processed| solutions-processed) 0)
358
((:|solutions_returned| solutions-returned) 0)
359
((:|parse_run_time| parse-run-time) nil)
360
((:|compile_run_time| compile-run-time) 0)
361
((:|state| state) nil))
362
(declare (ignore real-time parse-run-time))
363
(cond ((or *store-system-events*
364
(and (not (find agent-name *system-agent-names* :test #'equal))
365
(not (find account-name *system-account-names* :test #'equal))
366
(not (find repository-name *system-repository-names* :test #'equal))))
367
(flet ((limit-4 (value) (min (or value 0) (load-time-value (1- (expt 2 31))))) ;; plus and minus
368
(limit-8 (value) (min (or value 0) (load-time-value (1- (expt 2 63))))))
369
(if (and uuid form sha1)
370
(handler-case (bt:with-lock-held ((store-event-lock))
371
(clsql:with-database (event-db (event-database-definition) :if-exists :new
372
:database-type :postgresql-socket)
373
(clsql-sys:DATABASE-EXECUTE-COMMAND "SET search_path TO operations" event-db)
374
(clsql-sys:with-transaction (:database event-db)
375
(clsql:update-records-from-instance
378
:state (string-upcase state)
379
:timestamp (postgres-timestamp start-time)
380
:form (string-upcase form)
383
:account-uuid account-uuid
384
:account-key account-name
385
:repository-uuid repository-uuid
386
:repository-key repository-name
387
:revision-uuid (or revision-uuid "")
388
:agent-name agent-name ; can be null
389
:agent-tag agent-tag ; can be null
390
:agent-location agent-location ;; can be null
391
:elapsed-time (limit-4 query-time)
392
:process-time (limit-4 (floor (/ (or run-time 0) 1000000))) ; convert nanoseconds to milliseconds
393
:compile-time (limit-4 (floor (/ (or compile-run-time 0) 1000000)))
394
:algebra-operations (limit-4 algebra-operations)
395
:match-requests (limit-4 match-requests)
396
:match-responses (limit-4 match-responses)
397
:solutions-constructed (limit-4 solutions-constructed )
398
:solutions-processed (limit-4 solutions-processed)
399
:solutions-returned (limit-4 solutions-returned)
400
:bytes-read (limit-4 bytes-read)
401
:bytes-written (limit-4 bytes-written)
402
:bytes-allocated (limit-8 bytes-allocated))
406
(log-error "store-query-event: failed to store event: ~s: ~a" task c)
408
(log-warn "store-query-event: incomplete event: ~s" task))))
411
(defun store-transaction-event (&key task-id
412
revision-id (uuid revision-id)
414
(timestamp-start timestamp) (timestamp-end timestamp)
416
(repository-uuid (repository-uuid repository))
417
(repository-name (repository-name repository))
418
(account (repository-account repository))
419
(account-uuid (account-uuid account))
420
(account-name (account-name account))
422
(agent-name (agent-name agent))
425
(cond ((or *store-system-events*
426
(and (not (find agent-name *system-agent-names* :test #'equal))
427
(not (find account-name *system-account-names* :test #'equal))
428
(not (find repository-name *system-repository-names* :test #'equal))))
429
(if (and uuid account-uuid repository-uuid)
430
(handler-case (bt:with-lock-held ((store-event-lock))
431
(clsql:with-database (event-db (event-database-definition) :if-exists :new
432
:database-type :postgresql-socket)
433
(clsql-sys:DATABASE-EXECUTE-COMMAND "SET search_path TO operations" event-db)
434
(clsql-sys:with-transaction (:database event-db)
435
(clsql:update-records-from-instance
436
(make-transaction-event
439
:account-uuid account-uuid
440
:account-key account-name
441
:repository-uuid repository-uuid
442
:repository-key repository-name
443
:agent-name agent-name
445
:timestamp-start (postgres-timestamp timestamp-start)
446
:timestamp-end (postgres-timestamp timestamp-end)
447
:insert-count inserted
448
:remove-count removed)
452
(log-error "store-transaction-event: failed to store event: ~s: ~a" task-id c)
454
(log-warn "store-transaction-event: incomplete event: ~s" task-id)))
461
(defun read-sql-query-events (&key repository-name account-name start end limit)
462
(clsql:with-database (event-db (event-database-definition) :if-exists :new
463
:database-type :postgresql-socket)
464
(clsql-sys:DATABASE-EXECUTE-COMMAND "SET search_path TO operations" event-db)
466
(if (and repository-name account-name)
467
(clsql:select 'query-event :database event-db :where
470
(CLSQL-SYS:SQL-= (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'repository_key) repository-name)
471
(CLSQL-SYS:SQL-= (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'account_key) account-name))
473
(CLSQL-SYS:SQL->= (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'timestamp) (postgres-timestamp start))
474
(CLSQL-SYS:SQL-< (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'timestamp) (postgres-timestamp end))))
475
:order-by '((timestamp :desc))
478
(clsql:select 'query-event :database event-db :where
480
(CLSQL-SYS:SQL->= (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'timestamp) (postgres-timestamp start))
481
(CLSQL-SYS:SQL-< (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'timestamp) (postgres-timestamp end)))
482
:order-by '((timestamp :desc))
486
(defun read-sql-transaction-events (&key repository-name account-name start end limit)
487
(clsql:with-database (event-db (event-database-definition) :if-exists :new
488
:database-type :postgresql-socket)
489
(clsql-sys:DATABASE-EXECUTE-COMMAND "SET search_path TO operations" event-db)
491
(if (and repository-name account-name)
492
(clsql:select 'transaction-event :database event-db :where
495
(CLSQL-SYS:SQL-= (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'repository_key) repository-name)
496
(CLSQL-SYS:SQL-= (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'account_key) account-name))
498
(CLSQL-SYS:SQL->= (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'timestamp) (postgres-timestamp start))
499
(CLSQL-SYS:SQL-< (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'timestamp) (postgres-timestamp end))))
500
:order-by '((timestamp :desc))
503
(clsql:select 'transaction-event :database event-db :where
505
(CLSQL-SYS:SQL->= (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'timestamp) (postgres-timestamp start))
506
(CLSQL-SYS:SQL-< (CLSQL-SYS:SQL-SLOT-VALUE 'query-event 'timestamp) (postgres-timestamp end)))
507
:order-by '((timestamp :desc))
511
;;; (read-sql-query-events :account-name "fbfpt" :repository-name "kombuchadata" :start 0 :end (get-universal-time))
512
;;; (read-sql-query-events :account-name "nexperia" :repository-name "public-data" :start 0 :end (get-universal-time) :limit 10)
513
;;; (read-sql-query-events :account-name "nexperia" :repository-name "public-data" :start 0 :end (date-time-universal-time (spocq.e:date-time "2021-06-08T00:00:00Z")) :limit 10)
514
;;; (mapcar #'query-event-timestamp *)
515
;;; (mapcar #'query-event-timestamp (read-sql-query-events :account-name "nexperia" :repository-name "public-data" :start 0 :end (- (get-universal-time) (floor (* 60 60 2.7))) :limit 10))
519
in order to enable postgres logging, add the log destination and restart
521
root@nl9:~# diff /etc/postgresql/9.5/main/postgresql.conf{,~}
523
< log_destination = 'syslog' # Valid values are combinations of
527
mysql import view definition
529
"CREATE or REPLACE VIEW import_events
530
AS SELECT i.id, l.job_id, l.created_at, a.cached_slug as account_key,
531
r.cached_slug AS repository_key, r.uuid AS repository_uuid,
532
ag.cached_slug AS agent_key, l.url, l.base_uri, l.context, l.triples, l.success
533
FROM repository_import_logs l
534
LEFT JOIN accounts ag ON l.account_id = ag.id
535
LEFT JOIN repositories r ON l.repository_id = r.id
536
LEFT JOIN accounts a ON r.account_id = a.id
537
ORDER BY l.created_at DESC;"
540
postgres archiving (from nl10)
542
sudo -u postgres psql "${RAILS_ENV}"
543
SET search_path TO operations;
544
select count(*) from transaction_events; # public: 75266, nl7: 229998
545
select count(*) from query_events; # public: 2059325
547
# if no archive exists
548
create table query_events_archive as
549
select * from query_events where timestamp < '2019-04-01';
550
select count(*) from query_events;
551
select count(*) from query_events_archive;
552
delete from query_events where query_events.timestamp < '2019-04-01';
554
create table transaction_events_archive as
555
select * from transaction_events where timestamp_start < '2019-04-01';
556
select count(*) from transaction_events;
557
select count(*) from transaction_events_archive;
558
delete from transaction_events where transaction_events.timestamp_start < '2019-04-01';
562
# if augmenting an existing
563
# 20210701 nxp-prod, nxp-qa
564
insert into query_events_archive
565
select * from query_events
566
where query_events.timestamp < '2021-06-25'
568
select query_events_archive.uuid from query_events_archive
569
where query_events_archive.uuid = query_events.uuid
572
select count(*) from query_events_archive;
573
delete from query_events where query_events.timestamp < '2021-06-25';
575
insert into transaction_events_archive
576
select * from transaction_events
577
where transaction_events.timestamp_start < '2021-06-01'
579
select transaction_events_archive.uuid from transaction_events_archive
580
where transaction_events_archive.uuid = transaction_events.uuid
582
delete from transaction_events where transaction_events.timestamp_start < '2021-06-01';
585
to support statistic queries, the query_events table must beindexed
587
-- add indices to operations.query_events
590
SET search_path TO operations;
592
select count(*) from query_events;
593
select * from query_events order by timestamp desc limit 1;
595
create index query_events_time on operations.query_events
599
create index query_events_account on operations.query_events
603
create index query_events_repository on operations.query_events