Search code examples
docker-composemariadbdatabase-replicationmaxscale

MaxScale no Slave State set


We want to use MaxScale and two MariaDB databases with docker-compose.

We have the problem that we do not achieve replication of the database via maxscale. Write permissions are available via MaxScale on both databases. Via the command maxscale list servers in the maxscale container, we see both servers. The first server has the states Master, Running and the second server has only the state Running.

My docker-compose.yaml:

version: '3'
services:

  # Application
  app:
    build:
      context: .
      dockerfile: app.dockerfile
    working_dir: /var/www/project
    volumes:
      - ./project:/var/www/project
      - ./php.ini:/usr/local/etc/php/php.ini
    links:
      - database:database
    environment:
      - "DATABASE_HOST=database"
      - "DATABASE_PORT=4006"

  # Web server
  web:
    image: nginx:latest
    volumes:
      - ./vhost.conf:/etc/nginx/conf.d/default.conf
      - ./nginx-logs:/var/log/nginx
      # Inherit from app container
      - ./project:/var/www/project
      - ./php.ini:/usr/local/etc/php/php.ini
    ports:
      - 0.0.0.0:8021:80
    links:
      - app:app

  # Database
  database:
    image: mariadb:latest
    ports:
      - 0.0.0.0:3306:3306
    volumes:
      - ./database:/var/lib/mysql
      - ./database-config:/etc/mysql/
    command: mysqld --log-bin=mariadb-bin --binlog-format=ROW --server-id=3001 --log-slave-updates
    environment:
      - "MYSQL_ROOT_PASSWORD=secretDummyPassword"
      - "MYSQL_DATABASE=database"
      - "MYSQL_USER=database"
      - "MYSQL_PASSWORD=secretDummyPassword"
      - "skip-networking=0"

  #Max Scale
  maxscale:
    image: mariadb/maxscale:6.2.3
    depends_on:
      - database
    volumes:
      - ./maxscale.cnf:/etc/maxscale.cnf
    ports:
      - 0.0.0.0:4006:4006 # readwrite port
      - 0.0.0.0:4008:4008 # readonly port
      - 0.0.0.0:8989:8989 # REST API port
    links:
      - database:database

volumes:
  app: {}

My maxscale.cnf:

[maxscale]
threads=auto

[MariaDB-Monitor]
type=monitor
module=mariadbmon
servers=server1,server2
user=database
password=secretDummyPassword
auto_failover=true
auto_rejoin=true
enforce_read_only_slaves=1

[Read-Write-Service]
type=service
router=readwritesplit
servers=server1,server2
user=database
password=secretDummyPassword
master_failure_mode=fail_on_write

[Read-Write-Listener]
type=listener
service=Read-Write-Service
protocol=MariaDBClient
port=4006

[server1]
type=server
address=195.XXX.123.22
port=3306
protocol=MariaDBBackend

[server2]
type=server
address=142.XXX.186.188
port=3306
protocol=MariaDBBackend

Solution

  • If you haven't configured the replication manually, you can use the following command inside the Maxscale container to set up replication between the servers:

    maxctrl call command mariadbmon reset-replication MariaDB-Monitor server1
    

    This causes all other servers configured for the MariaDB-Monitor to start replicating from server1.

    Note: this command resets the GTID positions so it should not be used on a live system. If you are using a live system, use the CHANGE MASTER TO command with the correct GTID coordinates. It won't touch the data but you'll lose the history (it does a RESET MASTER).


    If you want the replication to be configured automatically when the container is first started, you can mount a file with SQL commands in it at /docker-entrypoint-initdb.d and MariaDB will execute them during startup. This is probably a better solution for automated systems and it is quite convenient for a test setup.