|
| 1 | +# Production readiness and baseline configuration |
| 2 | + |
| 3 | +Prepare each production host after you install Percona Server for MySQL. |
| 4 | + |
| 5 | +Use these values as a baseline. Test each value with a representative workload. Change one value at a time. |
| 6 | + |
| 7 | +!!! important |
| 8 | + |
| 9 | + Test this configuration in a test environment before production use. |
| 10 | + |
| 11 | + Memory, storage latency, concurrency, durability, and replication affect the correct values. |
| 12 | + |
| 13 | +## Day-1 checklist |
| 14 | + |
| 15 | +### Storage |
| 16 | + |
| 17 | +* Place data files, redo logs, binary logs, and temporary files on storage with predictable latency. |
| 18 | + |
| 19 | +* Confirm that the Linux file system supports direct input/output (I/O). |
| 20 | + |
| 21 | +* Monitor free space for each data directory and log directory. |
| 22 | + |
| 23 | +* Store backups outside the database host. |
| 24 | + |
| 25 | +* Test a restore from the backup. |
| 26 | + |
| 27 | +MySQL 8.4 uses `O_DIRECT` for `innodb_flush_method` when Linux supports the option. MySQL uses `fsync` as the fallback. |
| 28 | + |
| 29 | +Check the active flush method: |
| 30 | + |
| 31 | +```sql |
| 32 | +SHOW VARIABLES LIKE 'innodb_flush_method'; |
| 33 | +``` |
| 34 | + |
| 35 | +??? example "Expected output" |
| 36 | + |
| 37 | + ```{.text .no-copy} |
| 38 | + +---------------------+----------+ |
| 39 | + | Variable_name | Value | |
| 40 | + +---------------------+----------+ |
| 41 | + | innodb_flush_method | O_DIRECT | |
| 42 | + +---------------------+----------+ |
| 43 | + ``` |
| 44 | + |
| 45 | + MySQL returns `fsync` when the Linux file system lacks direct I/O support. |
| 46 | + |
| 47 | +### Memory |
| 48 | + |
| 49 | +* Set `innodb_buffer_pool_size` to 60–70% of physical random-access memory (RAM) on a dedicated database host. |
| 50 | + |
| 51 | +* Use a lower percentage when MySQL shares the host with other services. |
| 52 | + |
| 53 | +* Reserve memory for the operating system, Performance Schema, connections, temporary tables, sorts, replication, and backup tools. |
| 54 | + |
| 55 | +* Test the highest expected connection count. |
| 56 | + |
| 57 | +* Monitor swap use, resident memory, buffer pool hit rate, and temporary table use. |
| 58 | + |
| 59 | +Connection buffers use memory only when a connection needs each buffer. Actual use depends on workload concurrency. |
| 60 | + |
| 61 | +### Connections |
| 62 | + |
| 63 | +* Add all application connection pool limits. |
| 64 | + |
| 65 | +* Add connections for administration and metrics collection. |
| 66 | + |
| 67 | +* Add a small margin for failures. |
| 68 | + |
| 69 | +* Use the result for `max_connections`. |
| 70 | + |
| 71 | +* Set limits on application connection pools. |
| 72 | + |
| 73 | +* Queue or reject excess application work before MySQL reaches capacity. |
| 74 | + |
| 75 | +* Reserve access for database administrators. |
| 76 | + |
| 77 | +* Create an alert for high connection use. |
| 78 | + |
| 79 | +Use the default one-thread-per-connection model for most workloads. Consider the Percona thread pool after tests show a high-concurrency requirement. The thread pool usually offers little benefit below 20,000 connections. |
| 80 | + |
| 81 | +Check active, peak, and maximum connection values: |
| 82 | + |
| 83 | +```sql |
| 84 | +SHOW GLOBAL STATUS WHERE Variable_name IN ('Threads_connected', 'Max_used_connections'); |
| 85 | +SHOW VARIABLES LIKE 'max_connections'; |
| 86 | +``` |
| 87 | + |
| 88 | +??? example "Expected output" |
| 89 | + |
| 90 | + ```{.text .no-copy} |
| 91 | + +----------------------+-------+ |
| 92 | + | Variable_name | Value | |
| 93 | + +----------------------+-------+ |
| 94 | + | Max_used_connections | 84 | |
| 95 | + | Threads_connected | 32 | |
| 96 | + +----------------------+-------+ |
| 97 | + |
| 98 | + +-----------------+-------+ |
| 99 | + | Variable_name | Value | |
| 100 | + +-----------------+-------+ |
| 101 | + | max_connections | 200 | |
| 102 | + +-----------------+-------+ |
| 103 | + ``` |
| 104 | + |
| 105 | + The connection values depend on the workload. `Max_used_connections` must remain below `max_connections`. |
| 106 | + |
| 107 | +### Logs and observability |
| 108 | + |
| 109 | +* Collect, retain, and monitor the error log. |
| 110 | + |
| 111 | +* Enable the slow query log with a cautious threshold. |
| 112 | + |
| 113 | +* Adjust the threshold and sample rate after you measure log volume. |
| 114 | + |
| 115 | +* Use `log_output=FILE` when Percona Monitoring and Management (PMM) Query Analytics reads the slow query log. |
| 116 | + |
| 117 | +* Define retention and rotation for error, slow, binary, and audit logs. |
| 118 | + |
| 119 | +* Create alerts for availability, disk space, replication lag, connection pressure, and resource saturation. |
| 120 | + |
| 121 | +Logs can use substantial I/O capacity and disk space. |
| 122 | + |
| 123 | +## Recommended production `my.cnf` baseline |
| 124 | + |
| 125 | +Configure a dedicated MySQL host as follows: |
| 126 | + |
| 127 | +* Run a Linux operating system. |
| 128 | + |
| 129 | +* Allocate 16 GiB of RAM. |
| 130 | + |
| 131 | +* Use a solid-state drive (SSD) or Non-Volatile Memory Express (NVMe) storage device. |
| 132 | + |
| 133 | +Replace each value marked `CHANGE` before deployment. |
| 134 | + |
| 135 | +Package installs often load extra configuration files from `/etc/mysql/conf.d/` or `/etc/my.cnf.d/`. Use the path for your operating system. |
| 136 | + |
| 137 | +```ini |
| 138 | +[mysqld] |
| 139 | + |
| 140 | +# Memory |
| 141 | +# CHANGE: Use 60-70% of RAM on a dedicated database host. |
| 142 | +# 11G is about 70% of the RAM on a 16 GiB host. |
| 143 | +innodb_buffer_pool_size = 11G |
| 144 | + |
| 145 | +# Connections |
| 146 | +# CHANGE: Add application pool limits, metrics collection, and an administrative margin. |
| 147 | +max_connections = 200 |
| 148 | + |
| 149 | +# Storage and durability |
| 150 | +# MySQL 8.4 selects O_DIRECT on supported Linux systems. |
| 151 | +# Set this value only after you validate the file system and storage. |
| 152 | +# innodb_flush_method = O_DIRECT |
| 153 | +innodb_flush_log_at_trx_commit = 1 |
| 154 | +sync_binlog = 1 |
| 155 | + |
| 156 | +# Logs |
| 157 | +log_output = FILE |
| 158 | +slow_query_log = ON |
| 159 | +long_query_time = 1 |
| 160 | +log_slow_verbosity = standard |
| 161 | + |
| 162 | +# Keep binary logs for point-in-time recovery and replication. |
| 163 | +# CHANGE: Choose a retention period from the backup and recovery policy. |
| 164 | +binlog_expire_logs_seconds = 604800 |
| 165 | +``` |
| 166 | + |
| 167 | +??? example "Expected result" |
| 168 | + |
| 169 | + The configuration file contains one `[mysqld]` section with the selected production values. |
| 170 | + |
| 171 | +The durability values protect committed transactions during an operating system or host failure. |
| 172 | + |
| 173 | +Lower values for `innodb_flush_log_at_trx_commit` or `sync_binlog` can increase throughput. This change can also create a documented data loss period. |
| 174 | + |
| 175 | +Complete these steps before you restart the server: |
| 176 | + |
| 177 | +1. Save a copy of the active configuration. |
| 178 | + |
| 179 | +2. Replace the memory, connection, and retention values. |
| 180 | + |
| 181 | +3. Validate the configuration: |
| 182 | + |
| 183 | + ```shell |
| 184 | + mysqld --validate-config |
| 185 | + ``` |
| 186 | + |
| 187 | + ??? example "Expected output" |
| 188 | + |
| 189 | + A valid configuration produces no output. The command returns exit status zero. |
| 190 | + |
| 191 | +4. Restart MySQL during a maintenance period. |
| 192 | + |
| 193 | +5. Check the service state and error log. |
| 194 | + |
| 195 | +6. Confirm the active values: |
| 196 | + |
| 197 | + ```sql |
| 198 | + SHOW VARIABLES WHERE Variable_name IN ( |
| 199 | + 'binlog_expire_logs_seconds', |
| 200 | + 'innodb_buffer_pool_size', |
| 201 | + 'innodb_flush_log_at_trx_commit', |
| 202 | + 'innodb_flush_method', |
| 203 | + 'log_output', |
| 204 | + 'log_slow_verbosity', |
| 205 | + 'long_query_time', |
| 206 | + 'max_connections', |
| 207 | + 'slow_query_log', |
| 208 | + 'sync_binlog' |
| 209 | + ); |
| 210 | + ``` |
| 211 | + |
| 212 | + ??? example "Expected output" |
| 213 | + |
| 214 | + ```{.text .no-copy} |
| 215 | + +------------------------------------+-------------+ |
| 216 | + | Variable_name | Value | |
| 217 | + +------------------------------------+-------------+ |
| 218 | + | binlog_expire_logs_seconds | 604800 | |
| 219 | + | innodb_buffer_pool_size | 11811160064 | |
| 220 | + | innodb_flush_log_at_trx_commit | 1 | |
| 221 | + | innodb_flush_method | O_DIRECT | |
| 222 | + | log_output | FILE | |
| 223 | + | log_slow_verbosity | standard | |
| 224 | + | long_query_time | 1.000000 | |
| 225 | + | max_connections | 200 | |
| 226 | + | slow_query_log | ON | |
| 227 | + | sync_binlog | 1 | |
| 228 | + +------------------------------------+-------------+ |
| 229 | + ``` |
| 230 | + |
| 231 | + MySQL can return `fsync` for `innodb_flush_method`. The value depends on direct I/O support. |
| 232 | + |
| 233 | +### MySQL 8.4 defaults |
| 234 | + |
| 235 | +Review each MySQL 8.0 override before you use the override with MySQL 8.4. |
| 236 | + |
| 237 | +MySQL 8.4 has the following defaults: |
| 238 | + |
| 239 | +* `innodb_adaptive_hash_index=OFF`. |
| 240 | + |
| 241 | +* `innodb_change_buffering=none`. |
| 242 | + |
| 243 | +* `innodb_flush_method=O_DIRECT` on supported Linux systems. MySQL uses `fsync` as the fallback. |
| 244 | + |
| 245 | +* `innodb_io_capacity=10000`. This value targets SSD and NVMe storage. Hard disk drives may require a lower value. |
| 246 | + |
| 247 | +* `innodb_log_buffer_size=64M`. |
| 248 | + |
| 249 | +* `innodb_numa_interleave=ON`. |
| 250 | + |
| 251 | +* `temptable_max_ram` uses 3% of total memory. The minimum value is 1 GiB. The maximum value is 4 GiB. |
| 252 | + |
| 253 | +Read [Defaults and tuning guidance for MySQL 8.4](8.4-defaults-and-tuning.md) for more details. |
| 254 | + |
| 255 | +## Percona feature quick-activation matrix |
| 256 | + |
| 257 | +Each command requires the related package or component library. Run Structured Query Language (SQL) commands with the required administrative privileges. |
| 258 | + |
| 259 | +Some features also require tables or policy definitions. Follow the linked procedure before activation. |
| 260 | + |
| 261 | +| Feature | Activation | Production requirement | |
| 262 | +|---|---|---| |
| 263 | +| Thread pool | Add `thread_handling=pool-of-threads` under `[mysqld]`. Restart MySQL. | Use the feature only after high-concurrency tests show a benefit. Read [Thread pool](threadpool.md). | |
| 264 | +| Audit Log Filter | Run `SET GLOBAL audit_log_filter.disable = false;` after component installation and filter assignment. | Complete the [Audit Log Filter installation](install-audit-log-filter.md) and [Audit Log Filter quickstart](audit-log-filter-quickstart.md). Define production filters and retention. | |
| 265 | +| Data Masking | Create `mysql.masking_dictionaries`. Run `INSTALL COMPONENT 'file://component_masking_functions';`. | Use views and privileges to restrict access to unmasked data. Read [Install the data masking component](install-data-masking-component.md). | |
| 266 | +| Extended Slow Log | Add `slow_query_log=ON` and `log_slow_verbosity=standard` under `[mysqld]`. | Start with `long_query_time=1`. Measure log volume. Use `log_slow_rate_limit` when you need a sample. Read [Slow query log](slow-extended.md). | |
| 267 | + |
| 268 | +Verify each feature: |
| 269 | + |
| 270 | +```sql |
| 271 | +SHOW VARIABLES LIKE 'thread_handling'; |
| 272 | +SHOW GLOBAL STATUS LIKE 'audit_log_filter_events_written'; |
| 273 | +SELECT * FROM mysql.component |
| 274 | +WHERE component_urn = 'file://component_masking_functions'; |
| 275 | +SHOW VARIABLES WHERE Variable_name IN ( |
| 276 | + 'slow_query_log', |
| 277 | + 'log_slow_verbosity', |
| 278 | + 'long_query_time' |
| 279 | +); |
| 280 | +``` |
| 281 | + |
| 282 | +??? example "Expected output" |
| 283 | + |
| 284 | + ```{.text .no-copy} |
| 285 | + +-----------------+-----------------+ |
| 286 | + | Variable_name | Value | |
| 287 | + +-----------------+-----------------+ |
| 288 | + | thread_handling | pool-of-threads | |
| 289 | + +-----------------+-----------------+ |
| 290 | +
|
| 291 | + +---------------------------------+-------+ |
| 292 | + | Variable_name | Value | |
| 293 | + +---------------------------------+-------+ |
| 294 | + | audit_log_filter_events_written | 42 | |
| 295 | + +---------------------------------+-------+ |
| 296 | +
|
| 297 | + +--------------+--------------------+------------------------------------+ |
| 298 | + | component_id | component_group_id | component_urn | |
| 299 | + +--------------+--------------------+------------------------------------+ |
| 300 | + | 2 | 2 | file://component_masking_functions | |
| 301 | + +--------------+--------------------+------------------------------------+ |
| 302 | +
|
| 303 | + +--------------------+----------+ |
| 304 | + | Variable_name | Value | |
| 305 | + +--------------------+----------+ |
| 306 | + | log_slow_verbosity | standard | |
| 307 | + | long_query_time | 1.000000 | |
| 308 | + | slow_query_log | ON | |
| 309 | + +--------------------+----------+ |
| 310 | + ``` |
| 311 | + |
| 312 | + Event counts and component identifiers depend on the server. |
0 commit comments