Files
myasnikovdaniil 1d2418e4c4 fix(mariadb): derive my.cnf sizing from the instance's own resources (#3345)
## What this PR does

The chart shipped a my.cnf with sizing hardcoded for a large dedicated
host — `innodb_buffer_pool_size=60G`, `innodb_log_file_size=4096M`,
`key_buffer_size=1024M`, `max_connections=4096` — while the default
preset `t1.nano` gives the pod 250m CPU and 128Mi of memory, and the
default volume is 10Gi. Nothing connected the two, so the defaults asked
a 128Mi container for a 60G buffer pool and made every first boot
preallocate a redo log worth 40% of the volume.

That is not only a slow start. On the current default, MariaDB 10.6 is
OOM-killed before it finishes checking its configuration, and on 11.8
the server refuses to start at higher limits with `Cannot map
innodb_buffer_pool_size_max`. It survives in practice only because a
large node's overcommit heuristics allow the mapping and a small
database never touches most of it.

Sizing now derives from the instance's own limits through the same
helper that fills `resources` on the CR, so both `resourcesPreset` and
an explicit `resources` block work. The buffer pool takes half the
memory limit, rounded down to a 128 MiB multiple because InnoDB on the
10.6 line allocates in chunks of that size and rounds requests up — a
naive value would hand the pod a pool larger than its own limit. Half
rather than the conventional 70-80% because that advice assumes a
dedicated host where the remainder is page cache and overshoot means
swapping; under a cgroup limit the same budget also has to cover
per-connection buffers, temporary tables, the key cache and mysqld's own
heap, and overshoot means the kernel kills the process. The redo log
follows the smaller of the pool and 5% of the volume, and the remaining
allocations scale from memory or CPU with floors at the server's own
defaults.

`innodb_buffer_pool_instances` and `innodb_thread_concurrency` are
removed rather than scaled: every shipped server version logs that they
were removed and now do nothing, so this only drops a startup warning.

Settings that describe durability or disk behaviour rather than instance
size — `innodb_flush_log_at_trx_commit`, `innodb_flush_method`,
`innodb_io_capacity`, `innodb_fast_shutdown` — are deliberately left
alone, since the chart cannot derive them from a pod's resources.

### Upgrade safety

An existing instance has a 4096M redo log and will get a smaller one.
Shrinking it was verified on every shipped server version — 10.6.24,
10.11.15, 11.4.9 and 11.8.5 — after both a clean shutdown and a SIGKILL
with writes still unflushed. In all cases the server replayed crash
recovery first and resized the log afterwards, with data intact by
checksum and `CHECK TABLE ... EXTENDED`.

The ConfigMap carries no operator watch label, so a running healthy
instance keeps its current sizing until its next restart; an instance
already crash-looping on the old values picks the new ones up when it
restarts.

### Release note

```release-note
fix(mariadb): size my.cnf from the instance's own CPU, memory and volume instead of hardcoded values that assumed a large dedicated host. Instances on small presets previously advertised `max_connections=4096`, which they could not serve; the limit now scales with memory and starts at the server default of 151.
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- MariaDB server settings now scale automatically based on CPU, memory,
storage, and configured resource limits.
- Improved buffer pool, redo log, connection, cache, temporary table,
and thread sizing across instance presets.
- Large instances can use buffer pools beyond the previous fixed limit.

- **Bug Fixes**
  - Improved sizing for small-volume deployments.
- Removed obsolete MariaDB configuration options for improved version
compatibility.
  - Explicit resource settings now take precedence over preset values.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-20 12:26:34 +05:00
..

Managed MariaDB Service

The Managed MariaDB Service offers a powerful and widely used relational database solution. This service allows you to create and manage a replicated MariaDB cluster seamlessly.

Deployment Details

This managed service is controlled by mariadb-operator, ensuring efficient management and seamless operation.

storageClass is annotated as immutable in the chart schema — see docs/storage-immutability.md for the contract and which consumers enforce it.

HowTos

How to switch master/slave replica

kubectl edit mariadb <instance>

update:

spec:
  replication:
    primary:
      podIndex: 1

check status:

NAME        READY   STATUS    PRIMARY POD   AGE
<instance>  True    Running   app-db1-1     41d

How to back up and restore a MariaDB application

The recommended path is the Cozystack BackupClass / Plan / RestoreJob flow with the operator-native strategy.backups.cozystack.io/MariaDB strategy. See examples/backups/mariadb for a numbered, end-to-end walkthrough (bucket, source, strategy, BackupClass, Plan, ad-hoc BackupJob, and both in-place + to-copy RestoreJob fixtures).

The chart's backup.* block (mariadb-dump + restic CronJob) is deprecated and remains supported for backward compatibility only. Existing tenants can keep using it unchanged; new deployments should use the operator-native flow above.

How to restore from a deprecated restic-based backup

find snapshot:

restic -r s3:s3.example.org/mariadb-backups/database_name snapshots

restore:

restic -r s3:s3.example.org/mariadb-backups/database_name restore latest --target /tmp/

more details:

Known issues

  • Replication can't be finished with various errors

  • Replication can't be finished in case if binlog purged

    Until mariadbbackup is not used to bootstrap a node by mariadb-operator (this feature is not implemented yet), follow these manual steps to fix it: https://github.com/mariadb-operator/mariadb-operator/issues/141#issuecomment-1804760231

  • Corrupted indices Sometimes some indices can be corrupted on master replica, you can recover them from slave:

    mysqldump -h <slave> -P 3306 -u<user> -p<password> --column-statistics=0 <database> <table> ~/tmp/fix-table.sql
    mysql -h <master> -P 3306 -u<user> -p<password> <database> < ~/tmp/fix-table.sql
    

Parameters

Common parameters

Name Description Type Value
replicas Number of MariaDB replicas. int 2
resources Explicit CPU and memory configuration for each MariaDB replica. When omitted, the preset defined in resourcesPreset is applied. object {}
resources.cpu CPU available to each replica. quantity ""
resources.memory Memory (RAM) available to each replica. quantity ""
resourcesPreset Default sizing preset used when resources is omitted. string t1.nano
size Persistent Volume Claim size available for application data. quantity 10Gi
storageClass StorageClass used to store the data. string ""
external Enable external access from outside the cluster. bool false
version MariaDB major.minor version to deploy string v11.8

Application-specific parameters

Name Description Type Value
users Users configuration map. map[string]object {}
users[name].password Password for the user. string ""
users[name].maxUserConnections Maximum number of connections. int 0
databases Databases configuration map. map[string]object {}
databases[name].roles Roles assigned to users. object {}
databases[name].roles.admin List of users with admin privileges. []string []
databases[name].roles.readonly List of users with read-only privileges. []string []

Backup parameters (DEPRECATED)

Name Description Type Value
backup DEPRECATED: Backup configuration. Prefer the BackupClass / Plan flow under examples/backups/mariadb/. object {}
backup.enabled DEPRECATED: Enable regular backups (default: false). bool false
backup.s3Region DEPRECATED: AWS S3 region where backups are stored. string us-east-1
backup.s3Bucket DEPRECATED: S3 bucket used for storing backups. string s3.example.org/mariadb-backups
backup.schedule DEPRECATED: Cron schedule for automated backups. string 0 2 * * *
backup.cleanupStrategy DEPRECATED: Retention strategy for cleaning up old backups. string --keep-last=3 --keep-daily=3 --keep-within-weekly=1m
backup.s3AccessKey DEPRECATED: Access key for S3 authentication. string <your-access-key>
backup.s3SecretKey DEPRECATED: Secret key for S3 authentication. string <your-secret-key>
backup.resticPassword DEPRECATED: Password for Restic backup encryption. string <password>

Parameter examples and reference

resources and resourcesPreset

resources sets explicit CPU and memory configurations for each replica. When left empty, the preset defined in resourcesPreset is applied.

resources:
  cpu: 4000m
  memory: 4Gi

resourcesPreset sets named CPU and memory configurations for each replica. This setting is ignored if the corresponding resources value is set.

Presets follow a cloud-style <series>.<size> naming convention. Five series cover the full CPU-to-memory ratio range (t1 1:0.5, c1 1:1, s1 1:2, u1 1:4, m1 1:8) and each series ships eight sizes (nano through 4xlarge). The legacy flat names (nano, micro, small, medium, large, xlarge, 2xlarge) remain accepted as deprecated aliases of their 1:1 instance-type equivalents.

See docs/operations/resource-presets.md for the full size matrix and the legacy-to-instance-type mapping.

users

users:
  user1:
    maxUserConnections: 1000
    password: hackme
  user2:
    maxUserConnections: 1000
    password: hackme

databases

databases:
  myapp1:
    roles:
      admin:
      - user1
      readonly:
      - user2