Skip to content

Commit 30962ae

Browse files
committed
[#25373] YSQL: Avoid lazy initialization of YsqlAdvisoryLocksTable
Summary: Lazy initialization of the `YsqlAdvisoryLocksTable` object requires too much of tangling code. It is much easier to use `std::shared_future<client::YBClient*>` instead of `client::YBClient&` in the `YsqlAdvisoryLocksTable`'s constructor. Like other classes does: `PgTableCache`, `CDCStateTable`. **Note:** In context of this diff some additional improvement is performed: - created helper function `ValueAsFuture` - removed redundant constructor from `CDCStateTable` (it breaks thread safety) - included missed headers Jira: DB-14603 Test Plan: Jenkins Reviewers: pjain, hsunder, bkolagani, yyan, xCluster Reviewed By: hsunder Subscribers: ycdcxcluster, ybase, yql Tags: #jenkins-ready Differential Revision: https://phorge.dev.yugabyte.com/D40808
1 parent 79c1abb commit 30962ae

27 files changed

+216
-228
lines changed

src/yb/cdc/cdc_state_table.cc

+21-47
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@
3030
#include "yb/util/atomic.h"
3131
#include "yb/util/logging.h"
3232
#include "yb/util/stol_utils.h"
33-
3433
#include "yb/util/string_util.h"
34+
3535
#include "yb/yql/cql/ql/util/statement_result.h"
3636

3737
DEFINE_RUNTIME_int32(cdc_state_table_num_tablets, 0,
@@ -323,8 +323,6 @@ CDCStateTable::CDCStateTable(std::shared_future<client::YBClient*> client_future
323323
CHECK(client_future_.valid());
324324
}
325325

326-
CDCStateTable::CDCStateTable(client::YBClient* client) : client_(client) { CHECK_NOTNULL(client); }
327-
328326
std::string CDCStateTableKey::ToString() const {
329327
return Format(
330328
"TabletId: $0, StreamId: $1 $2", tablet_id, stream_id,
@@ -435,33 +433,28 @@ Result<master::CreateTableRequestPB> CDCStateTable::GenerateCreateCdcStateTableR
435433
}
436434

437435
Status CDCStateTable::WaitForCreateTableToFinishWithCache() {
438-
if (created_) {
439-
return Status::OK();
436+
if (!created_) {
437+
RETURN_NOT_OK(WaitForCreateTableToFinishWithoutCache());
438+
created_ = true;
440439
}
441-
auto* client = VERIFY_RESULT(GetClient());
442-
RETURN_NOT_OK(client->WaitForCreateTableToFinish(kCdcStateYBTableName));
443-
created_ = true;
444440
return Status::OK();
445441
}
446442

447443
Status CDCStateTable::WaitForCreateTableToFinishWithoutCache() {
448-
auto* client = VERIFY_RESULT(GetClient());
449-
return client->WaitForCreateTableToFinish(kCdcStateYBTableName);
444+
return client().WaitForCreateTableToFinish(kCdcStateYBTableName);
450445
}
451446

452-
Status CDCStateTable::OpenTable(client::TableHandle* cdc_table) {
453-
auto* client = VERIFY_RESULT(GetClient());
454-
RETURN_NOT_OK(cdc_table->Open(kCdcStateYBTableName, client));
455-
return Status::OK();
447+
Result<std::shared_ptr<client::TableHandle>> CDCStateTable::OpenTable() {
448+
auto cdc_table = std::make_shared<client::TableHandle>();
449+
RETURN_NOT_OK(cdc_table->Open(kCdcStateYBTableName, &client()));
450+
return cdc_table;
456451
}
457452

458453
Result<std::shared_ptr<client::TableHandle>> CDCStateTable::GetTable() {
459454
bool use_cache = GetAtomicFlag(&FLAGS_enable_cdc_state_table_caching);
460455
if (!use_cache) {
461456
RETURN_NOT_OK(WaitForCreateTableToFinishWithoutCache());
462-
auto cdc_table = std::make_shared<client::TableHandle>();
463-
RETURN_NOT_OK(OpenTable(cdc_table.get()));
464-
return cdc_table;
457+
return OpenTable();
465458
}
466459

467460
{
@@ -472,30 +465,16 @@ Result<std::shared_ptr<client::TableHandle>> CDCStateTable::GetTable() {
472465
}
473466

474467
std::lock_guard l(mutex_);
475-
if (cdc_table_) {
476-
return cdc_table_;
468+
if (!cdc_table_) {
469+
RETURN_NOT_OK(WaitForCreateTableToFinishWithCache());
470+
cdc_table_ = VERIFY_RESULT(OpenTable());
477471
}
478-
RETURN_NOT_OK(WaitForCreateTableToFinishWithCache());
479-
auto cdc_table = std::make_shared<client::TableHandle>();
480-
RETURN_NOT_OK(OpenTable(cdc_table.get()));
481-
cdc_table_.swap(cdc_table);
482472
return cdc_table_;
483473
}
484474

485-
Result<client::YBClient*> CDCStateTable::GetClient() {
486-
if (!client_) {
487-
CHECK(client_future_.valid());
488-
client_ = client_future_.get();
489-
}
490-
491-
SCHECK(client_, IllegalState, "CDC Client not initialized or shutting down");
492-
return client_;
493-
}
494-
495-
Result<std::shared_ptr<client::YBSession>> CDCStateTable::GetSession() {
496-
auto* client = VERIFY_RESULT(GetClient());
497-
auto session = client->NewSession(client->default_rpc_timeout());
498-
return session;
475+
std::shared_ptr<client::YBSession> CDCStateTable::MakeSession() {
476+
auto& c = client();
477+
return c.NewSession(c.default_rpc_timeout());
499478
}
500479

501480
template <class CDCEntry>
@@ -509,7 +488,7 @@ Status CDCStateTable::WriteEntriesAsync(
509488
}
510489

511490
auto cdc_table = VERIFY_RESULT(GetTable());
512-
auto session = VERIFY_RESULT(GetSession());
491+
auto session = MakeSession();
513492

514493
std::vector<client::YBOperationPtr> ops;
515494
ops.reserve(entries.size() * 2);
@@ -621,14 +600,9 @@ Result<CDCStateTableRange> CDCStateTable::GetTableRange(
621600

622601
Result<CDCStateTableRange> CDCStateTable::GetTableRangeAsync(
623602
CDCStateTableEntrySelector&& field_filter, Status* iteration_status) {
624-
auto* client = VERIFY_RESULT(GetClient());
625-
626-
bool table_creation_in_progress = false;
627-
RETURN_NOT_OK(client->IsCreateTableInProgress(kCdcStateYBTableName, &table_creation_in_progress));
628-
if (table_creation_in_progress) {
629-
return STATUS(Uninitialized, "CDC State Table creation is in progress");
630-
}
631-
603+
bool creation_in_progress = false;
604+
RETURN_NOT_OK(client().IsCreateTableInProgress(kCdcStateYBTableName, &creation_in_progress));
605+
SCHECK(!creation_in_progress, Uninitialized, "CDC State Table creation is in progress");
632606
return GetTableRange(std::move(field_filter), iteration_status);
633607
}
634608

@@ -645,7 +619,7 @@ Result<std::optional<CDCStateTableEntry>> CDCStateTable::TryFetchEntry(
645619
narrow_cast<ColumnIdRep>(Schema::first_column_id() + kCdcStreamIdIdx);
646620

647621
auto cdc_table = VERIFY_RESULT(GetTable());
648-
auto session = VERIFY_RESULT(GetSession());
622+
auto session = MakeSession();
649623

650624
const auto read_op = cdc_table->NewReadOp();
651625
auto* const req_read = read_op->mutable_request();

src/yb/cdc/cdc_state_table.h

+10-6
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,22 @@
1212

1313
#pragma once
1414

15+
#include <future>
16+
#include <memory>
17+
#include <optional>
1518
#include <shared_mutex>
19+
#include <string>
1620
#include <unordered_set>
21+
#include <vector>
1722

1823
#include "yb/client/table_handle.h"
1924

2025
#include "yb/common/opid.h"
2126

22-
#include "yb/util/status.h"
2327
#include "yb/gutil/thread_annotations.h"
2428

29+
#include "yb/util/status.h"
30+
2531
namespace yb {
2632

2733
namespace client {
@@ -120,7 +126,6 @@ class CDCStateTableRange;
120126
class CDCStateTable {
121127
public:
122128
explicit CDCStateTable(std::shared_future<client::YBClient*> client_future);
123-
explicit CDCStateTable(client::YBClient* client);
124129

125130
static const std::string& GetNamespaceName();
126131
static const std::string& GetTableName();
@@ -148,12 +153,12 @@ class CDCStateTable {
148153
const CDCStateTableKey& key, CDCStateTableEntrySelector&& field_filter = {}) EXCLUDES(mutex_);
149154

150155
private:
151-
Result<client::YBClient*> GetClient();
152-
Result<std::shared_ptr<client::YBSession>> GetSession();
156+
client::YBClient& client() { return *client_future_.get(); }
157+
std::shared_ptr<client::YBSession> MakeSession();
153158
Status WaitForCreateTableToFinishWithCache() REQUIRES(mutex_);
154159
Status WaitForCreateTableToFinishWithoutCache();
155160
Result<std::shared_ptr<client::TableHandle>> GetTable() EXCLUDES(mutex_);
156-
Status OpenTable(client::TableHandle* cdc_table);
161+
Result<std::shared_ptr<client::TableHandle>> OpenTable();
157162
template <class CDCEntry>
158163
Status WriteEntriesAsync(
159164
const std::vector<CDCEntry>& entries, QLWriteRequestPB::QLStmtType statement_type,
@@ -169,7 +174,6 @@ class CDCStateTable {
169174

170175
std::shared_mutex mutex_;
171176
std::shared_future<client::YBClient*> client_future_;
172-
client::YBClient* client_ = nullptr;
173177

174178
std::shared_ptr<client::TableHandle> cdc_table_ GUARDED_BY(mutex_);
175179
bool created_ GUARDED_BY(mutex_) = false;

src/yb/client/advisory_lock-test.cc

+21-17
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,35 @@
1111
// under the License.
1212
//
1313

14+
#include <future>
15+
#include <optional>
16+
1417
#include "yb/client/meta_cache.h"
1518
#include "yb/client/session.h"
1619
#include "yb/client/table.h"
1720
#include "yb/client/transaction.h"
1821
#include "yb/client/transaction_pool.h"
1922
#include "yb/client/yb_op.h"
2023
#include "yb/client/yb_table_name.h"
24+
2125
#include "yb/common/transaction_error.h"
26+
2227
#include "yb/integration-tests/cluster_itest_util.h"
28+
#include "yb/integration-tests/mini_cluster.h"
29+
#include "yb/integration-tests/yb_mini_cluster_test_base.h"
30+
2331
#include "yb/master/master_defaults.h"
32+
33+
#include "yb/rpc/sidecars.h"
34+
2435
#include "yb/tablet/tablet.h"
2536
#include "yb/tablet/tablet_peer.h"
37+
2638
#include "yb/tserver/mini_tablet_server.h"
2739
#include "yb/tserver/tablet_server.h"
2840
#include "yb/tserver/ysql_advisory_lock_table.h"
2941

30-
#include "yb/integration-tests/mini_cluster.h"
31-
#include "yb/integration-tests/yb_mini_cluster_test_base.h"
32-
33-
#include "yb/rpc/sidecars.h"
42+
#include "yb/util/std_util.h"
3443
#include "yb/util/test_thread_holder.h"
3544

3645
DECLARE_int32(catalog_manager_bg_task_wait_ms);
@@ -87,10 +96,11 @@ class AdvisoryLockTest: public MiniClusterTestWithClient<MiniCluster> {
8796

8897
Status WaitForCreateTableToFinishAndLoadTable() {
8998
client::YBTableName table_name(
90-
YQL_DATABASE_CQL, master::kSystemNamespaceName, kPgAdvisoryLocksTableName);
99+
YQL_DATABASE_CQL, master::kSystemNamespaceName,
100+
std::string(tserver::kPgAdvisoryLocksTableName));
91101
RETURN_NOT_OK(client_->WaitForCreateTableToFinish(
92102
table_name, CoarseMonoClock::Now() + 10s * kTimeMultiplier));
93-
advisory_locks_table_ = GetYsqlAdvisoryLocksTable();
103+
advisory_locks_table_.emplace(ValueAsFuture(client_.get()));
94104
table_ = VERIFY_RESULT(advisory_locks_table_->GetTable());
95105
return Status::OK();
96106
}
@@ -104,16 +114,11 @@ class AdvisoryLockTest: public MiniClusterTestWithClient<MiniCluster> {
104114

105115
Result<std::vector<client::internal::RemoteTabletPtr>> GetTablets() {
106116
CHECK_NOTNULL(table_.get());
107-
auto future = client_->LookupAllTabletsFuture(table_, CoarseMonoClock::Now() + 10s);
108-
return future.get();
109-
}
110-
111-
std::unique_ptr<YsqlAdvisoryLocksTable> GetYsqlAdvisoryLocksTable() {
112-
return std::make_unique<YsqlAdvisoryLocksTable>(*client_.get());
117+
return client_->LookupAllTabletsFuture(table_, CoarseMonoClock::Now() + 10s).get();
113118
}
114119

115120
Result<client::YBTablePtr> GetTable() {
116-
return GetYsqlAdvisoryLocksTable()->GetTable();
121+
return tserver::YsqlAdvisoryLocksTable(ValueAsFuture(client_.get())).GetTable();
117122
}
118123

119124
Result<client::YBTransactionPtr> StartTransaction(
@@ -125,9 +130,8 @@ class AdvisoryLockTest: public MiniClusterTestWithClient<MiniCluster> {
125130
return txn;
126131
}
127132

128-
Status Commit(client::YBTransactionPtr txn) {
129-
auto commit_future = txn->CommitFuture(TransactionRpcDeadline());
130-
return commit_future.get();
133+
static Status Commit(client::YBTransactionPtr txn) {
134+
return txn->CommitFuture(TransactionRpcDeadline()).get();
131135
}
132136

133137
protected:
@@ -137,8 +141,8 @@ class AdvisoryLockTest: public MiniClusterTestWithClient<MiniCluster> {
137141
}
138142

139143
std::unique_ptr<rpc::Sidecars> sidecars_;
140-
std::unique_ptr<YsqlAdvisoryLocksTable> advisory_locks_table_;
141144
client::YBTablePtr table_;
145+
std::optional<tserver::YsqlAdvisoryLocksTable> advisory_locks_table_;
142146
};
143147

144148
TEST_F(AdvisoryLockTest, TestAdvisoryLockTableCreated) {

src/yb/integration-tests/cdc_service-int-test.cc

+5-5
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ void AssertChangeRecords(
255255
}
256256

257257
void VerifyCdcStateNotEmpty(client::YBClient* client) {
258-
CDCStateTable cdc_state_table(client);
258+
auto cdc_state_table = MakeCDCStateTable(client);
259259
Status s;
260260
auto table_range = ASSERT_RESULT(
261261
cdc_state_table.GetTableRange(CDCStateTableEntrySelector().IncludeCheckpoint(), &s));
@@ -278,7 +278,7 @@ Status VerifyCdcStateMatches(
278278
LOG(INFO) << Format("Verifying tablet: $0, stream: $1, op_id: $2",
279279
tablet_id, stream_id, OpId(term, index).ToString());
280280

281-
CDCStateTable cdc_state_table(client);
281+
auto cdc_state_table = MakeCDCStateTable(client);
282282
auto row = VERIFY_RESULT(cdc_state_table.TryFetchEntry(
283283
{tablet_id, stream_id}, CDCStateTableEntrySelector().IncludeCheckpoint()));
284284
SCHECK(row, IllegalState, "CDC state row not found");
@@ -295,7 +295,7 @@ void VerifyStreamDeletedFromCdcState(
295295
const xrepl::StreamId& stream_id,
296296
const TabletId& tablet_id,
297297
int timeout_secs = 10) {
298-
CDCStateTable cdc_state_table(client);
298+
auto cdc_state_table = MakeCDCStateTable(client);
299299

300300
// The deletion of cdc_state rows for the specified stream happen in an asynchronous thread,
301301
// so even if the request has returned, it doesn't mean that the rows have been deleted yet.
@@ -2004,7 +2004,7 @@ TEST_F(CDCServiceTestDurableMinReplicatedIndex, TestBootstrapProducer) {
20042004

20052005
// Verify that for each of the table's tablets, a new row in cdc_state table with the returned
20062006
// id was inserted.
2007-
CDCStateTable cdc_state_table(client_.get());
2007+
auto cdc_state_table = MakeCDCStateTable(client_.get());
20082008
Status s;
20092009
auto table_range = ASSERT_RESULT(
20102010
cdc_state_table.GetTableRange(CDCStateTableEntrySelector().IncludeCheckpoint(), &s));
@@ -2161,7 +2161,7 @@ TEST_F(CDCServiceTestDurableMinReplicatedIndex, TestCdcMinReplicatedIndexAreRese
21612161
WaitForCDCIndex(
21622162
tablet_id, CDCService(tserver), 5, 4 * FLAGS_update_min_cdc_indices_interval_secs);
21632163

2164-
CDCStateTable cdc_state_table(client_.get());
2164+
auto cdc_state_table = MakeCDCStateTable(client_.get());
21652165

21662166
std::vector<CDCStateTableKey> keys_to_delete;
21672167
for (auto& stream_id : stream_ids) {

0 commit comments

Comments
 (0)