userver: userver/storages/postgres/component.hpp Source File
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
component.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/postgres/component.hpp
4/// @brief @copybrief components::Postgres
5
6#include <chrono>
7
8#include <userver/components/component_base.hpp>
9#include <userver/concurrent/async_event_source.hpp>
10#include <userver/dynamic_config/snapshot.hpp>
11#include <userver/engine/mutex.hpp>
12#include <userver/storages/secdist/secdist.hpp>
13#include <userver/utils/statistics/entry.hpp>
14
15#include <userver/storages/postgres/database.hpp>
16
17USERVER_NAMESPACE_BEGIN
18
19namespace components {
20
21// clang-format off
22
23/// @ingroup userver_components
24///
25/// @brief PosgreSQL client component
26///
27/// Provides access to a PostgreSQL cluster.
28///
29/// ## Dynamic options:
30/// * @ref POSTGRES_DEFAULT_COMMAND_CONTROL
31/// * @ref POSTGRES_HANDLERS_COMMAND_CONTROL
32/// * @ref POSTGRES_QUERIES_COMMAND_CONTROL
33/// * @ref POSTGRES_CONNECTION_POOL_SETTINGS
34/// * @ref POSTGRES_TOPOLOGY_SETTINGS
35/// * @ref POSTGRES_CONNECTION_SETTINGS
36/// * @ref POSTGRES_STATEMENT_METRICS_SETTINGS
37/// * @ref POSTGRES_CONNLIMIT_MODE_AUTO_ENABLED
38///
39/// ## Static configuration example:
40///
41/// ```
42/// # yaml
43/// postgres-taxi:
44/// dbalias: taxi
45/// blocking_task_processor: task-processor-name
46/// max_replication_lag: 60s
47/// min_pool_size: 4
48/// max_pool_size: 15
49/// max_queue_size: 200
50/// max_statement_metrics: 50
51/// ```
52/// You must specify either `dbalias` or `dbconnection`.
53/// If the component is configured with an alias, it will lookup connection data
54/// in Secdist.
55///
56/// It is a common practice to provide a database connection string via
57/// environment variables. To retrieve a value from the environment use
58/// `dbconnection#env: THE_ENV_VARIABLE_WITH_CONNECTION_STRING` as described
59/// in yaml_config::YamlConfig.
60///
61/// You must specify `blocking_task_processor` as well.
62///
63/// `max_replication_lag` can be used to tune replication lag limit for replicas.
64/// Once the replica lag exceeds this value it will be automatically disabled.
65/// Note, however, that client-size lag detection is not precise in nature
66/// and can only provide the precision of couple seconds.
67///
68/// ## Secdist format
69///
70/// A PosgreSQL alias in secdist is described as a JSON array of objects
71/// containing a single cluster description. There are two formats of describing
72/// a cluster, the first one assigns predefined roles to DSNs, the second one
73/// is just a list of DSNs and the Postgres component takes care of discovering
74/// the cluster's topology itself.
75///
76/// Note that if the `dbalias` option is provided and components::Secdist component has `update-period` other
77/// than 0, then new connections are created or gracefully closed as the secdist configuration change to new value.
78///
79/// ### Predefined roles
80///
81/// In predefined roles format the component requires single-host connection
82/// strings.
83///
84/// ```json
85/// {
86/// "shard_number" : 0,
87/// "master": "host=localhost dbname=example",
88/// "sync_slave": "host=localhost dbname=example",
89/// "slaves": [
90/// "host=localhost dbname=example"
91/// ]
92/// }
93/// ```
94///
95/// The predefined roles format is deprecated and the support will be removed
96/// soon.
97///
98/// ### Automatic discovery
99///
100/// In automatic discovery format the connection strings are any valid
101/// PostgreSQL connection strings including multi-host ones with the exception
102/// of `target_session_attrs` which will be ignored.
103///
104/// ```json
105/// {
106/// "shard_number" : 0,
107/// "hosts": [
108/// "host=host1,host2,host3 dbname=example",
109/// "postgresql://host1:5432,host2:6432,host3:12000/example"
110/// ]
111/// }
112/// ```
113///
114/// The `shard_number` parameter is required in both formats and must match the
115/// index of cluster description object in the alias array.
116///
117/// Please see [PostgreSQL documentation](https://www.postgresql.org/docs/12/libpq-connect.html#LIBPQ-CONNSTRING)
118/// on connection strings.
119///
120/// ## Static options:
121/// Name | Description | Default value
122/// ----------------------- | ----------------------------------------------------------------------------- | -------------
123/// dbalias | name of the database in secdist config (if available) | --
124/// name_alias | name alias to use in dynamic configs | name of the component
125/// dbconnection | connection DSN string (used if no dbalias specified) | --
126/// blocking_task_processor | name of task processor for background blocking operations | engine::current_task::GetBlockingTaskProcessor()
127/// max_replication_lag | replication lag limit for usable slaves | 60s
128/// sync-start | perform initial connections synchronously | true
129/// dns_resolver | server hostname resolver type (getaddrinfo or async) | 'async'
130/// persistent-prepared-statements | cache prepared statements or not | true
131/// user-types-enabled | allow use of user-defined types | true
132/// check-user-types | cancel service start if some user types have not been loaded, which helps to detect missing migrations | false
133/// ignore_unused_query_params| disable check for not-NULL query params that are not used in query | false
134/// monitoring-dbalias | name of the database for monitorings | calculated from dbalias or dbconnection options
135/// max_prepared_cache_size | prepared statements cache size limit | 200
136/// max_statement_metrics | limit of exported metrics for named statements | 0
137/// min_pool_size | number of connections created initially | 4
138/// max_pool_size | maximum number of created connections for "connlimit_mode: manual" | 15
139/// max_queue_size | maximum number of clients waiting for a connection | 200
140/// connecting_limit | limit for concurrent establishing connections number per pool (0 - unlimited) | 0
141/// connlimit_mode | max_connections setup mode (manual or auto), also see @ref scripts/docs/en/userver/pg_connlimit_mode_auto.md | auto
142/// error-injection | artificial error injection settings, error_injection::Settings | --
143/// deadline-propagation-enabled | whether deadline propagation sets statement timeout | true
144
145// clang-format on
146
147class Postgres : public ComponentBase {
148public:
149 /// Default shard number
150 static constexpr size_t kDefaultShardNumber = 0;
151 /// Default command control
152 static constexpr storages::postgres::CommandControl kDefaultCommandControl{
153 std::chrono::milliseconds{500}, // network timeout
154 std::chrono::milliseconds{250} // statement timeout
155 };
156
157 /// Component constructor
158 Postgres(const ComponentConfig&, const ComponentContext&);
159 /// Component destructor
160 ~Postgres() override;
161
162 /// Cluster accessor for default shard number
163 storages::postgres::ClusterPtr GetCluster() const;
164
165 /// Cluster accessor for specific shard number
166 storages::postgres::ClusterPtr GetClusterForShard(size_t shard) const;
167
168 /// Get total shard count
169 size_t GetShardCount() const;
170
171 /// Get database object
172 storages::postgres::DatabasePtr GetDatabase() const { return database_; }
173
174 /// Reports statistics for PostgreSQL driver
175 void ExtendStatistics(utils::statistics::Writer& writer);
176
177 static yaml_config::Schema GetStaticConfigSchema();
178
179private:
180 void OnConfigUpdate(const dynamic_config::Snapshot& cfg);
181
182 void OnSecdistUpdate(const storages::secdist::SecdistConfig& secdist);
183
184 std::string name_;
185 std::string db_name_;
186 std::string dbalias_;
187 storages::postgres::ClusterSettings initial_settings_;
188 storages::postgres::DatabasePtr database_;
189
190 // Subscriptions must be the last fields, because the fields above are used
191 // from callbacks.
192 concurrent::AsyncEventSubscriberScope config_subscription_;
193 concurrent::AsyncEventSubscriberScope secdist_subscription_;
194 utils::statistics::Entry statistics_holder_;
195 dynamic_config::Source config_source_;
196};
197
198template <>
199inline constexpr bool kHasValidate<Postgres> = true;
200
201} // namespace components
202
203USERVER_NAMESPACE_END