| 1290 | } |
| 1291 | |
| 1292 | bool DatabaseReplicated::checkDigestValid(const ContextPtr & local_context) const |
| 1293 | { |
| 1294 | LOG_TEST(log, "Current in-memory metadata digest: {}", tables_metadata_digest); |
| 1295 | |
| 1296 | /// Database is probably being dropped |
| 1297 | if (!local_context->getZooKeeperMetadataTransaction() && (!ddl_worker || !ddl_worker->isCurrentlyActive())) |
| 1298 | return true; |
| 1299 | |
| 1300 | /// SYSTEM RESTART REPLICA temporarily removes a table from the in-memory tables map |
| 1301 | /// without updating tables_metadata_digest, so the check would produce a false mismatch. |
| 1302 | if (tables_being_restarted.load() > 0) |
| 1303 | return true; |
| 1304 | |
| 1305 | UInt64 local_digest = 0; |
| 1306 | { |
| 1307 | std::lock_guard lock{mutex}; |
| 1308 | for (const auto & table : tables) |
| 1309 | local_digest += getMetadataHash(table.first); |
| 1310 | } |
| 1311 | |
| 1312 | if (local_digest != tables_metadata_digest) |
| 1313 | { |
| 1314 | LOG_ERROR(log, "Digest of local metadata ({}) is not equal to in-memory digest ({})", local_digest, tables_metadata_digest); |
| 1315 | |
| 1316 | #ifndef NDEBUG |
| 1317 | tryCompareLocalAndZooKeeperTablesAndDumpDiffForDebugOnly(local_context); |
| 1318 | #endif |
| 1319 | |
| 1320 | return false; |
| 1321 | } |
| 1322 | |
| 1323 | /// Do not check digest in Keeper after internal subquery, it's probably not committed yet |
| 1324 | if (local_context->isInternalSubquery()) |
| 1325 | return true; |
| 1326 | |
| 1327 | /// Check does not make sense to check digest in Keeper during recovering |
| 1328 | if (is_recovering) |
| 1329 | return true; |
| 1330 | |
| 1331 | String zk_digest = getZooKeeper()->get(replica_path + "/digest"); |
| 1332 | String local_digest_str = toString(local_digest); |
| 1333 | if (zk_digest != local_digest_str) |
| 1334 | { |
| 1335 | LOG_ERROR(log, "Digest of local metadata ({}) is not equal to digest in Keeper ({})", local_digest_str, zk_digest); |
| 1336 | #ifndef NDEBUG |
| 1337 | tryCompareLocalAndZooKeeperTablesAndDumpDiffForDebugOnly(local_context); |
| 1338 | #endif |
| 1339 | return false; |
| 1340 | } |
| 1341 | |
| 1342 | return true; |
| 1343 | } |
| 1344 | |
| 1345 | void DatabaseReplicated::checkQueryValid(const ASTPtr & query, ContextPtr query_context) const |
| 1346 | { |
no test coverage detected