www.bortolotto.eu

Newsfeeds
Planet MySQL
Planet MySQL - https://planet.mysql.com

  • New Contact Management in HeatWave MySQL
    Customer contacts in HeatWave is a new feature that streamlines notification management by allowing you to assign specific contacts for all critical databases. With this capability, your Cloud Ops and DBA team can stay informed about operational issues, maintenance updates, and service announcements, ensuring timely responses.

  • Replica Preserve Commit Order and Measuring Lag
    With multi-threaded replication (MTR), a replica can commit transactions in the same order as the source, or not. This is determined by sysvar replica_preserve_commit_order (RPCO). As of MySQL v8.0.27 (released October 2021) it’s ON by default, but it was OFF by default for several years prior. In either case, it’s relatively new compared to 20+ years of single-threaded replication for which commit order was not an issue or option. But with MTR, it’s important to understand the affects of RPCO, especially with respect to the focus of this three-part series: replication lag.

  • WeSQL Introduction – MySQL running on S3
    I recently became aware of WeSQL. A MySQL-compatible database that separates compute and storage, using S3 as the storage layer. The product uses a columnar format by default which is significantly more space-efficient than InnoDB. WeSQL introduces a new storage engine called SmartEngine using a LSM-tree-based structure that is ideal for a storage bucket implementation, and documentation shows the implementation of raft replication to combat latency concerns. There is a lot more information to review, the serverless architecture and WeScale, a database proxy and resource manager. It was very easy to take it for an initial spin using a docker container and an AWS S3 bucket. I would really like to try CloudFlare R2 which implements the S3 API. Under the covers there are over 180 new variables comprising 83 for the smartengine, 57 for raft, and 22 for objectstore and more. This implies a lot of tunable options and a lot of complexity to optimize for a variety of workloads using the 79 new status variables. I was able to launch a demo and confirm mysql> SELECT VERSION(); +-----------+ | VERSION() | +-----------+ | 8.0.35 | +-----------+ 1 row in set (0.01 sec) mysql> SELECT @@wesql_version; +-----------------+ | @@wesql_version | +-----------------+ | 0.1.0 | +-----------------+ 1 row in set (0.00 sec) One of my early tests showed that it does not support FOREIGN KEYS, which is not a major concern. ERROR 1235 (42000) at line 10: SE currently doesn't support foreign key constraints I did have some subsequent issues with the current docs version 8.0.35-0.1.0_beta1.37 and I did revert to a prior version from docs earlier this week 8.0.35-0.1.0_beta1.gedaf338.36. Given it’s a very new product I am sure there is a lot of ongoing development. This is just a quick introduction but it’s a definitely a different architecture in the RDBMS landscape for MySQL compatibility. I hope to run some more tests using the provided sysbench use cases and my own workloads to delve under the covers more. New Variables branch_objectstore_id clone_autotune_concurrency clone_block_ddl clone_buffer_size clone_ddl_timeout clone_delay_after_data_drop clone_donor_timeout_after_network_failure clone_enable_compression clone_max_concurrency clone_max_data_bandwidth clone_max_network_bandwidth clone_ssl_ca clone_ssl_cert clone_ssl_key clone_valid_donor_list initialize_branch_objectstore_id initialize_from_objectstore initialize_objectstore_bucket initialize_objectstore_endpoint initialize_objectstore_provider initialize_objectstore_region initialize_objectstore_use_https initialize_repo_objectstore_id initialize_smartengine_objectstore_data objectstore_bucket objectstore_endpoint objectstore_mtr_test_bucket_dir objectstore_provider objectstore_region objectstore_use_https raft_replication_allow_no_valid_entry raft_replication_appliedindex_force_delay raft_replication_archive_log_bin_index raft_replication_archive_recovery raft_replication_archive_recovery_stop_datetime raft_replication_auto_leader_transfer raft_replication_auto_leader_transfer_check_seconds raft_replication_auto_reset_match_index raft_replication_check_commit_index_interval raft_replication_checksum raft_replication_cluseter_info_on_objectstore raft_replication_cluster_id raft_replication_cluster_info raft_replication_configure_change_timeout raft_replication_current_term raft_replication_disable_election raft_replication_disable_fifo_cache raft_replication_dynamic_easyindex raft_replication_election_timeout raft_replication_flow_control raft_replication_force_change_meta raft_replication_force_recover_index raft_replication_force_reset_meta raft_replication_force_single_mode raft_replication_force_sync_epoch_diff raft_replication_heartbeat_thread_cnt raft_replication_io_thread_cnt raft_replication_large_batch_ratio raft_replication_large_event_split_size raft_replication_large_trx raft_replication_learner_heartbeat raft_replication_learner_node raft_replication_learner_pipelining raft_replication_learner_timeout raft_replication_log_cache_size raft_replication_log_level raft_replication_log_type_node raft_replication_max_delay_index raft_replication_max_log_size raft_replication_max_packet_size raft_replication_min_delay_index raft_replication_mts_recover_use_index raft_replication_new_follower_threshold raft_replication_optimistic_heartbeat raft_replication_pipelining_timeout raft_replication_prefetch_cache_size raft_replication_prefetch_wakeup_ratio raft_replication_prefetch_window_size raft_replication_purged_gtid raft_replication_recover_backup raft_replication_recover_new_cluster raft_replication_reset_prefetch_cache raft_replication_send_timeout raft_replication_start_index raft_replication_sync_follower_meta_interva raft_replication_with_cache_log raft_replication_worker_thread_cnt recovery_snapshot_from_objectstore recovery_snapshot_only recovery_snapshot_timestamp recovery_snapshot_tmpdir repo_objectstore_id server_id_on_objectstore serverless smartengine_auto_shrink_enabled smartengine_auto_shrink_schedule_interval smartengine_batch_group_max_group_size smartengine_batch_group_max_leader_wait_time_us smartengine_batch_group_slot_array_size smartengine_block_cache_size smartengine_block_size smartengine_bottommost_level smartengine_bulk_load_size smartengine_compact smartengine_compaction_delete_percent smartengine_compaction_task_extents_limit smartengine_compaction_threads smartengine_compression_options smartengine_compression_per_level smartengine_concurrent_writable_file_buffer_num smartengine_concurrent_writable_file_buffer_switch_limit smartengine_concurrent_writable_file_single_buffer_size smartengine_data_dir smartengine_deadlock_detect smartengine_disable_auto_compactions smartengine_disable_instant_ddl smartengine_disable_online_ddl smartengine_disable_parallel_ddl smartengine_dump_memtable_limit_size smartengine_enable_2pc smartengine_estimate_cost_depth smartengine_flush_delete_percent smartengine_flush_delete_percent_trigger smartengine_flush_delete_record_trigger smartengine_flush_log_at_trx_commit smartengine_flush_memtable smartengine_flush_threads smartengine_hotbackup smartengine_idle_tasks_schedule_time smartengine_level0_file_num_compaction_trigger smartengine_level0_layer_num_compaction_trigger smartengine_level1_extents_major_compaction_trigger smartengine_level2_usage_percent smartengine_level_compaction_dynamic_level_bytes smartengine_lock_scanned_rows smartengine_lock_wait_timeout smartengine_master_thread_compaction_enabled smartengine_master_thread_monitor_interval_ms smartengine_max_background_dumps smartengine_max_free_extent_percent smartengine_max_row_locks smartengine_max_shrink_extent_count smartengine_max_write_buffer_number_to_maintain smartengine_memtable_size smartengine_min_write_buffer_number_to_merge smartengine_mutex_backtrace_threshold_ns smartengine_parallel_flush_log smartengine_parallel_read_threads smartengine_parallel_recovery_thread_num smartengine_parallel_wal_recovery smartengine_pause_background_work smartengine_persistent_cache_dir smartengine_persistent_cache_mode smartengine_persistent_cache_size smartengine_purge_invalid_subtable_bg smartengine_query_trace_print_slow smartengine_query_trace_sum smartengine_query_trace_threshold_time smartengine_rate_limiter_bytes_per_sec smartengine_reset_pending_shrink smartengine_row_cache_size smartengine_scan_add_blocks_limit smartengine_shrink_allocate_interval smartengine_shrink_table_space smartengine_sort_buffer_size smartengine_stats_dump_period_sec smartengine_strict_collation_check smartengine_strict_collation_exceptions smartengine_table_cache_numshardbits smartengine_table_cache_size smartengine_total_max_shrink_extent_count smartengine_total_memtable_size smartengine_total_wal_size smartengine_unsafe_for_binlog smartengine_wal_dir smartengine_wal_recovery_mode smartengine_write_disable_wal snapshot_archive snapshot_archive_dir snapshot_archive_expire_auto_purge snapshot_archive_expire_seconds snapshot_archive_innodb_tar_mode snapshot_archive_on_objectstore snapshot_archive_period snapshot_archive_smartengine_backup_checkpoint snapshot_archive_smartengine_tar_mode table_on_objectstore wesql_version New Status Com_show_consensuslogs Com_raft_replication_start Com_raft_replication_stop Com_native_admin_proc Com_native_trans_proc Com_show_consensuslog_events Smartengine_block_cache_miss Smartengine_block_cache_hit Smartengine_block_cache_add Smartengine_block_cache_index_miss Smartengine_block_cache_index_hit Smartengine_block_cache_filter_miss Smartengine_block_cache_filter_hit Smartengine_block_cache_data_miss Smartengine_block_cache_data_hit Smartengine_row_cache_add Smartengine_row_cache_hit Smartengine_row_cache_miss Smartengine_memtable_hit Smartengine_memtable_miss Smartengine_number_keys_written Smartengine_number_keys_read Smartengine_number_keys_updated Smartengine_bytes_written Smartengine_bytes_read Smartengine_block_cachecompressed_miss Smartengine_block_cachecompressed_hit Smartengine_wal_synced Smartengine_wal_bytes Smartengine_write_self Smartengine_write_other Smartengine_write_wal Smartengine_number_superversion_acquires Smartengine_number_superversion_releases Smartengine_number_superversion_cleanups Smartengine_number_block_not_compressed Smartengine_snapshot_conflict_errors Smartengine_wal_group_syncs Smartengine_rows_deleted Smartengine_rows_inserted Smartengine_rows_updated Smartengine_rows_read Smartengine_system_rows_deleted Smartengine_system_rows_inserted Smartengine_system_rows_updated Smartengine_system_rows_read Smartengine_max_level0_layers Smartengine_max_imm_numbers Smartengine_max_level0_fragmentation_rate Smartengine_max_level1_fragmentation_rate Smartengine_max_level2_fragmentation_rate Smartengine_max_level0_delete_percent Smartengine_max_level1_delete_percent Smartengine_max_level2_delete_percent Smartengine_all_flush_megabytes Smartengine_all_compaction_megabytes Smartengine_top1_subtable_size Smartengine_top2_subtable_size Smartengine_top3_subtable_size Smartengine_top1_mod_mem_info Smartengine_top2_mod_mem_info Smartengine_top3_mod_mem_info Smartengine_global_external_fragmentation_rate Smartengine_write_transaction_count Smartengine_pipeline_group_count Smartengine_pipeline_group_wait_timeout_count Smartengine_pipeline_copy_log_size Smartengine_pipeline_copy_log_count Smartengine_pipeline_flush_log_size Smartengine_pipeline_flush_log_count Smartengine_pipeline_flush_log_sync_count Smartengine_pipeline_flush_log_not_sync_count

  • Dolphie – “Rerecord not fadeaway”
    After installing & configuring Dolphie, let’s take a look into how we can “re-record not fadeaway” and avoid using a VHS tape. One of the coolest features is being able to go back in time with Dolphie and analyze what was happening at a specific moment. This feature requires recording so we can replay. Setting Dolphie up for recording mode. I’m really just going to share the links to the the github site and organize my steps so someone else might want to rinse’n’repeat or “replay”. I’m just a mere messenger. It works via the Daemon mode. Let’s set up out dolphie service for systemd: vi /etc/systemd/system/dolphie.service [Unit] Description=Dolphie Daemon Service After=mysqld.service [Service] User=root ExecStart=/usr/local/bin/dolphie --config-file /etc/dolphie_daemon.cnf StandardOutput=journal StandardError=journal Environment=PYTHONUNBUFFERED=1 Restart=on-failure [Install] WantedBy=multi-user.target I added the following, ‘cos I’m like that (and because I installed jemalloc): systemctl edit dolphie [Service]LimitNOFILE=infinityLimitMEMLOCK=infinityLimitNPROC=infinityEnvironment="LD_PRELOAD=/usr/lib64/libjemalloc.so.2" “Ah.. but I don’t have a /etc/dolphie_daemon.cnf” I hear you cry… I can share mine. Doesn’t mean it’s the best one, but it works. In my previous post I used one with different a different [dolphie] section. This is what my section of dolphie_daemon.cnf looks like: [dolphie] login_path=icadmin host=db-01 startup_panels=dashboard,processlist,graphs show_additional_query_columns=TRUE refresh-interval="2" record=TRUE record_for_replay=TRUE daemon_mode=TRUE daemon_mode_log_file=/var/log/dolphie/dolphie_daemon.log replay_dir=/var/log/dolphie/replay Make sure all directories exist: mkdir -p /var/log/dolphie/replay/ Make sure it starts up when the server starts: systemctl enable dolphie Start it up!: systemctl start dolphie And check the status: ● dolphie.service - Dolphie Daemon Service Loaded: loaded (/etc/systemd/system/dolphie.service; enabled; vendor preset: disabled) Drop-In: /etc/systemd/system/dolphie.service.d └─override.conf Active: active (running) since Tue 2024-11-19 15:39:49 UTC; 54min ago Main PID: 2762053 (dolphie) Tasks: 2 (limit: 203648) Memory: 259.7M CGroup: /system.slice/dolphie.service └─2762053 /usr/bin/python3.9 /usr/local/bin/dolphie --config-file /etc/dolphie_daemon.cnf Nov 19 15:39:49 db01 systemd[1]: Started Dolphie Daemon Service. Nov 19 15:39:49 db01 dolphie[2762053]: 11-19-2024 15:39:49 [INFO] Starting Dolphie v6.5.3 in daemon mode with a refresh interval of 1s Nov 19 15:39:49 db01 dolphie[2762053]: 11-19-2024 15:39:49 [INFO] Log file: /var/log/dolphie/dolphie_daemon.log Nov 19 15:39:50 db01 dolphie[2762053]: 11-19-2024 15:39:50 [INFO] Connected to MySQL with Process ID 1049107 Nov 19 15:39:55 db01 dolphie[2762053]: 11-19-2024 15:39:55 [INFO] Replay SQLite file: /var/log/dolphie/replay/db01_3306/daemon.db (48 hours retention) Nov 19 15:39:55 db01 dolphie[2762053]: 11-19-2024 15:39:55 [INFO] Created new SQLite database and connected to it Nov 19 15:41:10 db01 dolphie[2762053]: 11-19-2024 15:41:10 [INFO] ZSTD compression dictionary trained with 10 samples (size: 52.14KB) Check the daemon log, as per our configuration: tail /var/log/dolphie/dolphie_daemon.log 11-19-2024 15:39:11 [INFO] Replay SQLite file: /var/log/dolphie/replay/db01_3306/daemon.db (48 hours retention) 11-19-2024 15:39:11 [INFO] Connected to SQLite 11-19-2024 15:39:11 [INFO] Replay database metadata - Host: db01, Port: 3306, Source: MySQL, Dolphie: 6.5.3 11-19-2024 15:39:11 [INFO] ZSTD compression dictionary loaded (size: 52.79KB) 11-19-2024 15:39:49 [INFO] Starting Dolphie v6.5.3 in daemon mode with a refresh interval of 1s 11-19-2024 15:39:49 [INFO] Log file: /var/log/dolphie/dolphie_daemon.log 11-19-2024 15:39:50 [INFO] Connected to MySQL with Process ID 1049107 11-19-2024 15:39:55 [INFO] Replay SQLite file: /var/log/dolphie/replay/db01_3306/daemon.db (48 hours retention) 11-19-2024 15:39:55 [INFO] Created new SQLite database and connected to it 11-19-2024 15:41:10 [INFO] ZSTD compression dictionary trained with 10 samples (size: 52.14KB) Ok, not we’ve got dolphie recording. How can we view the data and what can I do with it? As I want to avoid using the default config file (/etc/dolphie.cnf) I’m going to avoid it completely and force the replay-file on it: dolphie --config-file=/dev/null --replay-file=/var/log/dolphie/replay/db01_3306/daemon.db And there we have it: And we can interact with Dolphie too. Pause: And given we could be looking for an event or trying to find out what happened at a certain time, we can use “Seek“: And enter the time we’ll be looking for. And then play with the graphs: Isn’t that easy? Enjoy! PS/ Overlooked by myself so thanks for the reminder Charles, use the ` key to pull up the Tab Setup window so you can replay the recording you desire. This may deem a little stange on non-English keyboards as the key stroke is <`> + <space> on my spanish keyboard… But it helps not having to exit out and use the CLI. (Make sure you’ve specified the replay_dir in your dolphie.cnf).

  • Database Security: Best Practices to Protect Your MySQL Infrastructure
    As of 2024, MySQL ranks as the second most popular database management system globally. MySQL has become a go-to choice for database management due to its dependable performance, stability, and open-source licensing. However, its popularity also brings significant security challenges like SQL injection attacks and unauthorized data access. As cyber threats evolve, protecting MySQL infrastructure is more critical than ever. Advanced tools like ProxySQL are vital for addressing these issues. ProxySQL is a high-performance, open-source SQL proxy tailored for MySQL and other database systems sharing the same protocol. It optimizes database traffic by managing queries more efficiently and enhancing performance and security by supporting configurations that help prevent unauthorized access. Common MySQL Security Threats Understanding and mitigating common security threats is essential for maintaining the integrity and availability of your MySQL database. Here are five notable threats to be aware of: SQL Injection One of the most prevalent and dangerous threats is SQL injection, which occurs when an attacker manipulates SQL queries by injecting malicious code through application inputs. This can lead to unauthorized data access, manipulation, and, in severe cases, command execution on the database server. Brute Force Attacks Attackers use brute force to crack weak database credentials, gaining unauthorized access. Such attacks often exploit simple or default passwords, underscoring the importance of strong, complex passwords and account lockout policies. Denial of Service (DoS) By overwhelming the database with excessive requests, attackers can render the database services unavailable to legitimate users, disrupting operations and potentially leading to data loss. Data Leaks Improperly configured databases or weak access controls can lead to data leaks, exposing sensitive information publicly or to unauthorized parties. This compromises data confidentiality and can have legal and reputational repercussions. Malware and Ransomware These malicious software programs can be installed on database servers through vulnerabilities, leading to data theft, database encryption, or total loss of database control. Ensuring your database and its operating environment are regularly updated and monitored is crucial to preventing malware infections. Best Practices to Protect Your MySQL Infrastructure 1. Keep MySQL Updated Failing to update your MySQL server exposes your infrastructure to known vulnerabilities and security breaches, which could lead to significant operational disruptions and data compromises. It is imperative to consistently upgrade to the latest MySQL version, as this process introduces essential security patches and performance enhancements. By staying updated, you proactively shield your database from evolving cyber threats, maintaining a strong defense and ensuring operational integrity. 2. Regular Backups Neglecting to perform backups can lead to irreversible data loss, severely impacting your business operations and data integrity. A consistent backup protocol is imperative to maintain your MySQL database’s resilience against data corruption, system failures, or other unforeseen events. Implement scheduled and manual backups to secure copies of your database at regular intervals, ensuring that you can restore your system to a functional state swiftly and efficiently in any contingency. 3. Encryption Unencrypted data is susceptible to unauthorized access and potential breaches, posing a severe risk to the confidentiality and integrity of sensitive information stored within your MySQL database. Employ encryption techniques to secure data at rest, effectively transforming sensitive data into unreadable formats that can only be deciphered with specific decryption keys. Implementing data encryption is a critical component of a comprehensive data protection strategy that ensures compliance with data protection regulations, shields against data breaches, and maintains trust by safeguarding information.  4. Data Encryption Protocols Beyond securing data at rest, it is equally important to protect data in transit to prevent interception and tampering as it moves across networks. Implement strong encryption protocols, such as TLS (Transport Layer Security), to create a secure channel for data exchange. This prevents potential attackers from capturing or altering sensitive information during transmission. Regularly update and configure your encryption settings to use only strong ciphers and to disable outdated protocols, ensuring that data communications meet current security standards and safeguard against the latest threats. 5. Secure MySQL Installation A standard MySQL installation comes with default settings that may not suit the specific security needs of your environment and could leave your database vulnerable to attacks. Customizing these settings during the initial setup is crucial to enhance security. Begin by altering default configurations such as passwords, user permissions, and network accessibility to minimize potential attack vectors. Additionally, disable any unused database features or services to reduce exposure further. By taking these steps at installation, you effectively fortify your database against unauthorized access and establish a strong foundation for ongoing database security management. 6. User Authentication Weak authentication practices can expose your MySQL database to unauthorized access, leading to data breaches and potential compliance violations. To mitigate these risks, implement stringent authentication mechanisms. This involves configuring MySQL to use strong, multifactor authentication that requires more than one form of verification, dramatically reducing the likelihood of unauthorized access. Consider integrating authentication protocols that combine something the user knows (a password), something the user has (a security token), and something the user is (biometric verification). Additionally, routinely audit and update authentication methods to close gaps as new security threats emerge. This diligent focus on authentication secures your database and reinforces your organization’s overall security posture. 7. Use Strong Passwords Simple or default passwords can easily be compromised, leaving your MySQL database vulnerable to brute-force attacks. Enforcing a complex password policy is essential for safeguarding access to your database. Require passwords that include a mix of upper- and lowercase letters, numbers, and special characters. Additionally, a minimum password length must be set, and regular password expiration must be implemented to compel users to change their credentials periodically. Educate users on the importance of using unique passwords for different systems and encourage the use of password managers to maintain the security of their credentials. This policy not only strengthens individual user security but also enhances the overall protection of your database infrastructure. 8. Access Control and Limited Access  Effective access control and adherence to the principle of least privilege are critical for securing your MySQL database. Establish role-based access controls (RBAC) to define and limit user permissions strictly to the necessities of their job functions. This minimizes the risk of unauthorized access and data breaches by ensuring that users can access only the data essential for their roles. Neglecting these measures can lead to overprivileged accounts, and prime exploitation targets. This could lead to significant security incidents, compliance violations, and reputational harm. To maintain a secure and compliant database environment, regularly review and adjust permissions in line with changes in user roles and responsibilities. 9. Monitor Database Activity Continuous database activity monitoring is imperative to identify and address unauthorized or anomalous transactions that could indicate a security breach. Implement comprehensive logging of all database actions, including data access, alterations, and failed login attempts. Utilize advanced monitoring tools that employ real-time analytics to alert administrators to unusual activity patterns, such as unexpected access times, high data retrieval volumes, or changes from unrecognized IP addresses. The absence of diligent monitoring can lead to delayed detection of security incidents, allowing malicious actors to exploit data unnoticed. This can cause extensive damage to data integrity and organizational reputation. Regular audits of log files and prompt investigation of alerts are crucial in maintaining your database’s security and operational integrity. 10. Conduct Security Tests Routine security assessments are crucial for maintaining the integrity of your MySQL database. Establish a program that includes penetration testing, vulnerability scans, and security audits to detect flaws in your database security proactively. These evaluations should mimic potential attack vectors to uncover configuration, software version, or access control weaknesses. Failure to conduct these tests can lead to undetected vulnerabilities, exposing your database to potential breaches. Regularly identifying and addressing security issues protects your data and ensures compliance with regulatory standards. 11. Use Firewalls Deploying firewalls is a fundamental security measure to protect your MySQL database from unauthorized access. Firewalls are a barrier between your database and potential threats, filtering incoming and outgoing network traffic based on predetermined security rules. Configure your firewalls to block unauthorized IP addresses, restrict access to certain ports, and effectively manage traffic to and from the database. Without adequate firewall protection, your database remains vulnerable to attacks such as SQL injections and unauthorized access attempts. Properly implemented firewalls help prevent these threats by ensuring that only legitimate and necessary communications reach your database, enhancing its overall security posture. 12. Separate Database Servers Isolating your MySQL database servers from other network segments is a critical strategy for minimizing the risk of cross-system breaches. By deploying database servers on dedicated hardware or within isolated virtual environments, you effectively shield sensitive data from attacks that might compromise less secure areas of your network. This separation limits the scope of potential security incidents and simplifies security management by confining database traffic to controlled pathways. Failure to segregate database servers can lead to widespread system vulnerabilities, where an attack on one part of the network can easily extend to the database. Implementing strict network segmentation ensures that your database’s integrity remains intact even if other segments are compromised, safeguarding against cascading security failures. 13. Disable Remote Logins Limiting remote logins to your MySQL database is a critical security measure to reduce potential access points for attackers. Disable remote login capabilities by default and enable them only when necessary and under stringent controls. When remote access is required, secure it with strong authentication methods and encrypted connections to mitigate the risk of unauthorized access. Enabling remote logins without appropriate security measures can expose your database to attacks such as brute force or credential theft. By restricting this capability, you effectively minimize the attack surface, reducing the likelihood of external breaches while maintaining controlled access for essential operations. 14. Obfuscate the Root Account Due to its extensive privileges, the default root account on your MySQL database is a prime target for attackers. To enhance security, it’s essential to obfuscate this account by renaming it and/or disabling its remote access. This practice makes it significantly more challenging for malicious actors to guess which account holds administrative privileges, reducing the risk of targeted attacks. Leaving the root account with default settings can give attackers a straightforward path to attempt unauthorized access, especially using brute force methods. By altering the root account’s visibility and access, you shield your database from direct threats aimed at exploiting this high-level administrative entry point. 15. Bind Database Server to Loopback Address Configure your MySQL database server to bind to the loopback address, ensuring it only accepts connections from the host machine. Restricting the server to internal communications significantly reduces the risk of external attacks. This configuration prevents the database from being accessible over the network, which is crucial for protecting sensitive data from remote exploits. Accessing the server from any network address can expose it to various security threats. Binding to the loopback address effectively blocks these threats, allowing only locally initiated interactions to maintain the security of your database environment. 16. Change Default Port Mappings Altering your MySQL database’s default port settings is a critical security tactic. Changing from standard port numbers to non-standard ones obscures your database from automated scans targeting commonly used ports. This simple change can significantly reduce the visibility of your database to potential attackers who use scanning tools to find exploitable services. Using default port numbers makes it easier for attackers to identify and target your database, as these are well-known and frequently checked. Customizing port configurations helps to cloak your database in obscurity, providing an additional hurdle for unauthorized access attempts. 17. Disable Local Infile in MySQL Leaving local infile enabled may provide an attack vector that could compromise the database and the broader server environment. Disabling MySQL’s local infile feature is an essential security action to prevent unauthorized data imports. This feature allows clients to upload local files to the server during their SQL session, which can be exploited to introduce malicious data or scripts into the database. By turning off the local infile, you close a significant vulnerability, enhancing the security of your database environment. 18. Disable Public Network Access Configuring your MySQL database to reject connections from public or unknown networks is a critical safeguard. This setting ensures that only trusted, private networks can access the database, significantly reducing the likelihood of exposure to external attacks. By limiting connectivity to known sources, you enhance the security of your data and reduce the potential for unauthorized access. Permitting public network access can leave your database vulnerable to various attacks, including unauthorized data access and denial of service (DoS) attacks. Ensuring that connections are only possible from secure, controlled networks, which minimizes these risks and helps maintain the integrity and availability of your database services. 19. Integrate ProxySQL for Enhanced Security and Performance Integrating ProxySQL as a database proxy for your MySQL servers can significantly enhance security and performance. ProxySQL acts as a middleware between your application and your databases, enabling you to implement fine-grained access control, query caching, and query routing without modifying application logic. By using ProxySQL, you can also enforce advanced security policies like blocking queries that do not meet your security standards and limiting user access based on rules that match specific query patterns. Implementing ProxySQL helps mitigate risks by providing an additional layer of abstraction, which can protect your databases from direct exposure to the internet and reduce the risk of SQL injection attacks. Its ability to handle thousands of connections and multiplex them to MySQL servers improves database performance and scalability. Enhance Your MySQL Security with ProxySQL As cyber threats become more sophisticated, safeguarding your MySQL database is more crucial than ever. ProxySQL offers a powerful solution that enhances security and performance through intelligent query management. With ProxySQL, you get: Detailed Access Control: Tailor database access with precision, significantly reducing risks like SQL injection. Efficient Query Routing: Direct queries to the most appropriate servers, balancing loads and minimizing server stress. Scalability: Smoothly handle an increase in connections, allowing your system to expand without sacrificing performance. Integrating ProxySQL can boost your MySQL setup. Its advanced features secure your data and enhance query response times, ensuring your database system remains efficient under increased demands. Are you ready to upgrade your database capabilities? Begin the journey to a more secure and efficient database environment today. Contact us today! The post Database Security: Best Practices to Protect Your MySQL Infrastructure appeared first on ProxySQL.