noisebridge-wiki/modules/wiki-replica/mysql.nix
Jet 8cfede9f57
Some checks failed
CI / check (push) Has been cancelled
CI / deploy (push) Has been cancelled
feat: init
2026-03-17 04:07:44 -07:00

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";
};
}