-
Notifications
You must be signed in to change notification settings - Fork 3.9k
[fix](regression) fix index change wait timeout #65453
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
818bc03
537124f
57926e6
3cd514f
2fb05cb
7e4bb8f
773e4e2
f73a0a4
1814da5
25e5b66
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,22 +23,44 @@ import java.util.regex.Pattern; | |
|
|
||
| def delta_time = 1000 | ||
|
|
||
| Suite.metaClass.wait_for_last_build_index_finish = {table_name, OpTimeout -> | ||
| def useTime = 0 | ||
| for(int t = delta_time; t <= OpTimeout; t += delta_time){ | ||
| def alter_res = sql """SHOW BUILD INDEX WHERE TableName = "${table_name}" ORDER BY CreateTime DESC LIMIT 1;""" | ||
| alter_res = alter_res.toString() | ||
| if(alter_res.contains("FINISHED")) { | ||
| logger.info(table_name + " latest alter job finished, detail: " + alter_res) | ||
| Suite.metaClass.snapshot_build_index_job_ids = { table_name -> | ||
| def alter_res = sql """SHOW BUILD INDEX WHERE TableName = "${table_name}";""" | ||
| return alter_res.collect { it[0].toString() }.toSet() | ||
| } | ||
|
|
||
| Suite.metaClass.wait_for_new_build_index_jobs_finish = { table_name, OpTimeout, previous_job_ids -> | ||
| assertTrue(previous_job_ids != null, "previous build index job ids must be snapshotted before the operation") | ||
| def finished = false | ||
| def alter_res = [] | ||
| for (int t = 0; t <= OpTimeout; t += delta_time) { | ||
| def all_jobs = sql """SHOW BUILD INDEX WHERE TableName = "${table_name}" | ||
| ORDER BY CreateTime DESC;""" | ||
| alter_res = all_jobs.findAll { !previous_job_ids.contains(it[0].toString()) } | ||
|
|
||
| if (!alter_res.isEmpty() && alter_res.any { it[7] == "CANCELLED" }) { | ||
| logger.info(table_name + " build index job failed, detail: " + alter_res) | ||
| assertTrue(false, "build index job cancelled, result: ${alter_res}") | ||
| } | ||
| if (!alter_res.isEmpty() && alter_res.every { it[7] == "FINISHED" }) { | ||
| logger.info(table_name + " build index jobs finished, detail: " + alter_res) | ||
| finished = true | ||
| break | ||
| } | ||
| if (t >= OpTimeout) { | ||
| break | ||
| } else if (alter_res.contains("CANCELLED")) { | ||
| logger.info(table_name + " latest alter job failed, detail: " + alter_res) | ||
| assertTrue(false) | ||
| } | ||
| useTime = t | ||
| sleep(delta_time) | ||
| } | ||
| assertTrue(useTime <= OpTimeout, "wait for last build index finish timeout") | ||
| assertTrue(finished, "wait for build index finish timeout, latest result: ${alter_res}") | ||
| } | ||
|
|
||
| // Run an operation that must create one or more IndexChangeJobs and wait for | ||
| // every job created by that operation. SHOW BUILD INDEX history is retained, so | ||
| // the pre-operation snapshot is required to isolate the current operation. | ||
| Suite.metaClass.run_index_change_job_and_wait = { table_name, OpTimeout, Closure operation -> | ||
| def previous_job_ids = snapshot_build_index_job_ids(table_name) | ||
| operation.call() | ||
| wait_for_new_build_index_jobs_finish(table_name, OpTimeout, previous_job_ids) | ||
| } | ||
|
|
||
| Suite.metaClass.build_index_on_table = {index_name, table_name -> | ||
|
|
@@ -51,25 +73,28 @@ Suite.metaClass.build_index_on_table = {index_name, table_name -> | |
| } | ||
|
|
||
| Suite.metaClass.wait_for_last_col_change_finish = { table_name, OpTimeout -> | ||
| def useTime = 0 | ||
| def finished = false | ||
| def alter_res = "" | ||
|
|
||
| for (int t = delta_time; t <= OpTimeout; t += delta_time) { | ||
| def alter_res = sql """SHOW ALTER TABLE COLUMN WHERE TableName = "${table_name}" ORDER BY CreateTime DESC LIMIT 1;""" | ||
| for (int t = 0; t <= OpTimeout; t += delta_time) { | ||
| alter_res = sql """SHOW ALTER TABLE COLUMN WHERE TableName = "${table_name}" ORDER BY CreateTime DESC LIMIT 1;""" | ||
| alter_res = alter_res.toString() | ||
| if (alter_res.contains("FINISHED")) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The column waiter still treats a terminal |
||
| sleep(3000) // wait change table state to normal | ||
| logger.info(table_name + " latest alter job finished, detail: " + alter_res) | ||
| finished = true | ||
| break | ||
| } | ||
| if (t >= OpTimeout) { | ||
| break | ||
| } | ||
| useTime = t | ||
| sleep(delta_time) | ||
| } | ||
| assertTrue(useTime <= OpTimeout, "wait_for_last_col_change_finish timeout") | ||
| assertTrue(finished, "wait_for_last_col_change_finish timeout, latest result: ${alter_res}") | ||
| } | ||
|
|
||
| Suite.metaClass.wait_for_last_schema_change_finish = {table_name, OpTimeout -> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This wrapper now always calls
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 57926e6: the schema-change wrapper now waits only for the column/schema job. The two callers that explicitly submit BUILD INDEX now wait for the column job and build-index job separately.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Follow-up fixed in 3cd514f after inspecting P0 991501 and Cloud P0 991624. Direct shared-helper callers also legitimately see an empty SHOW BUILD INDEX result when no build-index job exists. The helper now returns immediately for an empty result, while remaining strict for existing nonterminal jobs. Mock coverage includes the empty-result path. |
||
| wait_for_last_col_change_finish(table_name, OpTimeout) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Making this wrapper column-only fixes the schema-only callers, but it also skips cloud full-table drop-index cleanup jobs. In cloud mode, dropping an inverted index with
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 2fb05cb. Cloud full-table DROP INDEX callers now snapshot existing build-index JobIds before the drop, wait for the column/schema job, and then wait for all newly created delete jobs. Schema-only create-index callers remain column-only. |
||
| wait_for_last_build_index_finish(table_name, OpTimeout) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This wrapper is now column-only, but
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 2fb05cb. test_add_drop_index now snapshots existing JobIds before the Cloud full-table drop, waits for the schema job, and then waits for all newly created delete jobs before creating the next index. |
||
| } | ||
|
|
||
|
|
||
|
|
@@ -137,4 +162,4 @@ Suite.metaClass.check_bf_index_filter_rows = { sql, expectedRowsBfFiltered -> | |
| log.info("filter number:{}", number) | ||
| assertEquals(expectedRowsBfFiltered, number) | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -461,9 +461,9 @@ suite("test_custom_analyzer", "p0") { | |
| qt_sql """ select tokenize("BAR", '"analyzer"="lowercase_delimited"'); """ | ||
|
|
||
| sql """ alter table ${indexTbName1} add index idx_ch_default(`ch`) using inverted; """ | ||
| wait_for_last_build_index_finish("${indexTbName1}", 60000) | ||
| wait_for_last_col_change_finish("${indexTbName1}", 60000) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In non-Cloud mode an |
||
| sql """ alter table ${indexTbName1} add index idx_ch(`ch`) using inverted properties("support_phrase" = "true", "analyzer" = "lowercase_delimited"); """ | ||
| wait_for_last_build_index_finish("${indexTbName1}", 60000) | ||
| wait_for_last_col_change_finish("${indexTbName1}", 60000) | ||
|
|
||
| qt_sql """ select * from ${indexTbName1} where ch match_all 'FOO'; """ | ||
| qt_sql """ select * from ${indexTbName1} where ch match_all 'BAR'; """ | ||
|
|
@@ -883,4 +883,4 @@ suite("test_custom_analyzer", "p0") { | |
| } finally { | ||
| sql "DROP TABLE IF EXISTS ${indexTbName7}" | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The snapshot path still produces a false timeout at the deadline. If the new jobs are first observed all
FINISHEDon thet == OpTimeoutpoll,confirmed_finished_job_idsis only initialized; this branch immediately breaks, and the final assertion fails despite the last permitted query having observed success. FE registers every siblingIndexChangeJobsynchronously before a successful DDL returns, so please either accept the nonempty all-finished set immediately or allow/reserve the confirmation poll beyond the deadline.