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