Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Upgrading timescale with partial aggregate continuous aggregate fails #5348

Closed
pushpeepkmonroe opened this issue Feb 20, 2023 · 20 comments · Fixed by #5367
Closed

[Bug]: Upgrading timescale with partial aggregate continuous aggregate fails #5348

pushpeepkmonroe opened this issue Feb 20, 2023 · 20 comments · Fixed by #5367
Assignees
Labels
bug continuous_aggregate upgrade Issue is related to upgrading the extension or the PostgreSQL version.

Comments

@pushpeepkmonroe
Copy link

What type of bug is this?

Configuration, Incorrect result, Unexpected error, Other

What subsystems and features are affected?

Other

What happened?

psql -X -d -c 'ALTER EXTENSION timescaledb UPDATE;'
ERROR: column "count" does not exist
CONTEXT: SQL statement "ALTER TABLE _timescaledb_internal._partial_view_288 RENAME COLUMN count TO pstag_android"
PL/pgSQL function _timescaledb_internal.alter_table_column(regclass,regclass,name,name) line 3 at EXECUTE
SQL statement "CALL _timescaledb_internal.alter_table_column(user_view, partial_view, old_name, new_name)"
PL/pgSQL function inline_code_block line 16 at CALL
The current columns in _timescaledb_internal._partial_view_288 have been attached with column agg_9_9 replacing the count column.
\dx timescaledb
FATAL: "timescaledb" already loaded with a different version
DETAIL: The new version is "2.4.0", this session is using version "2.9.3". The session will be restarted.
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
psql (12.6 (Ubuntu 12.6-1.pgdg18.04+1), server 12.14 (Ubuntu 12.14-1.pgdg18.04+1))

This view is owned by our database user. There is a column "count" that it is looking for does not exist in the view. After speaking with my manager I the "agg_9_9" column in timescale has replaced the "count" column. This is the error as to why it cannot ALTER the column "count" to "pstag_android".

_timescaledb_internal._partial_view_288
Columns:
bucket
account
browser_name
browser_version
device_type
platform_name
platform_version
website
agg_9_9 <- replaced the column "count"
chunk_id

TimescaleDB version affected

2.4.0

PostgreSQL version used

12.14

What operating system did you use?

Ubuntu 18.04

What installation method did you use?

Other

What platform did you run on?

On prem/Self-hosted

Relevant log output and stack trace

psql -X -d <database> -c 'ALTER EXTENSION timescaledb UPDATE;'
ERROR:  column "count" does not exist
CONTEXT:  SQL statement "ALTER TABLE _timescaledb_internal._partial_view_288 RENAME COLUMN count TO pstag_android"
PL/pgSQL function _timescaledb_internal.alter_table_column(regclass,regclass,name,name) line 3 at EXECUTE
SQL statement "CALL _timescaledb_internal.alter_table_column(user_view, partial_view, old_name, new_name)"
PL/pgSQL function inline_code_block line 16 at CALL
The current columns in _timescaledb_internal._partial_view_288 have been attached with column agg_9_9 replacing the count column.
 \dx timescaledb
FATAL:  "timescaledb" already loaded with a different version
DETAIL:  The new version is "2.4.0", this session is using version "2.9.3". The session will be restarted.
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
psql (12.6 (Ubuntu 12.6-1.pgdg18.04+1), server 12.14 (Ubuntu 12.14-1.pgdg18.04+1))

How can we reproduce the bug?

sudo su -
cd /etc/apt/sources.list.d
modify files: timescaledb_timescale.list and timescaledb.list

cat timescale_timescaledb.list
# this file was generated by packagecloud.io for
# the repository at https://packagecloud.io/timescale/timescaledb

deb [signed-by=/etc/apt/keyrings/timescale_timescaledb-archive-keyring.gpg] https://packagecloud.io/timescale/timescaledb/ubuntu/ bionic main
deb-src [signed-by=/etc/apt/keyrings/timescale_timescaledb-archive-keyring.gpg] https://packagecloud.io/timescale/timescaledb/ubuntu/ bionic main

cat timescaledb.list
#deb https://packagecloud.io/timescale/timescaledb/debian/ bionic main
#deb https://packagecloud.io/timescale/timescaledb/debian/ focal main
deb https://packagecloud.io/timescale/timescaledb/ubuntu/ focal main

sudo su -
curl -s https://packagecloud.io/install/repositories/timescale/timescaledb/script.deb.sh | os=ubuntu dist=focal sudo bash
sudo apt-get install timescaledb-2-2.9.3-postgresql-12=2.9.3~ubuntu20.04
sudo apt-get install timescaledb-2-postgresql-12=2.9.3~ubuntu20.04
sudo apt install timescaledb-2-2.9.3-postgresql-12=2.9.3~ubuntu20.04
sudo apt install timescaledb-2-postgresql-12=2.9.3~ubuntu20.04
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo tee /etc/apt/trusted.gpg.d/pgdg.asc &>/dev/null
wget --quiet -O - https://packagecloud.io/timescale/timescaledb/gpgkey | sudo apt-key add -
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys D8FF8E1F7DF8B07E
exit out of root and also run everything as ubuntu
@mkindahl mkindahl self-assigned this Feb 20, 2023
@mkindahl
Copy link
Contributor

Hi @pushpeepkmonroe and thanks for reporting this issue!

This view is owned by our database user. There is a column "count" that it is looking for does not exist in the view. After speaking with my manager I the "agg_9_9" column in timescale has replaced the "count" column. This is the error as to why it cannot ALTER the column "count" to "pstag_android".

Yes, this explains why the rename fails, but it is not clear how the count column was renamed to agg_9_9? Was it done as part of an upgrade, or was it done manually?

@mkindahl
Copy link
Contributor

The actual rename is done as part of the upgrade from 2.4.1 to 2.4.2, so could you create the following views and check the result of SELECT * FROM rename_tables? This is just a copy of the code from the actual upgrade, so it allow us to check what the upgrade thinks should be done and get some more information about the objects involved.

CREATE VIEW objs AS 
        SELECT format('%I.%I', user_view_schema, user_view_name)::regclass AS user_view,
               format('%I.%I', direct_view_schema, direct_view_name)::regclass AS direct_view,
               format('%I.%I', partial_view_schema, partial_view_name)::regclass AS partial_view,
               format('%I.%I', schema_name, table_name)::regclass AS mat_table,
               mat_hypertable_id AS mat_id
          FROM _timescaledb_catalog.continuous_agg
          JOIN _timescaledb_catalog.hypertable ON mat_hypertable_id = id;
	  
CREATE VIEW user_view AS 
        SELECT attrelid, attname, attnum, mat_id
          FROM objs, pg_attribute
         WHERE attrelid = objs.user_view;

CREATE VIEW direct_view AS
        SELECT attrelid, attname, attnum, mat_id
          FROM objs, pg_attribute
         WHERE attrelid = objs.direct_view;

CREATE VIEW rename_tables AS
SELECT (SELECT user_view FROM objs WHERE uv.attrelid = user_view),
       uv.attname AS new_name,
       dv.attname AS old_name,
       (SELECT partial_view FROM objs WHERE uv.attrelid = user_view),
       (SELECT direct_view FROM objs WHERE uv.attrelid = user_view),
       (SELECT mat_table FROM objs WHERE uv.attrelid = user_view),
       (SELECT mat_id FROM objs WHERE uv.attrelid = user_view)
  FROM user_view uv JOIN direct_view dv USING (mat_id, attnum)
 WHERE uv.attname != dv.attname;

@pushpeepkmonroe
Copy link
Author

pushpeepkmonroe commented Feb 20, 2023

Stores the counts that get manipulated the none caggs
Stores in a binary format that internally runs to turn it into a more efficient way to increment
Internal Timescale table which should know it has the agg_9_9 column instead of the count column
All of the partial views and _materialized_hypertables located under _timescaledb_internal have have the column agg_9_9 instead of count

@mkindahl
Copy link
Contributor

Stores the counts that get manipulated the none caggs Stores in a binary format that internally runs to turn it into a more efficient way to increment Internal Timescale table which should know it has the agg_9_9 column instead of the count column All of the partial views and _materialized_hypertables located under _timescaledb_internal have have the column agg_9_9 instead of count

Yes, but the problem is that the lookup that fetches the name of the column is confused for some reason, and it would be good to figure out why so that we can fix the problem. The above queries show the information that the rename uses to figure out the old and new column names and this would allow us to investigate what changes were made that causes this error.

If you could start by providing the information shown by SELECT * FROM rename_tables WHERE partial_view = '_timescaledb_internal._partial_view_288' after the views above are installed, we can figure that out.

@pushpeepkmonroe
Copy link
Author

pushpeepkmonroe commented Feb 21, 2023

postgres=# \c <database>
psql (12.6 (Ubuntu 12.6-1.pgdg18.04+1), server 12.14 (Ubuntu 12.14-1.pgdg18.04+1))
You are now connected to database "<database>" as user "postgres".
<database>=# CREATE VIEW objs AS
<database>-#         SELECT format('%I.%I', user_view_schema, user_view_name)::regclass AS user_view,
<database>-#                format('%I.%I', direct_view_schema, direct_view_name)::regclass AS direct_view,
<database>-#                format('%I.%I', partial_view_schema, partial_view_name)::regclass AS partial_view,
<database>-#                format('%I.%I', schema_name, table_name)::regclass AS mat_table,
<database>-#                mat_hypertable_id AS mat_id
<database>-#           FROM _timescaledb_catalog.continuous_agg
<database>-#           JOIN _timescaledb_catalog.hypertable ON mat_hypertable_id = id;
CREATE VIEW
<database>=# CREATE VIEW user_view AS
<database>-#         SELECT attrelid, attname, attnum, mat_id
<database>-#           FROM objs, pg_attribute
<database>-#          WHERE attrelid = objs.user_view;
CREATE VIEW
<database>=# CREATE VIEW direct_view AS
<database>-#         SELECT attrelid, attname, attnum, mat_id
<database>-#           FROM objs, pg_attribute
<database>-#          WHERE attrelid = objs.direct_view;
CREATE VIEW
<database>=# CREATE VIEW rename_tables AS
<database>-# SELECT (SELECT user_view FROM objs WHERE uv.attrelid = user_view),
<database>-#        uv.attname AS new_name,
<database>-#        dv.attname AS old_name,
<database>-#        (SELECT partial_view FROM objs WHERE uv.attrelid = user_view),
<database>-#        (SELECT direct_view FROM objs WHERE uv.attrelid = user_view),
<database>-#        (SELECT mat_table FROM objs WHERE uv.attrelid = user_view),
<database>-#        (SELECT mat_id FROM objs WHERE uv.attrelid = user_view)
<database>-#   FROM user_view uv JOIN direct_view dv USING (mat_id, attnum)
<database>-#  WHERE uv.attname != dv.attname;
CREATE VIEW
<database>=# SELECT * FROM rename_tables;
 hourly_email_bounce_undetermined                           | time          | bucket   | _timescaledb_internal._partial_view_340 | _timescaledb_internal._direct_view_340 | _timescaledb_internal._materialized_hypertable_340 |    340
 hourly_sms_sent                                            | time          | bucket   | _timescaledb_internal._partial_view_341 | _timescaledb_internal._direct_view_341 | _timescaledb_internal._materialized_hypertable_341 |    341
 hourly_sms_delivered                                       | time          | bucket   | _timescaledb_internal._partial_view_342 | _timescaledb_internal._direct_view_342 | _timescaledb_internal._materialized_hypertable_342 |    342
 hourly_sms_clicked                                         | time          | bucket   | _timescaledb_internal._partial_view_343 | _timescaledb_internal._direct_view_343 | _timescaledb_internal._materialized_hypertable_343 |    343
 hourly_sms_subscription_deactivated                        | time          | bucket   | _timescaledb_internal._partial_view_344 | _timescaledb_internal._direct_view_344 | _timescaledb_internal._materialized_hypertable_344 |    344
 hourly_native_app_opened                                   | time          | bucket   | _timescaledb_internal._partial_view_353 | _timescaledb_internal._direct_view_353 | _timescaledb_internal._materialized_hypertable_353 |    353
 hourly_native_clicked                                      | time          | bucket   | _timescaledb_internal._partial_view_354 | _timescaledb_internal._direct_view_354 | _timescaledb_internal._materialized_hypertable_354 |    354
 hourly_native_delivered                                    | time          | bucket   | _timescaledb_internal._partial_view_355 | _timescaledb_internal._direct_view_355 | _timescaledb_internal._materialized_hypertable_355 |    355
 hourly_native_optin_dismissed                              | time          | bucket   | _timescaledb_internal._partial_view_358 | _timescaledb_internal._direct_view_358 | _timescaledb_internal._materialized_hypertable_358 |    358
 hourly_native_optin_shown                                  | time          | bucket   | _timescaledb_internal._partial_view_359 | _timescaledb_internal._direct_view_359 | _timescaledb_internal._materialized_hypertable_359 |    359
 hourly_native_sent                                         | time          | bucket   | _timescaledb_internal._partial_view_360 | _timescaledb_internal._direct_view_360 | _timescaledb_internal._materialized_hypertable_360 |    360
 hourly_native_subscription_cancelled                       | time          | bucket   | _timescaledb_internal._partial_view_361 | _timescaledb_internal._direct_view_361 | _timescaledb_internal._materialized_hypertable_361 |    361
 hourly_native_subscription_created                         | time          | bucket   | _timescaledb_internal._partial_view_362 | _timescaledb_internal._direct_view_362 | _timescaledb_internal._materialized_hypertable_362 |    362
 hourly_native_subscription_deactivated                     | time          | bucket   | _timescaledb_internal._partial_view_363 | _timescaledb_internal._direct_view_363 | _timescaledb_internal._materialized_hypertable_363 |    363
 hourly_email_bounce_permanent                              | time          | bucket   | _timescaledb_internal._partial_view_364 | _timescaledb_internal._direct_view_364 | _timescaledb_internal._materialized_hypertable_364 |    364
 hourly_email_bounce_transient                              | time          | bucket   | _timescaledb_internal._partial_view_365 | _timescaledb_internal._direct_view_365 | _timescaledb_internal._materialized_hypertable_365 |    365
 hourly_email_complaint                                     | time          | bucket   | _timescaledb_internal._partial_view_366 | _timescaledb_internal._direct_view_366 | _timescaledb_internal._materialized_hypertable_366 |    366
 hourly_email_delivered                                     | time          | bucket   | _timescaledb_internal._partial_view_367 | _timescaledb_internal._direct_view_367 | _timescaledb_internal._materialized_hypertable_367 |    367
 hourly_email_optin_failed                                  | time          | bucket   | _timescaledb_internal._partial_view_368 | _timescaledb_internal._direct_view_368 | _timescaledb_internal._materialized_hypertable_368 |    368
 hourly_email_optin_hidden                                  | time          | bucket   | _timescaledb_internal._partial_view_369 | _timescaledb_internal._direct_view_369 | _timescaledb_internal._materialized_hypertable_369 |    369
 hourly_email_optin_shown                                   | time          | bucket   | _timescaledb_internal._partial_view_370 | _timescaledb_internal._direct_view_370 | _timescaledb_internal._materialized_hypertable_370 |    370
 hourly_email_optin_subscribed                              | time          | bucket   | _timescaledb_internal._partial_view_371 | _timescaledb_internal._direct_view_371 | _timescaledb_internal._materialized_hypertable_371 |    371
 hourly_email_subscription_created                          | time          | bucket   | _timescaledb_internal._partial_view_372 | _timescaledb_internal._direct_view_372 | _timescaledb_internal._materialized_hypertable_372 |    372
 hourly_email_subscription_deactivated                      | time          | bucket   | _timescaledb_internal._partial_view_373 | _timescaledb_internal._direct_view_373 | _timescaledb_internal._materialized_hypertable_373 |    373
 hourly_pushnomics_skipped                                  | time          | bucket   | _timescaledb_internal._partial_view_374 | _timescaledb_internal._direct_view_374 | _timescaledb_internal._materialized_hypertable_374 |    374
 hourly_sent_with_parent                                    | time          | bucket   | _timescaledb_internal._partial_view_379 | _timescaledb_internal._direct_view_379 | _timescaledb_internal._materialized_hypertable_379 |    379
(70 rows)

(END)

<database>-# SELECT * FROM rename_tables WHERE partial_view = '_timescaledb_internal._partial_view_288';
ERROR:  invalid input syntax for type oid: "_timescaledb_internal._partial_view_288"
LINE 1: SELECT * FROM rename_tables WHERE partial_view = '_timescale...

@mkindahl
Copy link
Contributor

The partial view you mentioned in the initial report is not in this list and there is no mention of the count column that you had problems with. Are you using the right database?

=# SELECT * FROM rename_tables;
hourly_email_bounce_undetermined | time | bucket | _timescaledb_internal._partial_view_340 | _timescaledb_internal._direct_view_340 | _timescaledb_internal._materialized_hypertable_340 | 340
    .
    .
    .

Not sure how you wrote this, it looks correct. Are you using some non-standard quotes as a result of a cut-and-paste?

-# SELECT * FROM rename_tables WHERE partial_view = '_timescaledb_internal._partial_view_288';
ERROR: invalid input syntax for type oid: "_timescaledb_internal._partial_view_288"
LINE 1: SELECT * FROM rename_tables WHERE partial_view = '_timescale...

@pushpeepkmonroe
Copy link
Author

The error is still present from the initial issue:

psql -X -d -c 'ALTER EXTENSION timescaledb UPDATE;'
ERROR: column "count" does not exist
CONTEXT: SQL statement "ALTER TABLE _timescaledb_internal._partial_view_288 RENAME COLUMN count TO pstag_android"
PL/pgSQL function _timescaledb_internal.alter_table_column(regclass,regclass,name,name) line 3 at EXECUTE
SQL statement "CALL _timescaledb_internal.alter_table_column(user_view, partial_view, old_name, new_name)"
PL/pgSQL function inline_code_block line 16 at CALL

@pushpeepkmonroe
Copy link
Author

The command you told me to run was typed out not copied and pasted:

SELECT * FROM rename_tables WHERE partial_view='_timescaledb_internal._partial_view_288';
ERROR: invalid input syntax for type oid: "_timescaledb_internal._partial_view_288"
LINE 1: SELECT * FROM rename_tables WHERE partial_view='_timescaledb...

@mkindahl
Copy link
Contributor

Try this instead:

SELECT * FROM rename_tables WHERE partial_view::text = '_timescaledb_internal._partial_view_288';

@pushpeepkmonroe
Copy link
Author

pushpeepkmonroe commented Feb 23, 2023

SELECT * FROM rename_tables WHERE partial_view::text = '_timescaledb_internal._partial_view_288';
     user_view      |   new_name    | old_name |              partial_view               |              direct_view               |                     mat_table                      | mat_id
--------------------+---------------+----------+-----------------------------------------+----------------------------------------+----------------------------------------------------+--------
 hourly_nossl_optin | time          | bucket   | _timescaledb_internal._partial_view_288 | _timescaledb_internal._direct_view_288 | _timescaledb_internal._materialized_hypertable_288 |    288
 hourly_nossl_optin | pstag         | website  | _timescaledb_internal._partial_view_288 | _timescaledb_internal._direct_view_288 | _timescaledb_internal._materialized_hypertable_288 |    288
 hourly_nossl_optin | pstag_android | count    | _timescaledb_internal._partial_view_288 | _timescaledb_internal._direct_view_288 | _timescaledb_internal._materialized_hypertable_288 |    288
(3 rows)

@pushpeepkmonroe
Copy link
Author

SELECT * FROM direct_view WHERE attname LIKE '%count%';
491622 | account | 2 | 207
491622 | count | 5 | 207
494018 | account | 2 | 208
494018 | count | 5 | 208
494412 | account | 2 | 209
494412 | count | 5 | 209
675326 | account | 2 | 210
675326 | count | 5 | 210
756745 | account | 2 | 230
756745 | count | 8 | 230
582164196 | account | 2 | 344
582164196 | count | 4 | 344
763209 | account | 2 | 235
763209 | count | 10 | 235
778991 | account | 2 | 237
778991 | count | 10 | 237
780623 | account | 2 | 238
780623 | count | 10 | 238
583869033 | account | 2 | 373
583869033 | count | 8 | 373
596851208 | account | 2 | 472
596851208 | count | 5 | 472
321726 | account | 2 | 193
321726 | count | 6 | 193
484924 | account | 2 | 206
484924 | country | 10 | 206
484924 | count | 11 | 206
176515779 | account | 2 | 288
176515779 | count | 9 | 288
176557371 | account | 2 | 290
176557371 | count | 12 | 290
176642363 | account | 2 | 292
176642363 | count | 6 | 292
89550391 | account | 2 | 267
89550391 | count | 8 | 267
85432888 | account | 2 | 266
85432888 | count | 8 | 266
113356 | account | 2 | 150
113356 | count | 6 | 150
153413943 | account | 2 | 270
153413943 | count | 4 | 270
153470963 | account | 2 | 272
153470963 | count | 6 | 272
153536314 | account | 2 | 274
153536314 | count | 6 | 274
154667676 | account | 2 | 278
154667676 | count | 6 | 278
154670565 | account | 2 | 279
154670565 | count | 11 | 279
176241491 | account | 2 | 282
176241491 | count | 4 | 282
176284739 | account | 2 | 284
176284739 | count | 4 | 284
176499003 | account | 2 | 286
176499003 | count | 4 | 286
596852078 | account | 2 | 474
596852078 | count | 6 | 474
234702637 | count | 2 | 297
234702695 | count | 2 | 298
234702724 | count | 2 | 299
(158 rows)

@pushpeepkmonroe
Copy link
Author

pushpeepkmonroe commented Feb 23, 2023

\d+ _timescaledb_internal._partial_view_288
                            View "_timescaledb_internal._partial_view_288"
      Column      |           Type           | Collation | Nullable | Default | Storage  | Description
------------------+--------------------------+-----------+----------+---------+----------+-------------
 bucket           | timestamp with time zone |           |          |         | plain    |
 account          | text                     |           |          |         | extended |
 browser_name     | text                     |           |          |         | extended |
 browser_version  | text                     |           |          |         | extended |
 device_type      | text                     |           |          |         | extended |
 platform_name    | text                     |           |          |         | extended |
 platform_version | text                     |           |          |         | extended |
 website          | text                     |           |          |         | extended |
 agg_9_9          | bytea                    |           |          |         | extended |
 chunk_id         | integer                  |           |          |         | plain    |
View definition:
 SELECT time_bucket('01:00:00'::interval, webpush_nossl_optin_shown."time") AS bucket,
    webpush_nossl_optin_shown.account,
    webpush_nossl_optin_shown.browser_name,
    webpush_nossl_optin_shown.browser_version,
    webpush_nossl_optin_shown.device_type,
    webpush_nossl_optin_shown.platform_name,
    webpush_nossl_optin_shown.platform_version,
    webpush_nossl_optin_shown.website,
    _timescaledb_internal.partialize_agg(sum(webpush_nossl_optin_shown.count)) AS agg_9_9,
    _timescaledb_internal.chunk_id_from_relid(webpush_nossl_optin_shown.tableoid) AS chunk_id
   FROM webpush_nossl_optin_shown
  GROUP BY (time_bucket('01:00:00'::interval, webpush_nossl_optin_shown."time")), webpush_nossl_optin_shown.account, webpush_nossl_optin_shown.browser_name, webpush_nossl_optin_shown.browser_version, webpush_nossl_optin_shown.device_type, webpush_nossl_optin_shown.platform_name, webpush_nossl_optin_shown.platform_version, webpush_nossl_optin_shown.website, (_timescaledb_internal.chunk_id_from_relid(webpush_nossl_optin_shown.tableoid));

@pushpeepkmonroe
Copy link
Author

pushpeepkmonroe commented Feb 23, 2023

We are using the old partial aggregate format as it is a bytea column type as well. Which is deprecated, but I am not sure when.

@mkindahl
Copy link
Contributor

We are using the old partial aggregate format as it is a bytea column type as well. Which is deprecated, but I am not sure when.

The deprecation announcement is in the release notes for 2.10

@mkindahl
Copy link
Contributor

This is straightforward to reproduce:

Start a docker image:

mats@fury:~/issues/tsdb5348$ docker run -d -p 5432:5432 -e POSTGRES_HOST_AUTH_METHOD=trust timescale/timescaledb:2.4.0-pg12

Connect to the database (using psql --port 5432 --host=localhost) and create a continuous aggregate using the old format. This is the default for 2.4.0.

-- Create a hypertable with some data
CREATE TABLE conditions(
    time TIMESTAMP NOT NULL,
    device_id INTEGER,
    temperature numeric,
    humidity numeric
);

SELECT * FROM create_hypertable('conditions', 'time', 'device_id', 12);

INSERT INTO conditions
SELECT time, (random()*3 + 1)::int, random()*80 - 40, random()*100
FROM generate_series(now() - INTERVAL '28 days', now(), '1 hour') AS time;

-- Create two continuous aggregates. Note that 2.4 automatically
-- creates the old-style continuous aggregate while the new one
-- requires timescaledb.finalized=false to create an old-style format.
CREATE MATERIALIZED VIEW conditions_summary_hourly
WITH (timescaledb.continuous) AS
SELECT device_id,
       time_bucket(INTERVAL '1 hour', "time") AS bucket,
       AVG(temperature),
       MAX(temperature),
       MIN(temperature)
FROM conditions
GROUP BY device_id, bucket
WITH NO DATA;

CREATE MATERIALIZED VIEW conditions_summary_daily
WITH (timescaledb.continuous) AS
SELECT device_id,
       time_bucket(INTERVAL '1 day', "time") AS bucket,
       AVG(temperature),
       MAX(temperature),
       MIN(temperature)
FROM conditions
GROUP BY device_id, bucket
WITH NO DATA;

Using a tweaked version of the view above (where the partial view name is added) it is easy to see that the name for the partial view does not match the name for the direct view:

mats=> select user_view_name, partial_view_name, direct_view_name from rename_tables ;
 user_view_name | partial_view_name | direct_view_name 
----------------+-------------------+------------------
 device_id      | device_id         | device_id
 bucket         | bucket            | bucket
 avg            | agg_3_3           | avg
 max            | agg_4_4           | max
 min            | agg_5_5           | min
 device_id      | device_id         | device_id
 bucket         | bucket            | bucket
 avg            | agg_3_3           | avg
 max            | agg_4_4           | max
 min            | agg_5_5           | min
(10 rows)

This will then fail when running this part of the upgrade script:

DO
$$
DECLARE
    user_view regclass;
    new_name name;
    old_name name;
    partial_view regclass;
    direct_view regclass;
    mat_table regclass;
    ht_id int;
BEGIN
  FOR user_view, new_name, old_name, partial_view, direct_view, mat_table, ht_id IN
  SELECT * FROM _timescaledb_internal.rename_tables
  LOOP
    -- There is no RENAME COLUMN for views, but we can use ALTER TABLE
    -- to rename a column in a view.
--> CALL _timescaledb_internal.alter_table_column(user_view, partial_view, old_name, new_name); <--
    CALL _timescaledb_internal.alter_table_column(user_view, direct_view, old_name, new_name);
    CALL _timescaledb_internal.alter_table_column(user_view, mat_table, old_name, new_name);
    UPDATE _timescaledb_catalog.dimension SET column_name = new_name
     WHERE hypertable_id = ht_id AND column_name = old_name;
  END LOOP;
END
$$;

@pushpeepkmonroe
Copy link
Author

You reproduced the error that I am initially having through Docker in your latest comment. Is there any workaround?

@mkindahl
Copy link
Contributor

You reproduced the error that I am initially having through Docker in your latest comment. Is there any workaround?

This is what I'm looking into. Reproduction is the first step.

@mkindahl mkindahl added continuous_aggregate upgrade Issue is related to upgrading the extension or the PostgreSQL version. labels Feb 27, 2023
@mkindahl mkindahl changed the title [Bug]: Has anyone ran into this problem upgrading timescale from 2.4.0 to 2.9.3 on postgresql-12 OS ubuntu? Is there a workaround? [Bug]: Upgrading timescale from 2.4.0 to 2.9.3 with partial aggregate continuous aggregate fails Feb 27, 2023
@mkindahl mkindahl changed the title [Bug]: Upgrading timescale from 2.4.0 to 2.9.3 with partial aggregate continuous aggregate fails [Bug]: Upgrading timescale with partial aggregate continuous aggregate fails Feb 27, 2023
@mkindahl
Copy link
Contributor

mkindahl commented Feb 27, 2023

In order to do an upgrade, it is necessary to do the renames manually before the actual upgrade. The update script will check if there are any renames that needs to be done and not do them if all looks good already.

The following procedure seems to work for that purpose, but use it at your own risk.

CREATE PROCEDURE alter_table_column(relation regclass, old_column_name name, new_column_name name) AS $$
BEGIN
    EXECUTE format('ALTER TABLE %s RENAME COLUMN %I TO %I', relation, old_column_name, new_column_name);
EXCEPTION
    WHEN SQLSTATE '42701' THEN
       -- Do nothing and just ignore it
END;
$$ LANGUAGE plpgsql;

CREATE PROCEDURE upgrade_all_caggs() AS 
$$
DECLARE
       user_view regclass;
       user_column text;
       partial_view regclass;
       partial_column text;
       direct_view regclass;
       direct_column text;
       mat_table regclass;
       ht_id int;
BEGIN
  PERFORM timescaledb_pre_restore();
  FOR user_view, user_column, direct_view, direct_column, partial_view, partial_column, mat_table, ht_id IN
  WITH
    objs AS (
	  SELECT format('%I.%I', user_view_schema, user_view_name)::regclass AS user_view,
		 format('%I.%I', direct_view_schema, direct_view_name)::regclass AS direct_view,
		 format('%I.%I', partial_view_schema, partial_view_name)::regclass AS partial_view,
		 format('%I.%I', schema_name, table_name)::regclass AS mat_table,
		 mat_hypertable_id AS mat_id
	    FROM _timescaledb_catalog.continuous_agg
	    JOIN _timescaledb_catalog.hypertable ON mat_hypertable_id = id),
    user_view AS (SELECT attrelid, attname, attnum, mat_id
	            FROM objs, pg_attribute
	           WHERE attrelid = objs.user_view),
    partial_view AS (SELECT attrelid, attname, attnum, mat_id
	               FROM objs, pg_attribute
	              WHERE attrelid = objs.partial_view),
    direct_view AS (SELECT attrelid, attname, attnum, mat_id
   	    	      FROM objs, pg_attribute
	             WHERE attrelid = objs.direct_view)
  SELECT (SELECT objs.user_view FROM objs WHERE uv.attrelid = objs.user_view),
	 uv.attname AS user_column,
	 (SELECT objs.direct_view FROM objs WHERE uv.attrelid = objs.user_view),
	 dv.attname AS direct_column,
	 (SELECT objs.partial_view FROM objs WHERE uv.attrelid = objs.user_view),
	 pv.attname AS partial_column,
	 (SELECT objs.mat_table FROM objs WHERE uv.attrelid = objs.user_view),
	 (SELECT objs.mat_id FROM objs WHERE uv.attrelid = objs.user_view)
    FROM user_view uv JOIN direct_view dv USING (mat_id, attnum)
		      JOIN partial_view pv USING (mat_id, attnum)
  LOOP
    CALL alter_table_column(partial_view, partial_column, user_column);
    CALL alter_table_column(direct_view, direct_column, user_column);
    CALL alter_table_column(mat_table, partial_column, user_column);
    UPDATE _timescaledb_catalog.dimension SET column_name = user_column
    WHERE hypertable_id = ht_id AND column_name = direct_column;
  END LOOP;
  PERFORM timescaledb_post_restore();
END
$$ LANGUAGE plpgsql;

Update: the procedure was updated to capture a failure to alter the column name so that it does not abort altering other columns.

@pushpeepkmonroe
Copy link
Author

This will rename the column agg_9_9 to count in the _timescaledb_internal._partial_view_288 in order to upgrade. Then we will have to rename it back, correct?

@mkindahl
Copy link
Contributor

This will rename the column agg_9_9 to count in the _timescaledb_internal._partial_view_288 in order to upgrade. Then we will have to rename it back, correct?

No. When renaming the column of the partial and direct view the update script will ignore them. It only processes continuous aggregates where the name of the user view and direct view is different.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug continuous_aggregate upgrade Issue is related to upgrading the extension or the PostgreSQL version.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants