Lý Thành
09/18/2026, 3:52 AMRocky
09/18/2026, 3:52 AMLý Thành
09/18/2026, 3:52 AMRocky
09/18/2026, 3:53 AMSIGSEGV (Segmentation Fault) at __memcpy_evex_unaligned_erms.
* Location: starrocks::BinaryColumnBase<unsigned int>::filter_range.
* Context: The crash occurred during an OLAP scan (OlapChunkSource) while the system was filtering a chunk of rows. The function filter_range is responsible for copying data from a column into a new chunk based on a filter bitmap (e.g., after a WHERE clause or runtime filter is applied).
* Root Cause Inference: The SIGSEGV during memcpy in a BinaryColumn (used for VARCHAR, STRING, or JSON types) typically indicates:
1. Offset Corruption: An offset in the binary column points outside the actual data buffer.
2. Size Mismatch: The filter vector size does not match the number of rows in the column, leading to out-of-bounds memory access.
3. Data Limits: In some versions of StarRocks, if the total size of strings in a single chunk exceeds 2GB or 4GB, the unsigned int offsets may overflow or be handled incorrectly during filtering.
Recommendations
1. Check the Query:
* The query_id associated with the crash is 01a0b276-0ec1-72c9-b9d8-425138bfe789.
* Search your fe.audit.log for this ID to identify the specific SQL being executed.
* Check if the query involves very large `VARCHAR`/`STRING` data or large ARRAY types.
2. Upgrade to 4.0.14+:
* StarRocks version 4.0.14 includes specific fixes for ARRAY and MAP constructors that could previously return corrupted values when flattened results exceeded addressable byte limits.
* Additionally, later patch releases often include stability fixes for vectorized filtering logic (filter_range).
3. Verify Data Consistency:
* Run ADMIN CHECK TABLET (tablet_id) on the tablets involved in the query (found in BE logs) to ensure there is no underlying data corruption on disk.
4. Workaround (if persistent):
* Try reducing the pipeline_max_batch_size (default 4096) for the session to see if smaller chunks avoid the overflow:
sql
SET pipeline_max_batch_size = 1024;
* If the crash is triggered by a specific runtime filter, you can try disabling them temporarily:
sql
SET enable_runtime_filter = false;
If the issue persists after upgrading, please provide the query plan (EXPLAIN ANALYZE) and the table schema to the StarRocks community or support team for further investigation.
References
• release_notes/release-4.0.mdLý Thành
09/18/2026, 5:23 AMRocky
09/18/2026, 5:24 AMsql
SELECT app_code,
COALESCE(get_json_string(OUTPUT, '$.CBSCORE'), ...) AS CB_Score,
...,
get_json_string(UPPER(OUTPUT), '$.CBHITTYPE') AS CBHITTYPE
FROM dmapp.dtm_los_log_cbscore
Analysis of the Failure
The query is crashing in the storage engine's scan layer (SegmentIterator) specifically within BinaryColumnBase<unsigned int>::filter_range. This function is responsible for filtering out rows (likely due to deleted rows if this is a Primary Key table, or version compaction) by copying data from the source column to a new memory block.
A SIGSEGV during memcpy in this function typically suggests one of the following:
1. Memory Corruption/Overflow: The OUTPUT column likely contains very large JSON strings. In StarRocks, BinaryColumnBase<unsigned int> uses 32-bit offsets. If the total size of data in a single processed "chunk" (group of rows) exceeds the addressable limit (2GB/4GB), the offsets can overflow, leading to an out-of-bounds memory access.
2. JSON Type Issues: The query uses UPPER(OUTPUT) and multiple get_json_string calls. If OUTPUT is a large VARCHAR being treated as JSON, the combination of high-concurrency and large string manipulation can trigger edge cases in memory management.
3. Known Regression in 4.0.x: There are known issues in early 4.0.x releases related to JSON subfield pushdown and large string processing that can lead to crashes (e.g., issues like #76594 or #63677).
Recommended Actions
1. Upgrade to 4.0.14 or 4.0.15:
* StarRocks 4.0.12 is susceptible to several stability issues related to complex type processing and large string filtering. Later patch versions (4.0.14+) include critical fixes for memory safety in vectorized filtering and JSON subfield extraction.
2. Avoid UPPER(OUTPUT) on Large JSON:
* The expression get_json_string(UPPER(OUTPUT), ...) is extremely expensive because it creates a complete uppercase copy of the entire JSON string for every row before extracting a single key.
* Optimization: Convert the extracted value instead: UPPER(get_json_string(OUTPUT, '$.CBHITTYPE')). This will be significantly faster and safer as it only operates on the small extracted string.
3. Reduce Batch Size (Temporary Mitigation):
* If you cannot upgrade immediately, try reducing the chunk size to prevent the 32-bit offset overflow:
sql
SET pipeline_max_batch_size = 1024; -- Default is usually 4096
4. Check Table Health:
* If this is a Primary Key table, run a check to ensure the underlying data segments are not corrupted:
sql
ADMIN CHECK TABLET (tablet_id); -- Get tablet_id from BE logs if possible
If the crash persists after changing the SQL to UPPER(get_json_string(...)), it strongly suggests a bug in the storage layer's handling of the OUTPUT column data, and an upgrade to a later patch release of the 4.0 branch is highly recommended.
References
• sql-reference/sql-functions/bitmap-functions/bitmap_subset_in_range.md
• sql-reference/sql-functions/bitmap-functions/bitmap_subset_limit.md
• release_notes/release-2.5.md
• release_notes/release-3.4.mdLý Thành
09/18/2026, 8:40 AMOUTPUT, '$.CBHitType'), get_json_string(OUTPUT, '$.cbhittype')) COMMENT "CBHitType from request json";
correctRocky
09/18/2026, 8:40 AMCBHitType during data ingestion or when the column is added. This avoids the expensive get_json_string and coalesce logic during query time.
2. Addressing the Crash: In your previous crash log, the error occurred during a memcpy while filtering. Moving the JSON extraction to a generated column reduces the computational complexity and the number of temporary string allocations during the scan phase, which may bypass the memory issue you encountered.
Correctness Check:
* Syntax: ADD COLUMN col_name data_type AS expr is the standard StarRocks syntax for generated columns.
* Data Type: VARCHAR(50) is appropriate for values extracted via get_json_string.
* Compatibility: COALESCE and get_json_string are scalar functions, which are allowed in generated expressions (aggregate functions are the only major restriction).
One Important Note:
Table Type: Generated columns are not supported on Aggregate Key tables. If your table dtm_los_log_cbscore is a Duplicate Key or Primary Key table (which is typical for log data), this command will work perfectly.
Recommended Execution:
If the OUTPUT column contains very large JSON objects, adding this column will trigger a background task to populate the new column for existing rows. You can monitor the progress with:
sql
SHOW ALTER TABLE COLUMN;
Once added, you should update your queries to use the new CBHitType column directly instead of the COALESCE(get_json_string(...)) expression. StarRocks will even try to automatically rewrite existing queries to use this generated column if the expressions match.
References
• sql-reference/sql-statements/generated_columns.md
• sql-reference/sql-statements/table_bucket_part_index/ALTER_TABLE.md
References
• sql-reference/sql-statements/table_bucket_part_index/ALTER_TABLE.md
• sql-reference/sql-statements/generated_columns.mdLý Thành
09/18/2026, 8:48 AMRocky
09/18/2026, 8:48 AM01a0b36a-7fa6-72e6-b55d-fdcea87835ab) is different from the first one but related to the same high-pressure workload.
Analysis of the Second Crash
* StarRocks Version: 4.0.12 RELEASE.
* Crash Type: SIGSEGV at std::_Sp_counted_base<...>::_M_release().
* Context: Spill to Disk logic (SpillProcessChannel::close).
* Trigger: The crash occurred while the query engine was tearing down/closing a "spill" operator. This typically happens when a query that was writing intermediate data to disk (because it ran out of memory) is either finishing or being canceled.
Root Cause
In version 4.0.12, there is a known race condition and memory management bug in the pipeline spilling logic. When a query is canceled while a spill operation is in progress (specifically during partition sorting or channel cleanup), StarRocks may attempt to release a shared pointer that has already been invalidated or is in an inconsistent state.
This is a recorded issue (related to internal PR #75140) where query cancellation during spilling triggers a segmentation fault in the SpillProcessChannel.
Recommendations
1. Immediate Fix: Upgrade to 4.0.14 or later
* Version 4.0.12 has several identified stability issues with the new pipeline execution engine and spilling. Later versions (4.0.14/4.0.15) contain critical fixes for SpillProcessOperator and general memory safety during query teardown.
2. Avoid Spilling (Optimization)
* Spilling is only triggered when a query exceeds the mem_limit.
* Increase Memory: If the BE has free RAM, increase the query memory limit to keep the operation in memory:
sql
SET mem_limit = 16106127360; -- Increase to 15GB or higher
* Disable Spilling (As a last resort): If the crashes are frequent and you'd prefer an Out of Memory error over a BE crash:
sql
SET enable_spill = false;
3. Monitor Query Cancellations
* Since this crash often happens during cancellation, check if your application or users are manually killing long-running queries. Sudden cancellations of heavy queries are the primary trigger for this specific close() crash in 4.0.12.
Summary of your issues
You are encountering two distinct bugs in 4.0.12:
1. Filtering crash: Caused by large string manipulation/JSON extraction (the filter_range crash).
2. Spilling crash: Caused by memory management during spill cleanup (the M_release crash).
Both are addressed by upgrading to a later patch of the 4.0 branch. If an upgrade is not immediate, the Generated Column solution we discussed earlier is your best path to reduce the memory pressure that leads to both filtering overhead and spilling.
References
• release_notes/release-4.0.mdLý Thành
09/18/2026, 8:50 AMRocky
09/18/2026, 8:50 AMenable_spill is a system variable, you can view its current value using the standard MySQL-compatible SHOW VARIABLES command.
To view the current session value:
This shows the value active for your current connection.
sql
SHOW VARIABLES LIKE 'enable_spill';
To view the global value:
This shows the default value set for the entire cluster.
sql
SHOW GLOBAL VARIABLES LIKE 'enable_spill';
Related variables you might want to check:
If you are troubleshooting the crash I mentioned earlier, you should also check these related spilling settings:
sql
SHOW VARIABLES LIKE '%spill%';
* spill_mode: Usually auto.
* enable_spill_to_remote_storage: If you are using object storage for spills.
How to change it:
* Session level (affects only your next queries):
sql
SET enable_spill = true;
* Global level (affects all new connections):
sql
SET GLOBAL enable_spill = true;
Note: For spilling to work, you must also have a valid directory configured in your be.conf under spill_local_storage_dir. If this is not set, enabling the variable will have no effect.
References
• administration/management/resource_management/spill_to_disk.md
• sql-reference/System_variable.md
References
• sql-reference/System_variable.md
• administration/management/resource_management/spill_to_disk.md
• administration/management/FE_configuration.md
• administration/management/BE_configuration.mdLý Thành
09/18/2026, 8:56 AMQuerySource=MV → query này được materialized view refresh task tự động sinh ra và chạy (không phải bạn gõ tay), chạy trong default_mv_wg.
can limit resource of this default_mv_wg work group to pass this errorRocky
09/18/2026, 8:56 AMdefault_mv_wg work group to prevent these background Materialized View (MV) refresh tasks from crashing your cluster.
Since you are on 4.0.12, modifying this system-defined resource group is the correct approach to isolate the impact of heavy background refreshes.
How to limit default_mv_wg
You can use the ALTER RESOURCE GROUP command to lower the memory ceiling and concurrency. This will force heavy MV refreshes to either wait in a queue or fail with a "memory limit exceeded" error instead of triggering the buggy spilling logic that crashes the BE.
Run the following SQL:
sql
ALTER RESOURCE GROUP default_mv_wg WITH (
"concurrency_limit" = "1", -- Only allow 1 MV refresh at a time
"mem_limit" = "20%", -- Limit total group memory to 20% of BE RAM
"big_query_mem_limit" = "10GB" -- Kill any single refresh task that exceeds 10GB
);
Why this helps:
1. concurrency_limit = 1: Prevents multiple MVs from refreshing simultaneously, which often causes the memory "spike" that triggers the crashing spilling code.
2. mem_limit: Lowers the overall resource footprint allowed for background tasks.
3. big_query_mem_limit: This is the most effective way to "pass" the crash. If a refresh task starts consuming too much memory, StarRocks will terminate the query with an error (visible in fe.audit.log) before it hits the critical threshold where the SpillProcessChannel crash occurs.
To check your changes:
You can verify the current configuration of the group with:
sql
SELECT * FROM information_schema.resource_groups WHERE name = 'default_mv_wg';
Proactive Tip:
If you have one specific Materialized View that is particularly large and causing these issues, you can create a dedicated resource group for it and assign the MV to that group:
sql
-- 1. Create a "low-priority" group
CREATE RESOURCE GROUP mv_heavy_task WITH ("mem_limit" = "10%", "concurrency_limit" = "1");
-- 2. Assign the specific MV to it (requires recreating or altering MV properties)
ALTER MATERIALIZED VIEW your_mv_name SET ("resource_group" = "mv_heavy_task");
Note: If the MV refresh fails frequently after these limits, it confirms the query is too large for the current memory settings. In that case, optimizing the MV definition or implementing the Generated Columns (as discussed earlier) to reduce the data volume is recommended.
References
• administration/management/resource_management/resource_group.md
• sql-reference/sql-statements/cluster-management/resource_group/ALTER_RESOURCE_GROUP.md
References
• administration/management/resource_management/resource_group.md
• sql-reference/sql-statements/cluster-management/resource_group/CREATE_RESOURCE_GROUP.mdLý Thành
09/18/2026, 9:01 AMRocky
09/18/2026, 9:01 AMdefault_mv_wg is currently allowed to use up to 80% of memory and has no concurrency limit (null). This is why your MV refreshes are likely triggering the spilling logic and subsequent BE crashes when multiple tasks run or memory spikes.
To stabilize your cluster and "pass" this error by failing the task safely instead of crashing the BE, run the following command:
sql
ALTER RESOURCE GROUP default_mv_wg WITH (
"concurrency_limit" = "1",
"mem_limit" = "20%",
"big_query_mem_limit" = "10G",
"spill_mem_limit_threshold" = "90%"
);
Why these values?
* concurrency_limit = 1: This is the most critical setting. It ensures only one Materialized View refresh happens at a time. Parallel refreshes in version 4.0.12 are the most common cause of memory instability and spilling crashes.
* mem_limit = 20%: Your other groups (bui_wg and cpm_wg) are already claiming 80-90% of memory. Lowering the MV group limit prevents background tasks from starving your main workloads or pushing the BE into a critical state.
* big_query_mem_limit = 10G: (Adjust this based on your BE RAM). If a single refresh task uses more than 10GB, StarRocks will kill the query. In version 4.0.12, it is much better for a task to fail with a "Memory limit exceeded" error than to attempt to spill and crash the node.
* spill_mem_limit_threshold = 90%: By setting this high, you instruct the system only to attempt spilling when it's almost at the limit. Combined with the big_query_mem_limit, this makes it more likely the query will be aborted safely before the buggy spilling code path is even entered.
Verification
After running the command, check the status again:
sql
SELECT * FROM information_schema.resource_groups WHERE name = 'default_mv_wg';
If your MV refreshes start failing with Memory exceed limit, you will need to either increase the BE memory or optimize the MV (e.g., using the Generated Columns or partition refreshes) rather than letting it run with refresh tasks run "unlimited."Lý Thành
09/18/2026, 9:05 AMRocky
09/18/2026, 9:05 AMbig_query_mem_limit is a circuit breaker for memory usage. It defines the maximum amount of memory a single query is allowed to consume on each individual BE (Backend) node.
In your specific example:
'big_query_mem_limit' = '1073741824'
This means any query assigned to this resource group will be automatically terminated if it tries to use more than 1 GB (1,073,741,824 bytes) of RAM on any single BE.
Key Characteristics:
* Unit: It is measured in bytes.
* Scope: The limit is applied per BE node, not globally across the cluster. If you have 3 BEs, a query could theoretically use nearly 3 GB in total across the cluster without being killed, as long as it stays under 1 GB on each node.
* Behavior: When a query exceeds this limit, StarRocks kills the query and returns a "Memory limit exceeded" error. You can find these events in the fe.audit.log under the ErrorCode column.
* Purpose: It protects the cluster from "rogue" or poorly written queries that might otherwise consume all available memory and crash the Backend process.
Difference between mem_limit and `big_query_mem_limit`:
* mem_limit (e.g., '20%'): This is the "soft" pool for the entire resource group. It defines the total memory all queries in that group can use together. If the group hits this, queries might start spilling to disk or queuing.
* big_query_mem_limit (e.g., '1073741824'): This is a "hard" limit for each individual query. It is used to catch and stop a single heavy query before it impacts others, regardless of whether the group still has memory available in its 20% quota.
References
• administration/management/resource_management/resource_group.md
• faq/resource_isolation_faq.md
• best_practices/audit_log_resource_group.md
References
• administration/management/resource_management/resource_group.md
• faq/resource_isolation_faq.md
• administration/management/monitoring/metrics.md
• best_practices/audit_log_resource_group.mdLý Thành
09/18/2026, 9:07 AM'big_query_mem_limit' = '1073741824' is 1GB how about 10GBRocky
09/18/2026, 9:07 AMbig_query_mem_limit to 10 GB, you should use the following value in bytes:
'big_query_mem_limit' = '10737418240'
Calculation:
* 1 GB = $1024 \times 1024 \times 1024 = 1,073,741,824$ bytes
* 10 GB = $1,073,741,824 \times 10 = \mathbf{10,737,418,240}$ bytes
Updated SQL Example:
sql
ALTER RESOURCE GROUP default_mv_wg WITH (
"big_query_mem_limit" = "10737418240"
);
Important Notes:
1. Units: Unlike the mem_limit parameter (which accepts percentages like "20%" or strings like "10G"), the big_query_mem_limit in the Resource Group definition strictly requires the value in bytes as a string.
2. Per BE Node: Remember that this limit is enforced on each individual BE node. If a query uses 9 GB on BE-1 and 9 GB on BE-2, it will not be killed (total 18 GB), but if it hits 10.1 GB on a single node, it will be terminated.
3. Safety: For your current issue (preventing crashes during MV refresh), setting this to roughly 10-20% of your total BE RAM is a good safety measure to ensure a "heavy" refresh is killed before it can destabilize the node.
References
• administration/management/resource_management/resource_group.md
• sql-reference/sql-functions/string-functions/format_bytes.md
References
• administration/management/BE_configuration.md
• sql-reference/System_variable.md
• sql-reference/sql-statements/loading_unloading/BROKER_LOAD.md
• sql-reference/sql-functions/string-functions/format_bytes.md
• administration/management/resource_management/Memory_management.md
• administration/management/resource_management/resource_group.md
• knowledge/usage/best-practice.mdLý Thành
09/21/2026, 2:47 AMRocky
09/21/2026, 2:47 AMDROP DATABASE command, StarRocks does not delete the data immediately. It moves the metadata to a "recycle bin" for a retention period (default is 24 hours).
* How to check: Look at your FE audit log (fe/log/fe.audit.log) for any DROP DATABASE statements.
* How to recover: Try running the recover command immediately:
sql
RECOVER DATABASE your_db_name;
Note: This will not work if the database was dropped using DROP DATABASE ... FORCE.
2. FE Metadata Sync Issues
In a non-shared cluster, the Frontend (FE) nodes manage metadata using BDBJE. If the FE nodes get out of sync or if you are connected to a "Follower" FE that hasn't replayed the latest journals, the database might appear missing.
* Check FE Status: Run SHOW FRONTENDS; and ensure the Alive column is true for all nodes and one is designated as LEADER.
* Check Logs: Look in fe/log/fe.log for errors like ReplicaWriteException or got interrupt exception... when replay journal. If an FE cannot replay the journal, it will have an outdated view of the metadata.
3. Visibility and Permissions
Sometimes the database exists, but your current session or user cannot see it.
* Catalog Context: Ensure you are in the internal catalog:
sql
SET CATALOG default_catalog;
SHOW DATABASES;
* Permissions: If your user's roles or permissions were modified, the database will be hidden from SHOW DATABASES. Try logging in as the root or admin user to verify if the database is visible to them.
4. Disk or Hardware Failure (Data Loss)
Since it is a shared-nothing cluster, the metadata lives on the FE's disk (under the meta_dir path).
* If the FE's local storage was wiped (e.g., a Kubernetes pod restarted without a Persistent Volume), and there are no other FE Followers to sync from, the metadata is lost.
* If you have a backup, you can use the RESTORE command to recover from a repository.
Recommendation:
1. Run RECOVER DATABASE <name>; just in case.
2. Check fe.audit.log for the string DROP.
3. Check fe.log for any "Metadata failure" or "BDBJE" errors.
4. If you are using Kubernetes, verify that your FE meta_dir is mounted to a persistent volume (PVC).
References
• administration/Meta_recovery.mdLý Thành
09/21/2026, 3:34 AMRocky
09/21/2026, 3:34 AMSET
In the SET clause, when a column name exists in both the target table and the source (the CTE), StarRocks may update the column with its own existing value (a "no-op") or throw an ambiguity error. You should qualify the source columns with the CTE name.
2. Date Arithmetic
While CURDATE() - 7 sometimes works, it is safer to use the INTERVAL syntax to ensure proper date handling.
3. Version & Table Type Requirements
* StarRocks Version: CTEs in UPDATE statements are supported starting from v3.0.
* Table Type: The target table (dmapp.dtm_los_approval) must be a Primary Key table. StarRocks does not support UPDATE on Duplicate, Aggregate, or Unique Key models.
Recommended Version
sql
WITH strategy AS (
SELECT id, strategy_decision, strategy_name, strategy_version
FROM losrep.approval
WHERE created_date > DATE_SUB(CURDATE(), INTERVAL 7 DAY)
AND strategy_name IS NOT NULL
AND strategy_name <> ''
)
UPDATE dmapp.dtm_los_approval
SET strategy_decision = strategy.strategy_decision, -- Explicitly reference the CTE
strategy_name = strategy.strategy_name,
strategy_version = strategy.strategy_version
FROM strategy
WHERE dmapp.dtm_los_approval.id = strategy.id;
Key Checks:
* Table Model: Run SHOW CREATE TABLE dmapp.dtm_los_approval; and verify it says PRIMARY KEY (id).
* Joins: StarRocks matches rows based on the FROM and WHERE clauses. If the CTE returns multiple rows for the same id, the target table will be updated with a value from one of those rows chosen randomly. Ensure id is unique in your losrep.approval source to avoid non-deterministic results.
References
• sql-reference/sql-statements/table_bucket_part_index/UPDATE.md
• table_design/table_types/primary_key_table.md
References
• sql-reference/sql-statements/table_bucket_part_index/UPDATE.md
• knowledge/usage/best-practice.mdLý Thành
09/21/2026, 3:43 AMRocky
09/21/2026, 3:43 AMSUBMIT TASK command.
However, there is a technical constraint: as of recent versions, SUBMIT TASK officially supports INSERT and CREATE TABLE AS SELECT (CTAS) statements, but may not support direct UPDATE statements in some versions.
The Recommended Way: Rewrite as INSERT
Since your target table dmapp.dtm_los_approval is a Primary Key table (required for that UPDATE syntax), an INSERT INTO ... SELECT statement performs an "upsert." This means it will update existing rows with the same id and insert new ones if they don't exist.
You can wrap this in a scheduled task like this:
sql
SUBMIT TASK daily_approval_update
SCHEDULE EVERY(INTERVAL 1 DAY)
AS
INSERT INTO dmapp.dtm_los_approval (id, strategy_decision, strategy_name, strategy_version)
SELECT
id,
strategy_decision,
strategy_name,
strategy_version
FROM losrep.approval
WHERE created_date > DATE_SUB(CURDATE(), INTERVAL 7 DAY)
AND strategy_name IS NOT NULL
AND strategy_name <> '';
Why this works:
1. Functionality: On a Primary Key table, INSERT acts exactly like your UPDATE for existing IDs.
2. Scheduling: The SCHEDULE EVERY(INTERVAL 1 DAY) clause tells StarRocks to trigger this every 24 hours.
3. Asynchronous: It runs in the background. You can check the status of the task using:
sql
-- View the task definition
SELECT * FROM INFORMATION_SCHEMA.tasks WHERE task_name = 'daily_approval_update';
-- View the execution history (Success/Failure)
SELECT * FROM INFORMATION_SCHEMA.task_runs WHERE task_name = 'daily_approval_update' ORDER BY create_time DESC;
How to manage the task:
* To run it manually once right now: ALTER TASK daily_approval_update RESUME; (if it was paused) or just wait for the schedule.
* To stop it: DROP TASK daily_approval_update;
* Version requirement: You need StarRocks v3.3 or higher for the EVERY(INTERVAL ...) scheduling syntax within SUBMIT TASK.
References
• sql-reference/sql-statements/loading_unloading/ETL/SUBMIT_TASK.md
• table_design/table_types/primary_key_table.md
• sql-reference/sql-statements/table_bucket_part_index/UPDATE.md
References
• sql-reference/sql-statements/table_bucket_part_index/UPDATE.md
• sql-reference/sql-statements/loading_unloading/ETL/SUBMIT_TASK.md
• loading/InsertInto.mdLý Thành
09/21/2026, 3:56 AMRocky
09/21/2026, 3:56 AMdate_trunc function or simply CURDATE(). Both effectively represent YYYY-MM-DD 00:00:00.
* Using `date_trunc`:
WHERE created_date < date_trunc('day', now())
* Using `CURDATE`:
WHERE created_date < CURDATE()
2. Schedule Task with Specific Start Time
In your SUBMIT TASK statement, you can use the START parameter to define exactly when the first execution should occur.
If you want the task to run every day starting at midnight tonight, you would format it like this:
sql
SUBMIT TASK daily_approval_update
-- Start at midnight on 2026-09-21 and repeat every 1 day
SCHEDULE START('2026-09-21 00:00:00') EVERY(INTERVAL 1 DAY)
AS
INSERT INTO dmapp.dtm_los_approval (id, strategy_decision, strategy_name, strategy_version)
SELECT
id,
strategy_decision,
strategy_name,
strategy_version
FROM losrep.approval
WHERE created_date < date_trunc('day', now()) -- Records before today's midnight
AND strategy_name IS NOT NULL
AND strategy_name <> '';
Summary of Syntax
* START('YYYY-MM-DD HH:mm:ss'): Tells StarRocks when to trigger the very first run.
* EVERY(INTERVAL 1 DAY): Tells StarRocks the frequency.
* date_trunc('day', now()): Returns today's date at 00:00:00.
Note: If you set a START time that is in the past, StarRocks will typically trigger the task immediately to "catch up" and then follow the 1-day interval from that point.
References
• sql-reference/sql-functions/date-time-functions/date_trunc.md
• sql-reference/sql-statements/loading_unloading/ETL/SUBMIT_TASK.md
• sql-reference/sql-functions/date-time-functions/now.md
References
• sql-reference/sql-statements/loading_unloading/ETL/SUBMIT_TASK.md
• using_starrocks/async_mv/materialized_view_task_run_details.mdLý Thành
09/22/2026, 7:12 AMRocky
09/22/2026, 7:12 AMLý Thành
09/22/2026, 7:15 AMRocky
09/22/2026, 7:16 AMINSERT validation and NOT MATCH logic for GIN indexes.
* Constraint: If you plan to eventually move to 4.1, staying on v4.0.13 is fine. However, once you move to the 4.1 branch, you cannot downgrade to anything lower than v4.0.6.
Summary Recommendation
* New Clusters / Major Upgrades: Go with v4.1.5. It has the best performance and the most advanced automation features (Adaptive Layout).
* Existing 4.0 Clusters: You can move to v4.0.13, but if you're taking the time to update, v4.0.14 is the more complete patch for that branch.
* Maximum Stability: If your organization requires the most conservative path possible, the v3.5.21 (Stable) branch is still the gold standard for "no-surprises" production use.
References
• StarRocks version 4.1 Release Notes
• StarRocks version 4.0 Release Notes
• Introduction - StarRocks Docs
• Version Release Guide
References
• release_notes/release-4.0.mdLý Thành
09/22/2026, 7:19 AMRocky
09/22/2026, 7:19 AMsql
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_scheduling_tablets" = "0");
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_balancing_tablets" = "0");
ADMIN SET FRONTEND CONFIG ("disable_balance" = "true");
ADMIN SET FRONTEND CONFIG ("disable_colocate_balance" = "true");
2. Meta Scan Rewrite (Precaution): Although the docs specifically mention this for v4.0.3, it is recommended to disable this optimization before moving back to the 3.5 branch:
sql
SET GLOBAL enable_rewrite_simple_agg_to_meta_scan = false;
3. FE Configuration: In your fe.conf, set ignore_unknown_log_id = true. This allows the older FE version to ignore metadata logs generated by the newer v4.0 version.
Downgrade Procedure
Important: You must downgrade FEs first, then BEs.
1. FE Nodes:
* Create a metadata snapshot: ALTER SYSTEM CREATE IMAGE;.
* Stop the Follower FEs one by one, replace the binaries with v3.5.21, and restart them.
* Finally, stop the Leader FE, replace the binaries, and restart it.
2. BE Nodes:
* Stop each BE gracefully (stop_be.sh --graceful), replace binaries, and restart.
3. Cleanup: Once the cluster is stable on v3.5.21, re-enable tablet balancing and (after the first checkpoint) you can set ignore_unknown_log_id = false in fe.conf.
Warning
If you have used features unique to v4.0 (like specific GIN index enhancements or new SQL syntax in materialized views), those may fail or become invalid after the downgrade. Always perform a metadata backup (copy the meta directory) before starting the process.
References
• release_notes/release-4.0.md
• deployment/downgrade.md
• release_notes/release-3.5.md
References
• release_notes/release-4.0.md
• release_notes/release-3.5.md
• deployment/downgrade.md
• release_notes/release-3.4.mdLý Thành
09/22/2026, 9:07 AMRocky
09/22/2026, 9:08 AMscore1 value from your OUTPUT column specifically when it matches the structure in Case 2 (where it is nested inside a result object), you can use the get_json_string function or the JSON arrow operator ->.
Method 1: Using get_json_string (Recommended for VARCHAR columns)
This function returns a VARCHAR. If the path $.result.score1 does not exist (as in Case 1), it will return NULL.
To update the table:
sql
UPDATE dtm_log_score
SET score1 = get_json_string(OUTPUT, '$.result.score1')
WHERE get_json_string(OUTPUT, '$.result.score1') IS NOT NULL;
To use in a SELECT (for insertion):
sql
SELECT
OUTPUT,
get_json_string(OUTPUT, '$.result.score1') AS extracted_score1
FROM dtm_log_score
WHERE json_exists(OUTPUT, '$.result.score1');
──────────
Method 2: Using the Arrow Operator -> (Recommended for JSON columns)
If your OUTPUT column is defined with the JSON data type, the syntax is even simpler. Note that this returns a JSON-type value, so you may need to CAST it to the target type of your score1 column.
To update the table:
sql
UPDATE dtm_log_score
SET score1 = CAST(OUTPUT->'result'->'score1' AS DOUBLE)
WHERE OUTPUT->'result'->'score1' IS NOT NULL;
Key Functions Used:
* get_json_string(json_str, path): Extracts a string from the specified JSON path.
* json_exists(json_expr, path): Returns 1 if the path exists, which is useful for filtering rows that follow the "Case 2" format.
* CAST(... AS TYPE): If your target score1 column is numeric (e.g., DOUBLE or DECIMAL), wrap the extraction in a cast since JSON extraction defaults to strings or JSON types.
Handling Case 1 vs. Case 2:
Because Case 1 does not have a result key, both get_json_string(OUTPUT, '$.result.score1') and OUTPUT->'result'->'score1' will safely return NULL for those rows, preventing incorrect data from being inserted.
References
• get_json_string
• json_exists
• JSON Data Type & Operators
References
• sql-reference/sql-functions/json-functions/json-query-and-processing-functions/get_json_string.md
• sql-reference/sql-functions/json-functions/json-query-and-processing-functions/json_exists.md
• sql-reference/data-types/semi_structured/JSON.md
• using_starrocks/Flat_json.md
References
• sql-reference/sql-functions/json-functions/json-query-and-processing-functions/json_exists.md
• sql-reference/sql-functions/json-functions/json-query-and-processing-functions/json_query.md
• sql-reference/sql-functions/json-functions/overview-of-json-functions-and-operators.md
• sql-reference/data-types/semi_structured/JSON.md
• sql-reference/sql-functions/json-functions/json-query-and-processing-functions/arrow-function.mdLý Thành
09/22/2026, 9:15 AMRocky
09/22/2026, 9:15 AMscore1 column to your dtm_log_score table, you have two main options depending on whether you want to manually update the data or have StarRocks extract it automatically.
Option 1: Standard Column (Manual Update)
Use this if you want a normal column that you will populate once or via your own ETL process. Since your data looks like a decimal (e.g., "0.881"), I recommend VARCHAR or DOUBLE.
sql
ALTER TABLE dtm_log_score
ADD COLUMN score1 VARCHAR(64) DEFAULT NULL;
After running this, you can use the UPDATE statement provided in the previous answer to fill it with data.
──────────
Option 2: Generated Column (Automatic Extraction)
Recommended: If you are on StarRocks v3.1 or higher, you can create a Generated Column. This column will automatically extract score1 whenever a new row is inserted or the OUTPUT column is updated. It also saves you from running manual UPDATE scripts.
sql
ALTER TABLE dtm_log_score
ADD COLUMN score1 VARCHAR(64) AS get_json_string(OUTPUT, '$.result.score1');
Why use this?
* Automatic: Any new data following "Case 2" will have its score1 populated immediately.
* Performance: StarRocks stores this value on disk, so queries on score1 will be much faster than parsing JSON at query time.
──────────
Important Notes:
1. Table Model:
* If your table is a Duplicate Key or Primary Key model, the command above works directly.
* If your table is an Aggregate Key model, you must specify an aggregation type (e.g., REPLACE or NONE):
sql
ALTER TABLE dtm_log_score ADD COLUMN score1 VARCHAR(64) REPLACE DEFAULT NULL;
2. Position: By default, the column is added at the end. If you want it after a specific column, add AFTER column_name at the end of the command.
3. Check Progress: Adding a column is an asynchronous operation. You can check if it's finished by running:
sql
SHOW ALTER TABLE COLUMN;
References
• ALTER TABLE
• Generated Columns
References
• sql-reference/sql-statements/table_bucket_part_index/ALTER_TABLE.md
• using_starrocks/Flat_json.md
• table_design/generated_columns.md
References
• sql-reference/sql-statements/table_bucket_part_index/ALTER_TABLE.mdLý Thành
09/22/2026, 9:21 AMRocky
09/22/2026, 9:22 AMscore1 column, since the values in your JSON are decimal-like strings (e.g., "0.881"), you should choose between DECIMAL and DOUBLE based on your precision needs:
1. Recommended: DECIMAL(P, S) (High Precision)
If you need exact precision for comparisons (e.g., score1 > 0.880) or if these scores are used for financial/risk calculations, use DECIMAL.
* Precision (P): Total number of digits.
* Scale (S): Number of digits after the decimal point.
* Example: DECIMAL(10, 3) would store numbers up to 9999999.999.
How to add it (as a Generated Column):
sql
ALTER TABLE dtm_log_score
ADD COLUMN score1 DECIMAL(10, 3)
AS CAST(get_json_string(OUTPUT, '$.result.score1') AS DECIMAL(10, 3));
2. Alternative: DOUBLE (Better Performance)
If these scores are used for general analytics, machine learning, or scientific calculations where a tiny rounding difference won't matter, DOUBLE is faster and uses less storage.
* Example: DOUBLE
How to add it:
sql
ALTER TABLE dtm_log_score
ADD COLUMN score1 DOUBLE
AS CAST(get_json_string(OUTPUT, '$.result.score1') AS DOUBLE);
Which one to choose?
Feature | ***DECIMAL*** | ***DOUBLE***
Precision | Exact (fixed-point) | Approximate (floating-point)
Performance | Good (Optimized "Fast Decimal") | Excellent (Native CPU support)
Use Case | Financials, Exact Thresholds | Statistics, Aggregations, ML
Recommendation: For a score like "0.881", DECIMAL(10, 3) is the safest choice to ensure the data you extract matches the JSON exactly without any floating-point "noise" (like 0.881000000001).
Important Tip for v4.0/v3.5
Since you are extracting from a JSON string, if some rows have non-numeric data in that field, CAST will return NULL for those rows instead of failing, which is usually the desired behavior for dirty data.
References
• Numeric Data Types
• Generated Columns
References
• sql-reference/data-types/numeric/DECIMAL.md
• sql-reference/data-types/numeric/DOUBLE.md
• table_design/generated_columns.md
References
• sql-reference/data-types/numeric/DECIMAL.md
• sql-reference/data-types/numeric/DOUBLE.md
• table_design/generated_columns.md
• sql-reference/data-types/numeric/FLOAT.md
• sql-reference/sql-functions/cast-functions/cast.md
References
• sql-reference/data-types/numeric/DECIMAL.md
• using_starrocks/Flat_json.md
• sql-reference/data-types/semi_structured/JSON.mdLý Thành
09/22/2026, 9:23 AMRocky
09/22/2026, 9:24 AMscore1 is a non-numeric string like "error", the following will happen:
1. The Result becomes NULL
When you use CAST(... AS DOUBLE) or CAST(... AS DECIMAL), StarRocks attempts to convert the string to a number. If the string is not a valid number (like "error", "N/A", or an empty string ""), the CAST function will return NULL.
It will not cause the entire query to fail or the data loading to crash.
2. Behavior in a Generated Column
If you set up score1 as a Generated Column, any row containing "error" in the JSON will simply have a NULL value in the score1 column.
sql
-- If OUTPUT is: {"result": {"score1": "error"}}
-- This expression:
CAST(get_json_string(OUTPUT, '$.result.score1') AS DOUBLE)
-- Returns: NULL
3. How to handle "error" strings
If you want to distinguish between a "missing" value and an "invalid/error" value, you have two options:
Option A: Keep it as a String (VARCHAR)
If you need to see the actual word "error" in your reports, define the column as VARCHAR instead of a numeric type.
sql
ALTER TABLE dtm_log_score
ADD COLUMN score1 VARCHAR(64)
AS get_json_string(OUTPUT, '$.result.score1');
Option B: Use a Default Value for Errors
If you want to treat "error" as a specific number (like -1), you can use ifnull or `CASE`:
sql
ALTER TABLE dtm_log_score
ADD COLUMN score1 DOUBLE
AS ifnull(CAST(get_json_string(OUTPUT, '$.result.score1') AS DOUBLE), -1.0);
Summary
* Valid number string ("0.881") $\rightarrow$ Extracted as 0.881.
* Invalid string ("error") $\rightarrow$ Extracted as NULL.
* Missing key (Case 1) $\rightarrow$ Extracted as NULL.
References
• CAST Function
• Generated Columns
References
• sql-reference/sql-functions/cast-functions/cast.md
• table_design/generated_columns.md
• sql-reference/sql-functions/json-functions/json-query-and-processing-functions/get_json_string.md
References
• sql-reference/sql-statements/generated_columns.mdLý Thành
09/22/2026, 9:27 AMRocky
09/22/2026, 9:32 AMUPDATE statements are unnecessary and will cause an error.
Here is the breakdown of why and the recommended way to do it:
1. The UPDATE statements will fail
When you define a column with the AS (...) syntax, it becomes a Generated Column. In StarRocks:
* Automatic Population: StarRocks automatically calculates and fills the data for all existing rows as soon as you add the column.
* Read-Only: You cannot manually UPDATE or INSERT values into a generated column. If you try to run your UPDATE statements, StarRocks will return an error: materialized column 'score' can not be specified.
2. Recommended SQL
You can simplify your request by combining the ALTER statements and removing the UPDATE scripts. I also recommend using get_json_double for cleaner code.
sql
-- Add both columns in one go (Recommended)
ALTER TABLE dmapp.dtm_log_score
ADD COLUMN score DOUBLE AS get_json_double(OUTPUT, '$.result.score'),
ADD COLUMN score1 DOUBLE AS get_json_double(OUTPUT, '$.result.score1');
3. Important Considerations
* Asynchronous Operation: Adding columns to an existing table is an asynchronous task. After running the ALTER command, check the progress with:
sql
SHOW ALTER TABLE COLUMN;
The columns will only be "visible" and populated once the State is FINISHED.
* Data Types: As discussed before, if you need 100% exact precision (like for financial balances), use DECIMAL(10,3) instead of DOUBLE.
* Aggregate Tables: If your table is an AGGREGATE KEY model, you cannot use Generated Columns. This feature is only supported for DUPLICATE KEY and PRIMARY KEY models.
Summary
Just run the ALTER TABLE statement. StarRocks will handle the data extraction for your existing rows and all future rows automatically. No UPDATE is needed.
References
• Generated Columns
• ALTER TABLE
• get_json_double
References
• sql-reference/sql-statements/table_bucket_part_index/ALTER_TABLE.md
• table_design/generated_columns.md
• sql-reference/sql-functions/json-functions/json-query-and-processing-functions/get_json_double.md
• loading/InsertInto.md
• sql-reference/sql-statements/generated_columns.md
• sql-reference/sql-functions/json-functions/json-query-and-processing-functions/get_json_string.md
• sql-reference/sql-functions/json-functions/overview-of-json-functions-and-operators.md
• sql-reference/sql-functions/json-functions/json-query-and-processing-functions/cast.md
• sql-reference/sql-statements/generated_columns.md
• sql-reference/sql-statements/table_bucket_part_index/ALTER_TABLE.mdRocky
09/22/2026, 9:32 AMRocky
09/22/2026, 9:32 AMRocky
09/22/2026, 9:32 AMRocky
09/22/2026, 9:32 AMRocky
09/22/2026, 9:32 AMRocky
09/22/2026, 9:32 AMRocky
09/22/2026, 9:32 AMRocky
09/22/2026, 9:32 AMRocky
09/22/2026, 9:32 AMLý Thành
09/22/2026, 10:06 AMdtm_log_score (
SYS_RUN_DATE datetime NULL COMMENT "",
ID decimal(38, 20) NULL COMMENT "",
APP_CODE varchar(20) NULL COMMENT "",
INPUT varchar(65533) NULL COMMENT "",
OUTPUT varchar(65533) NULL COMMENT "",
REQUEST_TIME datetime NULL COMMENT "",
RESPOND_TIME datetime NULL COMMENT "",
SCORE_STAGE varchar(100) NULL COMMENT "",
TYPE varchar(100) NULL COMMENT "",
score double NULL AS CAST((get_json_string(OUTPUT, '$.result.score')) AS DOUBLE) COMMENT "",
score1 double NULL AS CAST((get_json_string(OUTPUT, '$.result.score1')) AS DOUBLE) COMMENT ""
) ENGINE=OLAP
PRIMARY KEY(SYS_RUN_DATE, ID)
DISTRIBUTED BY HASH(APP_CODE) BUCKETS 8
PROPERTIES (
"compression" = "LZ4",
"fast_schema_evolution" = "true",
"replicated_storage" = "true",
"replication_num" = "2"
);
this table 17GB, review for better table designRocky
09/22/2026, 10:07 AMDUPLICATE KEY (Recommended for Logs)
You are currently using a PRIMARY KEY table.
* The Issue: PK tables keep an index in memory to handle updates. For a "log" table (which is usually append-only), this wastes a significant amount of RAM.
* The Fix: Use DUPLICATE KEY. It is the most efficient model for log data and allows StarRocks to use a "Sort Key" for extremely fast filtering on the columns you query most.
2. Add Partitioning
Your current table is one single block (17GB). As it grows to 100GB+, queries will slow down because StarRocks has to scan everything.
* The Fix: Partition by SYS_RUN_DATE. This allows StarRocks to "prune" (skip) entire days of data when you query a specific range.
3. Use the Native JSON Type
You are using VARCHAR(65533) and manual CAST(get_json_string...).
* The Issue: VARCHAR stores JSON as raw text, which is bulky.
* The Fix: Use the native JSON type. It stores data in a binary format (faster to parse) and supports Flat JSON (available in v3.3+, enabled by default in v4.0), which automatically speeds up sub-field access without needing generated columns.
4. Optimize the ID Column
* The Issue: decimal(38, 20) is a very heavy data type (16 bytes).
* The Fix: If your ID is a standard integer, use BIGINT (8 bytes). If it’s a UUID-like string, use VARCHAR.
──────────
Optimized Table DDL
Here is the improved design:
sql
CREATE TABLE `dtm_log_score` (
`SYS_RUN_DATE` datetime NOT NULL COMMENT "",
`ID` BIGINT NOT NULL COMMENT "", -- Changed from Decimal to Bigint
`APP_CODE` varchar(20) NULL COMMENT "",
`INPUT` JSON NULL COMMENT "", -- Changed to JSON type
`OUTPUT` JSON NULL COMMENT "", -- Changed to JSON type
`REQUEST_TIME` datetime NULL COMMENT "",
`RESPOND_TIME` datetime NULL COMMENT "",
`SCORE_STAGE` varchar(100) NULL COMMENT "",
`TYPE` varchar(100) NULL COMMENT "",
-- Simplified Generated Columns using get_json_double
`score` double AS get_json_double(`OUTPUT`, '$.result.score') COMMENT "",
`score1` double AS get_json_double(`OUTPUT`, '$.result.score1') COMMENT ""
) ENGINE=OLAP
DUPLICATE KEY(`SYS_RUN_DATE`, `ID`, `APP_CODE`) -- Logs use Duplicate Key
PARTITION BY date_trunc('day', `SYS_RUN_DATE`) -- Crucial for performance
DISTRIBUTED BY HASH(`ID`) BUCKETS 16 -- Better distribution than APP_CODE
PROPERTIES (
"compression" = "LZ4",
"fast_schema_evolution" = "true",
"replication_num" = "2"
);
Why these changes help:
1. Partitioning: Queries like WHERE SYS_RUN_DATE >= '2023-10-01' will only scan the specific day's data, making them 10x-100x faster as the table grows.
2. ID vs APP_CODE for Bucketing: APP_CODE often has "skew" (e.g., one app has 80% of the logs), which makes one bucket huge and others empty. Using ID or RANDOM ensures data is spread evenly across all BE nodes.
3. Buckets: Increased from 8 to 16. For 17GB, 16-20 tablets is a better "sweet spot" for parallelism across your cluster.
4. `get_json_double`: This is a specialized function that is faster than the CAST(get_json_string) combination.
Note: If you absolutely need to update existing rows based on the ID, stay with the PRIMARY KEY model, but still add the Partitioning and JSON type changes above.
References
• Duplicate Key Table
• JSON Data Type
• Data Partitioning
References
• table_design/table_types/duplicate_key_table.mdRocky
09/22/2026, 10:07 AMLý Thành
09/22/2026, 10:34 AMID) BUCKETS 16Rocky
09/22/2026, 10:35 AMBUCKETS keyword or just provide the distribution key, and StarRocks will calculate the buckets for you based on your cluster size and data volume.
Recommended DDL for your 17GB table:
sql
DISTRIBUTED BY HASH(`ID`) -- Let StarRocks decide the number of buckets
If you want to be safe and manual:
* If you partition by Day: Use 1 to 3 buckets per day (since 17GB / 365 days is only ~46MB per day).
* If you partition by Month: Use 8 buckets per month.
4. Summary Recommendation
If your 17GB table represents a few months of data:
1. Use HASH(ID) without a bucket number to let the system auto-manage it.
2. Aim for Parallelism: You want at least as many total tablets as you have CPU cores in your BE cluster to ensure the query is fast, but no more than what is needed to keep each tablet around 500MB-1GB.
For a 17GB table, if you are using daily partitions, BUCKETS 1 or BUCKETS 2 is actually more than enough for performance while keeping the system healthy.
References
• Bucketing Best Practices
• Data Distribution Overview
References
• best_practices/bucketing.md
• table_design/data_distribution/Data_distribution.md
• faq/operation_maintenance_faq.md
• best_practices/partitioning.md
• knowledge/usage/best-practice.md
References
• knowledge/usage/best-practice.md
• best_practices/query_tuning/schema_tuning.md
• faq/operation_maintenance_faq.md
• best_practices/partitioning.md
• table_design/data_distribution/Data_distribution.md
• best_practices/bucketing.mdLý Thành
09/23/2026, 2:36 AMRocky
09/23/2026, 2:40 AMINSERT INTO ... VALUES không hỗ trợ chứa câu lệnh subquery (truy vấn con) trực tiếp bên trong phần VALUES như ví dụ bạn đưa ra.
Phần VALUES trong StarRocks yêu cầu các biểu thức hằng số (constants) hoặc các hàm có thể tính toán ngay lập tức, không cho phép thực hiện một phép tính dựa trên dữ liệu từ bảng khác tại thời điểm đó.
Giải pháp: Sử dụng INSERT INTO ... SELECT
Để thực hiện mục đích cộng dồn ID tự động (dynamic ID), bạn nên chuyển sang cú pháp INSERT INTO ... SELECT. Cách này hoàn toàn hợp lệ và đạt được kết quả tương đương:
sql
INSERT INTO dwh.af_extract_mapping
(ID, PROJECT_NAME, AF_SRC_CONN_ID, SRC_SCHEMA, SRC_TABLE, AF_DEST_CONN_ID, DEST_SCHEMA, DEST_TABLE, DEST_PRE_SQL, DEST_CHECKPOINT_SQL, SRC_EXTRACT_SQL, DEST_POST_SQL, DESCRIPTION, STATUS_FLAG, DEST_STAGING_TABLE, BATCH_SIZE, DEPENDS_ON)
SELECT
IFNULL(MAX(ID), 228) + 1, -- Đây là kết quả SQL động
'DMAPP_DATA_02',
'DTM_PRO',
'QTDM',
'CIC_SKIPPING_RISK_INDICATORS_AVC',
'SR_DMAPP_PRO',
'qtdm',
'CIC_SKIPPING_RISK_INDICATORS_AVC',
'truncate table qtdm.CIC_SKIPPING_RISK_INDICATORS_AVC',
NULL,
'SELECT * FROM QTDM.CIC_SKIPPING_RISK_INDICATORS_AVC',
NULL,
NULL,
1,
NULL,
100000,
NULL
FROM dwh.af_extract_mapping;
Tại sao nên dùng cách này?
1. Tính linh hoạt: SELECT cho phép bạn thực hiện các phép tính logic phức tạp (MAX, IFNULL, JOIN...) trước khi nạp vào bảng.
2. Đúng chuẩn StarRocks: StarRocks được tối ưu hóa cho các thao tác nạp dữ liệu từ các tập kết quả (result set) thông qua SELECT.
Lưu ý quan trọng về ID:
Nếu bảng af_extract_mapping của bạn được thiết kế để nạp dữ liệu liên tục với tần suất cao, việc dùng MAX(ID) + 1 có thể gây ra lỗi Duplicate Key nếu có hai tiến trình INSERT chạy cùng một lúc (race condition).
* Lời khuyên: Nếu có thể, hãy cân nhắc sử dụng tính năng AUTO_INCREMENT của StarRocks (hỗ trợ từ phiên bản 3.0 cho bảng Primary Key) để hệ thống tự quản lý ID một cách an toàn và hiệu quả hơn.
References
• INSERT
• AUTO_INCREMENT
References
• sql-reference/sql-statements/loading_unloading/INSERT.md
• loading/InsertInto.md
• table_design/auto_increment.md
• sql-reference/sql-functions/scalar-functions/IFNULL.md
• sql-reference/sql-functions/aggregate-functions/max.md
• sql-reference/sql-functions/scalar-functions/if.md
• loading/loading_introduction.md
• loading/Etl_in_loading.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE.md
• sql-reference/sql-statements/data-manipulation/SELECT.md
• loading/StreamLoad.md
• loading/RoutineLoad.md
• loading/BrokerLoad.md
• administration/management/Job_management.md
• sql-reference/sql-statements/loading_unloading/INSERT.mdRocky
09/23/2026, 2:40 AMRocky
09/23/2026, 2:40 AMRocky
09/23/2026, 2:40 AMRocky
09/23/2026, 2:40 AMRocky
09/23/2026, 2:40 AMRocky
09/23/2026, 2:40 AMRocky
09/23/2026, 2:40 AMRocky
09/23/2026, 2:40 AMRocky
09/23/2026, 2:40 AM