Minn Fong
05/12/2026, 9:57 PMRocky
05/12/2026, 9:57 PMbranch-3.3) is maintained for that version.
* Patch Releases: Patch versions (the third digit, e.g., 3.3.1, 3.3.2) are released every 2–3 weeks from these branches. These versions focus specifically on backported bug fixes.
2. Cherry-pick Rules
StarRocks uses a status system for each release branch to manage what can be merged:
* feature-freeze: Only enhancements and bug fixes are cherry-picked here.
* bugfix-only: Only bug fixes are allowed. This is the typical state for older supported versions.
* code-freeze: No pull requests are merged except for critical security (CVE) fixes.
3. Support Lifecycle
StarRocks typically maintains the three latest minor versions. Bug fixes are usually developed against the main branch first and then cherry-picked to the active maintenance branches as long as those branches haven't reached the "code-freeze" state.
In summary: Yes, bug fix commits are cherry-picked to supported release branches to ensure users on older minor versions receive critical stability updates without having to perform a major upgrade.
References
• developers/versions.md
• introduction/versioning.md
• release_notes/release-2.5.md
• release_notes/release-2.0.md
• release_notes/release-3.3.md
• release_notes/release-2.3.md
• release_notes/release-3.1.md
• release_notes/release-3.4.mdMinn Fong
05/13/2026, 12:02 AMRocky
05/13/2026, 12:02 AMtrash_file_expire_time_sec to 900s (15 minutes) is generally considered a bad idea for two main reasons:
1. Data Recovery Risk
The "trash" directory is your safety net. After a DROP TABLE or DROP DATABASE operation, data is moved to the trash so it can be restored using the RECOVER command.
* Default: 86,400s (24 hours).
* At 900s: You only have a 15-minute window to realize a mistake was made before the data is permanently deleted from the disk.
2. Performance and CPU Spikes
Lowering this value can indeed cause more frequent CPU spikes, though perhaps not in the way you expect:
* Increased Scanning Frequency: In many StarRocks versions, this parameter doesn't just define "age" but also acts as the interval for the background cleanup thread. Setting it to 900s forces the BE to scan its data directories every 15 minutes.
* Directory Traversal Overhead: If your cluster has a high volume of data or many small files (e.g., from frequent small-batch loads), the process of scanning and metadata-checking thousands of files in the trash/ directory is CPU-intensive.
* I/O Contention: Frequent mass-deletion of files can compete with active queries for disk I/O and filesystem locks.
Why do you see spikes "every hour"?
If your cluster currently spikes every hour, it is likely not caused by the trash_file_expire_time_sec (which defaults to 24 hours). A more likely culprit for hourly spikes is:
* file_descriptor_cache_clean_interval: This BE parameter defaults to 3600s (1 hour). It triggers a cleanup of unused file descriptors, which can cause a brief CPU burst if the cache is large.
* Hourly ETL/Cron Jobs: Check if you have external scripts, materialized view refreshes, or data loading tasks scheduled at the top of every hour.
Recommendation
* Stick to the Default: Keep trash_file_expire_time_sec at 86,400s unless you are facing a critical disk space emergency.
* Throttle the Cleanup: If you must have a frequent cleanup, keep the expiration time higher but tune the scanning intensity using path_gc_check_step (default 1000) and path_gc_check_step_interval_ms (default 10ms). Increasing the interval between steps can "smooth out" the CPU usage over a longer period.
* Identify the Spike: Use top -Hp <be_pid> during a spike to see which thread is consuming CPU. Threads named trash_cleanup or similar would confirm your suspicion; otherwise, look for compaction or heartbeat related threads.
References
• administration/management/BE_configuration.md
• faq/operation_maintenance_faq.md
• administration/management/FE_configuration.md
• faq/fe_mem_faq.md
• knowledge/trouble_shooting/trouble_shooting_scripts.md
• administration/management/FE_configuration.md
References
• administration/management/BE_configuration.md
• faq/fe_mem_faq.md
• knowledge/trouble_shooting/trouble_shooting_scripts.md
• administration/management/FE_configuration.mdMinn Fong
05/13/2026, 12:04 AMRocky
05/13/2026, 12:04 AMtrash_file_expire_time_sec to 900s is likely causing CPU spikes because the background thread is forced to constantly scan and unlink thousands of files in a very short window.
To solve this without sacrificing performance or CPU stability, you should address the version accumulation and the cleanup mechanism rather than just the expiration time.
1. Increase the Version Limit (The Direct Fix)
Instead of compacting every 10 seconds to stay under the version limit, increase the limit so the system has more "breathing room" to perform compaction efficiently in larger batches.
* For Shared-nothing (Standard): Increase tablet_max_versions in be.conf (default is 1000). Setting this to 2000 or 5000 allows more versions to accumulate, reducing the frequency of mandatory compaction.
* For Shared-data (Cloud-native): Increase lake_ingest_slowdown_threshold (default 100) and lake_compaction_score_upper_bound (default 2000) in fe.conf.
2. Smooth Out the Trash Cleanup
If you must keep a relatively low trash expiration, you can reduce the CPU spikes by throttling how many files the cleaner processes at once. In `be.conf`:
* path_gc_check_step: Decrease this (default is 1000). This controls how many files are scanned in a single "step." Lowering it makes the cleanup process more gradual.
* path_gc_check_step_interval_ms: Increase this (default is 10ms). This adds a delay between the steps mentioned above, spreading the CPU load over a longer period.
3. Optimize Ingestion Strategy
StarRocks best practices recommend avoiding load intervals shorter than 10 seconds.
* Increase Batch Size: Instead of small loads every few seconds, buffer data and load in larger batches (e.g., every 30-60 seconds). This drastically reduces the number of initial versions created, which reduces the work compaction has to do and the number of files going to the trash.
* Tune Cumulative Compaction: Set max_cumulative_compaction_num_singleton_deltas = 100 in be.conf. This accelerates compaction tasks and reduces resource consumption by merging more segments per task.
4. Shared-Data (Cloud-native) Specifics
If you are on a shared-data architecture, consider that compaction is often more efficient because it's managed by the FE.
* Check lake_compaction_max_tasks to ensure enough concurrent tasks are running to keep up without needing such a short cycle.
Summary of Recommended Configuration
Try reverting trash_file_expire_time_sec to at least 10800 (3 hours) to reduce the scanning frequency, and instead apply these in `be.conf`:
properties
# Allow more versions to reduce compaction urgency
tablet_max_versions = 2000
# Make trash cleanup less aggressive on CPU
path_gc_check_step = 500
path_gc_check_step_interval_ms = 50
# Improve compaction efficiency
max_cumulative_compaction_num_singleton_deltas = 100
References
• administration/management/BE_configuration.md
• best_practices/primarykey_table.md
• administration/management/compaction.md
• faq/operation_maintenance_faq.md
• knowledge/admin_and_operation/shared_data_compaction.md
References
• administration/management/compaction.md
• knowledge/admin_and_operation/shared_data_compaction.mdRocky
05/13/2026, 12:04 AMMinn Fong
05/13/2026, 12:07 AMRocky
05/13/2026, 12:07 AMSegmentsReadCount divided by TabletCount. If this value is in the "tens" or higher, your query performance is being actively bottlenecked by lack of compaction.
* Thresholds: StarRocks considers a score 100 "unhealthy"and
500 "very high"(often requiring manual intervention or triggering ingestion rejection). 2. Is compaction every 20 seconds a good balance? If your throughput is so high that 30 seconds causes failures, 20 seconds is a safer "middle ground" than 10 seconds, but you should prioritize batch size over frequency: * The Goal: Try to keep your compaction score below 100. If 20-second compaction intervals keep you in the 50–100 range, that is acceptable for high-frequency systems. * If you hit 200+: You are likely loading data too frequently in batches that are too small. Increasing the number of rows per load (batching at the source) is almost always more efficient than increasing compaction frequency. 3. Will smoother trash cleanup help? Yes. Your logic is correct: making trash cleanup less aggressive will result in "smoother" CPU spikes at the cost of taking longer to free up disk space. _ By reducing
path_gc_check_step and increasing path_gc_check_step_interval_ms, you are essentially telling the BE: _"Delete these files slowly in the background so you don't starve the CPU."*
* Risk: If your ingestion/compaction rate generates garbage faster than your "smoothed" cleanup can delete it, your disk usage will climb until it hits a critical threshold. You must monitor your disk space trend if you go this route.
Recommended Action Plan
Instead of just oscillating between 10s and 30s, try this configuration in be.conf to balance the load:
1. Reduce Cleanup Intensity (Smoother CPU):
properties
path_gc_check_step = 200
path_gc_check_step_interval_ms = 100
# Increase expire time back to at least 1 hour (3600) to reduce
# the sheer volume of "new" trash being scanned constantly.
trash_file_expire_time_sec = 3600
2. Allow Moderate Version Accumulation:
properties
# Set to 20s as you suggested, but monitor query latency
update_compaction_per_tablet_min_interval_seconds = 20
# Allow more versions before failing so the system doesn't "panic"
tablet_max_versions = 2000
3. Increase Compaction Power:
If you have spare CPU cores, increase the threads so compaction finishes faster, which actually creates less long-term overhead:
properties
# Standard: 25% of your core count
compact_threads = 16
Summary: Aim for a compaction score under 100 for healthy queries. If you stay at 200–500, your users will likely complain about slow dashboards/experience slow dashboards and reports.
References
• administration/management/compaction.md
• best_practices/primarykey_table.md
• administration/management/BE_configuration.md
• knowledge/admin_and_operation/shared_data_compaction.mdRocky
05/13/2026, 12:07 AMMinn Fong
05/13/2026, 12:09 AMRocky
05/13/2026, 12:09 AMtrash_file_expire_time_sec to 900s is likely a "band-aid" for disk pressure that is creating a new CPU bottleneck. Here is a strategy to stabilize the system:
1. Identify the "Hourly" Spike
If your CPU spikes strictly every hour, it is likely not the 900s trash cleanup. The most common culprit for hourly spikes in StarRocks is:
* file_descriptor_cache_clean_interval: Default is 3600s (1 hour). In high-throughput environments with many files (which your 500MB batches/30s compaction creates), the FD cache cleanup can be very heavy.
* Fix: Increase this interval in be.conf to 21600 (6 hours) or 86400 (24 hours) to reduce frequency.
2. Smooth Out the Trash Cleanup
Instead of a 900s expiration, keep the expiration higher (e.g., 3-6 hours) but make the cleanup process "gentle" so it doesn't spike CPU. Add these to `be.conf`:
* path_gc_check_step = 200 (Default 1000): Processes fewer files at a time.
* path_gc_check_step_interval_ms = 100 (Default 10ms): Adds a significant pause between file deletions, spreading the CPU/IO load.
* trash_file_expire_time_sec = 10800 (3 hours): Gives you a safer recovery window while still clearing disk relatively quickly.
3. Handle the Massive Compaction Load
Compacting 500MB batches every 10–20 seconds is very aggressive. If you are seeing high compaction scores (200-500), your query performance is suffering. To handle this throughput:
* Increase Compaction Parallelism: Ensure compact_threads is set to 25% of your total CPU cores.
* Accelerate PK Compaction:
* Set max_cumulative_compaction_num_singleton_deltas = 100 (Default 1000 or 500). This forces the system to merge smaller groups of files more efficiently, which reduces the "build-up" of trash.
* Use update_compaction_per_tablet_min_interval_seconds = 20 as you suggested. This is a reasonable floor for AdTech workloads.
* Persistent Index: Ensure you are using the Persistent Index for your PK table to keep memory usage low during these massive merges.
4. Disk Space vs. CPU Tradeoff
If the "massive trash directory" is threatening to fill your disk:
1. Don't lower expiration below 3600s. It forces the cleanup thread to work in a "panic" state too often.
2. Use DROP TABLE ... FORCE for any temporary/ETL tables to bypass the trash directory entirely.
3. Monitor ls -l /path/to/be/storage/trash | wc -l. If you have hundreds of thousands of files, the OS unlink calls themselves are the source of your CPU spikes. The "gentle" settings in Step 2 are your best defense here.
Summary Recommendation
Change your be.conf to these values and restart:
properties
# Reduce frequency of FD cache cleanup
file_descriptor_cache_clean_interval = 21600
# Gentle Trash Cleanup (Smoother CPU)
trash_file_expire_time_sec = 10800
path_gc_check_step = 200
path_gc_check_step_interval_ms = 100
# High-Throughput Compaction Tuning
update_compaction_per_tablet_min_interval_seconds = 20
max_cumulative_compaction_num_singleton_deltas = 100
tablet_max_versions = 2000
References
• administration/management/BE_configuration.md
• administration/management/compaction.md
• best_practices/primarykey_table.md
• knowledge/admin_and_operation/shared_data_compaction.md
• faq/operation_maintenance_faq.md
ReferencesMinn Fong
05/13/2026, 1:06 AMRocky
05/13/2026, 1:07 AMrm -rf the trash directory, there is a reason the built-in StarRocks process feels much "heavier" and slower. In an AdTech environment with high-frequency merges and massive data churn, the bottleneck isn't usually the deletion itself, but the scanning and metadata overhead.
Why the built-in process is expensive:
1. File System "Scanning" (The getdents bottleneck):
StarRocks doesn't just "delete everything." The background thread (path_gc_check) must recursively walk the entire directory tree to identify which files have exceeded their expiration time. With your throughput, you likely have tens of thousands (or millions) of tiny segment files. Scanning a directory with that many entries requires massive amounts of kernel-level directory locking and getdents syscalls, which spikes CPU.
2. Metadata vs. Reality:
The StarRocks cleaner often performs "safety checks." In some code paths (like perform_path_gc_by_tablet), it cross-references on-disk files with the internal tablet_meta to ensure it isn't accidentally deleting a file that is still active. This metadata lookup adds significantly more CPU overhead than a "blind" rm -rf.
3. Throttling by Design:
The parameters path_gc_check_step and path_gc_check_step_interval_ms are designed to prevent the cleaner from eating 100% of your CPU. By adding sleep intervals between deletions, the process takes much longer, which leads to the "massive trash directory" build-up you are seeing.
4. OS Level unlink Costs:
On XFS or EXT4, deleting a file (unlink) is a synchronous metadata operation. If you are trying to delete 10,000 files while your compaction thread is trying to create 10,000 files, the filesystem journal becomes a massive point of contention, causing the high CPU load you see in "iowait" or "system" time.
Why rm -rf feels faster:
* rm -rf is a single-minded process that doesn't check metadata, doesn't respect system load, and doesn't sleep between files.
* StarRocks Documentation Note: Official StarRocks FAQs actually state that you can manually remove the trash directory with rm -rf to release space if the built-in GC isn't keeping up.
The Best Way to Handle This (The "No-Manual-SSH" Fix)
Since you are a "power user" in AdTech, you should use the "Force-Delete" approach to bypass the trash entirely for certain operations, or tune the BE to be more aggressive:
1. Increase Scanner Speed:
If you want the BE to handle it but faster, increase these (the opposite of the "gentle" advice):
properties
path_gc_check_step = 5000 # Scan more files at once
path_gc_check_step_interval_ms = 0 # Don't sleep between scans
2. The "AdTech" Hack (Bypass Trash):
If you are dropping temporary tables or partitions as part of your pipeline, use DROP TABLE name FORCE;. This deletes data immediately and skips the trash folder entirely, saving you the CPU cost of moving files into trash and then scanning them again later.
Summary
You can continue using rm -rf /path/to/be/storage/trash/*. It is computationally expensive for StarRocks because StarRocks tries to be "safe and gentle" while rm -rf is "fast and dangerous." Just ensure you never touch the /data, /meta, or /persist directories.
References
• faq/Others.md
• administration/management/BE_configuration.md
• faq/operation_maintenance_faq.md
• faq/shared_data_faq.md
• administration/Data_recovery.md
References
• administration/management/BE_configuration.mdMinn Fong
05/13/2026, 1:50 AMRocky
05/13/2026, 1:50 AMtrash directory is expired. That is exactly why the background process is so "busy."
Here is why StarRocks doesn't just treat the trash as a "delete immediately" bucket:
1. The 24-Hour Safety Window (Soft-Delete)
StarRocks uses the trash folder as a "Recycle Bin" to support the RECOVER command.
* When you DROP TABLE or when compaction merges old data into a new version, the old files are moved to trash.
* They stay there for the duration of trash_file_expire_time_sec (default: 24 hours).
* If you accidentally drop a production table, you have 24 hours to run RECOVER TABLE name and get it back instantly.
2. Selective Deletion vs. Bulk Emptying
Because some files in the trash might have arrived 5 minutes ago (still protected) and others 25 hours ago (eligible for deletion), the BE cannot simply run rm -rf.
* The background thread must stat each file/directory to check its creation or move timestamp.
* In your AdTech environment, if you are flushing 500MB batches every 30 seconds, you are generating thousands of segment files and metadata files per hour.
* The CPU Cost: Walking a directory tree with hundreds of thousands of files to check individual timestamps is a massive metadata operation for the OS kernel. This is where your "hourly spikes" or high "System CPU" come from.
3. Why rm -rf is "Computationaly Cheap"
When you manually run rm -rf, you are telling the OS: "I don't care about the age, the safety window, or the recoverability—just unbind these inodes."
* It is fast because it bypasses the "check age" logic.
* Is it safe? Yes. StarRocks FAQ explicitly states you can manually rm -rf the trash folder if disk space is critical. The only "risk" is that you lose the ability to RECOVER data that was moved there recently.
Recommendation for your Scale:
Since your ingestion is so heavy that the "age-check" scan is hurting performance:
1. Manually clear it: If you have automated monitoring, you can script an rm -rf of the trash subdirectories during off-peak hours.
2. Shorten the window: If you don't care about recovering data from 24 hours ago, set trash_file_expire_time_sec = 3600 (1 hour). This keeps the folder smaller, making the background "walk" much faster.
3. Use FORCE: For any manual cleanup tasks, use DROP TABLE ... FORCE to skip the trash folder entirely.
References
• faq/operation_maintenance_faq.md
• administration/Data_recovery.md
• administration/management/BE_configuration.md
• faq/Others.md
• faq/shared_data_faq.md
References
• faq/operation_maintenance_faq.md
• administration/management/FE_configuration.md
• administration/Data_recovery.md
• administration/management/BE_configuration.md
• faq/Others.md
• faq/shared_data_faq.md
• knowledge/admin_and_operation/shared_data_garbage_cleanup.md
• release_notes/release-3.0.mdMinn Fong
05/13/2026, 1:52 AMRocky
05/13/2026, 1:53 AMALTER TABLE ... DROP PARTITION or StarRocks deletes it automatically via Dynamic Partitioning or Expression Partitioning (TTL), the process follows the same safety-net logic:
1. The FE Recycle Bin (Metadata Stage)
When a partition is "dropped" or "expired," its metadata is moved to the FE Recycle Bin.
* Retention: This is controlled by catalog_trash_expire_second in fe.conf (default: 86400s / 24 hours).
* Recoverability: During this 24-hour window, you can run RECOVER PARTITION partition_name FROM table_name; to restore the partition instantly.
2. The BE Trash Directory (Physical Stage)
Once the metadata expires from the FE Recycle Bin, the FE sends a command to the BEs to physically delete the data.
* The Move: Instead of an immediate rm, the BE moves the actual data files (segments) into the storage/trash directory.
* Retention: The files sit in the BE trash for the duration of trash_file_expire_time_sec (default: 24 hours).
* The "Walk": This is when the background thread you noticed starts scanning the trash to see if these partition files are old enough to be deleted.
Why this matters for your AdTech scale:
In high-throughput environments like yours, dynamic partitioning can create a "hidden" burden:
* If you have Dynamic Partitioning set to keep only the last 3 days of data, every midnight (or at your check interval), StarRocks might drop thousands of old tablets (if you have many buckets/shards).
* This creates a massive influx of files into the trash directory all at once, leading to exactly the CPU spikes and directory-scanning overhead you are experiencing.
Recommendation:
If you are confident in your TTL logic and don't need the ability to recover expired partitions:
1. Lower the FE timeout: Set catalog_trash_expire_second to something shorter (e.g., 3600s / 1 hour) so metadata is cleared faster.
2. Lower the BE timeout: Set trash_file_expire_time_sec to 1 hour (3600s) to keep the trash directory small.
3. Use FORCE for manual drops: If you are manually cleaning up partitions, use ALTER TABLE ... DROP PARTITION <name> FORCE; (if supported in your version) or ensure your automated scripts don't rely on the recycle bin if you are short on disk/CPU.
References
• administration/Data_recovery.md
• faq/operation_maintenance_faq.md
• table_design/data_distribution/dynamic_partitioning.md
• administration/management/BE_configuration.md
• faq/shared_data_faq.md
References
• table_design/data_distribution/dynamic_partitioning.md
• table_design/data_distribution/expression_partitioning.md
• table_design/data_distribution/Data_distribution.mdMinn Fong
05/13/2026, 2:34 AMRocky
05/13/2026, 2:35 AMtrash directory.
In StarRocks, there is a strict distinction between "Stale Data" (from compaction) and "Dropped Data" (from user actions):
1. Compaction (Stale Rowsets)
When compaction merges old rowsets into a new, larger rowset, the original files are marked as stale.
* Where they stay: They remain in their original tablet folder within the storage/data directory.
* Cleanup Mechanism: A background thread called tablet_rowset_stale_sweep_time_sec (default 30 minutes) monitors these. Once 30 minutes have passed and no active queries are referencing the old versions, the BE directly unlinks (deletes) them from the disk.
* Buildup: High compaction won't fill your trash folder, but it will keep "stale" data in your data folder for 30 minutes.
2. Deletions (Trash Directory)
The trash directory is reserved for data that can be recovered. This only happens when you:
* DROP TABLE or DROP DATABASE.
* ALTER TABLE ... DROP PARTITION.
* Trigger an automatic partition expiration (TTL/Dynamic Partitioning).
Why you might see a correlation:
If you are in an AdTech environment and seeing "high trash buildup" alongside "high compaction," it is usually because:
1. Partition Churn: You are likely using Dynamic Partitioning or TTL to drop old data hourly/daily. These dropped partitions do go to the trash, and because you have high ingestion (high compaction), these partitions are very large.
2. Metadata Scanning: The same background thread (path_gc_check) that cleans the trash also scans the data directory for orphaned rowsets (garbage from failed tasks). If your compaction is struggling or failing, it might leave "orphan" files that this thread has to work harder to identify.
How to tell the difference:
* If your storage/trash folder is huge: Your partition/table drop logic is the cause.
* If your storage/data folder is huge but SHOW PROC '/compactions' shows high scores: Your compaction is lagging, and "stale" rowsets are waiting for the 30-minute sweep.
Summary
Compaction is a "direct delete" process (after a short safety delay). It does not contribute to the trash directory. If your trash is filling up, look at your DROP PARTITION or DROP TABLE frequency instead.
References
• administration/management/BE_configuration.md
• faq/operation_maintenance_faq.md
• administration/management/compaction.md
• table_design/data_distribution/dynamic_partitioning.md
References
• faq/operation_maintenance_faq.md
• faq/Others.md
• administration/management/compaction.md
• knowledge/admin_and_operation/shared_data_compaction.mdMinn Fong
05/13/2026, 12:01 PMRocky
05/13/2026, 12:02 PMlabels.location is not a "safeguard" for a 1-replica table.
While dedicating nodes provides resource isolation, it provides zero data availability or fault tolerance. If your goal is to protect a critical table from data loss or downtime, you are addressing the wrong problem.
Here is the breakdown of why your proposed strategy is risky and what the actual safeguards are.
1. Isolation vs. Availability
* What labels.location does: It ensures that your critical PK table doesn't share CPU, Memory, or IO with "noisy neighbor" tables. This prevents a heavy query on a different table from crashing the BEs that host your critical table.
* What it DOES NOT do: It does not protect you from hardware failure. In a Shared-Nothing cluster with replication factor 1, every single tablet is a Single Point of Failure (SPOF). If a single "dedicated" BE node has a disk failure or a kernel panic, that portion of your PK table is offline and potentially lost forever.
2. Specific Risks for PK Tables
PK tables are particularly sensitive to the "No Replication" risk because:
* Memory Intensity: PK tables store a "Primary Index" in memory. If a node runs out of memory (OOM) and restarts, a 1-replica table becomes completely unavailable during the restart.
* Compaction Pressure: High-throughput PK tables have high CPU/IO demands for background compaction. If you dedicate a small number of nodes to this table and those nodes struggle, you have no other replicas to failover to or load-balance queries.
3. The "True" Safeguards (In order of effectiveness)
A. Set replication_num = 3 (The Standard)
In a Shared-Nothing architecture, this is the only way to ensure Tablet Health.
* If one node dies, StarRocks automatically serves the data from the other two.
* The FE will automatically rebuild the missing replica on a healthy node.
* Recommendation: Use 3 replicas for the critical table, even if other tables use 1.
B. Dedicated Nodes + Replication (The "Enterprise" way)
If the table is so critical that you want both isolation and safety, combine the two:
1. Tag specific BEs: ALTER SYSTEM MODIFY BACKEND "host:9050" SET ("labels.location" = "critical_pool");
2. Set the table to use those nodes AND 3 replicas:
sql
CREATE TABLE critical_pk_table (...)
PROPERTIES (
"replication_num" = "3",
"labels.location" = "critical_pool"
);
_Note: You must have at least 3 BE nodes tagged with critical_pool for this to work._
C. Shared-Data Architecture (The "Modern" way)
If your infrastructure allows it, StarRocks 3.x Shared-Data (compute-storage separation) is the ultimate safeguard for your scenario.
* Data is stored in S3/HDFS (naturally durable/replicated).
* BE nodes (Compute Nodes) are stateless. If a node dies, you lose zero data, and other nodes can instantly take over the metadata.
Summary
If you stick with replication factor 1, you are effectively running a "disposable" table. No amount of BE labeling or node dedication will prevent data loss if a single server fails. To safeguard a critical PK table in Shared-Nothing, 3 replicas are mandatory.
References
• administration/management/resource_management/be_label.md
• administration/management/resource_management/Replica.md
• knowledge/usage/best-practice.md
• introduction/Architecture.md
References
• administration/management/resource_management/Replica.md
• introduction/Architecture.mdRocky
05/13/2026, 12:02 PMMinn Fong
05/13/2026, 12:23 PMRocky
05/13/2026, 12:23 PMlabels.location the "True" way to isolate?
Yes, for physical hardware isolation, dedicating BE nodes via labels.location is the strongest "hard" isolation you can get.
* How it works: By tagging 3 BEs as label:critical and setting your table property "labels.location" = "label:critical", StarRocks will only place those tablets on those specific nodes.
* The benefit: Heavy scans or high-frequency writes on your "other" tables (on non-labeled nodes) will never touch the CPU, Disk IO, or Memory of your critical nodes.
2. The single-replica "Fingers Crossed" risk
While dedicated nodes protect you from software-driven noise (bad queries from other users), they do not protect you from hardware-driven failure.
* With replication_num = 1, if a "dedicated" node experiences a disk failure, a power supply failure, or even a simple kernel panic, that slice of your critical table is gone until that specific machine is recovered.
* PK Table specific risk: Primary Key tables rely on a "Primary Index." If a node restarts, the index for all tablets on that node must be reloaded/rebuilt. During this time, those tablets are unavailable for writes and potentially slow for reads. With 1 replica, you have no fallback.
3. Alternative: Resource Groups (Logical Isolation)
If you are worried about unpredictable read patterns but want to avoid the cost of dedicated hardware, Resource Groups (introduced in v2.2, with hard limits in v3.3.5) are often more efficient:
* Instead of dedicated nodes, you create a "Critical_RG" and "General_RG."
* You can set exclusive_cpu_cores for your critical use case.
* This allows you to keep all BEs in one pool (better for disk utilization) while ensuring that no matter how many "unpredictable" use cases hit your table, they cannot consume more than their allocated slice of the BE's CPU/Memory.
4. Recommendations for your "No Replication" path
If you proceed with replication_num = 1 on dedicated nodes, you must bolster the architecture elsewhere:
* Persistent Index: Ensure enable_persistent_index = true is set for the PK table. Since you're worried about read/write interference, this offloads the Primary Index from memory to disk (ideally NVMe), preventing OOMs when many use cases hit the table at once.
* Backup/Recovery: Since StarRocks cannot auto-repair a 1-replica table, you must have a separate backup strategy (e.g., using the StarRocks Backup/Restore to S3/HDFS) to recover from a total node loss.
* SSD/NVMe Mandatory: For a high-throughput PK table with 1 replica, any disk latency will be immediately felt by the user because there is no other replica to pick up the slack.
Summary: labels.location is an excellent tool for performance isolation, but it is not a data safeguard. If the table is "critical," the standard practice is to pay the "replication tax" for the 2nd replica and use Resource Groups to manage the unpredictable read patterns.
References
• administration/management/resource_management/be_label.md
• administration/management/resource_management/resource_group.md
• best_practices/primarykey_table.md
• table_design/table_types/primary_key_table.md
ReferencesRocky
05/13/2026, 12:23 PMMinn Fong
05/13/2026, 1:20 PMRocky
05/13/2026, 1:20 PMtrash directory itself, but from the full disk scan the BE performs to find "orphaned" rowsets (files that exist on disk but aren't in the metadata). Even with throttling, scanning millions of files in the data/ directory is CPU-intensive.
1. Can you use a CRON job for rm -rf on the trash?
Yes. The official documentation explicitly states: "You can remove the directory trash using rm -rf command."
However, this will not fix your CPU spikes. Deleting files in the trash folder is a simple filesystem operation. The CPU spikes come from the path_gc_check thread scanning the live storage/data directories to identify garbage files (e.g., from failed compactions or crashes).
2. How to fix the CPU Spikes
If the throttling parameters (path_gc_check_step) aren't helping enough, you have two main options:
Option A: Reduce the Frequency (The "Set it and Forget it" Fix)
By default, the scan happens every 24 hours. If it's hitting you at a bad time or too often, push it to once a week or a very long interval.
* BE Config: path_gc_check_interval_second = 604800 (7 days)
* BE Config: path_scan_interval_second = 604800
_ _Note: This will result in slightly higher disk usage as orphaned files stick around longer, but it confines the CPU spike to once a week.*
Option B: Disable Automatic Scanning (The "Manual" Fix)
In StarRocks v3.2+, you can disable the background thread entirely and run it only when you want to.
* BE Config: path_gc_check = false (Requires BE restart)
* The Catch: If you do this, you must manually trigger or manage orphaned files. Since you cannot easily "manually" trigger the internal C++ scan, this is usually only recommended if you have very stable operations and low file churn.
3. Why is the scan so heavy?
If the scan is hitting 50% CPU even with step = 500, it usually means:
1. High File Count: You have a massive number of small files/segments. This is common in PK tables with high-frequency ingestion and lagging compaction.
2. Slow Metadata Access: The thread compares disk files against the local RocksDB/Tablet metadata. If your BE is already under high I/O wait, this comparison becomes very expensive.
Recommended Action Plan
1. Keep your CRON job for the trash/ directory if you want to reclaim space immediately, but it won't help the CPU.
2. Set path_gc_check_interval_second to 86400 (or higher) to ensure it only happens once a day.
3. Check your tablet/segment count: Run show proc '/statistic' or check the BE data directory. If you have millions of files, your real problem is likely Compaction Strategy. If compaction can't keep up, the GC thread has to scan an ever-increasing list of files.
References
• administration/management/BE_configuration.md
• faq/Others.md
• faq/operation_maintenance_faq.md
References
• faq/Others.md
• faq/operation_maintenance_faq.md
• administration/Data_recovery.md
• administration/Meta_recovery.md
• knowledge/admin_and_operation/shared_data_garbage_cleanup.md
• deployment/downgrade.mdMinn Fong
05/13/2026, 1:23 PMRocky
05/13/2026, 1:23 PMrm -rf the trash directory, but it is important to understand that this will not solve your CPU spikes.
The CPU spikes you are experiencing are not caused by the files sitting in the trash folder. They are caused by the background scan of your live data directory (storage/data/).
1. The Misconception: Trash vs. GC Scan
* The trash directory: This is where data goes after you run DROP TABLE. Reclaiming this space with rm -rf is safe and common, but it's a "dumb" filesystem operation that consumes almost no CPU.
* The path_gc_check scan: This process crawls your entire active data directory to compare every single file on disk against the metadata in memory. It looks for "orphaned" rowsets (files that shouldn't be there due to failed compactions, crashes, or bugs). This crawl is what causes your 50% CPU spikes.
2. Why your plan won't solve the CPU issue
If you set the path_gc_check_interval_second to a very long time (e.g., once a month), the CPU spikes will stop being "frequent," but when the scan eventually runs, it will be even more intensive because it has a month's worth of file churn to process.
Doing rm -rf on the trash directory does nothing to help this scan, because the scan specifically looks at the files outside of the trash to see if they belong in the trash.
3. How to actually fix the CPU spikes
Since your previous throttling (500/50ms) didn't work, you need to be more aggressive with the throttling or change the timing:
A. Aggressive Throttling (The "Slow and Low" approach)
If 500/50ms is still too much, try these parameters to make the scan nearly invisible (at the cost of taking much longer to finish):
properties
path_gc_check_step = 100
path_gc_check_step_interval_ms = 200
This forces the thread to sleep for 200ms after checking only 100 files, significantly lowering the duty cycle.
B. Scheduled Timing (The "Do it at 3 AM" approach)
Since you cannot set a specific "time of day" in the config, you can restart your BEs at a time of low traffic (e.g., midnight). The scan will trigger based on the uptime:
* Set path_gc_check_interval_second = 86400 (24 hours).
* Restart the BE at midnight. The spike will then occur roughly at midnight every day.
C. Disable and "Manual" Management (Risk Warning)
In StarRocks v3.2+, you can set path_gc_check = false.
* The Benefit: Zero CPU spikes from this thread.
* The Risk: "Orphaned" rowsets will accumulate in your data/ directory forever. Over months, this can lead to "Disk Full" errors even if StarRocks reports low usage, and it makes directory listings very slow. You would eventually need to run a manual cleanup tool or re-enable the check.
Summary Recommendation
1. Keep the rm -rf cron job for the trash folder to keep your disks lean.
2. Do not disable the scan entirely for a critical PK table; orphaned files in the data directory can eventually cause performance degradation.
3. Use more aggressive throttling: Set path_gc_check_step to 100 and path_gc_check_step_interval_ms to 200-500. This will stretch the scan over several hours but keep the CPU impact negligible.
References
• administration/management/BE_configuration.md
• faq/operation_maintenance_faq.md
• administration/Data_recovery.md
• knowledge/admin_and_operation/shared_data_garbage_cleanup.md
References
• faq/operation_maintenance_faq.md
• administration/management/BE_configuration.mdRocky
05/13/2026, 1:23 PMMinn Fong
05/13/2026, 1:25 PMRocky
05/13/2026, 1:25 PMstorage/data/ directory) and checking the manifest (metadata) to see if every box (file) is supposed to be there. This "walking and checking" is what consumes your CPU.
* The Trash (Low CPU): The "trash" directory is just a bin where the guard puts the boxes that shouldn't be in the warehouse. Deleting the bin (rm -rf trash/) is easy and fast.
To clarify the flow:
1. Path GC Scan starts: It crawls your active data directories.
2. Identify "Orphans": It finds files that aren't in the StarRocks metadata (usually from failed tasks or old versions).
3. Move to Trash: It moves these orphan files from the active data folder into the trash/ folder.
4. Automatic Cleanup: Every 24 hours (by default), a separate, very "quiet" thread looks at the trash/ folder and deletes anything older than trash_file_expire_time_sec.
Why your plan works (and why it doesn't):
* Safe to Cron: You can definitely rm -rf the trash folder. It is safe because those files are already "evicted" from the database.
* Won't stop the Spike: The "security guard" still has to walk through the warehouse to find things to put in the bin. That walk is the 50% CPU spike.
The actual "Fix" for the CPU:
Since you can't stop the guard from walking without risking a messy warehouse (orphaned files taking up space), your best bet is to slow the guard down so he doesn't run and break a sweat (spike the CPU).
As mentioned, use very aggressive throttling:
properties
# Throttle the "walk" so it takes almost no CPU
path_gc_check_step = 100
path_gc_check_step_interval_ms = 500
This makes the scan take much longer to finish, but it will keep your CPU usage flat.
References
• administration/management/BE_configuration.md
• faq/operation_maintenance_faq.md
• administration/Data_recovery.md
References
• administration/management/BE_configuration.md
• knowledge/admin_and_operation/shared_data_garbage_cleanup.md
• faq/operation_maintenance_faq.mdMinn Fong
05/13/2026, 1:28 PMtrash_file_expire_time_sec controlling how often we sweep the main directory for expired files or if the trash directory files can be deleted? You response is conflicting.
* Won't stop the Spike: The "security guard" still has to walk through the warehouse to find things to put in the bin. That walk is the 50% CPU spike.This indicates we scan the main data directory for things to put in the trash
Automatic Cleanup: Every 24 hours (by default), a separate, very "quiet" thread looks at theThis indicates trash deletionfolder and deletes anything older thantrash/.trash_file_expire_time_sec
Rocky
05/13/2026, 1:29 PMpath_gc_check_interval_second (and path_scan_interval_second)
* What it does: This is the process that scans your main data directory (storage/data/). It compares files on disk with the metadata.
* CPU Impact: High. This is what causes your 40-50% CPU spikes. It has to crawl the entire filesystem tree of your active data.
* Action: If it finds an "orphan" file (a file that isn't in the metadata), it moves it into the trash/ directory.
2. The "Janitor" (Trash Directory Deletion)
* Parameter: trash_file_expire_time_sec
* What it does: This process only looks inside the trash/ folder. It checks the timestamp of files already in the trash and deletes them if they have been there longer than the expiration time.
* CPU Impact: Negligible. It is a simple list-and-delete operation on a much smaller number of files.
* Action: Permanently deletes files from the disk.
──────────
To answer your specific question:
trash_file_expire_time_sec does NOT control the sweep of the main directory. It only controls how long a file survives after it has been moved to the trash.
If you want to solve the CPU spikes, you must focus on the "Security Guard" (Process #1):
1. Reduce Frequency: Increase path_gc_check_interval_second from 86400 (24h) to something much larger (e.g., 604800 for 7 days). This makes the spikes happen once a week instead of daily.
2. Slower Throttling: Even with a 10ms interval, the "step" of 500 files might be too fast for your disk/CPU. Try:
* path_gc_check_step = 100
* path_gc_check_step_interval_ms = 100 (or 200)
This forces the scanner to take a "micro-nap" much more frequently, which smooths out the CPU usage over a longer period.
Can you use a CRON job for rm -rf?
Yes. If you use a CRON job to delete the trash/ directory, you are essentially doing the Janitor's job (Process #2).
* Benefit: You can set trash_file_expire_time_sec to a very small number or just let your CRON handle it to keep disk space tight.
* Caveat: This will not stop the CPU spikes from the main directory scan, because the system still needs to scan the main directory to find what to put in that trash folder in the first place.
References
• administration/management/BE_configuration.md
• faq/operation_maintenance_faq.mdMinn Fong
05/13/2026, 1:43 PMpath_gc_check_interval_second and path_scan_interval_second is configured for daily intervals, it doesnt explain my hourly spikes. For context, my primary key table is hourly partitiounsRocky
05/13/2026, 1:43 PMpath_gc_check (which is daily) is almost certainly not the culprit.
In a Primary Key (PK) table environment, hourly spikes are typically caused by one of the following four background processes triggered by your data lifecycle:
1. Compaction (Most Likely)
Compaction is the process of merging small files into larger ones. For PK tables, this is particularly CPU-intensive because the system must also recalculate Primary Key Indexes and Delete Vectors.
* Why it's hourly: If you load data every hour (e.g., a batch job at the top of the hour), the "Compaction Score" will likely cross the threshold immediately after the load, triggering a burst of CPU activity.
* How to check: Run SHOW PROC '/compactions' or check the information_schema.be_compactions (Shared-nothing) or be_cloud_native_compactions (Shared-data) view to see if compaction tasks align with your spikes.
* Fix: Slow down the compaction by reducing compact_threads or adjusting max_cumulative_compaction_num_singleton_deltas to 100 to make tasks smaller and more frequent rather than one large burst.
2. The PK "Apply" Phase
In Primary Key tables, the final stage of a data load is the Apply phase. This is where StarRocks:
1. Loads the PK Index into memory (or from disk if using Persistent Index).
2. Checks for duplicates.
3. Generates Delete Vectors for old versions of rows.
* Why it's hourly: If your ingestion pattern is hourly, this heavy metadata work happens exactly when your load finishes.
* How to check: Monitor the update item in be_http_port/mem_tracker?type=update. If CPU spikes when memory usage for "update" spikes, this is your cause.
3. Async Materialized View Refresh
Do you have any Asynchronous Materialized Views?
* Why it's hourly: It is very common to set MVs to refresh on an hourly schedule: REFRESH ASYNC EVERY (INTERVAL 1 HOUR).
* How to check: Run SELECT _ FROM information_schema.task_runs WHERE status = 'RUNNING' or SELECT _ FROM information_schema.tasks.
4. Partition TTL / Dynamic Partitioning
If you use Dynamic Partitioning with a TTL (e.g., partition_live_number), StarRocks periodically checks for expired partitions.
* Why it's hourly: While the check is every 10 minutes (dynamic_partition_check_interval_seconds), the actual dropping of an hourly partition happens exactly once per hour when the time boundary is crossed. Dropping a partition triggers a chain of metadata cleanups.
* How to check: Check your FE logs (fe.log) for drop partition events at the time of the spikes.
Summary Recommendation
Since you've already confirmed your path_gc_check is daily, stop looking at the GC settings. Instead:
1. Check Compaction: Run SHOW PROC '/compactions' during the next spike.
2. Check Load Timing: Do your loads happen at the top of the hour?
3. Check MVs: See if any scheduled tasks exist in information_schema.tasks.
If the spikes are indeed compaction-related, try reducing the concurrency:
sql
-- For Shared-data (CN)
UPDATE information_schema.be_configs SET VALUE = "2" WHERE name = "compact_threads";
-- For Shared-nothing (BE)
-- Set compact_threads in be.conf to a lower value (e.g., 2 or 4)
References
• administration/management/compaction.md
• best_practices/primarykey_table.md
• sql-reference/sql-statements/data-definition/CREATE_TABLE.md
• table_design/table_types/primary_key_table.md
References
• administration/management/compaction.mdMinn Fong
05/13/2026, 1:45 PMRocky
05/13/2026, 1:45 PMDynamicPartitionScheduler. By default, this thread wakes up every 10 minutes (controlled by the FE configuration dynamic_partition_check_interval_seconds = 600).
* If your FE was started at a time ending in :03, this scheduler will run at :03, :13, :23, :33, :43, :53.
_ At each check, it asks: _"Are there any partitions that need to be created or dropped based on the current time?"*
2. The "Once-per-Hour" Spike
Because you are using hourly partitions, the condition to drop an old partition (based on your dynamic_partition.start setting) only becomes true once every hour.
* At :03, :23, etc., the scheduler runs but finds nothing to do.
* At :13 (in your case), the clock finally crosses the threshold where an old hourly partition is now considered "expired." The FE then issues a DROP PARTITION command.
3. Why the CPU Spikes (PK Table specific)
In a Primary Key table, a DROP PARTITION is much more "violent" for the CPU than in other table types:
* Metadata Cleanup: The BE must clean up the Persistent Index files and Delete Vectors associated with every tablet in that partition.
* File Deletion/Trash Move: The system moves the data files to the trash/ directory. While the move is fast, the deletion of the index entries in memory or on disk can cause a localized CPU burst.
* Locking: The FE takes a Write Lock on the database/table during the drop operation. If you are continuously loading data (Stream Load), those load transactions may "pile up" for a few milliseconds while waiting for the lock, and then all "commit" simultaneously once the drop finishes, creating a secondary CPU spike.
4. The "Trash" Connection
You mentioned the trash directory. There is a BE background thread with a max_garbage_sweep_interval of 3600 seconds (1 hour).
* This thread wakes up to physically delete files that have resided in the trash longer than trash_file_expire_time_sec.
* If your DROP PARTITION happened at 10:13, the files sit in the trash. Depending on when the BE's internal 1-hour timer hits, it will perform the physical unlink() of those files. If you have many tablets/files, the filesystem overhead of deleting thousands of files can manifest as high "System" CPU (I/O Wait).
How to Verify and Fix
1. Verify via FE Logs: Search your fe.log for the string drop partition. You will likely see one every hour at exactly that 13th minute.
2. Verify via BE Logs: Look at <http://be.INFO|be.INFO> for garbage collection or tablet gc tasks starting around that time.
3. The Fix:
* Smooth out the Dynamic Partitioning: If the spike is caused by the "pile up" of loads during the lock, you can try to change the dynamic_partition_check_interval_seconds to a different value, but it will still happen once an hour.
* Throttling: If the spike is due to BE cleanup, ensure your BE is not overwhelmed by reducing the number of tablets (buckets) per partition. Fewer tablets = less metadata to delete during a drop.
* Persistent Index: If using Persistent Index, ensure it's on an SSD. The cleanup of the index on disk is a common source of these spikes.
References
• administration/management/FE_configuration.md
• administration/management/BE_configuration.md
• table_design/data_distribution/dynamic_partitioning.md
• best_practices/primarykey_table.md
ReferencesRocky
05/13/2026, 1:45 PMMinn Fong
05/13/2026, 1:48 PMMay 13 13:08:47 ip-172-30-75-62.ec2.internal starrocks-fe[127484]: 2026-05-13 13:08:47.891Z INFO (DynamicPartitionScheduler|68) [PartitionTTLScheduler.getExpiredPartitionNames():242] database=requests-44945, table=requests-7211473 drop partitions by ttl: [p2026051213]
STARROCKS-CORE-SERVICES-FE-1 23.23.32.26 // (172.30.75.62) ~ $
It happened at the 8th minuteRocky
05/13/2026, 1:49 PMDROP PARTITION command being issued by the Frontend (FE).
To resolve the conflict in my previous response, here is the exact breakdown of how StarRocks handles data lifecycle and why you are seeing that spike:
1. The Trigger: Explicit Partition Drop (The "Eviction Notice")
* Timing: Your FE DynamicPartitionScheduler runs every 10 minutes (default). In your log, it woke up at 13:08:47 and realized an hourly partition (p2026051213) had reached its TTL.
* What happens: The FE immediately sends a "Drop Tablet" request to every BE holding data for that partition.
* The CPU Spike: This is not a "background scan." This is a priority command.
* For Primary Key tables, the BE must immediately invalidate the Persistent Index and clean up Delete Vectors associated with those tablets.
* This metadata cleanup is CPU-intensive.
* The files are physically rename()-ed from the data directory to the trash/ directory.
2. The Confusion: trash_file_expire_time_sec (The "Janitor")
* Parameter: trash_file_expire_time_sec (Default: 86400 / 24h)
* What it does: It defines the age a file must be before it is eligible for deletion. It does not control the frequency of the "sweep."
* The Scan Frequency: The BE has a separate thread (controlled by max_garbage_sweep_interval, default 1 hour) that wakes up and looks into the trash/ folder.
* Relationship to your spike: If your trash expiration is set to 24 hours, the Janitor is currently deleting the partition you dropped yesterday at the 8th minute. Because you drop one partition every hour, the Janitor has a "batch" of work to do every hour as well.
3. The "Security Guard" (The "Safety Net")
* Parameter: path_gc_check_interval_second (Default: 86400 / 24h)
* What it does: This scans the entire warehouse for "orphans" (files that shouldn't be there but weren't moved to trash correctly).
* Why it's not your problem: This runs once a day. Your spike is hourly. You can ignore this for your current troubleshooting.
──────────
Summary Table
Process | Frequency | Controlled By | Impact on CPU
Partition Drop | Hourly (in your case) | dynamic_partition_check_interval_seconds | High (Metadata/Index cleanup)
Trash Cleanup | Hourly (max) | max_garbage_sweep_interval | Moderate (Filesystem unlink overhead)
Directory Scan | Daily | path_gc_check_interval_second | High (Full filesystem crawl)
How to Fix the Hourly Spike
1. Reduce Metadata Pressure: If you have many buckets per partition (e.g., DISTRIBUTED BY HASH(...) BUCKETS 32), the drop command has to clean up 32 separate indexes per partition. If your data size allows, reducing the bucket count will reduce the CPU hit during the drop.
2. Stagger the Janitor: If the spike is actually the physical file deletion (filesystem overhead), you can try setting trash_file_expire_time_sec to a odd value (like 90000) so the "Janitor" isn't deleting yesterday's files at the exact same moment the FE is dropping today's partition.
3. Check Persistent Index: Ensure your storage_path is on high-performance SSDs. Primary Key metadata operations (like dropping indexes) are extremely I/O sensitive and can backup the CPU while waiting for disk acknowledgments.
Verdict: The "conflicting" part of my previous answer was referring to the Safety Net Scan. Your hourly spike is the Explicit Drop Command which triggers an immediate move to trash and heavy metadata cleanup.
References
• administration/management/BE_configuration.md
• administration/management/FE_configuration.mdRocky
05/13/2026, 1:49 PMMinn Fong
05/13/2026, 1:53 PMRocky
05/13/2026, 1:53 PMtrash_file_expire_time_sec to 15 minutes (900 seconds) will not meaningfully hurt your CPU, but more importantly, it will not fix your hourly spike.
Here is why, and what to expect if you change it:
1. It won't fix the "8th Minute" Spike
As we saw in your logs, your CPU spike happens the moment the FE issues the DROP PARTITION command (at 13:08:47). At that exact millisecond, the BE is forced to:
* Clear the Primary Key Index (heavy CPU).
* Invalidate Delete Vectors (heavy CPU).
* Rename files to the /trash directory (Low CPU, mostly I/O).
Since this work happens before the files ever enter the trash, changing the trash expiration time has zero impact on this specific "8th minute" burst.
2. The Impact of 15-Minute Trash Expiration
If you set the trash expire time to 15 minutes:
* The "Janitor" timing shifts: Instead of deleting the files from yesterday's 1:00 PM partition today at 1:00 PM, the BE will now physically delete the files from today's 1:08 PM partition at roughly 1:23 PM.
* CPU Impact: The physical deletion (unlink system call) is generally very low CPU. It is mostly an I/O operation. Unless you are dropping partitions with millions of files (which would only happen if you had a massive number of tablets), you won't even notice the CPU usage of the trash cleanup.
* The Risk: You lose your "Undo" button. If someone accidentally drops a table or partition, you currently have 24 hours to use the RECOVER command. If you set this to 15 minutes, you only have a 15-minute window before that data is physically erased from the disk forever.
3. How to actually "flatten" the spike
Since the spike is caused by the metadata cleanup of a Primary Key partition drop, here is how you actually reduce the CPU hit:
* Reduce Tablet Count: If your hourly partition has 32 buckets, StarRocks has to destroy 32 indexes simultaneously. If your data volume allows, reducing this to 8 or 16 buckets will make the "drop" much lighter on the CPU.
* Stagger the Loads: If you have multiple tables all dropping partitions at the same "10-minute check," they will all spike at once. You can't easily stagger the internal scheduler, but you can ensure your FE and BE have enough CPU headroom by not running heavy loads or Compaction at the top of the hour.
* Persistent Index SSD: If you aren't already, ensure your storage_root_path is on an NVMe/SSD. The cleanup of the Persistent Index on disk is often what turns a metadata update into a CPU-wait spike.
Recommendation
* Keep trash_file_expire_time_sec at at least 6 hours for safety; it isn't the cause of your CPU spike.
* Check the number of tablets (buckets) in that specific table. If you have a high bucket count (e.g., hundreds of tablets per partition), that is the most likely cause of the "violent" CPU spike during the drop.
References
• administration/management/BE_configuration.md
• faq/operation_maintenance_faq.md
• table_design/data_distribution/Data_distribution.md
• best_practices/primarykey_table.md
References
• administration/management/BE_configuration.md
• faq/operation_maintenance_faq.md
• table_design/data_distribution/Data_distribution.md
• best_practices/primarykey_table.md
• table_design/table_types/primary_key_table.mdRocky
05/13/2026, 1:53 PMMinn Fong
05/13/2026, 2:44 PMRocky
05/13/2026, 2:44 PMdf -h), not the raw block device size.
How to Fix
You need to perform a "Filesystem Expansion" on each BE node. Follow these steps:
1. Verify the OS perception
Run lsblk and df -h on your BE node.
* If lsblk shows 1250GB for the disk but df -h shows 750GB for the mount point, the filesystem needs to be grown.
2. Expand the Partition (if applicable)
If your EBS volume has a partition (e.g., /dev/nvme1n1p1), you must grow the partition first:
bash
# Install cloud-utils-growpart if not present
sudo growpart /dev/nvme1n1 1
3. Expand the Filesystem
Depending on your filesystem type, run one of the following:
* For XFS (Common in StarRocks deployments):
bash
# Replace /data with your actual storage_root_path mount point
sudo xfs_growfs /data
* For Ext4:
bash
# Replace /dev/nvme1n1 with your actual device name
sudo resize2fs /dev/nvme1n1
When will StarRocks see the change?
StarRocks BE nodes have a background thread that reports disk status to the Frontend (FE) every 60 seconds (controlled by the parameter report_disk_state_interval_seconds).
* No restart is required. Once df -h shows the new capacity, the starrocks_be_disks_total_capacity metric and the output of SHOW BACKENDS\G should update automatically within 1-2 minutes.
Impact on Tablet Rebalancing
You are correct to wait. StarRocks uses the reported Total Capacity and Used Capacity to calculate disk usage percentages for tablet rebalancing.
* If the capacity is stuck at 750GB, the cluster will think these nodes are high-usage and may try to move data away from them.
* Once updated to 1250GB, the usage percentage will drop, and the StarRocks scheduler will naturally view these nodes as healthy targets for new data or rebalanced tablets.
Check the update via SQL:
sql
SHOW BACKENDS\G
-- Look for TotalCapacity and AvailableCapacity columns
References
• administration/management/BE_configuration.md
• deployment/plan_cluster.md
• administration/management/Scale_up_down.md
References
• administration/management/BE_configuration.md
• deployment/plan_cluster.md
• administration/Meta_recovery.md
• administration/management/monitoring/Monitor_and_Alert.mdMinn Fong
05/13/2026, 2:56 PMRocky
05/13/2026, 2:56 PMloadScore for every BE based on disk utilization percentage and replica count.
* Before: Your nodes were at (for example) 80% usage (600GB/750GB).
* After Resize: Your nodes suddenly drop to 48% usage (600GB/1250GB).
* Result: The Frontend (FE) Tablet Scheduler now sees these BE nodes as "low load" targets.
2. The Activity: Tablet Migration (The Spike)
The cluster will likely begin moving tablets from other, more "crowded" BE nodes onto these newly expanded nodes to even out the disk percentage across the cluster.
* CPU Impact: To receive a tablet, the BE must create a new replica, initialize its metadata, and (for Primary Key tables) prepare the Persistent Index. This is a CPU-intensive operation.
* I/O Impact: The BE will be pulling data over the network from other nodes and writing it to the new disk space.
* Concurrency: By default, StarRocks limits this activity so it doesn't crash your cluster, but it is still a noticeable background load.
3. Will it affect your planned rebalance?
You mentioned you want to perform a manual tablet rebalance (limiting your main table to 6/8 nodes).
* Recommendation: Wait for the "automatic" rebalancing to stabilize first. If you start your manual rebalance while the system is already moving tablets to fill the new disk space, you will see a massive compounding CPU spike.
* Monitoring: Run SHOW BACKENDS\G and look at the TabletNum and DataUsedCapacity columns. Wait until these numbers stop shifting significantly before starting your manual redistribution.
Summary of "Spike" Expectations
Phase | CPU Impact | Duration
Reporting (Heartbeat) | Negligible | Seconds
Metadata Update | Low | Minutes
Tablet Migration | High | Hours (depending on data volume)
Pro-Tip: If you want to prevent the automatic spike while you prepare your manual changes, you can temporarily disable the balancer:
sql
ADMIN SET FRONTEND CONFIG ("tablet_sched_disable_balance" = "true");
Once your manual rebalance is done, set it back to false to allow the cluster to maintain health.
References
• administration/management/resource_management/Replica.md
• faq/operation_maintenance_faq.md
• administration/management/BE_configuration.md
• administration/management/FE_configuration.md
References
• administration/management/BE_configuration.md
• administration/management/monitoring/metrics.md
• administration/management/FE_configuration.mdMinn Fong
05/13/2026, 3:28 PMRocky
05/13/2026, 3:29 PMsql
SHOW PROC '/cluster_balance/running_tasks';
If you see many rows here, the cluster is mid-rebalance.
2. Emergency Stop (Restore Latency)
To immediately stop the resource contention and bring your transaction latency back down, disable the balancer:
sql
ADMIN SET FRONTEND CONFIG ("tablet_sched_disable_balance" = "true");
Note: This won't kill tasks already in progress, but it will prevent new ones from starting. Latency should stabilize within a few minutes as current moves finish.
3. Throttle the rebalance (Long-term)
If you want the cluster to balance without killing your performance, you can turn it back on but limit its "violence" by reducing concurrent tasks:
sql
-- Reduce the number of concurrent tablet clones (default is usually 10-20)
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_balancing_tablets" = "2");
ADMIN SET FRONTEND CONFIG ("tablet_sched_disable_balance" = "false");
Summary
Your disk expansion was successful, but the "helpful" auto-balancer is currently starving your transactions of IOPS and CPU. Disable the balancer temporarily to let your transaction queue clear, then re-enable it with a much lower concurrency limit during an off-peak window.
References
• administration/management/resource_management/Replica.md
• administration/management/FE_configuration.md
• faq/operation_maintenance_faq.md
• administration/management/monitoring/metrics.mdMinn Fong
05/13/2026, 3:29 PMRocky
05/13/2026, 3:29 PMsql
-- To see tablets currently being moved/rebalanced
SHOW PROC '/cluster_balance/running_tablets';
-- To see tablets waiting in the queue to be moved
SHOW PROC '/cluster_balance/pending_tablets';
Why you got that error
The SHOW PROC utility is very strict about its virtual file paths. running_tasks does not exist, but running_tablets contains the detailed list of every tablet StarRocks is currently cloning or migrating.
What to look for in the output
* Type: If you see BALANCE, it confirms StarRocks is moving data to fill the new 1250GB space.
* SrcBe / DestBe: This shows which nodes are sending data and which are receiving.
* State: If these are RUNNING, they are actively consuming CPU and disk IOPS.
Alternative High-Level View
If you just want to see a summary count of how many tablets are currently cloning across the whole cluster:
sql
SHOW PROC '/statistic';
Look for the CloningTabletNum column. If that number is high (e.g., in the hundreds or thousands), that is the source of your transaction latency.
Immediate Mitigation
As mentioned before, if your latency is hitting 60 seconds, you should pause the balancer to let the system recover:
sql
ADMIN SET FRONTEND CONFIG ("tablet_sched_disable_balance" = "true");
References
• administration/management/resource_management/Replica.md
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• administration/management/FE_configuration.md
References
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• administration/management/resource_management/Replica.md
• administration/management/monitoring/metrics.md
• faq/operation_maintenance_faq.md
-faq)
-7901842)
)
)
References
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• administration/management/resource_management/Replica.mdMinn Fong
05/13/2026, 3:34 PMTabletId,Type,Medium,Status,State,OrigPrio,DynmPrio,SrcBe,SrcPath,DestBe,DestPath,Timeout,Create,LstSched,LstVisit,Finished,Rate,FailedSched,FailedRunning,LstAdjPrio,VisibleVer,VisibleVerHash,CmtVer,CmtVerHash,ErrMsg
7445137,BALANCE,HDD,INTER_NODE_TABLET_DISTRIBUTION,RUNNING,LOW,LOW,203697,-2029043970693695594,203701,-2396125465657593808,638000,2026-05-13 15:33:11,2026-05-13 15:33:15,2026-05-13 15:33:15,,,3,0,,3568,0,3572,0,""
7449878,BALANCE,HDD,INTER_NODE_TABLET_DISTRIBUTION,RUNNING,LOW,LOW,171908,3155724088209648910,110783,-2870700534670145664,512000,2026-05-13 15:33:11,2026-05-13 15:33:12,2026-05-13 15:33:12,,,0,0,,2487,0,2492,0,""Rocky
05/13/2026, 3:34 PMClusterLoadStatistics updates).
* When you expanded your disk, the Load Score for those nodes dropped.
_ Every minute, the FE looks at the score and says, _"Node A is much lighter than Node B; let's pick a batch of tablets to move."*
2. Slot Throttling (The "Below 10" Limit)
The reason you only see ~10 tablets at a time is likely the path slot limit. StarRocks prevents a single disk from being overwhelmed by too many concurrent clones.
* Parameter: schedule_slot_num_per_path (FE configuration).
* By default, this is usually set to a low number (e.g., 2 or 5). Since you have 1 disk (EBS volume) per BE, the FE will only allow a few concurrent "Clone" tasks to target that BE at once.
_ Even if 1,000 tablets _need* to move, the FE only drips them into the RUNNING state as "slots" become available on the destination BEs.
3. Why ~10 tablets are enough to ruin your latency
You might think "Only 10 tablets moving shouldn't cause a 60-second latency spike," but here is what is happening under the hood for those 10 tablets:
* IOPS Saturation: Each BALANCE task is a physical file copy. On EBS, if you are hitting your IOPS or throughput limit, the Write-Ahead Logs (WAL) for your new transactions have to wait in line behind these massive data clones.
* Primary Key Indexing (CPU): If your table is a Primary Key table, the moment a tablet finishes moving to the new node, that node must load and verify the Persistent Index. This consumes significant CPU and memory.
* Transaction Lock Contention: If a transaction needs to write to a tablet that is currently being "committed" at the end of a clone, it may experience a brief lock wait, which compounds as your concurrency rises from 3 to 13.
Recommended Action
If 10 concurrent clones are causing 60-second latencies, your system is likely I/O bound. To restore your 3-5s latency immediately:
1. Pause the balancer:
sql
ADMIN SET FRONTEND CONFIG ("tablet_sched_disable_balance" = "true");
2. Wait for the current 10 to finish. Your latency should drop back to normal within minutes.
3. Resume slowly (optional): If you must balance now, you can lower the limit even further to 1 or 2 to see if latency stays stable:
sql
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_balancing_tablets" = "2");
ADMIN SET FRONTEND CONFIG ("tablet_sched_disable_balance" = "false");
Summary: Yes, it is periodic (1-minute cycles) and throttled (slots per path), but even this "slow" background movement is competing for the same EBS resources your transactions need.
References
• administration/management/resource_management/Replica.md
• administration/management/FE_configuration.md
• sql-reference/information_schema/fe_tablet_schedules.mdMinn Fong
05/13/2026, 3:35 PMRocky
05/13/2026, 3:35 PMfalse, StarRocks knows it still has work to do.
sql
SHOW PROC '/cluster_balance/balance_stat';
Look for the row inter-node disk usage.
* Balanced: If this is false, the FE will continue generating new move tasks.
* PendingTablets: This is the size of the current "active" backlog.
2. View the Cluster Skewness (The "Score")
To see why it's moving data and how far apart your nodes are, check the load statistics:
sql
SHOW PROC '/cluster_balance/cluster_load_stat';
This shows a Score for each BE. The balancer's goal is to make these scores nearly identical. If your new 1250GB nodes have a score of 0.1 and your old nodes are at 0.8, the FE will keep scheduling moves until they converge.
3. Monitor the "Tablet Count" convergence
Since you know you expanded the disks, you can track the "Total Tablets" on each node. Over time, the TabletNum on your expanded nodes should rise, and the TabletNum on other nodes should fall.
sql
SHOW PROC '/backends';
Compare the TabletNum and DataSize columns across backends. When these numbers stabilize and are roughly equal (relative to disk capacity), the rebalancing is complete.
Why you only see "10" pending?
The FE limits the number of pending tasks it creates to avoid overwhelming its own memory and the BEs. This is controlled by the FE configuration tablet_sched_max_balancing_tablets (default is often small). It will only "refill" that pending list once the current ones move to RUNNING or FINISHED.
In short: There is no "1,000/5,000 completed" progress bar. Instead, monitor balance_stat to see if it's still active (false) and backends to watch the tablet counts gradually equalize.
References
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• administration/management/resource_management/Replica.md
• administration/management/FE_configuration.md
References
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• administration/management/resource_management/Replica.mdMinn Fong
05/13/2026, 3:36 PMTabletId,Type,Medium,Status,State,OrigPrio,DynmPrio,SrcBe,SrcPath,DestBe,DestPath,Timeout,Create,LstSched,LstVisit,Finished,Rate,FailedSched,FailedRunning,LstAdjPrio,VisibleVer,VisibleVerHash,CmtVer,CmtVerHash,ErrMsg
7458486,REPAIR,HDD,REDUNDANT,PENDING,NORMAL,NORMAL,-1,-1,-1,-1,0,2026-05-13 15:35:27,2026-05-13 15:35:45,2026-05-13 15:35:45,,,18,0,2026-05-13 15:35:32,354,0,365,0,wait txn before 3125639 to be finished
7458518,REPAIR,HDD,REDUNDANT,PENDING,NORMAL,NORMAL,-1,-1,-1,-1,0,2026-05-13 15:35:27,2026-05-13 15:35:45,2026-05-13 15:35:45,,,18,0,2026-05-13 15:35:32,354,0,365,0,wait txn before 3125640 to be finished
7256167,REPAIR,HDD,REDUNDANT,PENDING,NORMAL,NORMAL,-1,-1,-1,-1,0,2026-05-13 15:35:07,2026-05-13 15:35:45,2026-05-13 15:35:45,,,38,0,2026-05-13 15:35:12,5007,0,5011,0,wait txn before 3125634 to be finished
7445137,REPAIR,HDD,REDUNDANT,PENDING,NORMAL,NORMAL,-1,-1,-1,-1,0,2026-05-13 15:34:47,2026-05-13 15:35:45,2026-05-13 15:35:45,,,58,0,2026-05-13 15:34:52,3578,0,3581,0,wait txn before 3125628 to be finished
Why are some tablets due for repair too?Minn Fong
05/13/2026, 3:38 PMTabletId,Type,Medium,Status,State,OrigPrio,DynmPrio,SrcBe,SrcPath,DestBe,DestPath,Timeout,Create,LstSched,LstVisit,Finished,Rate,FailedSched,FailedRunning,LstAdjPrio,VisibleVer,VisibleVerHash,CmtVer,CmtVerHash,ErrMsg
7458486,REPAIR,HDD,REDUNDANT,PENDING,NORMAL,NORMAL,-1,-1,-1,-1,0,2026-05-13 15:35:27,2026-05-13 15:35:45,2026-05-13 15:35:45,,,18,0,2026-05-13 15:35:32,354,0,365,0,wait txn before 3125639 to be finished
7458518,REPAIR,HDD,REDUNDANT,PENDING,NORMAL,NORMAL,-1,-1,-1,-1,0,2026-05-13 15:35:27,2026-05-13 15:35:45,2026-05-13 15:35:45,,,18,0,2026-05-13 15:35:32,354,0,365,0,wait txn before 3125640 to be finished
7256167,REPAIR,HDD,REDUNDANT,PENDING,NORMAL,NORMAL,-1,-1,-1,-1,0,2026-05-13 15:35:07,2026-05-13 15:35:45,2026-05-13 15:35:45,,,38,0,2026-05-13 15:35:12,5007,0,5011,0,wait txn before 3125634 to be finished
7445137,REPAIR,HDD,REDUNDANT,PENDING,NORMAL,NORMAL,-1,-1,-1,-1,0,2026-05-13 15:34:47,2026-05-13 15:35:45,2026-05-13 15:35:45,,,58,0,2026-05-13 15:34:52,3578,0,3581,0,wait txn before 3125628 to be finished
Why are some tablets due for repair too?Rocky
05/13/2026, 3:38 PMREPAIR tasks you see are actually the second half of the rebalancing process.
When StarRocks moves a tablet to a new node (rebalance), it doesn't just "move" it in one step. It follows this sequence:
1. Clone (Type: BALANCE): It copies the tablet from a high-load node to your new 1250GB node.
2. Verify: Once the copy is finished, the cluster now has 4 replicas (if your replication factor is 3).
3. Cleanup (Type: REPAIR, Status: REDUNDANT): The cluster now identifies the old replica on the original node as "redundant" and schedules a task to delete it.
Why they are stuck with "wait txn before..."
The error wait txn before 3125639 to be finished is the key to your latency issues.
StarRocks is extremely cautious. It will refuse to delete the old redundant replica until every transaction that was running when that replica was "active" has finished.
* If your system is experiencing 60-second transaction latencies, these repair tasks must wait at least 60 seconds before they can clean up.
* While they wait, they stay in the PENDING queue.
* If you have a high volume of continuous writes, new transactions keep "pinning" the old replica, delaying the cleanup further.
The "Feedback Loop"
This creates a performance death spiral:
1. The Balance task (copying data) saturates your EBS IOPS.
2. This causes Transactions to slow down (taking 60s).
3. Because Transactions are slow, the Repair task (cleanup) can't finish.
4. Because the Repair task doesn't finish, the cluster stays in an "unbalanced" state.
5. The FE then schedules more Balance tasks, adding even more I/O pressure.
Recommendation
The fact that you see wait txn... confirms that your background data movement is directly competing with your foreground transactions.
To break the cycle:
1. Check for stuck transactions: Run SHOW BACKENDS and check the LastHeartbeat and TabletNum. Then run SHOW PROC '/transactions' to see if any very old transactions are still RUNNING.
2. Throttle the Cleanup: You can tell StarRocks to be less aggressive with repairs by setting:
sql
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_scheduling_tablets" = "5");
3. Prioritize Latency: If your business cannot tolerate the 60s latency, turn off the balancer (tablet_sched_disable_balance = true) for a few hours during peak time. Let the "redundant" replicas stay there—they won't hurt anything except taking up a little extra disk space—and turn it back on during a low-traffic window.
References
• administration/management/resource_management/Replica.md
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• administration/management/FE_configuration.md
References
• knowledge/trouble_shooting/fe_deadlock_problems.mdRocky
05/13/2026, 3:40 PMBALANCE): It copies the tablet to the new BE.
2. Verify: It ensures the new replica is healthy and in sync.
3. Prune (REPAIR + REDUNDANT): Once the new replica is ready, the cluster suddenly has one extra copy (e.g., 4 replicas instead of the required 3). The system marks the old copy as REDUNDANT and creates a REPAIR task to delete it.
Why the "wait txn before..." error?
This is a safety lock. StarRocks is refusing to delete the old (redundant) replica because there are active write transactions (like your 10-15 concurrent loads) that started before the new replica was fully joined.
* The Risk: If StarRocks deleted the old replica right now, a transaction that was currently writing to it might fail or cause data inconsistency.
* The Logic: The Frontend (FE) tracks the Transaction ID (e.g., 3125639). It will keep these tablets in a PENDING state until that specific load job finishes.
* The Latency Link: This confirms your cluster is under heavy write pressure. The reason these "Repair" tasks are piling up is that your transactions are taking a long time to commit (the 60s latency you mentioned), which in turn blocks the cleaner from deleting old data.
Is this a problem?
No, it is normal behavior, but it indicates a "traffic jam":
1. Your loads are slow (due to IOPS/Balance contention).
2. Slow loads keep transactions open longer.
3. Open transactions block the deletion of old replicas.
4. Old replicas stay on disk longer, keeping your disk usage higher than it should be.
Summary of Status
* Type: REPAIR / Status: REDUNDANT = "I have an extra copy of this data and I want to delete it."
* ErrMsg: wait txn... = "I can't delete it yet because a load job is still using the old version of this tablet."
Once your 60-second latency spikes subside and transactions commit faster, these REPAIR tasks will disappear almost instantly.
References
• administration/management/resource_management/Replica.md
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• faq/operation_maintenance_faq.md
-faq)
-7901842)
)
)
• administration/management/resource_management/Replica.md
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• administration/management/FE_configuration.md
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• administration/management/resource_management/Replica.md
• administration/management/FE_configuration.md
• sql-reference/information_schema/fe_tablet_schedules.md
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• administration/management/resource_management/Replica.mdRocky
05/13/2026, 3:40 PMRocky
05/13/2026, 3:40 PMRocky
05/13/2026, 3:40 PMRocky
05/13/2026, 3:40 PMRocky
05/13/2026, 3:40 PMRocky
05/13/2026, 3:40 PMRocky
05/13/2026, 3:40 PMRocky
05/13/2026, 3:40 PMRocky
05/13/2026, 3:40 PMMinn Fong
05/13/2026, 3:43 PMRocky
05/13/2026, 3:43 PMbrpc (internal communication) threads are busy or the network is saturated by the tablet clones, these tiny "Publish" messages get stuck in the BE's task queue.
* The "Wait TXN" Lock: You saw REPAIR tasks waiting for transactions to finish. This is part of the metadata pressure. The FE is trying to manage the state of replicas that are currently being cloned, deleted, and updated all at once.
* EBS Throughput vs. IOPS: On AWS EBS, you can be "Throughput Bound" without being "IOPS Bound." Moving 10 tablets (clones) can easily max out the MiB/s limit of a GP3 volume. While the "Apply" phase might still be fast (because it writes in bursts), the constant stream of clone data creates a "floor" of high latency for the control-plane RPCs needed to finish a transaction.
3. How to verify it is an I/O/Throughput bound
Check these specific metrics in your dashboard or via `SHOW PROC`:
1. FE Publish Schedule Latency: Check the metric starrocks_fe_txn_publish_schedule_latency_ms.
* If this is high, the FE is overwhelmed and can't even get to the tasks.
2. FE Publish Execute Latency: Check starrocks_fe_txn_publish_execute_latency_ms.
* If this is the high one, the FE is waiting for BEs to say "Done." This confirms the BEs are too busy (likely with I/O or network from the clones) to respond to the version publish command quickly.
3. Check BE RPC Queue: Look at the BE metric brpc_endpoint_stub_count or the brpc status page (http://<be_ip>:<brpc_port>/status). If the queue is growing, the BE is struggling to process incoming control signals.
Verdict
You are likely throughput bound on your storage or network. The rebalancing clones are eating the "headroom" that your high-frequency transactions need for the final Publish phase.
Recommendation:
Since your apply duration is fine, you don't need more CPU. You need to throttle the background movement to give your RPCs room to breathe.
sql
-- Reduce the global limit of concurrent balancing tasks to 2 or 5
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_balancing_tablets" = "2");
This should cause your Publish latency to drop almost immediately by reducing the background I/O "noise" on your EBS volumes.
References
• administration/management/monitoring/metrics.md
• faq/shared_data_faq.md
• administration/management/FE_configuration.md
• administration/management/BE_configuration.md
References
• knowledge/usage/load/shared_data_batch_ingestion.md
• faq/Others.mdMinn Fong
05/13/2026, 3:48 PMRocky
05/13/2026, 3:49 PMPREPARE -> COMMITTED -> VISIBLE.
* Query Visibility: Data only becomes queryable once the transaction is marked as VISIBLE.
* The Lag: When you see high "Publish Latency," the data has been successfully written to the BEs (COMMITTED), but the FE hasn't finished the "handshake" to increment the table's version number and tell the cluster that this new data is ready.
* Result: Queries will continue to see the old data until that publish handshake completes. This is why you see a delay between a load job saying it's done and the data actually appearing in your dashboards.
──────────
2. Why did FE EBS Write IOPS/Bytes quadruple?
The FE is the "Brain" of the cluster, and it persists every single state change into its Edit Log (stored on the FE's disk). You are currently experiencing a Metadata Storm caused by the collision of two high-volume activities:
A. Rebalancing Metadata
Every single tablet that is moved, cloned, or deleted during rebalancing is a metadata event.
* If you are moving thousands of tablets, the FE must write a log entry for: "Tablet X is now moving to BE Y," "Tablet X clone is 50%," "Tablet X is now at BE Y," "Old Tablet X is now redundant."
* This creates a massive "floor" of background disk I/O on the FE's storage.
B. High-Frequency Transaction Commits
Each of your 10-15 concurrent load jobs also requires an Edit Log write to move from COMMITTED to VISIBLE.
* Because the rebalancing is already saturated the FE's disk bandwidth (the 100ms write time you're seeing), your transaction logs are getting stuck in the disk write queue.
* The Quadrupling: The 4x jump in write bytes and IOPS is the combined weight of thousands of "Tablet Moved" events plus your active load metadata.
──────────
3. Verdict: You are "Metadata Disk Bound"
You aren't CPU bound because the FE is just waiting for the EBS volume to acknowledge the write.
* The 100ms Write Time: This is the critical number. Usually, FE edit log writes should be <5ms. At 100ms, the FE can only "hand out" a very small number of transaction versions per second.
* The Fix: You need to throttle the "Metadata Storm" to give your transactions priority.
Immediate Actions:
1. Throttle Rebalancing: This is the most effective way to lower FE Disk I/O.
sql
-- Default is often 100-500; drop it to 2-5 to stop the metadata flood
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_balancing_tablets" = "5");
2. Verify Storage: Ensure your FE volumes are at least gp3 with high enough provisioned IOPS/Throughput. If you are on gp2, you might be hitting "burst bucket" exhaustion.
3. Check Batching: If you are on version 3.2.3 or higher, ensure batch publish is enabled to reduce the number of separate disk writes for transactions:
sql
ADMIN SET FRONTEND CONFIG ("lake_enable_batch_publish_version" = "true");
Once you throttle the rebalancing tasks, your FE EBS write time should drop back to <10ms, and your "Publish Latency" (and thus data queryability delay) will disappear.
References
• administration/management/FE_configuration.mdMinn Fong
05/13/2026, 3:51 PMRocky
05/13/2026, 3:51 PMstarrocks_be_disks_data_read_bytes / starrocks_be_disks_data_write_bytes.
* Action: Compare against your EBS volume limits (e.g., 3000 IOPS / 125 MiB/s for standard gp3). If you are at the limit, rebalancing is likely the culprit.
Step 3: Check Primary Key Index Metrics
If using Primary Key tables, check if the index "Apply" is the bottleneck.
* Metric: starrocks_be_update_rowset_commit_apply_duration (should be low).
* Metric: starrocks_be_primary_key_index_mem_usage.
* Action: If memory usage is near storage_page_cache_limit or the node is swapping, Apply latency will spike.
Step 4: Check Compaction Scores
* Command: SHOW PROC '/statistic/table_high_priority_compaction_score';
* Action: If scores are >100, the BE is struggling to merge data. New writes ("Apply") will be throttled to prevent the version count from exploding.
──────────
4. Emergency Actions
A. Reduce Background Contention
If the cluster is currently rebalancing (as in your case), stop or slow down the data movement immediately to free up I/O for transactions.
sql
-- Lower the number of concurrent tablet clones
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_balancing_tablets" = "2");
-- Lower the clone speed
ADMIN SET FRONTEND CONFIG ("clone_job_timeout_ms" = "300000");
B. Increase Write Wait/Timeout
If loads are failing because they can't "Apply" in time, temporarily increase the timeout to allow the cluster to catch up.
sql
-- Increase the wait time for the publish version phase
ADMIN SET FRONTEND CONFIG ("publish_version_timeout_second" = "120");
C. Identify the "Hot" Table
Use the following to find which table is causing the most pressure:
sql
SELECT * FROM information_schema.be_tablets
ORDER BY data_size DESC
LIMIT 10;
──────────
5. Summary for the Responder
Look at... | Healthy Value | Danger SignRocky
05/13/2026, 3:51 PMMinn Fong
05/13/2026, 4:03 PMRocky
05/13/2026, 4:03 PMstarrocks_fe_txn_publish_latency_ms) is the Publish phase (metadata versioning). "Apply Latency" is the Write phase where the BE physically writes data and resolves Primary Key conflicts.
The Correct Metrics for "Apply Latency"
1. BE-side (The "True" Apply Latency)
If you want to see how long the BE takes to update the Primary Key index and write rowsets:
* Metric Name: starrocks_be_update_rowset_commit_apply_duration_us
* Description: The time (in microseconds) the BE spends in the "Apply" phase for Primary Key tables.
* Grafana Tip: Since this is often a cumulative counter in Prometheus, you should use the rate() or irate() function to see the latency per second, or look for the summary/histogram version if your dashboard template provides it:
* rate(starrocks_be_update_rowset_commit_apply_duration_us[1m]) / rate(starrocks_be_update_rowset_commit_apply_total[1m]) (This calculates the average apply time per request).
2. FE-side (The "Write" Phase Proxy)
The FE tracks the phase before Publish, which includes the time it spends waiting for BEs to finish writing and applying data:
* Metric Name: starrocks_fe_txn_write_latency_ms
* Description: Time from prepare to commit. This captures the BE write/apply duration from the FE's perspective.
* Quantiles: You can find the p95 by looking for starrocks_fe_txn_write_latency_ms{quantile="0.95"}.
──────────
Comparison: Which one should you alert on?
Metric Phase | Grafana Metric Name | What it measures
Apply Latency | starrocks_fe_txn_write_latency_ms | BE Heavy Lifting: Disk I/O, PK Index updates, memory pressure.
Publish Latency | starrocks_fe_txn_publish_latency_ms | FE Handshake: Metadata disk (Edit Log), RPC congestion, versioning.
In your specific case:
Because you saw high FE EBS Write Latency but healthy Apply Duration on the BE, you should prioritize alerting on starrocks_fe_txn_publish_latency_ms or starrocks_fe_txn_publish_execute_latency_ms. This correctly identifies your current bottleneck: the FE metadata disk being choked by rebalancing logs.
References
• administration/management/monitoring/metrics.md
• administration/management/BE_configuration.mdMinn Fong
05/13/2026, 4:31 PMRocky
05/13/2026, 4:32 PMstarrocks_fe_txn_write_latency_ms is a global average across all table types (Duplicate, Aggregate, and Primary Key).
* Duplicate Key tables have almost zero "Apply" overhead—they just write data.
* Primary Key (PK) tables must perform a "Commit-Apply" step to update the index and handle deletes/upserts.
* Because the global write metric is "diluted" by the fast Duplicate Key writes, it looks much lower than the specialized PK metric.
To monitor this effectively, you need a multi-layered approach. Below is the unified runbook.
──────────
Runbook: Ingestion & Transaction Latency (Unified)
1. Alert Configuration: What to Monitor
Set up these three specific alerts to catch bottlenecks at different stages:
Metric | Threshold (p95) | What it catches
starrocks_fe_txn_publish_latency_ms | > 2,000ms | FE Metadata Bound: Disk I/O on FE (Edit Logs) or RPC congestion.
starrocks_be_update_rowset_commit_apply_duration_us | > 500,000us (500ms) | BE PK-Index Bound: Heavy upsert load, PK memory pressure, or BE disk I/O.
starrocks_fe_txn_write_latency_ms | > 1,000ms | Network/Storage Bound: General slowness in data transfer between FE and BE.
──────────
2. Diagnosis & Logic Flow
When an alert fires, follow this flow to isolate the "Who" and "Why."
Step 1: Is it the "Handshake" (FE) or the "Hard Labor" (BE)?
* If publish_latency is high but apply_duration is low: The BEs are done, but the FE is struggling to record the metadata.
* Diagnosis: Check FE Disk Write Latency (EBS metrics).
* Root Cause: Metadata storm (too many small loads or massive rebalancing).
* If apply_duration is high: The BEs are struggling to physically merge data into the tables.
* Diagnosis: Check BE Disk I/O and Memory.
* Root Cause: PK Index is swapping to disk or EBS volume is throttled.
Step 2: Check for "Resource Contention" (The Rebalance Factor)
Check if background maintenance is stealing your IOPS:
* Metric: starrocks_be_disks_data_write_latency_us (BE Disk Health).
* Command: SHOW PROC '/cluster_balance/history';
* Action: If disk latency is high (>20ms) and rebalancing is active, the maintenance is killing your ingestion.
Step 3: Check Primary Key Health (If Apply is high)
* Metric: starrocks_be_primary_key_index_mem_usage.
* Action: If the index memory usage is near its limit, the BE must frequently read the index from disk to resolve updates, which quadruples your I/O and spikes apply latency.
──────────
3. Emergency Response Actions
A. Throttle the Metadata Storm (Relieve the FE)
If publish_latency is the issue, give the FE's disk some breathing room:
sql
-- Stop or slow down rebalancing to lower FE Edit Log writes
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_balancing_tablets" = "2");
B. Stabilize the BE Write (Relieve the BE)
If apply_duration is high, reduce the frequency of incoming "Commits":
1. Increase Batch Size: Instead of 10 small Stream Loads, combine them into 1 large one.
2. Increase PK Cache: If memory is the issue, increase pk_index_map_capacity (requires node restart, use with caution).
3. Adjust Compaction: If compaction scores are >100, the BE is "Write Stalled":
sql
-- Check compaction scores
SHOW PROC '/statistic/table_high_priority_compaction_score';
C. The "Nuclear" Option (Pause Rebalance)
If ingestion is mission-critical and latency is unacceptable during a scaling operation:
sql
-- Temporarily disable all rebalancing
ADMIN SET FRONTEND CONFIG ("disable_balance" = "true");
Summary for the Responder
1. Check FE EBS Write Time: If >50ms, it's a Metadata bottleneck (Throttle rebalancing).
2. Check BE Apply Duration: If >1s, it's a PK table bottleneck (Check PK memory or EBS throughput).Rocky
05/13/2026, 4:32 PMMinn Fong
05/13/2026, 4:39 PMRocky
05/13/2026, 4:39 PMstarrocks_fe_txn_publish_latency_ms)
* Definition: The time the FE takes to finalize a transaction. Think of this as the "Git Commit" of the database.
* Diagnosis: If this is high, the FE is struggling to write to its own metadata disk.
* Likely Cause: The FE's disk (usually an EBS volume) is saturated, often due to a "Metadata Storm" caused by too many small, frequent commits or heavy background data rebalancing.
B. Apply Latency (starrocks_be_update_rowset_commit_apply_duration_us)
* Definition: The time a BE spends updating Primary Key indexes. This is the most CPU and I/O intensive part of an "Upsert."
* Diagnosis: If this is high (>500ms), the BEs are struggling to process record-level updates.
* Likely Cause: The Primary Key index has grown too large for memory (causing disk swapping) or the BE's data disks are at their IOPS/Throughput limit.
C. Write Latency (starrocks_fe_txn_write_latency_ms)
* Definition: The total time taken to move data from the source to the BE disks.
* Diagnosis: This is a "Global Average." If this is low while Apply Latency is high, it means your standard tables (Append-only) are fast, but your Primary Key tables (Upsert) are the bottleneck.
──────────
3. Diagnosis Checklist (The "Follow the Smoke" Guide)
Step 1: Identify the Bottlenecked Component
Check your Grafana dashboard for these signals:
1. Is FE Disk Latency high? (Look at EBS Write Latency for FE nodes). If yes, the issue is Publish Latency.
2. Is BE Disk Utilization >90%? If yes, background tasks (like Rebalancing or Compaction) are fighting with your ingestion.
3. Is BE Memory usage high? If the PK Index cannot fit in memory, "Apply Latency" will spike because the BE must read from disk to resolve every row update.
Step 2: Check for Background Conflict
Run this in your SQL client:
sql
-- See if the cluster is currently moving data between nodes (Rebalancing)
SHOW PROC '/cluster_balance/history';
If there are many active "CLONE" or "BALANCE" tasks, these are likely consuming the I/O needed for your transactions.
──────────
4. Remediation Actions
Level 1: Throttle Background Noise (Immediate Relief)
If rebalancing is choking the FE or BE disks, slow it down to prioritize ingestion:
sql
-- Reduce the number of concurrent data moves
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_balancing_tablets" = "2");
-- Increase the timeout to allow slower disks to keep up
ADMIN SET FRONTEND CONFIG ("publish_version_timeout_second" = "120");
Level 2: Batching (Reduce Commit Frequency)
If Publish Latency is the issue, you are likely sending too many small transactions.
* Action: Adjust your ingestion app to send larger batches (e.g., instead of 100 rows every second, send 10,000 rows every 10 seconds). This reduces the pressure on the FE metadata log.
Level 3: Resource Scaling (Long-term)Rocky
05/13/2026, 4:39 PMfe_txn_publish_latency | FE Metadata Disk IOPS | Slow down rebalancing / Increase batch size
Apply Spike | be_update_rowset_apply | BE Disk I/O or RAM | Check PK Index memory / Check EBS limits
Write Spike | fe_txn_write_latency | Network or General Disk | Check for "hot" nodes or network congestion
References
• administration/management/monitoring/metrics.md
• administration/management/FE_configuration.md
• administration/management/BE_configuration.mdMinn Fong
05/13/2026, 4:57 PMRocky
05/13/2026, 4:57 PMmax_running_txn_num_per_db (Default: 1000, but was 100 in older versions). If you are on an older version, you are already over the limit.
* BE Partition Limit: max_runnings_transactions_per_txn_map (Default: 100). This is a critical Back-End limit. If you have 170 concurrent transactions and many are targeting the same data partitions, you are likely hitting this internal queue limit on the BEs.
* The Problem: High concurrency (many small loads) is significantly more expensive for StarRocks than high throughput (fewer large loads). 170 separate transactions create a "Metadata Storm" on the FE.
2. The "Rebalance + High Ingestion" Conflict
Tablet rebalancing (moving data between BEs) and Ingestion both compete for:
1. FE Metadata Locks: Both need to update the global metadata log (Edit Log).
2. Disk I/O: Moving tablets requires heavy disk reads/writes, which starves the "Apply" phase of your Primary Key updates.
3. RPC/Network: Ingestion and rebalancing both flood the internal network between nodes.
3. Recommended Action Plan
Step A: Throttle Rebalancing (Don't Pause Ingestion yet)
Instead of stopping your data flow, force the cluster to prioritize ingestion over maintenance. This is the most common fix.
sql
-- Reduce the number of tablets moved at once (Default is often 20-100)
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_balancing_tablets" = "2");
-- If the FE is still struggling with Publish Latency, disable it temporarily
-- ADMIN SET FRONTEND CONFIG ("disable_balance" = "true");
Step B: Batch Your Ingestion (Reduce Transaction Count)
If you have 170 concurrent transactions, you are likely loading data in very small increments.
* Goal: Get that number below 50.
* How: If you are using Stream Load or Routine Load, increase the max_batch_interval (e.g., to 10–20 seconds) or max_batch_rows.
* Result: One transaction of 100k rows is 100x more efficient than 100 transactions of 1k rows.
Step C: Check for Slowdown Errors
Run the following to see if StarRocks is intentionally delaying your transactions due to "Compaction Score" (too many small files):
sql
SHOW PROC '/transactions/<your_db_name>/running';
Look at the ErrMsg column. If you see "Partition's compaction score is larger than 100.0, delay commit...", the cluster is begging you to slow down so it can merge files.
Summary: Should you pause?
* Pause if: Your publish_latency is consistently > 10 seconds or you are seeing "Too many versions" errors in your load logs.
* Throttle if: You just want to clear the 170 transaction backlog. Lower the rebalance concurrency and increase your ingestion batch size.
References
• administration/management/FE_configuration.md
• administration/management/BE_configuration.md
• best_practices/primarykey_table.md
References
• best_practices/primarykey_table.md
• knowledge/usage/load/shared_data_batch_ingestion.md
• faq/operation_maintenance_faq.md
• faq/shared_data_faq.mdRocky
05/13/2026, 4:57 PMMinn Fong
05/13/2026, 5:00 PMRocky
05/13/2026, 5:00 PMwait for publishing partition ... version 362. self version: 363 is the smoking gun. It means your transactions are stuck in a "Version Gap."
1. What this error means (Technical Summary)
StarRocks transactions are strictly sequential per partition. Version 363 (your current load) cannot be finished until Version 362 is successfully "published" (made visible).
* The Conflict: You have 170 concurrent transactions. If Transaction A (v362) is slow because a BE is busy rebalancing or has a high compaction score, Transactions B through Z (v363+) all stall behind it.
* The Rebalance Factor: When a tablet is being moved (rebalanced), the new replica might be missing recent versions. The system must wait for the "Version Repair" to complete before it can publish new data to that tablet. This is what's causing your backlog.
──────────
2. Immediate Recovery Actions
Step A: Kill the "Zombie" Transactions
If the backlog is not clearing, you may need to clear the queue to let the FE metadata catch up.
1. Identify the Table: The error gave you table ID 7211473. Find the name:
sql
SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_ID = 7211473;
2. Stop Ingestion: Temporarily stop the Stream Load or Routine Load feeding this table.
Step B: Force-Throttle Rebalancing
Your rebalancing is likely "starving" the Publish Version threads on the BE.
sql
-- Stop all rebalancing immediately to give the Publish process priority
ADMIN SET FRONTEND CONFIG ("disable_balance" = "true");
-- If you don't want to stop it, at least set it to 1
ADMIN SET FRONTEND CONFIG ("tablet_sched_max_balancing_tablets" = "1");
Step C: Check the Publish Queue
If this number is high (>10), your BEs are physically unable to keep up with the 170-transaction commit rate.
bash
# Check this on your BE monitoring or via metrics endpoint
# Metric: starrocks_be_publish_version_queue_count
──────────
3. Updated Runbook: "The Version Gap & Backlog"
Scenario | Symptom | Diagnostic | Fix
Version Gap | wait for publishing... version X | 100+ concurrent txns | Reduce Concurrency: Merge small loads into larger batches.
Publish Timeout | Transaction [XYZ] is COMMITTED but not VISIBLE | publish_version_queue_count > 20 | Increase BE Threads: Increase transaction_publish_version_worker_count in be.conf.
Rebalance Block | Backlog spikes during node add/remove | SHOW PROC '/cluster_balance/history' | Throttle Balance: Set tablet_sched_max_balancing_tablets to 1 or 2.
Why 170 transactions is the root cause:
You are effectively asking StarRocks to perform 170 "Git Commits" simultaneously on the same branch.
* The Fix: Increase your batch size. Instead of 170 simultaneous loads, aim for 5 to 10 larger loads.
* If using Routine Load: Increase max_batch_interval to 20 (seconds).
* If using Stream Load: Use a buffer in your application to send data every 10–30 seconds rather than every second.
Recommendation: Disable rebalancing (disable_balance = true) for 30 minutes. Let the 170 transactions flush through. Once the backlog is gone, re-enable it but with a much lower limit (e.g., 2).
References
• faq/loading/Loading_faq.md
• administration/management/BE_configuration.md
• administration/management/FE_configuration.md
References
• administration/management/BE_configuration.md
• administration/management/monitoring/metrics.md
• sql-reference/System_variable.mdRocky
05/13/2026, 5:00 PMMinn Fong
05/13/2026, 5:08 PMwait for publishing partition 7460587 version 362. self version: 363. table 7211473Rocky
05/13/2026, 5:08 PMsql
-- Replace <table_name> and <partition_name> with your actual names.
-- To find the names from the IDs in your error:
-- SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_ID = 7211473;
-- SELECT PARTITION_NAME FROM information_schema.partitions WHERE PARTITION_ID = 7460587;
ADMIN SHOW REPLICA STATUS FROM <table_name> PARTITION (<partition_name>);
What to look for in the results:
* Check the LastSuccessVersion column. Most replicas will likely show 362, but one or more will likely be stuck at 361 or lower.
* Note the BackendId of the lagging node.
──────────
2. Check the BE Node's "Vital Signs"
Go to the lagging BE node identified above and check its internal health:
1. Thread Pool Saturation: Check if the publish queue is full.
bash
curl http://<BE_IP>:<BE_HTTP_PORT>/metrics | grep publish_version_queue_count
If this count is high (e.g., > 100), the BE is physically overwhelmed and can't process the "Commit" signal for version 362.
2. BE Logs: Search the <http://be.INFO|be.INFO> or be.WARNING logs for the word publish.
bash
grep "publish version" <http://be.INFO|be.INFO> | tail -n 20
Look for errors like timeout, disk full, or too many open files.
──────────
3. Immediate Remediation Options
Option A: The "Mark as Bad" (Safest)
If only one replica is stuck and you have a replication factor of 3, you can tell StarRocks to ignore the stuck one. It will then clone a healthy version from another node.
sql
-- WARNING: Only do this if you have other healthy replicas (LastSuccessVersion = 362)
-- Replace <TabletId> and <BackendId> with values from the ADMIN SHOW REPLICA STATUS command.
ADMIN SET REPLICA STATUS PROPERTIES("tablet_id" = "<stuck_tablet_id>", "backend_id" = "<lagging_be_id>", "status" = "bad");
Option B: Increase Publish Worker Threads
If multiple nodes have high publish_version_queue_count, increase the workers so they can clear the backlog faster.
sql
-- Run on the FE to apply to the whole cluster
ADMIN SET FRONTEND CONFIG ("transaction_publish_version_worker_count" = "64");
Option C: The Nuclear Option (Metadata Manual Fix)
If the cluster is completely stuck and you are certain the data for 362 is actually on the disks, you can force the metadata to skip the gap. Use this only as a last resort.
sql
-- This tells the FE: "Trust me, version 362 is fine."
ADMIN SET TABLE <table_name> PARTITION (<partition_name>) VERSION TO 362;
Why this is happening
With 170 concurrent transactions, your FE was likely sending 170 "Publish Version" RPC calls to every BE simultaneously. One of your BEs likely hit a thread limit or a temporary I/O hang, missed the "362" success signal, and now the FE is waiting indefinitely for that node to report back before it allows "363" to proceed.
Recommendation: After you clear this gap using Option A or B, reduce your ingestion concurrency. Aim for < 10 concurrent transactions by batching your data into larger chunks.
References
• administration/management/resource_management/Replica.md
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_SET_PARTITION_VERSION.mdRocky
05/13/2026, 5:08 PMMinn Fong
05/13/2026, 5:13 PMADMIN SET TABLE requests PARTITION (<partition_name>) VERSION TO 362;
Didnt solve issue. All it did was cause error messages to say wait for publiushing partition <partition> to version 369 now.Rocky
05/13/2026, 5:13 PMCOMMITTED state.
sql
-- 1. Find your Database ID
SHOW PROC '/transactions';
-- 2. View running transactions for that DB (replace <db_id>)
SHOW PROC '/transactions/<db_id>/running';
Sort by PrepareTime. The oldest transaction at the top is the one blocking everything else. Note its TxnId.
2. Find the Bottleneck Backend (BE)
Once you have the TxnId of the oldest stuck transaction:
sql
SHOW TRANSACTION WHERE id = <TxnId>;
Check the ErrorReplicasCount. If it's greater than 0, some BEs failed to publish this version.
To see which BE is the problem for that specific data:
sql
-- Find the tablets for the stuck partition
-- Replace <table_name> and <partition_name>
ADMIN SHOW REPLICA STATUS FROM <table_name> PARTITION (<partition_name>);
Look for any BE where the LastFailedVersion matches the version the system is waiting for. That specific BE is likely overwhelmed or has a disk I/O hang.
3. Clear the Backlog (Step-by-Step)
Step A: STOP ALL INGESTION
You must stop the source of the 170 transactions (Stream Load, Routine Load, Flink, etc.). If you don't stop the input, the version numbers will keep climbing (370, 371, 372...), and you will never catch up.
Step B: Increase BE Publish Workers
If the BEs are just slow but not "broken," give them more threads to process the 170+ pending commits:
sql
-- Run this on the FE. It tells all BEs to use more threads for publishing.
-- Default is 0 (which usually means # of CPU cores). Try setting it to 64.
ADMIN SET FRONTEND CONFIG ("transaction_publish_version_worker_count" = "64");
Step C: Force-Invisible Cleanup (Shared-Data Only)
If you are on a Shared-Data (Cloud-Native) cluster, you can use a more aggressive repair that ignores the consistent version requirement:
sql
ADMIN REPAIR TABLE requests PARTITION (<partition_name>)
PROPERTIES ("enforce_consistent_version" = "false");
Step D: Restart the "Stuck" BE
If you identified a specific BE in Step 2 that is lagging behind all others and its publish_version_queue_count is not going down, restart that specific BE. When it comes back up, it will clear its internal task queue and try to sync the latest metadata from the FE.
Summary of why ADMIN SET VERSION "failed":
You treated a queue problem as a single point problem.
1. You had a line of 170 people (Versions 362-532).
2. You manually moved person #362 out of the way.
3. The system immediately bumped into person #363... #368.
4. It is now stuck on #369.
Crucial Advice: Do not use ADMIN SET VERSION again for every version. Instead, stop ingestion and increase transaction_publish_version_worker_count. Let the BEs drain the queue naturally. Once the number of running transactions drops below 10, you can resume ingestion with cautionally restart ingestion with much larger batches (higher (max_batch_interval = 20s).
References
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_SET_PARTITION_VERSION.md
• administration/management/BE_configuration.md
• sql-reference/sql-statements/loading_unloading/SHOW_TRANSACTION.mdRocky
05/13/2026, 5:13 PMMinn Fong
05/13/2026, 5:16 PM+----------+-----------+-----------+---------+-------------------+--------------------+------------------+------------+------------+-------+---------------+--------------+---------------+
| TabletId | ReplicaId | BackendId | Version | LastFailedVersion | LastSuccessVersion | CommittedVersion | SchemaHash | VersionNum | IsBad | IsSetBadForce | State | Status |
+----------+-----------+-----------+---------+-------------------+--------------------+------------------+------------+------------+-------+---------------+--------------+---------------+
| 7460588 | 7460589 | 110783 | 576 | -1 | 576 | 368 | 0 | 10 | false | false | NORMAL | OK |
| 7460590 | 7460591 | 11001 | 576 | -1 | 576 | 368 | 0 | 11 | false | false | NORMAL | OK |
| 7460592 | 7460593 | 171908 | 405 | -1 | 405 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460592 | 7462223 | 203697 | 408 | 409 | 408 | 368 | 0 | 177 | true | false | NORMAL | DEAD |
| 7460594 | 7460595 | 203701 | 409 | -1 | 409 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460594 | 7462293 | 171908 | 576 | -1 | 576 | 368 | 0 | 11 | false | false | NORMAL | OK |
| 7460596 | 7460597 | 95876 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460598 | 7460599 | 203699 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460600 | 7460601 | 203697 | 576 | -1 | 576 | 368 | 0 | 11 | false | false | NORMAL | OK |
| 7460602 | 7460603 | 203700 | 387 | -1 | 387 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460602 | 7462115 | 171908 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460604 | 7460605 | 110783 | 379 | -1 | 379 | 368 | 0 | 10 | true | false | DECOMMISSION | DEAD |
| 7460604 | 7461937 | 11001 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460606 | 7460607 | 11001 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460608 | 7460609 | 171908 | 576 | -1 | 576 | 368 | 0 | 11 | false | false | NORMAL | OK |
| 7460610 | 7460611 | 203701 | 416 | -1 | 416 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460610 | 7462328 | 171908 | 418 | 420 | 418 | 368 | 0 | 163 | true | false | NORMAL | DEAD |
| 7460612 | 7460613 | 95876 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460614 | 7460615 | 203699 | 576 | -1 | 576 | 368 | 0 | 11 | false | false | NORMAL | OK |
| 7460616 | 7460617 | 203697 | 576 | -1 | 576 | 368 | 0 | 11 | false | false | NORMAL | OK |
| 7460618 | 7460619 | 203700 | 404 | -1 | 404 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460618 | 7462253 | 171908 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460620 | 7460621 | 110783 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460622 | 7460623 | 11001 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460624 | 7460625 | 171908 | 413 | -1 | 413 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460624 | 7462358 | 11001 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460626 | 7460627 | 203701 | 435 | -1 | 435 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460626 | 7462488 | 95876 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460628 | 7460629 | 95876 | 576 | -1 | 576 | 368 | 0 | 11 | false | false | NORMAL | OK |
| 7460630 | 7460631 | 203699 | 576 | -1 | 576 | 368 | 0 | 12 | false | false | NORMAL | OK |
| 7460632 | 7460633 | 203697 | 576 | -1 | 576 | 368 | 0 | 11 | false | false | NORMAL | OK |
| 7460634 | 7460635 | 203700 | 387 | -1 | 387 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
Sample outputRocky
05/13/2026, 5:16 PMCommittedVersion is 368, but your healthy replicas (on Backend 110783, 11001, etc.) are already at 576.
* The Blockers: Tablets like 7460592 and 7460610 have replicas on Backends that are DEAD or DECOMMISSION. The FE is trying to publish version 369 to these dead nodes and is waiting for a response that will never come.
* The Chain Reaction: Because StarRocks publishes versions sequentially, the "Publish Version" queue is backed up behind version 369.
──────────
The Recovery Plan
Step 1: Tell the FE to ignore the Dead Replicas
You must manually mark the replicas on the failing/decommissioning nodes as "Bad" so the FE stops waiting for them to acknowledge the publish command.
Based on your table, run these for every DEAD status row (replacing with your IDs):
sql
-- Example for Tablet 7460592 on Backend 203697
ADMIN SET REPLICA STATUS PROPERTIES("tablet_id" = "7460592", "backend_id" = "203697", "status" = "bad");
-- Example for Tablet 7460610 on Backend 171908
ADMIN SET REPLICA STATUS PROPERTIES("tablet_id" = "7460610", "backend_id" = "171908", "status" = "bad");
Note: Do this for every row in your SHOW REPLICA STATUS output where the status is DEAD or the backend is DECOMMISSION.
Step 2: Jump the Version to 576
Since your healthy nodes already have the data for version 576, you should jump the metadata to that point to clear the 200+ version backlog in one go.
sql
ADMIN SET TABLE requests PARTITION (<partition_name>) VERSION TO 576;
Step 3: Check if the Backlog Drains
Once you jump to 576, check the running transactions again:
sql
SHOW PROC '/transactions/<db_id>/running';
The "wait for publishing" errors should either disappear or move to a version higher than 576 (e.g., 577).
Step 4: Final Cleanup of Decommissioning Nodes
The "DEAD" and "DECOMMISSION" statuses suggest a node removal failed or is stuck.
1. Check Backend State: SHOW BACKENDS;
2. If the nodes are gone for good: Drop them formally to stop the FE from trying to balance to them:
sql
ALTER SYSTEM DROP BACKEND "host:port";
3. If you were in the middle of a decommission: Cancel it and restart if necessary once the cluster is stable.
Why this happened
You hit a "Perfect Storm":
1. High Concurrency (170 txns): Created a massive queue of small version increments.
2. Node Decommissioning: StarRocks was trying to move data and publish versions at the same time.
3. Node Failure: A node went DEAD during this process, and the FE's "Publish Version" task for version 369 got stuck in a retry loop waiting for that dead node.
Crucial: Once stable, you must batch your data. StarRocks cannot reliably handle 170 concurrent commits per partition while performing cluster maintenance (like decommissioning nodes maintenance. Aim for larger batches every 10-30 seconds.
References
• knowledge/trouble_shooting/fe_deadlock_problems.md
• knowledge/admin_and_operation/shared_data_compaction.mdMinn Fong
05/13/2026, 5:19 PMRocky
05/13/2026, 5:19 PMlabels.location set (e.g., rack1, rack2), StarRocks doesn't just need a "quorum" of any nodes; it often needs to ensure the version is published to replicas in the specific locations you defined.
In your SHOW REPLICA STATUS output, you have replicas on Backends like 171908 and 203697 that are marked as DEAD or DECOMMISSION.
* The Problem: The FE is trying to send a "Publish Version" command for version 369 to those specific Backend IDs because they are currently assigned as the "owners" of those data copies.
* The Hang: Because the nodes are DEAD, they never reply. The FE will wait and retry indefinitely. Because versions must be published sequentially, version 370 cannot start until 369 is finished on those specific nodes.
2. Does marking "bad" break your location labels?
No. It actually triggers the system to fix them.
When you run `ADMIN SET REPLICA STATUS ... status = 'bad'`:
1. Metadata Unblock: You are telling the FE: "Stop waiting for Backend 171908 to respond. This replica is officially dead."
2. Quorum Check: The FE looks at your other healthy replicas (which are already at version 576). Since they are healthy, it realizes it has enough data to consider the version "published."
3. Label-Aware Repair: Once the replica is marked bad, StarRocks triggers a Clone Task. The Tablet Scheduler will look at your labels.location configuration and attempt to create a new replica on a healthy BE that satisfies your rack/location requirements.
3. The Rebalancing Conflict
You mentioned the cluster was already rebalancing. This is likely why the nodes are in a DECOMMISSION state. However, if a node goes DEAD during a decommission, the rebalance/migration task for those specific tablets often hangs.
By marking them bad, you are essentially "canceling" the slow migration from the dead node and telling the cluster to "rebuild from scratch" on the remaining healthy nodes.
Recommended Action
Since your healthy nodes are already at version 576 but your metadata is stuck at 368, your cluster is in a "split-brain" version state.
1. Mark the DEAD replicas as bad: This stops the FE from waiting for non-existent RPC responses.
sql
-- Do this for the tablets showing DEAD/DECOMMISSION in your output
ADMIN SET REPLICA STATUS PROPERTIES("tablet_id" = "7460592", "backend_id" = "171908", "status" = "bad");
2. Jump the Version: Force the partition to recognize the version that your healthy nodes already have.
sql
ADMIN SET TABLE requests PARTITION (<partition_name>) VERSION TO 576;
3. Verify Healing: Run ADMIN SHOW REPLICA STATUS again after 5 minutes. You should see new `ReplicaId`s appearing on healthy nodes that match your location labels, and they will start downloading data (cloning) from the version 576 replicas.
Summary: Marking them "bad" is the signal the FE needs to stop the "wait for publishing" loop and start the "label-aware repair" loop.
References
• administration/management/resource_management/be_label.md
• introduction/versioning.md
• release_notes/release-3.2.mdMinn Fong
05/13/2026, 5:19 PMRocky
05/13/2026, 5:20 PMsql
DROP TABLE requests;
Note: If the FE says the table is "not in normal state," use DROP TABLE requests FORCE; to bypass safety checks.
3. Recreate the table: Use your original CREATE TABLE statement.
* Because the old "Dead" and "Decommissioning" nodes are likely being ignored by the FE's new tablet placement logic, the FE will only place the new replicas on the healthy nodes that match your location labels.
──────────
The "Mini-Nuclear" Option: Drop the Partition
If you only have issues with one partition (e.g., p202310), you can blow up just that partition:
sql
ALTER TABLE requests DROP PARTITION <partition_name>;
-- Wait 10 seconds for the FE to clear the metadata
ALTER TABLE requests ADD PARTITION <partition_name> VALUES [...];
This forces the system to create brand-new tablets for that time range, which will be placed on your correctly labeled, healthy nodes.
──────────
Why this is the "Nuclear" fix:
* Sequential Queue: StarRocks versioning is a chain. You are stuck at link #369. To "continue," you either have to repair link #369 or throw the whole chain away. Dropping the table throws the chain away.
* Label Alignment: When you create a new table/partition, the FE runs its "Tablet Scheduler." It looks at your DISTRIBUTED BY and your location labels. It will see that the nodes you want to use are healthy and the nodes that were "Dead" should be avoided.
* Ingestion: Once the table is recreated, the VisibleVersion starts back at 1. Your ingestion will start immediately without waiting for any background publishing tasks.
Warning: Both of these will result in total data loss for the table or partition. Only do this if you have the source data elsewhere and can re-ingest it once the pipeline is back up.
If you need to keep the data: There is no "nuclear" button. You must follow the steps in the previous message to mark the dead replicas as bad so the FE can "forget" them and move on.Minn Fong
05/13/2026, 5:20 PMRocky
05/13/2026, 5:20 PMDEAD or DECOMMISSION in your status list are non-functional or you simply want to get rid of them, drop them from the system:
sql
-- Replace with the actual host and heartbeat port of the DEAD/DECOMMISSION backends
ALTER SYSTEM DROP BACKEND "171908_host:9050";
ALTER SYSTEM DROP BACKEND "203697_host:9050";
What this does: This is the nuclear cleanup. It removes these nodes from the FE's metadata. The FE will immediately stop trying to publish version 369 to them, which unblocks your transaction queue.
Step 2: Force the Version Jump (The Partition Level)
Since your metadata is stuck at 368 but your data is actually at 576, you need to tell the FE to "teleport" its metadata forward. This fixes the version gap for all tablets in that partition at once:
sql
-- Run this for the stuck partition
ADMIN SET TABLE <table_name> PARTITION (<partition_name>) VERSION TO 576;
Why this is nuclear: This bypasses the sequential "publish version" logic. It tells the FE: "Ignore everything between 369 and 575; version 576 is now the official truth."
Step 3: Clear the Ingestion Queue
You have 170 transactions stuck in the "Wait for Publishing" state. Now that you've jumped the version to 576, these old transactions are technically invalid. To clear the FE's memory and get back to a clean state:
1. Stop your upstream loader (Flink, Routine Load, etc.).
2. Abort all running transactions for that database (you may need to do this via the Leader FE's web UI or by restarting the FE if the queue is too large to handle manually).
──────────
What happens next?
Once you do this:
1. Rebalancing: The FE's Tablet Scheduler will notice that many tablets are now missing replicas (because you dropped the DEAD backends).
2. Label Compliance: It will look at your location labels and start creating Clone Tasks.
3. Healing: It will copy the version 576 data from your healthy nodes to the new nodes that match your labels.
Why this is better than dropping the table:
* You keep the data that is already on your healthy nodes.
* You stop the "sequential version" deadlock.
* The system automatically handles the "migration" to your labeled nodes via its built-in repair mechanism.
Caution: ADMIN SET PARTITION VERSION is a high-risk metadata operation. Ensure you use the version number (576) from your healthy replicas, or you may lose the most recent data on those nodes.
References
• knowledge/trouble_shooting/fe_deadlock_problems.mdMinn Fong
05/13/2026, 5:21 PMRocky
05/13/2026, 5:21 PMreplication_num = "1" and location label rebalancing is almost certainly the root cause of your problem. This setup creates a "high-wire act" with no safety net.
Here is exactly how these two features collided to cause your stuck status and version mismatch:
1. The "Single Point of Failure" during Migration
When you have replication_num = "1", there is only one authoritative copy of each tablet in the entire cluster.
* Normally: When StarRocks rebalances data, it creates a new replica on a "good" node, waits for it to sync, and then deletes the "old" one.
* With 1 Replica: While that tablet is moving from a non-labeled node to a labeled node, the system still treats the "old" node as the owner of the current version.
2. Why your Transactions are Stuck
If the node currently holding that single replica is the one you marked as DEAD or `DECOMMISSION`:
* Quorum is impossible: StarRocks requires a "Quorum" of replicas to acknowledge a data load. For a 1-replica table, the quorum is 1.
* The Deadlock: If that 1 node is dead, the FE (Front End) will wait forever for it to report a successful "Publish Version." Since there are no other replicas to "take over" the transaction, the version chain stops at that node. This is why you see versions like 368/369 stuck, even if the data physically moved elsewhere.
3. The Label Conflict
When you applied location labels, you told the Tablet Scheduler: "Move this data to nodes with Label X."
* The scheduler started a Clone Task to move your single replica.
* If the source node (the one without the label) went DEAD before the clone to the new labeled node was 100% finished and "published," the tablet became orphaned.
* The system now has a record of a replica on a dead node (version 368) and perhaps a "stunt" replica on a new node (version 576), but it cannot bridge the gap because it can't talk to the dead node to "hand off" the version history.
Summary of the "Why"
* Rebalancing triggered the move.
* Labels dictated where it had to go.
* replication_num = 1 meant there was no "healthy" secondary copy to keep the table alive while the primary copy was being moved or while the node it sat on was being decommissioned.
Recommendation
In the future, if you are planning to change labels or rebalance a cluster:
1. Temporarily increase replicas: Set ALTER TABLE ... SET ("replication_num" = "2"); before you start rebalancing. This creates a redundant copy so if one node goes dead during the move, the other can still publish versions.
2. Reduce to 1 later: Once the rebalance is finished and all tablets are on the correctly labeled nodes, you can set it back to 1.
For now: You must use the "Nuclear" or "Manual Bad Status" steps provided previously to force the FE to stop waiting for that dead single-replica node.
References
• administration/management/resource_management/be_label.md
• introduction/versioning.md
• administration/management/resource_management/Replica.md
References
• administration/management/resource_management/be_label.md
• knowledge/trouble_shooting/fe_deadlock_problems.mdMinn Fong
05/13/2026, 5:27 PMMySQL [requests]> ADMIN SHOW REPLICA STATUS FROM requests where status != "OK";
+----------+-----------+-----------+---------+-------------------+--------------------+------------------+------------+------------+-------+---------------+--------------+---------------+
| TabletId | ReplicaId | BackendId | Version | LastFailedVersion | LastSuccessVersion | CommittedVersion | SchemaHash | VersionNum | IsBad | IsSetBadForce | State | Status |
+----------+-----------+-----------+---------+-------------------+--------------------+------------------+------------+------------+-------+---------------+--------------+---------------+
| 7453456 | 7462071 | 203697 | 1963 | 1964 | 1963 | 1957 | 0 | 71 | false | false | NORMAL | VERSION_ERROR |
| 7453618 | 7462450 | 95876 | 1975 | 1976 | 1975 | 1957 | 0 | 58 | false | false | NORMAL | VERSION_ERROR |
| 7454640 | 7462453 | 203697 | 1702 | 1703 | 1702 | 1684 | 0 | 59 | false | false | NORMAL | VERSION_ERROR |
| 7458424 | 7462082 | 110783 | 809 | 810 | 809 | 801 | 0 | 76 | false | false | NORMAL | VERSION_ERROR |
| 7460592 | 7460593 | 171908 | 405 | -1 | 405 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460592 | 7462223 | 203697 | 408 | 409 | 408 | 368 | 0 | 177 | true | false | NORMAL | DEAD |
| 7460594 | 7460595 | 203701 | 409 | -1 | 409 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460602 | 7460603 | 203700 | 387 | -1 | 387 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460604 | 7460605 | 110783 | 379 | -1 | 379 | 368 | 0 | 10 | true | false | DECOMMISSION | DEAD |
| 7460610 | 7460611 | 203701 | 416 | -1 | 416 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460610 | 7462328 | 171908 | 418 | 420 | 418 | 368 | 0 | 163 | true | false | NORMAL | DEAD |
| 7460618 | 7460619 | 203700 | 404 | -1 | 404 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460624 | 7460625 | 171908 | 413 | -1 | 413 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460626 | 7460627 | 203701 | 435 | -1 | 435 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460634 | 7460635 | 203700 | 387 | -1 | 387 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460642 | 7460643 | 203701 | 374 | -1 | 374 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460650 | 7460651 | 203700 | 370 | -1 | 370 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460656 | 7460657 | 171908 | 446 | -1 | 446 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460658 | 7460659 | 203701 | 416 | -1 | 416 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460666 | 7460667 | 203700 | 428 | -1 | 428 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460666 | 7462448 | 203699 | 434 | 435 | 434 | 368 | 0 | 151 | true | false | NORMAL | DEAD |
| 7460674 | 7460675 | 203701 | 409 | -1 | 409 | 368 | 0 | 10 | true | false | DECOMMISSION | DEAD |
| 7460682 | 7460683 | 203700 | 412 | -1 | 412 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460682 | 7462332 | 171908 | 418 | 420 | 418 | 368 | 0 | 163 | true | false | NORMAL | DEAD |
| 7460688 | 7460689 | 171908 | 453 | -1 | 453 | 368 | 0 | 10 | true | false | DECOMMISSION | DEAD |
| 7460690 | 7460691 | 203701 | 435 | -1 | 435 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460690 | 7462511 | 203699 | 442 | 443 | 442 | 368 | 0 | 143 | true | false | NORMAL | DEAD |
| 7460698 | 7460699 | 203700 | 376 | -1 | 376 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460706 | 7460707 | 203701 | 409 | -1 | 409 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460714 | 7460715 | 203700 | 412 | -1 | 412 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460722 | 7460723 | 203701 | 392 | -1 | 392 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460730 | 7460731 | 203700 | 428 | -1 | 428 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460738 | 7460739 | 203701 | 416 | -1 | 416 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460754 | 7460755 | 203701 | 409 | -1 | 409 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460762 | 7460763 | 203700 | 363 | 364 | 368 | 368 | 0 | 12 | false | false | DECOMMISSION | VERSION_ERROR |
| 7460770 | 7460771 | 203701 | 401 | -1 | 401 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460778 | 7460779 | 203700 | 428 | -1 | 428 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460778 | 7462447 | 11001 | 434 | 435 | 434 | 368 | 0 | 149 | true | false | NORMAL | DEAD |
| 7460786 | 7460787 | 203701 | 363 | 364 | 368 | 368 | 0 | 12 | false | false | DECOMMISSION | VERSION_ERROR |
| 7460794 | 7460795 | 203700 | 436 | -1 | 436 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460810 | 7460811 | 203700 | 387 | -1 | 387 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7460818 | 7460819 | 203701 | 363 | 364 | 368 | 368 | 0 | 11 | false | false | DECOMMISSION | VERSION_ERROR |
| 7460826 | 7460827 | 203700 | 370 | -1 | 370 | 368 | 0 | 12 | true | false | DECOMMISSION | DEAD |
| 7460842 | 7460843 | 203700 | 370 | -1 | 370 | 368 | 0 | 11 | true | false | DECOMMISSION | DEAD |
| 7450088 | 7462417 | 95876 | 2737 | 2738 | 2737 | 2720 | 0 | 41 | false | false | NORMAL | VERSION_ERROR |
| 7451123 | 7451124 | 11001 | 2476 | 2477 | 2476 | 2477 | 0 | 10 | false | false | DECOMMISSION | VERSION_ERROR |
| 7437714 | 7437715 | 203697 | 5070 | 5071 | 5070 | 5071 | 0 | 13 | false | false | DECOMMISSION | VERSION_ERROR |
| 7437714 | 7461723 | 11001 | 5071 | 5072 | 5071 | 5071 | 0 | 15 | false | false | NORMAL | VERSION_ERROR |
| 7437778 | 7437779 | 203697 | 5070 | 5071 | 5070 | 5071 | 0 | 13 | false | false | DECOMMISSION | VERSION_ERROR |
| 7437778 | 7461715 | 203699 | 5071 | 5072 | 5071 | 5071 | 0 | 15 | false | false | NORMAL | VERSION_ERROR |
| 7437948 | 7461726 | 203699 | 5071 | 5072 | 5071 | 5071 | 0 | 13 | false | false | NORMAL | VERSION_ERROR |
| 7441509 | 7462391 | 110783 | 4500 | 4501 | 4500 | 4495 | 0 | 38 | false | false | NORMAL | VERSION_ERROR |
| 7444042 | 7462408 | 95876 | 3989 | 3990 | 3989 | 3981 | 0 | 40 | false | false | NORMAL | VERSION_ERROR |
| 7447659 | 7462416 | 11001 | 3284 | 3285 | 3284 | 3272 | 0 | 38 | false | false | NORMAL | VERSION_ERROR |
+----------+-----------+-----------+---------+-------------------+--------------------+------------------+------------+------------+-------+---------------+--------------+---------------+
What is exact steps to fix.Rocky
05/13/2026, 5:28 PMDEAD in your status report. You must remove them to clear the transaction queue.
1. Run SHOW BACKENDS;
2. Identify the IP:HeartbeatPort for the Backend IDs that are Alive = false (e.g., 203697, 171908, 203701, etc., from your list).
3. Drop them one by one:
sql
ALTER SYSTEM DROP BACKEND "10.0.0.x:9050";
This immediately tells the FE to stop waiting for version 369 from these nodes.
2. Find the "Truth" (The Highest Version)
Look at your ADMIN SHOW REPLICA STATUS output again. Look for replicas on Healthy nodes (the ones you want to keep).
* Example: For many tablets, the Version is 442 or higher, but the FE's CommittedVersion is stuck at 368.
* Note the highest Version or LastSuccessVersion you see for your partition. Let's assume it's 576 (from your previous context) or the highest one in your current list.
3. Force the Partition Version Forward
This is the "Nuclear" part. You are telling the FE to skip the missing links (369–575) and jump to the version that actually exists on your good nodes.
1. Get your partition name: SHOW PARTITIONS FROM requests;
2. Execute the version jump:
sql
-- Replace <partition_name> and <version> with your actual values
ADMIN SET TABLE requests PARTITION (<partition_name>) VERSION TO 576;
_Repeat this for every partition that shows VERSION_ERROR or a stuck CommittedVersion._
4. Handle "Bad" Replicas (If Necessary)
Since you have replication_num = 1, if a tablet is marked IsBad = true and that was your only copy, the data for those specific rows is likely lost.
* If the node is healthy but the replica is still marked Bad, you can try to force it back to `OK`:
sql
ADMIN SET REPLICA STATUS TABLE requests TABLET 7460592 BACKEND 95876 STATUS "OK";
* If the data is lost: The tablet will show as Inconsistent. To fix this and continue ingestion, you may have to TRUNCATE that specific partition. This is the only way to "factory reset" the tablets without dropping the whole table.
5. Resume and Protect
1. Resume Ingestion: Once the version jump is done, your "Wait for Publishing" queue should clear, and new data will start flowing.
2. Prevent Recursion: Immediately set your replicas to 2 while you finish the migration to ensure you have a safety net:
sql
ALTER TABLE requests SET ("replication_num" = "2");
Wait for the cluster to finish cloning, then you can set it back to 1 if you must.
Summary of what this fixes:
* Step 1 stops the FE from hanging on dead nodes.
* Step 3 bypasses the sequential version chain.
* Step 4 (Truncate) is your last resort for specific broken partitions to get them "Clean" tablets on your new labeled nodes.
References
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_SET_PARTITION_VERSION.md
• administration/management/resource_management/Replica.md
• knowledge/trouble_shooting/fe_deadlock_problems.md
References
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_SET_PARTITION_VERSION.mdMinn Fong
05/13/2026, 5:43 PMRocky
05/13/2026, 5:43 PMFORCE keyword:
sql
ALTER TABLE requests DROP PARTITION <partition_name> FORCE;
Why this works:
1. Metadata Purge: It completely removes the records of those version 368/369 tablets from the FE's memory.
2. Queue Clearing: Any pending "Publish Version" tasks associated with those specific tablets will be aborted/discarded.
3. Physical Cleanup: The BEs will eventually delete the underlying data files, freeing up space and stopping the "Dead" node reporting for those tablets.
Important Rules & Risks:
* Don't Drop the Last Partition: StarRocks requires a partitioned table to have at least one partition. If you only have one partition total, you cannot drop it; you must TRUNCATE it instead.
* FORCE is Final: Using FORCE bypasses the "Trash" bin. You cannot use the RECOVER command to bring it back.
* Data Loss: Obviously, all data within that partition is gone. If you have the source data (e.g., in S3 or a Kafka topic), you will need to re-ingest it.
What to do after dropping:
After you drop the partition, the "blockage" in your FE should clear. To get back to work:
1. Re-create the Partition:
sql
ALTER TABLE requests ADD PARTITION <partition_name> VALUES [ ... ];
2. Verify Status: Run SHOW TABLET FROM requests; to ensure the new tablets are created on your currently healthy, labeled nodes.
3. Resume Ingestion: Restart your loader.
Recommendation: If you have multiple partitions and only one is stuck, dropping the partition is much safer than dropping the whole table. Just make sure you've already dropped the DEAD backends (as mentioned in the previous step) so the new partition doesn't try to place replicas on them.
References
• sql-reference/sql-statements/table_bucket_part_index/ALTER_TABLE.md
• sql-reference/sql-statements/table_bucket_part_index/TRUNCATE_TABLE.md
References
• sql-reference/sql-statements/table_bucket_part_index/ALTER_TABLE.md
• knowledge/admin_and_operation/shared_data_compaction.mdMinn Fong
05/13/2026, 5:51 PMSHOW PROC '/transactions/44945/running';
I Dropped the affected partitions. No ErrorMsg. Transactions just not applying? Now 67 pending transactions leftRocky
05/13/2026, 5:52 PMrunning in SHOW PROC '/transactions/...', it is because the Front End (FE) is still waiting for the internal timeout to expire for those specific transaction IDs. Dropping a partition stops new data from being accepted, but it doesn't automatically kill transactions that were already in the "Commit" or "Publishing" phase.
Here is how to clear them and what is happening:
1. Identify the "Stuck" Source
To stop these transactions, you first need to find their Labels. Internal transactions usually have a system-generated label (like insert_... or stream_load_...).
Run this for one of the transaction IDs you see in your SHOW PROC output:
sql
-- Replace <id> with one of the TxnIds from your proc list
SHOW TRANSACTION WHERE id = <id>;
Check the Label and the TimeoutMs fields in the output.
2. How to Force Abort them
Depending on the source (Label), use the corresponding command:
* If they have a Label (Broker Load, INSERT, etc.):
You can manually cancel the jobs by their label to clear the queue:
sql
CANCEL LOAD WHERE LABEL = "your_stuck_label_name";
* If they are Routine Load (Kafka):
The transactions are managed by the Routine Load job. If you haven't already, Pause or Stop the routine load job. It will automatically abort any "running" transactions once it realizes the partitions are gone.
sql
PAUSE ROUTINE LOAD FOR requests;
* If they are from a Connector (Flink/Spark):
The connector usually holds the transaction open. If you stop the Flink/Spark job, the FE will eventually reach the TimeoutMs (visible in SHOW TRANSACTION) and abort them.
3. Why they are "Not Applying"
The transactions are likely stuck in a Publishing Wait state.
* Because you had replication_num = 1 and some nodes are DEAD, the FE is sending RPC requests to backends to "Publish" the data.
* Since the backend is dead, the FE waits for a network timeout (often several minutes) before retrying or giving up.
* The Problem: Even though you dropped the partition, the Transaction Manager in the FE still thinks it needs to "finish" the lifecycle of that transaction.
4. Immediate Cleanup (The "Flush")
If the transactions don't clear after a few minutes:
1. Drop Dead Backends: If you haven't already, run SHOW BACKENDS; and ALTER SYSTEM DROP BACKEND "ip:port"; for the dead nodes. This forces the FE to immediately fail any RPCs going to those nodes.
2. Wait for `TimeoutMs`: Every transaction has a timeout (default is 5 minutes for many loads). You can see the remaining time in SHOW TRANSACTION WHERE ID = .... Once that time hits 0, the FE will move them from running to aborted.
Summary
The 67 transactions are essentially "orphans." They are trying to talk to tablets and nodes that no longer exist. They will not apply (they cannot, the target is gone), but they must timeout or be manually canceled by Label before the "running" count hits 0.
Next Step: Run SHOW TRANSACTION WHERE ID = <one_of_the_67_ids>; to find out what label is generating them, then use CANCEL LOAD on that label.
References
• administration/management/compaction.md
• loading/Stream_Load_transaction_interface.md
• loading/SQL_transaction.md
• sql-reference/sql-statements/loading_unloading/SHOW_TRANSACTION.md
• administration/Data_recovery.md
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_CANCEL_REPAIR.mdMinn Fong
05/13/2026, 5:55 PMcancel load where label = "merge_commit_019e2252-374b-7801-b2d2-01c7fb10527b";Rocky
05/13/2026, 5:55 PMLoad job does not exist occurs because the Merge Commit feature uses internal Stream Load transactions. In StarRocks, CANCEL LOAD only works for "Load Jobs" (like Broker Load or Spark Load) that are managed by the FE Load Manager. Stream Load transactions are managed by the Transaction Manager and do not appear as "Load Jobs."
Since you have already dropped the partitions, these transactions are effectively "orphaned"—they are trying to write to data structures that no longer exist. They will not "Apply" (become visible) because their target is gone.
How to Clear the 67 Transactions
Option 1: Manual Rollback (The Fast Way)
For Stream Load transactions, you must use the HTTP API to roll them back by their label. Execute this from your terminal (not MySQL):
bash
curl --location-trusted -u <username>:<password> \
-H "label:merge_commit_019e2252-374b-7801-b2d2-01c7fb10527b" \
-H "db:requests" \
-XPOST http://<FE_IP>:<FE_HTTP_PORT>/api/transaction/rollback
(Repeat for the most recent labels or the ones blocking the queue. If you have many, you may need a small script to loop through the labels from your SHOW PROC output.)
Option 2: Verify Status and Wait for Timeout
If the transactions are in the COMMITTED state (waiting to be published), they cannot be rolled back; they must finish or timeout.
1. Check the specific status:
sql
-- Find the TxnId from your SHOW PROC output
SHOW TRANSACTION WHERE id = 12345;
2. Check the TimeoutMs and State.
• If State is PREPARED, they will eventually timeout and move to ABORTED.
• If State is COMMITTED, the FE is currently retrying the "Publish" phase. Since you dropped the partitions, the FE will eventually realize the tablets are missing and fail the transaction.
Why "Transactions are not applying"
In StarRocks, the sequence is: RUNNING -> COMMITTED -> VISIBLE.
"Applying" (Publishing) happens after COMMITTED. It requires a response from the Backends. If you have Dead Backends in your cluster, the FE will hang for several minutes per transaction trying to talk to them before giving up.
To speed up the "Cleaning" process:
If you haven't already, Drop the Dead Backends. This forces the FE to immediately fail any RPC calls to those nodes instead of waiting for a network timeout:
sql
SHOW BACKENDS; -- Find the IP:HeartbeatPort of nodes where Alive=false
ALTER SYSTEM DROP BACKEND "10.0.0.x:9050";
Recommendation
1. Stop the Source: If you have a Flink job or ingestion script running, stop it now. It is likely still trying to send "Merge Commit" requests, which is why the count stays high.
2. Clear Dead Nodes: Drop the backends as shown above.
3. Wait 5-10 Minutes: Once the source is stopped and dead nodes are dropped, the transaction queue will clear automatically as they hit their internal timeouts.
References
• loading/Stream_Load_transaction_interface.md
• sql-reference/sql-statements/loading_unloading/SHOW_TRANSACTION.md
• sql-reference/sql-statements/loading_unloading/CANCEL_LOAD.md
• administration/management/monitoring/metrics.md
• loading/Flink-connector-starrocks.md
• sql-reference/sql-statements/cluster-management/backend/ALTER_SYSTEM_DROP_BACKEND.md
References
• loading/SQL_transaction.mdRocky
05/13/2026, 5:55 PMMinn Fong
05/13/2026, 6:02 PMRocky
05/13/2026, 6:02 PMsql
-- 1. Reduce the time FE waits for replicas to report "Success" (Default is 30s)
ADMIN SET FRONTEND CONFIG ("publish_version_timeout_second" = "10");
-- 2. Reduce the time FE tolerates a "straggler" or slow replica (Default is 300s)
ADMIN SET FRONTEND CONFIG ("load_straggler_wait_second" = "10");
2. Why this helps
When you drop a partition or a node, the FE doesn't always know immediately that the target is gone for active transactions. It keeps retrying the "Publish Version" RPC call. By lowering these values:
* The FE will stop retrying the dead nodes/partitions almost immediately.
* Transactions will move from RUNNING or COMMITTED to ABORTED or VISIBLE (with partial failure) much faster.
* The transaction "slots" (default 100 per database) will be freed up for new data.
3. Important: Check for "PREPARED" transactions
If you are using the Flink Connector or Stream Load Transaction Interface, some transactions might be in a PREPARED state. These have a much longer default timeout:
* Parameter: prepared_transaction_default_timeout_second
* Default: 86400 (24 hours).
If your SHOW PROC '/transactions/...' shows transactions in the PREPARED state, you should also temporarily lower this:
sql
ADMIN SET FRONTEND CONFIG ("prepared_transaction_default_timeout_second" = "60");
4. Summary Checklist to clear the 67 txns:
1. Stop the Ingestion Source: Ensure your Flink job or load script is stopped, or it will just keep creating new transactions.
2. Drop Dead Backends: Run SHOW BACKENDS; and if any are Alive: false, run ALTER SYSTEM DROP BACKEND "IP:PORT";.
3. Apply the Configs: Run the ADMIN SET FRONTEND CONFIG commands above.
4. Wait 1-2 Minutes: The backlog should flush.
5. Revert: Once the queue is 0, reset the configurations to their defaults to prevent healthy, large loads from failing prematurely in the future.
References
• administration/management/FE_configuration.md
• loading/Stream_Load_transaction_interface.md
• sql-reference/sql-statements/loading_unloading/SHOW_TRANSACTION.md
• faq/loading/Loading_faq.md
References
• administration/management/FE_configuration.md
• administration/management/BE_configuration.mdMinn Fong
05/13/2026, 6:04 PMRocky
05/13/2026, 6:04 PMretry_apply_timeout_second
* Default: 7200 (which is exactly 2 hours).
* What it does: This controls the maximum cumulative time a Backend will retry applying a "pending version" (the final phase of a transaction) before it gives up.
* Why it's clogging your backlog: When you have dead nodes or dropped partitions, the BEs are stuck in a retry loop for up to 2 hours trying to finish the "Apply" phase. While these transactions are in this state, they remain in the FE's transaction manager, consuming slots and appearing in your SHOW PROC list.
──────────
How to fix it
You can drastically lower this value on your Backends to force them to fail the stuck transactions faster.
1. Lower the timeout on all BEs
Since this is a BE configuration, you must set it for the backends. You can do this dynamically without a restart:
sql
-- Set it to 60 seconds (1 minute) instead of 7200 (2 hours)
ADMIN SET BACKEND CONFIG ("retry_apply_timeout_second" = "60");
Note: If you have multiple BEs, ensure you apply this to all of them.
2. Verify other 1-2 hour defaults
While retry_apply_timeout_second is the most likely culprit for "Applying" hangs, check these if the queue still doesn't clear:
* stream_load_default_timeout_second: (FE config) Default is often 3600 (1 hour) or higher in some versions.
* insert_load_default_timeout_second: (FE config) Default is 3600 (1 hour).
Summary Recommendation
Run this to flush the backlog:
1. ADMIN SET BACKEND CONFIG ("retry_apply_timeout_second" = "10"); (Flushes the 2-hour retry loop)
2. ADMIN SET FRONTEND CONFIG ("publish_version_timeout_second" = "10"); (Flushes the FE's wait time)
Once the 67 transactions are cleared and your SHOW PROC is empty, reset these to their defaults (7200 for BE, 30 for FE) to ensure future healthy loads aren't killed too quickly killed by transient network blips.
References
• administration/management/BE_configuration.md
• administration/management/FE_configuration.md
• loading/Stream_Load_transaction_interface.md
• sql-reference/sql-statements/loading_unloading/SHOW_TRANSACTION.md
References
• administration/management/FE_configuration.mdMinn Fong
05/13/2026, 6:10 PMSTARROCKS-CORE-SERVICES-FE-1 23.23.32.26 // (172.30.75.62) ~ 7 $ curl --location-trusted -u root: -H "label:merge_commit_019e2252-374b-7801-b2d2-01c7fb10527b" -H "db:requests" -XPOST <http://172.30.75.62:8030/api/transaction/rollback>
{
"Status": "FAILED",
"Message": "class com.starrocks.common.StarRocksException: Can not abort COMMITTED transaction 3128001, label is merge_commit_019e2252-374b-7801-b2d2-01c7fb10527b"
}Rocky
05/13/2026, 6:10 PMCan not abort COMMITTED transaction occurs because a transaction in the COMMITTED state has already passed the "point of no return" for manual rollback.
In StarRocks, the lifecycle is:
RUNNING $\rightarrow$ PREPARED $\rightarrow$ COMMITTED $\rightarrow$ VISIBLE.
* COMMITTED means the data has been successfully written to the Backend (BE) storage nodes.
* The system is now in the Publish Version phase (trying to make the data visible to queries).
* Because the data is already "on disk" (or in memory awaiting a final version tag), the system does not allow a manual rollback or cancel.
Why they are stuck
Since you dropped the partitions, the target tablets for these transactions no longer exist. The FE (Front End) is stuck in a loop trying to "Publish" a version to tablets that have been deleted.
How to force them to clear
Since you cannot manually abort them, you must force the system's internal retry logic to "give up" faster.
1. Lower the Backend Retry Limit (The 2-hour culprit)
The 2-hour delay you are experiencing is governed by the BE configuration retry_apply_timeout_second (default 7200s). You must lower this on the Backends to force them to stop trying to apply the version to the deleted tablets:
sql
-- Run this to force BEs to give up on the 'Apply' phase after 10 seconds
ADMIN SET BACKEND CONFIG ("retry_apply_timeout_second" = "10");
2. Lower the Frontend Publish Timeout
The FE will wait for the BEs to report success. Lower this so the FE marks the publish as failed sooner:
sql
-- Run this to force FE to stop waiting for the BEs after 10 seconds
ADMIN SET FRONTEND CONFIG ("publish_version_timeout_second" = "10");
What will happen next?
Once these timeouts are applied:
1. The BEs will stop retrying the "Apply" for the deleted tablets.
2. The FE will receive a failure report (or time out itself).
3. The transactions will eventually move from COMMITTED to ABORTED (or disappear) because the underlying storage structures (the partitions) are missing.
4. Your transaction backlog (the 67 jobs) will clear, freeing up the slots.
Important: After the backlog is cleared (check with SHOW PROC '/transactions'), revert these settings to their defaults to ensure that future healthy loads don't fail during normal high-load periods:
* ADMIN SET BACKEND CONFIG ("retry_apply_timeout_second" = "7200");
* ADMIN SET FRONTEND CONFIG ("publish_version_timeout_second" = "30");
References
• loading/Stream_Load_transaction_interface.md
• administration/management/BE_configuration.md
• administration/management/FE_configuration.md
• sql-reference/sql-statements/loading_unloading/SHOW_TRANSACTION.md
References
• sql-reference/System_variable.md
• knowledge/trouble_shooting/fe_deadlock_problems.mdMinn Fong
05/13/2026, 6:14 PMRocky
05/13/2026, 6:14 PMADMIN SQL command. BE configurations must be updated via a curl command to the BE's HTTP port (default 8040).
To clear the 2-hour retry window, run this on every BE node:
bash
# Update the retry timeout to 10 seconds
curl -XPOST http://<be_ip>:8040/api/update_config?retry_apply_timeout_second=10
# Optional: Force the BE to stop retrying immediately
curl -XPOST http://<be_ip>:8040/api/update_config?enable_retry_apply=false
_Note: Replace <be_ip> with your Backend IP address._
──────────
2. Fix for "Config 'publish_version_timeout_second' does not exist..."
The variable name or mutability varies by StarRocks version. In some versions, this is an internal setting that cannot be changed via SQL.
To find the correct name for your version, run:
sql
ADMIN SHOW FRONTEND CONFIG LIKE '%publish%';
Look for IsMutable: true. If you find a similar name like transaction_publish_timeout_second, use that. If none are mutable, you will have to rely on the BE fix above to clear the backlog.
──────────
3. Why rollback failed for COMMITTED
You cannot manually rollback a transaction once it reaches the COMMITTED state.
* RUNNING/PREPARED: Can be aborted.
* COMMITTED: The data is already written to the BEs. The FE is now simply waiting for the BEs to report that they have "Applied" the version (made it visible).
Because you dropped the partitions, the BEs are searching for tablets that no longer exist and retrying for the default 2 hours (retry_apply_timeout_second).
Final Strategy to Clear the 67 Transactions:
1. Set BE Retry Timeout to 10s (via curl above) on all BEs.
2. Wait ~1 minute. The BEs will give up on the "Apply" phase for the deleted partitions.
3. The transactions will fail their "Publish" step and move out of the COMMITTED state (becoming ABORTED or failing with an error).
4. Crucial: Once the backlog is clear, revert the BE config to avoid failing healthy future loads:
bash
curl -XPOST http://<be_ip>:8040/api/update_config?retry_apply_timeout_second=7200
curl -XPOST http://<be_ip>:8040/api/update_config?enable_retry_apply=true
References
• administration/management/BE_configuration.md
• administration/management/FE_configuration.md
• sql-reference/sql-statements/cluster-management/config_vars/ADMIN_SET_CONFIG.md
• loading/Stream_Load_transaction_interface.md
References
• administration/management/BE_configuration.md
• administration/management/FE_configuration.md
• sql-reference/System_variable.md
• loading/Flink-connector-starrocks.mdMinn Fong
05/13/2026, 6:21 PMRocky
05/13/2026, 6:21 PMstorage_root_path configuration in be.conf.
* Parallel Compaction: StarRocks performs background data compaction. By default, it limits compaction concurrency per disk (controlled by pindex_major_compaction_limit_per_disk, default is 1). With 8 disks, you can run 8 compaction tasks in parallel without them competing for the same disk's I/O queue.
* Parallel Scans: During queries, StarRocks can read from multiple disks simultaneously, significantly increasing the effective throughput.
2. Matching CPU to I/O
With 32 vCPUs, your node has plenty of processing power to handle the overhead of 8 disks. StarRocks is a compute-intensive engine; a common bottleneck is having too much I/O wait because the CPU is waiting for a single slow disk. Spreading the load across 8 EBS volumes helps ensure the 32 vCPUs stay busy processing data rather than waiting on storage.
3. EBS Throughput Optimization (The "GP3" Strategy)
If you are using gp3 volumes, each volume has a baseline performance of 3,000 IOPS and 125 MB/s.
* 8 volumes $\times$ 125 MB/s = 1,000 MB/s total throughput.
* This is often cheaper than provisioned throughput on a single large volume and provides a much higher performance floor.
4. Configuration Best Practices
* Don't use RAID: You do not need to RAID these 8 volumes at the OS level. Instead, list them all in your `be.conf`:
bash
storage_root_path = /data1;/data2;/data3;/data4;/data5;/data6;/data7;/data8
StarRocks will manage the data distribution across these paths automatically.
* Check Instance Limits: Ensure your EC2 instance type can actually handle the combined throughput of 8 EBS volumes. A 32-vCPU instance (like an m6i.8xlarge) usually has an EBS-optimized bandwidth of around 10,000 Mbps to 12,500 Mbps (~1,250–1,500 MB/s). 8 volumes are well within this limit.
* Filesystem: Use XFS for all 8 volumes, as it generally performs better than ext4 for StarRocks workloads.
* Disk Failure Handling: Set ignore_broken_disk = true in be.conf. This allows the BE to stay online and serve data from the remaining 7 disks even if one EBS volume fails or becomes detached.
Summary
8 EBS volumes for a 32-vCPU node is a "sweet spot" for many production workloads, balancing cost, I/O performance, and reliability.
References
• administration/management/BE_configuration.md
• deployment/plan_cluster.md
• faq/Deploy_faq.md
• deployment/environment_configurations.md
References
• deployment/plan_cluster.md
• faq/Others.md
• administration/management/monitoring/Monitor_and_Alert.md
• faq/Deploy_faq.mdMinn Fong
05/13/2026, 6:25 PMRocky
05/13/2026, 6:25 PMwrite_quorum acknowledges the data.
2. Is replication_num = 2 possible?
Yes, it is possible, but it is strongly discouraged for production for the following reasons:
* Quorum Math: By default, StarRocks uses write_quorum = "MAJORITY". For 2 replicas, the majority is 2.
* This means if one BE node goes down, your write operations (Stream Load, INSERT, etc.) will fail because the system cannot reach a majority.
* Effectively, a 2-replica setup with a majority quorum has the same write availability as a 1-replica setup but uses twice the storage.
* Split Brain Risk: If you were to set write_quorum = "ONE" to allow writes when one node is down, you risk data inconsistency during network partitions.
* Standard Recommendation: For high availability where you can survive one node failure and still perform writes, you should use replication_num = 3 (where the majority is 2).
Summary Table
Replication Count | Majority Quorum | Can survive 1 node failure?
1 | 1 | No
2 | 2 | No (Writes will fail)
3 (Recommended) | 2 | Yes (Writes still succeed)
How to set it (if you must)
If you are in a testing environment and want to use 2 replicas, you can specify it in your table properties:
sql
CREATE TABLE my_pk_table (
id BIGINT NOT NULL,
data VARCHAR(65533)
) ENGINE=OLAP
PRIMARY KEY(id)
DISTRIBUTED BY HASH(id)
PROPERTIES (
"replication_num" = "2"
);
_Note: You must have at least 2 BE nodes in your cluster to use replication_num = 2 2._
References
• administration/management/resource_management/Replica.md
• introduction/Architecture.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE.md
References
• administration/management/resource_management/Replica.md
• table_design/table_types/primary_key_table.mdMinn Fong
05/13/2026, 6:29 PMRocky
05/13/2026, 6:30 PMMAJORITY): For 2 replicas, the majority is 2. This means every INSERT or Stream Load must successfully write to both BE nodes before the transaction is marked as VISIBLE.
* No Partial Writes: If one node is down or fails during the write, the transaction will fail. This prevents "version divergence" where one node has the data and the other doesn't.
* Consistency: Because both nodes must acknowledge the write, you won't encounter a "version error" caused by replicas being out of sync during normal operation.
2. The "Version Error" Risk
While you won't get data corruption, you are significantly more likely to see publish version timeout errors.
* In a 3-replica setup, if one BE is struggling (high CPU/IO), the FE can "Publish" the version to the other 2 and consider the job done.
* In a 2-replica setup, the FE must wait for both. if one BE is slow or has a momentary network blip, your entire loading pipeline stops until that specific BE recovers.
3. The Recovery Danger Zone
The real risk to data integrity with replication_num = 2 happens during recovery:
1. Node A goes down. Writes are now blocked.
2. You are tempted to change write_quorum to ONE to get your business moving again.
3. Now you have a "Version Gap." Node B has Version 100, but Node A (which is down) only has Version 90.
4. Node A comes back. If StarRocks attempts to serve a query from Node A before it has finished "catching up" (cloning), and there is a bug or configuration error, that is where "version errors" or inconsistent query results occur.
Summary: Is it "Acceptable"?
* For Development/Staging: Yes. It saves 33% storage and ensures that if you see "Success," the data is on both disks.
* For Production: No. The risk isn't just "writes failing." The risk is that you will eventually be forced to make a manual intervention (like dropping a replica or forcing a quorum) during an outage, which is the #1 cause of actual data corruption and metadata version errors.
Recommendation: If you have the vCPU and EBS bandwidth (as you mentioned earlier with the 8 EBS volumes), use replication_num = 3. The "cost" is only disk space; the stability gain for the "Publish Version" process is massive.
References
• administration/management/resource_management/Replica.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE.md
• administration/management/FE_configuration.md
• introduction/Architecture.md
References
• administration/Meta_recovery.md
• administration/management/resource_management/Replica.mdMinn Fong
05/13/2026, 6:31 PMRocky
05/13/2026, 6:32 PMreplication_num = 2 and write_quorum = MAJORITY, the system will maintain version consistency because it will simply refuse to commit any new data unless both replicas acknowledge it. In this state, the version counts stay in sync.
However, the "issue" isn't about data corruption; it's about cluster stability and disaster recovery. Here is why replication_num = 2 is risky in practice:
1. Zero Write-Availability
In production, a single BE node going down (for a reboot, a kernel panic, or a network blip) is common.
* With 2 replicas: Your entire data ingestion pipeline stops immediately.
* With 3 replicas: If one node goes down, the other two (the majority) continue to accept writes. Your business stays online while you fix the third node.
2. High Risk of Permanent Data Loss
With 2 replicas, you are always one disk failure away from a "Single Point of Failure":
* If Node A is down for maintenance, you only have one copy of your data left (on Node B).
* If Node B’s EBS volume has an unexpected failure during that window, your data is gone forever.
* In a 3-replica setup, even if one node is down, you still have two copies, providing a safety net against a second simultaneous failure.
3. Sensitivity to "Jitter" (Performance)
StarRocks must wait for the "Publish Version" step to complete on both nodes before a load is considered successful.
* If you have 2 replicas and one node experiences a "Stop the World" GC pause or an EBS I/O spike, your load will hang or timeout because there is no "spare" replica to fulfill the quorum.
* This leads to frequent publish version timeout or close load manager failed errors, making your ingestion pipeline brittle.
4. The "Stale Replica" Recovery Loop
When the second node comes back online, it will be "stale" (it might have missed metadata updates or housekeeping tasks).
* The FE must now trigger a Clone task to catch the node up.
* During this clone, the node is under extra I/O and CPU load. In a 2-node scenario, this load is concentrated on your only healthy node (the source of the clone), potentially slowing down queries for your users.
Summary
While you are right that version consistency is preserved, you are essentially running a system that is fragile. Most users choose 3 replicas because the cost of the extra disk space is much lower than the cost of a production outage or the manual effort required to recover a cluster where a single node failure has frozen all data loading.
If you prioritize cost over availability: replication_num = 2 is technically consistent.
If you prioritize "Sleep at Night": Stick with replication_num = 3.
References
• administration/management/resource_management/Replica.md
• faq/operation_maintenance_faq.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE.md
• administration/management/FE_configuration.md
• introduction/Architecture.md
References
• administration/management/resource_management/Replica.md
• administration/management/FE_configuration.md
• faq/operation_maintenance_faq.md
• knowledge/usage/best-practice.mdMinn Fong
05/13/2026, 6:50 PMPROPERTIES (
"compression" = "LZ4",
"enable_persistent_index" = "true",
"fast_schema_evolution" = "true",
"labels.location" = "group:requests",
"partition_live_number" = "24",
"replicated_storage" = "true",
"replication_num" = "2"
);
And SHOW BACKENDS only has group:requests Location column on 6/8 BE nodes. Why are all my BE nodes still receiving wrtiesRocky
05/13/2026, 6:50 PMlabels.location.
1. Storage BEs vs. Coordinator BEs
The property "labels.location" = "group:requests" specifically controls where the data (tablets) is stored. It does not prevent the other 2 BE nodes from participating in the cluster as Coordinators.
* How it works: When you perform a write (like a Stream Load or an INSERT), your client or load balancer likely sends the request to any of the 8 BE IPs in the cluster.
* The Coordinator role: That BE acts as a "Coordinator." It receives the raw data, parses it, and then routes it over the internal network to the specific BEs that actually hold the replicas for that table.
* The Result: Even if a BE is not allowed to store data for your table, it will still show "write activity" in your metrics because it is processing the data before handing it off to the "Storage BEs."
2. Replicated Storage Behavior
You have "replicated_storage" = "true" enabled. This feature changes the data flow:
* Standard (false): The Coordinator sends data to all replicas (both nodes in your case) simultaneously.
* Replicated Storage (true): The Coordinator sends data to only one "Primary" replica. That Primary BE then takes responsibility for replicating the data to the "Secondary" replica.
Because the Coordinator can be any BE node, and the Primary replica must be one of the 6 nodes with the group:requests label, you are seeing traffic move through the cluster in a way that involves multiple nodes.
3. How to Verify if the Label is Working
To confirm that your data is actually restricted to the 6 nodes, check the Tablet Distribution rather than the write traffic:
1. Run SHOW BACKENDS;
2. Look at the TabletNum column for the 2 BEs that do not have the group:requests location.
3. If those nodes have 0 (or a significantly lower number if you have other tables), then the labels.location property is working correctly.
Summary of your Properties
* `labels.location`: Successfully restricts where the data sits on disk.
* `replicated_storage`: Optimizes the internal write path so only the primary replica receives the initial write from the coordinator.
* Why all 8 BEs are active: They are likely acting as entry points (Coordinators) for your load requests.
Pro-Tip: If you want to strictly isolate the write traffic, you should point your data loading tools (like Flink, Spark, or curl) only at the 6 BE IPs that have the group:requests label.
References
• administration/management/resource_management/be_label.md
• sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE.md
• faq/operation_maintenance_faq.md
• administration/management/resource_management/Replica.md
References
• administration/management/resource_management/be_label.md
• administration/management/resource_management/Replica.mdMinn Fong
05/13/2026, 6:51 PMRocky
05/13/2026, 6:51 PMTabletNum is 800+ on all nodes (including the 2 nodes without the label) suggests one of three things:
1. TabletNum is a Cluster-Wide Metric
The TabletNum column in SHOW BACKENDS shows the total count of all tablets stored on that BE, across all databases and tables.
* If you have other tables in your cluster that do not have the labels.location property set, their tablets will be distributed across all 8 nodes by default.
* To see if your specific table is respecting the label, you need to check the tablets for that table only:
sql
-- Check which BEs hold tablets for your specific table
SHOW TABLETS FROM your_table_name;
In the output, look at the BackendId column. If the label is working, you should only see IDs corresponding to the 6 labeled BEs.
2. Version Requirement (v3.2.8+)
The labels.location property for tablet placement is a relatively new feature introduced in StarRocks v3.2.8.
* If your StarRocks version is older than 3.2.8, the FE will allow you to set that property in the PROPERTIES block, but it will simply ignore it because it doesn't recognize it as a placement constraint.
* If you are on an older version, you would typically use replication_allocation (e.g., "replication_allocation" = "tag.location.group_requests: 2") alongside BE tags, which is a different mechanism.
3. Historical Data and Rebalancing
If you added the labels.location property to the table after it was already created and populated:
* StarRocks does not instantly delete tablets from the "wrong" nodes.
* It triggers a background process called the Tablet Scheduler to create new replicas on the labeled nodes and then decommission the ones on the unlabeled nodes.
* With 800+ tablets, this migration can take some time depending on your tablet_sched_slots_per_path configuration and disk I/O.
4. System/Internal Tables
StarRocks has internal system tables (like _statistics_) that are managed by the FE and usually distributed across all available BEs to ensure metadata high availability. These tablets will contribute to the TabletNum on every node.
How to verify for sure:
Run this query to see exactly which tables have tablets on your "unlabeled" nodes:
sql
SELECT
db_name,
table_name,
COUNT(tablet_id) AS tablet_count
FROM information_schema.be_tablets
WHERE be_id = <ID_OF_UNLABELED_NODE>
GROUP BY db_name, table_name;
_(Note: information_schema.be_tablets is available in newer versions. If it's not available, use SHOW TABLETS FROM table_name for your specific table.)_
Summary: Your labels.location property likely is working for that specific table, but you are seeing tablets from other tables or system processes on those 2 nodes. If your specific table's tablets are still on those 2 nodes after several hours, check your StarRocks version.
References
• administration/management/resource_management/be_label.md
• sql-reference/information_schema/be_tablets.md
• administration/management/resource_management/Replica.md
• faq/operation_maintenance_faq.md
References
• administration/management/resource_management/be_label.md
• sql-reference/information_schema/be_tablets.md
• administration/management/resource_management/Replica.mdMinn Fong
05/13/2026, 6:54 PMPROPERTIES (
"compression" = "LZ4",
"enable_persistent_index" = "true",
"fast_schema_evolution" = "true",
"labels.location" = "group:requests",
"partition_live_number" = "24",
"replicated_storage" = "true",
"replication_num" = "2"
);
BackendId,IP,HeartbeatPort,BePort,HttpPort,BrpcPort,LastStartTime,LastHeartbeat,Alive,SystemDecommissioned,ClusterDecommissioned,TabletNum,DataUsedCapacity,AvailCapacity,TotalCapacity,UsedPct,MaxDiskUsedPct,ErrMsg,Version,Status,DataTotalCapacity,DataUsedPct,CpuCores,MemLimit,NumRunningQueries,MemUsedPct,CpuUsedPct,DataCacheMetrics,Location,StatusCode
203701,172.30.65.182,9050,9060,8040,8060,2026-05-07 18:24:09,2026-05-13 18:54:24,true,false,false,873,9.191 GB,3.807 TB,4.802 TB,20.72 %,26.36 %,"",4.0.7-b75f536,"{""lastSuccessReportTabletsTime"":""2026-05-13 18:54:14""}",3.816 TB,0.24 %,32,211.808GB,2,26.71 %,13.0 %,"Status: Normal, DiskUsage: 0B/680GB, MemUsage: 42.3GB/42.3GB","",OK
171908,172.30.65.224,9050,9060,8040,8060,2026-05-07 18:52:35,2026-05-13 18:54:24,true,false,false,887,8.413 GB,4.004 TB,4.802 TB,16.62 %,18.04 %,"",4.0.7-b75f536,"{""lastSuccessReportTabletsTime"":""2026-05-13 18:53:41""}",4.012 TB,0.20 %,32,211.808GB,3,28.23 %,10.5 %,"Status: Normal, DiskUsage: 0B/780GB, MemUsage: 42.3GB/42.3GB",group:requests,OK
110783,172.30.68.175,9050,9060,8040,8060,2026-05-07 18:52:20,2026-05-13 18:54:24,true,false,false,870,7.833 GB,2.726 TB,4.802 TB,43.22 %,44.53 %,"",4.0.7-b75f536,"{""lastSuccessReportTabletsTime"":""2026-05-13 18:53:56""}",2.734 TB,0.28 %,32,211.808GB,3,28.19 %,10.3 %,"Status: Normal, DiskUsage: 0B/1TB, MemUsage: 42.3GB/42.3GB",group:requests,OK
95876,172.30.75.179,9050,9060,8040,8060,2026-05-07 18:52:35,2026-05-13 18:54:24,true,false,false,884,8.704 GB,2.654 TB,4.802 TB,44.74 %,45.17 %,"",4.0.7-b75f536,"{""lastSuccessReportTabletsTime"":""2026-05-13 18:53:41""}",2.662 TB,0.32 %,32,211.808GB,2,29.47 %,13.8 %,"Status: Normal, DiskUsage: 0B/990GB, MemUsage: 42.3GB/42.3GB",group:requests,OK
203697,172.30.77.163,9050,9060,8040,8060,2026-05-07 18:52:25,2026-05-13 18:54:24,true,false,false,877,7.804 GB,2.623 TB,4.802 TB,45.37 %,46.87 %,"",4.0.7-b75f536,"{""lastSuccessReportTabletsTime"":""2026-05-13 18:53:59""}",2.631 TB,0.29 %,32,211.808GB,3,29.13 %,14.1 %,"Status: Normal, DiskUsage: 0B/970GB, MemUsage: 42.3GB/42.3GB",group:requests,OK
203699,172.30.78.249,9050,9060,8040,8060,2026-05-07 18:52:25,2026-05-13 18:54:24,true,false,false,875,7.840 GB,2.813 TB,4.802 TB,41.42 %,41.94 %,"",4.0.7-b75f536,"{""lastSuccessReportTabletsTime"":""2026-05-13 18:54:24""}",2.821 TB,0.27 %,32,211.808GB,3,29.67 %,19.2 %,"Status: Normal, DiskUsage: 0B/1TB, MemUsage: 42.3GB/42.3GB",group:requests,OK
203700,172.30.81.176,9050,9060,8040,8060,2026-05-07 18:52:25,2026-05-13 18:54:24,true,false,false,874,7.878 GB,3.899 TB,4.802 TB,18.80 %,20.73 %,"",4.0.7-b75f536,"{""lastSuccessReportTabletsTime"":""2026-05-13 18:53:26""}",3.907 TB,0.20 %,32,211.808GB,4,29.54 %,11.2 %,"Status: Normal, DiskUsage: 0B/1020GB, MemUsage: 42.3GB/42.3GB","",OK
11001,172.30.87.186,9050,9060,8040,8060,2026-05-07 18:52:30,2026-05-13 18:54:24,true,false,false,875,8.382 GB,2.836 TB,4.802 TB,40.95 %,41.55 %,"",4.0.7-b75f536,"{""lastSuccessReportTabletsTime"":""2026-05-13 18:53:41""}",2.844 TB,0.29 %,32,211.808GB,2,28.42 %,8.7 %,"Status: Normal, DiskUsage: 0B/1TB, MemUsage: 42.3GB/42.3GB",group:requests,OK
however, show tablets from requests (my table name) still has backendid 203701 as one of the tabletsRocky
05/13/2026, 6:55 PM203701 despite the "labels.location" = "group:requests" property is likely due to the Tablet Migration Delay or a Re-enforcement Requirement.
In StarRocks (specifically since v3.2.8+), the labels.location property is a "hard" placement constraint, but it does not cause an instantaneous move of existing data. Here is why you are still seeing tablets on the unlabeled node:
1. Historical Data doesn't move automatically
If the table was created before you added labels to the BEs, or if you added the labels to the BEs after the table already had data, the StarRocks Tablet Scheduler does not immediately evict tablets from "wrong" nodes.
* The Fix: Even if the property already shows up in your table definition, you should "kick" the scheduler by re-applying the property. Run this command:
sql
ALTER TABLE requests SET ("labels.location" = "group:requests");
This forces the FE to re-evaluate the placement of every tablet in that table against the current BE labels.
2. Migration takes time (Check the Scheduler)
After you run the ALTER or if the system has recognized the mismatch, it must create a new replica on one of the 6 labeled nodes, wait for it to sync, and only then delete the replica on node 203701.
* With 870+ tablets on that node, this can take a while depending on your disk I/O and network.
* How to check status:
sql
SHOW PROC '/cluster_balance/tablet_scheduler';
Look for Pending, Running, or Finished tasks. If you see many "Clone" tasks, the system is actively moving your table data to the correct nodes.
3. Check for Colocation Groups
Is your table part of a Colocation Group? (Check for colocate_with in your SHOW CREATE TABLE output).
* Colocated tables use a separate balancer called the ColocateTableBalancer.
* In some versions, Colocation balancing rules may conflict with or take precedence over labels.location constraints. If your table is colocated, the FE might be struggling to find a distribution that satisfies both the colocation rule and the label rule.
4. TabletNum vs. Specific Table Tablets
As mentioned earlier, TabletNum in SHOW BACKENDS is a cluster-wide total. Since all your BEs have ~870 tablets, it indicates that either:
1. All your tables in the cluster are ignoring the label.
2. You have many other tables (or internal _statistics_ tables) that do not have any location labels set, so they are filling up all nodes equally.
Next Steps to Resolve:
1. Verify only this table is affected: Run SHOW TABLETS FROM requests and look at the BackendId column. If you see IDs other than the 6 labeled ones, then the migration is definitely pending or blocked.
2. Trigger the move: Run the ALTER TABLE ... SET ("labels.location" = ...) command mentioned above.
3. Check for errors: Look at the FE leader's fe.log for any "tablet scheduler" errors. If the labeled nodes are too full (check DataUsedPct), the scheduler might refuse to move data there to prevent a disk-full event.
References
• administration/management/resource_management/be_label.md
• administration/management/resource_management/Replica.md
• using_starrocks/Colocate_join.md
• sql-reference/sql-statements/table_bucket_part_index/ALTER_TABLE.md
• faq/operation_maintenance_faq.md
References
• administration/management/FE_configuration.mdRocky
05/13/2026, 6:55 PMMinn Fong
05/13/2026, 6:56 PMRocky
05/13/2026, 6:57 PM203701) that lacks the group:requests label, there are three likely reasons for this behavior:
1. The "Colocation Group" Override
If your table creation included a colocate_with property (even if not shown in your snippet), or if StarRocks automatically assigned it to a group, the Colocate Balancer takes precedence over the labels.location property.
* Why it happens: Colocation groups ensure that related tables have tablets on the exact same set of BEs to optimize joins. If that group was already established across all 8 nodes, your new table's tablets will follow the group's distribution regardless of the label.
* How to check: Run SHOW CREATE TABLE requests;. Look for a property called "colocate_with". If it exists, the label restriction will be ignored until the group itself is modified.
2. FE Metadata/Heartbeat Latency
If you applied the labels to the BE nodes (ALTER SYSTEM MODIFY BACKEND ...) immediately before creating the table, there is a chance the Frontend (FE) had not yet processed the updated heartbeat from node 203701.
* Why it happens: The FE maintains a cache of backend metadata. If the FE still thought node 203701 had the label (or if it hadn't yet registered the other nodes as having it) at the exact millisecond of table creation, it might have placed the tablets incorrectly.
* The Fix: Run a manual "kick" to force the FE to re-evaluate the placement:
sql
ALTER TABLE requests SET ("labels.location" = "group:requests");
Even though the property is already there, re-applying it triggers the Tablet Scheduler to move any "misplaced" tablets to the correct nodes.
3. "Primary-Secondary" placement with Replicated Storage
You have "replicated_storage" = "true". This property is specifically used for Primary Key tables to optimize writes by only sending data to one replica, which then replicates it to others.
* In some edge cases (or specific dev versions like the v4.0.7 you are running), the initial placement algorithm for replicated_storage may have a bug where it honors labels for the "Primary" replica but falls back to a global random selection for the "Secondary" replica.
* Verification: Run SHOW TABLETS FROM requests; and look at the IsBad or State columns. If the tablet on 203701 is NORMAL, then the FE intentionally put it there. If it is DECOMMISSION, the system is already trying to move it.
4. Check for Tablet Migration in Progress
Since the table is brand new, it might have been created during a period where the FE was still "learning" the labels.
Check if the system is currently moving those tablets:
sql
SHOW PROC '/cluster_balance/tablet_scheduler';
Look for any tasks where the DestBeId belongs to one of your 6 labeled nodes and the SrcBeId is 203701.
Summary & Recommendation
The labels.location feature (introduced in v3.2.8) is a hard constraint. The fact that SHOW TABLETS shows data on node 203701 means the FE specifically chose that node.
1. Check Colocation: Ensure the table isn't tied to a colocate_with group.
2. Force Re-check: Run the ALTER TABLE ... SET ("labels.location" = "group:requests"); command.
3. Monitor Scheduler: Wait 5-10 minutes to see if the TabletNum on 203701 drops and the tablets move to the labeled nodes.
If the tablets persist on 203701 after the ALTER command, it is likely a bug related to the interaction between replicated_storage and labels.location in your specific StarRocks version.
References
• administration/management/resource_management/be_label.md
• using_starrocks/Colocate_join.mdRocky
05/13/2026, 6:57 PMMinn Fong
05/13/2026, 7:02 PMRocky
05/13/2026, 7:02 PM"labels.location" = "group:requests". The system should treat those nodes as excluded from that specific table's distribution.
If your tablets for a brand new table still exist on node 203701 (which has no label), there are three primary reasons why this is happening:
1. Colocation Group Inheritance (Most Common)
If your table creation script included a colocate_with property, or if StarRocks automatically assigned it to a colocation group, the Colocation Balancer takes priority over labels.location.
* Why: Colocation groups ensure that tablets for multiple tables are placed on the exact same set of BEs to enable efficient joins. If the colocation group was created across all nodes before you set the labels, the table will ignore the label property to maintain colocation.
* How to check:
sql
SHOW CREATE TABLE requests;
-- Look for "colocate_with" = "some_group_name"
If it exists, check the group distribution:
sql
SHOW PROC '/colocation_group';
2. "Insufficient Nodes" Fallback
StarRocks documentation notes that if the number of available BEs matching the label is fewer than the replication_num, it will fallback and place replicas on other nodes to ensure data safety.
* The Problem: You have 6 labeled nodes and replication_num = 2, so there are plenty of nodes. However, if the 6 labeled nodes were under high disk stress, high CPU, or had heartbeat issues at the exact moment the table was created, the FE may have panicked and used the unlabeled nodes to guarantee the 2 replicas were created.
* Verification: Check the ErrMsg or Alive status in SHOW BACKENDS for those 6 nodes around the time of table creation.
3. Interaction with replicated_storage
You have "replicated_storage" = "true". This is specifically for Primary Key tables to enable the "Single Leader Replication" (multi-raft) mode.
* In some versions (particularly v3.3+ and the v4.0.x you are using), the placement logic for Replicated Storage tablets involves a "Primary" and "Secondary" assignment.
* There is a known edge case where the "Secondary" replicas might be placed using the global default load balancer if the primary placement was satisfied, though this is usually considered a bug or a configuration mismatch.
How to Force the Move
Since the table is new, you can force the FE to re-calculate the placement and evict the tablets from node `203701`:
1. Re-apply the property:
sql
ALTER TABLE requests SET ("labels.location" = "group:requests");
Even if the property is already there, this command triggers the Tablet Scheduler to re-scan the table.
2. Monitor the migration:
sql
-- This will show you if the FE is moving tablets from 203701 to the correct nodes
SHOW PROC '/cluster_balance/tablet_scheduler';
Look for tasks where SrcBeId is 203701.
3. Check for "No Label" catch-all:
Ensure you don't have a cluster-wide FE configuration that relaxes placement. (Rare, but check admin_tablet_scheduler_check_interval_seconds to ensure the scheduler is running).
Summary: Your "no label" nodes should not be taking data for this table. If the ALTER TABLE command doesn't trigger a move within 5–10 minutes, check for a colocate_with property, as that is the only feature that strictly overrides location labels.
References
• administration/management/resource_management/be_label.md
• using_starrocks/Colocate_join.md
• administration/management/resource_management/Replica.mdRocky
05/13/2026, 7:02 PMMinn Fong
05/13/2026, 7:04 PMGroupId,GroupName,TableIds,TableNames,BucketsNum,ReplicationNum,DistCols,IsStable
44945.6511660,44945_requests,6540237*,[deleted],128,1,varchar(65533),true
I have colocation group but it is not associated with any non-deleted tables.
I already ensured my table schema has no colocation group. labels.location is group:requests and only 6/8 BE nodes have the label group:requests. Whbat is the issueRocky
05/13/2026, 7:04 PM203701 indicates that the StarRocks Tablet Scheduler either ignored the constraint during the initial creation or is currently in a "fallback" state.
Here are the specific reasons why this happens and how to resolve it:
1. The replicated_storage Initial Placement Bug
You have "replicated_storage" = "true". This enables the Single Leader Replication (multi-raft) protocol for Primary Key tables.
* The Issue: In some StarRocks versions (including v3.x and development builds like your v4.0.7), the initial placement logic for replicated_storage tablets sometimes honors the labels.location for the Primary replica but defaults to a global round-robin for the Secondary replicas to ensure high availability.
* The Fix: You must manually "kick" the scheduler to force it to comply with the label for all replicas:
sql
ALTER TABLE requests SET ("labels.location" = "group:requests");
Wait 2–5 minutes and check SHOW TABLETS FROM requests again. This command triggers a re-validation of every replica against the table's location constraints.
2. Disk Balance vs. Label Constraint
In your SHOW BACKENDS output:
* The labeled nodes (e.g., 110783, 95876) have a UsedPct of 41% - 45%.
* The unlabeled node (203701) is much emptier at 20%.
StarRocks tries to keep the cluster balanced. If the FE detects that the labeled group is significantly more "loaded" than the unlabeled group, and there isn't a strict configuration preventing it, the load balancer might "panic" and place new tablets on the emptier nodes to prevent the labeled nodes from hitting storage watermarks.
3. Check for FE Metadata Lag
If you added the labels to the Backends very recently (within minutes of creating the table), the Frontend leader might not have fully refreshed its internal "Node-to-Label" map.
* Check FE state: Run SHOW BACKENDS and ensure the Location column is exactly group:requests (case-sensitive) for all 6 nodes. If it shows as empty or different, the FE won't use them.
4. Verify "Implicit" Colocation
Even if you didn't specify a group, StarRocks sometimes creates an internal group if you have many tables with the same distribution.
* Run SHOW CREATE TABLE requests; and look for an ID or group name you didn't put there.
* If it is part of a group, the label property is ignored because the Colocation Balancer takes absolute priority over labels to ensure tablets of different tables stay together.
How to Diagnose & Fix
1. Check the Scheduler's mind:
sql
SHOW PROC '/cluster_balance/tablet_scheduler';
Look for any "Clone" tasks. If the system realized the mistake, it will be actively moving tablets off of 203701 and onto your 6 labeled nodes.
2. Verify Tablet Distribution:
Run this to see which Backend IDs currently hold your data:
sql
SHOW TABLETS FROM requests;
If the Backend IDs are exclusively 203701 and the other unlabeled node, then the label was completely ignored.
3. Force the migration (Recommended):
Run the ALTER TABLE command mentioned in step 1. This is the most effective way to force StarRocks to move tablets that were placed "outside" their designated label.
A note on your version (4.0.7-b75f536)
As this appears to be a future or internal build, there may be specific changes to the replicated_storage placement logic. If the ALTER TABLE command does not move the tablets within 10 minutes, it is likely a bug in the interaction between the label constraint and the primary-key replication protocol in that specific build.
References
• administration/management/resource_management/be_label.mdRocky
05/13/2026, 7:04 PMMinn Fong
05/13/2026, 7:17 PMRocky
05/13/2026, 7:17 PMlabels.location = "group:requests" property.
Why this is happening
1. Placement Mismatch: In StarRocks, "Unhealthy" doesn't always mean "data loss." It often means "Policy Violation." The FE has realized that a portion of your replicas are on nodes that do not have the required label.
2. Initial Distribution: Since the table was created across the whole cluster (possibly due to the replicated_storage placement logic or a delay in FE metadata refresh), 25% of your replicas ended up on the unlabeled nodes.
3. The Fix is Automatic (but slow): The system has already correctly identified them as "unhealthy" and is likely planning to move them to the 6 labeled nodes.
How to accelerate the fix
To force StarRocks to move these tablets immediately and clear the "unhealthy" status:
1. Re-trigger the policy check:
Run this command to tell the FE to re-evaluate the location of every tablet in the table:
sql
ALTER TABLE requests SET ("labels.location" = "group:requests");
2. Verify the migration tasks:
Check if the scheduler is actively creating "Clone" tasks to move data off the 2 unlabeled nodes:
sql
SHOW PROC '/cluster_balance/tablet_scheduler';
In the output, look for tasks where SrcBeId is 203701 (or the other unlabeled node).
3. Check the "Location Mismatch" count:
You can see the specific reason for unhealthiness here:
sql
SHOW PROC '/statistic';
-- Look for the 'ReplicaLocationMismatch' or 'Unhealthy' column for your database.
Summary
The 25% unhealthy status is actually *good news*—it means the StarRocks safety checker is working. It recognizes that the tablets on the 2 nodes without the group:requests label should not be there. Once the Tablet Scheduler moves those replicas to the 6 labeled nodes, the status will return to Healthy.
Note: If you are using replicated_storage (Primary Key table), ensure you are on a stable release (v3.2.11+ or v3.3.x), as there were known bugs in earlier versions regarding "label-aware" repairs for replicated storage.Minn Fong
05/13/2026, 7:32 PMRocky
05/13/2026, 7:32 PMtablet_scheduler is not a valid terminal path in StarRocks. The scheduler's tasks are split into three specific categories.
To see what the scheduler is doing with those "unhealthy" tablets, use these paths instead:
1. Check for Active Movement
To see the tablets currently being moved from the unlabeled nodes to the correct nodes:
sql
SHOW PROC '/cluster_balance/running_tablets';
To see tablets waiting in the queue to be moved:
sql
SHOW PROC '/cluster_balance/pending_tablets';
What to look for: Look at the Type and Status columns. You will likely see Type: REPAIR and Status: REPLICA_LOCATION_MISMATCH. This confirms the 25% unhealthy status is because StarRocks is trying to evict data from the unlabeled nodes.
2. Verify the Policy Violation
To see if the cluster explicitly recognizes the label mismatch as an unbalanced state:
sql
SHOW PROC '/cluster_balance/balance_stat';
In the results, look for the row where BalanceType is label-aware location.
* If Balanced is false, the system is aware that tablets are on the wrong nodes and is actively working to move them.
3. Identify Specific Unhealthy Tablets
To see exactly why the tablets are flagged, you can run:
sql
ADMIN SHOW REPLICA STATUS FROM requests WHERE STATUS != "OK";
This will likely return a status like REPLICA_LOCATION_MISMATCH for the replicas sitting on your two unlabeled backends.
Why exactly 25%?
As you deduced, the math is exact: 2 nodes out of 8 have no label. If your table was initially distributed across all nodes, the 25% of replicas residing on those 2 nodes are now "illegal" according to your labels.location property.
StarRocks marks them as "unhealthy" not because the data is corrupted, but because they violate the placement policy. The FE will now:
1. Create new replicas on the 6 labeled nodes.
2. Once the new replicas are healthy, delete the "illegal" ones on the unlabeled nodes.
Note: If the number of pending_tablets isn't decreasing, it may be because the 6 labeled nodes are too full or have reached their maximum "clone slots" (controlled by tablet_sched_max_scheduling_tablets in FE config).
References
• administration/management/resource_management/Replica.md
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• administration/management/resource_management/be_label.md
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_SHOW_REPLICA_STATUS.md
References
• sql-reference/sql-statements/cluster-management/nodes_processes/SHOW_PROC.md
• administration/management/resource_management/Replica.mdMinn Fong
05/13/2026, 7:34 PMStorageMedium,BalanceType,Balanced,PendingTablets,RunningTablets
HDD,inter-node disk usage,true,0,0
HDD,inter-node tablet distribution,true,0,0
HDD,intra-node disk usage,true,0,0
HDD,intra-node tablet distribution,true,0,0
HDD,colocation group,true,0,0
HDD,label-aware location,false,0,0
ADMIN SHOW REPLICA STATUS FROM requests WHERE STATUS != "OK"; => empty setRocky
05/13/2026, 7:34 PMADMIN SHOW REPLICA STATUS is empty while your global statistics show 25% unhealthy tablets confirms a specific state: your replicas are technically "functional" but "policically illegal."
Here is the breakdown of why this is happening and how to fix it:
1. "OK" Status vs. "Unhealthy" Statistic
* ADMIN SHOW REPLICA STATUS ... WHERE STATUS != 'OK': This checks for technical failures (e.g., the BE is dead, the disk is corrupted, or the data version is lagging). Since your output is empty, it means the replicas on the unlabeled nodes are alive and have the correct data.
* SHOW PROC '/statistic' (Unhealthy count): This counts any tablet that violates the cluster's defined policy. A Location Mismatch (a replica sitting on a node that doesn't match the labels.location property) is flagged as "Unhealthy" here even if the replica is "OK."
2. Why the Balancer is Idle (Balanced: false, Pending: 0)
The label-aware location balancer is aware of the mismatch but isn't creating tasks. This usually happens for one of three reasons:
* Low Priority/Throttling: The scheduler prioritizes "Dead" or "Missing" replicas over "Location Mismatches." If your FE is busy or the tablet_sched_max_scheduling_tablets limit is reached, it may skip these.
* Multi-Raft (Primary Key) Constraint: Since you are using replicated_storage (Primary Key), tablet migration is handled by the Multi-Raft protocol. In some versions, if the Primary replica is on a labeled node but Secondary replicas (if you have them) are not, the scheduler sometimes waits for a specific trigger.
* Single Replica Restriction: If your table has replication_num = 1, the scheduler is extremely conservative. It will not move the only copy of your data unless it is 100% certain the target node is ready.
3. The Fix: Force the Repair
Since the automatic balancer is not picking up the tasks, you need to manually "kick" the scheduler to prioritize these location mismatches.
Step 1: Force a re-evaluation
This command forces the FE to re-calculate the placement for every tablet in that table:
sql
ALTER TABLE requests SET ("labels.location" = "group:requests");
Step 2: Elevate repair priority
Tell the FE that this table needs immediate attention regardless of the global balancer state:
sql
ADMIN REPAIR TABLE requests;
Step 3: Check the specific mismatches
To see exactly which tablets are "illegal," use the database ID from SHOW PROC '/statistic' to drill down:
sql
SHOW PROC '/statistic/<db_id>';
This will give you a list of Tablet IDs. Pick one and run:
sql
SHOW TABLET <tablet_id>;
Look at the DetailCmd column. Running that command will show you exactly which Backend ID the tablet is on. You will likely see Backend IDs that correspond to your unlabeled nodes.
Summary
The 25% unhealthy rate is exactly the 2/8 nodes that are unlabeled. The replicas are functioning (hence STATUS = OK), but they are in the wrong place. Use ADMIN REPAIR TABLE to force the scheduler to move them to the labeled nodes. Once they move, the UnhealthyTabletNum in /statistic will drop to 0.
References
• administration/management/resource_management/be_label.md
• using_starrocks/Colocate_join.md
• administration/management/FE_configuration.mdMinn Fong
05/13/2026, 7:36 PMReplicaId,BackendId,Version,VersionHash,LstSuccessVersion,LstSuccessVersionHash,LstFailedVersion,LstFailedVersionHash,LstFailedTime,SchemaHash,DataSize,RowCount,State,IsBad,IsSetBadForce,VersionCount,PathHash,MetaUrl,CompactionStatus,IsErrorState
7475313,171908,109,0,109,0,-1,0,,1901059982,135900,1,NORMAL,false,false,2,5451311888450748204,<http://172.30.65.224:8040/api/meta/header/7475312,http://172.30.65.224:8040/api/compaction/show?tablet_id=7475312&schema_hash=1901059982,false>
7475314,203701,109,0,109,0,-1,0,,1901059982,135083,1,NORMAL,false,false,2,343659635488245780,<http://172.30.65.182:8040/api/meta/header/7475312,http://172.30.65.182:8040/api/compaction/show?tablet_id=7475312&schema_hash=1901059982,false>
Example output of detailcmd of the unhealthy tabletRocky
05/13/2026, 7:36 PMSHOW TABLET output:
* Replica 7475313 (Backend 171908): Version 109, State NORMAL, IsBad false. This node likely has the correct label.
* Replica 7475314 (Backend 203701): Version 109, State NORMAL, IsBad false. This node (203701) is one of the two backends missing the group:requests label.
Why it's "Unhealthy" but shows "NORMAL"
The StarRocks FE uses two different definitions for health:
1. Replica Health (Internal): Are the files there? Is the version correct? Is the BE alive? Your output shows NORMAL, meaning the data is perfectly safe and usable. This is why ADMIN SHOW REPLICA STATUS ... WHERE STATUS != 'OK' returns nothing.
2. Tablet Health (Global Policy): Does this tablet satisfy the table's properties? Because one replica sits on BE 203701 (which lacks the required label), the tablet is flagged as Unhealthy in SHOW PROC '/statistic'.
In StarRocks, a "Location Mismatch" is treated as a high-level health violation, even if the data is consistent.
Why is the Balancer Idle?
Your balance_stat showed PendingTablets: 0 despite the mismatch. This happens if:
* The cluster is in "Maintenance Mode": Check if any nodes are currently being decommissioned or if disable_tablet_scheduler is set to true in FE config.
* Replication Constraint: If your replication_num is 2, and you have 8 nodes, StarRocks is trying to find a new home on the other 6 labeled nodes. If those 6 nodes are nearing disk capacity (e.g., above the high_watermark in FE config), the scheduler will refuse to move the data.
How to resolve this:
Since the automatic balancer is currently idle (PendingTablets: 0), you need to manually trigger the move:
1. Force the Repair:
sql
ADMIN REPAIR TABLE requests;
2. Verify the Backend Label: Double-check that BE 203701 definitely lacks the label:
sql
SHOW BACKENDS;
-- Look at the 'Labels' column for BackendId 203701.
3. Check FE Scheduler Log: If the tablets still don't move, check the FE leader log (fe.log) for messages containing tablet scheduler. It will tell you if it's skipping the repair due to "no available backends" or "disk limit reached."
Summary: Your data is safe. The "Unhealthy" status is simply a warning that your data is not following your group:requests placement rule. Once the replica on BE 203701 is moved to a labeled BE, the status will clear.
References
• sql-reference/sql-statements/cluster-management/tablet_replica/ADMIN_CHECK_TABLET.md
• faq/operation_maintenance_faq.md
• administration/management/resource_management/Replica.mdMinn Fong
05/13/2026, 7:37 PMdisable_tablet_schedulerRocky
05/13/2026, 7:38 PMADMIN SHOW FRONTEND CONFIG command.
Run this in your SQL client:
sql
ADMIN SHOW FRONTEND CONFIG LIKE "disable_tablet_scheduler";
Interpreting the Results
* Value: true: The scheduler is disabled. StarRocks will not perform any replica repairs, balance data, or move replicas to fulfill your labels.location policy.
* Value: false: The scheduler is enabled (default).
Related Settings
If the tablet scheduler is enabled but your tablets are still not moving, check if specific sub-schedulers (like the balancer) are disabled:
sql
ADMIN SHOW FRONTEND CONFIG LIKE "disable_balance";
ADMIN SHOW FRONTEND CONFIG LIKE "disable_colocate_balance";
How to Enable it
If it is currently true and you want the system to start moving your 25% unhealthy tablets, you can enable it dynamically (no restart required):
sql
ADMIN SET FRONTEND CONFIG ("disable_tablet_scheduler" = "false");
*(Note: Always check ADMIN SHOW FRONTEND CONFIG on the Leader FE. If you are connected to a Follower, you may need to prefix your command with set forward_to_master = true; to ensure you are seeing the global state.)*
References
• administration/management/FE_configuration.md
• sql-reference/sql-statements/cluster-management/nodes_processes/ADMIN_SHOW_CONFIG.md
References
• administration/management/FE_configuration.md
• administration/management/BE_configuration.mdMinn Fong
05/13/2026, 7:40 PMMySQL [requests]> ADMIN SHOW FRONTEND CONFIG LIKE "disable_balance";
+------------------------------+-------------------+-------+---------+-----------+---------+
| Key | AliasNames | Value | Type | IsMutable | Comment |
+------------------------------+-------------------+-------+---------+-----------+---------+
| tablet_sched_disable_balance | [disable_balance] | false | boolean | true | |
+------------------------------+-------------------+-------+---------+-----------+---------+
1 row in set (0.001 sec)
MySQL [requests]>
Is there a specific FE config that needs to be changed so it knows not to route writes to the BE nodes without the location labels?Rocky
05/13/2026, 7:40 PMbalance_stat shows Balanced: false but PendingTablets: 0. This is the critical clue: the FE has noticed the location mismatch but has not created any migration tasks. This usually happens for one of the following reasons:
1. Disk Capacity Thresholds
The Tablet Scheduler will not move data to the labeled nodes if it thinks they are "full." Check the AvailCapacity of your 6 labeled nodes:
sql
SHOW BACKENDS;
If those nodes are above the tablet_sched_storage_high_watermark_usage_percent (default 90%), the scheduler will refuse to move any more data to them.
2. Scheduler Limits
The scheduler might be throttled. Check these FE configurations:
sql
ADMIN SHOW FRONTEND CONFIG LIKE "tablet_sched_max_scheduling_tablets";
ADMIN SHOW FRONTEND CONFIG LIKE "tablet_sched_num_threads_per_worker";
If tablet_sched_max_scheduling_tablets is very low (or accidentally set to 0), migration stops. The default is typically 2000.
3. Primary Key Table Constraints
Since you mentioned replicated_storage (Primary Key table), the migration involves the Raft protocol. If the cluster is under heavy load or if there are many "Version Count" issues (as seen in your SHOW TABLET output where VersionCount is low at 2, but could be high for others), the scheduler may delay moves to avoid performance impact.
4. "Safe" Mode for Single Replicas
If your table has replication_num = 1, StarRocks is extremely cautious. If the 6 target nodes are even slightly imbalanced in terms of disk or tablet count, the label-aware location balancer might stay in a "pending" state because it cannot find a "perfect" target node that won't violate another balancing rule.
Recommended Action
Since the automatic "routing" (migration) is stuck at 0 pending tasks, you should force the system to prioritize these specific tablets:
1. Check for Disk Issues: Ensure the 6 nodes in group:requests have plenty of free space.
2. Force a Repair:
sql
-- This tells the FE to ignore global balancing logic and
-- prioritize fixing the location of this specific table.
ADMIN REPAIR TABLE requests;
3. Monitor Task Creation:
After running the repair, check if the PendingTablets count in SHOW PROC '/cluster_balance/history' or the global balance status starts to increase.
Summary: You cannot change a config to "stop writes" to those nodes while data is still on them. You must use ADMIN REPAIR to force the data to move; once the data moves, the writes will naturally follow it to the new nodes automatically.
References
• administration/management/FE_configuration.md
• administration/management/resource_management/be_label.md
• administration/management/monitoring/metrics.md
References
• administration/management/FE_configuration.md
• administration/management/monitoring/metrics.md
• administration/management/resource_management/be_label.md