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

Change default key column size and make it configurable for MySQL and Oracle #2245

Merged
merged 7 commits into from
Sep 30, 2024

Conversation

jnmt
Copy link
Contributor

@jnmt jnmt commented Sep 20, 2024

Description

This PR changes the default key column size and makes it configurable for MySQL and Oracle.

Background:
Currently, the default key column size for MySQL and Oracle is 64 bytes due to the underlying database limitation. It is sometimes short for certain applications. For example, ScalarDL uses the binary name of the class to identify a contract, and it often exceeds 64 bytes.

Solution:
We change the default value to 128 bytes. In addition, we make it configurable because the underlying databases limit the total size of primary key columns; i.e., the larger default key column size affects the total number of primary key columns. So, users may want to create a primary key with a large number of small key columns size.

Related issues and/or PRs

N/A

Changes made

  • Add options for changing the key column size for MySQL and Oracle and use 128 bytes as the default

Checklist

  • I have commented my code, particularly in hard-to-understand areas.
  • I have updated the documentation to reflect the changes.
  • Any remaining open issues linked to this PR are documented and up-to-date (Jira, GitHub, etc.).
  • Tests (unit, integration, etc.) have been added for the changes.
  • My changes generate no new warnings.
  • Any dependent changes in other PRs have been merged and published.

Additional notes (optional)

This change is backward-compatible since it doesn't affect existing tables.

Release notes

Added options for changing the key column size for MySQL and Oracle and used 128 bytes as the default.

Comment on lines +50 to +53
public static final String MYSQL_VARIABLE_KEY_COLUMN_SIZE =
PREFIX + "mysql.variable_key_column_size";
public static final String ORACLE_VARIABLE_KEY_COLUMN_SIZE =
PREFIX + "oracle.variable_key_column_size";
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 introduced two separate settings (only) for MySQL and Oracle for the following reasons.

  • PostgreSQL also has a limit of 10485760 for each key column (but not for total). So, users might be confused if the common setting jdbc.variable_key_column_size does not affect it.
  • We can also make the limit of PostgreSQL configurable, but the common settings would decrease the current limit since 10485760 is too large for MySQL and Oracle.
  • I guess there is no motivation to decrease 10485760 for PostgreSQL.

Copy link
Contributor

@Torch3333 Torch3333 Sep 25, 2024

Choose a reason for hiding this comment

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

What is the reasoning for adding variable in the configuration name?
In essence, it is a configuration, implying that the value is configurable (== variable). Following the same logic, we could have added variable in all the other configuration names.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Torch3333 Thank you for the question. It's a good point. It doesn't mean it's configurable, but the size of the variable (data-type) key column. I would like to distinguish it from other fixed-size data types like int and double since this option only affects data types (e.g., varchar and varbinary) with variable length. Still weird?

Copy link
Contributor

@Torch3333 Torch3333 Sep 26, 2024

Choose a reason for hiding this comment

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

Oh, ok. I completely missed this interpretation. I agree with this reasoning. 👍
Thank you for the explanation.

@@ -60,8 +59,7 @@ public JdbcDatabase(DatabaseConfig databaseConfig) {
databaseConfig.getMetadataCacheExpirationTimeSecs());

OperationChecker operationChecker = new OperationChecker(databaseConfig, tableMetadataManager);
QueryBuilder queryBuilder = new QueryBuilder(rdbEngine);
jdbcService = new JdbcService(tableMetadataManager, operationChecker, queryBuilder);
jdbcService = new JdbcService(tableMetadataManager, operationChecker, rdbEngine);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Push down RdbEngineStrategy since we don't have to create it again at the deeper level (i.e., ConditionMutator).

@@ -201,9 +212,9 @@ public String getDataTypeForEngine(DataType scalarDbDataType) {
public String getDataTypeForKey(DataType dataType) {
switch (dataType) {
case TEXT:
return "VARCHAR(64)";
return "VARCHAR(" + keyColumnSize + ")";
Copy link
Contributor

Choose a reason for hiding this comment

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

I guess this column definition is also used for coordinator.state.tx_id column, which usually contains a UUID value or a UUID value plus 25 byte prefix for the group commit feature. So, a validation that confirms the key column size is equal to or larger than 64 would be needed somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@komamitsu Thank you! That's a really good point. We should check it maybe in JdbcConfig. I will add it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@komamitsu Revised in b04a069. PTAL!

@jnmt jnmt requested a review from komamitsu September 24, 2024 08:33
Copy link
Contributor

@komamitsu komamitsu left a comment

Choose a reason for hiding this comment

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

LGTM! 👍

Copy link
Collaborator

@brfrn169 brfrn169 left a comment

Choose a reason for hiding this comment

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

LGTM! Thank you!

Comment on lines +69 to +82
// MySQL and Oracle have limitations regarding the total size of key columns. Thus, we should set
// a small but enough key column size so that users can create multiple key columns without
// exceeding the limit and changing the default. Since we found the old default size of 64 bytes
// was small for some applications, we changed it based on the following specifications. See the
// official documents for details.
// 1) In MySQL, the maximum total size of key columns is 3072 bytes in the default, and thus,
// depending on the charset, it can be up to 768 characters long. It can further be reduced if the
// different settings are used.
// 2) In Oracle, the maximum total size of key columns is approximately 75% of the database block
// size minus some overhead. The default block size is 8KB, and it is typically 4kB or 8kB. Thus,
// the maximum size can be similar to the MySQL.
// See the official documents for details.
// https://dev.mysql.com/doc/refman/8.0/en/innodb-limits.html
// https://docs.oracle.com/en/database/oracle/oracle-database/23/refrn/logical-database-limits.html
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

Comment on lines +207 to +208
// The number 10485760 is due to the maximum length of the character column.
// https://www.postgresql.org/docs/15/datatype-character.html
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

@feeblefakie feeblefakie left a comment

Choose a reason for hiding this comment

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

Left one suggestion.
Other than that, LGTM! Thank you!

ORACLE_VARIABLE_KEY_COLUMN_SIZE,
DEFAULT_VARIABLE_KEY_COLUMN_SIZE);

if (mysqlVariableKeyColumnSize < 64 || oracleVariableKeyColumnSize < 64) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's probably better to make 64 a static variable like `MINIMUM_VARIABLE_KEY_COLUMN_SIZE.
We should probably note why 64.

Copy link
Contributor Author

@jnmt jnmt Sep 26, 2024

Choose a reason for hiding this comment

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

@feeblefakie Definitely, thank you! I updated it with the reason based on Mitsu's comment in 1072e98. PTAL, just in case.

Copy link
Contributor

@Torch3333 Torch3333 left a comment

Choose a reason for hiding this comment

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

LGTM, thank you!

@jnmt
Copy link
Contributor Author

jnmt commented Sep 26, 2024

@josh-wong Can you take a look at the message part? I forgot to add you as a reviewer when revising this PR to add the error message.

Copy link
Contributor

@feeblefakie feeblefakie left a comment

Choose a reason for hiding this comment

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

LGTM! Thank you!

Copy link
Member

@josh-wong josh-wong left a comment

Choose a reason for hiding this comment

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

LGTM! Thank you!🙇🏻‍♂️

@jnmt jnmt merged commit a4b2cf9 into master Sep 30, 2024
46 checks passed
@jnmt jnmt deleted the change-default-key-columns-size-and-configurable branch September 30, 2024 08:28
jnmt added a commit that referenced this pull request Sep 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants