Databases 35 min read

MySQL Containerization vs Host Installation: Production‑Grade Selection Framework

The article explains that the real challenge is not merely running MySQL but placing it in the right resource model, and it provides a four‑dimensional decision framework—performance ceiling, stability floor, automation level, and organizational maturity—to guide when to use host‑installed MySQL, single‑node containers, or full Kubernetes deployment, illustrated with concrete resource analyses, architecture diagrams, configuration examples, pitfalls, checklists, and an evolution roadmap.

Cloud Architecture
Cloud Architecture
Cloud Architecture
MySQL Containerization vs Host Installation: Production‑Grade Selection Framework

Conclusion: Not a Simple Binary Choice

Many teams reduce the debate to the question “Should MySQL run on Kubernetes?” but the real problem is to ask which workload characteristics, latency targets, and team capabilities dictate the deployment model.

Four Decision Dimensions

Performance ceiling

Stability floor

Automation degree

Organizational maturity

Balancing these dimensions leads to a layered answer rather than a single option.

Why MySQL Is Sensitive to Deployment

It is a strongly stateful system where data correctness outweighs service availability.

IO latency, especially on the transaction commit path, is critical.

Scaling is usually read‑scale, sharding, or archiving, not simple horizontal scaling.

It depends on kernel, filesystem, block device, NUMA, and time‑sync settings.

Failure recovery involves consistency, replication topology, failover, backup chains, and rollback capabilities.

The core question becomes: How much infrastructure uncertainty are you willing to let enter the transaction path?

First‑Principle Resource Facets

CPU Facet

MySQL is not a pure compute service; throttling or steal time can cause transaction latency spikes, lock contention, and replication lag. Monitoring should focus on CPU steal, context switches, run‑queue length, NUMA cross‑node access, and core exclusivity rather than average utilization.

Memory Facet

Setting innodb_buffer_pool_size to a fixed percentage of pod memory (e.g., 50 GB in a 64 GB pod) is dangerous. In host‑installations the buffer pool should occupy 50‑70 % of physical RAM, while in containers a more conservative 45‑60 % of the container limit is recommended, with additional headroom for connection buffers, temporary tables, and OS page cache.

IO Facet

The commit chain—redo log → binlog → fsync → filesystem → block device → SSD/NVMe controller—must be predictable. Any jitter in this chain manifests as TPS drop, P99/P999 latency increase, replication lag, lock wait growth, and application timeouts. The guiding principle is to define the storage semantics first, then decide on containerization.

Network Facet

Replication, routing, backup, monitoring, and failover all rely on stable network paths. Small jitter can cause topology mis‑detection, half‑sync fallback, delayed catch‑up, split‑brain protection triggers, or proxy stream‑cut errors. The goal is low jitter, short paths, clear fault domains, and observable connection semantics.

Deployment Options

Host‑Installed MySQL

Direct installation on bare metal, dedicated VMs, or dedicated database nodes gives the database direct access to the host filesystem, kernel parameters, NUMA, and storage. The advantages are predictable performance and easier fault isolation, while the drawbacks are slower environment replication and reliance on manual scripts for new instances.

Single‑Node Containerization

Running MySQL in a Docker container with host‑mounted directories is suitable for development, functional testing, lightweight pre‑release, or PoC. It is not recommended for high‑value production primary nodes because it adds a runtime‑to‑storage mapping layer without delivering true orchestration capabilities.

Kubernetes Containerization

Deploying MySQL on Kubernetes introduces scheduling, storage orchestration, node affinity, CRDs, backup jobs, and network policies. It provides declarative delivery, environment consistency, standardized backup/restore, and platform‑level automation, but only if the team has mature node‑level governance, local‑disk lifecycle management, a reliable Operator, and automated failover drills.

Real‑World Scenario: E‑Commerce System

核心交易主库
  → 宿主机直装 / 专用虚机 / 专用数据库节点
  → 追求低抖动、低恢复面、强可预测

交易读副本
  → 可放容器化专用节点
  → 承担查询、报表、灰度读流量

分析库 / 回放库 / 恢复演练库
  → 优先容器化
  → 追求交付效率和环境复制能力

This mixed‑deployment pattern satisfies both strict latency requirements for the primary and rapid iteration for auxiliary workloads.

Decision Framework

When to Prefer Host‑Install

Core transaction primary databases.

P99 latency < 5 ms and latency spikes are unacceptable.

High short‑transaction concurrency.

Heavy hotspot updates.

Strict fsync, IO isolation, and NUMA awareness.

Team lacks mature K8s stateful‑workload experience.

Disaster‑recovery processes are not yet standardized.

Key takeaway: If you care more about “the database never jitter” than “the database is easier to deliver”, choose host‑install.

When Containerization Adds Value

Read replicas, reporting databases, replay databases.

Recovery‑exercise environments.

Workloads that require frequent cloning.

Multi‑tenant internal platforms.

Teams that already have dedicated nodes, local‑disk governance, and automated backup/restore.

The biggest benefit is declarative delivery, environment consistency, standardized backup, automated topology orchestration, and treating the database as a platform capability.

When Not to Force Containerization

Placing the primary on shared storage just because PVC is convenient.

Co‑locating the database with batch jobs, log collectors, or image‑pull storms.

Using Local PV without a clear node‑affinity and recovery plan.

Assuming an Operator alone guarantees high availability.

Missing replication, commit‑latency, or slow‑SQL monitoring.

Architecture Comparison

Host‑Install Baseline

┌──────────────────────────────┐
               │   Application / Proxy Layer   │
               │ ProxySQL / MySQL Router       │
               └─────────────┬────────────────┘
                             │
               ┌─────────────▼─────────────┐
               │                           │
   ┌───────▼───────┐          ┌───────▼───────┐
   │ Primary 主库   │          │ Replica 从库1 │
   │ 专用节点 A    │  binlog/ │ 专用节点 B   │
   │ NVMe + XFS    │ GTID →   │ NVMe + XFS   │
   └────────────────┘          └───────────────┘
                             │
               ┌───────▼───────┐
               │ Replica 从库2 │
               │ 专用节点 C   │
               └────────────────┘

Advantages: short fault path, rich tuning options, predictable performance. Drawbacks: slower environment replication and manual provisioning.

Kubernetes Platform

┌──────────────────────────────┐
                │   K8s Control Plane / GitOps   │
                │ Operator / Backup / Policy     │
                └─────────────┬────────────────┘
                              │
   ┌─────────────────────────┼─────────────────────────┐
   │                         │                         │
┌──▼───┐               ┌─────▼─────┐               ┌─────▼─────┐
│Node‑A│               │Node‑B     │               │Node‑C     │
│专用节点│               │专用节点 │               │专用节点 │
│Local PV│               │Local PV │               │Local PV │
│MySQL‑0│               │MySQL‑1   │               │MySQL‑2   │
└──┬───┘               └─────┬─────┘               └─────┬─────┘
   │                         │                         │
   └───────复制 / 组复制 / Router───────────────┘

The key is not merely “running in a container” but meeting the seven conditions listed in the article (dedicated node, dedicated local disk, controlled StatefulWorkload, clear topology, built‑in backup, monitoring, and automated failover). Missing any of them quickly erodes the benefits.

Production‑Level Host‑Install Guidance

OS & Filesystem Baseline

Dedicated database node, no co‑location with JVM services, batch jobs, or log collectors.

Stable clock synchronization.

Prefer XFS or ext4, unified across the team.

Separate data and system disks.

RAID, cache policy, power‑loss protection, firmware managed by the infra team.

Fixed NUMA, IRQ, I/O scheduler baselines.

Avoid swap on core nodes.

Sample my.cnf (MySQL 8.0, 128 GB RAM, NVMe)

[mysqld]
server_id = 101
port = 3306
datadir = /data/mysql/data
socket = /data/mysql/run/mysql.sock
pid-file = /data/mysql/run/mysqld.pid
log_error = /data/mysql/log/error.log

character_set_server = utf8mb4
collation_server = utf8mb4_0900_ai_ci
skip_name_resolve = ON
default_time_zone = '+08:00'

max_connections = 1200
max_connect_errors = 100000
thread_cache_size = 256
table_open_cache = 8192
table_definition_cache = 4096
open_files_limit = 65535

innodb_buffer_pool_size = 72G
innodb_buffer_pool_instances = 8
innodb_log_file_size = 4G
innodb_redo_log_capacity = 8G
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
innodb_flush_method = O_DIRECT
innodb_io_capacity = 12000
innodb_io_capacity_max = 24000
innodb_flush_neighbors = 0
innodb_print_all_deadlocks = ON
innodb_adaptive_hash_index = OFF

binlog_format = ROW
binlog_row_image = MINIMAL
log_bin = mysql-bin
binlog_expire_logs_seconds = 604800
gtid_mode = ON
enforce_gtid_consistency = ON
log_replica_updates = ON
replica_parallel_workers = 16
replica_preserve_commit_order = ON

slow_query_log = ON
slow_query_log_file = /data/mysql/log/slow.log
long_query_time = 0.2
log_slow_admin_statements = ON
log_queries_not_using_indexes = OFF

tmp_table_size = 128M
max_heap_table_size = 128M
sort_buffer_size = 2M
join_buffer_size = 2M
read_rnd_buffer_size = 1M

sql_mode = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

The focus is on dual‑write consistency, sufficient buffer pool, limited large connection‑level memory, and aggressive slow‑query logging.

ProxySQL Read/Write Splitting Example

INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES
(10, '10.10.1.11', 3306),
(20, '10.10.1.12', 3306),
(20, '10.10.1.13', 3306);

INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup, apply) VALUES
(1, 1, '^SELECT.*FOR UPDATE', 10, 1),
(2, 1, '^SELECT ', 20, 1),
(3, 1, '^INSERT|^UPDATE|^DELETE|^REPLACE', 10, 1);

LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL QUERY RULES TO DISK;

Production‑level concerns are latency awareness (auto‑remove reads on replication lag), consistency boundaries (strong reads never go to a plain replica), and safe traffic fallback after a node is peeled.

High‑Concurrency Patterns

Connection Storm

Request surge → Application thread explosion → Connection‑pool borrow slowdown → More threads pile up → Retries increase → MySQL connections rise → Context switches & lock wait grow

Host‑install concentrates the problem in MySQL; containerized setups add pod limits, node jitter, and proxy‑layer effects. The mitigation focus is connection budgeting, circuit‑breaking, read‑rate throttling, query tiering, and caching—not merely raising max_connections.

Hot‑Row Updates

Scenarios like inventory decrement, coupon redemption, or balance updates amplify latency, lock hold time, deadlocks, and retry storms when additional deployment jitter is introduced. The recommended approach is business‑level sharding, batch merging, state‑machine driving, idempotent tokens, outbox async propagation, and query result caching.

Read‑Write Splitting & Replication Lag

Not all reads can be blindly sent to replicas. Proper layering separates strong‑consistency reads (primary or guaranteed path), regular reads (replicas), heavy analytical queries (dedicated analytics replica), and replay/audit workloads (isolated recovery DB). Without this layering, containerization merely propagates the problem to more instances.

Common Pitfalls (Six Most Frequent)

Assuming "running" equals "stable" – ignore transaction latency, fsync delay, slow‑SQL percentiles, replication lag, and active‑connection metrics.

Treating Local PV as a migratable cloud disk – it is node‑bound and loses availability on node failure.

Pooling database nodes like generic compute – primary nodes need low jitter and isolation, not high average utilization.

Claiming HA without recovery drills – true HA requires verified failover and data‑correctness after a disaster.

Believing parameter tuning alone solves performance – many root causes are business‑level (large transactions, hotspot rows, uncontrolled retries, non‑index‑friendly SQL, connection‑pool explosion).

Using containerization as a badge of technical modernity – without solid configuration, change, monitoring, and recovery governance, containers only accelerate failure propagation.

Production Checklists

Host‑Install Checklist

Dedicated database node or VM.

Clear separation of data, log, and system disks.

my.cnf validated by load tests and regression.

Master‑slave replication, delay alerts, automatic read‑traffic removal.

Completed master‑slave switchover drills.

Backup‑restore drills.

Observability of slow‑SQL, connection count, commit latency, and disk latency.

Containerization Checklist

Use Local PV or equivalent high‑quality local storage.

Deploy on dedicated database nodes.

PodDisruptionBudget, node‑maintenance strategy, upgrade windows.

Operator, Router, backup jobs exercised in drills.

Clear node‑failure rebuild path.

Gray‑scale read‑traffic switch‑over plan.

Recovery‑instance for periodic restore verification.

High‑Concurrency Governance Checklist

Total application connection budget converged.

Hot‑path caching or async decoupling.

Long transactions broken into smaller units.

Strong‑consistency read path explicitly defined.

Key SQL profiling and regression baselines.

Rate‑limit, circuit‑break, and degradation aligned with DB capacity.

Evolution Roadmap

Standardize host‑install: unified config templates, backup/restore, monitoring, switchover runbooks, SQL governance.

Containerize low‑risk databases (replicas, reporting, replay, drill DB) to gain orchestration experience.

Build a mixed architecture: core primary on dedicated hardware, auxiliary workloads on Kubernetes.

Only after stable dedicated nodes, local‑disk governance, automated backup/restore, frequent drills, mature change management, and closed‑loop incident analysis should the core primary be considered for Kubernetes.

Final Recommendation

First layer databases by business value, then match each layer to the team’s operational maturity. Core transaction primaries default to host‑install or dedicated VMs for maximum predictability; replicas, reporting, and rehearsal databases benefit from containerization for delivery efficiency. The decisive factor is not the platform but whether the full production chain—resource model, storage semantics, topology governance, backup‑restore, exercise, and observability—has been established.

资源模型
  → 存储语义
  → 拓扑治理
  → 备份恢复
  → 演练验证
  → 应用配合
  → 可观测与回滚

Only when these steps are in place does the “where to run MySQL” question become meaningful.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PerformancedeploymentHigh AvailabilityKubernetesContainerizationbest-practicesMySQL
Cloud Architecture
Written by

Cloud Architecture

Focuses on cloud‑native and distributed architecture engineering, sharing practical solutions and lessons learned. Covers microservice governance, Kubernetes, observability, and stability engineering to help your systems run stable, fast, and cost‑effectively.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.