Skip to content

Commit bbb5a88

Browse files
authored
Merge pull request ClickHouse#77893 from ClickHouse/bk3
Pause refreshable materialized views when restoring backup
2 parents 7c6d555 + bfcf63c commit bbb5a88

File tree

20 files changed

+282
-76
lines changed

20 files changed

+282
-76
lines changed

docs/en/sql-reference/statements/system.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -580,21 +580,25 @@ SYSTEM REFRESH VIEW [db.]name
580580

581581
Wait for the currently running refresh to complete. If the refresh fails, throws an exception. If no refresh is running, completes immediately, throwing an exception if previous refresh failed.
582582

583-
### STOP VIEW, STOP VIEWS {#stop-view-stop-views}
583+
### STOP [REPLICATED] VIEW, STOP VIEWS {#stop-view-stop-views}
584584

585585
Disable periodic refreshing of the given view or all refreshable views. If a refresh is in progress, cancel it too.
586586

587+
If the view is in a Replicated or Shared database, `STOP VIEW` only affects the current replica, while `STOP REPLICATED VIEW` affects all replicas.
588+
587589
```sql
588590
SYSTEM STOP VIEW [db.]name
589591
```
590592
```sql
591593
SYSTEM STOP VIEWS
592594
```
593595

594-
### START VIEW, START VIEWS {#start-view-start-views}
596+
### START [REPLICATED] VIEW, START VIEWS {#start-view-start-views}
595597

596598
Enable periodic refreshing for the given view or all refreshable views. No immediate refresh is triggered.
597599

600+
If the view is in a Replicated or Shared database, `START VIEW` undoes the effect of `STOP VIEW`, and `START REPLICATED VIEW` undoes the effect of `STOP REPLICATED VIEW`.
601+
598602
```sql
599603
SYSTEM START VIEW [db.]name
600604
```
@@ -604,7 +608,7 @@ SYSTEM START VIEWS
604608

605609
### CANCEL VIEW {#cancel-view}
606610

607-
If there's a refresh in progress for the given view, interrupt and cancel it. Otherwise do nothing.
611+
If there's a refresh in progress for the given view on the current replica, interrupt and cancel it. Otherwise do nothing.
608612
609613
```sql
610614
SYSTEM CANCEL VIEW [db.]name
@@ -616,6 +620,8 @@ Waits for the running refresh to complete. If no refresh is running, returns imm
616620
617621
Can be used right after creating a new refreshable materialized view (without EMPTY keyword) to wait for the initial refresh to complete.
618622
623+
If the view is in a Replicated or Shared database, and refresh is running on another replica, waits for that refresh to complete.
624+
619625
```sql
620626
SYSTEM WAIT VIEW [db.]name
621627
```

src/Backups/BackupCoordinationStage.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ namespace BackupCoordinationStage
4040
/// Inserting restored data to tables.
4141
constexpr const char * INSERTING_DATA_TO_TABLES = "inserting data to tables";
4242

43+
/// Unpausing refreshable materialized views.
44+
constexpr const char * FINALIZING_TABLES = "finalizing tables";
45+
4346
/// Coordination stage meaning that a host finished its work.
4447
constexpr const char * COMPLETED = "completed";
4548
}

src/Backups/BackupCoordinationStageSync.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -891,8 +891,19 @@ bool BackupCoordinationStageSync::checkIfHostsReachStage(const Strings & hosts,
891891
}
892892

893893
if (host_info.finished)
894+
{
895+
if (stage_to_wait == BackupCoordinationStage::FINALIZING_TABLES)
896+
{
897+
/// This is a newly added stage. For compatibility with older server versions,
898+
/// allow other replicas to skip this stage. This doesn't break anything: this stage
899+
/// unpauses refreshable materialized views, but older server versions don't pause
900+
/// them in the first place.
901+
results[i] = "";
902+
continue;
903+
}
894904
throw Exception(ErrorCodes::FAILED_TO_SYNC_BACKUP_OR_RESTORE,
895905
"{} finished without coming to stage {}", getHostDesc(host), stage_to_wait);
906+
}
896907

897908
if (should_stop_watching_thread)
898909
throw Exception(ErrorCodes::LOGICAL_ERROR, "waitHostsReachStage() can't wait for stage {} after the watching thread stopped", stage_to_wait);

src/Backups/RestorerFromBackup.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ void RestorerFromBackup::run(Mode mode_)
176176
insertDataToTables();
177177
runDataRestoreTasks();
178178

179+
setStage(Stage::FINALIZING_TABLES);
180+
finalizeTables();
181+
179182
/// Restored successfully!
180183
setStage(Stage::COMPLETED);
181184
}
@@ -1174,6 +1177,20 @@ void RestorerFromBackup::runDataRestoreTasks()
11741177
}
11751178
}
11761179

1180+
void RestorerFromBackup::finalizeTables()
1181+
{
1182+
std::vector<StoragePtr> tables;
1183+
{
1184+
std::lock_guard lock{mutex};
1185+
tables.reserve(table_infos.size());
1186+
for (const auto & [_, info] : table_infos)
1187+
tables.push_back(info.storage);
1188+
}
1189+
1190+
for (const auto & storage : tables)
1191+
storage->finalizeRestoreFromBackup();
1192+
}
1193+
11771194
void RestorerFromBackup::throwTableIsNotEmpty(const StorageID & storage_id)
11781195
{
11791196
throw Exception(

src/Backups/RestorerFromBackup.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ class RestorerFromBackup : private boost::noncopyable
133133

134134
void runDataRestoreTasks();
135135

136+
void finalizeTables();
137+
136138
void setStage(const String & new_stage, const String & message = "");
137139

138140
/// Schedule a task from the thread pool and start executing it.

src/Interpreters/InterpreterCreateQuery.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,7 +1778,8 @@ bool InterpreterCreateQuery::doCreateTable(ASTCreateQuery & create,
17781778
getContext()->getGlobalContext(),
17791779
properties.columns,
17801780
properties.constraints,
1781-
mode);
1781+
mode,
1782+
is_restore_from_backup);
17821783
};
17831784
auto temporary_table = TemporaryTableHolder(getContext(), creator, query_ptr);
17841785

@@ -1955,7 +1956,8 @@ bool InterpreterCreateQuery::doCreateTable(ASTCreateQuery & create,
19551956
getContext()->getGlobalContext(),
19561957
properties.columns,
19571958
properties.constraints,
1958-
mode);
1959+
mode,
1960+
is_restore_from_backup);
19591961

19601962
/// If schema was inferred while storage creation, add columns description to create query.
19611963
auto & create_query = query_ptr->as<ASTCreateQuery &>();

src/Interpreters/InterpreterSystemQuery.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,14 @@ BlockIO InterpreterSystemQuery::execute()
718718
case Type::STOP_VIEWS:
719719
startStopAction(ActionLocks::ViewRefresh, false);
720720
break;
721+
case Type::START_REPLICATED_VIEW:
722+
for (const auto & task : getRefreshTasks())
723+
task->startReplicated();
724+
break;
725+
case Type::STOP_REPLICATED_VIEW:
726+
for (const auto & task : getRefreshTasks())
727+
task->stopReplicated("SYSTEM STOP REPLICATED VIEW");
728+
break;
721729
case Type::REFRESH_VIEW:
722730
for (const auto & task : getRefreshTasks())
723731
task->run();
@@ -1625,8 +1633,10 @@ AccessRightsElements InterpreterSystemQuery::getRequiredAccessForDDLOnCluster()
16251633
case Type::WAIT_VIEW:
16261634
case Type::START_VIEW:
16271635
case Type::START_VIEWS:
1636+
case Type::START_REPLICATED_VIEW:
16281637
case Type::STOP_VIEW:
16291638
case Type::STOP_VIEWS:
1639+
case Type::STOP_REPLICATED_VIEW:
16301640
case Type::CANCEL_VIEW:
16311641
case Type::TEST_VIEW:
16321642
{

src/Parsers/ASTSystemQuery.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,9 @@ void ASTSystemQuery::formatImpl(WriteBuffer & ostr, const FormatSettings & setti
400400
}
401401
case Type::REFRESH_VIEW:
402402
case Type::START_VIEW:
403+
case Type::START_REPLICATED_VIEW:
403404
case Type::STOP_VIEW:
405+
case Type::STOP_REPLICATED_VIEW:
404406
case Type::CANCEL_VIEW:
405407
case Type::WAIT_VIEW:
406408
{

src/Parsers/ASTSystemQuery.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,10 @@ class ASTSystemQuery : public IAST, public ASTQueryWithOnCluster
107107
WAIT_VIEW,
108108
START_VIEW,
109109
START_VIEWS,
110+
START_REPLICATED_VIEW,
110111
STOP_VIEW,
111112
STOP_VIEWS,
113+
STOP_REPLICATED_VIEW,
112114
CANCEL_VIEW,
113115
TEST_VIEW,
114116
LOAD_PRIMARY_KEY,

src/Parsers/ParserSystemQuery.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,9 @@ bool ParserSystemQuery::parseImpl(IParser::Pos & pos, ASTPtr & node, Expected &
441441
case Type::REFRESH_VIEW:
442442
case Type::WAIT_VIEW:
443443
case Type::START_VIEW:
444+
case Type::START_REPLICATED_VIEW:
444445
case Type::STOP_VIEW:
446+
case Type::STOP_REPLICATED_VIEW:
445447
case Type::CANCEL_VIEW:
446448
if (!parseDatabaseAndTableAsAST(pos, expected, res->database, res->table))
447449
return false;

0 commit comments

Comments
 (0)