{ config, pkgs, siteConfig, ... }: let replicationUser = siteConfig.database.replicationUser; mysqlCli = "${pkgs.mariadb}/bin/mysql -u root"; initReplicaSql = pkgs.writeText "mysql-init-replica.sql" '' STOP SLAVE; SET @repl_pass = FROM_BASE64('$repl_pass_b64'); SET @change_master = CONCAT( "CHANGE MASTER TO ", "MASTER_HOST='${siteConfig.hosts.primary.tailscaleName}', ", "MASTER_USER='${replicationUser}', ", "MASTER_PASSWORD=", QUOTE(@repl_pass), ", ", "MASTER_USE_GTID=slave_pos" ); PREPARE stmt FROM @change_master; EXECUTE stmt; DEALLOCATE PREPARE stmt; START SLAVE; SHOW SLAVE STATUS\G ''; in { services.mysql = { enable = true; package = pkgs.mariadb; settings.mysqld = { bind-address = "127.0.0.1"; server-id = 2; relay_log = "relay-bin"; log_slave_updates = 1; read_only = 1; super_read_only = 1; gtid_strict_mode = 1; innodb_file_per_table = 1; innodb_buffer_pool_size = "2G"; innodb_log_file_size = "256M"; innodb_flush_method = "O_DIRECT"; innodb_flush_neighbors = 0; innodb_io_capacity = 500; innodb_io_capacity_max = 1000; max_connections = 40; thread_cache_size = 50; table_open_cache = 2000; tmp_table_size = "32M"; max_heap_table_size = "32M"; performance_schema = true; slow_query_log = 1; long_query_time = 1; skip_name_resolve = 1; }; }; age.secrets.mysql-replication = { file = ../../secrets/mysql-replication.age; owner = "mysql"; group = "mysql"; mode = "0400"; }; services.rsyncd = { enable = true; settings = { globalSection = { "use chroot" = false; }; sections.mediawiki-images = { path = "/var/lib/mediawiki/images"; comment = "MediaWiki upload mirror target"; "read only" = false; list = false; }; }; }; environment.systemPackages = [ (pkgs.writeShellScriptBin "init-replica" '' set -euo pipefail repl_pass_b64="$(tr -d '\n' < ${config.age.secrets.mysql-replication.path} | base64 -w0)" ${mysqlCli} <