Skip to content

[fix](wal) rename wal_reader and move to wal directory#61135

Merged
yiguolei merged 1 commit intoapache:masterfrom
mymeiyi:fix-wal-reader
Mar 9, 2026
Merged

[fix](wal) rename wal_reader and move to wal directory#61135
yiguolei merged 1 commit intoapache:masterfrom
mymeiyi:fix-wal-reader

Conversation

@mymeiyi
Copy link
Contributor

@mymeiyi mymeiyi commented Mar 9, 2026

What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary:

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

Copilot AI review requested due to automatic review settings March 9, 2026 03:14
@hello-stephen
Copy link
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors WAL reading by separating low-level WAL file parsing from the vectorized GenericReader implementation, renaming the old file-based reader to WalFileReader and relocating the vectorized WAL reader into the group-commit WAL directory.

Changes:

  • Introduce WalFileReader as the low-level WAL file reader (init/read header/read blocks/finalize).
  • Move/rename the vectorized WalReader (GenericReader implementation) to be/src/load/group_commit/wal/ and update includes/usages.
  • Remove the previous be/src/format/wal/wal_reader.{h,cpp} implementation and update tests and call sites.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
be/test/format/wal/wal_reader_writer_test.cpp Update unit test to use WalFileReader.
be/src/load/group_commit/wal/wal_table.cpp Switch header-reading helper to WalFileReader.
be/src/load/group_commit/wal/wal_reader.h New location for vectorized WalReader (GenericReader) and switch to WalFileReader backend.
be/src/load/group_commit/wal/wal_reader.cpp Vectorized WAL block conversion now reads via WalFileReader.
be/src/load/group_commit/wal/wal_manager.cpp Update include to new wal_reader.h location.
be/src/load/group_commit/wal/wal_file_reader.h Add new low-level WAL file reader API.
be/src/load/group_commit/wal/wal_file_reader.cpp Implement low-level WAL file reading/parsing logic.
be/src/format/wal/wal_reader.h Remove old vectorized WAL reader header.
be/src/format/wal/wal_reader.cpp Remove old vectorized WAL reader implementation.
be/src/exec/scan/file_scanner.cpp Update include to new WalReader header location.
Comments suppressed due to low confidence (1)

be/src/load/group_commit/wal/wal_table.cpp:345

  • If read_header() (or the logging line) returns an error, finalize() won't run and the underlying file handle can leak because WalFileReader's destructor doesn't close. Consider a scope guard/RAII pattern so finalize() is always executed after a successful init().
    RETURN_IF_ERROR(wal_reader->read_header(version, columns));
    VLOG_DEBUG << "wal=" << wal_path << ",version=" << std::to_string(version)
               << ",columns=" << columns;
    RETURN_IF_ERROR(wal_reader->finalize());
    return Status::OK();

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +23 to +33
namespace doris::vectorized {
#include "common/compile_check_begin.h"
struct ScannerCounter;
class WalReader : public GenericReader {
ENABLE_FACTORY_CREATOR(WalReader);

#include "common/status.h"
#include "io/fs/file_reader_writer_fwd.h"

namespace doris {

class WalReader {
public:
explicit WalReader(const std::string& file_name);
~WalReader();

Status init();
Status finalize();

Status read_block(PBlock& block);
Status read_header(uint32_t& version, std::string& col_ids);
WalReader(RuntimeState* state);
~WalReader() override = default;
Status init_reader(const TupleDescriptor* tuple_descriptor);
Status get_next_block(Block* block, size_t* read_rows, bool* eof) override;
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WalReader's public API uses RuntimeState*, but this header doesn't declare RuntimeState (nor include runtime/runtime_state.h). This can break any TU that includes this header without already forward-declaring RuntimeState (e.g. wal_manager.h includes it). Add a forward declaration for doris::RuntimeState (preferred) or include the defining header.

Copilot uses AI. Check for mistakes.
if (UNLIKELY(!block.ParseFromString(buf))) {
return Status::InternalError(
"failed to deserialize row, file_size=" + std::to_string(file_reader->size()) +
", read_offset=" + std::to_string(_offset) + +", block_bytes=" +
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_deserialize() builds an error string with ... + std::to_string(_offset) + + ", block_bytes=" + ... (double +), which is a compile-time error. Remove the stray + so the concatenation is valid (or switch to a formatter to avoid manual concatenation).

Suggested change
", read_offset=" + std::to_string(_offset) + +", block_bytes=" +
", read_offset=" + std::to_string(_offset) + ", block_bytes=" +

Copilot uses AI. Check for mistakes.
// read block
std::string block_buf;
block_buf.resize(block_len);
RETURN_IF_ERROR(file_reader->read_at(_offset, {block_buf.c_str(), block_len}, &bytes_read));
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

read_at() writes into the provided buffer, but block_buf.c_str() returns a pointer to a const, null-terminated view of the string. Writing through it relies on const_cast and is undefined behavior per the C++ standard; use a mutable buffer pointer from the string (e.g., its writable data) instead.

Suggested change
RETURN_IF_ERROR(file_reader->read_at(_offset, {block_buf.c_str(), block_len}, &bytes_read));
RETURN_IF_ERROR(file_reader->read_at(_offset, {block_buf.data(), block_len}, &bytes_read));

Copilot uses AI. Check for mistakes.
return Status::InternalError("failed to read header expected= " + std::to_string(len) +
",actually=" + std::to_string(bytes_read));
for (auto* slot_desc : _tuple_descriptor->slots()) {
auto pos = _column_pos_map[slot_desc->col_unique_id()];
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using _column_pos_map[slot_desc->col_unique_id()] will insert a default entry (pos=0) when the WAL header doesn't contain that column id, silently reading the wrong column. Use a lookup that doesn't mutate the map and return an error / record it in missing_cols when the id is absent.

Suggested change
auto pos = _column_pos_map[slot_desc->col_unique_id()];
auto it = _column_pos_map.find(slot_desc->col_unique_id());
if (it == _column_pos_map.end()) {
return Status::InternalError("read wal {} fail, column id {} not found in header",
_wal_path, slot_desc->col_unique_id());
}
auto pos = it->second;

Copilot uses AI. Check for mistakes.
pos, src_block.columns());
}
vectorized::ColumnPtr column_ptr = src_block.get_by_position(pos).column;
if (!column_ptr && slot_desc->is_nullable()) {
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make_nullable() dereferences its argument; calling it with a null column_ptr will crash. If a WAL column can be absent/null here, construct an all-NULL column of the expected type/row count instead; otherwise, remove the null check and assert the column is always present.

Suggested change
if (!column_ptr && slot_desc->is_nullable()) {
if (!column_ptr) {
// WAL column is absent; create an all-NULL column with the expected type and row count.
auto& type = output_block_columns[index].type;
column_ptr = type->create_column();
column_ptr->insert_many_defaults(src_block.rows());
} else if (slot_desc->is_nullable()) {

Copilot uses AI. Check for mistakes.
Comment on lines +107 to +118
std::vector<std::string> column_id_vector =
absl::StrSplit(col_ids, ",", absl::SkipWhitespace());
_column_id_count = column_id_vector.size();
try {
int64_t pos = 0;
for (auto col_id_str : column_id_vector) {
auto col_id = std::strtoll(col_id_str.c_str(), nullptr, 10);
_column_pos_map.emplace(col_id, pos);
pos++;
}
} catch (const std::invalid_argument& e) {
return Status::InvalidArgument("Invalid format, {}", e.what());
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::strtoll doesn't throw std::invalid_argument, so the try/catch here is ineffective. If you need validation, parse with an end-pointer/errno check and return InvalidArgument when the entire token isn't a valid integer; also consider clearing _column_pos_map before filling to avoid stale entries if get_columns() is called more than once.

Copilot uses AI. Check for mistakes.
@mymeiyi
Copy link
Contributor Author

mymeiyi commented Mar 9, 2026

run buildall

@github-actions github-actions bot added the approved Indicates a PR has been approved by one committer. label Mar 9, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

PR approved by at least one committer and no changes requested.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

PR approved by anyone and no changes requested.

@hello-stephen
Copy link
Contributor

skip buildall

@yiguolei yiguolei merged commit 798d644 into apache:master Mar 9, 2026
31 of 35 checks passed
@doris-robot
Copy link

TPC-H: Total hot run time: 27741 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit b611fd3548e53e46723e1f3fa3757877333f4e10, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17663	4541	4317	4317
q2	q3	10647	770	517	517
q4	4672	361	256	256
q5	7558	1208	1027	1027
q6	171	174	144	144
q7	769	834	677	677
q8	9298	1484	1343	1343
q9	4871	4772	4723	4723
q10	6263	1929	1674	1674
q11	478	260	261	260
q12	690	570	486	486
q13	18027	3012	2199	2199
q14	242	237	226	226
q15	903	810	806	806
q16	739	716	686	686
q17	740	855	415	415
q18	6014	5451	5182	5182
q19	1232	996	619	619
q20	501	501	408	408
q21	4724	2133	1491	1491
q22	396	366	285	285
Total cold run time: 96598 ms
Total hot run time: 27741 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4715	4540	4545	4540
q2	q3	3878	4345	3850	3850
q4	893	1198	837	837
q5	4095	4387	4321	4321
q6	176	184	150	150
q7	1814	1626	1516	1516
q8	2525	2673	2748	2673
q9	7560	7634	7323	7323
q10	3773	3984	3598	3598
q11	516	431	418	418
q12	482	590	478	478
q13	2660	3105	2302	2302
q14	278	315	298	298
q15	900	808	814	808
q16	758	759	716	716
q17	1185	1473	1378	1378
q18	7139	6842	6695	6695
q19	867	937	903	903
q20	2100	2200	2022	2022
q21	3984	3605	3284	3284
q22	455	438	403	403
Total cold run time: 50753 ms
Total hot run time: 48513 ms

@doris-robot
Copy link

TPC-DS: Total hot run time: 153268 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit b611fd3548e53e46723e1f3fa3757877333f4e10, data reload: false

query5	4323	648	527	527
query6	333	221	213	213
query7	4229	467	264	264
query8	371	242	234	234
query9	8758	2730	2757	2730
query10	493	390	360	360
query11	7314	5874	5615	5615
query12	187	127	119	119
query13	1257	427	344	344
query14	5649	3847	3584	3584
query14_1	2819	2795	2823	2795
query15	212	196	177	177
query16	986	477	484	477
query17	885	718	631	631
query18	2447	467	361	361
query19	221	213	186	186
query20	134	134	137	134
query21	222	143	126	126
query22	4889	5051	4934	4934
query23	16639	16095	15708	15708
query23_1	15954	16074	15785	15785
query24	7495	1727	1326	1326
query24_1	1282	1258	1252	1252
query25	566	492	433	433
query26	1246	262	156	156
query27	2781	482	285	285
query28	4554	1864	1855	1855
query29	839	584	502	502
query30	314	250	215	215
query31	1357	1283	1240	1240
query32	82	75	81	75
query33	523	341	294	294
query34	937	922	553	553
query35	665	704	612	612
query36	1104	1122	949	949
query37	141	98	81	81
query38	2948	2938	2849	2849
query39	894	885	865	865
query39_1	832	820	827	820
query40	273	154	138	138
query41	64	58	56	56
query42	294	296	296	296
query43	237	251	237	237
query44	
query45	192	195	182	182
query46	891	991	605	605
query47	2119	2130	2031	2031
query48	310	311	227	227
query49	629	459	374	374
query50	685	270	209	209
query51	4102	4097	4063	4063
query52	285	291	281	281
query53	286	331	275	275
query54	311	262	272	262
query55	93	89	89	89
query56	334	341	312	312
query57	1350	1342	1270	1270
query58	283	284	270	270
query59	1376	1463	1315	1315
query60	336	337	311	311
query61	149	143	141	141
query62	626	608	528	528
query63	307	276	278	276
query64	5047	1285	1014	1014
query65	
query66	1463	459	348	348
query67	16369	16394	16307	16307
query68	
query69	392	320	292	292
query70	1019	940	955	940
query71	347	310	296	296
query72	2797	2707	2466	2466
query73	550	587	328	328
query74	10015	9930	9839	9839
query75	2880	2773	2471	2471
query76	2272	1032	687	687
query77	363	379	309	309
query78	11231	11351	10650	10650
query79	1242	808	584	584
query80	1367	609	549	549
query81	584	288	251	251
query82	1006	153	115	115
query83	337	262	239	239
query84	303	124	95	95
query85	915	497	447	447
query86	430	329	299	299
query87	3171	3070	3001	3001
query88	3539	2666	2657	2657
query89	422	373	348	348
query90	2047	175	174	174
query91	169	158	139	139
query92	77	76	66	66
query93	1004	832	505	505
query94	629	327	293	293
query95	600	348	323	323
query96	641	521	229	229
query97	2448	2521	2408	2408
query98	229	220	219	219
query99	1012	1014	920	920
Total cold run time: 234229 ms
Total hot run time: 153268 ms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. reviewed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants