mirror of
https://github.com/timescale/timescaledb.git
synced 2025-06-02 19:26:43 +08:00
The installation metadata has been refactored: - The installation metadata store now takes Datums of any type as input and output - Move metadata functions from uuid.c -> metadata.c - Make metadata functions return native types rather than text, including for tests Telemetry tests for ssl and nossl have been combined. Note that PG 9.6 does not have pg_backend_random() that gives us a secure random numbers for UUIDs that we send in telemetry. Therefore, we fall back to the generating the UUID from the timestamp if we are on PG 9.6. This change also fixes a number of test issues. For instance, in the telemetry test the escape char `E` was passed on as part of the response string when set as a variable with `\set`. This was not detected before because the response parser didn't parse the start of the response properly. A number of fixes have been made to the formatting of log messages for telemetry to conform to the PostgreSQL standard as well as being consistent with other messages. Numerous build issues on Windows have been resolved. There is also new functionality to get OS version info on Windows (for telemetry), including a SQL function get_os_info() to retrieve this information. The net library will now allow connecting to a servicename, e.g., http or https. A port is resolved from this service name via getaddrinfo(). An explicit port can still be given, and it that case it will not resolve the service name. Databases the are updated to the new version of the extension will have an install_timestamp in their installation metadata that does not reflect the actual original install date of the extension. To be able to distinguish these updated installations from those that are freshly installed, we add a bogus "epoch" install_timestamp in the update script. Parsing of the version string in the telemetry response has been refactored to be more amenable to testing. Tests have been added.
325 lines
9.3 KiB
Plaintext
325 lines
9.3 KiB
Plaintext
\c single_2 :ROLE_SUPERUSER
|
|
/*
|
|
* Note on testing: need a couple wrappers that pg_sleep in a loop to wait for changes
|
|
* to appear in pg_stat_activity.
|
|
* Further Note: PG 9.6 changed what appeared in pg_stat_activity, so the launcher doesn't actually show up.
|
|
* we can still test its interactions with its children, but can't test some of the things specific to the launcher.
|
|
* So we've added some bits about the version number as needed.
|
|
*/
|
|
CREATE VIEW worker_counts as SELECT count(*) filter (WHERE application_name = 'TimescaleDB Background Worker Launcher') as launcher,
|
|
count(*) filter (WHERE application_name = 'TimescaleDB Background Worker Scheduler' AND datname = 'single') as single_scheduler,
|
|
count(*) filter (WHERE application_name = 'TimescaleDB Background Worker Scheduler' AND datname = 'single_2') as single_2_scheduler
|
|
FROM pg_stat_activity;
|
|
CREATE FUNCTION wait_worker_counts(launcher_ct INTEGER, scheduler1_ct INTEGER, scheduler2_ct INTEGER) RETURNS BOOLEAN LANGUAGE PLPGSQL AS
|
|
$BODY$
|
|
DECLARE
|
|
r INTEGER;
|
|
BEGIN
|
|
FOR i in 1..10
|
|
LOOP
|
|
SELECT COUNT(*) from worker_counts where (launcher = launcher_ct OR current_setting('server_version_num')::int < 100000)
|
|
AND single_scheduler = scheduler1_ct AND single_2_scheduler=scheduler2_ct into r;
|
|
if(r < 1) THEN
|
|
PERFORM pg_sleep(0.1);
|
|
PERFORM pg_stat_clear_snapshot();
|
|
ELSE
|
|
--We have the correct counts!
|
|
RETURN TRUE;
|
|
END IF;
|
|
END LOOP;
|
|
RETURN FALSE;
|
|
END
|
|
$BODY$;
|
|
/*
|
|
* When we've connected to single_2, we should be able to see the cluster launcher
|
|
* and the scheduler for single in pg_stat_activity
|
|
* but single_2 shouldn't have a scheduler because ext not created yet
|
|
*/
|
|
SELECT wait_worker_counts(1,1,0);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
/*Now create the extension in single_2*/
|
|
CREATE EXTENSION timescaledb CASCADE;
|
|
WARNING:
|
|
WELCOME TO
|
|
_____ _ _ ____________
|
|
|_ _(_) | | | _ \ ___ \
|
|
| | _ _ __ ___ ___ ___ ___ __ _| | ___| | | | |_/ /
|
|
| | | | _ ` _ \ / _ \/ __|/ __/ _` | |/ _ \ | | | ___ \
|
|
| | | | | | | | | __/\__ \ (_| (_| | | __/ |/ /| |_/ /
|
|
|_| |_|_| |_| |_|\___||___/\___\__,_|_|\___|___/ \____/
|
|
Running version 0.11.1-dev
|
|
For more information on TimescaleDB, please visit the following links:
|
|
|
|
1. Getting started: https://docs.timescale.com/getting-started
|
|
2. API reference documentation: https://docs.timescale.com/api
|
|
3. How TimescaleDB is designed: https://docs.timescale.com/introduction/architecture
|
|
|
|
Note: TimescaleDB collects anonymous reports to better understand and assist our users.
|
|
For more information and how to disable, please see our docs https://docs.timescaledb.com/using-timescaledb/telemetry.
|
|
|
|
SELECT wait_worker_counts(1,1,1);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
DROP DATABASE single;
|
|
/* Now the db_scheduler for single should have disappeared*/
|
|
SELECT wait_worker_counts(1,0,1);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
/*Now let's restart the scheduler and make sure our backend_start changed */
|
|
SELECT backend_start as orig_backend_start
|
|
FROM pg_stat_activity
|
|
WHERE application_name = 'TimescaleDB Background Worker Scheduler'
|
|
AND datname = 'single_2' \gset
|
|
/* We'll do this in a txn so that we can see that the worker locks on our txn before continuing*/
|
|
BEGIN;
|
|
SELECT _timescaledb_internal.restart_background_workers();
|
|
restart_background_workers
|
|
----------------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT wait_worker_counts(1,0,1);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT (backend_start > :'orig_backend_start'::timestamptz) backend_start_changed,
|
|
(wait_event = 'virtualxid') wait_event_changed
|
|
FROM pg_stat_activity
|
|
WHERE application_name = 'TimescaleDB Background Worker Scheduler'
|
|
AND datname = 'single_2';
|
|
backend_start_changed | wait_event_changed
|
|
-----------------------+--------------------
|
|
t | t
|
|
(1 row)
|
|
|
|
COMMIT;
|
|
SELECT wait_worker_counts(1,0,1);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT (wait_event IS DISTINCT FROM 'virtualxid') wait_event_changed
|
|
FROM pg_stat_activity
|
|
WHERE application_name = 'TimescaleDB Background Worker Scheduler'
|
|
AND datname = 'single_2';
|
|
wait_event_changed
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
/*Test stop*/
|
|
SELECT _timescaledb_internal.stop_background_workers();
|
|
stop_background_workers
|
|
-------------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT wait_worker_counts(1,0,0);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
/*Make sure it doesn't break if we stop twice in a row*/
|
|
SELECT _timescaledb_internal.stop_background_workers();
|
|
stop_background_workers
|
|
-------------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT wait_worker_counts(1,0,0);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
/*test start*/
|
|
SELECT _timescaledb_internal.start_background_workers();
|
|
start_background_workers
|
|
--------------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT wait_worker_counts(1,0,1);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
/*make sure start is idempotent*/
|
|
SELECT backend_start as orig_backend_start
|
|
FROM pg_stat_activity
|
|
WHERE application_name = 'TimescaleDB Background Worker Scheduler'
|
|
AND datname = 'single_2' \gset
|
|
/* Since we're doing idempotency tests, we're also going to exercise our queue and start 20 times*/
|
|
SELECT _timescaledb_internal.start_background_workers() as start_background_workers, * FROM generate_series(1,20);
|
|
start_background_workers | generate_series
|
|
--------------------------+-----------------
|
|
t | 1
|
|
t | 2
|
|
t | 3
|
|
t | 4
|
|
t | 5
|
|
t | 6
|
|
t | 7
|
|
t | 8
|
|
t | 9
|
|
t | 10
|
|
t | 11
|
|
t | 12
|
|
t | 13
|
|
t | 14
|
|
t | 15
|
|
t | 16
|
|
t | 17
|
|
t | 18
|
|
t | 19
|
|
t | 20
|
|
(20 rows)
|
|
|
|
/*Here we're waiting to see if something shows up in pg_stat_activity,
|
|
* so we have to condition our loop in the opposite way. We'll only wait
|
|
* half a second in total as well so that tests don't take too long. */
|
|
CREATE FUNCTION wait_equals(TIMESTAMPTZ) RETURNS BOOLEAN LANGUAGE PLPGSQL AS
|
|
$BODY$
|
|
DECLARE
|
|
r BOOLEAN;
|
|
BEGIN
|
|
FOR i in 1..5
|
|
LOOP
|
|
SELECT (backend_start = $1::timestamptz) backend_start_unchanged
|
|
FROM pg_stat_activity
|
|
WHERE application_name = 'TimescaleDB Background Worker Scheduler'
|
|
AND datname = 'single_2' into r;
|
|
if(r) THEN
|
|
PERFORM pg_sleep(0.1);
|
|
PERFORM pg_stat_clear_snapshot();
|
|
ELSE
|
|
RETURN FALSE;
|
|
END IF;
|
|
END LOOP;
|
|
RETURN TRUE;
|
|
END
|
|
$BODY$;
|
|
select wait_equals(:'orig_backend_start');
|
|
wait_equals
|
|
-------------
|
|
t
|
|
(1 row)
|
|
|
|
/*Make sure restart works from stopped worker state*/
|
|
SELECT _timescaledb_internal.stop_background_workers();
|
|
stop_background_workers
|
|
-------------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT wait_worker_counts(1,0,0);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT _timescaledb_internal.restart_background_workers();
|
|
restart_background_workers
|
|
----------------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT wait_worker_counts(1,0,1);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
/*Make sure drop extension statement restarts the worker and on rollback it keeps running*/
|
|
/*Now let's restart the scheduler and make sure our backend_start changed */
|
|
SELECT backend_start as orig_backend_start
|
|
FROM pg_stat_activity
|
|
WHERE application_name = 'TimescaleDB Background Worker Scheduler'
|
|
AND datname = 'single_2' \gset
|
|
BEGIN;
|
|
DROP EXTENSION timescaledb;
|
|
SELECT wait_worker_counts(1,0,1);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
ROLLBACK;
|
|
CREATE FUNCTION wait_greater(TIMESTAMPTZ) RETURNS BOOLEAN LANGUAGE PLPGSQL AS
|
|
$BODY$
|
|
DECLARE
|
|
r BOOLEAN;
|
|
BEGIN
|
|
FOR i in 1..10
|
|
LOOP
|
|
SELECT (backend_start > $1::timestamptz) backend_start_changed
|
|
FROM pg_stat_activity
|
|
WHERE application_name = 'TimescaleDB Background Worker Scheduler'
|
|
AND datname = 'single_2' into r;
|
|
if(NOT r) THEN
|
|
PERFORM pg_sleep(0.1);
|
|
PERFORM pg_stat_clear_snapshot();
|
|
ELSE
|
|
RETURN TRUE;
|
|
END IF;
|
|
END LOOP;
|
|
RETURN FALSE;
|
|
END
|
|
$BODY$;
|
|
SELECT wait_greater(:'orig_backend_start');
|
|
wait_greater
|
|
--------------
|
|
t
|
|
(1 row)
|
|
|
|
/* Make sure canceling the launcher backend causes a restart of schedulers */
|
|
SELECT backend_start as orig_backend_start
|
|
FROM pg_stat_activity
|
|
WHERE application_name = 'TimescaleDB Background Worker Scheduler'
|
|
AND datname = 'single_2' \gset
|
|
SELECT coalesce(
|
|
(SELECT pg_cancel_backend(pid) FROM pg_stat_activity WHERE application_name = 'TimescaleDB Background Worker Launcher'),
|
|
(SELECT current_setting('server_version_num')::int < 100000));
|
|
coalesce
|
|
----------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT wait_worker_counts(1,0,1);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT ((current_setting('server_version_num')::int < 100000) OR wait_greater(:'orig_backend_start')) as wait_greater;
|
|
wait_greater
|
|
--------------
|
|
t
|
|
(1 row)
|
|
|
|
/* Make sure dropping the extension means that the scheduler is stopped*/
|
|
BEGIN;
|
|
DROP EXTENSION timescaledb;
|
|
COMMIT;
|
|
SELECT wait_worker_counts(1,0,0);
|
|
wait_worker_counts
|
|
--------------------
|
|
t
|
|
(1 row)
|
|
|