diff --git a/compute_tools/src/checker.rs b/compute_tools/src/checker.rs index b6a287bdeb..6f52004fa8 100644 --- a/compute_tools/src/checker.rs +++ b/compute_tools/src/checker.rs @@ -1,12 +1,39 @@ -use anyhow::{anyhow, Result}; +use anyhow::{anyhow, Ok, Result}; +use postgres::Client; use tokio_postgres::NoTls; use tracing::{error, instrument}; use crate::compute::ComputeNode; +/// Create a special service table for availability checks +/// only if it does not exist already. +pub fn create_availability_check_data(client: &mut Client) -> Result<()> { + let query = " + DO $$ + BEGIN + IF NOT EXISTS( + SELECT 1 + FROM pg_catalog.pg_tables + WHERE tablename = 'health_check' + ) + THEN + CREATE TABLE health_check ( + id serial primary key, + updated_at timestamptz default now() + ); + INSERT INTO health_check VALUES (1, now()) + ON CONFLICT (id) DO UPDATE + SET updated_at = now(); + END IF; + END + $$;"; + client.execute(query, &[])?; + + Ok(()) +} + /// Update timestamp in a row in a special service table to check /// that we can actually write some data in this particular timeline. -/// Create table if it's missing. #[instrument(skip_all)] pub async fn check_writability(compute: &ComputeNode) -> Result<()> { // Connect to the database. @@ -24,19 +51,15 @@ pub async fn check_writability(compute: &ComputeNode) -> Result<()> { }); let query = " - CREATE TABLE IF NOT EXISTS health_check ( - id serial primary key, - updated_at timestamptz default now() - ); INSERT INTO health_check VALUES (1, now()) ON CONFLICT (id) DO UPDATE SET updated_at = now();"; let result = client.simple_query(query).await?; - if result.len() != 2 { + if result.len() != 1 { return Err(anyhow::format_err!( - "expected 2 query results, but got {}", + "expected 1 query result, but got {}", result.len() )); } diff --git a/compute_tools/src/compute.rs b/compute_tools/src/compute.rs index 03ae39f79f..5c08ebe06a 100644 --- a/compute_tools/src/compute.rs +++ b/compute_tools/src/compute.rs @@ -27,6 +27,7 @@ use utils::measured_stream::MeasuredReader; use remote_storage::{DownloadError, GenericRemoteStorage, RemotePath}; +use crate::checker::create_availability_check_data; use crate::pg_helpers::*; use crate::spec::*; use crate::sync_sk::{check_if_synced, ping_safekeeper}; @@ -696,6 +697,7 @@ impl ComputeNode { handle_role_deletions(spec, self.connstr.as_str(), &mut client)?; handle_grants(spec, self.connstr.as_str())?; handle_extensions(spec, &mut client)?; + create_availability_check_data(&mut client)?; // 'Close' connection drop(client); diff --git a/control_plane/src/endpoint.rs b/control_plane/src/endpoint.rs index 7ebcf98ab0..4ed03c8771 100644 --- a/control_plane/src/endpoint.rs +++ b/control_plane/src/endpoint.rs @@ -138,7 +138,13 @@ impl ComputeControlPlane { mode, tenant_id, pg_version, - skip_pg_catalog_updates: false, + // We don't setup roles and databases in the spec locally, so we don't need to + // do catalog updates. Catalog updates also include check availability + // data creation. Yet, we have tests that check that size and db dump + // before and after start are the same. So, skip catalog updates, + // with this we basically test a case of waking up an idle compute, where + // we also skip catalog updates in the cloud. + skip_pg_catalog_updates: true, }); ep.create_endpoint_dir()?; @@ -152,7 +158,7 @@ impl ComputeControlPlane { http_port, pg_port, pg_version, - skip_pg_catalog_updates: false, + skip_pg_catalog_updates: true, })?, )?; std::fs::write(