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

csun5285 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new 7488bc7a19e [fix](ccr) Disallow Row Binlog on MOW tables with cluster 
keys (#66093)
7488bc7a19e is described below

commit 7488bc7a19e5d2e4856ab69319240a0943bd630a
Author: Chenyang Sun <[email protected]>
AuthorDate: Tue Jul 28 12:18:30 2026 +0800

    [fix](ccr) Disallow Row Binlog on MOW tables with cluster keys (#66093)
    
    Disallow Row Binlog on MOW tables with cluster keys
---
 .../java/org/apache/doris/catalog/Database.java    | 20 +++++
 .../apache/doris/datasource/InternalCatalog.java   | 18 ++---
 .../trees/plans/commands/info/CreateTableInfo.java | 10 +++
 .../row_binlog_p0/test_row_binlog_cluster_key.out  |  8 ++
 .../test_row_binlog_cluster_key.groovy             | 88 ++++++++++++++++++++++
 5 files changed, 135 insertions(+), 9 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
index f6f21be4977..ac6d53271f2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
@@ -1049,6 +1049,26 @@ public class Database extends MetaObject implements 
Writable, DatabaseIf<Table>,
         return binlogConfig;
     }
 
+    /**
+     * Get the database binlog config snapshot and the effective table binlog 
config for creating a table.
+     *
+     * <p>The first value is the database binlog config snapshot, and the 
second value is the effective
+     * table binlog config after applying table properties.
+     */
+    public Pair<BinlogConfig, BinlogConfig> getBinlogConfigsForCreateTable(
+            Map<String, String> tableProperties) {
+        BinlogConfig dbBinlogConfig;
+        readLock();
+        try {
+            dbBinlogConfig = new BinlogConfig(binlogConfig);
+        } finally {
+            readUnlock();
+        }
+        BinlogConfig createTableBinlogConfig = new 
BinlogConfig(dbBinlogConfig);
+        createTableBinlogConfig.mergeFromProperties(tableProperties);
+        return Pair.of(dbBinlogConfig, createTableBinlogConfig);
+    }
+
     public void checkStorageVault(Map<String, String> properties) throws 
DdlException {
         Env env = Env.getCurrentEnv();
         if (!Config.isCloudMode() || !((CloudEnv) 
env).getEnableStorageVault()) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java 
b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
index 6a43988ccfd..4b44421e583 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
@@ -2310,15 +2310,10 @@ public class InternalCatalog implements 
CatalogIf<Database> {
         }
 
         boolean tableHasExist = false;
-        BinlogConfig dbBinlogConfig;
-        db.readLock();
-        try {
-            dbBinlogConfig = new BinlogConfig(db.getBinlogConfig());
-        } finally {
-            db.readUnlock();
-        }
-        BinlogConfig createTableBinlogConfig = new 
BinlogConfig(dbBinlogConfig);
-        
createTableBinlogConfig.mergeFromProperties(createTableInfo.getProperties());
+        Pair<BinlogConfig, BinlogConfig> binlogConfigs =
+                
db.getBinlogConfigsForCreateTable(createTableInfo.getProperties());
+        BinlogConfig dbBinlogConfig = binlogConfigs.first;
+        BinlogConfig createTableBinlogConfig = binlogConfigs.second;
         if (dbBinlogConfig.getEnable() && 
!createTableBinlogConfig.isEnableForCCR() && !createTableInfo.isTemp()) {
             throw new DdlException("Cannot create table with binlog disabled 
when database binlog enable");
         }
@@ -2840,6 +2835,11 @@ public class InternalCatalog implements 
CatalogIf<Database> {
                     if (Config.isCloudMode()) {
                         throw new AnalysisException("Binlog<Row> is not 
supported in the cloud mode yet");
                     }
+                    if (keysType == KeysType.UNIQUE_KEYS && 
enableUniqueKeyMergeOnWrite
+                            && 
!CollectionUtils.isEmpty(keysDesc.getOrderByKeysColumnNames())) {
+                        throw new AnalysisException(
+                                "Unique merge-on-write tables with cluster 
keys do not support binlog<Row>");
+                    }
                     if (keysType == KeysType.DUP_KEYS && 
binlogConfig.getNeedHistoricalValue()) {
                         throw new AnalysisException("Duplicate table model 
don't support record historical value");
                     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
index fd30dacc9d1..ad4a526cb6a 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java
@@ -26,6 +26,7 @@ import org.apache.doris.analysis.SlotRef;
 import org.apache.doris.catalog.AggregateType;
 import org.apache.doris.catalog.BinlogConfig;
 import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.Database;
 import org.apache.doris.catalog.Env;
 import org.apache.doris.catalog.Index;
 import org.apache.doris.catalog.KeysType;
@@ -298,6 +299,14 @@ public class CreateTableInfo {
         return sortOrderFields;
     }
 
+    private boolean isEffectiveRowBinlogEnabled() {
+        Database db = Env.getCurrentInternalCatalog().getDbNullable(dbName);
+        BinlogConfig binlogConfig = db == null
+                ? BinlogConfig.fromProperties(properties)
+                : db.getBinlogConfigsForCreateTable(properties).second;
+        return binlogConfig.isEnableForStreaming();
+    }
+
     public void setRollups(List<RollupDefinition> rollups) {
         this.rollups = rollups;
     }
@@ -611,6 +620,7 @@ public class CreateTableInfo {
 
             try {
                 if (Config.random_add_order_by_keys_for_mow && 
isEnableMergeOnWrite && sortOrderFields.isEmpty()
+                        && !isEffectiveRowBinlogEnabled()
                         && PropertyAnalyzer.analyzeUseLightSchemaChange(new 
HashMap<>(properties))) {
                     // exclude columns whose data type can not be order key, 
see {@link ColumnDefinition#validate}
                     List<ColumnDefinition> orderKeysCandidates = 
columns.stream().filter(c -> {
diff --git a/regression-test/data/row_binlog_p0/test_row_binlog_cluster_key.out 
b/regression-test/data/row_binlog_p0/test_row_binlog_cluster_key.out
new file mode 100644
index 00000000000..0690e49b8a1
--- /dev/null
+++ b/regression-test/data/row_binlog_p0/test_row_binlog_cluster_key.out
@@ -0,0 +1,8 @@
+-- This file is automatically generated. You should know what you did if you 
want to edit this
+-- !effective_row_binlog_properties --
+binlog.enable  true
+binlog.format  ROW
+
+-- !show_create_without_random_cluster_key --
+test_row_binlog_without_cluster_key    CREATE TABLE 
`test_row_binlog_without_cluster_key` (\n  `id` bigint NOT NULL,\n  
`cluster_value` int NOT NULL,\n  `payload` varchar(32) NOT NULL\n) 
ENGINE=OLAP\nUNIQUE KEY(`id`)\nDISTRIBUTED BY HASH(`id`) BUCKETS 1\nPROPERTIES 
(\n"replication_allocation" = "tag.location.default: 
1",\n"min_load_replica_num" = "-1",\n"is_being_synced" = 
"false",\n"storage_medium" = "hdd",\n"storage_format" = 
"V2",\n"inverted_index_storage_format" = "V3",\n"enable_unique_ [...]
+
diff --git 
a/regression-test/suites/row_binlog_p0/test_row_binlog_cluster_key.groovy 
b/regression-test/suites/row_binlog_p0/test_row_binlog_cluster_key.groovy
new file mode 100644
index 00000000000..39eb4d3c2c3
--- /dev/null
+++ b/regression-test/suites/row_binlog_p0/test_row_binlog_cluster_key.groovy
@@ -0,0 +1,88 @@
+// 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.
+
+suite("test_row_binlog_cluster_key", "nonConcurrent") {
+    if (isCloudMode()) {
+        return
+    }
+
+    def inheritedBinlogDb = "test_row_binlog_cluster_key_db"
+
+    sql "DROP TABLE IF EXISTS test_row_binlog_cluster_key FORCE"
+    sql "DROP DATABASE IF EXISTS ${inheritedBinlogDb} FORCE"
+    sql "CREATE DATABASE ${inheritedBinlogDb}"
+    sql """
+        ALTER DATABASE ${inheritedBinlogDb} SET PROPERTIES (
+            "binlog.enable" = "false",
+            "binlog.format" = "ROW"
+        )
+    """
+
+    setFeConfigTemporary([random_add_order_by_keys_for_mow: true]) {
+        test {
+            sql """
+                CREATE TABLE test_row_binlog_cluster_key (
+                    id BIGINT NOT NULL,
+                    cluster_value INT NOT NULL,
+                    payload VARCHAR(32) NOT NULL
+                )
+                UNIQUE KEY(id)
+                ORDER BY(cluster_value)
+                DISTRIBUTED BY HASH(id) BUCKETS 1
+                PROPERTIES (
+                    "replication_num" = "1",
+                    "enable_unique_key_merge_on_write" = "true",
+                    "light_schema_change" = "true",
+                    "binlog.enable" = "true",
+                    "binlog.format" = "ROW"
+                )
+            """
+            exception "Unique merge-on-write tables with cluster keys do not 
support binlog<Row>"
+        }
+
+        sql """
+            CREATE TABLE 
${inheritedBinlogDb}.test_row_binlog_without_cluster_key (
+                id BIGINT NOT NULL,
+                cluster_value INT NOT NULL,
+                payload VARCHAR(32) NOT NULL
+            )
+            UNIQUE KEY(id)
+            DISTRIBUTED BY HASH(id) BUCKETS 1
+            PROPERTIES (
+                "replication_num" = "1",
+                "enable_unique_key_merge_on_write" = "true",
+                "light_schema_change" = "true",
+                "storage_format" = "V2",
+                "binlog.enable" = "true"
+            )
+        """
+
+        order_qt_effective_row_binlog_properties """
+            SELECT PROPERTY_NAME, PROPERTY_VALUE
+            FROM information_schema.table_properties
+            WHERE TABLE_CATALOG = 'internal'
+                AND TABLE_SCHEMA = '${inheritedBinlogDb}'
+                AND TABLE_NAME = 'test_row_binlog_without_cluster_key'
+                AND PROPERTY_NAME IN ('binlog.enable', 'binlog.format')
+            ORDER BY PROPERTY_NAME
+        """
+
+        qt_show_create_without_random_cluster_key """
+            SHOW CREATE TABLE 
${inheritedBinlogDb}.test_row_binlog_without_cluster_key
+        """
+    }
+}


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

Reply via email to