Skip to content

Commit 6f6fa15

Browse files
committed
[yugabyte#24578] DocDB: Fix TSAN failure in webserver
Summary: Fixed concurrent access to access_logging_enabled and tcmalloc_logging_enabled. Also fixed access to rpcz and ybrpczMemoryContext in webserver_worker_main in yb_pg_metrics.c. Jira: DB-13615 Test Plan: ./yb_build.sh tsan --gtest_filter PgCatalogPerfTest.ResponseCacheInvalidationOnConnectionWithTempTableClosure Reviewers: telgersma Reviewed By: telgersma Subscribers: ybase, yql Tags: #jenkins-ready Differential Revision: https://phorge.dev.yugabyte.com/D39336
1 parent 7f01d3a commit 6f6fa15

File tree

2 files changed

+69
-65
lines changed

2 files changed

+69
-65
lines changed

src/postgres/yb-extensions/yb_pg_metrics/yb_pg_metrics.c

Lines changed: 58 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -619,85 +619,85 @@ ws_sigterm_handler(SIGNAL_ARGS)
619619
void
620620
webserver_worker_main(Datum unused)
621621
{
622-
YBCInitThreading();
623-
/*
624-
* We call YBCInit here so that HandleYBStatus can correctly report potential error.
625-
*/
626-
HandleYBStatus(YBCInit(NULL /* argv[0] */, palloc, NULL /* cstring_to_text_with_len_fn */));
622+
YBCInitThreading();
623+
/*
624+
* We call YBCInit here so that HandleYBStatus can correctly report potential error.
625+
*/
626+
HandleYBStatus(YBCInit(NULL /* argv[0] */, palloc, NULL /* cstring_to_text_with_len_fn */));
627627

628-
backendStatusArray = getBackendStatusArray();
628+
backendStatusArray = getBackendStatusArray();
629629

630-
BackgroundWorkerUnblockSignals();
630+
BackgroundWorkerUnblockSignals();
631631

632-
/*
633-
* Assert that shared memory is allocated to backendStatusArray before this webserver
634-
* is started.
635-
*/
636-
if (!backendStatusArray)
637-
ereport(FATAL,
638-
(errcode(ERRCODE_INTERNAL_ERROR),
639-
errmsg("Shared memory not allocated to BackendStatusArray before starting YSQL webserver")));
632+
/*
633+
* Assert that shared memory is allocated to backendStatusArray before this webserver
634+
* is started.
635+
*/
636+
if (!backendStatusArray)
637+
ereport(FATAL,
638+
(errcode(ERRCODE_INTERNAL_ERROR),
639+
errmsg("Shared memory not allocated to BackendStatusArray before starting YSQL webserver")));
640640

641-
webserver = CreateWebserver(ListenAddresses, port);
641+
webserver = CreateWebserver(ListenAddresses, port);
642642

643-
RegisterMetrics(ybpgm_table, num_entries, metric_node_name);
643+
RegisterMetrics(ybpgm_table, num_entries, metric_node_name);
644644

645-
postgresCallbacks callbacks;
646-
callbacks.pullRpczEntries = pullRpczEntries;
647-
callbacks.freeRpczEntries = freeRpczEntries;
648-
callbacks.getTimestampTz = GetCurrentTimestamp;
649-
callbacks.getTimestampTzDiffMs = getElapsedMs;
650-
callbacks.getTimestampTzToStr = timestamptz_to_str;
645+
postgresCallbacks callbacks;
646+
callbacks.pullRpczEntries = pullRpczEntries;
647+
callbacks.freeRpczEntries = freeRpczEntries;
648+
callbacks.getTimestampTz = GetCurrentTimestamp;
649+
callbacks.getTimestampTzDiffMs = getElapsedMs;
650+
callbacks.getTimestampTzToStr = timestamptz_to_str;
651651

652-
YbConnectionMetrics conn_metrics;
653-
conn_metrics.max_conn = &MaxConnections;
654-
conn_metrics.too_many_conn = yb_too_many_conn;
655-
conn_metrics.new_conn = yb_new_conn;
652+
YbConnectionMetrics conn_metrics;
653+
conn_metrics.max_conn = &MaxConnections;
654+
conn_metrics.too_many_conn = yb_too_many_conn;
655+
conn_metrics.new_conn = yb_new_conn;
656656

657-
RegisterRpczEntries(&callbacks, &num_backends, &rpcz, &conn_metrics);
658-
HandleYBStatus(StartWebserver(webserver));
657+
RegisterRpczEntries(&callbacks, &num_backends, &rpcz, &conn_metrics);
658+
HandleYBStatus(StartWebserver(webserver));
659659

660660
pqsignal(SIGHUP, ws_sighup_handler);
661661
pqsignal(SIGTERM, ws_sigterm_handler);
662662

663-
SetWebserverConfig(webserver, log_accesses, log_tcmalloc_stats,
664-
webserver_profiler_sample_freq_bytes);
665-
666-
int rc;
667-
while (!got_SIGTERM)
668-
{
669-
rc = WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1, PG_WAIT_EXTENSION);
670-
ResetLatch(MyLatch);
663+
SetWebserverConfig(webserver, log_accesses, log_tcmalloc_stats,
664+
webserver_profiler_sample_freq_bytes);
671665

672-
if (rc & WL_POSTMASTER_DEATH)
673-
break;
674-
675-
if (got_SIGHUP)
676-
{
677-
got_SIGHUP = false;
678-
ProcessConfigFile(PGC_SIGHUP);
679-
SetWebserverConfig(webserver, log_accesses, log_tcmalloc_stats,
680-
webserver_profiler_sample_freq_bytes);
681-
}
682-
}
683-
684-
if (rpcz != NULL && ybrpczMemoryContext != NULL)
685-
{
686-
MemoryContext oldcontext = MemoryContextSwitchTo(ybrpczMemoryContext);
687-
pfree(rpcz);
688-
MemoryContextSwitchTo(oldcontext);
689-
}
666+
int rc;
667+
while (!got_SIGTERM)
668+
{
669+
rc = WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1, PG_WAIT_EXTENSION);
670+
ResetLatch(MyLatch);
671+
672+
if (rc & WL_POSTMASTER_DEATH)
673+
break;
674+
675+
if (got_SIGHUP)
676+
{
677+
got_SIGHUP = false;
678+
ProcessConfigFile(PGC_SIGHUP);
679+
SetWebserverConfig(webserver, log_accesses, log_tcmalloc_stats,
680+
webserver_profiler_sample_freq_bytes);
681+
}
682+
}
690683

691684
if (webserver)
692685
{
693686
DestroyWebserver(webserver);
694687
webserver = NULL;
695688
}
696689

697-
if (rc & WL_POSTMASTER_DEATH)
698-
proc_exit(1);
690+
if (rpcz != NULL && ybrpczMemoryContext != NULL)
691+
{
692+
MemoryContext oldcontext = MemoryContextSwitchTo(ybrpczMemoryContext);
693+
pfree(rpcz);
694+
MemoryContextSwitchTo(oldcontext);
695+
}
696+
697+
if (rc & WL_POSTMASTER_DEATH)
698+
proc_exit(1);
699699

700-
proc_exit(0);
700+
proc_exit(0);
701701
}
702702

703703
/*

src/yb/server/webserver.cc

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,6 @@ class Webserver::Impl {
136136

137137
Status GetInputHostPort(HostPort* hp) const;
138138

139-
bool access_logging_enabled = false;
140-
bool tcmalloc_logging_enabled = false;
141-
142139
void RegisterPathHandler(const std::string& path, const std::string& alias,
143140
const PathHandlerCallback& callback,
144141
bool is_styled = true,
@@ -157,6 +154,11 @@ class Webserver::Impl {
157154

158155
bool ContainsFlag(const std::string& flag) const EXCLUDES(flags_mutex_);
159156

157+
void SetLogging(bool enable_access_logging, bool enable_tcmalloc_logging) {
158+
access_logging_enabled_.store(enable_access_logging, std::memory_order_release);
159+
tcmalloc_logging_enabled_.store(enable_tcmalloc_logging, std::memory_order_release);
160+
}
161+
160162
private:
161163
// Container class for a list of path handler callbacks for a single URL.
162164
class PathHandler {
@@ -267,6 +269,9 @@ class Webserver::Impl {
267269
// this server needs. This is used to filter out the flags that are shown in the varz UI.
268270
std::unordered_set<std::string> auto_flags_ GUARDED_BY(flags_mutex_);
269271
std::unordered_set<std::string> process_flags_ GUARDED_BY(flags_mutex_);
272+
273+
std::atomic<bool> access_logging_enabled_ = false;
274+
std::atomic<bool> tcmalloc_logging_enabled_ = false;
270275
};
271276

272277
Webserver::Impl::Impl(const WebserverOptions& opts, const std::string& server_name)
@@ -589,7 +594,7 @@ sq_callback_result_t Webserver::Impl::BeginRequestCallback(struct sq_connection*
589594
handler = it->second;
590595
}
591596

592-
if (access_logging_enabled) {
597+
if (access_logging_enabled_.load(std::memory_order_acquire)) {
593598
string params = request_info->query_string ? Format("?$0", request_info->query_string) : "";
594599
LOG(INFO) << "webserver request: " << request_info->uri << params;
595600
}
@@ -598,7 +603,7 @@ sq_callback_result_t Webserver::Impl::BeginRequestCallback(struct sq_connection*
598603
MemTracker::GcTcmallocIfNeeded();
599604

600605
#if YB_TCMALLOC_ENABLED
601-
if (tcmalloc_logging_enabled)
606+
if (tcmalloc_logging_enabled_.load(std::memory_order_acquire))
602607
LOG(INFO) << "webserver tcmalloc stats:"
603608
<< " heap size bytes: " << GetTCMallocPhysicalBytesUsed()
604609
<< ", total physical bytes: " << GetTCMallocCurrentHeapSizeBytes()
@@ -867,8 +872,7 @@ Status Webserver::GetInputHostPort(HostPort* hp) const {
867872
}
868873

869874
void Webserver::SetLogging(bool enable_access_logging, bool enable_tcmalloc_logging) {
870-
impl_->access_logging_enabled = enable_access_logging;
871-
impl_->tcmalloc_logging_enabled = enable_tcmalloc_logging;
875+
impl_->SetLogging(enable_access_logging, enable_tcmalloc_logging);
872876
}
873877

874878
void Webserver::RegisterPathHandler(const std::string& path,

0 commit comments

Comments
 (0)