Open a Postgres [Consensus] instance with `config`, for the collection named `shard`.
(config: PostgresConsensusConfig)
| 273 | /// Open a Postgres [Consensus] instance with `config`, for the collection |
| 274 | /// named `shard`. |
| 275 | pub async fn open(config: PostgresConsensusConfig) -> Result<Self, ExternalError> { |
| 276 | // don't need to unredact here because we just want to pull out the username |
| 277 | let pg_config: Config = config.url.to_string().parse()?; |
| 278 | let role = pg_config.get_user().expect("failed to get PostgreSQL user"); |
| 279 | let create_schema = format!( |
| 280 | "CREATE SCHEMA IF NOT EXISTS consensus AUTHORIZATION {}", |
| 281 | escape_identifier(role), |
| 282 | ); |
| 283 | |
| 284 | let dyncfg = Arc::clone(&config.dyncfg); |
| 285 | |
| 286 | // Filled in below once we've detected the backend. The isolation resolver runs per |
| 287 | // connection, so the flag takes effect as the pool cycles connections. |
| 288 | let is_pg_backend = Arc::new(AtomicBool::new(false)); |
| 289 | let client_config = PostgresClientConfig::new(config.url, config.knobs, config.metrics) |
| 290 | .with_isolation(Arc::new({ |
| 291 | let dyncfg = Arc::clone(&dyncfg); |
| 292 | let is_pg_backend = Arc::clone(&is_pg_backend); |
| 293 | move || { |
| 294 | let flag_enabled = USE_POSTGRES_TUNED_QUERIES.get(&dyncfg); |
| 295 | let is_pg_backend = is_pg_backend.load(Ordering::Relaxed); |
| 296 | if flag_enabled && is_pg_backend { |
| 297 | IsolationLevel::ReadCommitted |
| 298 | } else { |
| 299 | IsolationLevel::Serializable |
| 300 | } |
| 301 | } |
| 302 | })); |
| 303 | let postgres_client = PostgresClient::open(client_config)?; |
| 304 | |
| 305 | let client = postgres_client.get_connection().await?; |
| 306 | |
| 307 | let mode = match pg_batch_execute( |
| 308 | &client, |
| 309 | &format!( |
| 310 | "{}; {}{}; {};", |
| 311 | create_schema, SCHEMA, CRDB_SCHEMA_OPTIONS, CRDB_CONFIGURE_ZONE, |
| 312 | ), |
| 313 | ) |
| 314 | .await |
| 315 | { |
| 316 | Ok(()) => PostgresMode::CockroachDB, |
| 317 | Err(e) if e.code() == Some(&SqlState::INSUFFICIENT_PRIVILEGE) => { |
| 318 | warn!( |
| 319 | "unable to ALTER TABLE consensus, this is expected and OK when connecting with a read-only user" |
| 320 | ); |
| 321 | PostgresMode::CockroachDB |
| 322 | } |
| 323 | // Vanilla Postgres doesn't support the Cockroach zone configuration |
| 324 | // that we attempted, so we use that to determine what mode we're in. |
| 325 | Err(e) |
| 326 | if e.code() == Some(&SqlState::INVALID_PARAMETER_VALUE) |
| 327 | || e.code() == Some(&SqlState::SYNTAX_ERROR) => |
| 328 | { |
| 329 | info!( |
| 330 | "unable to initiate consensus with CRDB params, this is expected and OK when running against Postgres: {:?}", |
| 331 | e |
| 332 | ); |
nothing calls this directly
no test coverage detected