| 1117 | } |
| 1118 | |
| 1119 | bool InterpreterSystemQuery::dropReplicaImpl(ASTSystemQuery & query, const StoragePtr & table) |
| 1120 | { |
| 1121 | auto * storage_replicated = dynamic_cast<StorageReplicatedMergeTree *>(table.get()); |
| 1122 | if (!storage_replicated) |
| 1123 | return false; |
| 1124 | |
| 1125 | StorageReplicatedMergeTree::Status status; |
| 1126 | auto zookeeper = getContext()->getZooKeeper(); |
| 1127 | storage_replicated->getStatus(status); |
| 1128 | |
| 1129 | /// Do not allow to drop local replicas and active remote replicas |
| 1130 | if (query.replica == status.replica_name) |
| 1131 | throw Exception("We can't drop local replica, please use `DROP TABLE` " |
| 1132 | "if you want to clean the data and drop this replica", ErrorCodes::TABLE_WAS_NOT_DROPPED); |
| 1133 | |
| 1134 | /// NOTE it's not atomic: replica may become active after this check, but before dropReplica(...) |
| 1135 | /// However, the main usecase is to drop dead replica, which cannot become active. |
| 1136 | /// This check prevents only from accidental drop of some other replica. |
| 1137 | if (zookeeper->exists(status.zookeeper_path + "/replicas/" + query.replica + "/is_active")) |
| 1138 | throw Exception("Can't drop replica: " + query.replica + ", because it's active", |
| 1139 | ErrorCodes::TABLE_WAS_NOT_DROPPED); |
| 1140 | |
| 1141 | storage_replicated->dropReplica(zookeeper, status.zookeeper_path, query.replica, log); |
| 1142 | LOG_TRACE(log, "Dropped replica {} of {}", query.replica, table->getStorageID().getNameForLogs()); |
| 1143 | |
| 1144 | return true; |
| 1145 | } |
| 1146 | |
| 1147 | void InterpreterSystemQuery::recalculateMetrics(ASTSystemQuery & query) |
| 1148 | { |
nothing calls this directly
no test coverage detected