You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过SaltStack与mysql-formula管理两个MySQL实例?

解决mysql-formula多实例配置引用与应用连接问题

我之前在折腾mysql-formula多实例部署的时候,也碰到过和你一模一样的问题——明明部署了两个实例,却没法同时引用它们的配置,应用那边拿不到连接信息急得跳脚。别担心,大概率是咱们对formula的多实例逻辑没摸透,咱们一步步来捋清楚:

1. 先把Pillar的多实例配置捋顺

mysql-formula默认是单实例逻辑,但它原生支持多实例,核心就是通过mysql:server:instances这个pillar节点来定义所有实例。你现在把配置拆成了db1-host.sls和db2-host.sls,很可能导致目标主机只拿到了其中一个实例的配置,没法同时识别两个。

建议把两个实例的配置合并到一个pillar文件(比如pillar/mysql/multi-instances.sls),结构如下:

mysql:
  server:
    instances:
      db1:
        port: 3306
        datadir: /var/lib/mysql/db1
        socket: /var/run/mysqld/db1.sock
        bind_address: 0.0.0.0
        # 其他你需要的配置,比如skip_name_resolve、max_connections等
      db2:
        port: 3307
        datadir: /var/lib/mysql/db2
        socket: /var/run/mysqld/db2.sock
        bind_address: 0.0.0.0

然后在pillar/top.sls里确保目标主机能拿到这个完整的多实例pillar:

base:
  'db-host':  # 你的MySQL主机的minion ID或匹配规则
    - mysql.multi-instances

2. 调整Salt状态文件适配多实例

默认的mysql.server模块已经支持多实例部署,你只需要在salt/MySQL/init.sls里循环处理每个实例就行,不用硬编码单实例配置:

include:
  - mysql.server

# 循环启动并管理所有MySQL实例
{% for instance_name, instance_config in salt['pillar.get']('mysql:server:instances', {}).items() %}
mysql_server_{{ instance_name }}:
  mysql_server.running:
    - name: {{ instance_name }}
    - config: {{ instance_config }}
    - enable: True
    - require:
      - pkg: mysql_server
{% endfor %}

这样执行状态后,formula会自动为每个实例生成独立的配置文件(比如/etc/mysql/my.cnf.d/db1.cnf)和systemd服务(比如mysql@db1.service),两个实例不会互相干扰。

3. 让应用获取数据库连接配置

应用需要的连接信息(主机、端口、用户名密码等),可以通过两种方式传递:

方式一:直接从Pillar读取(适合应用和MySQL在同一主机或应用主机能拿到MySQL的pillar)

在应用的状态文件里,通过pillar获取实例的配置,渲染到应用的配置文件中:

my_app_config:
  file.managed:
    - name: /etc/my_app/config.ini
    - source: salt://my_app/templates/config.ini.j2
    - template: jinja
    - context:
        db1_host: {{ grains['fqdn'] }}  # 或者直接写IP
        db1_port: {{ salt['pillar.get']('mysql:server:instances:db1:port') }}
        db1_user: {{ salt['pillar.get']('mysql:server:instances:db1:user:app_user') }}  # 如果在pillar里定义了用户
        db2_host: {{ grains['fqdn'] }}
        db2_port: {{ salt['pillar.get']('mysql:server:instances:db2:port') }}

方式二:用Salt Mine收集实例信息(适合应用和MySQL在不同主机,且不想把MySQL的pillar暴露给应用主机)

先在MySQL主机的状态文件里配置Mine,发布实例信息:

# 在MySQL主机的sls里添加
mine_functions:
  mysql_instances:
    - function: pillar.get
    - args:
        - mysql:server:instances

然后在应用主机的状态文件里,通过Mine获取MySQL主机的实例信息:

{% set mysql_host_instances = salt['mine.get']('db-host', 'mysql_instances', tgt_type='glob') %}
{% set db1_config = mysql_host_instances.values()|first.get('db1', {}) %}
{% set db2_config = mysql_host_instances.values()|first.get('db2', {}) %}

my_app_config:
  file.managed:
    - name: /etc/my_app/config.ini
    - source: salt://my_app/templates/config.ini.j2
    - template: jinja
    - context:
        db1_host: 'db-host'  # MySQL主机的minion ID或IP
        db1_port: {{ db1_config.get('port', 3306) }}
        db2_host: 'db-host'
        db2_port: {{ db2_config.get('port', 3307) }}

4. 常见坑点排查

  • 确认pillar的top.sls没有只分配单个实例的pillar给主机,要确保主机拿到完整的instances配置;
  • 检查两个实例的端口、socket、datadir有没有冲突,冲突会导致实例启动失败;
  • 用systemctl status mysql@db1.service和systemctl status mysql@db2.service验证实例是否正常运行;
  • 如果应用拿不到配置,检查应用主机是否有读取MySQL pillar或Mine数据的权限(Salt的权限控制)。

内容的提问来源于stack exchange,提问作者jma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:34:15