[Bug] Upper-case hex in cloud initial rowset id is mis-parsed by BE from_hex (lossy, non-unique RowsetId)
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 78/100
Hướng nghiên cứu
Bắt đầu bằng cách đọc be/src/util/uid_util.h và be/src/storage/rowset_id.cpp, sau đó kiểm tra các vị trí gọi from_hex() được đề cập trong issue. Tái hiện trường hợp phân tích chuỗi có chữ hoa và kiểm tra các bài kiểm thử đơn vị hiện có cho việc phân tích UID hoặc rowset ID. Công việc hoàn tất khi các giá trị hex viết hoa được phân tích thành cùng giá trị như khi viết thường và các ký tự không hợp lệ được xử lý an toàn.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Search before asking
- I had searched in the issues and found no similar issues.
Version
4.1.4 (cloud mode). master is the same (351d9388d5):
- FE
fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java:690-692builds the initial[0-1]rowset id withString.format("%016X", ...)(upper-case hex). - BE
be/src/util/uid_util.h:48-61from_hex()only handles0-9anda-f; any other character is mapped withc - 'a' + 10. - BE
be/src/storage/rowset_id.cpp:57-63RowsetId::init(std::string_view)parses the 48-char id withfrom_hex().
Description
In cloud mode the FE creates the empty [0-1] rowset of every new tablet with a V2 rowset id formatted as upper-case hex:
String rowsetIdV2Str = String.format("%016X", 2L << 56)
+ String.format("%016X", uuid.getMostSignificantBits())
+ String.format("%016X", uuid.getLeastSignificantBits());
The BE parses rowset ids with from_hex(), which treats every non-digit as lower-case:
if (i >= '0' && i <= '9') {
buf_val = i - '0';
} else {
buf_val = i - 'a' + 10; // 'A'..'F' -> -22..-17
}
val <<= 4;
val = val | buf_val; // a negative nibble sets all upper bits
For 'A'..'F' the nibble is negative, so val | buf_val sets every higher bit. Any UUID half that contains an upper-case letter parses to a value like 0xffffffffffffffea. The BE then shows these rowsets as, e.g.,
0200000000000000ffffffffffffffeafffffffffffffffe
Consequences:
- The parse is lossy: everything before the last letter in each 16-char half is lost, so
[0-1]rowset ids of different tablets can parse to the sameRowsetId. RowsetId::to_string()never round-trips to the id stored in the meta-service, so any code that compares the BE-side id string with the stored one sees a mismatch for these rowsets.- These ids look like version-hole rowsets in BE logs, which is confusing when diagnosing rowset reference counts.
The [0-1] rowset is empty (0 segments, 0 rows), so we have not seen data impact, but the ids are wrong and not unique.
Solution
Either side fixes it; both are one-liners:
- BE: make
from_hex()accept upper case, e.g.else if (i >= 'A' && i <= 'F') buf_val = i - 'A' + 10;(and ideally reject anything else instead of producing a negative nibble). - FE: format with
%016x(lower case), matching how the BE prints rowset ids.
Doing (1) keeps existing upper-case ids already stored in the meta-service parsing correctly.
How to Reproduce?
- Start a cloud-mode cluster, create any table.
- Look at the
[0-1]rowset id of a tablet on the BE (e.g. in BE logs or via the tablet meta HTTP API): it shows as0200000000000000ffff..., while the meta-service stores0200000000000000+ 32 upper-case hex chars. - Unit level:
RowsetId id; id.init("0200000000000000ABCDEF0123456789ABCDEF0123456789");givesmiandlowith all upper bits set (e.g.0xffffffef0123456789-style values truncated to 64 bits) instead of0xABCDEF0123456789.
Anything Else?
from_hex() is also used for UniqueId parsing; any other caller that can receive upper-case hex is affected the same way.
Are you willing to submit PR?
- Yes I am willing to submit a PR!
Code of Conduct
- I agree to follow this project's Code of Conduct
- Ngôn ngữ chính
- Java
- Star
- 16.1k
- Fork
- 4k
- Merge trung bình
- 2 ngày 20 giờ
- Pull request đã merge (30 ngày)
- 672
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của apache/doris
-
Độ khó 2/5 Dưới một giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[Enhancement] Update documentation to build you own docker imageCó thể đã có người làm @NUAAwqy đã nhận 2 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 Nửa ngày Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 1 ngày
-
4.1.4.1 Release NoteĐang mởrelease notes
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug] FE metric http_copy_into_query_err_total is registered under the upload error nameCó thể đã có người làm @manesioz đã nhận 27 ngày trước. Đang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
apache/doris#68505 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Issue tương tự
-
human-required sync-failed
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Azure/osdu-spi-file#63 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
frontend quick win
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
CodeForPhilly/benefit-decision-toolkit#571 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
approved
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 67/100
checkstyle/checkstyle#22129 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Add Hardcharger JDBC driverCó thể đã có người làm @prmoore77 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày