@@ -233,46 +233,56 @@ void SystemLog<LogElement>::add(const LogElement & element)
233233 // / Otherwise the tests like 01017_uniqCombined_memory_usage.sql will be flacky.
234234 auto temporarily_disable_memory_tracker = getCurrentMemoryTrackerActionLock ();
235235
236- std::lock_guard lock (mutex);
236+ // / Should not log messages under mutex.
237+ bool queue_is_half_full = false ;
237238
238- if (is_shutdown)
239- return ;
240-
241- if (queue.size () == DBMS_SYSTEM_LOG_QUEUE_SIZE / 2 )
242239 {
243- // The queue more than half full, time to flush.
244- // We only check for strict equality, because messages are added one
245- // by one, under exclusive lock, so we will see each message count.
246- // It is enough to only wake the flushing thread once, after the message
247- // count increases past half available size.
248- const uint64_t queue_end = queue_front_index + queue.size ();
249- if (requested_flush_before < queue_end)
250- requested_flush_before = queue_end;
240+ std::unique_lock lock (mutex);
251241
252- flush_event.notify_all ();
253- LOG_INFO (log, " Queue is half full for system log '{}'." , demangle (typeid (*this ).name ()));
254- }
242+ if (is_shutdown)
243+ return ;
255244
256- if (queue.size () >= DBMS_SYSTEM_LOG_QUEUE_SIZE)
257- {
258- // Ignore all further entries until the queue is flushed.
259- // Log a message about that. Don't spam it -- this might be especially
260- // problematic in case of trace log. Remember what the front index of the
261- // queue was when we last logged the message. If it changed, it means the
262- // queue was flushed, and we can log again.
263- if (queue_front_index != logged_queue_full_at_index)
245+ if (queue.size () == DBMS_SYSTEM_LOG_QUEUE_SIZE / 2 )
264246 {
265- logged_queue_full_at_index = queue_front_index;
247+ queue_is_half_full = true ;
248+
249+ // The queue more than half full, time to flush.
250+ // We only check for strict equality, because messages are added one
251+ // by one, under exclusive lock, so we will see each message count.
252+ // It is enough to only wake the flushing thread once, after the message
253+ // count increases past half available size.
254+ const uint64_t queue_end = queue_front_index + queue.size ();
255+ if (requested_flush_before < queue_end)
256+ requested_flush_before = queue_end;
257+
258+ flush_event.notify_all ();
259+ }
266260
267- // TextLog sets its logger level to 0, so this log is a noop and
268- // there is no recursive logging.
269- LOG_ERROR (log, " Queue is full for system log '{}' at {}" , demangle (typeid (*this ).name ()), queue_front_index);
261+ if (queue.size () >= DBMS_SYSTEM_LOG_QUEUE_SIZE)
262+ {
263+ // Ignore all further entries until the queue is flushed.
264+ // Log a message about that. Don't spam it -- this might be especially
265+ // problematic in case of trace log. Remember what the front index of the
266+ // queue was when we last logged the message. If it changed, it means the
267+ // queue was flushed, and we can log again.
268+ if (queue_front_index != logged_queue_full_at_index)
269+ {
270+ logged_queue_full_at_index = queue_front_index;
271+
272+ // TextLog sets its logger level to 0, so this log is a noop and
273+ // there is no recursive logging.
274+ lock.unlock ();
275+ LOG_ERROR (log, " Queue is full for system log '{}' at {}" , demangle (typeid (*this ).name ()), queue_front_index);
276+ }
277+
278+ return ;
270279 }
271280
272- return ;
281+ queue. push_back (element) ;
273282 }
274283
275- queue.push_back (element);
284+ if (queue_is_half_full)
285+ LOG_INFO (log, " Queue is half full for system log '{}'." , demangle (typeid (*this ).name ()));
276286}
277287
278288
0 commit comments