Azure Database for MySQL Flexible Server: HA and Performance Design

MySQL remains the database under a staggering share of the web, and Azure MySQL Flexible Server is its managed home on Azure. The shape mirrors yesterday’s PostgreSQL post, same tiers, same VNet options, same HA model, so today I will move faster on the shared ground and slower on what is MySQL specific.

The Shared Foundation, Quickly

Burstable for dev, General Purpose for most production, Business Critical for latency sensitive or high concurrency workloads. Delegated subnet or private endpoint networking, public access off, Entra authentication on. Zone redundant HA gives a synchronous standby in a second zone with automatic failover; same zone HA exists for regions without zones or workloads that want local standby without cross zone write latency. Autogrow on, 35 day backups with geo redundancy, maintenance window pinned to your quietest hour. All the arguments from yesterday transfer directly.

resource "azurerm_mysql_flexible_server" "this" {
  name                         = "mysql-shop-prod"
  resource_group_name          = azurerm_resource_group.data.name
  location                     = "westeurope"
  version                      = "8.0.21"
  sku_name                     = "GP_Standard_D4ds_v4"
  delegated_subnet_id          = azurerm_subnet.mysql.id
  private_dns_zone_id          = azurerm_private_dns_zone.mysql.id
  backup_retention_days        = 35
  geo_redundant_backup_enabled = true
  zone                         = "1"

  storage {
    size_gb           = 256
    auto_grow_enabled = true
    iops              = 2000
    log_on_disk_enabled = true
  }

  high_availability {
    mode                      = "ZoneRedundant"
    standby_availability_zone = "2"
  }
}

resource "azurerm_mysql_flexible_server_configuration" "slow_log" {
  name                = "slow_query_log"
  resource_group_name = azurerm_resource_group.data.name
  server_name         = azurerm_mysql_flexible_server.this.name
  value               = "ON"
}

resource "azurerm_mysql_flexible_server_configuration" "long_query" {
  name                = "long_query_time"
  resource_group_name = azurerm_resource_group.data.name
  server_name         = azurerm_mysql_flexible_server.this.name
  value               = "0.5"
}

MySQL Specific Performance Levers

InnoDB buffer pool size is the parameter that matters most and it is preset per SKU, which is the hidden reason scaling up often fixes performance: you bought buffer pool. Before scaling, check the hit rate; if reads are missing the pool and the working set genuinely exceeds memory, scale, otherwise fix the queries. The accelerated logs feature on Business Critical (log_on_disk settings vary by tier) moves redo logging to faster storage and measurably lifts write throughput for commit heavy workloads, effectively free performance, enable it where offered. Connection handling differs from Postgres in a friendly way, MySQL threads are cheaper than Postgres processes, but the ecosystem habit of enormous application pool sizes still bites; size pools to what the server tier supports and let queueing happen in the app, not as max_connections errors. And temporary table spill to disk is the classic silent killer for reporting queries, watch created_tmp_disk_tables and raise tmp_table_size and max_heap_table_size judiciously when sorted or grouped result sets exceed memory.

Replicas, GTID, and the Upgrade Path

Read replicas (up to ten, async, in region or cross region) carry the usual uses: read scaling, reporting isolation, and DR by promotion. GTID based replication underpins them, which pays off in clean promotion semantics, and replica lag is your metric to alert on, lag during business hours usually traces to large transactions or missing indexes on the replica applied workload. For DR, a cross region replica plus a rehearsed promotion runbook is the standard pattern, and after promotion your application config flip should be DNS or App Configuration driven rather than a redeploy. Version upgrades: 5.7 to 8.0 was the industry’s great migration and if any 5.7 still lurks in your estate, it is running on borrowed time everywhere, not just Azure; test with a replica upgraded ahead of the primary. Slow query log to Log Analytics, weekly review of the top offenders, same discipline as yesterday, because databases reward routines more than heroics.

Cheers
Osama

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.