diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 556d134a02cf9e2f0a19706575ad0691bce18f3c..59cba2a9e295e610e80651be2116b789b2d4bc8b 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1,4 +1,5 @@ /* Copyright (c) 2009, 2021, Oracle and/or its affiliates. + Copyright (c) 2021, JINZHUAN Information Technology Co., Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2.0, @@ -69,9 +70,12 @@ #include #include +#ifdef HAVE_ZSQL_LOG_PERMISSION #include // dirname() +#endif // HAVE_ZSQL_LOG_PERMISSION #include "ft_global.h" +#include "git_version.h" #include "libbinlogevents/include/binlog_event.h" #include "m_string.h" #include "my_aes.h" // my_aes_opmode_names @@ -93,7 +97,6 @@ #include "sql/auth/auth_acls.h" #include "sql/auth/auth_common.h" // validate_user_plugins #include "sql/binlog.h" // mysql_bin_log -#include "sql/changestreams/apply/replication_thread_status.h" #include "sql/clone_handler.h" #include "sql/conn_handler/connection_handler_impl.h" // Per_thread_connection_handler #include "sql/conn_handler/connection_handler_manager.h" // Connection_handler_manager @@ -118,9 +121,9 @@ #include "sql/rpl_log_encryption.h" #include "sql/rpl_mi.h" // Master_info #include "sql/rpl_msr.h" // channel_map -#include "sql/rpl_mta_submode.h" // MTS_PARALLEL_TYPE_DB_NAME -#include "sql/rpl_replica.h" // SLAVE_THD_TYPE +#include "sql/rpl_mts_submode.h" // MTS_PARALLEL_TYPE_DB_NAME #include "sql/rpl_rli.h" // Relay_log_info +#include "sql/rpl_slave.h" // SLAVE_THD_TYPE #include "sql/rpl_write_set_handler.h" // transaction_write_set_hashing_algorithms #include "sql/server_component/log_builtins_filter_imp.h" // until we have pluggable variables #include "sql/server_component/log_builtins_imp.h" @@ -149,14 +152,71 @@ #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE #include "storage/perfschema/pfs_server.h" -#include "storage/perfschema/terminology_use_previous.h" #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ +#ifdef HAVE_ZSQL_QUICK_SYNC +#include "sql/zsql_features/thread_pool/threadpool.h" +#include "sql/zsql_features/semisync/rpl_semisync_master_plugin.h" +#include "sql/zsql_features/semisync/rpl_semisync_slave_plugin.h" +#endif // HAVE_ZSQL_QUICK_SYNC + +#ifdef HAVE_ZSQL_TRX_QUERY_LOG +#include "sql/zsql_features/trx_log/trx_log.h" +#include "sql/zsql_features/trx_log/trx_log_thread.h" +#include "sql/zsql_features/trx_log/trx_log_memory_pool.h" +extern Trx_log_memory_pool g_trx_log_memory_pool; +#endif // HAVE_ZSQL_TRX_QUERY_LOG + +#ifdef HAVE_ZSQL_QUICK_SYNC +#define MAX_CONNECTIONS 100000 +#endif // HAVE_ZSQL_QUICK_SYNC + +#ifdef HAVE_ZSQL_SUPPORT_JDBC_5_1_40_THROUGH_DBPROXY +ulong query_cache_size; +#endif /* HAVE_ZSQL_SUPPORT_JDBC_5_1_40_THROUGH_DBPROXY */ + +#ifdef HAVE_ZSQL_SLOW_LOG_DETAILED_EXECUTED_TIME +#include "sql/zsql_features/detailed_slow_log/detailed_execute_time.h" +#include "storage/innobase/include/zsql_features/lock0tally.h" +#endif /* HAVE_ZSQL_SLOW_LOG_DETAILED_EXECUTED_TIME */ + +#include "sql/oracle_compatibility/oracle_trunc/oracle_trunc.h" // HAVE_ZSQL_TRUNC_FUNC +#include "sql/oracle_compatibility/convert_datetime.h" // HAVE_ZSQL_TO_DATE +#include "sql/zsql_features/eplan/eplan_table_access.h" // HAVE_ZSQL_EPLAN +#include "sql/zsql_features/sql_blacklist/sql_blacklist_table_access.h" // HAVE_ZSQL_SQL_BLACKLIST_INTERCEPT +#include "sql/zsql_features/outline/outline_table_access.cc" // HAVE_ZSQL_OUTLINE +#include "sql/oracle_compatibility/dbms_package/dbms_output/dbms_output.h" // HAVE_ZSQL_DBMS_OUTPUT +#include "sql/oracle_compatibility/interval_partition/interval_thread.h" // HAVE_ZSQL_INTERVAL_PARTITION + +#ifdef HAVE_ZSQL_DB_QUOTAS +#include "sql/oracle_compatibility/db_quota/db_quota.h" +#endif // HAVE_ZSQL_DB_QUOTAS + +#ifdef HAVE_ZSQL_READONLY_WHITELIST +#define READONLY_WHITELIST_LOCK(need_lock) \ + do \ + { \ + if (need_lock) { \ + mysql_mutex_unlock(&LOCK_global_system_variables); \ + mysql_mutex_lock(&LOCK_read_only_whitelist); \ + } \ + } while(0) + +#define READONLY_WHITELIST_UNLOCK(need_lock) \ + do \ + { \ + if (need_lock) { \ + mysql_mutex_unlock(&LOCK_read_only_whitelist); \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + } \ + } while(0) +#endif // HAVE_ZSQL_READONLY_WHITELIST + TYPELIB bool_typelib = {array_elements(bool_values) - 1, "", bool_values, nullptr}; static bool update_buffer_size(THD *, KEY_CACHE *key_cache, - ptrdiff_t offset [[maybe_unused]], + ptrdiff_t offset MY_ATTRIBUTE((unused)), ulonglong new_value) { bool error = false; assert(offset == offsetof(KEY_CACHE, param_buff_size)); @@ -237,10 +297,8 @@ static bool update_keycache_param(THD *, KEY_CACHE *key_cache, ptrdiff_t offset, @param thd the session context @param setv the SET operations metadata */ -static bool check_session_admin_or_replication_applier(sys_var *self - [[maybe_unused]], - THD *thd, - set_var *setv) { +static bool check_session_admin_or_replication_applier( + sys_var *self MY_ATTRIBUTE((unused)), THD *thd, set_var *setv) { assert(self->scope() != sys_var::GLOBAL); Security_context *sctx = thd->security_context(); if ((setv->type == OPT_SESSION || setv->type == OPT_DEFAULT) && @@ -258,51 +316,45 @@ static bool check_session_admin_or_replication_applier(sys_var *self return false; } +#ifdef HAVE_ZSQL_CN_SESSION_VARIABLES_ADMIN /** - Utility method that checks if user has correct session administrative - dynamic privileges. - @return 0 on success, 1 on failure. -*/ -static bool check_session_admin_privileges_only(sys_var *self [[maybe_unused]], - THD *thd, set_var *setv) { - // Privilege check for global variable must have already done before. - assert(self->scope() != sys_var::GLOBAL); - Security_context *sctx = thd->security_context(); - if ((setv->type == OPT_SESSION || setv->type == OPT_DEFAULT) && - !sctx->has_global_grant(STRING_WITH_LEN("SESSION_VARIABLES_ADMIN")) - .first && - !sctx->has_global_grant(STRING_WITH_LEN("SYSTEM_VARIABLES_ADMIN")) - .first) { - return true; - } - return false; -} - -/** - Check if SESSION_VARIABLES_ADMIN granted. Throw SQL error if not. + Whether there is CN_SESSION_VARIABLES_ADMIN privilege and whether variables can be modified + @param [in] var + @param [in] sctx - Use this when setting session variables that are sensitive and should - be protected. + @returns true if has CN_SESSION_VARIABLES_ADMIN privilege and variables in array cn_session_admin_var, + otherwise false +*/ - We also accept SYSTEM_VARIABLES_ADMIN since it doesn't make a lot of - sense to be allowed to set the global variable and not the session ones. +static bool check_cn_session_admin(sys_var *var, Security_context *sctx) { + assert(var != nullptr); + assert(sctx != nullptr); - @retval true failure - @retval false success + // Variables that can be modified with CN_SESSION_VARIABLES_ADMIN privileges + constexpr const char *cn_session_admin_var[] = { + "character_set_database", + "character_set_filesystem" + }; - @param self the system variable to set value for - @param thd the session context - @param setv the SET operations metadata - */ -static bool check_session_admin_no_super(sys_var *self, THD *thd, - set_var *setv) { - if (check_session_admin_privileges_only(self, thd, setv)) { - my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), - "SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN"); - return true; + /* + Loop to determine whether the variable is in the array cn_session_admin_var + and whether the user has CN_SESSION_VARIABLES_ADMIN privileges + */ + for(auto i : cn_session_admin_var) { + if (strcasecmp(var->name.str, i) == 0) { + if (sctx->has_global_grant(STRING_WITH_LEN("CN_SESSION_VARIABLES_ADMIN")).first) { + return true; + } else { + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), + "SUPER, SYSTEM_VARIABLES_ADMIN, SESSION_VARIABLES_ADMIN or CN_SESSION_VARIABLES_ADMIN"); + return false; + } + } } + return false; } +#endif // HAVE_ZSQL_CN_SESSION_VARIABLES_ADMIN /** Check if SESSION_VARIABLES_ADMIN granted. Throw SQL error if not. @@ -322,10 +374,23 @@ static bool check_session_admin_no_super(sys_var *self, THD *thd, @param thd the session context @param setv the SET operations metadata */ -static bool check_session_admin(sys_var *self, THD *thd, set_var *setv) { +static bool check_session_admin(sys_var *self MY_ATTRIBUTE((unused)), THD *thd, + set_var *setv) { + assert(self->scope() != + sys_var::GLOBAL); // don't abuse check_session_admin() Security_context *sctx = thd->security_context(); - if (check_session_admin_privileges_only(self, thd, setv) && - !sctx->check_access(SUPER_ACL)) { + if ((setv->type == OPT_SESSION || setv->type == OPT_DEFAULT) && + !sctx->has_global_grant(STRING_WITH_LEN("SESSION_VARIABLES_ADMIN")) + .first && + !sctx->has_global_grant(STRING_WITH_LEN("SYSTEM_VARIABLES_ADMIN")) + .first && + !sctx->check_access(SUPER_ACL) +#ifdef HAVE_ZSQL_CN_SESSION_VARIABLES_ADMIN + // Verify whether there is CN_SESSION_VARIABLES_ADMIN privilege + // and whether variables can be modified + && !check_cn_session_admin(self, sctx)) +#endif // HAVE_ZSQL_CN_SESSION_VARIABLES_ADMIN + { my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER, SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN"); return true; @@ -590,7 +655,11 @@ static Sys_var_long Sys_pfs_max_program_instances( VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSCALE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES); +#ifdef HAVE_ZSQL_FIX_ORIGINAL_BUGS +static constexpr int num_prepared_stmt_limit = 20 * 1024 * 1024; +#else static constexpr int num_prepared_stmt_limit = 4 * 1024 * 1024; +#endif // HAVE_ZSQL_FIX_ORIGINAL_BUGS static Sys_var_long Sys_pfs_max_prepared_stmt_instances( "performance_schema_max_prepared_statements_instances", @@ -837,12 +906,6 @@ static Sys_var_long Sys_pfs_digest_size( VALID_RANGE(-1, 1024 * 1024), DEFAULT(PFS_AUTOSIZE_VALUE), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES); -static Sys_var_bool Sys_pfs_digest_lru( - "performance_schema_digests_lru", - "Updating PFS events_statements_summary_by_digest according to LRU.", - READ_ONLY GLOBAL_VAR(pfs_param.m_digest_lru), CMD_LINE(OPT_ARG), - DEFAULT(false), PFS_TRAILING_PROPERTIES); - static Sys_var_long Sys_pfs_events_transactions_history_long_size( "performance_schema_events_transactions_history_long_size", "Number of rows in EVENTS_TRANSACTIONS_HISTORY_LONG." @@ -959,19 +1022,12 @@ static Sys_var_charptr Sys_basedir( READ_ONLY NON_PERSIST GLOBAL_VAR(mysql_home_ptr), CMD_LINE(REQUIRED_ARG, 'b'), IN_FS_CHARSET, DEFAULT(nullptr)); -/* - --authentication_policy will take precendence over this variable - except in case where plugin name for first factor is not a concrete - value. Please refer authentication_policy variable. -*/ static Sys_var_charptr Sys_default_authentication_plugin( "default_authentication_plugin", "The default authentication plugin " "used by the server to hash the password.", READ_ONLY NON_PERSIST GLOBAL_VAR(default_auth_plugin), - CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT("caching_sha2_password"), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr), - DEPRECATED_VAR("authentication_policy")); + CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT("caching_sha2_password")); static PolyLock_mutex Plock_default_password_lifetime( &LOCK_default_password_lifetime); @@ -1145,17 +1201,13 @@ static Sys_var_ulong Sys_binlog_group_commit_sync_no_delay_count( CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 100000 /* max connections */), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG); -static Sys_var_ulonglong Sys_tmpfile_max_write_speed( - "tmpfile_max_write_speed", - "The writeback speed (byte/s) of system background flush threads.", - GLOBAL_VAR(g_tmpfile_writeback_speed), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, 1024 * 1024 * 1024 * 1024ULL), DEFAULT(0), BLOCK_SIZE(1)); - -static Sys_var_ulonglong Sys_tmpfile_dirty_threshold( - "tmpfile_dirty_threshold", - "The threshold of dirty bytes in system cache.", - GLOBAL_VAR(g_tmpfile_dirty_threshold), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, 1024 * 1024 * 1024 * 1024ULL), DEFAULT(0), BLOCK_SIZE(1)); +#ifdef HAVE_ZSQL_TRANS_MAX_BINLOG_SIZE +static Sys_var_ulonglong Sys_transaction_max_binlog_size( + "transaction_max_binlog_size", + "Max binlog size per transaction. If exceeded, abort the transaction", + SESSION_VAR(transaction_max_binlog_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, ULLONG_MAX), DEFAULT(0), BLOCK_SIZE(1)); +#endif /* HAVE_ZSQL_TRANS_MAX_BINLOG_SIZE */ static bool check_outside_trx(sys_var *, THD *thd, set_var *var) { if (thd->in_active_multi_stmt_transaction()) { @@ -1205,9 +1257,15 @@ static bool check_explicit_defaults_for_timestamp(sys_var *self, THD *thd, return true; } if (thd->in_active_multi_stmt_transaction()) { - my_error(ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION, MYF(0), - var->var->name.str); - return true; + /* + Change error to warning, and set it to the original value + when there is an ongoing transaction. + */ + push_warning_printf(thd, Sql_condition::SL_WARNING, + ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION, + ER_THD(thd, ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION), + var->var->name.str); + var->save_result.ulonglong_value = thd->variables.explicit_defaults_for_timestamp; } return false; } @@ -1368,12 +1426,15 @@ static Sys_var_test_flag Sys_core_file("core_file", static Sys_var_enum Sys_binlog_format( "binlog_format", - "The format used when writing the binary log. ROW writes each changed " - "row in a binary format. STATEMENT writes SQL statements. MIXED writes " - "SQL statements for most statements, and row format for statements that " - "cannot be replayed in a deterministic manner using SQL. If NDBCLUSTER " - "is enabled and binlog-format is MIXED, the format switches to row-based " - "and back implicitly for each query accessing an NDBCLUSTER table.", + "What form of binary logging the master will " + "use: either ROW for row-based binary logging, STATEMENT " + "for statement-based binary logging, or MIXED. MIXED is statement-" + "based binary logging except for those statements where only row-" + "based is correct: those which involve user-defined functions (i.e. " + "UDFs) or the UUID() function; for those, row-based binary logging is " + "automatically used. If NDBCLUSTER is enabled and binlog-format is " + "MIXED, the format switches to row-based and back implicitly per each " + "query accessing an NDBCLUSTER table", SESSION_VAR(binlog_format), CMD_LINE(REQUIRED_ARG, OPT_BINLOG_FORMAT), binlog_format_names, DEFAULT(BINLOG_FORMAT_ROW), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(binlog_format_check), @@ -1391,8 +1452,8 @@ static Sys_var_enum rbr_exec_mode( DEFAULT(RBR_EXEC_MODE_STRICT), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(prevent_global_rbr_exec_mode_idempotent), ON_UPDATE(nullptr)); -static bool check_binlog_row_image(sys_var *self [[maybe_unused]], THD *thd, - set_var *var) { +static bool check_binlog_row_image(sys_var *self MY_ATTRIBUTE((unused)), + THD *thd, set_var *var) { DBUG_TRACE; if (check_session_admin(self, thd, var)) return true; if (var->save_result.ulonglong_value == BINLOG_ROW_IMAGE_FULL) { @@ -1429,14 +1490,14 @@ static Sys_var_enum Sys_binlog_row_image( static const char *binlog_row_metadata_names[] = {"MINIMAL", "FULL", NullS}; static Sys_var_enum Sys_binlog_row_metadata( "binlog_row_metadata", - "Controls how much type information is written to the binary log when " - "using ROW format. FULL causes all metadata to be logged. MINIMAL means " - "that only metadata actually needed by replicas is logged.", + "Controls whether metadata is logged using FULL or MINIMAL format. " + "FULL causes all metadata to be logged; MINIMAL means that only " + "metadata actually required by slave is logged. Default: MINIMAL.", GLOBAL_VAR(binlog_row_metadata), CMD_LINE(REQUIRED_ARG), binlog_row_metadata_names, DEFAULT(BINLOG_ROW_METADATA_MINIMAL), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr)); -static bool check_binlog_trx_compression(sys_var *self [[maybe_unused]], +static bool check_binlog_trx_compression(sys_var *self MY_ATTRIBUTE((unused)), THD *thd, set_var *var) { DBUG_TRACE; if (check_session_admin(self, thd, var)) return true; @@ -1456,6 +1517,45 @@ static Sys_var_bool Sys_binlog_trx_compression( SESSION_VAR(binlog_trx_compression), CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_binlog_trx_compression)); +#ifdef HAVE_ZSQL_DISABLE_CLONE_GTID_PERSIST +static Sys_var_bool Sys_clone_remove_gtid_in_undo( + "disable_clone_gtid_persist", + "Clone plugin assigns update undo rollback segments for INSERT sql and " + "persists gtids in undo log header, which brings more redo logs and " + "overhead. We remove the addtional update undo rollback segments and " + "gtids in undo log header and do not persist gtids in mysql.gtid_executed " + "unless binlog rotates.", + READ_ONLY GLOBAL_VAR(g_disable_clone_gtid_persist), + CMD_LINE(OPT_ARG), DEFAULT(false)); +#endif + +#ifdef HAVE_ZSQL_ORACLE_CHARSET_END_SPACE +void init_ora_charset_pad_attribute() { + if (g_ora_charset_with_no_pad) { + my_charset_gb18030_bin.coll = &my_collation_mb_no_pad_bin_handler; + my_charset_gb18030_bin.pad_attribute = NO_PAD; + my_charset_gbk_bin.coll = &my_collation_mb_no_pad_bin_handler; + my_charset_gbk_bin.pad_attribute = NO_PAD; + } else { + my_charset_gb18030_bin.coll = &my_collation_mb_bin_handler; + my_charset_gb18030_bin.pad_attribute = PAD_SPACE; + my_charset_gbk_bin.coll = &my_collation_mb_bin_handler; + my_charset_gbk_bin.pad_attribute = PAD_SPACE; + } +} + +static bool set_gbk_bin(sys_var *, THD *, enum_var_type) { + init_ora_charset_pad_attribute(); + return false; +} + +static Sys_var_bool Sys_ora_charset_with_no_pad( + "ora_charset_with_no_pad", + "GBK_BIN & GB18030_BIN add NO_PAD attribute instead of PAD_SPACE.", + GLOBAL_VAR(g_ora_charset_with_no_pad), CMD_LINE(OPT_ARG), DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(set_gbk_bin)); +#endif /* HAVE_ZSQL_ORACLE_CHARSET_END_SPACE */ + #include "libbinlogevents/include/compression/zstd.h" static Sys_var_uint Sys_binlog_transaction_compression_level_zstd( "binlog_transaction_compression_level_zstd", @@ -1513,11 +1613,10 @@ static bool binlog_direct_check(sys_var *self, THD *thd, set_var *var) { static Sys_var_bool Sys_binlog_direct( "binlog_direct_non_transactional_updates", "Causes updates to non-transactional engines using statement format to " - "be written directly to binary log, after executing them and before " - "committing the transaction. Before using this option make sure " + "be written directly to binary log. Before using this option make sure " "that there are no dependencies between transactional and " "non-transactional tables such as in the statement INSERT INTO t_myisam " - "SELECT * FROM t_innodb; otherwise, replicas may diverge.", + "SELECT * FROM t_innodb; otherwise, slaves may diverge from the master.", SESSION_VAR(binlog_direct_non_trans_update), CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(binlog_direct_check)); @@ -1575,30 +1674,19 @@ static bool repository_check(sys_var *self, THD *thd, set_var *var, lock_slave_threads(mi); init_thread_mask(&running, mi, false); if (!running) { - bool is_pos_info_invalid{false}; switch (thread_mask) { case SLAVE_THD_IO: - is_pos_info_invalid = mi->is_receiver_position_info_invalid(); - mysql_mutex_lock(&mi->data_lock); - mi->flush_info(true); - mysql_mutex_unlock(&mi->data_lock); if (Rpl_info_factory::change_mi_repository( mi, static_cast(var->save_result.ulonglong_value), &msg)) { ret = true; my_error(ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE, MYF(0), msg); } - mi->set_receiver_position_info_invalid(is_pos_info_invalid); break; case SLAVE_THD_SQL: mts_recovery_groups(mi->rli); if (!mi->rli->is_mts_recovery()) { - is_pos_info_invalid = - mi->rli->is_applier_source_position_info_invalid(); if (Rpl_info_factory::reset_workers(mi->rli) || - mi->rli->flush_info( - Relay_log_info::RLI_FLUSH_IGNORE_SYNC_OPT | - Relay_log_info::RLI_FLUSH_IGNORE_GTID_ONLY) || Rpl_info_factory::change_rli_repository( mi->rli, static_cast(var->save_result.ulonglong_value), @@ -1606,8 +1694,6 @@ static bool repository_check(sys_var *self, THD *thd, set_var *var, ret = true; my_error(ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE, MYF(0), msg); } - mi->rli->set_applier_source_position_info_invalid( - is_pos_info_invalid); } else LogErr(WARNING_LEVEL, ER_RPL_REPO_HAS_GAPS); break; @@ -1645,7 +1731,7 @@ static const char *repository_names[] = {"FILE", "TABLE", ulong opt_mi_repository_id = INFO_REPOSITORY_TABLE; static Sys_var_enum Sys_mi_repository( "master_info_repository", - "The repository format for the replication connection configuration.", + "Defines the type of the repository for the master information.", GLOBAL_VAR(opt_mi_repository_id), CMD_LINE(REQUIRED_ARG, OPT_MASTER_INFO_REPOSITORY), repository_names, DEFAULT(INFO_REPOSITORY_TABLE), NO_MUTEX_GUARD, NOT_IN_BINLOG, @@ -1663,6 +1749,10 @@ static Sys_var_enum Sys_rli_repository( ON_CHECK(relay_log_info_repository_check), ON_UPDATE(nullptr), DEPRECATED_VAR("")); +#ifdef HAVE_ZSQL_SLAVE_CDC +ulong opt_compose_repository_id = INFO_REPOSITORY_TABLE; +#endif /* HAVE_ZSQL_SLAVE_CDC */ + static Sys_var_bool Sys_binlog_rows_query( "binlog_rows_query_log_events", "Allow writing of Rows_query_log events into binary log.", @@ -1693,8 +1783,7 @@ static Sys_var_ulong Sys_select_into_buffer_size( "select_into_buffer_size", "Buffer size for SELECT INTO OUTFILE/DUMPFILE.", HINT_UPDATEABLE SESSION_VAR(select_into_buffer_size), CMD_LINE(OPT_ARG), VALID_RANGE(IO_SIZE * 2, INT_MAX32), DEFAULT(128 * 1024), - BLOCK_SIZE(IO_SIZE), NO_MUTEX_GUARD, NOT_IN_BINLOG, - ON_CHECK(check_session_admin_no_super)); + BLOCK_SIZE(IO_SIZE)); static Sys_var_bool Sys_select_into_disk_sync( "select_into_disk_sync", @@ -1707,8 +1796,7 @@ static Sys_var_uint Sys_select_into_disk_sync_delay( "The delay in milliseconds after each buffer sync " "for SELECT INTO OUTFILE/DUMPFILE. Requires select_into_sync_disk = ON.", HINT_UPDATEABLE SESSION_VAR(select_into_disk_sync_delay), CMD_LINE(OPT_ARG), - VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, - NOT_IN_BINLOG, ON_CHECK(check_session_admin_no_super)); + VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(0), BLOCK_SIZE(1)); static bool check_not_null(sys_var *, THD *, set_var *var) { return var->value && var->value->is_null(); @@ -1816,6 +1904,35 @@ struct Get_csname { } // namespace + +#ifdef HAVE_ZSQL_DISTRIBUTE_MVCC +static char default_list[FN_REFLEN]= {""}; +static Sys_var_gtmgtid_activelist Sys_active_list( + "active_gtm_gtid_list", "active list of transaction", + HINT_UPDATEABLE SESSION_VAR(gtmgtid_active_list), CMD_LINE(NO_ARG), + IN_SYSTEM_CHARSET, DEFAULT(default_list)); + +static Sys_var_ulonglong Sys_lowwater_mark( + "next_gtm_gtid", + "lowwater_mark for next gtid_max", + HINT_UPDATEABLE SESSION_ONLY(next_gtmgtid), CMD_LINE(NO_ARG), + VALID_RANGE(0, ULLONG_MAX), DEFAULT(0), BLOCK_SIZE(1)); +#endif + +#ifdef HAVE_ZSQL_SAVEPOINT_HINT_INFO +static Sys_var_sql_gdb_savepoint Sys_sql_gdb_savepoint( + "sql_gdb_savepoint", "sql gdb savepoint for proxy's rollback", + SESSION_ONLY(sql_gdb_savepoint), CMD_LINE(NO_ARG), IN_SYSTEM_CHARSET, + DEFAULT(nullptr)); +#endif // HAVE_ZSQL_SAVEPOINT_HINT_INFO + +#ifdef HAVE_ZSQL_SUPPORT_SET_SEQUENCE +static Sys_var_sql_gdb_sequence Sys_sql_gdb_sequence( + "sql_gdb_sequence", "sql gdb sequence for trx sequence", + SESSION_ONLY(sql_gdb_sequence), CMD_LINE(NO_ARG), IN_SYSTEM_CHARSET, + DEFAULT(nullptr)); +#endif // HAVE_ZSQL_SUPPORT_SET_SEQUENCE + static CHARSET_INFO *charset_system_default = &my_charset_utf8_general_ci; static Sys_var_struct Sys_character_set_system( @@ -1837,14 +1954,6 @@ static bool check_charset_db(sys_var *self, THD *thd, set_var *var) { var->save_result.ptr = thd->db_charset; return false; } - -static bool update_deprecated_with_removal_message(sys_var *self, THD *thd, - enum_var_type) { - push_warning_printf(thd, Sql_condition::SL_WARNING, ER_WARN_DEPRECATED_SYNTAX, - ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT), - self->name.str); - return false; -} static bool update_deprecated(sys_var *self, THD *thd, enum_var_type) { push_warning_printf( thd, Sql_condition::SL_WARNING, ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT, @@ -2166,6 +2275,30 @@ static Sys_var_ulong Sys_binlog_expire_logs_seconds( VALID_RANGE(0, 0xFFFFFFFF), DEFAULT(2592000), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_expire_logs_seconds), ON_UPDATE(nullptr)); +#ifdef HAVE_ZSQL_LOG_ROTATE_PURGE +static Sys_var_ulong Sys_generallog_expire_logs_seconds( + "generallog_expire_logs_seconds", + "Time threshold for general log expiration", + GLOBAL_VAR(generallog_expire_logs_seconds), + CMD_LINE(OPT_ARG), + VALID_RANGE(0, UINT_MAX), DEFAULT(604800), BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_slowlog_expire_logs_seconds( + "slowlog_expire_logs_seconds", + "Time threshold for slow log expiration", + GLOBAL_VAR(slowlog_expire_logs_seconds), + CMD_LINE(OPT_ARG), + VALID_RANGE(0, UINT_MAX), DEFAULT(604800), BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_errorlog_expire_logs_seconds( + "errorlog_expire_logs_seconds",/*default 365 days*/ + "Time threshold for error log expiration", + GLOBAL_VAR(g_errorlog_expire_logs_seconds), + CMD_LINE(OPT_ARG), + VALID_RANGE(0, UINT_MAX), DEFAULT(86400 * 365), BLOCK_SIZE(1)); + +#endif // HAVE_ZSQL_LOG_ROTATE_PURGE + static Sys_var_bool Sys_flush( "flush", "Flush MyISAM tables to disk between SQL commands", GLOBAL_VAR(myisam_flush), CMD_LINE(OPT_ARG), DEFAULT(false)); @@ -2239,23 +2372,41 @@ static Sys_var_charptr Sys_init_file( READ_ONLY NON_PERSIST GLOBAL_VAR(opt_init_file), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(nullptr)); -static PolyLock_rwlock PLock_sys_init_replica(&LOCK_sys_init_replica); -static Sys_var_lexstring Sys_init_replica( - "init_replica", - "Command(s) that are executed by the replication applier thread " - "each time the applier threads start.", - GLOBAL_VAR(opt_init_replica), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET, - DEFAULT(""), &PLock_sys_init_replica, NOT_IN_BINLOG, +static PolyLock_rwlock PLock_sys_init_slave(&LOCK_sys_init_slave); +static Sys_var_lexstring Sys_init_slave( + "init_slave", + "Command(s) that are executed by a slave server " + "each time the SQL thread starts", + GLOBAL_VAR(opt_init_slave), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET, + DEFAULT(""), &PLock_sys_init_slave, NOT_IN_BINLOG, ON_CHECK(check_init_string)); -static Sys_var_deprecated_alias Sys_init_slave("init_slave", Sys_init_replica); +#ifdef HAVE_ZSQL_ORA_PROFILE +static bool check_idle_time_effect(sys_var *, THD *thd, set_var *var) { + if (!(var->type & enum_var_type::OPT_SESSION)) + return false; + + if (thd->m_profile.idle_time) { + String error_info; + error_info.append("change session "); + error_info.append(var->var->name.str, var->var->name.length); + my_error(ER_BLACKLIST_COMMAND,MYF(0), error_info.c_ptr_quick()); + return true; + } + return false; +} +#endif //HAVE_ZSQL_ORA_PROFILE static Sys_var_ulong Sys_interactive_timeout( "interactive_timeout", "The number of seconds the server waits for activity on an interactive " "connection before closing it", SESSION_VAR(net_interactive_timeout), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1)); + VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1) +#ifdef HAVE_ZSQL_ORA_PROFILE + , NO_MUTEX_GUARD, NOT_IN_BINLOG,ON_CHECK(check_idle_time_effect) +#endif //HAVE_ZSQL_ORA_PROFILE + ); static Sys_var_ulong Sys_join_buffer_size( "join_buffer_size", "The size of the buffer that is used for full joins", @@ -2334,7 +2485,21 @@ static Sys_var_ulong Sys_lock_wait_timeout( "lock_wait_timeout", "Timeout in seconds to wait for a lock before returning an error.", HINT_UPDATEABLE SESSION_VAR(lock_wait_timeout), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(LONG_TIMEOUT), BLOCK_SIZE(1)); +#ifdef HAVE_ZSQL_FIX_ORIGINAL_BUGS + VALID_RANGE(0, LONG_TIMEOUT), +#else + VALID_RANGE(1, LONG_TIMEOUT), +#endif + DEFAULT(LONG_TIMEOUT), BLOCK_SIZE(1)); + +#ifdef HAVE_ZSQL_ORA_XA +static Sys_var_ulong Sys_gdb_xa_wait_timeout( + "gdb_xa_wait_timeout", + "Timeout in seconds to wait for another SQL completing in a GoldenDB XA " + "transaction.", + HINT_UPDATEABLE SESSION_VAR(gdb_xa_wait_timeout), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(5), BLOCK_SIZE(1)); +#endif // HAVE_ZSQL_ORA_XA #ifdef HAVE_MLOCKALL static Sys_var_bool Sys_locked_in_memory( @@ -2407,27 +2572,23 @@ static Sys_var_enum Sys_extract_write_set( "transaction_write_set_extraction", "This option is used to let the server know when to " "extract the write set which will be used for various purposes. ", - SESSION_VAR(transaction_write_set_extraction), - CMD_LINE(OPT_ARG, OPT_TRANSACTION_WRITE_SET_EXTRACTION), + SESSION_VAR(transaction_write_set_extraction), CMD_LINE(OPT_ARG), transaction_write_set_hashing_algorithms, DEFAULT(HASH_ALGORITHM_XXHASH64), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(transaction_write_set_check), - ON_UPDATE(nullptr), DEPRECATED_VAR("")); + ON_UPDATE(nullptr)); -static Sys_var_ulong Sys_rpl_stop_replica_timeout( - "rpl_stop_replica_timeout", - "Timeout in seconds to wait for replication threads to stop, before " - "STOP REPLICA returns a warning.", - GLOBAL_VAR(rpl_stop_replica_timeout), CMD_LINE(REQUIRED_ARG), +static Sys_var_ulong Sys_rpl_stop_slave_timeout( + "rpl_stop_slave_timeout", + "Timeout in seconds to wait for slave to stop before returning a " + "warning.", + GLOBAL_VAR(rpl_stop_slave_timeout), CMD_LINE(REQUIRED_ARG), VALID_RANGE(2, LONG_TIMEOUT), DEFAULT(LONG_TIMEOUT), BLOCK_SIZE(1)); -static Sys_var_deprecated_alias Sys_rpl_stop_slave_timeout( - "rpl_stop_slave_timeout", Sys_rpl_stop_replica_timeout); - static Sys_var_enum Sys_binlog_error_action( "binlog_error_action", "When statements cannot be written to the binary log due to a fatal " - "error, this option determines whether the server ignores the error and " - "closes the binary log, or aborts.", + "error, the server can either ignore the error and let the master " + "continue, or abort.", GLOBAL_VAR(binlog_error_action), CMD_LINE(REQUIRED_ARG), binlog_error_action_list, DEFAULT(ABORT_SERVER)); @@ -2543,8 +2704,9 @@ static bool check_log_error_services(sys_var *self, THD *thd, set_var *var) { return false; } -static bool fix_log_error_services(sys_var *self [[maybe_unused]], THD *thd, - enum_var_type type [[maybe_unused]]) { +static bool fix_log_error_services(sys_var *self MY_ATTRIBUTE((unused)), + THD *thd, + enum_var_type type MY_ATTRIBUTE((unused))) { bool ret = false; // syntax is OK and services exist; try to initialize them! size_t pos; @@ -2610,10 +2772,9 @@ static bool check_log_error_suppression_list(sys_var *self, THD *thd, return false; } -static bool fix_log_error_suppression_list(sys_var *self [[maybe_unused]], - THD *thd [[maybe_unused]], - enum_var_type type - [[maybe_unused]]) { +static bool fix_log_error_suppression_list( + sys_var *self MY_ATTRIBUTE((unused)), THD *thd MY_ATTRIBUTE((unused)), + enum_var_type type MY_ATTRIBUTE((unused))) { // syntax is OK and errcodes have messages; try to make filter rules for // them! int rr = log_builtins_filter_parse_suppression_list( @@ -2650,16 +2811,13 @@ static Sys_var_bool Sys_log_slow_admin_statements( GLOBAL_VAR(opt_log_slow_admin_statements), CMD_LINE(OPT_ARG), DEFAULT(false)); -static Sys_var_bool Sys_log_slow_replica_statements( - "log_slow_replica_statements", - "Log slow statements executed by the replication applier threads to the " - "slow log if it is open.", - GLOBAL_VAR(opt_log_slow_replica_statements), CMD_LINE(OPT_ARG), +static Sys_var_bool Sys_log_slow_slave_statements( + "log_slow_slave_statements", + "Log slow statements executed by slave thread to the slow log if it is " + "open.", + GLOBAL_VAR(opt_log_slow_slave_statements), CMD_LINE(OPT_ARG), DEFAULT(false)); -static Sys_var_deprecated_alias Sys_log_slow_slave_statements( - "log_slow_slave_statements", Sys_log_slow_replica_statements); - static bool update_log_throttle_queries_not_using_indexes(sys_var *, THD *thd, enum_var_type) { // Check if we should print a summary of any suppressed lines to the slow @@ -2751,7 +2909,7 @@ static Sys_var_bool Sys_low_priority_updates( "low_priority_updates", "INSERT/DELETE/UPDATE has lower priority than selects", SESSION_VAR(low_priority_updates), CMD_LINE(OPT_ARG), DEFAULT(false), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_session_admin_no_super), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(fix_low_prio_updates)); static Sys_var_bool Sys_lower_case_file_system( @@ -2761,6 +2919,30 @@ static Sys_var_bool Sys_lower_case_file_system( READ_ONLY NON_PERSIST GLOBAL_VAR(lower_case_file_system), NO_CMD_LINE, DEFAULT(false)); +#ifdef HAVE_ZSQL_FLEX_STREAM_FETCH +static Sys_var_bool Sys_flex_stream_fetch( + "use_flex_stream_fetch", + "Whether to enable flex stream fetch. Default: OFF.", + HINT_UPDATEABLE SESSION_VAR(use_flex_stream_fetch), CMD_LINE(OPT_ARG), + DEFAULT(false)); + +static Sys_var_uint Sys_max_produce_num( + "max_flex_stream_fetch_stmt_count", + "The maximum number of total prepared statements using flex stream fecth " + "that can be created at the same time. Default: 1000.", + GLOBAL_VAR(g_max_flex_stream_fetch_stmt_count), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, INT_MAX), DEFAULT(1000), + BLOCK_SIZE(1)); + +static Sys_var_uint Sys_session_max_produce( + "session_max_flex_stream_fetch_stmt_count", + "The maximum number of prepared statements using flex stream fecth that " + "can be created at the same time in one session. Default: 10.", + SESSION_VAR(session_max_flex_stream_fetch_stmt_count), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, INT_MAX), DEFAULT(10), + BLOCK_SIZE(1)); +#endif // HAVE_ZSQL_FLEX_STREAM_FETCH + static Sys_var_uint Sys_lower_case_table_names( "lower_case_table_names", "If set to 1 table names are stored in lowercase on disk and table " @@ -2782,9 +2964,10 @@ static bool session_readonly(sys_var *self, THD *, set_var *var) { return true; } -static bool check_max_allowed_packet(sys_var *self, THD *thd, set_var *var) { +static bool check_max_allowed_packet(sys_var *self MY_ATTRIBUTE((unused)), THD *thd, set_var *var) { longlong val; - if (session_readonly(self, thd, var)) return true; + // HAVE_ZSQL_SET_GLOBAL_SESSION_VARIABLES + // if (session_readonly(self, thd, var)) return true; val = var->save_result.ulonglong_value; if (val < (longlong)global_system_variables.net_buffer_length) { @@ -2803,17 +2986,14 @@ static Sys_var_ulong Sys_max_allowed_packet( BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_max_allowed_packet)); -static Sys_var_ulong Sys_replica_max_allowed_packet( - "replica_max_allowed_packet", - "The maximum size of packets sent from an upstream source server to this " - "server.", - GLOBAL_VAR(replica_max_allowed_packet), CMD_LINE(REQUIRED_ARG), +static Sys_var_ulong Sys_slave_max_allowed_packet( + "slave_max_allowed_packet", + "The maximum packet length to sent successfully from the master to " + "slave.", + GLOBAL_VAR(slave_max_allowed_packet), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1024, MAX_MAX_ALLOWED_PACKET), DEFAULT(MAX_MAX_ALLOWED_PACKET), BLOCK_SIZE(1024)); -static Sys_var_deprecated_alias Sys_slave_max_allowed_packet( - "slave_max_allowed_packet", Sys_replica_max_allowed_packet); - static Sys_var_ulonglong Sys_max_binlog_cache_size( "max_binlog_cache_size", "Sets the total size of the transactional cache", GLOBAL_VAR(max_binlog_cache_size), CMD_LINE(REQUIRED_ARG), @@ -2856,6 +3036,30 @@ static Sys_var_ulong Sys_max_binlog_size( BLOCK_SIZE(IO_SIZE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(fix_max_binlog_size)); +#ifdef HAVE_ZSQL_LOG_ROTATE_PURGE +static Sys_var_ulong Sys_max_generallog_size( + "max_generallog_size", + "Threshold size of general log rotation", + GLOBAL_VAR(max_generallog_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(IO_SIZE, ULONG_MAX), DEFAULT(100 * 1024L * 1024L), + BLOCK_SIZE(IO_SIZE)); + +static Sys_var_ulong Sys_max_slowlog_size( + "max_slowlog_size", + "Threshold size of slow log rotation", + GLOBAL_VAR(max_slowlog_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(IO_SIZE, ULONG_MAX), DEFAULT(100 * 1024L * 1024L), + BLOCK_SIZE(IO_SIZE)); + +static Sys_var_ulong Sys_max_errorlog_size( + "max_errorlog_size", + "Threshold size of error log rotation", + GLOBAL_VAR(g_max_errorlog_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(IO_SIZE, ULONG_MAX), DEFAULT(100 * 1024L * 1024L), + BLOCK_SIZE(IO_SIZE)); + +#endif // HAVE_ZSQL_LOG_ROTATE_PURGE + static Sys_var_ulong Sys_max_connections( "max_connections", "The number of simultaneous clients allowed", GLOBAL_VAR(max_connections), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, 100000), @@ -2876,8 +3080,7 @@ static Sys_var_long Sys_max_digest_length( READ_ONLY GLOBAL_VAR(max_digest_length), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 1024 * 1024), DEFAULT(1024), BLOCK_SIZE(1)); -static bool check_max_delayed_threads(sys_var *self, THD *thd, set_var *var) { - if (check_session_admin_no_super(self, thd, var)) return true; +static bool check_max_delayed_threads(sys_var *, THD *, set_var *var) { return (!var->is_global_persist()) && var->save_result.ulonglong_value != 0 && var->save_result.ulonglong_value != global_system_variables.max_insert_delayed_threads; @@ -2907,8 +3110,7 @@ static Sys_var_ulong Sys_max_delayed_threads( static Sys_var_ulong Sys_max_error_count( "max_error_count", "Max number of errors/warnings to store for a statement", HINT_UPDATEABLE SESSION_VAR(max_error_count), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, 65535), DEFAULT(DEFAULT_ERROR_COUNT), BLOCK_SIZE(1), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_session_admin_no_super)); + VALID_RANGE(0, 65535), DEFAULT(DEFAULT_ERROR_COUNT), BLOCK_SIZE(1)); static Sys_var_ulonglong Sys_max_heap_table_size( "max_heap_table_size", @@ -2934,13 +3136,43 @@ static bool fix_max_join_size(sys_var *self, THD *thd, enum_var_type type) { sv->option_bits &= ~OPTION_BIG_SELECTS; return false; } + +#ifdef HAVE_ZSQL_ORA_PROFILE +static bool check_max_join_size_effect(sys_var *, THD *thd, set_var *var) { + if (!(var->type & enum_var_type::OPT_SESSION)) + return false; + + if (thd->m_profile.max_join_size) { + my_error(ER_BLACKLIST_COMMAND, MYF(0), "change session max_join_size "); + return true; + } + return false; +} +#endif // HAVE_ZSQL_ORA_PROFILE + +#ifdef HAVE_ZSQL_TRUNC_FUNC +static const char *first_day_of_week_names[]= {"MONDAY", "SUNDAY", nullptr}; +static Sys_var_enum Sys_first_day_of_week( + "first_day_of_week", + "MONDAY: The first day of the week is monday, " + "SUNDAY: The first day of the week is sunday", + GLOBAL_VAR(g_sunday_first_day_of_week), + CMD_LINE(REQUIRED_ARG), first_day_of_week_names, + DEFAULT(enum_first_day_of_week::SUNDAY)); +#endif // HAVE_ZSQL_TRUNC_FUNC + static Sys_var_harows Sys_max_join_size( "max_join_size", "Joins that are probably going to read more than max_join_size " "records return an error", HINT_UPDATEABLE SESSION_VAR(max_join_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, HA_POS_ERROR), DEFAULT(HA_POS_ERROR), BLOCK_SIZE(1), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + NO_MUTEX_GUARD, NOT_IN_BINLOG, +#ifdef HAVE_ZSQL_ORA_PROFILE + ON_CHECK(check_max_join_size_effect), +#else + ON_CHECK(nullptr), +#endif //HAVE_ZSQL_ORA_PROFILE ON_UPDATE(fix_max_join_size)); static Sys_var_ulong Sys_max_seeks_for_key( @@ -2975,6 +3207,38 @@ static Sys_var_ulong Sys_max_prepared_stmt_count( schema. */ sys_var::PARSE_EARLY); +#ifdef HAVE_ZSQL_PREPARED_STMT_POOL +/* prepared_stmt_pool mechanism switch */ +static Sys_var_bool Sys_prepared_stmt_pool_enabled( + "prepared_stmt_pool", + "prepared_statement pool mechanism ON / OFF.", + READ_ONLY GLOBAL_VAR(g_opt_prepared_stmt_pool), + CMD_LINE(OPT_ARG), DEFAULT(false)); + +static Sys_var_int32 Sys_prepared_stmt_pool_size( + "prepared_stmt_pool_size", + "Maximum number of prepared statement pools in the server", + READ_ONLY GLOBAL_VAR(g_prepared_stmt_pool_size), CMD_LINE(REQUIRED_ARG), + /* VALID_RANGE() is the same with "max_connections" */ + VALID_RANGE(1, 100000), DEFAULT(100), BLOCK_SIZE(1), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(NULL), ON_UPDATE(NULL), NULL, + /* prepared_stmt_pool_size is used to init prepared_stmt_maps. */ + sys_var::PARSE_EARLY); + +static Sys_var_int32 Sys_prepared_stmt_pool_oversubscribe( + "prepared_stmt_pool_oversubscribe", + "Maximum number of concurrent count per prepared statments per pool", + GLOBAL_VAR(g_prepared_stmt_pool_oversubscribe), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(1, num_prepared_stmt_limit), DEFAULT(5), BLOCK_SIZE(1)); + +static Sys_var_ulonglong Sys_timeout_of_get_stmt( + "timeout_of_get_stmt", + "timeout (us) getting idle stmt in get_one_idle_stmt() under prepared statments pool. " + "if timeout_of_get_stmt set to 0, no wait, directly timeout immediately.", + GLOBAL_VAR(g_timeout_of_get_stmt), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, ULLONG_MAX), DEFAULT(1000), BLOCK_SIZE(1)); +#endif /* HAVE_ZSQL_PREPARED_STMT_POOL */ + static bool fix_max_relay_log_size(sys_var *, THD *, enum_var_type) { Master_info *mi = nullptr; @@ -3033,8 +3297,7 @@ static Sys_var_ulong Sys_min_examined_row_limit( "Don't write queries to slow log that examine fewer rows " "than that", SESSION_VAR(min_examined_row_limit), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, - NOT_IN_BINLOG, ON_CHECK(check_session_admin_no_super)); + VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1)); #ifdef _WIN32 static Sys_var_bool Sys_named_pipe("named_pipe", "Enable the named pipe (NT)", @@ -3130,6 +3393,29 @@ static Sys_var_ulong Sys_net_write_timeout( NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(fix_net_write_timeout)); +//HAVE_ZSQL_FIX_ORIGINAL_BUGS FIX BUG START +// Sync kill_idle_transaction and innodb_kill_idle_transaction values +extern long srv_kill_idle_transaction; + +static bool fix_kill_idle_transaction(sys_var *, THD *, + enum_var_type) +{ + //srv_kill_idle_transaction= kill_idle_transaction_timeout; + return false; +} + +static Sys_var_ulong Sys_kill_idle_transaction( + "kill_idle_transaction", + "If non-zero, number of seconds to wait before killing idle " + "connections that have open transactions", + GLOBAL_VAR(kill_idle_transaction_timeout), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(0), BLOCK_SIZE(1), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(fix_kill_idle_transaction)); + +//HAVE_ZSQL_FIX_ORIGINAL_BUGS END + + static bool fix_net_retry_count(sys_var *self, THD *thd, enum_var_type type) { if (!self->is_global_persist(type)) { // net_write_timeout is a specific property for the classic protocols @@ -3165,6 +3451,13 @@ static Sys_var_bool Sys_old_alter_table("old_alter_table", SESSION_VAR(old_alter_table), CMD_LINE(OPT_ARG), DEFAULT(false)); +#ifdef HAVE_ZSQL_COMPATIBLE_COUNT_FORCE_INDEX +static Sys_var_bool Sys_compatible_count_force_index("compatible_count_force_index", + "Compatible mode for count(*) force index to search in 5.7 mode", + SESSION_VAR(compatible_count_force_index), + CMD_LINE(OPT_ARG),DEFAULT(false)); +#endif + static Sys_var_ulong Sys_open_files_limit( "open_files_limit", "If this is not 0, then mysqld will use this value to reserve file " @@ -3265,7 +3558,7 @@ export void update_parser_max_mem_size() { global_system_variables.parser_max_mem_size = new_val; } -static bool check_optimizer_switch(sys_var *, THD *thd [[maybe_unused]], +static bool check_optimizer_switch(sys_var *, THD *thd MY_ATTRIBUTE((unused)), set_var *var) { const bool current_hypergraph_optimizer = thd->optimizer_switch_flag(OPTIMIZER_SWITCH_HYPERGRAPH_OPTIMIZER); @@ -3326,6 +3619,10 @@ static const char *optimizer_switch_names[] = { "prefer_ordering_index", "hypergraph_optimizer", // Deliberately not documented below. "derived_condition_pushdown", + "sec_derived_condition_pushdown", // HAVE_ZSQL_SEC_CONDITION_PUSHDOWN + "sec_derived_condition_pushdown_for_more_op", + "set_operation_do_semijoin", // HAVE_ZSQL_WRAP_SET_OP_FOR_SEMIJOIN + "limit_pushdown", // HAVE_ZSQL_LIMIT_PUSHDOWN "default", NullS}; static Sys_var_flagset Sys_optimizer_switch( @@ -3339,8 +3636,9 @@ static Sys_var_flagset Sys_optimizer_switch( " block_nested_loop, batched_key_access, use_index_extensions," " condition_fanout_filter, derived_merge, hash_join," " subquery_to_derived, prefer_ordering_index," - " derived_condition_pushdown} and val is one of " - "{on, off, default}", + " derived_condition_pushdown, sec_derived_condition_pushdown_for_more_op," + " set_operation_do_semijoin, limit_pushdown} " + "and val is one of {on, off, default}", HINT_UPDATEABLE SESSION_VAR(optimizer_switch), CMD_LINE(REQUIRED_ARG), optimizer_switch_names, DEFAULT(OPTIMIZER_SWITCH_DEFAULT), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_optimizer_switch), ON_UPDATE(nullptr)); @@ -3430,8 +3728,7 @@ static Sys_var_ulong Sys_preload_buff_size( "preload_buffer_size", "The size of the buffer that is allocated when preloading indexes", SESSION_VAR(preload_buff_size), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(1024, 1024 * 1024 * 1024), DEFAULT(32768), BLOCK_SIZE(1), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_session_admin_no_super)); + VALID_RANGE(1024, 1024 * 1024 * 1024), DEFAULT(32768), BLOCK_SIZE(1)); static Sys_var_uint Sys_protocol_version( "protocol_version", @@ -3465,8 +3762,8 @@ static bool check_read_only(sys_var *, THD *thd, set_var *) { return false; } -static bool check_require_secure_transport(sys_var *, THD *, - set_var *var [[maybe_unused]]) { +static bool check_require_secure_transport( + sys_var *, THD *, set_var *var MY_ATTRIBUTE((unused))) { #if !defined(_WIN32) /* always allow require_secure_transport to be enabled on @@ -3489,20 +3786,104 @@ static bool check_require_secure_transport(sys_var *, THD *, #endif } +#ifdef HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO +static void event_scheduler_restart(THD *thd) { + /* + Restart event scheduler if needed. + + At present, turning on SUPER_READ_ONLY means that we + can no longer acquire an MDL to update mysql.*. + As a result of this, updating the "last run at ..." + timestamp of events fails, and the event scheduler + shuts down when trying to do so. + + As a convenience, we restart the event scheduler when + [SUPER_]READ_ONLY is turned off while the scheduler is + enabled (in the settings), but not actually running. + */ + if (Events::opt_event_scheduler == Events::EVENTS_ON) { + bool evsched_error; // Did we fail to start the event scheduler? + int evsched_errcode = 0; // If we failed, what was the actual error code? + + /* + We must not hold the lock while starting the event scheduler, + as that will internally try to take the lock while creating a THD. + */ + mysql_mutex_unlock(&LOCK_global_system_variables); + evsched_error = Events::start(&evsched_errcode); + mysql_mutex_lock(&LOCK_global_system_variables); + + if (evsched_error) { + /* + The user requested a change of super_read_only. + That change succeeded, so we do not signal a failure here, + since it is only the side-effect/convenience of restarting + the event scheduler that failed. + We do however notify them of that failure, since we're + just that nice. + We also do not modify opt_event_scheduler, since user + intent has not changed. If this policy ever changes, + opt_event_scheduler should probably be unset when the + event scheduler shuts down. + */ + push_warning_printf(thd, Sql_condition::SL_WARNING, + ER_EVENT_SET_VAR_ERROR, + ER_THD(thd, ER_EVENT_SET_VAR_ERROR), evsched_errcode); + } + } +} +#endif // HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO + static bool fix_read_only(sys_var *self, THD *thd, enum_var_type) { bool result = true; bool new_read_only = read_only; // make a copy before releasing a mutex DBUG_TRACE; +#ifdef HAVE_ZSQL_READONLY_WHITELIST_PRINT_LOG + if (read_only != opt_readonly) { + LogErr(INFORMATION_LEVEL, ER_NUMBER_CONFIG_MODIFIED, "read_only", + read_only); + } +#endif // HAVE_ZSQL_READONLY_WHITELIST_PRINT_LOG + + /* + If we're not newly turning on READ_ONLY, we don't have to worry + about locks. + */ if (read_only == false || read_only == opt_readonly) { + opt_readonly = read_only; // HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO + + /* + If we're turning off READ_ONLY here, turn off + SUPER_READ_ONLY as well (if on). + */ if (opt_super_readonly && !read_only) { opt_super_readonly = false; super_read_only = false; + // Do this last as it temporarily releases the global sys-var lock. + event_scheduler_restart(thd); // HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO + } + +#ifdef HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO + /* + When the whitelist_enabled stays ON,if we're turning off READ_ONLY here, + we restart the event scheduler. + */ + if (g_read_only_super_whitelist_enabled == true && !read_only) { + // Do this last as it temporarily releases the global sys-var lock. + event_scheduler_restart(thd); } - opt_readonly = read_only; +#endif // HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO return false; } + /* + Check whether we can change read_only state without causing a deadlock. + + Not to be confused with check_readonly(), which checks in a + standardized way whether the current settings of opt_readonly + and opt_super_readonly prohibit certain operations. + */ if (check_read_only(self, thd, nullptr)) // just in case goto end; @@ -3513,11 +3894,14 @@ static bool fix_read_only(sys_var *self, THD *thd, enum_var_type) { - FLUSH TABLES WITH READ LOCK - SET GLOBAL READ_ONLY = 1 */ + opt_readonly = read_only; // HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO + if (opt_super_readonly && !read_only) { opt_super_readonly = false; super_read_only = false; + // Do this last as it temporarily releases the global sys-var lock. + event_scheduler_restart(thd); // HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO } - opt_readonly = read_only; return false; } @@ -3563,55 +3947,20 @@ static bool fix_super_read_only(sys_var *, THD *thd, enum_var_type type) { /* return if no changes: */ if (super_read_only == opt_super_readonly) return false; +#ifdef HAVE_ZSQL_READONLY_WHITELIST_PRINT_LOG + LogErr(INFORMATION_LEVEL, ER_NUMBER_CONFIG_MODIFIED, "super_read_only", + super_read_only); +#endif // HAVE_ZSQL_READONLY_WHITELIST_PRINT_LOG + /* return immediately if turning super_read_only OFF: */ if (super_read_only == false) { opt_super_readonly = false; - /* - Restart event scheduler if needed. - - At present, turning on super_read_only means that we - can no longer acquire an MDL to update mysql.*. - As a result of this, updating the "last run at ..." - timestamp of events fails, and the event scheduler - shuts down when trying to do so. - - As a convenience, we restart the event scheduler when - super_read_only is turned off, and the scheduler is - turned on (in the settings), but not actually running - (anymore). - */ - if (Events::opt_event_scheduler == Events::EVENTS_ON) { - bool evsched_error; // Did we fail to start the event scheduler? - int evsched_errcode = 0; // If we failed, what was the actual error code? - - /* - We must not hold the lock while starting the event scheduler, - as that will internally try to take the lock while creating a THD. - */ - mysql_mutex_unlock(&LOCK_global_system_variables); - evsched_error = Events::start(&evsched_errcode); - mysql_mutex_lock(&LOCK_global_system_variables); - - if (evsched_error) { - /* - The user requested a change of super_read_only. - That change succeeded, so we do not signal a failure here, - since it is only the side-effect/convenience of restarting - the event scheduler that failed. - We do however notify them of that failure, since we're - just that nice. - We also do not modify opt_event_scheduler, since user - intent has not changed. If this policy ever changes, - opt_event_scheduler should probably be unset when the - event scheduler shuts down. - */ - push_warning_printf( - thd, Sql_condition::SL_WARNING, ER_EVENT_SET_VAR_ERROR, - ER_THD(thd, ER_EVENT_SET_VAR_ERROR), evsched_errcode); - } - } - +#ifdef HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO + if (g_read_only_super_whitelist_enabled == false) + // Do this last as it temporarily releases the global sys-var lock. + event_scheduler_restart(thd); +#endif // HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO return false; } bool result = true; @@ -3676,7 +4025,7 @@ static Sys_var_bool Sys_require_secure_transport( static Sys_var_bool Sys_readonly( "read_only", "Make all non-temporary tables read-only, with the exception for " - "replication applier threads and users with the SUPER privilege.", + "replication (slave) threads and users with the SUPER privilege", GLOBAL_VAR(read_only), CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_read_only), ON_UPDATE(fix_read_only)); @@ -3686,13 +4035,135 @@ Setting super_read_only to ON triggers read_only to also be set to ON. static Sys_var_bool Sys_super_readonly( "super_read_only", "Make all non-temporary tables read-only, with the exception for " - "replication applier threads. Users with the SUPER privilege are " + "replication (slave) threads. Users with the SUPER privilege are " "affected, unlike read_only. Setting super_read_only to ON " "also sets read_only to ON.", GLOBAL_VAR(super_read_only), CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(fix_super_read_only)); +#ifdef HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO +static bool fix_whitelist_enabled(sys_var *, THD *thd, enum_var_type){ + +#ifdef HAVE_ZSQL_READONLY_WHITELIST_PRINT_LOG + LogErr(INFORMATION_LEVEL, ER_NUMBER_CONFIG_MODIFIED, + "gdb_read_only_super_whitelist_enabled", + g_read_only_super_whitelist_enabled); +#endif // HAVE_ZSQL_READONLY_WHITELIST_PRINT_LOG + + if(g_read_only_super_whitelist_enabled == false && super_read_only == false){ + // Do this last as it temporarily releases the global sys-var lock. + event_scheduler_restart(thd); + } + return false; +} +#endif // HAVE_ZSQL_FIX_EVENT_RESTART_SCENARIO + +#ifdef HAVE_ZSQL_READONLY_WHITELIST +static Sys_var_bool Sys_read_only_super_whitelist_enabled( + "gdb_read_only_super_whitelist_enabled", + "if it is enabled and read_only is set, super users in whitelist" + " should be allowed to write operation, if disable, whitelist is not used", + GLOBAL_VAR(g_read_only_super_whitelist_enabled), CMD_LINE(OPT_ARG), + DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(0), ON_UPDATE(fix_whitelist_enabled)); + +static bool check_read_only_super_whitelist(sys_var *, THD *, set_var *var) { + + const char *new_str = var->save_result.string_value.str; + if(new_str == nullptr) + return false; + + if (my_strnlen(new_str, READONLY_WHITELIST_MAX_USERS*(USERNAME_CHAR_LENGTH + 1)) + == READONLY_WHITELIST_MAX_USERS*(USERNAME_CHAR_LENGTH+1)) + return true; + + return false; +} + +static bool update_read_only_super_whitelist(sys_var *, THD *, enum_var_type) { + const char *current_pos = g_opt_read_only_super_whitelist; + size_t user_name_len = 0; + size_t user_count = 0; + + if (current_pos == nullptr) { + LogErr(INFORMATION_LEVEL, ER_STRING_CONFIG_MODIFIED, + "gdb_read_only_super_whitelist", g_opt_read_only_super_whitelist); + return false; + } + + READONLY_WHITELIST_LOCK(g_mysqld_super_whitelist_is_initialized); + memset(g_read_only_super_whitelist, 0x0, + READONLY_WHITELIST_MAX_USERS*(USERNAME_CHAR_LENGTH+1)); + + do { + if (*current_pos != ' ' && *current_pos != ',' && *current_pos != '\0') { + user_name_len++; + current_pos++; + if (user_name_len > USERNAME_CHAR_LENGTH) { + READONLY_WHITELIST_UNLOCK(g_mysqld_super_whitelist_is_initialized); + return true; + } + continue; + } + + if (user_name_len > 0 && user_count >= READONLY_WHITELIST_MAX_USERS) { + READONLY_WHITELIST_UNLOCK(g_mysqld_super_whitelist_is_initialized); + return true; + } + + if (user_name_len > 0) { + memcpy(g_read_only_super_whitelist[user_count], + current_pos-user_name_len, user_name_len); + user_count++; + user_name_len = 0; + } + + if (*current_pos == '\0') break; + + current_pos++; + } while(current_pos - g_opt_read_only_super_whitelist + < READONLY_WHITELIST_MAX_USERS*(USERNAME_CHAR_LENGTH+1)); + +#ifdef HAVE_ZSQL_READONLY_WHITELIST_PRINT_LOG + LogErr(INFORMATION_LEVEL, ER_STRING_CONFIG_MODIFIED, + "gdb_read_only_super_whitelist", g_opt_read_only_super_whitelist); +#endif // HAVE_ZSQL_READONLY_WHITELIST_PRINT_LOG + + READONLY_WHITELIST_UNLOCK(g_mysqld_super_whitelist_is_initialized); + return false; +} + +bool check_and_initialize_read_only_super_whitelist() { + + const char *new_str = g_opt_read_only_super_whitelist; + if (new_str == nullptr) + return false; + + if (my_strnlen(new_str, READONLY_WHITELIST_MAX_USERS*(USERNAME_CHAR_LENGTH+1)) + == READONLY_WHITELIST_MAX_USERS*(USERNAME_CHAR_LENGTH+1)) + return true; + + if (!my_strcasecmp(system_charset_info, g_opt_read_only_super_whitelist, "NULL")) + g_opt_read_only_super_whitelist = nullptr; + + if (update_read_only_super_whitelist(nullptr, nullptr, enum_var_type::OPT_DEFAULT)) + return true; + + return false; +} + +static Sys_var_charptr Sys_read_only_super_whitelist( + "gdb_read_only_super_whitelist", + "This option can be used to specify which super users " + "are allowed to write when read_only and read_only_super_whitelist_enabled " + "is set, takes the form of a comma or space separated list of users. ", + GLOBAL_VAR(g_opt_read_only_super_whitelist), + CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET, DEFAULT(nullptr), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(check_read_only_super_whitelist), + ON_UPDATE(update_read_only_super_whitelist)); +#endif // HAVE_ZSQL_READONLY_WHITELIST + // Small lower limit to be able to test MRR static Sys_var_ulong Sys_read_rnd_buff_size( "read_rnd_buffer_size", @@ -3787,8 +4258,9 @@ static Sys_var_ulong Sys_thread_stack( "thread_stack", "The stack size for each thread", READ_ONLY GLOBAL_VAR(my_thread_stack_size), CMD_LINE(REQUIRED_ARG), #if defined(__clang__) && defined(HAVE_UBSAN) - // Clang with DEBUG needs more stack, esp. with UBSAN. - VALID_RANGE(DEFAULT_THREAD_STACK, ULONG_MAX), + // DEFAULT_THREAD_STACK is multiplied by 3 for clang/UBSAN + // We need to increase the minimum value as well. + VALID_RANGE(DEFAULT_THREAD_STACK / 2, ULONG_MAX), #else VALID_RANGE(128 * 1024, ULONG_MAX), #endif @@ -3830,12 +4302,24 @@ static Sys_var_ulong Sys_trans_prealloc_size( BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(fix_trans_mem_root)); +// HAVE_ZSQL_QUICK_SYNC loaded-dynamically->pool-of-threads static const char *thread_handling_names[] = { - "one-thread-per-connection", "no-threads", "loaded-dynamically", nullptr}; + "one-thread-per-connection", "no-threads", "pool-of-threads", nullptr}; + +// HAVE_ZSQL_QUICK_SYNC begin +#if defined (_WIN32) && defined (HAVE_ZSQL_QUICK_SYNC) +/* Windows is using OS threadpool, so we're pretty sure it works well */ +#define DEFAULT_THREAD_HANDLING 2 +#else +#define DEFAULT_THREAD_HANDLING 0 +#endif +// HAVE_ZSQL_QUICK_SYNC end + +// HAVE_ZSQL_QUICK_SYNC loaded-dynamically->pool-of-threads static Sys_var_enum Sys_thread_handling( "thread_handling", "Define threads usage for handling queries, one of " - "one-thread-per-connection, no-threads, loaded-dynamically", + "one-thread-per-connection, no-threads, pool-of-threads", READ_ONLY GLOBAL_VAR(Connection_handler_manager::thread_handling), CMD_LINE(REQUIRED_ARG), thread_handling_names, DEFAULT(0)); @@ -3884,35 +4368,27 @@ static Sys_var_int32 Sys_regexp_stack_limit( GLOBAL_VAR(opt_regexp_stack_limit), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, INT32_MAX), DEFAULT(8000000), BLOCK_SIZE(1)); -static Sys_var_bool Sys_replica_compressed_protocol( - "replica_compressed_protocol", - "Use compression in the source/replica protocol.", - GLOBAL_VAR(opt_replica_compressed_protocol), CMD_LINE(OPT_ARG), +static Sys_var_bool Sys_slave_compressed_protocol( + "slave_compressed_protocol", "Use compression on master/slave protocol", + GLOBAL_VAR(opt_slave_compressed_protocol), CMD_LINE(OPT_ARG), DEFAULT(false)); -static Sys_var_deprecated_alias Sys_slave_compressed_protocol( - "slave_compressed_protocol", Sys_replica_compressed_protocol); - -static const char *replica_exec_mode_names[] = {"STRICT", "IDEMPOTENT", - nullptr}; -static Sys_var_enum Sys_replica_exec_mode( - "replica_exec_mode", +static const char *slave_exec_mode_names[] = {"STRICT", "IDEMPOTENT", nullptr}; +static Sys_var_enum Slave_exec_mode( + "slave_exec_mode", "Modes for how replication events should be executed. Legal values " "are STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, " - "replication will ignore duplicate key errors and key not found errors. " - "In STRICT mode, replication will stop at those errors.", - GLOBAL_VAR(replica_exec_mode_options), CMD_LINE(REQUIRED_ARG), - replica_exec_mode_names, DEFAULT(RBR_EXEC_MODE_STRICT)); + "replication will not stop for operations that are idempotent. " + "In STRICT mode, replication will stop on any unexpected difference " + "between the master and the slave", + GLOBAL_VAR(slave_exec_mode_options), CMD_LINE(REQUIRED_ARG), + slave_exec_mode_names, DEFAULT(RBR_EXEC_MODE_STRICT)); -static Sys_var_deprecated_alias Sys_slave_exec_mode("slave_exec_mode", - Sys_replica_exec_mode); - -const char *replica_type_conversions_name[] = { +const char *slave_type_conversions_name[] = { "ALL_LOSSY", "ALL_NON_LOSSY", "ALL_UNSIGNED", "ALL_SIGNED", nullptr}; -static Sys_var_set Sys_replica_type_conversions( - "replica_type_conversions", - "Set of type conversions that may be used by the replication applier " - "thread for row events. Allowed values are:" +static Sys_var_set Slave_type_conversions( + "slave_type_conversions", + "Set of slave type conversions that are enabled. Legal values are:" " ALL_LOSSY to enable lossy conversions," " ALL_NON_LOSSY to enable non-lossy conversions," " ALL_UNSIGNED to treat all integer column type data to be unsigned " @@ -3923,24 +4399,18 @@ static Sys_var_set Sys_replica_type_conversions( " specified, ALL_SIGNED will take higher priority than ALL_UNSIGNED." " If the variable is assigned the empty set, no conversions are" " allowed and it is expected that the types match exactly.", - GLOBAL_VAR(replica_type_conversions_options), CMD_LINE(REQUIRED_ARG), - replica_type_conversions_name, DEFAULT(0)); - -static Sys_var_deprecated_alias Sys_slave_type_conversions( - "slave_type_conversions", Sys_replica_type_conversions); + GLOBAL_VAR(slave_type_conversions_options), CMD_LINE(REQUIRED_ARG), + slave_type_conversions_name, DEFAULT(0)); -static Sys_var_bool Sys_replica_sql_verify_checksum( - "replica_sql_verify_checksum", +static Sys_var_bool Sys_slave_sql_verify_checksum( + "slave_sql_verify_checksum", "Force checksum verification of replication events after reading them " - "from relay log. Note: The replica always verifies checksums for events " - "received from the network, if the event has a checksum at all, before " - "it writes the event to the relay log. Enabled by default.", - GLOBAL_VAR(opt_replica_sql_verify_checksum), CMD_LINE(OPT_ARG), + "from relay log. Note: Events are always checksum-verified by slave on " + "receiving them from the network before writing them to the relay " + "log. Enabled by default.", + GLOBAL_VAR(opt_slave_sql_verify_checksum), CMD_LINE(OPT_ARG), DEFAULT(true)); -static Sys_var_deprecated_alias Sys_slave_sql_verify_checksum( - "slave_sql_verify_checksum", Sys_replica_sql_verify_checksum); - static bool check_not_null_not_empty(sys_var *self, THD *thd, set_var *var) { String str, *res; /* null value is not allowed */ @@ -3957,7 +4427,12 @@ static bool check_slave_stopped(sys_var *self, THD *thd, set_var *var) { bool result = false; Master_info *mi = nullptr; - if (check_not_null_not_empty(self, thd, var)) return true; + if ( +#ifdef HAVE_ZSQL_SLAVE_IMPROVE + strcasecmp(self->name.str, "slave_replay_performance") != 0 && +#endif // HAVE_ZSQL_SLAVE_IMPROVE + check_not_null_not_empty(self, thd, var)) + return true; channel_map.wrlock(); @@ -3981,10 +4456,12 @@ static const char *slave_rows_search_algorithms_names[] = { "TABLE_SCAN", "INDEX_SCAN", "HASH_SCAN", nullptr}; static Sys_var_set Slave_rows_search_algorithms( "slave_rows_search_algorithms", - "The set of algorithms used by the replication applier while searching the " - "table for rows to update or delete. Possible values are: INDEX_SCAN, " - "TABLE_SCAN and HASH_SCAN. Any combination is allowed, and the applier " - "picks the most efficient among them for any given scenario. " + "Set of searching algorithms that the slave will use while " + "searching for records from the storage engine to either " + "updated or deleted them. Possible values are: INDEX_SCAN, " + "TABLE_SCAN and HASH_SCAN. Any combination is allowed, and " + "the slave will always pick the most suitable algorithm for " + "any given scenario. " "(Default: INDEX_SCAN, HASH_SCAN).", GLOBAL_VAR(slave_rows_search_algorithms_options), CMD_LINE(REQUIRED_ARG, OPT_SLAVE_ROWS_SEARCH_ALGORITHMS), @@ -3995,23 +4472,14 @@ static Sys_var_set Slave_rows_search_algorithms( static const char *mts_parallel_type_names[] = {"DATABASE", "LOGICAL_CLOCK", nullptr}; -static Sys_var_enum Sys_replica_parallel_type( - "replica_parallel_type", - "The method used by the replication applier to parallelize " - "transactions. DATABASE, indicates that it " - "may apply transactions in parallel in case they update different " - "databases. LOGICAL_CLOCK, which is the default, indicates that it decides " - "whether two " - "transactions can be applied in parallel using the logical timestamps " - "computed by the source, according to " - "binlog_transaction_dependency_tracking.", +static Sys_var_enum Mts_parallel_type( + "slave_parallel_type", + "Specifies if the slave will use database partitioning " + "or information from master to parallelize transactions." + "(Default: DATABASE).", PERSIST_AS_READONLY GLOBAL_VAR(mts_parallel_option), CMD_LINE(REQUIRED_ARG), - mts_parallel_type_names, DEFAULT(MTS_PARALLEL_TYPE_LOGICAL_CLOCK), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_slave_stopped), - ON_UPDATE(nullptr)); - -static Sys_var_deprecated_alias Sys_slave_parallel_type( - "slave_parallel_type", Sys_replica_parallel_type); + mts_parallel_type_names, DEFAULT(MTS_PARALLEL_TYPE_DB_NAME), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(check_slave_stopped), ON_UPDATE(nullptr)); static bool check_binlog_transaction_dependency_tracking(sys_var *, THD *, set_var *var) { @@ -4039,15 +4507,14 @@ static bool update_binlog_transaction_dependency_tracking(sys_var *, THD *, } static PolyLock_mutex PLock_slave_trans_dep_tracker( - &LOCK_replica_trans_dep_tracker); + &LOCK_slave_trans_dep_tracker); static const char *opt_binlog_transaction_dependency_tracking_names[] = { "COMMIT_ORDER", "WRITESET", "WRITESET_SESSION", NullS}; static Sys_var_enum Binlog_transaction_dependency_tracking( "binlog_transaction_dependency_tracking", "Selects the source of dependency information from which to " - "compute logical timestamps, which replicas can use to decide which " - "transactions can be executed in parallel when using " - "replica_parallel_type=LOGICAL_CLOCK. " + "assess which transactions can be executed in parallel by the " + "slave's multi-threaded applier. " "Possible values are COMMIT_ORDER, WRITESET and WRITESET_SESSION.", GLOBAL_VAR(mysql_bin_log.m_dependency_tracker.m_opt_tracking_mode), CMD_LINE(REQUIRED_ARG), opt_binlog_transaction_dependency_tracking_names, @@ -4059,21 +4526,57 @@ static Sys_var_ulong Binlog_transaction_dependency_history_size( "Maximum number of rows to keep in the writeset history.", GLOBAL_VAR(mysql_bin_log.m_dependency_tracker.get_writeset() ->m_opt_max_history_size), - CMD_LINE(REQUIRED_ARG, 0), VALID_RANGE(1, 1000000), DEFAULT(25000), + CMD_LINE(REQUIRED_ARG, 0), VALID_RANGE(1, ULONG_MAX), DEFAULT(25000), BLOCK_SIZE(1), &PLock_slave_trans_dep_tracker, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr)); -static Sys_var_bool Sys_replica_preserve_commit_order( - "replica_preserve_commit_order", - "Force replication worker threads to commit in the same order as on the " - "source. Enabled by default", - PERSIST_AS_READONLY GLOBAL_VAR(opt_replica_preserve_commit_order), - CMD_LINE(OPT_ARG, OPT_REPLICA_PRESERVE_COMMIT_ORDER), DEFAULT(true), +static char *gdb_instance_name; +static Sys_var_charptr Sys_gdb_instance_name( + "gdb_instance_name", "gdb_instance_name", + GLOBAL_VAR(gdb_instance_name),CMD_LINE(REQUIRED_ARG), + IN_SYSTEM_CHARSET, DEFAULT("gdb_dn"), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(nullptr),ON_UPDATE(nullptr)); + +static Sys_var_bool Sys_slave_preserve_commit_order( + "slave_preserve_commit_order", + "Force slave workers to make commits in the same order as on the master. " + "Disabled by default.", + PERSIST_AS_READONLY GLOBAL_VAR(opt_slave_preserve_commit_order), + CMD_LINE(OPT_ARG, OPT_SLAVE_PRESERVE_COMMIT_ORDER), DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_slave_stopped), ON_UPDATE(nullptr)); -static Sys_var_deprecated_alias Sys_slave_preserve_commit_order( - "slave_preserve_commit_order", Sys_replica_preserve_commit_order); +#ifdef HAVE_ZSQL_SLAVE_IMPROVE +static Sys_var_bool Sys_slave_no_wait_last_committed_trx( + "slave_sql_thread_no_wait", + "MTS Coordinator don't wait for last committed trx. " + "Disabled by default.", + PERSIST_AS_READONLY GLOBAL_VAR(opt_slave_no_wait_last_committed_trx), + CMD_LINE(OPT_ARG), DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_slave_stopped), + ON_UPDATE(NULL)); + +// TODO: remove NONE when GoldenDB insight fix the configure pushdown system. +static const char *slave_replay_perf_names[] = { + "MEMORY_OPTIMIZE", "THREAD_OPTIMIZE", "NONE", nullptr}; + +static Sys_var_set Sys_slave_replay_performance( + "slave_replay_performance", + "Whether slave host opens performance. Possible values are: " + // "MEMORY_OPTIMIZE, THREAD_OPTIMIZE and NONE. NONE value is ignored unless " + "MEMORY_OPTIMIZE and NONE. NONE value is ignored unless " + "there are no other value set", + GLOBAL_VAR(opt_slave_replay_perf), CMD_LINE(REQUIRED_ARG), + slave_replay_perf_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_slave_stopped)); + +static Sys_var_ulonglong Sys_slave_replay_max_memory( + "slave_replay_max_memory", + "The threshold value of the memory pool when the slave replay uses memory " + "optimization", + GLOBAL_VAR(opt_slave_replay_max_memory), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, ULLONG_MAX), DEFAULT(1 << 30 /* 1 GiB */), BLOCK_SIZE(1)); +#endif // HAVE_ZSQL_SLAVE_IMPROVE bool Sys_var_charptr::global_update(THD *, set_var *var) { char *new_val, *ptr = var->save_result.string_value.str; @@ -4091,6 +4594,27 @@ bool Sys_var_charptr::global_update(THD *, set_var *var) { return false; } +#ifdef HAVE_ZSQL_VERSION_CHANGABLE +bool Sys_var_version::global_update(THD *, set_var *var) { + //we don't need to new a char* when update + //we already have a global charptr + char *old_val = global_var(char *); + size_t len = var->save_result.string_value.length; + char *new_val = var->save_result.string_value.str; + if (new_val) + { + strncpy(old_val, new_val, len); + old_val[len] = 0; + } + else + { + old_val[0] = 0; + } + flags |= ALLOCATED; + return false; +} +#endif + bool Sys_var_enum_binlog_checksum::global_update(THD *thd, set_var *var) { bool check_purge = false; @@ -4206,7 +4730,7 @@ bool Sys_var_gtid_set::session_update(THD *thd, set_var *var) { */ static void issue_deprecation_warnings_gtid_mode( - THD *thd, Gtid_mode::value_type oldmode [[maybe_unused]], + THD *thd, Gtid_mode::value_type oldmode MY_ATTRIBUTE((unused)), Gtid_mode::value_type newmode) { channel_map.assert_some_lock(); @@ -4307,19 +4831,18 @@ bool Sys_var_gtid_mode::global_update(THD *thd, set_var *var) { goto err; } - DBUG_PRINT("info", ("sql_replica_skip_counter=%d", sql_replica_skip_counter)); - if (new_gtid_mode == Gtid_mode::ON && sql_replica_skip_counter > 0) { - push_warning( - thd, Sql_condition::SL_WARNING, - ER_SQL_REPLICA_SKIP_COUNTER_USED_WITH_GTID_MODE_ON, - ER_THD(thd, ER_SQL_REPLICA_SKIP_COUNTER_USED_WITH_GTID_MODE_ON)); + DBUG_PRINT("info", ("sql_slave_skip_counter=%d", sql_slave_skip_counter)); + if (new_gtid_mode == Gtid_mode::ON && sql_slave_skip_counter > 0) { + push_warning(thd, Sql_condition::SL_WARNING, + ER_SQL_SLAVE_SKIP_COUNTER_USED_WITH_GTID_MODE_ON, + ER_THD(thd, ER_SQL_SLAVE_SKIP_COUNTER_USED_WITH_GTID_MODE_ON)); } if (new_gtid_mode != Gtid_mode::ON && replicate_same_server_id && - opt_log_replica_updates && opt_bin_log) { + opt_log_slave_updates && opt_bin_log) { std::stringstream ss; - ss << "replicate_same_server_id is set together with log_replica_updates" + ss << "replicate_same_server_id is set together with log_slave_updates" << " and log_bin. Thus, any anonymous transactions" << " would circulate infinitely in case this server is part of a" << " circular replication topology"; @@ -4375,11 +4898,10 @@ bool Sys_var_gtid_mode::global_update(THD *thd, set_var *var) { "Execute CHANGE MASTER TO " "ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS = OFF " "FOR CHANNEL '%.192s' before you set " - "@@GLOBAL.GTID_MODE = '%s'", + "@@GLOBAL.GTID_MODE = '%s'.", mi->get_channel(), mi->get_channel(), Gtid_mode::to_string(new_gtid_mode)); - my_error(ER_CANT_SET_GTID_MODE, MYF(0), - Gtid_mode::to_string(new_gtid_mode), buf); + my_error(ER_CANT_SET_GTID_MODE, MYF(0), "OFF", buf); goto err; } } @@ -4399,29 +4921,6 @@ bool Sys_var_gtid_mode::global_update(THD *thd, set_var *var) { } } } - /* - Cannot set to <> ON when gtid_only is enabled for any channel. - */ - if (old_gtid_mode == Gtid_mode::ON && new_gtid_mode != Gtid_mode::ON) { - for (auto it : channel_map) { - Master_info *mi = it.second; - if (mi != nullptr && mi->is_gtid_only_mode()) { - char buf[1024]; - snprintf(buf, sizeof(buf), - "replication channel '%.192s' is configured " - "with GTID_ONLY = 1. " - "Execute CHANGE REPLICATION SOURCE TO " - "GTID_ONLY = 0 " - "FOR CHANNEL '%.192s' before you set " - "@@GLOBAL.GTID_MODE = '%s'", - mi->get_channel(), mi->get_channel(), - Gtid_mode::to_string(new_gtid_mode)); - my_error(ER_CANT_SET_GTID_MODE, MYF(0), - Gtid_mode::to_string(new_gtid_mode), buf); - goto err; - } - } - } // Can't set GTID_MODE != ON when group replication is enabled. if (is_group_replication_running()) { @@ -4622,16 +5121,13 @@ static Sys_var_enum_binlog_checksum Binlog_checksum_enum( binlog_checksum_type_names, DEFAULT(binary_log::BINLOG_CHECKSUM_ALG_CRC32), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_outside_trx)); -static Sys_var_bool Sys_source_verify_checksum( - "source_verify_checksum", - "Force checksum verification of events in binary log before " - "sending them to replicas or printing them in output of SHOW BINLOG " +static Sys_var_bool Sys_master_verify_checksum( + "master_verify_checksum", + "Force checksum verification of logged events in binary log before " + "sending them to slaves or printing them in output of SHOW BINLOG " "EVENTS. " "Disabled by default.", - GLOBAL_VAR(opt_source_verify_checksum), CMD_LINE(OPT_ARG), DEFAULT(false)); - -static Sys_var_deprecated_alias Sys_master_verify_checksum( - "master_verify_checksum", Sys_source_verify_checksum); + GLOBAL_VAR(opt_master_verify_checksum), CMD_LINE(OPT_ARG), DEFAULT(false)); static Sys_var_ulong Sys_slow_launch_time( "slow_launch_time", @@ -4692,6 +5188,21 @@ export sql_mode_t expand_sql_mode(sql_mode_t sql_mode, THD *thd) { MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_ERROR_FOR_DIVISION_BY_ZERO | MODE_NO_ENGINE_SUBSTITUTION); +#ifdef HAVE_ZSQL_ORA_DATATYPE + if (sql_mode & MODE_ORA_COMPATIBLE_MODE) { + sql_mode |= + (MODE_ANSI_QUOTES | MODE_PIPES_AS_CONCAT | MODE_NO_BACKSLASH_ESCAPES | + MODE_EMPTY_STRING_IS_NULL | MODE_DECIMAL_ACTUAL_FRACTION | + MODE_ORA_SECONDARY_INDEX_NULLS_EQUAL | MODE_ORA_DATATYPE | + MODE_ORA_ROWID | MODE_ORA_ERRCODE | MODE_ORA_IGNORE | + MODE_ORA_PREFIX_INDEX_LENGTH_CUT | MODE_ORA_KEYWORD | + MODE_ORA_COMMENT | MODE_ORA_FUNCTION | MODE_ORA_WELL_SIGN_AFTER_IDENT | + MODE_ORA_CONCAT | MODE_ORA_NUMTOSTR_ERROR | MODE_ORA_NULLS_ORDER); + + sql_mode &= ~MODE_SYSDATE_FOR_MYSQL; + } +#endif // HAVE_ZSQL_ORA_DATATYPE + check_sub_modes_of_strict_mode(sql_mode, thd); return sql_mode; } @@ -4706,8 +5217,8 @@ static bool check_sql_mode(sys_var *, THD *thd, set_var *var) { } if (candidate_mode & ~MODE_ALLOWED_MASK) { - if (thd->variables.pseudo_replica_mode && // (1) - thd->lex->sphead == nullptr) { // (2) + if (thd->variables.pseudo_slave_mode && // (1) + thd->lex->sphead == nullptr) { // (2) /* (1): catch the auto-generated SET SQL_MODE calls in the output of mysqlbinlog, @@ -4784,6 +5295,23 @@ static const char *sql_mode_names[] = {"REAL_AS_FLOAT", "NO_ENGINE_SUBSTITUTION", "PAD_CHAR_TO_FULL_LENGTH", "TIME_TRUNCATE_FRACTIONAL", + "SYSDATE_FOR_MYSQL", // HAVE_ZSQL_SYSDATE + "ORA_COMPATIBLE_MODE", // HAVE_ZSQL_ORA_DATATYPE + "EMPTY_STRING_IS_NULL", // HAVE_ZSQL_EMPTY_STRING_IS_NULL + "DECIMAL_ACTUAL_FRACTION", // HAVE_ZSQL_DECIMAL_ACTUAL_FRACTION + "ORA_SECONDARY_INDEX_NULLS_EQUAL", // HAVE_ZSQL_SECONDARY_INDEX_NULLS_EQUAL + "ORA_DATATYPE", // HAVE_ZSQL_ORA_DATATYPE + "ORA_ROWID", // HAVE_ZSQL_ROWID + "ORA_ERRCODE", // HAVE_ZSQL_ORA_ERRCODE + "ORA_IGNORE", // HAVE_ZSQL_ORA_IGNORE_TABLESPACE + "ORA_PREFIX_INDEX_LENGTH_CUT", // HAVE_ZSQL_ORACLE_PREFIX_INDEX_LENGTH_CUT + "ORA_KEYWORD", // HAVE_ZSQL_ORA_KEYWORD + "ORA_COMMENT", // HAVE_ZSQL_ORA_COMMENT + "ORA_FUNCTION", // HAVE_ZSQL_SYSDATE_CONST + "ORA_WELL_SIGN_AFTER_IDENT", // HAVE_ZSQL_ORACLE_ALLOW_WELL_SIGN_AFTER_IDENT + "ORA_CONCAT", // HAVE_ZSQL_COMPATIBLE_CONCAT + "ORA_NUMTOSTR_ERROR", // HAVE_ZSQL_NUMTOSTR_ERROR + "ORA_NULLS_ORDER", // HAVE_ZSQL_ORACLE_ORDER_BY_NULLS nullptr}; export bool sql_mode_string_representation(THD *thd, sql_mode_t sql_mode, LEX_STRING *ls) { @@ -4812,18 +5340,35 @@ static Sys_var_set Sys_sql_mode( NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_sql_mode), ON_UPDATE(fix_sql_mode)); +#ifdef HAVE_ZSQL_ORA_PROFILE +static bool check_max_execution_time_effect(sys_var *, THD *thd, set_var *var) { + if (!(var->type & enum_var_type::OPT_SESSION)) + return false; + + if (thd->m_profile.execution_time) { + my_error(ER_BLACKLIST_COMMAND,MYF(0),"change session max_execution_time "); + return true; + } + return false; +} +#endif //HAVE_ZSQL_ORA_PROFILE + static Sys_var_ulong Sys_max_execution_time( "max_execution_time", "Kill SELECT statement that takes over the specified number of " "milliseconds", HINT_UPDATEABLE SESSION_VAR(max_execution_time), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1)); + VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1) +#ifdef HAVE_ZSQL_ORA_PROFILE + , NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_max_execution_time_effect) +#endif //HAVE_ZSQL_ORA_PROFILE +); static bool update_fips_mode(sys_var *, THD *, enum_var_type) { char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'}; if (set_fips_mode(opt_ssl_fips_mode, ssl_err_string) != 1) { opt_ssl_fips_mode = get_fips_mode(); - my_error(ER_DA_SSL_FIPS_MODE_ERROR, MYF(0), "Openssl is not fips enabled"); + my_error(ER_SSL_FIPS_MODE_ERROR, MYF(0), "Openssl is not fips enabled"); return true; } else { return false; @@ -4860,8 +5405,11 @@ static Sys_var_enum Sys_updatable_views_with_limit( HINT_UPDATEABLE SESSION_VAR(updatable_views_with_limit), CMD_LINE(REQUIRED_ARG), updatable_views_with_limit_names, DEFAULT(true)); -static Sys_var_system_time_zone Sys_system_time_zone( - "system_time_zone", "The server system time zone"); +static char *system_time_zone_ptr; +static Sys_var_charptr Sys_system_time_zone( + "system_time_zone", "The server system time zone", + READ_ONLY NON_PERSIST GLOBAL_VAR(system_time_zone_ptr), NO_CMD_LINE, + IN_FS_CHARSET, DEFAULT(system_time_zone)); static Sys_var_ulong Sys_table_def_size( "table_definition_cache", "The number of cached table definitions", @@ -4956,7 +5504,186 @@ static Sys_var_ulong Sys_parse_mode( "How db parse query statment", SESSION_VAR(m_opt_parse_mode), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, 2), DEFAULT(1), BLOCK_SIZE(1)); +#endif //HAVE_ZSQL_ORACLE_COMPATIBILITY + +#ifdef HAVE_ZSQL_EXPORT_NULL_AS_SPACE +static Sys_var_bool Sys_export_null_as_space( + "export_null_as_space", + "When exports data, replace null to 0 length space", + SESSION_VAR(export_null_as_space), + CMD_LINE(OPT_ARG), + DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(0), ON_UPDATE(0)); + +static Sys_var_bool Sys_import_space_as_null( + "import_space_as_null", + "When import data, replace 0 length space as null", + SESSION_VAR(import_space_as_null), + CMD_LINE(OPT_ARG), + DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(0), ON_UPDATE(0)); +#endif /* HAVE_ZSQL_EXPORT_NULL_AS_SPACE */ + +#ifdef HAVE_ZSQL_QUICK_SYNC +static bool fix_tp_max_threads(sys_var *, THD *, enum_var_type) +{ +#ifdef _WIN32 + tp_set_max_threads(threadpool_max_threads); +#endif + return false; +} + + +#ifdef _WIN32 +static bool fix_tp_min_threads(sys_var *, THD *, enum_var_type) +{ + tp_set_min_threads(threadpool_min_threads); + return false; +} +#endif + + +#ifndef _WIN32 +static bool fix_threadpool_size(sys_var*, THD*, enum_var_type) +{ + tp_set_threadpool_size(threadpool_size); + return false; +} + + +static bool fix_threadpool_stall_limit(sys_var*, THD*, enum_var_type) +{ + tp_set_threadpool_stall_limit(threadpool_stall_limit); + return false; +} +#endif + +static inline int my_getncpus() +{ +#ifdef _SC_NPROCESSORS_ONLN + return sysconf(_SC_NPROCESSORS_ONLN); +#else + return 2; /* The value returned by the old my_getncpus implementation */ #endif +} + +#ifdef _WIN32 +static Sys_var_uint Sys_threadpool_min_threads( + "thread_pool_min_threads", + "Minimum number of threads in the thread pool.", + GLOBAL_VAR(threadpool_min_threads), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(1, 256), DEFAULT(1), BLOCK_SIZE(1), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(fix_tp_min_threads) + ); +#else +static Sys_var_uint Sys_threadpool_idle_thread_timeout( + "thread_pool_idle_timeout", + "Timeout in seconds for an idle thread in the thread pool." + "Worker thread will be shut down after timeout", + GLOBAL_VAR(threadpool_idle_timeout), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(1, UINT_MAX), DEFAULT(60), BLOCK_SIZE(1) +); +static Sys_var_uint Sys_threadpool_oversubscribe( + "thread_pool_oversubscribe", + "How many additional active worker threads in a group are allowed.", + GLOBAL_VAR(threadpool_oversubscribe), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(3, 1000), DEFAULT(3), BLOCK_SIZE(1) +); +static Sys_var_uint Sys_threadpool_size( + "thread_pool_size", + "Number of thread groups in the pool. " + "This parameter is roughly equivalent to maximum number of concurrently " + "executing threads (threads in a waiting state do not count as executing).", + GLOBAL_VAR(threadpool_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(1, MAX_THREAD_GROUPS), DEFAULT(64), BLOCK_SIZE(1), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(fix_threadpool_size) +); +static Sys_var_uint Sys_threadpool_stall_limit( + "thread_pool_stall_limit", + "Maximum query execution time in milliseconds," + "before an executing non-yielding thread is considered stalled." + "If a worker thread is stalled, additional worker thread " + "may be created to handle remaining clients.", + GLOBAL_VAR(threadpool_stall_limit), CMD_LINE(REQUIRED_ARG), + /* + HAVE_ZSQL_OPTIMIZE_STATEMENT_BLOCK_WITH_QUICKSYNC + Change the threadpool_stall_limit minimum from 10ms to 1ms. + */ + VALID_RANGE(1, UINT_MAX), DEFAULT(500), BLOCK_SIZE(1), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(fix_threadpool_stall_limit) +); +static Sys_var_uint Sys_threadpool_high_prio_tickets( + "thread_pool_high_prio_tickets", + "Number of tickets to enter the high priority event queue for each " + "transaction.", + SESSION_VAR(threadpool_high_prio_tickets), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, UINT_MAX), DEFAULT(UINT_MAX), BLOCK_SIZE(1) +); + +static Sys_var_enum Sys_threadpool_high_prio_mode( + "thread_pool_high_prio_mode", + "High priority queue mode: one of 'transactions', 'statements' or 'none'. " + "In the 'transactions' mode the thread pool uses both high- and low-priority " + "queues depending on whether an event is generated by an already started " + "transaction or a connection holding a MDL, table, user, or a global read " + "or backup lock and whether it has any high priority tickets (see " + "thread_pool_high_prio_tickets). In the 'statements' mode all events (i.e. " + "individual statements) always go to the high priority queue, regardless of " + "the current transaction and lock state and high priority tickets. " + "'none' is the opposite of 'statements', i.e. disables the high priority queue " + "completely.", + SESSION_VAR(threadpool_high_prio_mode), CMD_LINE(REQUIRED_ARG), + threadpool_high_prio_mode_names, DEFAULT(TP_HIGH_PRIO_MODE_TRANSACTIONS)); + +#endif /* !WIN32 */ +static Sys_var_uint Sys_threadpool_max_threads( + "thread_pool_max_threads", + "Maximum allowed number of worker threads in the thread pool", + GLOBAL_VAR(threadpool_max_threads), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(1, MAX_CONNECTIONS), DEFAULT(MAX_CONNECTIONS), BLOCK_SIZE(1), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(fix_tp_max_threads) +); +#endif // HAVE_ZSQL_QUICK_SYNC + +#ifdef HAVE_ZSQL_OPTIMIZE_THREAD_POOL +static Sys_var_bool Sys_threadpool_sharp_mode( + "thread_pool_sharp_mode", + "Whether to enable thread pool sharp mode (disabled by default).", + GLOBAL_VAR(threadpool_sharp_mode), CMD_LINE(OPT_ARG), DEFAULT(false)); + +static Sys_var_uint Sys_threadpool_reserved_idle_threads( + "thread_pool_reserved_idle_threads", + "The number of idle threads reserved in each group", + GLOBAL_VAR(threadpool_reserved_idle_threads), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(1, 1000), DEFAULT(1), BLOCK_SIZE(1)); + +static Sys_var_uint Sys_threadpool_wait_time( + "thread_pool_wait_time", + "time interval of thread creation in milliseconds, " + "enabled when sharp mode is on", + GLOBAL_VAR(threadpool_wait_time), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(1, UINT_MAX), DEFAULT(500), BLOCK_SIZE(1) +); +#endif // HAVE_ZSQL_OPTIMIZE_THREAD_POOL + +#ifdef HAVE_ZSQL_BATCH_EXECUTE +static Sys_var_bool Sys_batch_insert_ignore_dup_entry( + "batch_insert_ignore_duplicate_key", + "Whether to ignore duplicate key entry (disabled by default).", + GLOBAL_VAR(g_batch_insert_ignore), CMD_LINE(OPT_ARG), DEFAULT(false)); +#endif // HAVE_ZSQL_BATCH_EXECUTE + +#ifdef HAVE_ZSQL_REGEXP_ALLOW_BIN_ARG +static Sys_var_bool Sys_regexp_allow_bin_arg( + "regexp_allow_bin_arg", + "Whether to allow using binary argument in regexp function " + "(disabled by default).", + GLOBAL_VAR(g_regexp_allow_bin_arg), CMD_LINE(OPT_ARG), DEFAULT(false)); +#endif // HAVE_ZSQL_REGEXP_ALLOW_BIN_ARG /** Function to check if the 'next' transaction isolation level @@ -5021,6 +5748,50 @@ bool Sys_var_transaction_isolation::session_update(THD *thd, set_var *var) { return false; } +#ifdef HAVE_ZSQL_SUPPORT_JDBC_5_1_40_THROUGH_DBPROXY +static bool fix_query_cache_size(sys_var *, THD *thd, enum_var_type) +{ + push_warning_printf(thd, Sql_condition::SL_WARNING, + ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT, + ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT), + "query_cache_size"); + + return false; +} + +static Sys_var_ulong Sys_query_cache_size( + "query_cache_size", + "This variable is deprecated and removed, " + "only use it compatible with the old version of the driver.", + GLOBAL_VAR(query_cache_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, ULONG_MAX), DEFAULT(1024U*1024U), BLOCK_SIZE(1024), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(fix_query_cache_size)); + +static const char *query_cache_type_names[]= { "OFF", "ON", "DEMAND", 0 }; +static bool check_query_cache_type(sys_var *, THD *thd, set_var *) +{ + push_warning_printf(thd, Sql_condition::SL_WARNING, + ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT, + ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT), + "query_cache_type"); + return false; +} +static Sys_var_enum Sys_query_cache_type( + "query_cache_type", + "This variable is deprecated and removed, " + "only use it compatible with the old version of the driver.", + SESSION_VAR(query_cache_type), CMD_LINE(REQUIRED_ARG), + query_cache_type_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_query_cache_type), ON_UPDATE(NULL)); + +static Sys_var_transaction_isolation Sys_tx_isolation( + "tx_isolation", "Default transaction isolation level", + UNTRACKED_DEFAULT SESSION_VAR(transaction_isolation), NO_CMD_LINE, + tx_isolation_names, DEFAULT(ISO_REPEATABLE_READ), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(check_transaction_isolation)); +#endif /* HAVE_ZSQL_SUPPORT_JDBC_5_1_40_THROUGH_DBPROXY */ + // NO_CMD_LINE static Sys_var_transaction_isolation Sys_transaction_isolation( "transaction_isolation", "Default transaction isolation level", @@ -5096,11 +5867,62 @@ static Sys_var_ulonglong Sys_tmp_table_size( VALID_RANGE(1024, (ulonglong) ~(intptr)0), DEFAULT(16 * 1024 * 1024), BLOCK_SIZE(1)); +#ifdef HAVE_ZSQL_GOLDENDB_SERVER_VERSION +/* variable for goldendb */ +static char *goldendb_server_version_ptr; +static Sys_var_version Sys_version_goldendb( + "goldendb_version", "Goldendb server version", + READ_ONLY GLOBAL_VAR(goldendb_server_version_ptr), NO_CMD_LINE, + IN_SYSTEM_CHARSET, DEFAULT(goldendb_server_version)); +#endif /* HAVE_ZSQL_GOLDENDB_SERVER_VERSION */ + +#ifdef HAVE_ZSQL_GIT_REVISION +/* git version for DN */ +static char *git_version_ptr; +static char *build_time_ptr; +static Sys_var_version Sys_git_version( + "git_version", "git version for DN", + READ_ONLY GLOBAL_VAR(git_version_ptr), NO_CMD_LINE, + IN_SYSTEM_CHARSET, DEFAULT(GIT_VERSION)); + +/* get build_time for DN */ +auto build_time = std::string(__DATE__) + std::string(" ") + std::string(__TIME__); +static Sys_var_version Sys_build_time( + "build_time", "build time for DN", + READ_ONLY GLOBAL_VAR(build_time_ptr), NO_CMD_LINE, + IN_SYSTEM_CHARSET, DEFAULT(build_time.data())); + +#endif /* HAVE_ZSQL_GIT_REVISION*/ + +#ifdef HAVE_ZSQL_GTMGTID_IDX +/* gtid_idx mechanism switch */ +static Sys_var_bool Sys_binlog_gtmgtid_index_enabled( + "enable_binlog_gtmgtid_index", + "Enable the ${binlog_name}.gtid_idx mechanism.", + GLOBAL_VAR(opt_gtmgtid_idx), + CMD_LINE(OPT_ARG), DEFAULT(true)); +#endif /* HAVE_ZSQL_GTMGTID_IDX */ + +#ifndef HAVE_ZSQL_VERSION_CHANGABLE static char *server_version_ptr; static Sys_var_version Sys_version( "version", "Server version", READ_ONLY NON_PERSIST GLOBAL_VAR(server_version_ptr), NO_CMD_LINE, IN_SYSTEM_CHARSET, DEFAULT(server_version)); +#else +/* version can be changed simultaneously either when gdb_external_id is set in my.cnf + * or when executing `set global gdb_external_id = "8.0.25"` + * because the variable "version" cannot be modified in my.cnf */ +static Sys_var_version Sys_version( + "version", "Server version", + GLOBAL_VAR(zsql_version_ptr), NO_CMD_LINE, + IN_SYSTEM_CHARSET, DEFAULT(zsql_version)); + +static Sys_var_version Sys_version_zsql( + "gdb_external_id", "Zsql Server version", + GLOBAL_VAR(zsql_version_ptr), CMD_LINE(REQUIRED_ARG), + IN_SYSTEM_CHARSET, DEFAULT(zsql_version)); +#endif static char *server_version_comment_ptr; static Sys_var_charptr Sys_version_comment( @@ -5132,7 +5954,11 @@ static Sys_var_ulong Sys_net_wait_timeout( "connection before closing it", SESSION_VAR(net_wait_timeout), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, IF_WIN(INT_MAX32 / 1000, LONG_TIMEOUT)), - DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1)); + DEFAULT(NET_WAIT_TIMEOUT), BLOCK_SIZE(1) +#ifdef HAVE_ZSQL_ORA_PROFILE + , NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_idle_time_effect) +#endif // HAVE_ZSQL_ORA_PROFILE +); static Sys_var_plugin Sys_default_storage_engine( "default_storage_engine", "The default storage engine for new tables", @@ -5147,8 +5973,7 @@ static Sys_var_enum Sys_internal_tmp_mem_storage_engine( "The default storage engine for in-memory internal temporary tables.", HINT_UPDATEABLE SESSION_VAR(internal_tmp_mem_storage_engine), CMD_LINE(REQUIRED_ARG), internal_tmp_mem_storage_engine_names, - DEFAULT(TMP_TABLE_TEMPTABLE), NO_MUTEX_GUARD, NOT_IN_BINLOG, - ON_CHECK(check_session_admin_no_super)); + DEFAULT(TMP_TABLE_TEMPTABLE)); static Sys_var_ulonglong Sys_temptable_max_ram( "temptable_max_ram", @@ -5167,14 +5992,10 @@ static Sys_var_ulonglong Sys_temptable_max_mmap( GLOBAL_VAR(temptable_max_mmap), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, ULLONG_MAX), DEFAULT(1 << 30 /* 1 GiB */), BLOCK_SIZE(1)); -static Sys_var_bool Sys_temptable_use_mmap( - "temptable_use_mmap", - "Use mmap files for temptables. " - "This variable is deprecated and will be removed in a future release.", - GLOBAL_VAR(temptable_use_mmap), CMD_LINE(OPT_ARG), DEFAULT(true), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), - ON_UPDATE(update_deprecated_with_removal_message), nullptr, - sys_var::PARSE_NORMAL); +static Sys_var_bool Sys_temptable_use_mmap("temptable_use_mmap", + "Use mmap files for temptables", + GLOBAL_VAR(temptable_use_mmap), + CMD_LINE(OPT_ARG), DEFAULT(false));// HAVE_ZSQL_MMAP static Sys_var_plugin Sys_default_tmp_storage_engine( "default_tmp_storage_engine", @@ -5223,6 +6044,9 @@ static bool pre_autocommit(sys_var *self, THD *thd, set_var *var) { if (!(self->is_global_persist(var->type)) && (thd->variables.option_bits & OPTION_NOT_AUTOCOMMIT) && var->save_result.ulonglong_value) { +#ifdef HAVE_ZSQL_TRANS_STATUS_STAT + trans_commit_count_inc(thd); +#endif // HAVE_ZSQL_TRANS_STATUS_STAT // Autocommit mode is about to be activated. if (trans_commit_stmt(thd) || trans_commit(thd)) return true; } @@ -5304,8 +6128,8 @@ static Sys_var_bit Sys_log_off("sql_log_off", "sql_log_off", @return @c false. */ -static bool fix_sql_log_bin_after_update(sys_var *, THD *thd, - enum_var_type type [[maybe_unused]]) { +static bool fix_sql_log_bin_after_update( + sys_var *, THD *thd, enum_var_type type MY_ATTRIBUTE((unused))) { assert(type == OPT_SESSION); if (thd->variables.sql_log_bin) @@ -5324,6 +6148,7 @@ static bool fix_sql_log_bin_after_update(sys_var *, THD *thd, - there is no on-going transaction. @param thd Current thread + @param[in] self A pointer to the sys_var, i.e. Sys_log_binlog. @param[in] var A pointer to the set_var created by the parser. @@ -5605,38 +6430,36 @@ static Sys_var_charptr Sys_hostname( static Sys_var_charptr Sys_repl_report_host( "report_host", - "Hostname or IP that this replica will report to the source while " - "initiating the replication connection. Will appear in the output of " - "SHOW REPLICAS. Leave this unset if you do not want the replica to " - "register itself with the source. Note that it is not sufficient for " - "the source to simply read the IP of the replica off the socket once the " - "replica connects: in the presence of NAT other routing features, that IP " - "may not be valid for connecting to the replica from the source or other " - "hosts.", + "Hostname or IP of the slave to be reported to the master during " + "slave registration. Will appear in the output of SHOW SLAVE HOSTS. " + "Leave unset if you do not want the slave to register itself with the " + "master. Note that it is not sufficient for the master to simply read " + "the IP of the slave off the socket once the slave connects. Due to " + "NAT and other routing issues, that IP may not be valid for connecting " + "to the slave from the master or other hosts", READ_ONLY GLOBAL_VAR(report_host), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(nullptr)); static Sys_var_charptr Sys_repl_report_user( "report_user", - "The account user name that this replica will report to the source " - "while initiating the replication connection.", + "The account user name of the slave to be reported to the master " + "during slave registration", READ_ONLY GLOBAL_VAR(report_user), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(nullptr)); static Sys_var_charptr Sys_repl_report_password( "report_password", - "The account password that this replica will report to the source " - "while initiating the replication connection.", + "The account password of the slave to be reported to the master " + "during slave registration", READ_ONLY GLOBAL_VAR(report_password), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(nullptr)); static Sys_var_uint Sys_repl_report_port( "report_port", - "The port for connecting to the replica, which this replica will report " - "to the source while initiating the replication connection. " - "Set it only if the replica is listening on a non-default " - "port or if you have a special tunnel from the source or other clients " - "to this replica. If not sure, leave this option unset.", + "Port for connecting to slave reported to the master during slave " + "registration. Set it only if the slave is listening on a non-default " + "port or if you have a special tunnel from the master or other clients " + "to the slave. If not sure, leave this option unset", READ_ONLY GLOBAL_VAR(report_port), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 65535), DEFAULT(0), BLOCK_SIZE(1)); @@ -5741,7 +6564,7 @@ static Sys_var_charptr Sys_general_log_path( DEFAULT(nullptr), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_log_path), ON_UPDATE(fix_general_log_file)); -static bool fix_slow_log_file(sys_var *, THD *thd [[maybe_unused]], +static bool fix_slow_log_file(sys_var *, THD *thd MY_ATTRIBUTE((unused)), enum_var_type) { bool res; @@ -5790,6 +6613,41 @@ static Sys_var_have Sys_have_compress( "have_compress", "have_compress", READ_ONLY NON_PERSIST GLOBAL_VAR(have_compress), NO_CMD_LINE); +#ifdef HAVE_ZSQL_EPLAN +static bool update_execution_plan_cache(sys_var *, THD *thd, enum_var_type) { + bool error = false; + + /* + Initialization of g_execution_plan_cache could be time-consuming, so release + LOCK_global_system_variables. + */ + mysql_mutex_unlock(&LOCK_global_system_variables); + if (g_persist_execution_plan) { + error = g_execution_plan_cache.init(thd); + } else { + g_execution_plan_cache.clean(); + } + mysql_mutex_lock(&LOCK_global_system_variables); + + return error; +} + +static Sys_var_bool Sys_persist_execution_plan( + "persist_execution_plan", + "Whether to enable persist execution plan (disabled by default).", + GLOBAL_VAR(g_persist_execution_plan), CMD_LINE(OPT_ARG), DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(update_execution_plan_cache)); +#endif // HAVE_ZSQL_EPLAN + +#ifdef HAVE_ZSQL_SLOW_LOG_PATTERNED_SQL +static Sys_var_bool Sys_pattern_query_log( + "pattern_query_log", + "Whether to pattern log (disabled by default).", + GLOBAL_VAR(g_enable_pattern_log), CMD_LINE(OPT_ARG), DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG); +#endif // HAVE_ZSQL_SLOW_LOG_PATTERNED_SQL + static Sys_var_have Sys_have_dlopen( "have_dynamic_loading", "have_dynamic_loading", READ_ONLY NON_PERSIST GLOBAL_VAR(have_dlopen), NO_CMD_LINE); @@ -5798,14 +6656,14 @@ static Sys_var_have Sys_have_geometry( "have_geometry", "have_geometry", READ_ONLY NON_PERSIST GLOBAL_VAR(have_geometry), NO_CMD_LINE); -static SHOW_COMP_OPTION have_ssl_func(THD *thd [[maybe_unused]]) { +static SHOW_COMP_OPTION have_ssl_func(THD *thd MY_ATTRIBUTE((unused))) { return have_ssl() ? SHOW_OPTION_YES : SHOW_OPTION_DISABLED; } enum SHOW_COMP_OPTION Sys_var_have_func::dummy_; static Sys_var_have_func Sys_have_openssl("have_openssl", "have_openssl", - have_ssl_func, DEPRECATED_VAR("")); + have_ssl_func); static Sys_var_have Sys_have_profiling( "have_profiling", "have_profiling", @@ -5825,9 +6683,7 @@ static Sys_var_have Sys_have_rtree_keys( "have_rtree_keys", "have_rtree_keys", READ_ONLY NON_PERSIST GLOBAL_VAR(have_rtree_keys), NO_CMD_LINE); -static Sys_var_have_func Sys_have_ssl( - "have_ssl", "have_ssl", have_ssl_func, - DEPRECATED_VAR("performance_schema.tls_channel_status table")); +static Sys_var_have_func Sys_have_ssl("have_ssl", "have_ssl", have_ssl_func); static Sys_var_have Sys_have_symlink( "have_symlink", "have_symlink", @@ -5849,6 +6705,12 @@ static bool fix_general_log_state(sys_var *, THD *thd, enum_var_type) { query_logger.deactivate_log_handler(QUERY_LOG_GENERAL); } else { res = query_logger.activate_log_handler(thd, QUERY_LOG_GENERAL); + +#ifdef HAVE_ZSQL_LOG_ROTATE_PURGE + if (!res) { + res = query_logger.log_rotate_init(QUERY_LOG_GENERAL); + } +#endif // HAVE_ZSQL_LOG_ROTATE_PURGE } mysql_mutex_lock(&LOCK_global_system_variables); @@ -5873,6 +6735,71 @@ static Sys_var_bool Sys_log_raw( GLOBAL_VAR(opt_general_log_raw), CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG); +#ifdef HAVE_ZSQL_SLOW_LOG_DETAILED_EXECUTED_TIME +static bool update_cached_log_slow_lock_monitor(sys_var *, THD *, + enum_var_type) { + // only when opt_slow_log and opt_log_slow_lock_monitor_cached are both on + set_lock_func_ptr(opt_slow_log && + (opt_log_slow_lock_monitor_cached & MONITOR_INNODB_MUTEX)); + + void *service = tallied_mutex_hook->get_interface( + (opt_slow_log && + (opt_log_slow_lock_monitor_cached & MONITOR_SERVER_MUTEX)) + ? TALLY_MUTEX_VERSION_1 + : TALLY_MUTEX_VERSION_2); + if (service != nullptr) { + set_tallied_mutex_service(service); + } + + opt_log_slow_lock_monitor_rwlock = + opt_slow_log && + (opt_log_slow_lock_monitor_cached & MONITOR_INNODB_RWLOCK); + + return false; +} + +// TODO: remove NONE when GoldenDB insight fix the configure pushdown system. +static const char *lock_monitor_types_names[] = { + "INNODB_MUTEX", "INNODB_RWLOCK", "SERVER_MUTEX", "NONE", nullptr}; + +static Sys_var_set Sys_log_slow_lock_monitor( + "log_slow_lock_monitor", + "Log statistics of mutex and rwlocks in innodb and several important mutex " + "in server to slow query log. Has no effect when slow_query_log is not " + "ON. Possible values are: INNODB_MUTEX, INNODB_RWLOCK, SERVER_MUTEX and " + "NONE. NONE value is ignored unless there are no other value set", + GLOBAL_VAR(opt_log_slow_lock_monitor_cached), CMD_LINE(REQUIRED_ARG), + lock_monitor_types_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(nullptr), ON_UPDATE(update_cached_log_slow_lock_monitor)); + +static Sys_var_double Sys_log_slow_lock_monitor_time_ratio( + "log_slow_lock_monitor_time_ratio", + "Ratio of time to print details in slow log." + "An item in Execute_time_details, Innodb_mutex, Innodb_rw_lock or " + "Server_mutex will be printed in slow log only when the ratio of its time " + "and long_query_time execeeds log_slow_lock_monitor_time_ratio.", + GLOBAL_VAR(opt_log_slow_lock_monitor_time_ratio), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 10000), DEFAULT(0.2), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(nullptr), ON_UPDATE(nullptr)); + +static bool update_cached_long_background_phase_time(sys_var *, THD *, + enum_var_type) { + opt_long_background_phase_time = + double2ulonglong(opt_long_background_phase_time_double * 1e6); + return false; +} + +static Sys_var_double Sys_long_background_phase_time( + "long_background_phase_time", + "Log a long time info to the system log when an innodb mutex in backgroup " + "thread waits more than long_background_phase_time seconds or some " + "processes like binlog rotate takes more than that. The argument will be " + "treated as a decimal value with microsecond precision", + GLOBAL_VAR(opt_long_background_phase_time_double), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(10), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(nullptr), ON_UPDATE(update_cached_long_background_phase_time)); +#endif /* HAVE_ZSQL_SLOW_LOG_DETAILED_EXECUTED_TIME */ + static bool fix_slow_log_state(sys_var *, THD *thd, enum_var_type) { bool new_state = opt_slow_log, res = false; @@ -5885,12 +6812,24 @@ static bool fix_slow_log_state(sys_var *, THD *thd, enum_var_type) { query_logger.deactivate_log_handler(QUERY_LOG_SLOW); } else { res = query_logger.activate_log_handler(thd, QUERY_LOG_SLOW); + +#ifdef HAVE_ZSQL_LOG_ROTATE_PURGE + if (!res) { + res = query_logger.log_rotate_init(QUERY_LOG_SLOW); + } +#endif // HAVE_ZSQL_LOG_ROTATE_PURGE } mysql_mutex_lock(&LOCK_global_system_variables); if (res) opt_slow_log = false; +#ifdef HAVE_ZSQL_SLOW_LOG_DETAILED_EXECUTED_TIME + // if the slow log is on, update the switch of log monitor locks + (void)update_cached_log_slow_lock_monitor( + nullptr, nullptr, enum_var_type::OPT_DEFAULT); +#endif /* HAVE_ZSQL_SLOW_LOG_DETAILED_EXECUTED_TIME */ + return res; } static Sys_var_bool Sys_slow_query_log( @@ -5928,6 +6867,228 @@ static bool fix_log_output(sys_var *, THD *, enum_var_type) { return false; } +#ifdef HAVE_ZSQL_TRX_QUERY_LOG +static bool update_cached_trx_query_log_time(sys_var *, THD *thd, + enum_var_type type) { + if (type == OPT_SESSION) + thd->variables.trx_query_log_time = + double2ulonglong(thd->variables.trx_query_log_time_double * 1e6); + else + global_system_variables.trx_query_log_time = double2ulonglong( + global_system_variables.trx_query_log_time_double * 1e6); + return false; +} + +static Sys_var_double Sys_trx_query_log_time( + "trx_query_log_time", + "Log all queries that have taken more than trx_query_log_time seconds " + "to execute to file. The argument will be treated as a decimal value " + "with microsecond precision", + SESSION_VAR(trx_query_log_time_double), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, LONG_TIMEOUT), DEFAULT(10), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(nullptr), ON_UPDATE(update_cached_trx_query_log_time)); + +static Sys_var_uint Sys_trx_query_log_level( + "trx_query_log_level", + "How detailed the log should be: " + "0, record transaction info and sql_text of all transactions; " + "1, record transaction info and sql_text of transcation when it has " + "trx_serial_num; " + "2, record transaction info of all transactions; " + "3, record transaction info of transaction when it has trx_serial_num. ", + GLOBAL_VAR(opt_trx_query_log_level), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 3), DEFAULT(1), BLOCK_SIZE(1), NO_MUTEX_GUARD, + NOT_IN_BINLOG); + +static bool fix_trx_query_log_state(sys_var *, THD *thd, enum_var_type) { + bool new_state = opt_trx_query_log; + bool res = false; + + if (query_logger.is_log_file_enabled(QUERY_LOG_TRX) == new_state) + return false; + + mysql_mutex_unlock(&LOCK_global_system_variables); + + if (!new_state) { + // when value change from 1 to 0,write the last record list to log file and + // destory the trx log memory pool. + g_trx_log_memory_pool.destory(); + query_logger.deactivate_log_handler(QUERY_LOG_TRX); + } else { + // when value change from 0 to 1,initialize the trx log memory pool. + g_trx_log_memory_pool.initialize(); + res = query_logger.activate_log_handler(thd, QUERY_LOG_TRX); + +#ifdef HAVE_ZSQL_LOG_ROTATE_PURGE + if (!res) { + res = query_logger.log_rotate_init(QUERY_LOG_TRX); + } +#endif // HAVE_ZSQL_LOG_ROTATE_PURGE + } + + mysql_mutex_lock(&LOCK_global_system_variables); + + if (res) opt_trx_query_log = false; + + return res; +} + +static Sys_var_bool Sys_trx_query_log( + "trx_query_log", + "Log trx info to a log file. " + "hostname-trx.log" + "Must be enabled to activate other trx_query log options", + GLOBAL_VAR(opt_trx_query_log), CMD_LINE(OPT_ARG), DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(fix_trx_query_log_state)); + +static Sys_var_bool Sys_trx_query_log_simple( + "trx_query_log_simple", "Print SQL statements only in trx_query_log. ", + GLOBAL_VAR(opt_trx_query_log_simple), CMD_LINE(OPT_ARG), + DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(nullptr)); + +static bool fix_trx_query_log_file(sys_var *, THD *thd MY_ATTRIBUTE((unused)), + enum_var_type) { + bool res; + + DEBUG_SYNC(thd, "log_fix_trx_query_log_holds_sysvar_lock"); + + if (!opt_trx_query_logname) // SET ... = DEFAULT + { + char buff[FN_REFLEN]; + opt_trx_query_logname = + my_strdup(key_memory_LOG_name, make_query_log_name(buff, QUERY_LOG_TRX), + MYF(MY_FAE + MY_WME)); + if (!opt_trx_query_logname) return true; + } + + res = query_logger.set_log_file(QUERY_LOG_TRX); + + DEBUG_SYNC(thd, "log_fix_trx_query_log_released_logger_lock"); + + if (opt_trx_query_log) { + mysql_mutex_unlock(&LOCK_global_system_variables); + + DEBUG_SYNC(thd, "log_fix_trx_query_log_released_sysvar_lock"); + + if (!res) + res = query_logger.reopen_log_file(QUERY_LOG_TRX); + else + query_logger.deactivate_log_handler(QUERY_LOG_TRX); + + mysql_mutex_lock(&LOCK_global_system_variables); + } + + if (res) opt_trx_query_log = false; + + return res; +} + +static Sys_var_charptr Sys_trx_query_log_path( + "trx_query_log_file", + "Log trx queries to given log file. " + "Defaults logging to hostname-trx.log. Must be enabled to activate " + "other trx_query log options", + GLOBAL_VAR(opt_trx_query_logname), CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, + DEFAULT(nullptr), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_log_path), + ON_UPDATE(fix_trx_query_log_file)); + +static Sys_var_ulong Sys_max_trxlog_size( + "max_trxlog_size", "Threshold size of trx log rotation", + GLOBAL_VAR(max_trxlog_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(IO_SIZE, ULONG_MAX), DEFAULT(100 * 1024L * 1024L), + BLOCK_SIZE(IO_SIZE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(nullptr)); + +static Sys_var_ulong Sys_trxlog_expire_logs_seconds( + "trxlog_expire_logs_seconds", "Time threshold for trx log expiration", + GLOBAL_VAR(trxlog_expire_logs_seconds), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 0xFFFFFFFF), DEFAULT(604800), BLOCK_SIZE(1), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(nullptr)); + +static Sys_var_bool Sys_xa_prepared_auto_clean_enable( + "xa_prepared_auto_clean", + "enalbe or not to auto clean the timeout Goldendb XA prepared transaction.", + READ_ONLY GLOBAL_VAR(g_xa_prepared_auto_clean_enable), + CMD_LINE(OPT_ARG), + DEFAULT(true)); + +static Sys_var_ulong Sys_xa_prepared_timeout_seconds( + "xa_prepared_timeout", "Goldendb timeout threshold for XA prepared state, 0 means no timeout", + GLOBAL_VAR(g_xa_prepared_timeout_seconds), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 86400), DEFAULT(1800), BLOCK_SIZE(1), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(nullptr)); + + +static bool check_trx_query_log_effective_period(sys_var *, THD *, + set_var *var) { + if (parse_trx_query_log_effective_period(var->save_result.string_value.str, + Enum_error_dest::ERROR_TO_CLIENT)) + return true; + + return false; +} + +static Sys_var_charptr Sys_trx_query_log_effective_period( + "trx_query_log_effective_period", + "Log trx effective period to active log file. " + "If the start time is the same as the end time, indicating the whole day. " + "Defaults 00:00:00~00:00:00", + GLOBAL_VAR(opt_trx_query_log_effective_period), CMD_LINE(REQUIRED_ARG), + IN_FS_CHARSET, DEFAULT("00:00:00~00:00:00"), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_trx_query_log_effective_period)); + +static bool check_and_modify_block_size_then_initialize(sys_var *, THD *, enum_var_type) { + if (opt_trx_query_log && opt_trx_log_cache_size != g_trx_log_memory_pool.get_block_size() ) { + mysql_mutex_unlock(&LOCK_global_system_variables); + g_trx_log_memory_pool.initialize(); + mysql_mutex_lock(&LOCK_global_system_variables); + } + + return false; +} + +static bool check_and_modify_pool_size_then_initialize(sys_var *, THD *, enum_var_type) { + if (opt_trx_query_log && opt_trx_log_cache_total_size != g_trx_log_memory_pool.get_pool_size() ) { + mysql_mutex_unlock(&LOCK_global_system_variables); + g_trx_log_memory_pool.initialize(); + mysql_mutex_lock(&LOCK_global_system_variables); + } + + return false; +} + +static Sys_var_uint Sys_trx_log_cache_size( + "trx_log_cache_size", + "Log trx cache size for THD. " + "Range 16*1024B ~ 10*1024*1024B", + GLOBAL_VAR(opt_trx_log_cache_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(16 * 1024, 10 * 1024 * 1024), DEFAULT(512 * 1024), + BLOCK_SIZE(16 * 1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(nullptr), + ON_UPDATE(check_and_modify_block_size_then_initialize)); + +static Sys_var_ulonglong Sys_trx_log_cache_total_size( + "trx_log_cache_total_size", + "Log trx total cache size for THD. " + "Range 16M ~ 100*1024M", + GLOBAL_VAR(opt_trx_log_cache_total_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(16ULL * 1024 * 1024, 100ULL * 1024 * 1024 * 1024), + DEFAULT(5ULL * 1024 * 1024 * 1024), BLOCK_SIZE(16 * 1024), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(check_and_modify_pool_size_then_initialize)); + +static Sys_var_int32 Sys_trx_log_reserved_block_num( + "trx_log_reserved_block_num", + "Log trx total cache size for THD. " + "Range 0 ~ 4096", + GLOBAL_VAR(opt_trx_log_reserved_block_num), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 4096), DEFAULT(1024), BLOCK_SIZE(1), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(nullptr)); +#endif // HAVE_ZSQL_TRX_QUERY_LOG + static const char *log_output_names[] = {"NONE", "FILE", "TABLE", nullptr}; static Sys_var_set Sys_log_output( @@ -5938,15 +7099,12 @@ static Sys_var_set Sys_log_output( DEFAULT(LOG_FILE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_not_empty_set), ON_UPDATE(fix_log_output)); -static Sys_var_bool Sys_log_replica_updates( - "log_replica_updates", - "If enabled, the replication applier threads will write to this server's " - "binary log.", - READ_ONLY GLOBAL_VAR(opt_log_replica_updates), - CMD_LINE(OPT_ARG, OPT_LOG_REPLICA_UPDATES), DEFAULT(1)); - -static Sys_var_deprecated_alias Sys_log_slave_updates("log_slave_updates", - Sys_log_replica_updates); +static Sys_var_bool Sys_log_slave_updates( + "log_slave_updates", + "Tells the slave to log the updates from " + "the slave thread to the binary log.", + READ_ONLY GLOBAL_VAR(opt_log_slave_updates), + CMD_LINE(OPT_ARG, OPT_LOG_SLAVE_UPDATES), DEFAULT(1)); static Sys_var_charptr Sys_relay_log( "relay_log", "The location and name to use for relay logs", @@ -6004,13 +7162,10 @@ static Sys_var_bool Sys_relay_log_purge( static Sys_var_bool Sys_relay_log_recovery( "relay_log_recovery", - "If enabled, existing relay logs will be skipped by the " - "replication threads. The receiver will start a new relay " - "log and the applier will start reading from the beginning of that file. " - "The receiver's position relative to the source will be reset to the " - "applier's " - "position relative to the source; the receiver uses this in case " - "SOURCE_AUTO_POSITION=0.", + "Enables automatic relay log recovery " + "right after the database startup, which means that the IO Thread " + "starts re-fetching from the master right after the last transaction " + "processed", READ_ONLY GLOBAL_VAR(relay_log_recovery), CMD_LINE(OPT_ARG), DEFAULT(false)); @@ -6024,28 +7179,19 @@ static Sys_var_ulong Sys_rpl_read_size( VALID_RANGE(IO_SIZE * 2, ULONG_MAX), DEFAULT(IO_SIZE * 2), BLOCK_SIZE(IO_SIZE)); -static Sys_var_bool Sys_replica_allow_batching( - "replica_allow_batching", - "Allow this replica to batch requests when " - "using the NDB storage engine.", - GLOBAL_VAR(opt_replica_allow_batching), CMD_LINE(OPT_ARG), DEFAULT(false)); - -static Sys_var_deprecated_alias Sys_slave_allow_batching( - "slave_allow_batching", Sys_replica_allow_batching); - -static Sys_var_charptr Sys_replica_load_tmpdir( - "replica_load_tmpdir", - "The location where this replica will store temporary files when " - "replicating a LOAD DATA INFILE command from a source having " - "binlog_format=STATEMENT.", - READ_ONLY NON_PERSIST GLOBAL_VAR(replica_load_tmpdir), - CMD_LINE(REQUIRED_ARG), IN_FS_CHARSET, DEFAULT(nullptr)); +static Sys_var_bool Sys_slave_allow_batching( + "slave_allow_batching", "Allow slave to batch requests", + GLOBAL_VAR(opt_slave_allow_batching), CMD_LINE(OPT_ARG), DEFAULT(false)); -static Sys_var_deprecated_alias Sys_slave_load_tmpdir("slave_load_tmpdir", - Sys_replica_load_tmpdir); +static Sys_var_charptr Sys_slave_load_tmpdir( + "slave_load_tmpdir", + "The location where the slave should put " + "its temporary files when replicating a LOAD DATA INFILE command", + READ_ONLY NON_PERSIST GLOBAL_VAR(slave_load_tmpdir), CMD_LINE(REQUIRED_ARG), + IN_FS_CHARSET, DEFAULT(nullptr)); -static bool fix_replica_net_timeout(sys_var *, THD *thd, enum_var_type) { - DEBUG_SYNC(thd, "fix_replica_net_timeout"); +static bool fix_slave_net_timeout(sys_var *, THD *thd, enum_var_type) { + DEBUG_SYNC(thd, "fix_slave_net_timeout"); Master_info *mi; /* @TODO: slave net timeout is for all channels, but does this make @@ -6063,7 +7209,7 @@ static bool fix_replica_net_timeout(sys_var *, THD *thd, enum_var_type) { for this global variable and releasing the lock here and acquiring locks back again at the end of this function. */ - mysql_mutex_unlock(&LOCK_replica_net_timeout); + mysql_mutex_unlock(&LOCK_slave_net_timeout); mysql_mutex_unlock(&LOCK_global_system_variables); channel_map.wrlock(); @@ -6071,10 +7217,9 @@ static bool fix_replica_net_timeout(sys_var *, THD *thd, enum_var_type) { it++) { mi = it->second; - DBUG_PRINT("info", - ("replica_net_timeout=%u mi->heartbeat_period=%.3f", - replica_net_timeout, (mi ? mi->heartbeat_period : 0.0))); - if (mi != nullptr && replica_net_timeout < mi->heartbeat_period) + DBUG_PRINT("info", ("slave_net_timeout=%u mi->heartbeat_period=%.3f", + slave_net_timeout, (mi ? mi->heartbeat_period : 0.0))); + if (mi != nullptr && slave_net_timeout < mi->heartbeat_period) push_warning(thd, Sql_condition::SL_WARNING, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX, ER_THD(thd, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX)); @@ -6082,21 +7227,18 @@ static bool fix_replica_net_timeout(sys_var *, THD *thd, enum_var_type) { channel_map.unlock(); mysql_mutex_lock(&LOCK_global_system_variables); - mysql_mutex_lock(&LOCK_replica_net_timeout); + mysql_mutex_lock(&LOCK_slave_net_timeout); return false; } -static PolyLock_mutex PLock_replica_net_timeout(&LOCK_replica_net_timeout); -static Sys_var_uint Sys_replica_net_timeout( - "replica_net_timeout", +static PolyLock_mutex PLock_slave_net_timeout(&LOCK_slave_net_timeout); +static Sys_var_uint Sys_slave_net_timeout( + "slave_net_timeout", "Number of seconds to wait for more data " - "from a replication connection before aborting the read.", - GLOBAL_VAR(replica_net_timeout), CMD_LINE(REQUIRED_ARG), - VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(REPLICA_NET_TIMEOUT), BLOCK_SIZE(1), - &PLock_replica_net_timeout, NOT_IN_BINLOG, ON_CHECK(nullptr), - ON_UPDATE(fix_replica_net_timeout)); - -static Sys_var_deprecated_alias Sys_slave_net_timeout("slave_net_timeout", - Sys_replica_net_timeout); + "from a master/slave connection before aborting the read", + GLOBAL_VAR(slave_net_timeout), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(1, LONG_TIMEOUT), DEFAULT(SLAVE_NET_TIMEOUT), BLOCK_SIZE(1), + &PLock_slave_net_timeout, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(fix_slave_net_timeout)); static bool check_slave_skip_counter(sys_var *, THD *thd, set_var *var) { /* @@ -6107,35 +7249,28 @@ static bool check_slave_skip_counter(sys_var *, THD *thd, set_var *var) { */ if (global_gtid_mode.get() == Gtid_mode::ON && var->save_result.ulonglong_value > 0) - push_warning( - thd, Sql_condition::SL_WARNING, - ER_SQL_REPLICA_SKIP_COUNTER_USED_WITH_GTID_MODE_ON, - ER_THD(thd, ER_SQL_REPLICA_SKIP_COUNTER_USED_WITH_GTID_MODE_ON)); + push_warning(thd, Sql_condition::SL_WARNING, + ER_SQL_SLAVE_SKIP_COUNTER_USED_WITH_GTID_MODE_ON, + ER_THD(thd, ER_SQL_SLAVE_SKIP_COUNTER_USED_WITH_GTID_MODE_ON)); return false; } -static PolyLock_mutex PLock_sql_replica_skip_counter( - &LOCK_sql_replica_skip_counter); -static Sys_var_uint Sys_sql_replica_skip_counter( - "sql_replica_skip_counter", "sql_replica_skip_counter", - GLOBAL_VAR(sql_replica_skip_counter), NO_CMD_LINE, VALID_RANGE(0, UINT_MAX), - DEFAULT(0), BLOCK_SIZE(1), &PLock_sql_replica_skip_counter, NOT_IN_BINLOG, +static PolyLock_mutex PLock_sql_slave_skip_counter( + &LOCK_sql_slave_skip_counter); +static Sys_var_uint Sys_slave_skip_counter( + "sql_slave_skip_counter", "sql_slave_skip_counter", + GLOBAL_VAR(sql_slave_skip_counter), NO_CMD_LINE, VALID_RANGE(0, UINT_MAX), + DEFAULT(0), BLOCK_SIZE(1), &PLock_sql_slave_skip_counter, NOT_IN_BINLOG, ON_CHECK(check_slave_skip_counter)); -static Sys_var_deprecated_alias Sys_sql_slave_skip_counter( - "sql_slave_skip_counter", Sys_sql_replica_skip_counter); - -static Sys_var_charptr Sys_replica_skip_errors( - "replica_skip_errors", - "Comma-separated list of error numbers. If an applier thread on this " - "replica encounters one of these errors while applying a Query_log_event, " - "it will ignore the error, rather than stop.", - READ_ONLY GLOBAL_VAR(opt_replica_skip_errors), CMD_LINE(REQUIRED_ARG), +static Sys_var_charptr Sys_slave_skip_errors( + "slave_skip_errors", + "Tells the slave thread to continue " + "replication when a query event returns an error from the " + "provided list", + READ_ONLY GLOBAL_VAR(opt_slave_skip_errors), CMD_LINE(REQUIRED_ARG), IN_SYSTEM_CHARSET, DEFAULT(nullptr)); -static Sys_var_deprecated_alias Sys_slave_skip_errors("slave_skip_errors", - Sys_replica_skip_errors); - static Sys_var_ulonglong Sys_relay_log_space_limit( "relay_log_space_limit", "Maximum space to use for all relay logs", READ_ONLY GLOBAL_VAR(relay_log_space_limit), CMD_LINE(REQUIRED_ARG), @@ -6156,36 +7291,29 @@ static Sys_var_uint Sys_sync_relayloginfo_period( GLOBAL_VAR(sync_relayloginfo_period), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, UINT_MAX), DEFAULT(10000), BLOCK_SIZE(1)); -static Sys_var_uint Sys_replica_checkpoint_period( - "replica_checkpoint_period", - "When using a multi-threaded applier (replica_parallel_workers>0), it " - "will update the worker progress status periodically. This option " - "specifies the maximum number of milliseconds between updates.", - GLOBAL_VAR(opt_mta_checkpoint_period), CMD_LINE(REQUIRED_ARG), +static Sys_var_uint Sys_checkpoint_mts_period( + "slave_checkpoint_period", + "Gather workers' activities to " + "Update progress status of Multi-threaded slave and flush " + "the relay log info to disk after every #th milli-seconds.", + GLOBAL_VAR(opt_mts_checkpoint_period), CMD_LINE(REQUIRED_ARG), #ifndef NDEBUG VALID_RANGE(0, UINT_MAX), DEFAULT(300), BLOCK_SIZE(1)); #else VALID_RANGE(1, UINT_MAX), DEFAULT(300), BLOCK_SIZE(1)); #endif /* NDEBUG */ -static Sys_var_deprecated_alias Sys_slave_checkpoint_period( - "slave_checkpoint_period", Sys_replica_checkpoint_period); - -static Sys_var_uint Sys_replica_checkpoint_group( - "replica_checkpoint_group", - "When using multi-threaded applier (replica_parallel_workers>0), it will " - "update the worker progress status periodically. This option specifies " - "the maximum number of committed transactions between updates.", - GLOBAL_VAR(opt_mta_checkpoint_group), CMD_LINE(REQUIRED_ARG), +static Sys_var_uint Sys_checkpoint_mts_group( + "slave_checkpoint_group", + "Maximum number of processed transactions by Multi-threaded slave " + "before a checkpoint operation is called to update progress status.", + GLOBAL_VAR(opt_mts_checkpoint_group), CMD_LINE(REQUIRED_ARG), #ifndef NDEBUG VALID_RANGE(1, MTS_MAX_BITS_IN_GROUP), DEFAULT(512), BLOCK_SIZE(1)); #else VALID_RANGE(32, MTS_MAX_BITS_IN_GROUP), DEFAULT(512), BLOCK_SIZE(8)); #endif /* NDEBUG */ -static Sys_var_deprecated_alias Sys_slave_checkpoint_group( - "slave_checkpoint_group", Sys_replica_checkpoint_group); - static Sys_var_uint Sys_sync_binlog_period( "sync_binlog", "Synchronously flush binary log to disk after" @@ -6194,59 +7322,46 @@ static Sys_var_uint Sys_sync_binlog_period( GLOBAL_VAR(sync_binlog_period), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, UINT_MAX), DEFAULT(1), BLOCK_SIZE(1)); -static Sys_var_uint Sys_sync_source_info( - "sync_source_info", - "Synchronize replication receiver positions to disk periodically, after " - "the specified number of events. Use 0 to disable periodic " - "synchronization.", +static Sys_var_uint Sys_sync_masterinfo_period( + "sync_master_info", + "Synchronously flush master info to disk " + "after every #th event. Use 0 to disable synchronous flushing", GLOBAL_VAR(sync_masterinfo_period), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, UINT_MAX), DEFAULT(10000), BLOCK_SIZE(1)); -static Sys_var_deprecated_alias Sys_sync_master_info("sync_master_info", - Sys_sync_source_info); - static Sys_var_ulonglong Sys_var_original_commit_timestamp( "original_commit_timestamp", "The time when the current transaction was committed on the originating " - "source, measured in microseconds since 1970 (the \"epoch\").", + "replication master, measured in microseconds since the epoch.", SESSION_ONLY(original_commit_timestamp), NO_CMD_LINE, VALID_RANGE(0, MAX_COMMIT_TIMESTAMP_VALUE), DEFAULT(MAX_COMMIT_TIMESTAMP_VALUE), BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_session_admin_or_replication_applier)); -static Sys_var_ulong Sys_replica_transaction_retries( - "replica_transaction_retries", - "Number of times the replication applier will retry a transaction in " - "case it failed with a deadlock or other transient error, before it gives " - "up and stops.", +static Sys_var_ulong Sys_slave_trans_retries( + "slave_transaction_retries", + "Number of times the slave SQL " + "thread will retry a transaction in case it failed with a deadlock " + "or elapsed lock wait timeout, before giving up and stopping", GLOBAL_VAR(slave_trans_retries), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, ULONG_MAX), DEFAULT(10), BLOCK_SIZE(1)); -static Sys_var_deprecated_alias Sys_slave_transaction_retries( - "slave_transaction_retries", Sys_replica_transaction_retries); - -static Sys_var_ulong Sys_replica_parallel_workers( - "replica_parallel_workers", +static Sys_var_ulong Sys_slave_parallel_workers( + "slave_parallel_workers", "Number of worker threads for executing events in parallel ", - PERSIST_AS_READONLY GLOBAL_VAR(opt_mts_replica_parallel_workers), - CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, MTS_MAX_WORKERS), DEFAULT(4), + PERSIST_AS_READONLY GLOBAL_VAR(opt_mts_slave_parallel_workers), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, MTS_MAX_WORKERS), DEFAULT(0), BLOCK_SIZE(1)); -static Sys_var_deprecated_alias Sys_slave_parallel_workers( - "slave_parallel_workers", Sys_replica_parallel_workers); - -static Sys_var_ulonglong Sys_replica_pending_jobs_size_max( - "replica_pending_jobs_size_max", - "Soft limit on the size, in bytes, of per-worker queues of events that " - "have not yet been applied. The queue size may exceed this limit in case " - "a single event is bigger than the limit.", +static Sys_var_ulonglong Sys_mts_pending_jobs_size_max( + "slave_pending_jobs_size_max", + "Max size of Slave Worker queues holding not yet applied events. " + "The least possible value must be not less than the master side " + "max_allowed_packet.", GLOBAL_VAR(opt_mts_pending_jobs_size_max), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1024, (ulonglong) ~(intptr)0), DEFAULT(128 * 1024 * 1024), BLOCK_SIZE(1024), ON_CHECK(nullptr)); -static Sys_var_deprecated_alias Sys_slave_pending_jobs_size_max( - "slave_pending_jobs_size_max", Sys_replica_pending_jobs_size_max); - static bool check_locale(sys_var *self, THD *thd, set_var *var) { if (!var->value) return false; @@ -6374,10 +7489,10 @@ static Sys_var_ulong Sys_sp_cache_size( GLOBAL_VAR(stored_program_cache_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(16, 512 * 1024), DEFAULT(256), BLOCK_SIZE(1)); -static bool check_pseudo_replica_mode(sys_var *self, THD *thd, set_var *var) { +static bool check_pseudo_slave_mode(sys_var *self, THD *thd, set_var *var) { if (check_session_admin_or_replication_applier(self, thd, var)) return true; if (check_outside_trx(self, thd, var)) return true; - longlong previous_val = thd->variables.pseudo_replica_mode; + longlong previous_val = thd->variables.pseudo_slave_mode; longlong val = (longlong)var->save_result.ulonglong_value; bool rli_fake = false; @@ -6392,7 +7507,7 @@ static bool check_pseudo_replica_mode(sys_var *self, THD *thd, set_var *var) { goto ineffective; else if (!previous_val && val) push_warning(thd, Sql_condition::SL_WARNING, ER_WRONG_VALUE_FOR_VAR, - "'pseudo_replica_mode' is already ON."); + "'pseudo_slave_mode' is already ON."); } else { if (!previous_val && !val) goto ineffective; @@ -6405,21 +7520,20 @@ static bool check_pseudo_replica_mode(sys_var *self, THD *thd, set_var *var) { ineffective: push_warning(thd, Sql_condition::SL_WARNING, ER_WRONG_VALUE_FOR_VAR, - "'pseudo_replica_mode' change was ineffective."); + "'pseudo_slave_mode' change was ineffective."); end: return false; } -static Sys_var_bool Sys_pseudo_replica_mode( - "pseudo_replica_mode", - "Internal variable that will be enabled while applying a " - "Format_description_log_event encoded in a BINLOG statement printed " - "by mysqlbinlog.", - SESSION_ONLY(pseudo_replica_mode), NO_CMD_LINE, DEFAULT(false), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_pseudo_replica_mode)); - -static Sys_var_deprecated_alias Sys_pseudo_slave_mode("pseudo_slave_mode", - Sys_pseudo_replica_mode); +static Sys_var_bool Sys_pseudo_slave_mode( + "pseudo_slave_mode", + "SET pseudo_slave_mode= 0,1 are commands that mysqlbinlog " + "adds to beginning and end of binary log dumps. While zero " + "value indeed disables, the actual enabling of the slave " + "applier execution mode is done implicitly when a " + "Format_description_event is sent through the session.", + SESSION_ONLY(pseudo_slave_mode), NO_CMD_LINE, DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_pseudo_slave_mode)); #ifdef HAVE_GTID_NEXT_LIST static bool check_gtid_next_list(sys_var *self, THD *thd, set_var *var) { @@ -6516,6 +7630,10 @@ bool Sys_var_gtid_purged::global_update(THD *thd, set_var *var) { char *previous_gtid_executed = nullptr, *previous_gtid_purged = nullptr, *current_gtid_executed = nullptr, *current_gtid_purged = nullptr; gtid_state->get_executed_gtids()->to_string(&previous_gtid_executed); +#ifdef HAVE_ZSQL_RELAY_LOG_REPLICA_ROLE + /* This is equivalent to a part functions of 'reset master'. */ + if (g_is_relay_log_replica) gtid_state->clear(thd); +#endif // HAVE_ZSQL_RELAY_LOG_REPLICA_ROLE gtid_state->get_lost_gtids()->to_string(&previous_gtid_purged); Gtid_set gtid_set(global_sid_map, global_sid_lock); bool starts_with_plus = false; @@ -6541,8 +7659,13 @@ bool Sys_var_gtid_purged::global_update(THD *thd, set_var *var) { // Log messages saying that GTID_PURGED and GTID_EXECUTED were changed. LogErr(SYSTEM_LEVEL, ER_GTID_PURGED_WAS_UPDATED, previous_gtid_purged, current_gtid_purged); - LogErr(SYSTEM_LEVEL, ER_GTID_EXECUTED_WAS_UPDATED, previous_gtid_executed, - current_gtid_executed); +#ifdef HAVE_ZSQL_RELAY_LOG_REPLICA_ROLE + if (!g_is_relay_log_replica) +#endif // HAVE_ZSQL_RELAY_LOG_REPLICA_ROLE + { + LogErr(SYSTEM_LEVEL, ER_GTID_EXECUTED_WAS_UPDATED, previous_gtid_executed, + current_gtid_executed); + } end: global_sid_lock->unlock(); @@ -6581,8 +7704,8 @@ static Sys_var_gtid_mode Sys_gtid_mode( "GTID. ON_PERMISSIVE means that new transactions are assigned a " "GTID, and replicated transactions are allowed to have or not " "have a GTID. ON means that all transactions have a GTID. " - "ON is required on a source before any replica can use " - "SOURCE_AUTO_POSITION=1. To safely switch from OFF to ON, first " + "ON is required on a master before any slave can use " + "MASTER_AUTO_POSITION=1. To safely switch from OFF to ON, first " "set all servers to OFF_PERMISSIVE, then set all servers to " "ON_PERMISSIVE, then wait for all transactions without a GTID to " "be replicated and executed on all servers, and finally set all " @@ -6743,9 +7866,8 @@ static Sys_var_bool Sys_show_old_temporals( "table as a comment in COLUMN_TYPE field. " "This variable is deprecated and will be removed in a future release.", SESSION_VAR(show_old_temporals), CMD_LINE(OPT_ARG, OPT_SHOW_OLD_TEMPORALS), - DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, - ON_CHECK(check_session_admin_no_super), ON_UPDATE(nullptr), - DEPRECATED_VAR("")); + DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(nullptr), DEPRECATED_VAR("")); static Sys_var_charptr Sys_disabled_storage_engines( "disabled_storage_engines", @@ -6996,8 +8118,9 @@ static Sys_var_bool Sys_show_create_table_verbosity( "show_create_table_verbosity", "When this option is enabled, it increases the verbosity of " "'SHOW CREATE TABLE'.", - SESSION_VAR(show_create_table_verbosity), CMD_LINE(OPT_ARG), DEFAULT(false), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr)); + SESSION_VAR(show_create_table_verbosity), CMD_LINE(OPT_ARG), + DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(nullptr)); static const char *use_secondary_engine_values[] = {"OFF", "ON", "FORCED", nullptr}; @@ -7169,9 +8292,8 @@ static Sys_var_uint Sys_immediate_server_version( BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(check_session_admin_or_replication_applier)); -static bool check_set_default_table_encryption_access(sys_var *self - [[maybe_unused]], - THD *thd, set_var *var) { +static bool check_set_default_table_encryption_access( + sys_var *self MY_ATTRIBUTE((unused)), THD *thd, set_var *var) { DBUG_EXECUTE_IF("skip_table_encryption_admin_check_for_set", { return false; }); if ((var->type == OPT_GLOBAL || var->type == OPT_PERSIST) && @@ -7283,27 +8405,656 @@ static Sys_var_charptr Sys_protocol_compression_algorithms( NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_set_protocol_compression_algorithms), ON_UPDATE(nullptr)); -static bool check_set_require_row_format(sys_var *, THD *thd, set_var *var) { - /* - Should own SUPER or SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN - when the value is changing to NO, no privileges are needed to set to YES - */ - longlong previous_val = thd->variables.require_row_format; - longlong val = (longlong)var->save_result.ulonglong_value; - assert(!var->is_global_persist()); - - // if it was true and we are changing it - if (previous_val && val != previous_val) { - if (thd->security_context()->check_access(SUPER_ACL) || - thd->security_context() - ->has_global_grant(STRING_WITH_LEN("SYSTEM_VARIABLES_ADMIN")) - .first || - thd->security_context() - ->has_global_grant(STRING_WITH_LEN("SESSION_VARIABLES_ADMIN")) - .first) - return false; +#ifdef HAVE_ZSQL_QUICK_SYNC +/****** add for semisync inline optimize ******/ - my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), +static bool fix_rpl_semi_sync_master_enabled(sys_var *, + THD *, enum_var_type) +{ + if (rpl_semi_sync_master_enabled) + { + if (repl_semisync_master->enableMaster() != 0) + rpl_semi_sync_master_enabled = false; + else if (ack_receiver->start()) + { + repl_semisync_master->disableMaster(); + rpl_semi_sync_master_enabled = false; + } + + if(rpl_semi_sync_master_enabled && + rpl_semi_sync_master_quick_sync_enabled) + { + if(time_inspection->start()) + { + repl_semisync_master->disableMaster(); + rpl_semi_sync_master_enabled = false; + ack_receiver->stop(); + } + } + } + else + { + if (repl_semisync_master->disableMaster() != 0) + rpl_semi_sync_master_enabled = true; + ack_receiver->stop(); + time_inspection->stop(); + } + + set_is_quick_sync_enabled(); + return false; +} +static Sys_var_bool Sys_rpl_semi_sync_master_enabled( + "rpl_semi_sync_master_enabled", + "Enable semi-synchronous replication master (disabled by default). ", + GLOBAL_VAR(rpl_semi_sync_master_enabled), + CMD_LINE(OPT_ARG), + DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(0), ON_UPDATE(fix_rpl_semi_sync_master_enabled)); + +static bool fix_rpl_semi_sync_master_timeout(sys_var *, + THD *, enum_var_type) +{ + repl_semisync_master->setWaitTimeout(rpl_semi_sync_master_timeout); + return false; +} +static Sys_var_ulong Sys_rpl_semi_sync_master_timeout( + "rpl_semi_sync_master_timeout", + "The timeout value (in ms) for semi-synchronous replication in the master", + GLOBAL_VAR(rpl_semi_sync_master_timeout), + CMD_LINE(OPT_ARG),VALID_RANGE(0, ~0L), + DEFAULT(10000), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(0), ON_UPDATE(fix_rpl_semi_sync_master_timeout)); + + +static bool check_rpl_semi_sync_master_wait_no_slave(sys_var *, + THD *, set_var *var) +{ + if (!var->value) + return false; // DEFAULT is ok + + repl_semisync_master->set_wait_no_slave((char)var->save_result.ulonglong_value); + return false; +} +static Sys_var_bool Sys_rpl_semi_sync_master_wait_no_slave( + "rpl_semi_sync_master_wait_no_slave", + "Wait until timeout when no semi-synchronous replication slave available (enabled by default). ", + GLOBAL_VAR(rpl_semi_sync_master_wait_no_slave), + CMD_LINE(OPT_ARG), + DEFAULT(true), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_wait_no_slave), + ON_UPDATE(0)); + +#ifdef HAVE_ZSQL_SERVICE_AVAILABLE_EVEN_BELLOW_LWM +static Sys_var_bool Sys_service_available_even_bellow_lwm( + "service_available_even_bellow_lwm", + "Whether to allow writing when groups is less than the lwm cond (disabled by default). ", + GLOBAL_VAR(service_available_even_bellow_lwm), + CMD_LINE(OPT_ARG), + DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(0), ON_UPDATE(0)); +#endif /* HAVE_ZSQL_SERVICE_AVAILABLE_EVEN_BELLOW_LWM */ + + +static bool fix_rpl_semi_sync_master_trace_level(sys_var *, + THD *, enum_var_type) +{ + repl_semisync_master->setTraceLevel(rpl_semi_sync_master_trace_level); + ack_receiver->setTraceLevel(rpl_semi_sync_master_trace_level); + return false; +} +static Sys_var_ulong Sys_rpl_semi_sync_master_trace_level( + "rpl_semi_sync_master_trace_level", + "The tracing level for semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_master_trace_level), + CMD_LINE(OPT_ARG),VALID_RANGE(0, ~0L), + DEFAULT(32), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(0), ON_UPDATE(fix_rpl_semi_sync_master_trace_level)); + + +static const char *wait_point_names[]= {"AFTER_SYNC", "AFTER_COMMIT", NullS}; +static bool fix_rpl_semi_sync_master_wait_point(sys_var *, + THD *, enum_var_type) +{ + set_is_quick_sync_enabled(); + return false; +} +static Sys_var_enum Sys_rpl_semi_sync_master_wait_point( + "rpl_semi_sync_master_wait_point", + "Semisync can wait for slave ACKs at one of two points,", + GLOBAL_VAR(rpl_semi_sync_master_wait_point), + CMD_LINE(OPT_ARG), wait_point_names, + DEFAULT(WAIT_AFTER_SYNC), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0), + ON_UPDATE(fix_rpl_semi_sync_master_wait_point)); + +static bool check_rpl_semi_sync_master_wait_for_slave_count(sys_var *, + THD *, set_var *var) +{ + if (!var->value) + return false; // DEFAULT is ok + + repl_semisync_master->setWaitSlaveCount(var->save_result.ulonglong_value); + return false; +} +static bool fix_rpl_semi_sync_master_wait_for_slave_count(sys_var *, + THD *, enum_var_type) +{ + rpl_semi_sync_master_wait_for_slave_count = repl_semisync_master->get_wait_slave_count_inline(); + return false; +} +static Sys_var_uint Sys_rpl_semi_sync_master_wait_for_slave_count( + "rpl_semi_sync_master_wait_for_slave_count", + "How many slaves the events should be replicated to. Semisynchronous " + "replication master will wait until all events of the transaction are " + "replicated to at least rpl_semi_sync_master_wait_for_slave_count slaves", + GLOBAL_VAR(rpl_semi_sync_master_wait_for_slave_count), + CMD_LINE(OPT_ARG),VALID_RANGE(1, 65535), + DEFAULT(1), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_wait_for_slave_count), + ON_UPDATE(fix_rpl_semi_sync_master_wait_for_slave_count)); + + +static bool check_rpl_semi_sync_master_quick_sync_enabled(sys_var *, + THD *, set_var *var) +{ + if (!var->value) + return false; // DEFAULT is ok + + if(repl_semisync_master->set_quick_sync_enabled( + var->save_result.ulonglong_value)) + return true; + + set_is_quick_sync_enabled(); + return false; +} +static Sys_var_bool Sys_rpl_semi_sync_master_quick_sync_enabled( + "rpl_semi_sync_master_quick_sync_enabled", + "Enable the quick-sync mode(enabled by default, disabled means semi-sync mode). ", + GLOBAL_VAR(rpl_semi_sync_master_quick_sync_enabled), + CMD_LINE(OPT_ARG), + DEFAULT(true), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_quick_sync_enabled), + ON_UPDATE(0)); + + +static bool fix_rpl_semi_sync_master_inspection_time(sys_var *, + THD *, enum_var_type) +{ + time_inspection->set_inspection_time(rpl_semi_sync_master_inspection_time); + return false; +} +static Sys_var_ulong Sys_rpl_semi_sync_master_inspection_timeout( + "rpl_semi_sync_master_inspection_time", + "The timeout inspection time (in ms) for semi-sync replication in the master", + GLOBAL_VAR(rpl_semi_sync_master_inspection_time), + CMD_LINE(OPT_ARG),VALID_RANGE(1, ~0L), + DEFAULT(1000), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(0), ON_UPDATE(fix_rpl_semi_sync_master_inspection_time)); + + +static bool check_rpl_semi_sync_master_wait_cond_hwm(sys_var *, + THD *, set_var *var) +{ + if (!var->value) + return false; // DEFAULT is ok + + if(false == repl_semisync_master->set_wait_cond_hwm( + (char*)var->save_result.string_value.str)) + return true; + + return false; +} +static Sys_var_charptr Sys_rpl_semi_sync_master_wait_cond_hwm( + "rpl_semi_sync_master_wait_cond_hwm", + "How many slave_groups the events should be replicated to. Semisynchronous " + "replication master will wait until all events of the transaction are " + "replicated to at least rpl_semi_sync_master_wait_cond_hwm slaves", + GLOBAL_VAR(rpl_semi_sync_master_wait_cond_hwm), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_wait_cond_hwm), + ON_UPDATE(0)); + + +static bool check_rpl_semi_sync_master_wait_cond_lwm(sys_var *, + THD *, set_var *var) +{ + if (!var->value) + return false; // DEFAULT is ok + + if(false == repl_semisync_master->set_wait_cond_lwm( + (char*)var->save_result.string_value.str)) + return true; + + return false; +} +static Sys_var_charptr Sys_rpl_semi_sync_master_wait_cond_lwm( + "rpl_semi_sync_master_wait_cond_lwm", + "How many slave_groups the events should be replicated to. Semisynchronous " + "replication master will wait until all events of the transaction are " + "replicated to at least rpl_semi_sync_master_wait_cond_lwm slaves", + GLOBAL_VAR(rpl_semi_sync_master_wait_cond_lwm), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_wait_cond_lwm), + ON_UPDATE(0)); + + +static bool check_rpl_semi_sync_master_group_all(sys_var *, THD *, + set_var *var, unsigned int group_id) +{ + if (!var->value) + return false; // DEFAULT is ok + + if(false == repl_semisync_master->set_ack_group_info( + (char*)var->save_result.string_value.str, group_id)) + return true; + return false; +} +static bool check_rpl_semi_sync_master_group1(sys_var *self, + THD *thd, set_var *var) +{ + return check_rpl_semi_sync_master_group_all(self, thd, var, 1); +} +static bool check_rpl_semi_sync_master_group2(sys_var *self, + THD *thd, set_var *var) +{ + return check_rpl_semi_sync_master_group_all(self, thd, var, 2); +} +static bool check_rpl_semi_sync_master_group3(sys_var *self, + THD *thd, set_var *var) +{ + return check_rpl_semi_sync_master_group_all(self, thd, var, 3); +} +static bool check_rpl_semi_sync_master_group4(sys_var *self, + THD *thd, set_var *var) +{ + return check_rpl_semi_sync_master_group_all(self, thd, var, 4); +} +static bool check_rpl_semi_sync_master_group5(sys_var *self, + THD *thd, set_var *var) +{ + return check_rpl_semi_sync_master_group_all(self, thd, var, 5); +} +static bool check_rpl_semi_sync_master_group6(sys_var *self, + THD *thd, set_var *var) +{ + return check_rpl_semi_sync_master_group_all(self, thd, var, 6); +} +static bool check_rpl_semi_sync_master_group7(sys_var *self, + THD *thd, set_var *var) +{ + return check_rpl_semi_sync_master_group_all(self, thd, var, 7); +} +static bool check_rpl_semi_sync_master_group8(sys_var *self, + THD *thd, set_var *var) +{ + return check_rpl_semi_sync_master_group_all(self, thd, var, 8); +} +static bool check_rpl_semi_sync_master_group9(sys_var *self, + THD *thd, set_var *var) +{ + return check_rpl_semi_sync_master_group_all(self, thd, var, 9); +} +static bool check_rpl_semi_sync_master_group10(sys_var *self, + THD *thd, set_var *var) +{ + return check_rpl_semi_sync_master_group_all(self, thd, var, 10); +} + +static Sys_var_charptr Sys_rpl_semi_sync_master_group1( + "rpl_semi_sync_master_group1", + "The group_1 info for quick semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_master_group[0]), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_group1), ON_UPDATE(0)); + +static Sys_var_charptr Sys_rpl_semi_sync_master_group2( + "rpl_semi_sync_master_group2", + "The group_2 info for quick semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_master_group[1]), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_group2), ON_UPDATE(0)); + +static Sys_var_charptr Sys_rpl_semi_sync_master_group3( + "rpl_semi_sync_master_group3", + "The group_3 info for quick semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_master_group[2]), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_group3), ON_UPDATE(0)); + +static Sys_var_charptr Sys_rpl_semi_sync_master_group4( + "rpl_semi_sync_master_group4", + "The group_4 info for quick semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_master_group[3]), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_group4), ON_UPDATE(0)); + +static Sys_var_charptr Sys_rpl_semi_sync_master_group5( + "rpl_semi_sync_master_group5", + "The group_5 info for quick semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_master_group[4]), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_group5), ON_UPDATE(0)); + +static Sys_var_charptr Sys_rpl_semi_sync_master_group6( + "rpl_semi_sync_master_group6", + "The group_6 info for quick semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_master_group[5]), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_group6), ON_UPDATE(0)); + +static Sys_var_charptr Sys_rpl_semi_sync_master_group7( + "rpl_semi_sync_master_group7", + "The group_7 info for quick semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_master_group[6]), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_group7), ON_UPDATE(0)); + +static Sys_var_charptr Sys_rpl_semi_sync_master_group8( + "rpl_semi_sync_master_group8", + "The group_8 info for quick semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_master_group[7]), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_group8), ON_UPDATE(0)); + +static Sys_var_charptr Sys_rpl_semi_sync_master_group9( + "rpl_semi_sync_master_group9", + "The group_9 info for quick semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_master_group[8]), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_group9), ON_UPDATE(0)); + +static Sys_var_charptr Sys_rpl_semi_sync_master_group10( + "rpl_semi_sync_master_group10", + "The group_10 info for quick semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_master_group[9]), + CMD_LINE(OPT_ARG), + IN_FS_CHARSET, DEFAULT(NULL), + NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_rpl_semi_sync_master_group10), ON_UPDATE(0)); + + +static bool fix_rpl_semi_sync_slave_enabled(sys_var *, + THD *, enum_var_type) +{ +#ifdef HAVE_ZSQL_SLAVE_CDC + if (g_is_relay_log_cdc_role) { + rpl_semi_sync_slave_enabled = false; + LogErr(WARNING_LEVEL, ER_RELAY_LOG_CDC_FIX_VARIABLE, + "rpl_semi_sync_slave_enabled", "OFF"); + } +#endif /* HAVE_ZSQL_SLAVE_CDC */ + repl_semisync_slave->setSlaveEnabled(rpl_semi_sync_slave_enabled != 0); + return false; +} +static Sys_var_bool Sys_rpl_semi_sync_slave_enabled( + "rpl_semi_sync_slave_enabled", + "Enable semi-synchronous replication slave (disabled by default). ", + GLOBAL_VAR(rpl_semi_sync_slave_enabled), + CMD_LINE(OPT_ARG), + DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(0), ON_UPDATE(fix_rpl_semi_sync_slave_enabled)); + + +static bool fix_rpl_semi_sync_trace_level(sys_var *, + THD *, enum_var_type) +{ + repl_semisync_slave->setTraceLevel(rpl_semi_sync_slave_trace_level); + return false; +} +static Sys_var_ulong Sys_rpl_semi_sync_slave_trace_level( + "rpl_semi_sync_slave_trace_level", + "The tracing level for semi-sync replication.", + GLOBAL_VAR(rpl_semi_sync_slave_trace_level), + CMD_LINE(OPT_ARG),VALID_RANGE(0, ~0L), + DEFAULT(32), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(0), ON_UPDATE(fix_rpl_semi_sync_trace_level)); +#endif // HAVE_ZSQL_QUICK_SYNC + +#ifdef HAVE_ZSQL_SYNC_DYNAMIC_TIMEOUT +static bool fix_sync_wait_timeout_ratio(sys_var *, THD *, enum_var_type) { + repl_semisync_master->setWaitTimeoutRatio(rpl_semi_sync_master_timeout_ratio); + return false; +} + +static Sys_var_ulong Sys_sync_wait_timeout_ratio( + "rpl_semi_sync_master_timeout_ratio", + "sync wait timeout value for per GB binlog size (in ms/GB)", + GLOBAL_VAR(rpl_semi_sync_master_timeout_ratio), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, ULONG_MAX), DEFAULT(20000), BLOCK_SIZE(1), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(fix_sync_wait_timeout_ratio)); +#endif // HAVE_ZSQL_SYNC_DYNAMIC_TIMEOUT + +#ifdef HAVE_ZSQL_FLASHBACK +static Sys_var_bool Sys_recyclebin( + "recyclebin", + "Whether to enable recyclebin(disabled by default).", + GLOBAL_VAR(g_recyclebin), + CMD_LINE(OPT_ARG), + DEFAULT(false)); + +static const char *recyclebin_support_command_options[] = { + "DROP_TABLE", "TRUNCATE_TABLE", "DROP_DATABASE", nullptr}; + +static Sys_var_set Sys_recyclebin_support_command( + "recyclebin_support_command", + "Set of types for the flashback support command, " + "the possible values are:DROP_TABLE, TRUNCATE_TABLE, DROP_DATABASE. " + "Any combination is allowed. " + "(Default: DROP_TABLE,TRUNCATE_TABLE,DROP_DATABASE).", + GLOBAL_VAR(g_recyclebin_support_command), CMD_LINE(REQUIRED_ARG), + recyclebin_support_command_options, + DEFAULT(RECYCLEBIN_DROP_TABLE | RECYCLEBIN_DROP_DATABASE), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(check_not_empty_set), ON_UPDATE(nullptr)); + +// static Sys_var_ulong Sys_expire_recyclebin_seconds( +// "expire_recyclebin_seconds", +// "Time threshold for general log expiration", +// GLOBAL_VAR(g_expire_recyclebin_seconds), +// CMD_LINE(OPT_ARG), +// VALID_RANGE(0, UINT_MAX), DEFAULT(86400), BLOCK_SIZE(1)); +#endif //HAVE_ZSQL_FLASHBACK + +#ifdef HAVE_ZSQL_ORA_VARCHAR_LEN_BYTE +// HAVE_ZSQL_ORACLE_CREATE_INDEX_WITH_GLOBAL_UNIQUE_NAME add OMS_GLOBAL_UNIQUE_INDEX +constexpr ulonglong ORA_ALL_SWITCHES = + OMS_ALL_ON | OMS_VARCHAR_LEN_BYTE | OMS_GLOBAL_UNIQUE_INDEX; + +// HAVE_ZSQL_ORACLE_CREATE_INDEX_WITH_GLOBAL_UNIQUE_NAME add GLOBAL_UNIQUE_INDEX +static const char *oracle_mode_switch_options[] = { + "ALL_OFF", "ALL_ON", "VARCHAR_LEN_BYTE", "GLOBAL_UNIQUE_INDEX", NullS}; + +bool postprocess_oracle_mode_switch(System_variables *sv) { + if (sv->oracle_mode_switch & OMS_ALL_OFF) { + sv->oracle_mode_switch = OMS_ALL_OFF; + } else if (sv->oracle_mode_switch & OMS_ALL_ON) { + sv->oracle_mode_switch |= ORA_ALL_SWITCHES; + } + return false; +} + +static bool fix_oracle_mode_switch(sys_var *self, THD *thd, enum_var_type type) { + System_variables *sv = (self->is_global_persist(type)) + ? &global_system_variables + : &thd->variables; + return postprocess_oracle_mode_switch(sv); +} + +// HAVE_ZSQL_ORACLE_CREATE_INDEX_WITH_GLOBAL_UNIQUE_NAME add GLOBAL_UNIQUE_INDEX +static Sys_var_set Sys_oracle_mode_switch( + "oracle_mode_switch", + "Set of switches for oracle compatible functions, any combination of " + "ALL_OFF, ALL_ON, VARCHAR_LEN_BYTE, GLOBAL_UNIQUE_INDEX is allowed. If including ALL_OFF, " + "switch all to OFF; If including ALL_ON, switch all to ON. If including " + "both ALL_OFF and ALL_ON, switch all to OFF. (Default: ALL_OFF).", + HINT_UPDATEABLE SESSION_VAR(oracle_mode_switch), CMD_LINE(REQUIRED_ARG), + oracle_mode_switch_options, DEFAULT(OMS_ALL_OFF), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(check_not_empty_set), + ON_UPDATE(fix_oracle_mode_switch)); +#endif // HAVE_ZSQL_ORA_VARCHAR_LEN_BYTE + +#ifdef HAVE_ZSQL_TCMALLOC_RELEASE +static bool set_tc_release_size(sys_var *, THD *thd, enum_var_type) { + const char *LD_src = getenv("LD_PRELOAD"); + if(LD_src == nullptr) { + push_warning_printf(thd, Sql_condition::SL_WARNING, ER_TC_RELEASE_MEMORY, + "tcmalloc LD_PRELOAD not found!"); + return false; + } + + /* The result of the "getenv" is the internal attributes pointing to the process, + for security, create a copy here. */ + const size_t LD_length = strlen(LD_src) + 1; + String LD_bak(LD_length); + LD_bak.copy(LD_src, LD_length, &my_charset_bin); + if (strstr(LD_bak.c_ptr(), "tcmalloc") == nullptr) { + push_warning_printf(thd, Sql_condition::SL_WARNING, ER_TC_RELEASE_MEMORY, + "tcmalloc shared library not found!"); + return false; + } + + void *handle = dlopen(LD_bak.c_ptr(), RTLD_LAZY); + if (handle == nullptr) { + push_warning_printf(thd, Sql_condition::SL_WARNING, ER_TC_RELEASE_MEMORY, + "open tcmalloc shared library failure!"); + return false; + } + + void (*release_to_system)(size_t); + release_to_system = (void (*)(size_t))dlsym(handle, "MallocExtension_ReleaseToSystem"); + if (release_to_system == nullptr) { + push_warning_printf(thd, Sql_condition::SL_WARNING, ER_TC_RELEASE_MEMORY, + "sym MallocExtension_ReleaseToSystem of tcmalloc not found!"); + dlclose(handle); + return false; + } + + mysql_mutex_unlock(&LOCK_global_system_variables); + + /* Release free memory of tcmalloc to system. + To minimize the influence of memory releasement, release a little memory + (100M) each time, and sleep 10ms between releasements. */ + const size_t release_block = 100 * 1024 * 1024; + uint release_times = g_tc_release_size / release_block; + while (release_times--) { + if (thd->killed) { + dlclose(handle); + mysql_mutex_lock(&LOCK_global_system_variables); + return false; + } + release_to_system(release_block); + my_sleep(10000); + } + + sql_print_information( + "tcmalloc try to release %zu bytes of free memory to system.", + size_t(g_tc_release_size)); + + dlclose(handle); + mysql_mutex_lock(&LOCK_global_system_variables); + return false; +} + +static Sys_var_ulonglong Sys_tc_release_size( + "tc_release_size", "the size of free memory inside tcmalloc to be released to system.", + GLOBAL_VAR(g_tc_release_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 10 * 1024 * 1024 * 1024ULL), DEFAULT(0), BLOCK_SIZE(IO_SIZE), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(set_tc_release_size)); +#endif // HAVE_ZSQL_TCMALLOC_RELEASE + +#ifdef HAVE_ZSQL_ORA_REAL2DEC +// TMP_FUNC_USED_TABLE: HAVE_ZSQL_USED_TABLES_ORIGINAL_BUG +// TMP_FUNC_CMP_NUM_IN_STR_KEY: HAVE_ZSQL_CMP_NUM_IN_STR_KEY +constexpr ulonglong TMP_FUNC_ALL_SWITCHES = + TMP_FUNC_ALL_ON | TMP_FUNC_DATATYPE_CONV | TMP_FUNC_CONCAT_UTF8MB4 + | TMP_FUNC_CMP_NUM_IN_STR_KEY | TMP_FUNC_DROP_TABLE_CASCADE_CONSTRAINTS; + +static const char *tmp_function_for_future_options[] = { + "ALL_OFF", "ALL_ON", "DATATYPE_CONV", "CONCAT_UTF8MB4", + "CMP_NUM_IN_STR_KEY", // HAVE_ZSQL_CMP_NUM_IN_STR_KEY + "DROP_TABLE_CASCADE_CONSTRAINTS", // HAVE_ZSQL_DROP_CASCADE_CONSTRAINTS + NullS}; + +static bool postprocess_tmp_function_for_future(System_variables *sv) { + if (sv->tmp_function_for_future & TMP_FUNC_ALL_OFF) { + sv->tmp_function_for_future = TMP_FUNC_ALL_OFF; + } else if (sv->tmp_function_for_future & TMP_FUNC_ALL_ON) { + sv->tmp_function_for_future |= TMP_FUNC_ALL_SWITCHES; + } + return false; +} + +bool postprocess_system_variables(System_variables *sv) { + postprocess_oracle_mode_switch(sv); // HAVE_ZSQL_ORA_VARCHAR_LEN_BYTE + postprocess_tmp_function_for_future(sv); + return false; +} + +static bool fix_tmp_function_for_future(sys_var *self, THD *thd, + enum_var_type type) { + System_variables *sv = (self->is_global_persist(type)) + ? &global_system_variables + : &thd->variables; + return postprocess_tmp_function_for_future(sv); +} + +static Sys_var_set Sys_tmp_function_for_future( + "tmp_function_for_future", + "Set of switches for temporary functions, any combination of " + "ALL_OFF, ALL_ON, DATATYPE_CONV, CONCAT_UTF8MB4, CMP_NUM_IN_STR_KEY, " + "DROP_TABLE_CASCADE_CONSTRAINTS " + "is allowed. " + "If including ALL_OFF, switch all to OFF; " + "If including ALL_ON, switch all to ON. If " + "including both ALL_OFF and ALL_ON, switch all to OFF. (Default: ALL_OFF).", + HINT_UPDATEABLE SESSION_VAR(tmp_function_for_future), CMD_LINE(REQUIRED_ARG), + tmp_function_for_future_options, DEFAULT(TMP_FUNC_ALL_OFF), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(check_not_empty_set), + ON_UPDATE(fix_tmp_function_for_future)); +#endif // HAVE_ZSQL_ORA_REAL2DEC + +static bool check_set_require_row_format(sys_var *, THD *thd, set_var *var) { + /* + Should own SUPER or SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN + when the value is changing to NO, no privileges are needed to set to YES + */ + longlong previous_val = thd->variables.require_row_format; + longlong val = (longlong)var->save_result.ulonglong_value; + assert(!var->is_global_persist()); + + // if it was true and we are changing it + if (previous_val && val != previous_val) { + if (thd->security_context()->check_access(SUPER_ACL) || + thd->security_context() + ->has_global_grant(STRING_WITH_LEN("SYSTEM_VARIABLES_ADMIN")) + .first || + thd->security_context() + ->has_global_grant(STRING_WITH_LEN("SESSION_VARIABLES_ADMIN")) + .first) + return false; + + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER or SYSTEM_VARIABLES_ADMIN or SESSION_VARIABLES_ADMIN"); return true; } @@ -7339,7 +9090,7 @@ static Sys_var_bool Sys_replication_optimize_for_static_plugin_config( "Optional flag that blocks plugin install/uninstall and allows skipping " "the acquisition of the lock to read from the plugin list and the usage " "of read-optimized spin-locks. Use only when plugin hook callback needs " - "optimization (a lot of semi-sync replicas, for instance).", + "optimization (a lot of semi-sync slaves, for instance).", GLOBAL_VAR(opt_replication_optimize_for_static_plugin_config), CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(handle_plugin_lock_type_change)); @@ -7352,78 +9103,47 @@ static Sys_var_bool Sys_replication_sender_observe_commit_only( DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr)); -static Sys_var_bool Sys_skip_replica_start( - "skip_replica_start", - "Do not start replication threads automatically " - "when the server starts.", - READ_ONLY GLOBAL_VAR(opt_skip_replica_start), CMD_LINE(OPT_ARG), +static Sys_var_bool Sys_skip_slave_start( + "skip_slave_start", "If set, slave is not autostarted.", + READ_ONLY GLOBAL_VAR(opt_skip_slave_start), CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr)); -static bool check_authentication_policy(sys_var *, THD *, set_var *var) { - if (!(var->save_result.string_value.str)) return true; - return validate_authentication_policy(var->save_result.string_value.str); -} +#ifdef HAVE_ZSQL_DISABLE_TCP_CONNECTION +static Sys_var_bool Sys_disable_tcp_connection( + "disable_tcp_connection", + "Disable tcp connections(0 by default, 1 means disable). ", + GLOBAL_VAR(g_disable_tcp_connection), + CMD_LINE(OPT_ARG), + DEFAULT(false)); +#endif /* HAVE_ZSQL_DISABLE_TCP_CONNECTION */ -static bool fix_authentication_policy(sys_var *, THD *, enum_var_type) { - DBUG_TRACE; - update_authentication_policy(); - return false; -} -/** - This is a mutex used to protect @@global.authentication_policy variable. -*/ -static PolyLock_mutex PLock_authentication_policy(&LOCK_authentication_policy); -/* - when authentication_policy = 'mysql_native_password,,' and - --default-authentication-plugin = 'caching_sha2_password' - set default as mysql_native_password. - --authentication_policy has precedence over --default-authentication-plugin - with 1 exception as below: when authentication_policy = '*,,' and - --default-authentication-plugin = 'mysql_native_password' - set default as mysql_native_password - in case no concrete plugin can be extracted from --authentication_policy - for first factor, server picks plugin name from - --default-authentication-plugin -*/ -static Sys_var_charptr Sys_authentication_policy( - "authentication_policy", - "Defines policies around how user account can be configured with Multi " - "Factor authentication methods during CREATE/ALTER USER statement. " - "This variable accepts at-most 3 comma separated list of authentication " - "plugin names where each value refers to what authentication plugin should " - "be used in place of 1st Factor Authentication (FA), 2FA and 3FA method. " - "Value * indicates any plugin is allowed for 1FA, 2FA and 3FA method. " - "An empty value means nth FA method is optional.", - GLOBAL_VAR(opt_authentication_policy), CMD_LINE(REQUIRED_ARG), - IN_FS_CHARSET, DEFAULT("*,,"), &PLock_authentication_policy, NOT_IN_BINLOG, - ON_CHECK(check_authentication_policy), - ON_UPDATE(fix_authentication_policy)); - -static Sys_var_deprecated_alias Sys_skip_slave_start("skip_slave_start", - Sys_skip_replica_start); - -static const char *terminology_use_previous_names[] = {"NONE", "BEFORE_8_0_26", - nullptr}; +#ifdef HAVE_ZSQL_REMOVE_PARTITION_KEY_LIMITATION +static Sys_var_bool Sys_remove_partition_key_limitation( + "remove_partition_key_limitation", + "Whether to remove_partition key limitation. Default is OFF." + "If set to ON, it's allowed to create partition table whose partition key is not in primary or unique key", + GLOBAL_VAR(g_remove_partition_key_limitation), + CMD_LINE(OPT_ARG), + DEFAULT(false)); +#endif // HAVE_ZSQL_REMOVE_PARTITION_KEY_LIMITATION -static Sys_var_enum Sys_terminology_use_previous( - "terminology_use_previous", - "Make monitoring tables and statements use the identifiers that were " - "in use before they were changed in a given release. That includes names " - "for mutexes, read/write locks, condition variables, memory allocations, " - "thread names, thread stages, and thread commands. When the session " - "option is set to BEFORE_8_0_26, the session uses the names that were in " - "use until 8.0.25, when it selects from performance_schema tables, or " - "selects from INFORMATION_SCHEMA.PROCESSLIST, or issues SHOW PROCESSLIST " - "or SHOW REPLICA STATUS. When the global option is set to BEFORE_8_0_26, " - "new sessions use BEFORE_8_0_26 as default for the session option, and in " - "addition the thread commands that were in use until 8.0.25 are written " - "to the slow query log.", - SESSION_VAR(terminology_use_previous), CMD_LINE(REQUIRED_ARG), - terminology_use_previous_names, DEFAULT(terminology_use_previous::NONE), - NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr), - DEPRECATED_VAR("")); +#ifdef HAVE_ZSQL_DISABLE_FULL_TABLE_SCAN +static Sys_var_bool Sys_disable_full_table_scan_in_delete( + "disable_full_table_scan_in_delete", + "Whether to disable full table scan in single table deletion.", + GLOBAL_VAR(g_disable_full_table_scan_in_delete), + CMD_LINE(OPT_ARG), + DEFAULT(false)); +static Sys_var_bool Sys_disable_full_table_scan_in_select( + "disable_full_table_scan_in_select", + "Whether to disable full table/index scan in single table selection.", + GLOBAL_VAR(g_disable_full_table_scan_in_select), + CMD_LINE(OPT_ARG), + DEFAULT(false)); +#endif //HAVE_ZSQL_DISABLE_FULL_TABLE_SCAN +#ifdef HAVE_ZSQL_TEMPTABLE static Sys_var_ulonglong Sys_tmp_table_max_rows( "tmp_table_max_rows", "If an internal in-memory temporary table exceeds this size, MySQL " @@ -7431,7 +9151,506 @@ static Sys_var_ulonglong Sys_tmp_table_max_rows( SESSION_VAR(tmp_table_max_rows), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, (uint64_t)~(intptr)0), DEFAULT(0), BLOCK_SIZE(1)); +#endif /* HAVE_ZSQL_TEMPTABLE */ + +#ifdef HAVE_ZSQL_ROWSIZE_LIMIT +static Sys_var_uint Sys_max_table_record_size( + "max_table_record_size", + "The size of record in tables", + READ_ONLY GLOBAL_VAR(g_max_table_record_size), CMD_LINE(OPT_ARG), +#ifdef HAVE_ZSQL_INCREASE_TABLE_RECORD_SIZE + VALID_RANGE(64 * 1024, 2 * 1024 * 1024), DEFAULT(64 * 1024), +#else + VALID_RANGE(64 * 1024, 3 * 64 * 1024), DEFAULT(64 * 1024), +#endif //HAVE_ZSQL_INCREASE_TABLE_RECORD_SIZE + BLOCK_SIZE(64 * 1024)); +#endif //HAVE_ZSQL_ROWSIZE_LIMIT + +#ifdef HAVE_ZSQL_TO_DATE +static bool check_default_date_format(sys_var *, THD *thd, set_var *setv) { + LEX_STRING &new_format = setv->save_result.string_value; + return check_datetime_format_valid(new_format, thd); +} + +static Sys_var_charptr Sys_default_date_format( + "default_date_format", "Default date format for TO_DATE().", + SESSION_VAR(default_date_format), CMD_LINE(OPT_ARG), IN_FS_CHARSET, + DEFAULT("YYYY-MM-DD HH24:MI:SS"), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_default_date_format), + ON_UPDATE(0)); + +static bool check_default_timestamp_format(sys_var *, THD *thd, set_var *setv) { + LEX_STRING &new_format = setv->save_result.string_value; + return check_datetime_format_valid(new_format, thd); +} + +static Sys_var_charptr Sys_default_timestamp_format( + "default_timestamp_format", "Default timestamp format for TO_TIMESTAMP().", + SESSION_VAR(default_timestamp_format), CMD_LINE(OPT_ARG), IN_FS_CHARSET, + DEFAULT("YYYY-MM-DD HH24:MI:SS.FF"), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_default_timestamp_format), + ON_UPDATE(0)); +#endif // HAVE_ZSQL_TO_DATE + +#ifdef HAVE_ZSQL_LISTAGG_FUNC +static Sys_var_ulong Sys_listagg_max_len( + "listagg_max_len", + "The maximum length of the result of function LISTAGG()", + HINT_UPDATEABLE SESSION_VAR(m_listagg_max_len), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(4, ULONG_MAX), DEFAULT(4000), BLOCK_SIZE(1)); +#endif /* HAVE_ZSQL_LISTAGG_FUNC */ + +#ifdef HAVE_ZSQL_VARCHAR2 +static const char *my_nls_length_semantics[] = {"BYTE", "CHAR", NullS}; +static Sys_var_enum Sys_nls_length_semantics( + "nls_length_semantics", + "Default length semantics to use for VARCHAR2 table columns.", + SESSION_VAR(nls_length_semantics), CMD_LINE(OPT_ARG), + my_nls_length_semantics, DEFAULT(SEMANTICS_BYTE)); +#endif /* HAVE_ZSQL_VARCHAR2 */ + +#ifdef HAVE_ZSQL_DISABLE_PREPARED_STMT_REWRITE_QUERY +static Sys_var_bool Sys_disable_prepared_stmt_rewrite_query( + "disable_prepared_stmt_rewrite_query", + "Whether to disable rewriting query for Prepared Statement(enabled by default).", + GLOBAL_VAR(g_disable_prepared_stmt_rewrite_query), + CMD_LINE(OPT_ARG), + DEFAULT(false)); +#endif //HAVE_ZSQL_DISABLE_PREPARED_STMT_REWRITE_QUERY + +#ifdef HAVE_ZSQL_FILTER_GDB_FIELDS +static Sys_var_bool Sys_goldendb_transparent_link( + "goldendb_transparent_link", + "Whether is a goldendb transparent link (false by default).", + SESSION_ONLY(goldendb_transparent_link), NO_CMD_LINE, DEFAULT(false)); +#endif // HAVE_ZSQL_FILTER_GDB_FIELDS + +#ifdef HAVE_ZSQL_GDB_VISIBLE_SESSION +static bool check_gdb_session_id(sys_var *, THD *thd, set_var *var) { + constexpr ulonglong LOWER_BOUND = 1ULL << 32; + + ulonglong val = var->save_result.ulonglong_value; + if (val != static_cast(var->value->val_int()) || // <1> the corrected value + (val > 0 && val < LOWER_BOUND)) { // <2> no frontend id + my_error(ER_UNEXPECTED_VISIBILE_SESSION, MYF(0), + "Value is out of range, valid range: 0, " + "or 4294967296 ~ 18446744073709551615"); + return true; + } + + if (thd->is_gdb_xa_owner_thread()) { + std::swap(thd->variables.gdb_session_id, + thd->gdb_xa().origin_thd()->variables.gdb_session_id); + } + return false; +} + +static bool fix_gdb_session_id(sys_var *, THD *thd, enum_var_type) { + ulonglong gdb_sess_id = thd->variables.gdb_session_id; + THD *to = thd; + + if (thd->is_gdb_xa_owner_thread()) { + to = thd->gdb_xa().origin_thd(); + std::swap(thd->variables.gdb_session_id, to->variables.gdb_session_id); + } + + to->set_visible_session_id(static_cast(gdb_sess_id & 0xFFFFFFFFULL)); + to->set_frontend_id(static_cast(gdb_sess_id >> 32)); + return false; +} + +static Sys_var_ulonglong Sys_gdb_session_id( + "gdb_session_id", + "gdb_session_id consists of gdb_frontend_id (higher 4 bytes) and attached " + "DB session id (lower 4 bytes)", + HINT_UPDATEABLE SESSION_ONLY(gdb_session_id), NO_CMD_LINE, + VALID_RANGE(0, ULLONG_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(check_gdb_session_id), + ON_UPDATE(fix_gdb_session_id)); +#endif // HAVE_ZSQL_GDB_VISIBLE_SESSION + +#ifdef HAVE_ZSQL_LOCK_WAIT_SLOT_COUNT +static Sys_var_uint Sys_innodb_lock_wait_slot_count( + "innodb_lock_wait_slot_count", + "The slot count in lock wait log", + READ_ONLY GLOBAL_VAR(g_innodb_lock_wait_slot_count), CMD_LINE(OPT_ARG), + VALID_RANGE(10, 1024), DEFAULT(1024), + BLOCK_SIZE(1)); +#endif //HAVE_ZSQL_LOCK_WAIT_SLOT_COUNT + +#ifdef HAVE_ZSQL_TMPDIR_FILES_SIZE_LIMIT +static Sys_var_ulonglong Sys_tmpdir_max_files_size( + "tmpdir_max_files_size", + "The maximum size of temporary files that are created by filsort, unique " + "and hash join in tmpdir.", + GLOBAL_VAR(g_tmpdir_max_files_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 1024 * 1024 * 1024 * 1024ULL), DEFAULT(0), BLOCK_SIZE(1)); + +static Sys_var_ulonglong Sys_tmpdir_min_disk_free_space( + "tmpdir_min_disk_free_space", + "The minimum free space of disk owned by tmpdir.", + GLOBAL_VAR(g_tmpdir_min_disk_free_space), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 1024 * 1024 * 1024 * 1024ULL), DEFAULT(0), BLOCK_SIZE(1)); + +static Sys_var_uint Sys_tmpdir_min_disk_free_ratio( + "tmpdir_min_disk_free_ratio", + "The minimum free percentage ratio of disk owned by tmpdir.", + GLOBAL_VAR(g_tmpdir_min_disk_free_ratio), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 100), DEFAULT(0), BLOCK_SIZE(1)); +#endif // HAVE_ZSQL_TMPDIR_FILES_SIZE_LIMIT + +#ifdef HAVE_ZSQL_ROWID +static constexpr char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +void encode_base64_group_id() { + g_base64_group_id[1] = base64_table[g_group_id & 0x003FU]; + g_base64_group_id[0] = base64_table[(g_group_id >> 6) & 0x003FU]; +} + +static bool fix_group_id(sys_var*, THD*, enum_var_type) { + encode_base64_group_id(); + return false; +} + +static Sys_var_uint Sys_group_id( + "group_id", "GoldenDB group id.", + GLOBAL_VAR(g_group_id), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 0x0FFF), + DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(fix_group_id)); +#endif // HAVE_ZSQL_ROWID + +#ifdef HAVE_ZSQL_SQL_BLACKLIST_INTERCEPT +static bool refresh_sql_blacklist_cache(sys_var *, THD *thd, enum_var_type) { + bool error = false; + + // Refresh g_sql_blacklist_cache could be slow. + mysql_mutex_unlock(&LOCK_global_system_variables); + if (g_sql_blacklist) { + error = g_sql_blacklist_cache.refresh(thd); + } else { + g_sql_blacklist_cache.clean(); + } + mysql_mutex_lock(&LOCK_global_system_variables); + + return error; +} + +static Sys_var_bool Sys_sql_blacklist( + "sql_blacklist", "Whether to enable SQL blacklist (disabled by default).", + GLOBAL_VAR(g_sql_blacklist), CMD_LINE(OPT_ARG), DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(refresh_sql_blacklist_cache)); +#endif // HAVE_ZSQL_SQL_BLACKLIST_INTERCEPT + +#ifdef HAVE_ZSQL_OUTLINE +static bool refresh_outline_cache(sys_var *, THD *thd, enum_var_type) { + bool error = false; + + // Refresh g_outline_cache could be slow. + mysql_mutex_unlock(&LOCK_global_system_variables); + if (g_outline) { + error = g_outline_cache.refresh(thd); + } else { + g_outline_cache.clean(); + } + mysql_mutex_lock(&LOCK_global_system_variables); + + return error; +} + +static Sys_var_bool Sys_outline( + "outline", "Whether to enable outline (disabled by default).", + GLOBAL_VAR(g_outline), CMD_LINE(OPT_ARG), DEFAULT(false), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(refresh_outline_cache)); +#endif // HAVE_ZSQL_OUTLINE + +#ifdef HAVE_ZSQL_DBMS_OUTPUT +static bool switch_dbms_output(sys_var *, THD *thd, enum_var_type) { + bool new_state = thd->variables.dbms_output_enable; + + if (!new_state) { + if (thd->m_output != nullptr) { + thd->m_output->disable(); + } + return false; + } + + if (thd->m_output == nullptr) { + thd->m_output = new (std::nothrow) dbms_output_t(thd); + if (thd->m_output == nullptr) { + thd->variables.dbms_output_enable = false; + my_error(ER_DBMS_OUTPUT_INCORRECT_USE, MYF(0), "Out of memory"); + return true; + } + } + thd->m_output->enable(); + + return false; +} + +static Sys_var_bool Sys_dbms_output_enable( + "dbms_output_enable", + "Whether to enable dbms_output (disable by default).", + SESSION_ONLY(dbms_output_enable), + CMD_LINE(OPT_ARG), + DEFAULT(false), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), + ON_UPDATE(switch_dbms_output)); +static bool update_serveroutput(sys_var *, THD *thd, enum_var_type) { + thd->variables.dbms_output_enable = thd->variables.serveroutput; + + return switch_dbms_output(nullptr,thd, enum_var_type::OPT_SESSION); +} + +static Sys_var_bool Sys_serveroutput( + "serveroutput", + "Whether to enable dbms_output and flush buffer in dbms_output to client " + "after issuing a SQL statement or anonymous PL/SQL calls.", + SESSION_ONLY(serveroutput), CMD_LINE(OPT_ARG), DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), + ON_UPDATE(update_serveroutput)); + +// set max_buffer_size always happened after enable, which is wrapped in +// dbms_output.enable() +static bool update_dbms_output_max_buffer_size(sys_var *, THD *thd, + enum_var_type) { + if (thd->m_output != nullptr) { + thd->m_output->set_max_buffer_size(thd->variables.dbms_output_buffer_size); + } + return false; +} + +static Sys_var_ulong Sys_dbms_output_max_buffer_size( + "dbms_output_max_buffer_size", + "The max size of the buffer in dbms_output(valid value: 2000 ~ 1000000, " + "20000 by default).", + SESSION_ONLY(dbms_output_buffer_size), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(2000, 1000000), DEFAULT(20000), BLOCK_SIZE(1), NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(NULL), + ON_UPDATE(update_dbms_output_max_buffer_size)); +#endif /* HAVE_ZSQL_DBMS_OUTPUT */ + +#ifdef HAVE_ZSQL_ORA_DATATYPE +static Sys_var_uint Sys_default_number_precision( + "default_number_precision", + "The default precision(maximum number of digits) of NUMBER data type and " + "DECIMAL, NUMERIC, FIXED data types in ORA_DATATYPE SQL mode.", + HINT_UPDATEABLE SESSION_VAR(default_number_precision), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, 65), DEFAULT(10), BLOCK_SIZE(1)); + +static Sys_var_uint Sys_default_number_scale( + "default_number_scale", + "The default scale(number of digits to the right of the decimal point) of " + "NUMBER data type.", + HINT_UPDATEABLE SESSION_VAR(default_number_scale), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 30), DEFAULT(0), BLOCK_SIZE(1)); +#endif // HAVE_ZSQL_ORA_DATATYPE + +#ifdef HAVE_ZSQL_RELAY_LOG_REPLICA_ROLE +static Sys_var_bool Sys_relay_log_replica_role( + "relay_log_replica_role", + "if disabled - common DN role. " + "if enabled - only save relay log and don't apply relay log.", + READ_ONLY GLOBAL_VAR(g_is_relay_log_replica), CMD_LINE(OPT_ARG), + DEFAULT(false)); + +static Sys_var_ulong Sys_relay_log_expire_logs_seconds( + "relay_log_expire_logs_seconds", + "Time threshold for relay log expiration when g_is_relay_log_replica is on.", + GLOBAL_VAR(g_relay_log_expire_logs_seconds), + CMD_LINE(OPT_ARG), + VALID_RANGE(0, UINT_MAX), DEFAULT(2592000), BLOCK_SIZE(1)); + +static Sys_var_relay_log_gtid_purged Sys_relay_log_gtid_purged( + "relay_log_gtid_purged", + "The global variable contains the set of GTIDs not in the " + "relay log, we use it when g_is_relay_log_replica is on."); +#endif // HAVE_ZSQL_RELAY_LOG_REPLICA_ROLE + +#ifdef HAVE_ZSQL_GEOMETRY_FUNCTION_AND_INDEXES_BACK +static Sys_var_bool Sys_geometry_function_and_indexes_back( + "geometry_function_and_indexes_back", + "if ON - some function about geometry will back to version 5.7" + "if OFF - no change", + GLOBAL_VAR(opt_geometry_function_and_indexes_back), CMD_LINE(OPT_ARG), + DEFAULT(false)); +#endif // HAVE_ZSQL_GEOMETRY_FUNCTION_AND_INDEXES_BACK + +#ifdef HAVE_ZSQL_SLAVE_CDC +static Sys_var_bool Sys_relay_log_cdc_log( + "relay_log_cdc_log", + "if enabled - write large amounts of logs to errlog ", + GLOBAL_VAR(g_is_relay_log_cdc_log), CMD_LINE(OPT_ARG), + DEFAULT(false)); + +static Sys_var_bool Sys_relay_log_cdc_debug_info( + "relay_log_cdc_debug_info", + "if enabled - write large amounts of logs to errlog for get_cdc_binlog_trx", + GLOBAL_VAR(g_is_relay_log_cdc_debug_info), CMD_LINE(OPT_ARG), + DEFAULT(false)); + +static Sys_var_bool Sys_relay_log_cdc_role( + "relay_log_cdc_role", + "if disabled - common DN role. " + "if enabled - cdc ", + READ_ONLY GLOBAL_VAR(g_is_relay_log_cdc_role), CMD_LINE(OPT_ARG), + DEFAULT(false)); + +static Sys_var_ulong Sys_cdc_role_logic_type( + "cdc_role_logic_type", + "Cdc role logic type: 1: logic master 2: logic slave", + GLOBAL_VAR(g_log_cdc_role), CMD_LINE(OPT_ARG), + VALID_RANGE(1, 2), DEFAULT(1), BLOCK_SIZE(1)); + +static Sys_var_uint Sys_cdc_ctid_discard_threshold( + "cdc_ctid_discard_threshold", + "The exit threshold for a fetch search during the merge process of " + "distributed DDL transactions. This value represents the fetch trx_list " + "size.", + GLOBAL_VAR(g_ctid_discard_threshold), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, UINT_MAX), DEFAULT(1000000), BLOCK_SIZE(1)); + +static Sys_var_ulong Sys_cdc_ctid_discard_seconds( + "cdc_ctid_discard_seconds", + "The exit seconds for a fetch search during the merge process of " + "distributed DDL transactions.", + GLOBAL_VAR(g_ctid_discard_seconds), CMD_LINE(OPT_ARG), + VALID_RANGE(0, UINT_MAX), DEFAULT(86400), BLOCK_SIZE(1)); +#endif // HAVE_ZSQL_SLAVE_CDC + +#ifdef HAVE_ZSQL_BINLOG_SEQ_TO_TABLE_MAP +/* This switch has no effect on the slave machine.*/ +static Sys_var_bool Sys_support_cdc( + "support_cdc", + "if enable - change table_map_event data header format" + "if disable - keep original format", + GLOBAL_VAR(opt_support_cdc), CMD_LINE(OPT_ARG), DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(nullptr)); +#endif // HAVE_ZSQL_BINLOG_SEQ_TO_TABLE_MAP + +#ifdef HAVE_ZSQL_COMPARE_LONGSTR_NUMBER_IN_DECIMAL +static Sys_var_bool Sys_var_compare_longstr_number_in_decimal( + "compare_longstr_number_in_decimal", + "Enable comparing a long string and a number in decimal in stead of double " + "in case lose accuracy", + HINT_UPDATEABLE SESSION_VAR(compare_longstr_number_in_decimal), CMD_LINE(OPT_ARG), + DEFAULT(false)); +#endif // HAVE_ZSQL_COMPARE_LONGSTR_NUMBER_IN_DECIMAL + +#ifdef HAVE_ZSQL_FIRST_ROWS_HINT +static Sys_var_bool Sys_first_rows_set_flex_stream_fetch( + "first_rows_set_flex_stream_fetch", + "if enable - first_rows hint would set use_flex_stream_fetch = on" + "if disable - do nothing", + GLOBAL_VAR(g_first_rows_set_flex_stream_fetch), CMD_LINE(OPT_ARG), DEFAULT(false)); +#endif /* HAVE_ZSQL_FIRST_ROWS_HINT */ + +#ifdef HAVE_ZSQL_INTERVAL_PARTITION +static bool update_auto_partition_interval_enabled(sys_var *, THD *, + enum_var_type) { + bool is_enabled = g_interval_thread.m_enabled; + + /* + startup or stop background thread could be time-consuming, so release + LOCK_global_system_variables. + */ + mysql_mutex_unlock(&LOCK_global_system_variables); + + mysql_mutex_lock(&g_interval_thread.m_enabled_mutex); + + bool is_shutdown = g_interval_thread.m_shutdown; + if (is_shutdown) { + /* 在shutdonw 时, 执行启动后台线程操作: 启动线程 */ + if (is_enabled) + g_interval_thread.startup_interval_thread(); + else /* 在shutdonw 时, 执行停后台线程 操作: do nothing */ + g_interval_thread.m_enabled = false; + } else { /* 当前 后台线程正在running */ + /* 正在运行时,执行启动后台线程,操作:do nothing */ + if (is_enabled) + g_interval_thread.m_enabled = true; + else + g_interval_thread.stop_interval_thread(); + } + + mysql_mutex_unlock(&g_interval_thread.m_enabled_mutex); + mysql_mutex_lock(&LOCK_global_system_variables); + return false; +} + +static Sys_var_bool Sys_auto_partition_interval_enabled( + "auto_partition_interval_enabled", + "Whether to enable background thread(disabled by default).", + GLOBAL_VAR(g_interval_thread.m_enabled), CMD_LINE(OPT_ARG), DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(update_auto_partition_interval_enabled)); + +static Sys_var_ulong Sys_ato_partition_interval_seconds( + "auto_partition_interval_seconds", + "Auto partition interval time, in seconds", + GLOBAL_VAR(g_interval_thread.m_sleep_seconds), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(1, ULONG_MAX), DEFAULT(5), BLOCK_SIZE(1), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(nullptr)); +#endif // HAVE_ZSQL_INTERVAL_PARTITION + +#ifdef HAVE_ZSQL_DB_QUOTAS +bool init_db_quota_map(THD *thd); + +bool init_db_quotas_enabled(THD *thd, bool is_enabled) { + mysql_mutex_lock(&g_db_quotas_thread.m_enabled_mutex); + + bool ret{false}; + if (is_enabled) { + if (!g_db_quotas_thread.m_is_running) { + ret = init_db_quota_map(thd); + g_db_quotas_thread.startup_db_quotas_thread(); + g_db_quotas_thread.m_is_running = true; + } + } else if (g_db_quotas_thread.m_is_running) { + g_db_quotas_thread.stop_db_quotas_thread(); + g_db_quotas_thread.m_is_running = false; + } + + mysql_mutex_unlock(&g_db_quotas_thread.m_enabled_mutex); + return ret; +} + +static bool update_db_quotas_enabled(sys_var *, THD *thd, enum_var_type) { + bool is_enabled = g_db_quotas_thread.m_enabled; + + /* + startup or stop background thread could be time-consuming, so release + LOCK_global_system_variables. + */ + mysql_mutex_unlock(&LOCK_global_system_variables); + + bool ret = init_db_quotas_enabled(thd, is_enabled); + + mysql_mutex_lock(&LOCK_global_system_variables); + return ret; +} + +static Sys_var_bool Sys_db_quotas_enabled( + "db_quotas_enabled", + "Whether to enable background thread(disabled by default).", + GLOBAL_VAR(g_db_quotas_thread.m_enabled), CMD_LINE(OPT_ARG), DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(update_db_quotas_enabled)); + +static Sys_var_ulong Sys_db_quotas_check_interval( + "db_quotas_check_interval", + "db quotas check time, in milliseconds", + GLOBAL_VAR(g_db_quotas_thread.m_sleep_milliseconds), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(10, ULONG_MAX), DEFAULT(10), BLOCK_SIZE(1), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(nullptr), + ON_UPDATE(nullptr)); +#endif // HAVE_ZSQL_DB_QUOTAS + +#ifdef HAVE_ZSQL_LOG_PERMISSION static bool check_log_permission(sys_var *, THD *thd, set_var *var) { int value = var->value->val_int(); @@ -7468,6 +9687,12 @@ static bool set_log_permission(sys_var *, THD *thd, enum_var_type) { push_warning_printf(thd, Sql_condition::SL_WARNING, ER_LOG_PERMISSION, "Chmod %s fail, error_info:%s. (errno=%d)", opt_slow_logname, strerror(errno), errno); + /* chmod trx_query log */ + if (opt_trx_query_logname != nullptr && + chmod_by_log_permission(opt_trx_query_logname, false)) + push_warning_printf(thd, Sql_condition::SL_WARNING, ER_LOG_PERMISSION, + "Chmod %s fail, error_info:%s. (errno=%d)", + opt_trx_query_logname, strerror(errno), errno); /* chmod innodb_lock_wait_log. @@ -7516,19 +9741,90 @@ static Sys_var_int32 Sys_log_permission( VALID_RANGE(0, 1000), DEFAULT(640), BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_log_permission), ON_UPDATE(set_log_permission)); +#endif // HAVE_ZSQL_LOG_PERMISSION + +#ifdef HAVE_ZSQL_ORACLE_LPAD_MAX_LENGTH +static Sys_var_ulong Sys_oracle_pad_max_length( + "oracle_pad_max_length", + "Max lengths for lpad and rpad function. 0 means trun off, default is 4000", + GLOBAL_VAR(g_oracle_pad_max_length), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, ULONG_MAX), DEFAULT(4000), BLOCK_SIZE(1),NO_MUTEX_GUARD, + NOT_IN_BINLOG, ON_CHECK(nullptr), ON_UPDATE(nullptr)); +#endif // HAVE_ZSQL_ORACLE_LPAD_MAX_LENGTH + +#ifdef HAVE_ZSQL_IGNORE_GCOL_VALUE +static Sys_var_bool Sys_ignore_gcol_value( + "ignore_gcol_value", + "Whether to ignore the insert, update and load values specified for " + "generated columns (disabled by default).", + HINT_UPDATEABLE SESSION_VAR(ignore_gcol_value), CMD_LINE(OPT_ARG), + DEFAULT(false)); +#endif // HAVE_ZSQL_IGNORE_GCOL_VALUE + +#ifdef HAVE_ZSQL_CHARSET_NUMBER +static Sys_var_uint Sys_character_set_number( + "character_set_number", + "The character set number used for returning query results to the client", + GLOBAL_VAR(g_character_set_number), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(0, 309), DEFAULT(0), BLOCK_SIZE(1)); +#endif // HAVE_ZSQL_CHARSET_NUMBER +#ifdef HAVE_ZSQL_SHOW_CREATE_TABLE_PRECISION static Sys_var_bool Sys_show_create_table_precision( "show_create_table_precision", "whether show the display width for integer types. ", SESSION_VAR(show_create_table_precision), CMD_LINE(OPT_ARG), DEFAULT(false)); +#endif // HAVE_ZSQL_SHOW_CREATE_TABLE_PRECISION + +#ifdef HAVE_ZSQL_FIX_ORIGINAL_BUGS // WL#14700 Bug#31599926 +static Sys_var_bool Sys_xa_detatch_on_prepare( + "xa_detach_on_prepare", + "When set, XA transactions will be detached (AKA dissociated or " + "disconnected) from connection as part of XA PREPARE. This means that " + "the XA transaction can be committed/rolled back by any connection, " + "even if the starting connection has not terminated, and the starting " + "connection can start new transactions. As a side effect, temporary " + "tables cannot be used inside XA transactions. " + "When disabled, XA transactions are associated with the same connection " + "until the session disconnects. ON is the only safe choice for " + "replication.", + HINT_UPDATEABLE SESSION_VAR(xa_detach_on_prepare), CMD_LINE(OPT_ARG), + DEFAULT(true), NO_MUTEX_GUARD, IN_BINLOG, + ON_CHECK(check_session_admin_outside_trx_outside_sf)); +#endif // HAVE_ZSQL_FIX_ORIGINAL_BUGS + +#ifdef HAVE_ZSQL_GLOBAL_COMPRESS +static Sys_var_bool Sys_gdb_compress_table( + "gdb_global_compress", + "Whether to compress table automatically (disabled by default).", + GLOBAL_VAR(g_opt_global_compress), CMD_LINE(OPT_ARG), DEFAULT(false), + NO_MUTEX_GUARD, NOT_IN_BINLOG); -#ifdef HAVE_ZSQL_REMOVE_PARTITION_KEY_LIMITATION -static Sys_var_bool Sys_remove_partition_key_limitation( - "remove_partition_key_limitation", - "Whether to remove_partition key limitation. Default is OFF." - "If set to ON, it's allowed to create partition table whose partition key is not in primary or unique key", - GLOBAL_VAR(g_remove_partition_key_limitation), - CMD_LINE(OPT_ARG), - DEFAULT(false)); -#endif // HAVE_ZSQL_REMOVE_PARTITION_KEY_LIMITATION +static bool check_global_compression_algorithm(sys_var *, THD *, set_var *var) { + const char *compress_str = var->save_result.string_value.str; + + /* It's no use to set the global compression algo is NULL. */ + if(compress_str == nullptr) + return true; + + if (my_strcasecmp(system_charset_info, compress_str, "zlib") == 0) + return false; + + if (my_strcasecmp(system_charset_info, compress_str, "none") == 0) + return false; + + if (my_strcasecmp(system_charset_info, compress_str, "lz4") == 0) + return false; + + return true; +} + +static Sys_var_charptr Sys_gdb_global_compression_algo( + "gdb_global_compression_algo", + "This option sets the global compression algorithm of tables and is used " + "only when gdb_global_compress is true. ", + GLOBAL_VAR(g_opt_global_compression_algo), CMD_LINE(REQUIRED_ARG), + IN_SYSTEM_CHARSET, DEFAULT("zlib"), NO_MUTEX_GUARD, NOT_IN_BINLOG, + ON_CHECK(check_global_compression_algorithm)); +#endif // HAVE_ZSQL_GLOBAL_COMPRESS