106 lines
2.9 KiB
Nix
106 lines
2.9 KiB
Nix
{ config, pkgs, lib, ... }:
|
|
{
|
|
services.mysql = {
|
|
enable = true;
|
|
package = pkgs.mariadb;
|
|
dataDir = "/var/lib/mysql";
|
|
|
|
settings.mysqld = {
|
|
bind-address = "127.0.0.1";
|
|
|
|
# InnoDB (smaller for replica)
|
|
innodb_buffer_pool_size = "128M";
|
|
innodb_log_file_size = "64M";
|
|
innodb_flush_log_at_trx_commit = 2;
|
|
innodb_file_per_table = 1;
|
|
|
|
# GTID replication (replica)
|
|
server-id = 2;
|
|
read_only = 1;
|
|
relay_log = "relay-bin";
|
|
log_slave_updates = 1;
|
|
gtid_strict_mode = 1;
|
|
|
|
# Performance
|
|
max_connections = 50;
|
|
table_open_cache = 200;
|
|
|
|
# Character set
|
|
character-set-server = "binary";
|
|
collation-server = "binary";
|
|
};
|
|
|
|
# Do NOT use ensureDatabases or ensureUsers on the replica —
|
|
# they require writes, but read_only=1 blocks writes.
|
|
# The database, tables, and users arrive via replication from the primary.
|
|
};
|
|
|
|
# Node exporter (scraped by primary over Tailscale)
|
|
# Includes textfile collector for failover metrics
|
|
services.prometheus.exporters.node = {
|
|
enable = true;
|
|
port = 9100;
|
|
enabledCollectors = [
|
|
"cpu"
|
|
"diskstats"
|
|
"filesystem"
|
|
"loadavg"
|
|
"meminfo"
|
|
"netdev"
|
|
"stat"
|
|
"time"
|
|
"vmstat"
|
|
"systemd"
|
|
"textfile"
|
|
];
|
|
extraFlags = [
|
|
"--collector.textfile.directory=/var/lib/prometheus-node-exporter/textfile"
|
|
];
|
|
};
|
|
|
|
# mysqld exporter (scraped by primary over Tailscale for replication metrics)
|
|
# Key metrics: mysql_slave_status_seconds_behind_master,
|
|
# mysql_slave_status_slave_io_running, mysql_slave_status_slave_sql_running,
|
|
# mysql_global_status_queries (read-only query volume)
|
|
services.prometheus.exporters.mysqld = {
|
|
enable = true;
|
|
port = 9104;
|
|
runAsLocalSuperUser = true;
|
|
};
|
|
|
|
# Memcached exporter (scraped by primary over Tailscale)
|
|
# Key metrics: hit ratio, evictions, memory usage
|
|
services.prometheus.exporters.memcached = {
|
|
enable = true;
|
|
port = 9150;
|
|
extraFlags = [ "--memcached.address=localhost:11211" ];
|
|
};
|
|
|
|
# Helper script to initialize replication (run once after provisioning)
|
|
environment.systemPackages = [
|
|
(pkgs.writeShellScriptBin "init-replication" ''
|
|
set -euo pipefail
|
|
REPL_PASS=$(cat ${config.age.secrets.mysql-replication.path})
|
|
echo "Configuring GTID-based replication from wiki (primary)..."
|
|
${pkgs.mariadb}/bin/mysql -u root <<SQL
|
|
SET GLOBAL read_only = 0;
|
|
STOP SLAVE;
|
|
CHANGE MASTER TO
|
|
MASTER_HOST='wiki',
|
|
MASTER_USER='repl',
|
|
MASTER_PASSWORD='$REPL_PASS',
|
|
MASTER_USE_GTID=slave_pos;
|
|
START SLAVE;
|
|
SET GLOBAL read_only = 1;
|
|
SHOW SLAVE STATUS\G
|
|
SQL
|
|
echo "Replication initialized. Check SHOW SLAVE STATUS for errors."
|
|
'')
|
|
];
|
|
|
|
age.secrets.mysql-replication = {
|
|
file = ../../secrets/mysql-replication.age;
|
|
owner = "mysql";
|
|
group = "mysql";
|
|
};
|
|
}
|