Skip to content
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

Resolve table dependencies on metadata loading #28373

Merged
merged 13 commits into from
Sep 20, 2021
Merged

Conversation

tavplubix
Copy link
Member

@tavplubix tavplubix commented Aug 30, 2021

I hereby agree to the terms of the CLA available at: https://yandex.ru/legal/cla/?lang=en

Changelog category (leave one):

  • Improvement

Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
Resolve table dependencies on metadata loading. Closes #8004, closes #15170.

Detailed description / Documentation draft:

@robot-clickhouse robot-clickhouse added the pr-improvement Pull request with some product improvements label Aug 30, 2021
@tavplubix tavplubix added the force tests The label does nothing, NOOP, None, nil label Aug 31, 2021
@robot-ch-test-poll1 robot-ch-test-poll1 added the submodule changed At least one submodule changed in this PR. label Sep 1, 2021
@tavplubix tavplubix removed the submodule changed At least one submodule changed in this PR. label Sep 2, 2021
@tavplubix tavplubix marked this pull request as ready for review September 2, 2021 13:36
@tavplubix
Copy link
Member Author

Test failures are irrelevant

@alesapin alesapin self-assigned this Sep 8, 2021
@alesapin
Copy link
Member

alesapin commented Sep 8, 2021

@Mergifyio update

@mergify
Copy link
Contributor

mergify bot commented Sep 8, 2021

Command update: success

Branch has been successfully updated

@tavplubix
Copy link
Member Author

Functional stateless tests flaky check (address) - Dictionary (`test_9dzpz8.dict1`) not found ... - looks like race in ExternalLoader, I will try to debug it

@tavplubix
Copy link
Member Author

Functional stateless tests flaky check (address) - Dictionary (`test_9dzpz8.dict1`) not found ... - looks like race in ExternalLoader, I will try to debug it

#28853

Copy link
Member

@alesapin alesapin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general looks good to me, simple and straightforward implementation.


void DDLDependencyVisitor::visit(const ASTFunction & function, Data & data)
{
if (function.name == "joinGet" ||
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it worth to make a property for such functions?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will have to create a function through FunctionFactory just to check if it can take table/dictionary name as argument or not, so I'm not sure.

if (literal->value.getType() != Field::Types::String)
return;

String maybe_qualified_name = literal->value.get<String>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still don't have a function for parsing qualified names?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we don't, because for historical reasons parsing of qualified name from string literal is a bit different from parsing of compound identifier from SQL query.

else if (const auto * identifier = arg->as<ASTIdentifier>())
{
auto table_identifier = identifier->createTable();
if (!table_identifier)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment? Not clear to me how we can get here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can get here if create query is incorrect and compound identifier has 3 (or more) name parts.

if (!dict_source.elements)
return;

auto config = getDictionaryConfigurationFromAST(data.create_query->as<ASTCreateQuery &>(), data.global_context);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also very soon we will have predefined connections... I'd prefer to move this part into separate function like isLocalDictionaryFromClickHouseTable or something like this.

class ASTFunctionWithKeyValueArguments;


class DDLDependencyVisitor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need comment.

String default_database;

std::mutex mutex;
ParsedMetadata metadata;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Metadata inside metadata :) Maybe just ParsedTables?

@@ -14,4 +15,6 @@ void loadMetadataSystem(ContextMutablePtr context);
/// Use separate function to load system tables.
void loadMetadata(ContextMutablePtr context, const String & default_database_name = {});

void startupSystemTables();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment why it is required?

iterateMetadataFiles(local_context, process_metadata);

size_t total_tables = file_names.size() - total_dictionaries;
ParsedTablesMetadata metadata;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

metadata -> parsed_tables?


void startLoadingIndependentTables(ThreadPool & pool, size_t level);

void checkCyclicDependencies() const;
Copy link
Member

@alesapin alesapin Sep 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be called only after we have loaded everything what was possible to load.

}

void DatabaseOrdinary::startupTablesImpl(ThreadPool & thread_pool)
void DatabaseOrdinary::startupTables(ThreadPool & thread_pool, bool /*force_restore*/, bool /*force_attach*/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slightly unclear interface -- why we create pool out of this function scope, but wait it here?

@tavplubix tavplubix removed the force tests The label does nothing, NOOP, None, nil label Sep 13, 2021
@alesapin
Copy link
Member

Integration tests failures related?

@tavplubix
Copy link
Member Author

Integration tests failures related?

Seems like they are

@tavplubix
Copy link
Member Author

Functional stateless tests (release, DatabaseReplicated) - merge stuck with Directory tmp_merge_9_0_64_2/ already exists

2021-09-14 11:20:15 sync failed, queue:	default	alter_table_1	r_1auto_r1	0	queue-0000003927	MERGE_PARTS	2021-09-14 11:13:34	0	r_8auto_r2	9_0_64_2	['9_0_1_1','9_2_2_0','9_3_3_0','9_5_5_0','9_6_6_0','9_7_7_0','9_9_16_1','9_17_27_1','9_28_28_0','9_29_29_0','9_30_30_0','9_33_45_1','9_47_47_0','9_49_49_0','9_52_52_0','9_54_54_0','9_56_64_1']	0	0	1622	Code: 84. DB::Exception: Directory /var/lib/clickhouse/store/397/3976fa6a-afd1-4c7b-b976-fa6aafd11c7b/tmp_merge_9_0_64_2/ already exists. (DIRECTORY_ALREADY_EXISTS) (version 21.11.1.8075)	2021-09-14 11:20:14	26	Not executing log entry queue-0000003927 of type MERGE_PARTS for part 9_0_64_2 because source parts size (8.59 MiB) is greater than the current maximum (4.45 MiB). 1 free of 16 threads, required 8 free threads.	2021-09-14 11:13:46	REGULAR

@filimonov
Copy link
Contributor

What do you think of #7944 - needed for schema dumps & recreate on the other node

/// How many dependencies this table have
size_t dependencies_count = 0;
/// List of tables/dictionaries which depend on this table/dictionary
TableNames dependent_database_objects;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dependency_kind (enum) may also be useful sometimes (could be exposed in system.tables for introspection / schema analise) but can be done later

Copy link
Member

@alesapin alesapin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@tavplubix
Copy link
Member Author

Functional stateless tests (release, DatabaseReplicated) - 01161_all_system_tables - fixed in #29061

@tavplubix tavplubix merged commit 922cf7e into master Sep 20, 2021
@tavplubix tavplubix deleted the tables_topsort branch September 20, 2021 11:46
@tavplubix tavplubix mentioned this pull request Sep 20, 2021
tavplubix added a commit that referenced this pull request Sep 21, 2021
@tavplubix
Copy link
Member Author

It's because table test_9.join does not exist.

else if (Poco::toLower(function.name) == "in")
{
extractTableNameFromArgument(function, data, 1);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tavplubix
Do you remember what is the reason that loading of a table depends on the default expressions for its columns? The default expression should be required only during insertion to that table, shouldn't they?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, there was a check that the default expression type is compatible with the column type, but probably there's another reason.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr-improvement Pull request with some product improvements
Projects
None yet
7 participants