Home DevOps Microsoft Azure — Database for MySQL & PostgreSQL
Intermediate 6 min · July 12, 2026

Microsoft Azure — Database for MySQL & PostgreSQL

Azure Database for MySQL and PostgreSQL, scale, high availability, read replicas, and backup..

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Notes here come from systems that actually shipped.

Follow
Verified
production tested
July 12, 2026
last updated
436
articles · all by Naren
Before you start⏱ 25 min
  • Azure subscription, Azure CLI 2.50+, Terraform 1.5+ or Bicep 0.20+, basic knowledge of SQL and database concepts, familiarity with Azure portal and resource groups.
✦ Definition~90s read
What is Microsoft Azure?

Microsoft Azure — Database for MySQL & PostgreSQL is a core Azure service that handles mysql postgresql in the Microsoft cloud ecosystem.

Database for MySQL & PostgreSQL is like having a specialized tool that handles mysql postgresql in the Microsoft cloud — you manage the configuration, Azure handles the infrastructure.
Plain-English First

Database for MySQL & PostgreSQL is like having a specialized tool that handles mysql postgresql in the Microsoft cloud — you manage the configuration, Azure handles the infrastructure.

Azure is Microsoft's cloud computing platform offering over 200 services. This article covers database for mysql & postgresql with production-ready configurations, best practices, and hands-on examples.

Choosing Between Azure Database for MySQL and PostgreSQL

Azure offers managed database services for both MySQL and PostgreSQL, but the choice between them should be driven by workload requirements, not familiarity. MySQL excels in read-heavy workloads, simple replication, and compatibility with legacy applications. PostgreSQL shines in complex queries, JSONB support, and advanced indexing like GIN and GiST. For production, consider your data integrity needs: PostgreSQL's MVCC and full ACID compliance make it better for financial systems, while MySQL's InnoDB engine is sufficient for most web apps. Both support high availability with zone-redundant deployment, but PostgreSQL's logical replication offers more flexibility for zero-downtime upgrades. Benchmark with your actual query patterns—don't assume one is faster. Use Azure's pricing calculator to compare vCore-based tiers; General Purpose is the default for production, but Memory Optimized may be needed for analytical workloads. Avoid the temptation to use the Basic tier in production—it lacks SLA and features like read replicas.

choose-tier.shBASH
1
2
3
4
5
6
7
8
9
10
az mysql flexible-server create \
  --resource-group prod-rg \
  --name prod-mysql \
  --sku-name Standard_D4ds_v4 \
  --tier GeneralPurpose \
  --storage-size 128 \
  --backup-retention 7 \
  --high-availability ZoneRedundant \
  --admin-user dbadmin \
  --admin-password 'Str0ng!Pass'
Output
{
"id": "/subscriptions/.../servers/prod-mysql",
"name": "prod-mysql",
"sku": {
"name": "Standard_D4ds_v4",
"tier": "GeneralPurpose"
},
"storage": {
"storageSizeGB": 128
},
"highAvailability": "ZoneRedundant"
}
⚠ Don't use Basic tier in production
The Basic tier lacks an SLA, no zone redundancy, and no read replicas. It's for development only. Always use General Purpose or Memory Optimized for production workloads.
📊 Production Insight
We once migrated a financial reporting system from MySQL to PostgreSQL because MySQL's GROUP BY with non-aggregated columns caused silent data truncation. PostgreSQL's strict SQL compliance caught the issue.
🎯 Key Takeaway
Choose MySQL for read-heavy web apps; PostgreSQL for complex queries and data integrity.
azure-mysql-postgresql THECODEFORGE.IO Provisioning Azure MySQL/PostgreSQL with IaC Step-by-step deployment using Terraform or Bicep Define Resource Group Set location and tags for organization Configure Server Parameters SKU, storage, backup retention, version Set Network Security Private endpoint or firewall rules Enable High Availability Zone-redundant or same-zone standby Deploy with CI/CD Pipeline Validate and apply via GitHub Actions Monitor and Audit Enable diagnostic logs and alerts ⚠ Forgetting to set backup retention period Always define backup_retention_days >= 7 THECODEFORGE.IO
thecodeforge.io
Azure Mysql Postgresql

Provisioning with Infrastructure as Code

Manual provisioning via portal is a recipe for drift. Use Terraform or Bicep to define your Azure Database for MySQL/PostgreSQL as code. This ensures repeatability, version control, and auditability. For Terraform, use the azurerm_mysql_flexible_server or azurerm_postgresql_flexible_server resources. Pin the provider version and use remote state with locking. Key parameters: sku_name (e.g., GP_Standard_D4ds_v4), storage_mb, backup_retention_days, and geo_redundant_backup_enabled. Enable delegated_subnet_id for private access—never expose to public internet. Use administrator_login and administrator_password from a key vault reference, not plain text. For PostgreSQL, set version to 14 or 15 (avoid 11, which is EOL). Add a azurerm_private_endpoint for secure connectivity. Store the connection string in Azure Key Vault and reference it in App Service settings via @Microsoft.KeyVault() syntax.

main.tfHCL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
resource "azurerm_resource_group" "rg" {
  name     = "prod-db-rg"
  location = "eastus"
}

resource "azurerm_postgresql_flexible_server" "pg" {
  name                   = "prod-pg"
  resource_group_name    = azurerm_resource_group.rg.name
  location               = azurerm_resource_group.rg.location
  version                = "15"
  delegated_subnet_id    = azurerm_subnet.db.id
  private_dns_zone_id    = azurerm_private_dns_zone.pg.id
  administrator_login    = "dbadmin"
  administrator_password = data.azurerm_key_vault_secret.db_password.value
  storage_mb             = 262144
  sku_name               = "GP_Standard_D4ds_v4"
  backup_retention_days  = 7
  geo_redundant_backup_enabled = true

  high_availability {
    mode = "ZoneRedundant"
  }
}
Output
azurerm_postgresql_flexible_server.pg: Creation complete after 5m32s [id=/subscriptions/.../servers/prod-pg]
💡Use private endpoints for security
Never enable public access on production databases. Use VNet integration and private endpoints. This prevents exposure to the internet and reduces attack surface.
📊 Production Insight
A team once manually changed the PostgreSQL version in the portal, causing Terraform to detect drift and attempt a destructive update. Always use IaC and lock changes via policy.
🎯 Key Takeaway
Provision databases with Terraform/Bicep to ensure repeatability and avoid configuration drift.

Configuring High Availability and Disaster Recovery

Azure's flexible server offers zone-redundant HA with automatic failover. This replicates data synchronously to a standby in a different availability zone. Failover is automatic and typically completes within 60-120 seconds. For cross-region DR, enable geo-redundant backup (stored in paired region) and configure read replicas in another region. For PostgreSQL, use logical replication to create a cross-region replica for near-sync DR. For MySQL, use the built-in read replica feature (asynchronous). Test failover regularly—schedule a quarterly game day where you simulate a zone outage. Monitor replication lag using Azure Monitor metrics: Replication Lag for MySQL, pg_replication_slots for PostgreSQL. Set alerts for lag > 30 seconds. For zero data loss, consider Azure's Zone-Redundant HA with synchronous commit; but be aware of latency impact (typically 1-2ms). Never rely solely on backups for DR—restore times can be hours for large databases.

check-replication-lag.sqlSQL
1
2
3
4
5
6
7
8
9
-- PostgreSQL: Check replication lag in seconds
SELECT
  pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes,
  EXTRACT(EPOCH FROM (now() - pg_last_xact_replay_timestamp())) AS lag_seconds
FROM pg_stat_replication;

-- MySQL: Check replication lag
SHOW SLAVE STATUS\G
-- Look for Seconds_Behind_Master
Output
lag_bytes | lag_seconds
-----------+-------------
123456 | 2.5
(1 row)
🔥Test failover quarterly
Don't assume HA works until you've tested it. Use Azure's forced failover API to simulate a zone outage. Verify application reconnects without manual intervention.
📊 Production Insight
During a real zone outage, our PostgreSQL failover took 90 seconds, but the application connection pool didn't refresh, causing 5 minutes of downtime. We now use a connection string with host=...&target_session_attrs=read-write and a short TTL.
🎯 Key Takeaway
Use zone-redundant HA for in-region resilience and geo-redundant backups for cross-region DR.
azure-mysql-postgresql THECODEFORGE.IO Azure Database for MySQL/PostgreSQL Architecture Layered stack for high availability and security Client Access Application | Azure CLI | pgAdmin/MySQL Workbench Network Security Private Endpoint | VNet Integration | Firewall Rules Database Service Flexible Server | Read Replicas | High Availability Standby Storage and Backup Managed Disks | Automated Backups | Geo-Redundant Storage Monitoring and Management Azure Monitor | Query Performance Insight | Alert Rules THECODEFORGE.IO
thecodeforge.io
Azure Mysql Postgresql

Performance Tuning: Indexing and Query Optimization

Performance starts with the schema. Use EXPLAIN ANALYZE to identify full table scans. For PostgreSQL, leverage partial indexes, covering indexes, and BRIN indexes for large tables. For MySQL, use composite indexes with the most selective column first. Avoid over-indexing—each index slows writes. Use Azure's Query Performance Insight to find expensive queries. Set work_mem (PostgreSQL) or tmp_table_size (MySQL) appropriately for your workload. For read-heavy apps, add read replicas and route read traffic to them. Use connection pooling with PgBouncer or ProxySQL to reduce connection overhead. Monitor buffer cache hit ratio—if below 99%, increase memory. For PostgreSQL, enable pg_stat_statements to track query performance. For MySQL, use Performance Schema. Set innodb_buffer_pool_size to 70-80% of available memory for MySQL. Avoid using SELECT * in production—always specify columns.

optimize-query.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- PostgreSQL: Find missing indexes
SELECT
  relname,
  seq_scan,
  seq_tup_read,
  idx_scan,
  seq_tup_read / seq_scan AS avg_rows_per_seq_scan
FROM pg_stat_user_tables
WHERE seq_scan > 1000
ORDER BY seq_tup_read DESC
LIMIT 10;

-- MySQL: Find slow queries
SELECT * FROM performance_schema.events_statements_summary_by_digest
WHERE SUM_TIMER_WAIT > 1000000000
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;
Output
relname | seq_scan | seq_tup_read | idx_scan | avg_rows_per_seq_scan
----------+----------+--------------+----------+----------------------
orders | 15000 | 15000000 | 2000 | 1000
(1 row)
💡Use partial indexes for filtered queries
If you frequently query WHERE status = 'active', create a partial index: CREATE INDEX idx_orders_active ON orders(status) WHERE status = 'active'. This saves space and speeds up writes.
📊 Production Insight
A missing index on a user_id column caused a query to scan 10M rows every second, maxing out CPU. We added a composite index and CPU dropped from 95% to 20%. Always monitor query performance in staging before production.
🎯 Key Takeaway
Use EXPLAIN ANALYZE and Query Performance Insight to identify and fix slow queries.

Security: Authentication, Authorization, and Encryption

Use Azure Active Directory (Azure AD) authentication for both MySQL and PostgreSQL. This eliminates password management and enables conditional access policies. For legacy apps, use password auth with strong rotation policies via Key Vault. Enable SSL/TLS enforcement—set require_secure_transport to ON for MySQL, and ssl to require for PostgreSQL. Use private endpoints and network security groups to restrict access. For data at rest, Azure Storage Service Encryption is enabled by default; use customer-managed keys (CMK) for compliance. For column-level encryption, use pgcrypto (PostgreSQL) or AES_ENCRYPT (MySQL). Implement row-level security (RLS) in PostgreSQL for multi-tenant apps. Audit all connections using Azure's audit logs. Set log_connections and log_disconnections to ON. Use Azure Policy to enforce TLS version 1.2 or higher. Never use the root user for application connections—create role-specific users with least privilege.

create-user.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
-- PostgreSQL: Create read-only user
CREATE ROLE app_readonly WITH LOGIN PASSWORD 'strong_password';
GRANT CONNECT ON DATABASE prod_db TO app_readonly;
GRANT USAGE ON SCHEMA public TO app_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO app_readonly;

-- MySQL: Create read-only user
CREATE USER 'app_readonly'@'%' IDENTIFIED BY 'strong_password';
GRANT SELECT ON prod_db.* TO 'app_readonly'@'%';
FLUSH PRIVILEGES;
Output
CREATE ROLE
GRANT
GRANT
ALTER DEFAULT PRIVILEGES
⚠ Never use root for app connections
Root has full privileges. If compromised, an attacker can drop databases. Always create application-specific users with minimal required permissions.
📊 Production Insight
A developer accidentally committed a connection string with root credentials to a public repo. Within hours, the database was compromised and data was exfiltrated. We now scan repos for secrets and enforce Azure AD auth.
🎯 Key Takeaway
Use Azure AD authentication, enforce TLS, and apply least privilege for all database users.

Backup and Restore Strategies

Azure automatically takes full backups weekly, differential daily, and transaction log backups every 5 minutes. Retention is configurable up to 35 days. For longer retention, use Azure Backup or export to blob storage. Always test restores—backups are useless if they can't be restored. Use point-in-time restore (PITR) to recover to any second within the retention period. For cross-region restore, enable geo-redundant backup. For large databases (>1TB), restore times can be hours; consider using read replicas for faster recovery. Automate backup validation with a script that restores to a temporary server and runs integrity checks. For PostgreSQL, use pg_restore with --jobs for parallel restore. For MySQL, use mysqlpump or mydumper. Monitor backup status via Azure Monitor alerts. Never rely solely on Azure's automated backups—export periodic logical backups to a different storage account for defense in depth.

restore-test.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
# Test PITR restore to a temporary server
RESTORE_TIME="2026-07-10T03:00:00Z"
az postgres flexible-server restore \
  --resource-group prod-rg \
  --name prod-pg-restore-test \
  --source-server prod-pg \
  --restore-time $RESTORE_TIME

# Run integrity checks
PGPASSWORD='temp_pass' psql -h prod-pg-restore-test.postgres.database.azure.com \
  -U dbadmin -d prod_db -c "SELECT count(*) FROM orders;"

# Clean up
az postgres flexible-server delete --resource-group prod-rg --name prod-pg-restore-test --yes
Output
Restore started...
Restore completed in 3m45s
count
-------
123456
(1 row)
🔥Test restores monthly
Schedule a monthly job that restores the latest backup to a temporary server and runs pg_checksums or mysqlcheck. This ensures backups are valid and restore procedures work.
📊 Production Insight
We discovered that our automated backups were failing silently for 3 days because the storage account was full. Now we monitor backup success metrics and set up alerts for any failures.
🎯 Key Takeaway
Automate backup validation with periodic restore tests to ensure recoverability.

Monitoring and Alerting with Azure Monitor

Use Azure Monitor to collect metrics and logs from your database. Key metrics: CPU percent, memory percent, storage percent, IOPS, connections, and replication lag. Set alerts for thresholds: CPU > 80% for 5 minutes, storage > 80%, connections > 90% of max. Enable diagnostic settings to stream logs to Log Analytics for query analysis. Use Azure Workbooks to create dashboards for at-a-glance health. For PostgreSQL, enable pg_stat_statements and log slow queries with log_min_duration_statement = 1000 (1 second). For MySQL, set slow_query_log = ON and long_query_time = 1. Use Azure's Intelligent Insights for proactive anomaly detection. Set up action groups to notify Slack, PagerDuty, or email. Monitor deadlocks—PostgreSQL logs them automatically; MySQL requires innodb_print_all_deadlocks = ON. Create a runbook for common alerts so on-call engineers know how to respond.

alert-rule.jsonJSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "name": "High CPU Alert",
  "description": "Alert when CPU > 80% for 5 minutes",
  "severity": 2,
  "condition": {
    "allOf": [
      {
        "field": "Percentage CPU",
        "operator": "GreaterThan",
        "threshold": 80,
        "timeAggregation": "Average",
        "windowSize": "PT5M"
      }
    ]
  },
  "actions": [
    {
      "actionGroupId": "/subscriptions/.../actionGroups/on-call"
    }
  ]
}
Output
Alert rule created successfully.
💡Use Intelligent Insights for anomaly detection
Azure's Intelligent Insights automatically detects unusual patterns like sudden query performance degradation or connection spikes. Enable it in the Azure portal for your database.
📊 Production Insight
We missed a storage full alert because it was set to 'Average' over 1 hour, which masked a rapid fill. Now we use 'Maximum' over 5 minutes for storage alerts.
🎯 Key Takeaway
Set up alerts on CPU, storage, connections, and replication lag; use Log Analytics for deep query analysis.

Scaling: Vertical and Horizontal Strategies

Azure allows vertical scaling (changing vCores and memory) with minimal downtime (typically 60-120 seconds). Use this for predictable growth. For unpredictable spikes, enable autoscale via Azure's scaling API—but be aware it's not instantaneous (takes 5-10 minutes). For read scaling, add read replicas (up to 10 for MySQL, up to 5 for PostgreSQL). Replicas are asynchronous; monitor lag. For write scaling, consider sharding at the application layer. PostgreSQL supports partitioning natively; MySQL has partitioning but with limitations. Use Azure's Connection Pooling feature (via PgBouncer) to handle thousands of connections without scaling up. For storage, Azure automatically grows up to 16TB; set auto_grow_enabled to true. Plan for scale by testing with production-like load in a staging environment. Use Azure Load Testing to simulate traffic. Remember: scaling up is easier than scaling out; design your schema for horizontal scaling from day one if you anticipate massive growth.

scale-up.shBASH
1
2
3
4
5
6
7
8
9
10
11
# Scale up PostgreSQL from D4ds to D8ds
az postgres flexible-server update \
  --resource-group prod-rg \
  --name prod-pg \
  --sku-name Standard_D8ds_v4

# Add a read replica
az postgres flexible-server replica create \
  --resource-group prod-rg \
  --replica-name prod-pg-replica \
  --source-server prod-pg
Output
Server scaling initiated. Expected completion in 2 minutes.
Replica creation started. Estimated time: 5 minutes.
⚠ Scaling up causes a brief downtime
Vertical scaling triggers a failover. Plan during maintenance windows. For zero downtime, use read replicas and switch traffic after scaling the primary.
📊 Production Insight
We scaled up during peak hours and caused a 2-minute outage. Now we always scale during low-traffic windows and use replicas to absorb traffic during the switch.
🎯 Key Takeaway
Use vertical scaling for predictable growth, read replicas for read scaling, and sharding for write scaling.

Migration: On-Premises to Azure

Use Azure Database Migration Service (DMS) for online migrations with minimal downtime. For offline migrations, use pg_dump/pg_restore (PostgreSQL) or mysqldump (MySQL). For large databases (>100GB), use Azure's Data Factory or bulk copy with COPY (PostgreSQL) or LOAD DATA INFILE (MySQL). Pre-migration checklist: validate source version compatibility (Azure supports MySQL 5.7/8.0, PostgreSQL 11-15), check for unsupported features (e.g., MySQL's FEDERATED engine), and reduce downtime by using continuous sync. For PostgreSQL, use pglogical extension for real-time sync. For MySQL, use DMS with CDC. Test the migration in a staging environment first. After migration, run ANALYZE to update statistics. Monitor performance for a week before cutting over. Have a rollback plan: keep the source database running until you're confident.

migrate-pg.shBASH
1
2
3
4
5
6
7
8
9
# Offline migration using pg_dump/pg_restore
pg_dump --host=onprem-db --port=5432 --username=admin \
  --dbname=proddb --format=custom --file=proddb.dump

pg_restore --host=prod-pg.postgres.database.azure.com --port=5432 \
  --username=dbadmin --dbname=proddb --jobs=4 --verbose proddb.dump

# Run analyze
psql -h prod-pg.postgres.database.azure.com -U dbadmin -d proddb -c "ANALYZE;"
Output
pg_restore: restoring data for table "orders"
pg_restore: restoring data for table "users"
...
ANALYZE completed.
🔥Use DMS for minimal downtime
Azure Database Migration Service supports online migrations with continuous sync. This reduces downtime to minutes. For offline migrations, expect hours of downtime for large databases.
📊 Production Insight
We migrated a 2TB PostgreSQL database using pg_dump and it took 14 hours. The application was down the entire time. Next time, we'll use DMS with CDC to reduce downtime to under 5 minutes.
🎯 Key Takeaway
Use DMS for online migrations; test thoroughly and have a rollback plan.

Cost Optimization and Governance

Azure Database for MySQL/PostgreSQL costs are driven by vCores, storage, and backup retention. Use reserved instances for 1 or 3 years to save up to 40% for steady-state workloads. For dev/test, use Burstable tier (B-series) which accumulates CPU credits. Right-size your tier: monitor CPU and memory usage; if average CPU < 20% for a week, consider scaling down. Use Azure Cost Management to set budgets and alerts. For backup storage, reduce retention to 7 days if not required by compliance. Use geo-redundant backup only if needed—it doubles backup storage costs. For read replicas, consider using lower tier than primary. Implement tagging for cost allocation (e.g., Environment: Production, Team: Payments). Use Azure Policy to enforce tags and restrict allowed SKUs. Schedule start/stop for non-production databases using automation (but not for production).

cost-optimize.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
# Purchase reserved instance for 3 years
az reservations purchase \
  --reserved-resource-type VirtualMachines \
  --sku Standard_D4ds_v4 \
  --term P3Y \
  --quantity 1

# Scale down dev database
az mysql flexible-server update \
  --resource-group dev-rg \
  --name dev-mysql \
  --sku-name Standard_D2ds_v4
Output
Reservation purchase successful. Estimated savings: 40%.
Server scaled down.
💡Use reserved instances for steady workloads
If your database runs 24/7, reserved instances can save 30-40%. For dev/test, use Burstable tier and auto-shutdown during off-hours.
📊 Production Insight
We were paying for a Memory Optimized tier that was only 10% utilized. After monitoring, we scaled down to General Purpose and saved $500/month. Always monitor before scaling.
🎯 Key Takeaway
Right-size tiers, use reserved instances, and enforce tagging to control costs.

Automating Maintenance and Patching

Azure handles OS and database engine patching automatically, but you control the maintenance window. Set it to a low-traffic period (e.g., 2 AM Sunday). For critical patches, you can schedule a one-time maintenance. Use Azure's maintenance notifications to get advance notice. For zero-downtime patching, use read replicas: failover to replica, patch primary, then failback. For PostgreSQL, use pg_rewind to quickly sync after failback. For MySQL, use the built-in replica failover. Test patching in a staging environment first. Monitor patching history via Activity Log. For custom extensions (e.g., pg_cron, postgis), ensure they are compatible with the new version. Use Azure Policy to enforce maintenance window settings. Automate the failover process with Azure CLI scripts and test them quarterly.

patch-failover.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Failover to replica before patching
az postgres flexible-server replica stop-replication \
  --resource-group prod-rg \
  --name prod-pg-replica

# Promote replica to primary (manual failover)
az postgres flexible-server replica promote \
  --resource-group prod-rg \
  --name prod-pg-replica

# Update application connection string to point to replica
# After patching original primary, reattach as replica
az postgres flexible-server replica create \
  --resource-group prod-rg \
  --replica-name prod-pg-replica2 \
  --source-server prod-pg
Output
Replication stopped.
Replica promoted to primary.
New replica creation started.
⚠ Test patching in staging first
Patching can cause unexpected behavior, especially with custom extensions. Always test in a non-production environment before applying to production.
📊 Production Insight
A security patch caused a conflict with a custom PostgreSQL extension, leading to a crash. Now we always test patches in staging and have a rollback plan.
🎯 Key Takeaway
Use maintenance windows and replica failover to achieve zero-downtime patching.
Azure MySQL vs PostgreSQL: Key Differences Choose based on workload and ecosystem needs Azure Database for MySQL Azure Database for PostgreSQL SQL Standard Compliance Partial (MySQL-specific extensions) Full (ANSI SQL, advanced window function Replication Options Read replicas, GTID-based replication Logical replication, streaming replicati Extension Support Limited (InnoDB, MyRocks) Extensive (PostGIS, pg_stat_statements) Indexing Features B-tree, hash, full-text, spatial B-tree, hash, GiST, GIN, BRIN, bloom High Availability Zone-redundant HA with standby Zone-redundant HA with standby THECODEFORGE.IO
thecodeforge.io
Azure Mysql Postgresql

Troubleshooting Common Production Issues

Common issues: connection timeouts, slow queries, replication lag, and storage full. For connection timeouts, check max_connections (default 100 for MySQL, 100 for PostgreSQL) and increase if needed. Use connection pooling. For slow queries, use EXPLAIN ANALYZE and add indexes. For replication lag, check network latency between regions and increase wal_keep_segments (PostgreSQL) or binlog_expire_logs_seconds (MySQL). For storage full, enable auto-grow and set up alerts at 80%. For deadlocks, review transaction ordering and use nowait or skip locked where possible. For authentication failures, check Azure AD integration and password expiry. For SSL errors, ensure client supports TLS 1.2. Use Azure's troubleshooting guides and support tickets for deeper issues. Keep a runbook of common fixes and share with the team.

troubleshoot.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
-- PostgreSQL: Check active connections
SELECT count(*) FROM pg_stat_activity;

-- MySQL: Check active connections
SHOW STATUS LIKE 'Threads_connected';

-- PostgreSQL: Check for blocking locks
SELECT blocked_locks.pid AS blocked_pid,
       blocked_activity.usename AS blocked_user,
       blocking_locks.pid AS blocking_pid,
       blocking_activity.usename AS blocking_user
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_locks.pid = blocked_activity.pid
JOIN pg_catalog.pg_locks blocking_locks ON blocking_locks.locktype = blocked_locks.locktype
  AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database
  AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
  AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
  AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
  AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
  AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
  AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
  AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
  AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
  AND blocking_locks.pid != blocked_locks.pid
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_locks.pid = blocking_activity.pid
WHERE NOT blocked_locks.granted;
Output
blocked_pid | blocked_user | blocking_pid | blocking_user
-------------+--------------+--------------+--------------
12345 | app_user | 12346 | admin_user
(1 row)
🔥Enable deadlock detection logging
For PostgreSQL, deadlocks are logged automatically. For MySQL, set innodb_print_all_deadlocks = ON to capture them in the error log.
📊 Production Insight
A sudden spike in connections caused max_connections to be exceeded, leading to application errors. We now set alerts at 80% of max connections and use PgBouncer to pool connections.
🎯 Key Takeaway
Monitor connections, replication lag, and storage; use EXPLAIN ANALYZE for slow queries.
⚙ Quick Reference
12 commands from this guide
FileCommand / CodePurpose
choose-tier.shaz mysql flexible-server create \Choosing Between Azure Database for MySQL and PostgreSQL
main.tfresource "azurerm_resource_group" "rg" {Provisioning with Infrastructure as Code
check-replication-lag.sqlSELECTConfiguring High Availability and Disaster Recovery
optimize-query.sqlSELECTPerformance Tuning
create-user.sqlCREATE ROLE app_readonly WITH LOGIN PASSWORD 'strong_password';Security
restore-test.shRESTORE_TIME="2026-07-10T03:00:00Z"Backup and Restore Strategies
alert-rule.json{Monitoring and Alerting with Azure Monitor
scale-up.shaz postgres flexible-server update \Scaling
migrate-pg.shpg_dump --host=onprem-db --port=5432 --username=admin \Migration
cost-optimize.shaz reservations purchase \Cost Optimization and Governance
patch-failover.shaz postgres flexible-server replica stop-replication \Automating Maintenance and Patching
troubleshoot.sqlSELECT count(*) FROM pg_stat_activity;Troubleshooting Common Production Issues

Key takeaways

1
Choose the right engine
MySQL for read-heavy web apps, PostgreSQL for complex queries and data integrity.
2
Automate everything
Use IaC (Terraform/Bicep) for provisioning, CI/CD for schema changes, and automated backup validation.
3
Plan for failure
Use zone-redundant HA, geo-redundant backups, and test failover quarterly.
4
Monitor and alert
Set up Azure Monitor alerts on CPU, storage, connections, and replication lag; use Log Analytics for deep analysis.

Common mistakes to avoid

3 patterns
×

Not planning mysql postgresql properly before deployment

Fix
Design your architecture with redundancy, scaling, and security in mind from the start.
×

Ignoring Azure best practices for mysql postgresql

Fix
Follow Microsoft's Well-Architected Framework and review Azure Advisor recommendations regularly.
×

Overlooking cost implications of mysql postgresql

Fix
Set budgets and alerts, right-size resources, and use Azure pricing calculator before deploying.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
Explain Database for MySQL & PostgreSQL and its use cases.
Q02JUNIOR
How does Database for MySQL & PostgreSQL handle high availability?
Q03JUNIOR
What are the security best practices for mysql postgresql?
Q04JUNIOR
How do you optimize costs for mysql postgresql?
Q05JUNIOR
Compare Azure mysql postgresql with self-hosted alternatives.
Q01 of 05JUNIOR

Explain Database for MySQL & PostgreSQL and its use cases.

ANSWER
Microsoft Azure — Database for MySQL & PostgreSQL is an Azure service for managing mysql postgresql in the cloud. Use it when you need reliable, scalable mysql postgresql without managing underlying infrastructure.
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
What is the difference between Azure Database for MySQL Single Server and Flexible Server?
02
How do I migrate from on-premises MySQL to Azure Database for MySQL with minimal downtime?
03
Can I use Azure Active Directory authentication with Azure Database for PostgreSQL?
04
How do I handle a failover in Azure Database for PostgreSQL Flexible Server?
05
What is the maximum storage size for Azure Database for MySQL Flexible Server?
06
How do I monitor replication lag on a read replica?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Notes here come from systems that actually shipped.

Follow
Verified
production tested
July 12, 2026
last updated
436
articles · all by Naren
🔥

That's Azure. Mark it forged?

6 min read · try the examples if you haven't

Previous
Microsoft Azure — Cosmos DB (Global NoSQL)
28 / 55 · Azure
Next
Microsoft Azure — Azure Cache for Redis