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

Added max_sessions_for_user setting #51724

Merged
merged 3 commits into from Jul 31, 2023
Merged

Conversation

Demilivor
Copy link
Contributor

@Demilivor Demilivor commented Jul 3, 2023

Closes #44032.

This change adds a limit on the maximum number of simultaneous sessions per authenticated user.

Changelog category (leave one):

  • New Feature

Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):

Added max_sessions_for_user setting

@Demilivor

This comment was marked as outdated.

@qoega qoega added the can be tested Allows running workflows for external contributors label Jul 3, 2023
@robot-ch-test-poll4 robot-ch-test-poll4 added the pr-feature Pull request with new product feature label Jul 3, 2023
@robot-ch-test-poll4
Copy link
Contributor

robot-ch-test-poll4 commented Jul 3, 2023

This is an automated comment for commit 7e9e0ac with description of existing statuses. It's updated for the latest CI running
The full report is available here
The overall status of the commit is 🔴 failure

Check nameDescriptionStatus
AST fuzzerRuns randomly generated queries to catch program errors. The build type is optionally given in parenthesis. If it fails, ask a maintainer for help🟢 success
CI runningA meta-check that indicates the running CI. Normally, it's in success or pending state. The failed status indicates some problems with the PR🟢 success
ClickHouse build checkBuilds ClickHouse in various configurations for use in further steps. You have to fix the builds that fail. Build logs often has enough information to fix the error, but you might have to reproduce the failure locally. The cmake options can be found in the build log, grepping for cmake. Use these options and follow the general build process🟢 success
Compatibility checkChecks that clickhouse binary runs on distributions with old libc versions. If it fails, ask a maintainer for help🟢 success
Docker image for serversThe check to build and optionally push the mentioned image to docker hub🟢 success
Docs CheckBuilds and tests the documentation🟢 success
Fast testNormally this is the first check that is ran for a PR. It builds ClickHouse and runs most of stateless functional tests, omitting some. If it fails, further checks are not started until it is fixed. Look at the report to see which tests fail, then reproduce the failure locally as described here🟢 success
Flaky testsChecks if new added or modified tests are flaky by running them repeatedly, in parallel, with more randomization. Functional tests are run 100 times with address sanitizer, and additional randomization of thread scheduling. Integrational tests are run up to 10 times. If at least once a new test has failed, or was too long, this check will be red. We don't allow flaky tests, read the doc🟢 success
Install packagesChecks that the built packages are installable in a clear environment🟢 success
Integration testsThe integration tests report. In parenthesis the package type is given, and in square brackets are the optional part/total tests🟢 success
Mergeable CheckChecks if all other necessary checks are successful🟢 success
Performance ComparisonMeasure changes in query performance. The performance test report is described in detail here. In square brackets are the optional part/total tests🟢 success
Push to DockerhubThe check for building and pushing the CI related docker images to docker hub🟢 success
SQLancerFuzzing tests that detect logical bugs with SQLancer tool🟢 success
SqllogicRun clickhouse on the sqllogic test set against sqlite and checks that all statements are passed🟢 success
Stateful testsRuns stateful functional tests for ClickHouse binaries built in various configurations -- release, debug, with sanitizers, etc🟢 success
Stateless testsRuns stateless functional tests for ClickHouse binaries built in various configurations -- release, debug, with sanitizers, etc🟢 success
Stress testRuns stateless functional tests concurrently from several clients to detect concurrency-related errors🟢 success
Style CheckRuns a set of checks to keep the code style clean. If some of tests failed, see the related log from the report🟢 success
Unit testsRuns the unit tests for different release types🟢 success
Upgrade checkRuns stress tests on server version from last release and then tries to upgrade it to the version from the PR. It checks if the new server can successfully startup without any errors, crashes or sanitizer asserts🔴 failure

@rvasin

This comment was marked as outdated.

@rvasin

This comment was marked as outdated.

@rschu1ze rschu1ze self-assigned this Jul 17, 2023
@rschu1ze

This comment was marked as outdated.

@rschu1ze
Copy link
Member

rschu1ze commented Jul 17, 2023

My understanding is that the existing server parameter max_connections (default: 1024) already provides sufficient protection against DoS, independently if

  • the users are unknown/untrusted and have public credentials, e.g. user/password "default/default", or
  • the users are known and have "private" credentials (e.g. "denis"/"12345!@#$%").

The subject of protection is the server itself.

This PR aims to make this protection more fine-granular which will be handy for "untrusted" public credentials. In more detail, it can prevent the case that a single untrusted user is able to flood the server with hundreds of connections at the detriment of other (e.g. trusted) users that behave normally. Th is is different from max_connections as the subject of protection are other users.

docs/en/operations/settings/query-complexity.md Outdated Show resolved Hide resolved
docs/en/operations/settings/query-complexity.md Outdated Show resolved Hide resolved
docs/en/operations/settings/query-complexity.md Outdated Show resolved Hide resolved
src/Core/Settings.h Outdated Show resolved Hide resolved
src/Interpreters/SessionTracker.h Outdated Show resolved Hide resolved
src/Interpreters/SessionTracker.h Outdated Show resolved Hide resolved
src/Interpreters/SessionTracker.cpp Outdated Show resolved Hide resolved
src/Interpreters/Context.cpp Show resolved Hide resolved
enabled_quota = access_control->getEnabledQuota(
*params.user_id, user_name, roles_info->enabled_roles, params.address, params.forwarded_address, params.quota_key);

/// TCP connection handler receives quota key after session creation
Copy link
Member

Choose a reason for hiding this comment

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

I don't really understand the changes around the quota_key. How is it related to the session tracking?

Copy link
Contributor 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 if my solution is the best, but I haven't found a better and simpler solution to not change the current TCP protocol and make both client and server work without errors.
If you have better ideas, I will be happy to implement them.

During a session between client and server, the client assumes that there should be no errors on the server side after the server has replied Hello.
However, with the addition of the max_sessions_per_user constraint, throwing an error after server hello is now possible. To get max_sessions_per_user we need to reach the profile settings, and to do that we need to create a session context.
Creating a session context and creating a quota without a quota key can throw exception.

To better understand the problem, I have created attached images.
I hope they will make it easier to understand.

bad_variant_make_session_context_after_sending_hello
bad_variant_quota_key_initialize
good_variant

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the detailed explanation and the figures, I understood the problem now 😄

I am not an expert with the TCP protocol, but the current solution looks fine to me (not great but also not terrible) - we can go with it. My main question at this point is about this assumption:

During a session between client and server, the client assumes that there should be no errors on the server side after the server has replied Hello.

That's interesting. What happens exactly on the client? Does the connection abruptly end?

I see that there is a handler for exceptions: sendException(). Just curious, would it be possible to use this to send an exception after "Hello" to the client?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's interesting. What happens exactly on the client? Does the connection abruptly end?

Server closes connection.
If exception happens after hello received from server client tries to send quota key if it has it. Usually server doesn't have time to close the connection while the client is sending quota key, this step passes (Client and server are on the same computer).
If the client was in interactive mode then it waits for query to enter.
After client has an query then it tries to send it to the server. Client detects that connection is closed by Connection::ping and doesn't print any error (client does not read exception code at all), and finally client tries to reconnect and reauthenticate.

I see that there is a handler for exceptions: sendException(). Just curious, would it be possible to use this to send an exception > after "Hello" to the client?

Yes, but client doesn't read the socket data after receiving hello from server, because it does not expect an error.

src/Interpreters/Context.cpp Outdated Show resolved Hide resolved
@Demilivor
Copy link
Contributor Author

Most of the core team was on an offsite meeting last week. I'll take a look.

Thank you for the thoughtful review!

My understanding is that the existing server parameter max_connections (default: 1024) already provides sufficient protection against DoS, independently if

  • the users are unknown/untrusted and have public credentials, e.g. user/password "default/default", or
  • the users are known and have "private" credentials (e.g. "denis"/"12345!@#$%").

The subject of protection is the server itself.

This PR aims to make this protection more fine-granular which will be handy for "untrusted" public credentials. In more detail, it can prevent the case that a single untrusted user is able to flood the server with hundreds of connections at the detriment of other (e.g. trusted) users that behave normally. Th is is different from max_connections as the subject of protection are other users.

You're getting the right idea.
PR adds a limit on the maximum number of simultaneous connections on some users,
This is an additional protection that is not enabled by default and should not hurt existing ClickHouse clients.
It can cover this use-case:

There are 4 analysts in the company, they use one clickhouse account, there should not be more than 4 simultaneous connections, in case of the 5th connection, it should be immediately disabled.

Session Tracker currently records not only the number of connections, but also information about connections, perhaps in the future it will be possible to create a new system table System.ActiveSessions, it will contain all information about all current connections in the system. It is not very convenient to use Session Log for this purpose.

docs/en/operations/settings/query-complexity.md Outdated Show resolved Hide resolved
docs/en/operations/settings/query-complexity.md Outdated Show resolved Hide resolved
src/Interpreters/Context.cpp Show resolved Hide resolved
@rschu1ze
Copy link
Member

Session Tracker currently records not only the number of connections, but also information about connections, perhaps in the future it will be possible to create a new system table System.ActiveSessions, it will contain all information about all current connections in the system. It is not very convenient to use Session Log for this purpose.

I generally like this idea 👍 ... but before going ahead and implementing it, I recommend to first discuss the system table fields in an RFC issue on GitHub.

src/Interpreters/Session.cpp Outdated Show resolved Hide resolved
src/Interpreters/Session.cpp Outdated Show resolved Hide resolved
src/Interpreters/SessionTracker.cpp Show resolved Hide resolved
src/Interpreters/Session.cpp Outdated Show resolved Hide resolved
enabled_quota = access_control->getEnabledQuota(
*params.user_id, user_name, roles_info->enabled_roles, params.address, params.forwarded_address, params.quota_key);

/// TCP connection handler receives quota key after session creation
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the detailed explanation and the figures, I understood the problem now 😄

I am not an expert with the TCP protocol, but the current solution looks fine to me (not great but also not terrible) - we can go with it. My main question at this point is about this assumption:

During a session between client and server, the client assumes that there should be no errors on the server side after the server has replied Hello.

That's interesting. What happens exactly on the client? Does the connection abruptly end?

I see that there is a handler for exceptions: sendException(). Just curious, would it be possible to use this to send an exception after "Hello" to the client?

@Demilivor
Copy link
Contributor Author

That's interesting. What happens exactly on the client? Does the connection abruptly end?

Server closes connection.
If exception happens after hello received from server client tries to send quota key if it has it. Usually server doesn't have time to close the connection while the client is sending quota key, this step passes (Client and server are on the same computer).
If the client was in interactive mode then it waits for query to enter.
After client has an query then it tries to send it to the server. Client detects that connection is closed by Connection::ping and doesn't print any error (client does not read exception code at all), and finally client tries to reconnect and reauthenticate.

I see that there is a handler for exceptions: sendException(). Just curious, would it be possible to use this to send an exception > after "Hello" to the client?

Yes, but client doesn't read the socket data after receiving hello from server, because it does not expect an error.

@Demilivor
Copy link
Contributor Author

I generally like this idea 👍 ... but before going ahead and implementing it, I recommend to first discuss the system table fields in an RFC issue on GitHub.

Of course we will create RFC issue if there is a need to create such a table, but at the moment there is no immediate need.

@Demilivor Demilivor changed the title Added max_sessions_per_user setting Added max_sessions_for_user setting Jul 19, 2023
session_tracker_handle = session_context->getSessionTracker().trackSession(
*user_id,
{ session_name_ },
session_context->getSettingsRef().max_sessions_for_user);
Copy link
Member

Choose a reason for hiding this comment

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

Can a user update the value of max_sessions_for_user in the session_context by executing a SET query, for example?

Copy link
Contributor Author

@Demilivor Demilivor Jul 19, 2023

Choose a reason for hiding this comment

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

Yes, but Behaviour will not be oblivious for user,
SET sets changes in current session, but it will not have effect, because max_sessions_for_user value is taken from user profile, not session:

// in profile we have max_sessions_for_user = 0

Client_1 (user Alice):
SET max_sessions_for_user = 1 // changes value for client_1 only
SELECT value FROM  system.settings WHERE name="max_sessions_for_user" // return 1

Client 2 (user Alice):
SELECT value FROM  system.settings WHERE name="max_sessions_for_user" // return 0

Client 3 (user Alice): // connections count per user (3) already
SET max_sessions_for_user = 1 // active session willl continue.

So it looks like a bug to me. This bug can be applied to other settings from profile without contraints.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This SQL looks like working:

ALTER SETTINGS PROFILE <dynamic_non_readonly_profile> SETTINGS max_sessions_for_user = 1

It will not close active sessions, but at least it will not allow to start new sessions.

I would certainly throw exception when trying to set up any settings taken from the profile for a session, but during quick looking into the code of how SET work and got no easy solution. I would create an separate issue for that and investigate the problem more thoughtful.

Copy link
Member

Choose a reason for hiding this comment

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

because max_sessions_for_user value is taken from user profile, not session

No, it's taken from session_context:
https://github.com/ClickHouse/ClickHouse/blob/d3e08a1e2a91cd4bef08b8270e5e68d05332a770/src/Interpreters/Session.cpp#L470

You probably mean that it's a new session_context that was just created and the user could not modify it. But it's not true for named http sessions because NamedSessionsStorage may return an existing session that was already in use, so the setting could be modified:
https://github.com/ClickHouse/ClickHouse/blob/d3e08a1e2a91cd4bef08b8270e5e68d05332a770/src/Interpreters/Session.cpp#L443-L444

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the case of a named session, if session_context was already created, It is possible that max_sessions_for_user will have an old value:
https://github.com/ClickHouse/ClickHouse/blob/d3e08a1e2a91cd4bef08b8270e5e68d05332a770/src/Interpreters/Session.cpp#L458-L459

So, yes, it looks like a problem in this case:

ALTER SETTINGS PROFILE ALICE_PROFILE  max_sessions_for_user = 100
User  Alice started session_id_1 // session lifetime is 1000, max_session_per_user = 100
User  Alice started session_id_2 // session lifetime is 1000, max_session_per_user = 100
User  Alice started session_id_3 // session lifetime is 1000, max_session_per_user = 100
ALTER SETTINGS PROFILE ALICE_PROFILE  max_sessions_for_user = 1
User Alice finished session_id_3 // named session is not deleted and context remains valid with max_session_per_user = 100
User Alice started session_id_3 // existing context was reused with max_session_per_user = 100

Calling new_session_context->setUser(*user_id) always before reading max_sessions_for_user will fix the issue.
setUser is quite a complicated operation, do you know a better way to get the max_sessions_for_user value?

Copy link
Member

@tavplubix tavplubix Jul 21, 2023

Choose a reason for hiding this comment

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

Calling new_session_context->setUser(*user_id) always before reading max_sessions_for_user will fix the issue.

And will break SET queries (because it will overwrite all the settings with the user's defaults, not only max_sessions_for_user)

setUser is quite a complicated operation, do you know a better way to get the max_sessions_for_user value?

I don't know. We can take something from the implementation of setUser, maybe smth like access->getDefaultProfileInfo()->settings.max_sessions_for_user will work. Or we can save the value in NamedSessionData when creating a session. Or we can forbid changing the setting (see Context::setSettings and Context::recalculateAccessRightsIfNeeded)

Copy link
Contributor Author

@Demilivor Demilivor Jul 24, 2023

Choose a reason for hiding this comment

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

Thanks for the explanation.

Just pushed an update that should forbid using SET max_sessions_for_user = 10 and several other parameters that shouldn't be updated by SET query  or SETTINGS like

clickhouse-client -q "select 1 SETTINGS max_sessions_for_user = 1"

// error
Received exception from server (version 23.7.1):
Code: 164. DB::Exception: Received from localhost:9000. DB::Exception: Setting max_sessions_for_user is not allowed to be set by query. (READONLY)
(query: select 1 SETTINGS max_sessions_for_user = 2)

ALTER SETTINGS PROFILE works fine.

clickhouse-client -q "create profile my_profile"
clickhouse-client -q "ALTER SETTINGS PROFILE 'my_profile' SETTINGS max_sessions_for_user = 2"

Copy link
Contributor Author

@Demilivor Demilivor Jul 25, 2023

Choose a reason for hiding this comment

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

I removed settings source restrictions from SettingsConstraints.cpp for other parameters, and left just for max_sessions_for_user just to not accidentally break something. This pool request is already big.

Comment on lines 467 to 568
session_tracker_handle = session_context->getSessionTracker().trackSession(
*user_id,
{ session_name_ },
session_context->getSettingsRef().max_sessions_for_user);
Copy link
Member

@tavplubix tavplubix Jul 19, 2023

Choose a reason for hiding this comment

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

Hm, seems like it will count one named http session multiple times. Please add a test with named http sessions (see session_id parameter)

Copy link
Contributor Author

@Demilivor Demilivor Jul 20, 2023

Choose a reason for hiding this comment

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

I will add a test with different sesssion IDs, but this should not be an issue because session id must be unique for all sessions on server.

I got this error, if i try to use the same session id for HTTP:

ClickHouse HTTP server returned 500 Internal Server Error: Code: 373. DB::Exception: Session 1 is locked by a concurrent client. (SESSION_IS_LOCKED) (version 23.7.1.1)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done (Test added)

Copy link
Member

Choose a reason for hiding this comment

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

The tricky part is that named http sessions can be reused. Of course, it's not allowed to use the same session concurrently, but it's totally fine to use it sequentially from different http requests. A new session will not be created for each request, the old one will be reused instead.

Copy link
Member

Choose a reason for hiding this comment

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

I've just tested it locally, and found that it counts an http session only if there's a running query in this session. So it's possible to open an unlimited number of named http sessions (max_sessions_for_user = 2):

    ~/ch/test  echo "select 1" | curl -X POST "http://localhost:8123/?user=maxsessions&session_id=1" -d @-                                                                                                                        ✔ 
1
    ~/ch/test  echo "select 1" | curl -X POST "http://localhost:8123/?user=maxsessions&session_id=2" -d @-                                                                                                                        ✔ 
1
    ~/ch/test  echo "select 1" | curl -X POST "http://localhost:8123/?user=maxsessions&session_id=3" -d @-                                                                                                                        ✔ 
1
    ~/ch/test  echo "select 1" | curl -X POST "http://localhost:8123/?user=maxsessions&session_id=4" -d @-                                                                                                                        ✔ 
1
    ~/ch/test  echo "select 1" | curl -X POST "http://localhost:8123/?user=maxsessions&session_id=5" -d @-                                                                                                                        ✔ 
1

(now there are 5 sessions, they will be closed after default_session_timeout seconds)

But it will not be possible to use more than 2 sessions concurrently anyway, so maybe it's fine

Copy link
Member

Choose a reason for hiding this comment

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

Hm, no, it's possible if you update the setting with a SET query: https://pastila.nl/?0120fcc0/a41fe96d1a48546e4a4939fec4fc1c7a

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Confirm this issue. I'm going to fix it in the next update of this PR.

A simple uncoditional call to new_session_context->setUser(*user_id) in makeSessionContext for named sessions fixes the issue (in my old code not upmerged with master), But I'm not sure if there are any pitfalls I haven't considered.

I got several merge conflicts with master and can't update the code right now. I hope to finish the update on Monday if I do not meet other issues.

Copy link
Member

Choose a reason for hiding this comment

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

A simple uncoditional call to new_session_context->setUser(*user_id) in makeSessionContext for named sessions fixes the issue

See #51724 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This issue is no longer actual, because SET for max_sessions_for_user is prohibited now.

A similar case with ALTER SETTINGS PROFILE works fine. See the test tests/queries/0_stateless/02832_alter_max_sessions_for_user.sh

@tavplubix
Copy link
Member

There's a minor usability issue:

  1. Create a user with <max_sessions_for_user>2</max_sessions_for_user>
  2. Connect to the server with clickhouse-client in interactive mode (starts a session)
  3. Run another instance of interactive clickhouse-client. If will fail to load suggestions (due to the limitation on concurrent sessions) but then will continue working as usual:
ClickHouse client version 23.7.1.1.
Connecting to localhost:9000 as user maxsessions.
Connected to ClickHouse server version 23.7.1 revision 54464.

Warnings:
 * Server was built with sanitizer. It will work slowly.
 * Server logging level is set to 'test' and performance is degraded. This cannot be used in production.
 * Some obsolete setting is changed. Check 'select * from system.settings where changed' and read the changelog.

Cannot load data for command line suggestions: Code: 700. DB::Exception: Received from localhost:9000. DB::Exception: User 5eb5f051-64a4-19bc-ff75-494154bf67a9 has overflown session count 2. () (version 23.7.1.1)
dell9510 :) select 1

SELECT 1

Query id: e860678a-650c-499d-8852-d1c44f3cd06e

┌─1─┐
│ 1 │
└───┘

1 row in set. Elapsed: 0.002 sec. 

dell9510 :) 

@tavplubix tavplubix self-assigned this Jul 20, 2023
@Demilivor
Copy link
Contributor Author

There's a minor usability issue:

  1. Create a user with <max_sessions_for_user>2</max_sessions_for_user>
  2. Connect to the server with clickhouse-client in interactive mode (starts a session)
  3. Run another instance of interactive clickhouse-client. If will fail to load suggestions (due to the limitation on concurrent sessions) but then will continue working as usual:
ClickHouse client version 23.7.1.1.
Connecting to localhost:9000 as user maxsessions.
Connected to ClickHouse server version 23.7.1 revision 54464.

Warnings:
 * Server was built with sanitizer. It will work slowly.
 * Server logging level is set to 'test' and performance is degraded. This cannot be used in production.
 * Some obsolete setting is changed. Check 'select * from system.settings where changed' and read the changelog.

Cannot load data for command line suggestions: Code: 700. DB::Exception: Received from localhost:9000. DB::Exception: User 5eb5f051-64a4-19bc-ff75-494154bf67a9 has overflown session count 2. () (version 23.7.1.1)
dell9510 :) select 1

SELECT 1

Query id: e860678a-650c-499d-8852-d1c44f3cd06e

┌─1─┐
│ 1 │
└───┘

1 row in set. Elapsed: 0.002 sec. 

dell9510 :) 

This is a known issue. I added a comment for this issue. The client should work fine, but without receiving suggestions for connection.
I think we should create a new issue to fix this after this PR.

I see two main ways of fixing this:

  1. Somehow indicate the suggestion connection to let the server know that this connection should not be counted.
  2. If the suggestion connection fails, try to get the suggestion on the main connection.

@Demilivor Demilivor force-pushed the ADQM-939 branch 2 times, most recently from 3790f89 to deabacf Compare July 27, 2023 02:08
@Demilivor
Copy link
Contributor Author

The style check failed in files I did not change:

https://s3.amazonaws.com/clickhouse-test-reports/51724/deabacfc15e7ab8b08508c1e6a0c4ab03574511f/style_check/style_output.txt

/ClickHouse/src/Processors/Formats/Impl/Parquet/Write.cpp:758:                N(UInt8 , Int32Type);
/ClickHouse/src/Processors/Formats/Impl/Parquet/Write.cpp:764:        case TypeIndex::Int16  : N(Int16 , Int32Type); break;
/ClickHouse/src/Processors/Formats/Impl/Parquet/Write.cpp:765:        case TypeIndex::Int32  : N(Int32 , Int32Type); break;
/ClickHouse/src/Processors/Formats/Impl/Parquet/Write.cpp:766:        case TypeIndex::Int64  : N(Int64 , Int64Type); break;
/ClickHouse/src/Processors/Formats/Impl/Parquet/Write.cpp:769:        case TypeIndex::Enum16:     N(Int16 , Int32Type); break;
/ClickHouse/src/Processors/Formats/Impl/Parquet/Write.cpp:771:        case TypeIndex::Date32:     N(Int32 , Int32Type); break;
/ClickHouse/src/Processors/Formats/Impl/Parquet/PrepareForWrite.cpp:306:                types(T::INT32, C::UINT_8 , int_type(8 , false));
/ClickHouse/src/Processors/Formats/Impl/Parquet/PrepareForWrite.cpp:312:        case TypeIndex::Int8:   types(T::INT32, C::INT_8  , int_type(8 , true)); break;
/ClickHouse/src/Processors/Formats/Impl/Parquet/PrepareForWrite.cpp:313:        case TypeIndex::Int16:  types(T::INT32, C::INT_16 , int_type(16, true)); break;
/ClickHouse/src/Processors/Formats/Impl/Parquet/PrepareForWrite.cpp:322:        case TypeIndex::Enum8:    types(T::INT32, C::INT_8  , int_type(8 , true)); break; //  Int8
/ClickHouse/src/Processors/Formats/Impl/Parquet/PrepareForWrite.cpp:323:        case TypeIndex::Enum16:   types(T::INT32, C::INT_16 , int_type(16, true)); break; //  Int16
/ClickHouse/src/Processors/Formats/Impl/Parquet/PrepareForWrite.cpp:395:        case TypeIndex::Decimal32:  decimal(4 , getDecimalPrecision(*type), getDecimalScale(*type)); break;
/ClickHouse/src/Processors/Formats/Impl/Parquet/PrepareForWrite.cpp:396:        case TypeIndex::Decimal64:  decimal(8 , getDecimalPrecision(*type), getDecimalScale(*type)); break;
^ There is bad punctuation: whitespace before comma. You should write it like this: 'Hello, world!'

@tavplubix
Copy link
Member

It was accidentally broken in master due to a race condition between #49367 and #52549

It's fixed in #52647, please update your branch

@tavplubix
Copy link
Member

Upgrade check (asan) - #52540

@tavplubix tavplubix merged commit 7359a81 into ClickHouse:master Jul 31, 2023
277 of 279 checks passed
@Demilivor
Copy link
Contributor Author

Created and issue to fix this: #51724 (comment) #52843

@tavplubix
Copy link
Member

@alexey-milovidov
Copy link
Member

@tavplubix, we have a "fearless reverting" policy - if a test is flaky - revert the feature.

@Demilivor
Copy link
Contributor Author

I apologize,

This test was my first integration test for ClickHouse,
when I created this test I didn't know about the possibility of running tests in parallel and test reordering.
This test has always performed without any error on the my machine.

I have removed the dependency on sleep and test execution order in this pool request
#52897

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
can be tested Allows running workflows for external contributors pr-feature Pull request with new product feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

add setting max_connections_per_user
7 participants