This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new f99471b5680 branch-4.1: [fix](be) Synchronize load error log access 
#66250 (#66887)
f99471b5680 is described below

commit f99471b56807174d48d2379307b5bcfb8a6fb6ac
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Aug 20 09:19:20 2026 +0800

    branch-4.1: [fix](be) Synchronize load error log access #66250 (#66887)
    
    Cherry-picked from #66250
    
    Co-authored-by: Refrain <[email protected]>
---
 be/src/runtime/runtime_state.cpp | 87 ++++++++++++++++++++++++++--------------
 be/src/runtime/runtime_state.h   |  5 ++-
 2 files changed, 61 insertions(+), 31 deletions(-)

diff --git a/be/src/runtime/runtime_state.cpp b/be/src/runtime/runtime_state.cpp
index a12c8743ee4..0054dd0aa82 100644
--- a/be/src/runtime/runtime_state.cpp
+++ b/be/src/runtime/runtime_state.cpp
@@ -388,6 +388,21 @@ Status 
RuntimeState::append_error_msg_to_file(std::function<std::string()> line,
     if (query_type() != TQueryType::LOAD) {
         return Status::OK();
     }
+
+    const auto error_limit_status = [this]() -> Status {
+        if (_load_zero_tolerance) {
+            return Status::DataQualityError(
+                    "Encountered unqualified data, stop processing. Please 
check if the source "
+                    "data matches the schema, and consider disabling strict 
mode or increasing "
+                    "max_filter_ratio.");
+        }
+        return Status::OK();
+    };
+    if (_num_print_error_rows.load(std::memory_order_relaxed) > MAX_ERROR_NUM) 
{
+        return error_limit_status();
+    }
+
+    std::lock_guard<std::mutex> l(_load_error_log_lock);
     // If file haven't been opened, open it here
     if (_error_log_file == nullptr) {
         Status status = create_error_log_file();
@@ -404,14 +419,7 @@ Status 
RuntimeState::append_error_msg_to_file(std::function<std::string()> line,
     }
     // If num of printed error row exceeds the limit, don't add error messages 
to error log file any more
     if (_num_print_error_rows.fetch_add(1, std::memory_order_relaxed) > 
MAX_ERROR_NUM) {
-        // if _load_zero_tolerance, return Error to stop the load process 
immediately.
-        if (_load_zero_tolerance) {
-            return Status::DataQualityError(
-                    "Encountered unqualified data, stop processing. Please 
check if the source "
-                    "data matches the schema, and consider disabling strict 
mode or increasing "
-                    "max_filter_ratio.");
-        }
-        return Status::OK();
+        return error_limit_status();
     }
 
     fmt::memory_buffer out;
@@ -433,33 +441,52 @@ Status 
RuntimeState::append_error_msg_to_file(std::function<std::string()> line,
     return Status::OK();
 }
 
+std::string RuntimeState::get_first_error_msg() const {
+    std::lock_guard<std::mutex> l(_load_error_log_lock);
+    return _first_error_msg;
+}
+
 std::string RuntimeState::get_error_log_file_path() {
-    DBUG_EXECUTE_IF("RuntimeState::get_error_log_file_path.block", {
-        if (!_error_log_file_path.empty()) {
-            std::this_thread::sleep_for(std::chrono::seconds(1));
+    std::lock_guard<std::mutex> s3_lock(_s3_error_log_file_lock);
+    std::shared_ptr<io::S3FileSystem> s3_error_fs;
+    std::string local_error_log_file_path;
+    std::string remote_error_log_file_path;
+    {
+        std::lock_guard<std::mutex> load_lock(_load_error_log_lock);
+        DBUG_EXECUTE_IF("RuntimeState::get_error_log_file_path.block", {
+            if (!_error_log_file_path.empty()) {
+                std::this_thread::sleep_for(std::chrono::seconds(1));
+            }
+        });
+        if (!_s3_error_fs || !_error_log_file || !_error_log_file->is_open()) {
+            return _error_log_file_path;
         }
-    });
-    std::lock_guard<std::mutex> l(_s3_error_log_file_lock);
-    if (_s3_error_fs && _error_log_file && _error_log_file->is_open()) {
+
         // close error log file
         _error_log_file->close();
-        std::string error_log_absolute_path =
-                
_exec_env->load_path_mgr()->get_load_error_absolute_path(_error_log_file_path);
-        // upload error log file to s3
-        Status st = _s3_error_fs->upload(error_log_absolute_path, 
_s3_error_log_file_path);
-        if (!st.ok()) {
-            // upload failed and return local error log file path
-            LOG(WARNING) << "Fail to upload error file to s3, 
error_log_file_path="
-                         << _error_log_file_path << ", error=" << st;
-            return _error_log_file_path;
-        }
-        // expiration must be less than a week (in seconds) for presigned url
-        static const unsigned EXPIRATION_SECONDS = 7 * 24 * 60 * 60 - 1;
-        // Use public or private endpoint based on configuration
-        _error_log_file_path =
-                _s3_error_fs->generate_presigned_url(_s3_error_log_file_path, 
EXPIRATION_SECONDS,
-                                                     
config::use_public_endpoint_for_error_log);
+        s3_error_fs = _s3_error_fs;
+        local_error_log_file_path = _error_log_file_path;
+        remote_error_log_file_path = _s3_error_log_file_path;
+    }
+
+    std::string error_log_absolute_path =
+            
_exec_env->load_path_mgr()->get_load_error_absolute_path(local_error_log_file_path);
+    // upload error log file to s3
+    Status st = s3_error_fs->upload(error_log_absolute_path, 
remote_error_log_file_path);
+    if (!st.ok()) {
+        // upload failed and return local error log file path
+        LOG(WARNING) << "Fail to upload error file to s3, error_log_file_path="
+                     << local_error_log_file_path << ", error=" << st;
+        return local_error_log_file_path;
     }
+    // expiration must be less than a week (in seconds) for presigned url
+    static const unsigned EXPIRATION_SECONDS = 7 * 24 * 60 * 60 - 1;
+    // Use public or private endpoint based on configuration
+    auto presigned_url =
+            s3_error_fs->generate_presigned_url(remote_error_log_file_path, 
EXPIRATION_SECONDS,
+                                                
config::use_public_endpoint_for_error_log);
+    std::lock_guard<std::mutex> load_lock(_load_error_log_lock);
+    _error_log_file_path = std::move(presigned_url);
     return _error_log_file_path;
 }
 
diff --git a/be/src/runtime/runtime_state.h b/be/src/runtime/runtime_state.h
index 7b3bb7e3339..3184b74a744 100644
--- a/be/src/runtime/runtime_state.h
+++ b/be/src/runtime/runtime_state.h
@@ -335,7 +335,7 @@ public:
 
     std::string get_error_log_file_path();
 
-    std::string get_first_error_msg() const { return _first_error_msg; }
+    std::string get_first_error_msg() const;
 
     // append error msg and error line to file when loading data.
     // is_summary is true, means we are going to write the summary line
@@ -1021,6 +1021,9 @@ private:
     std::shared_ptr<io::S3FileSystem> _s3_error_fs;
     // error file path on s3, 
${bucket}/${prefix}/error_log/${label}_${fragment_instance_id}
     std::string _s3_error_log_file_path;
+    // Protects the load error log stream, paths, and first error message.
+    mutable std::mutex _load_error_log_lock;
+    // Serializes S3 upload and presigned URL publication.
     std::mutex _s3_error_log_file_lock;
 
     // used for encoding the global lazy materialize


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to