#include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace DB { namespace ErrorCodes { extern const int LOGICAL_ERROR; } } namespace DB { NamesAndTypesList StorageSystemRocksDB::getNamesAndTypes() { return { { "database", std::make_shared() }, { "table", std::make_shared() }, { "name", std::make_shared() }, { "value", std::make_shared() }, }; } void StorageSystemRocksDB::fillData(MutableColumns & res_columns, ContextPtr context, const SelectQueryInfo & query_info) const { const auto access = context->getAccess(); const bool check_access_for_databases = !access->isGranted(AccessType::SHOW_TABLES); using RocksDBStoragePtr = std::shared_ptr; std::map> tables; for (const auto & db : DatabaseCatalog::instance().getDatabases()) { const bool check_access_for_tables = check_access_for_databases && !access->isGranted(AccessType::SHOW_TABLES, db.first); for (auto iterator = db.second->getTablesIterator(context); iterator->isValid(); iterator->next()) { StoragePtr table = iterator->table(); RocksDBStoragePtr rocksdb_table = table ? std::dynamic_pointer_cast(table) : nullptr; if (!rocksdb_table) continue; if (check_access_for_tables && !access->isGranted(AccessType::SHOW_TABLES, db.first, iterator->name())) continue; tables[db.first][iterator->name()] = rocksdb_table; } } MutableColumnPtr col_database_mut = ColumnString::create(); MutableColumnPtr col_table_mut = ColumnString::create(); for (auto & db : tables) { for (auto & table : db.second) { col_database_mut->insert(db.first); col_table_mut->insert(table.first); } } ColumnPtr col_database_to_filter = std::move(col_database_mut); ColumnPtr col_table_to_filter = std::move(col_table_mut); /// Determine what tables are needed by the conditions in the query. { Block filtered_block { { col_database_to_filter, std::make_shared(), "database" }, { col_table_to_filter, std::make_shared(), "table" }, }; VirtualColumnUtils::filterBlockWithQuery(query_info.query, filtered_block, context); if (!filtered_block.rows()) return; col_database_to_filter = filtered_block.getByName("database").column; col_table_to_filter = filtered_block.getByName("table").column; } bool show_zeros = context->getSettingsRef().system_events_show_zero_values; for (size_t i = 0, tables_size = col_database_to_filter->size(); i < tables_size; ++i) { String database = (*col_database_to_filter)[i].safeGet(); String table = (*col_table_to_filter)[i].safeGet(); auto statistics = tables[database][table]->getRocksDBStatistics(); if (!statistics) throw Exception(ErrorCodes::LOGICAL_ERROR, "RocksDB statistics are not available"); for (auto [tick, name] : rocksdb::TickersNameMap) { UInt64 value = statistics->getTickerCount(tick); if (!value && !show_zeros) continue; /// trim "rocksdb." if (startsWith(name, "rocksdb.")) name = name.substr(strlen("rocksdb.")); size_t col_num = 0; res_columns[col_num++]->insert(database); res_columns[col_num++]->insert(table); res_columns[col_num++]->insert(name); res_columns[col_num++]->insert(value); } } } }