YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/yql/pgwrapper/pg_wrapper.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
13
#ifndef YB_YQL_PGWRAPPER_PG_WRAPPER_H
14
#define YB_YQL_PGWRAPPER_PG_WRAPPER_H
15
16
#include <string>
17
#include <atomic>
18
19
#include <boost/optional.hpp>
20
21
#include "yb/gutil/ref_counted.h"
22
#include "yb/util/subprocess.h"
23
#include "yb/util/status_fwd.h"
24
#include "yb/util/enums.h"
25
26
namespace yb {
27
28
class Thread;
29
30
namespace pgwrapper {
31
32
// Returns the root directory of our PostgreSQL installation.
33
std::string GetPostgresInstallRoot();
34
35
// Configuration for an external PostgreSQL server.
36
struct PgProcessConf {
37
  static constexpr uint16_t kDefaultPort = 5433;
38
39
  static Result<PgProcessConf> CreateValidateAndRunInitDb(
40
      const std::string& bind_addresses,
41
      const std::string& data_dir,
42
      const int tserver_shm_fd);
43
44
  std::string ToString();
45
46
  std::string data_dir;
47
  uint16_t pg_port = kDefaultPort;
48
  std::string listen_addresses = "0.0.0.0";
49
  std::string master_addresses;
50
  std::string certs_dir;
51
  std::string certs_for_client_dir;
52
  std::string cert_base_name;
53
  bool enable_tls = false;
54
55
  // File descriptor of the local tserver's shared memory.
56
  int tserver_shm_fd = -1;
57
58
  // If this is true, we will not log to the file, even if the log file is specified.
59
  bool force_disable_log_file = false;
60
};
61
62
// Invokes a PostgreSQL child process once. Also allows invoking initdb. Not thread-safe.
63
class PgWrapper {
64
 public:
65
  explicit PgWrapper(PgProcessConf conf);
66
67
  // Checks if we have a valid configuration in order to be able to run PostgreSQL.
68
  CHECKED_STATUS PreflightCheck();
69
70
  CHECKED_STATUS Start();
71
72
  void Kill();
73
74
  // Calls initdb if the data directory does not exist. This is intended to use during tablet server
75
  // initialization.
76
  CHECKED_STATUS InitDbLocalOnlyIfNeeded();
77
78
  // Calls PostgreSQL's initdb program for initial database initialization.
79
  // yb_enabled - whether initdb should be talking to YugaByte cluster, or just initialize a
80
  //              PostgreSQL data directory. The former is only done once from outside of the YB
81
  //              cluster, and the latter is done on every tablet server startup.
82
  CHECKED_STATUS InitDb(bool yb_enabled);
83
84
  // Waits for the running PostgreSQL process to complete. Returns the exit code or an error.
85
  // Non-zero exit codes are considered non-error cases for the purpose of this function.
86
  Result<int> Wait();
87
88
  // Run initdb in a mode that sets up the required metadata in the YB cluster. This is done
89
  // only once after the cluster has started up. tmp_dir_base is used as a base directory to
90
  // create a temporary PostgreSQL directory that is later deleted.
91
  static Status InitDbForYSQL(
92
      const std::string& master_addresses, const std::string& tmp_dir_base, int tserver_shm_fd);
93
94
 private:
95
  static std::string GetPostgresExecutablePath();
96
  static std::string GetPostgresLibPath();
97
  static std::string GetPostgresThirdPartyLibPath();
98
  static std::string GetInitDbExecutablePath();
99
  static CHECKED_STATUS CheckExecutableValid(const std::string& executable_path);
100
101
  // Set common environment for a child process (initdb or postgres itself).
102
  void SetCommonEnv(Subprocess* proc, bool yb_enabled);
103
104
  PgProcessConf conf_;
105
  boost::optional<Subprocess> pg_proc_;
106
};
107
108
YB_DEFINE_ENUM(PgProcessState,
109
    (kNotStarted)
110
    (kRunning)
111
    (kStopping)
112
    (kStopped));
113
114
// Keeps a PostgreSQL process running in the background, and restarts in case it crashes.
115
// Starts a separate thread to monitor the child process.
116
class PgSupervisor {
117
 public:
118
  explicit PgSupervisor(PgProcessConf conf);
119
  ~PgSupervisor();
120
121
  CHECKED_STATUS Start();
122
  void Stop();
123
  PgProcessState GetState();
124
125
0
  const PgProcessConf& conf() const {
126
0
    return conf_;
127
0
  }
128
129
 private:
130
  CHECKED_STATUS ExpectStateUnlocked(PgProcessState state);
131
  CHECKED_STATUS StartServerUnlocked();
132
  void RunThread();
133
  CHECKED_STATUS CleanupOldServerUnlocked();
134
135
  PgProcessConf conf_;
136
  boost::optional<PgWrapper> pg_wrapper_;
137
  PgProcessState state_ = PgProcessState::kNotStarted;
138
  scoped_refptr<Thread> supervisor_thread_;
139
  std::mutex mtx_;
140
};
141
142
}  // namespace pgwrapper
143
}  // namespace yb
144
145
#endif  // YB_YQL_PGWRAPPER_PG_WRAPPER_H