This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.1 by this push:
new af846b20acf branch-3.1: [Fix](mow) Fix DeleteBitmap's assignment
operator and constructor #52582 (#52975)
af846b20acf is described below
commit af846b20acfb7ab1610040b0b0207e32aecb1b5e
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Jul 9 14:49:31 2025 +0800
branch-3.1: [Fix](mow) Fix DeleteBitmap's assignment operator and
constructor #52582 (#52975)
Cherry-picked from #52582
Co-authored-by: bobhan1 <[email protected]>
---
be/src/olap/tablet_meta.cpp | 30 ++++--
be/src/olap/tablet_meta.h | 4 +-
.../cloud/test_cloud_mow_sc_inc_rowsets_dup.out | Bin 0 -> 197 bytes
.../cloud/test_cloud_mow_sc_inc_rowsets_dup.groovy | 103 +++++++++++++++++++++
4 files changed, 128 insertions(+), 9 deletions(-)
diff --git a/be/src/olap/tablet_meta.cpp b/be/src/olap/tablet_meta.cpp
index a53518eb6e4..a6a2f900501 100644
--- a/be/src/olap/tablet_meta.cpp
+++ b/be/src/olap/tablet_meta.cpp
@@ -1116,24 +1116,40 @@ DeleteBitmapAggCache*
DeleteBitmapAggCache::create_instance(size_t capacity) {
DeleteBitmap::DeleteBitmap(int64_t tablet_id) : _tablet_id(tablet_id) {}
DeleteBitmap::DeleteBitmap(const DeleteBitmap& o) {
- delete_bitmap = o.delete_bitmap; // just copy data
+ std::shared_lock l1(o.lock);
+ delete_bitmap = o.delete_bitmap;
_tablet_id = o._tablet_id;
}
DeleteBitmap& DeleteBitmap::operator=(const DeleteBitmap& o) {
- delete_bitmap = o.delete_bitmap; // just copy data
- _tablet_id = o._tablet_id;
+ if (this == &o) return *this;
+ if (this < &o) {
+ std::unique_lock l1(lock);
+ std::shared_lock l2(o.lock);
+ delete_bitmap = o.delete_bitmap;
+ _tablet_id = o._tablet_id;
+ } else {
+ std::shared_lock l2(o.lock);
+ std::unique_lock l1(lock);
+ delete_bitmap = o.delete_bitmap;
+ _tablet_id = o._tablet_id;
+ }
return *this;
}
-DeleteBitmap::DeleteBitmap(DeleteBitmap&& o) {
+DeleteBitmap::DeleteBitmap(DeleteBitmap&& o) noexcept {
+ std::scoped_lock l(o.lock, o._rowset_cache_version_lock);
delete_bitmap = std::move(o.delete_bitmap);
- _tablet_id = o._tablet_id;
+ _tablet_id = std::move(o._tablet_id);
+ o._rowset_cache_version.clear();
}
-DeleteBitmap& DeleteBitmap::operator=(DeleteBitmap&& o) {
+DeleteBitmap& DeleteBitmap::operator=(DeleteBitmap&& o) noexcept {
+ if (this == &o) return *this;
+ std::scoped_lock l(lock, o.lock, o._rowset_cache_version_lock);
delete_bitmap = std::move(o.delete_bitmap);
- _tablet_id = o._tablet_id;
+ _tablet_id = std::move(o._tablet_id);
+ o._rowset_cache_version.clear();
return *this;
}
diff --git a/be/src/olap/tablet_meta.h b/be/src/olap/tablet_meta.h
index 0937dfbac9e..36aa566c7ef 100644
--- a/be/src/olap/tablet_meta.h
+++ b/be/src/olap/tablet_meta.h
@@ -427,8 +427,8 @@ public:
/**
* Move c-tor for making delete bitmap snapshot on read path
*/
- DeleteBitmap(DeleteBitmap&& r);
- DeleteBitmap& operator=(DeleteBitmap&& r);
+ DeleteBitmap(DeleteBitmap&& r) noexcept;
+ DeleteBitmap& operator=(DeleteBitmap&& r) noexcept;
static DeleteBitmap from_pb(const DeleteBitmapPB& pb, int64_t tablet_id);
diff --git
a/regression-test/data/fault_injection_p0/cloud/test_cloud_mow_sc_inc_rowsets_dup.out
b/regression-test/data/fault_injection_p0/cloud/test_cloud_mow_sc_inc_rowsets_dup.out
new file mode 100644
index 00000000000..545f2c2edbb
Binary files /dev/null and
b/regression-test/data/fault_injection_p0/cloud/test_cloud_mow_sc_inc_rowsets_dup.out
differ
diff --git
a/regression-test/suites/fault_injection_p0/cloud/test_cloud_mow_sc_inc_rowsets_dup.groovy
b/regression-test/suites/fault_injection_p0/cloud/test_cloud_mow_sc_inc_rowsets_dup.groovy
new file mode 100644
index 00000000000..f57a1b4de1f
--- /dev/null
+++
b/regression-test/suites/fault_injection_p0/cloud/test_cloud_mow_sc_inc_rowsets_dup.groovy
@@ -0,0 +1,103 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+import java.util.concurrent.TimeUnit
+import org.awaitility.Awaitility
+
+suite("test_cloud_mow_sc_inc_rowsets_dup", "nonConcurrent") {
+ if (!isCloudMode()) {
+ return
+ }
+
+ GetDebugPoint().clearDebugPointsForAllFEs()
+ GetDebugPoint().clearDebugPointsForAllBEs()
+
+ def table1 = "test_cloud_mow_sc_inc_rowsets_dup"
+ sql "DROP TABLE IF EXISTS ${table1} FORCE;"
+ sql """ CREATE TABLE IF NOT EXISTS ${table1} (
+ `k1` int NOT NULL,
+ `c1` int,
+ `c2` int,
+ `c3` int
+ )UNIQUE KEY(k1)
+ DISTRIBUTED BY HASH(k1) BUCKETS 1
+ PROPERTIES (
+ "enable_unique_key_merge_on_write" = "true",
+ "disable_auto_compaction" = "true",
+ "replication_num" = "1"); """
+
+ sql "insert into ${table1} values(1,1,1,10);" // 2
+ sql "insert into ${table1} values(2,2,2,20);" // 3
+ sql "insert into ${table1} values(3,3,3,30);" // 4
+ sql "sync;"
+ qt_sql "select * from ${table1} order by k1;"
+
+ def backends = sql_return_maparray('show backends')
+ def tabletStats = sql_return_maparray("show tablets from ${table1};")
+ assert tabletStats.size() == 1
+ def tabletId = tabletStats[0].TabletId
+ def tabletBackendId = tabletStats[0].BackendId
+ def tabletBackend
+ for (def be : backends) {
+ if (be.BackendId == tabletBackendId) {
+ tabletBackend = be
+ break;
+ }
+ }
+ logger.info("tablet ${tabletId} on backend ${tabletBackend.Host} with
backendId=${tabletBackend.BackendId}");
+
+ try {
+
GetDebugPoint().enableDebugPointForAllBEs("CloudSchemaChangeJob::_process_delete_bitmap.before_new_inc.block")
+ sql "alter table ${table1} modify column c2 varchar(100);"
+
+ Thread.sleep(1000)
+
+ tabletStats = sql_return_maparray("show tablets from ${table1};")
+ def newTabletId = "-1"
+ for (def stat : tabletStats) {
+ if (stat.TabletId != tabletId) {
+ newTabletId = stat.TabletId
+ break
+ }
+ }
+ logger.info("new_tablet_id: ${newTabletId}")
+
+ sql "insert into ${table1} values(1,99,99,99);"
+ sql "insert into ${table1} values(1,99,99,99);"
+ sql "insert into ${table1} values(1,99,99,99);"
+ sql "insert into ${table1} values(1,99,99,99);"
+
+ Thread.sleep(1000)
+
+
GetDebugPoint().disableDebugPointForAllBEs("CloudSchemaChangeJob::_process_delete_bitmap.before_new_inc.block")
+
+ waitForSchemaChangeDone {
+ sql """ SHOW ALTER TABLE COLUMN WHERE TableName='${table1}' ORDER
BY createtime DESC LIMIT 1 """
+ time 1000
+ }
+
+ qt_dup_key_count "select k1,count() as cnt from ${table1} group by k1
having cnt>1;"
+ order_qt_sql "select * from ${table1};"
+
+ } catch(Exception e) {
+ logger.info(e.getMessage())
+ throw e
+ } finally {
+ GetDebugPoint().clearDebugPointsForAllBEs()
+ GetDebugPoint().clearDebugPointsForAllFEs()
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]