Mission-critical applications require . The goal of high availability is to provide users with consistent access to services or resources, minimizing the chances of interruption. is a specific mechanism used to achieve high availability. It involves automatically detecting the failure of a system component (like a server, network, or database) and immediately switching operations to a standby component without human intervention. This increases resiliency. high availability Automatic failover MariaDB MaxScale is a database proxy that includes features for high availability. In this article, I'll show you how you can try it out with an application implemented in Java and Svelte. online store simulator Architecture The following diagram shows the architecture of the demo application: A web application developed with JavaScript and the Svelte framework makes HTTP requests to a Java backend. The backend answers with that the frontend uses to update the user interface on the browser. server-sent events The backend is implemented with and connects to a database cluster using (reactive). The backend logic is, in short, a simulation of reads and writes to an online store database. The simulation is parameterized, and the user can adjust: Spring Boot MariaDB R2DBC How many reads to the database per minute. Product visits per minute: How many writes to the database per minute. Orders per minute: Write amplification. Products per order: How many seconds until a request to the database is considered failed. Timeout in milliseconds: The database cluster is front-ended by a called MaxScale. This proxy makes the cluster look like a single logical database to the Java backend. MaxScale also performs read/write splitting (sending writes to the primary MariaDB server and reads to replicas), as well as load-balancing of reads among replica servers using a configurable algorithm. Data is automatically replicated from the primary to the replica database servers. database proxy Building the Docker images from source I have prepared custom Docker images for every component in the simulator. You can either build the images from the source (optional) or use the already built and published images from Docker Hub. If you decide to build the images yourself, you can find the source code on GitHub: Custom images for easy deployment of replicated MariaDB topologies with MaxScale. These images are suitable only for demo applications. Use the for production deployments. : MariaDB deployments DO NOT USE THESE IN PRODUCTION! official MariaDB Docker images The backend application that connects to the database cluster. : Backend application The frontend application that makes simulation configuration requests to the backend and receives events to show the simulation result. : Frontend application Each repository has Dockerfiles that you can use to build your own Docker images. For example, to build the backend application image, run: docker build --tag alejandrodu/online-store-simulator-java-backend . Running the simulation All the services can be started using the following Docker Compose file ( ): docker-compose.yml version: "3.9" services: server-1: container_name: server-1 image: alejandrodu/mariadb ports: - "3306:3306" environment: - MARIADB_CREATE_DATABASE=demo - MARIADB_CREATE_USER=user:Password123! - MARIADB_CREATE_REPLICATION_USER=replication_user:ReplicationPassword123! - MARIADB_CREATE_MAXSCALE_USER=maxscale_user:MaxScalePassword123! server-2: container_name: server-2 image: alejandrodu/mariadb ports: - "3307:3306" environment: - MARIADB_REPLICATE_FROM=replication_user:ReplicationPassword123!@server-1:3306 server-3: container_name: server-3 image: alejandrodu/mariadb ports: - "3308:3306" environment: - MARIADB_REPLICATE_FROM=replication_user:ReplicationPassword123!@server-1:3306 maxscale: container_name: maxscale image: alejandrodu/mariadb-maxscale command: --admin_host 0.0.0.0 --admin_secure_gui false ports: - "4000:4000" - "8989:8989" - "27017:27017" environment: - MAXSCALE_USER=maxscale_user:MaxScalePassword123! - MARIADB_HOST_1=server-1 3306 - MARIADB_HOST_2=server-2 3306 - MARIADB_HOST_3=server-3 3306 healthcheck: test: ["CMD", "maxctrl", "list", "servers"] interval: 5s timeout: 10s retries: 5 java-backend: container_name: java-backend image: alejandrodu/online-store-simulator-java-backend ports: - "8080:8080" environment: - spring.r2dbc.url=r2dbc:mariadb://maxscale:4000/demo - spring.r2dbc.username=user - spring.r2dbc.password=Password123! - spring.liquibase.url=jdbc:mariadb://maxscale:4000/demo - spring.liquibase.user=user - spring.liquibase.password=Password123! depends_on: maxscale: condition: service_healthy svelte-frontend: container_name: svelte-fronted image: alejandrodu/online-store-simulator-svelte-frontend ports: - "5173:80" environment: - BACKEND_URL=http://java-backend:8080 Move to the directory in which the Docker Compose file is, and start the services in detached mode as follows: docker compose up -d Configuring MaxScale Before you start the simulation, configure MaxScale for transaction replay. Also, timeouts should be adjusted to make the simulation more interesting. Navigate to and log into the UI using: http://localhost:8989/ Username: admin Password: mariadb You'll see a dashboard with the MariaDB cluster state. There's a primary server ( ), and two replicas ( and ). Replication is already configured from (primary) to and (replicas). All servers should be up and running. server-1 server-2 server-3 server-1 server-2 server-3 Click on and then on the icon to enable parameter editing. Set the following parameters: mdb_monitor pencil ( ): This enables automatic failover. When a MariaDB server is down, MaxScale selects a replica server and reconfigures it as the new primary so that writes can continue to happen. auto_failover true ( ): This enables the automatic rejoin of recovered servers. When a failed server is up again, MaxScale detects it and configures it as an available replica server. auto_rejoin true ( ): Sets the number of monitor (a component in MaxScale that checks server status) iterations required for a server to be down in order to activate the failover process. We set a value of to make sure the failover starts immediately after failure. failcount 1 1 ( ): Connection timeout for monitor connections. We set a low value (one second) to quickly activate failover for this demo. backend_connect_timeout 1000 ( ): Read timeout for monitor connections. backend_read_timeout 1000 ( ): Write timeout for monitor connections. backend_write_timeout 1000 ( ): Primary failure timeout. master_failure_timeout 1000 ( ): How often the servers are monitored. monitor_interval 1000 ⚠️ These values are appropriate for this demo but very likely not the best for production environments! WARNING: Once the parameters are set, click on and . Done Editing Confirm You also need to enable transaction replay, which automatically re-executes failed in-flight transactions on servers that went down just after a SQL statement was routed. This is a useful feature for software developers since it prevents the need for coding failure cases and transaction retry. On the main menu, click on and then on any of the links in the list of servers. Edit the parameters as follows: Dashboard query_router_service ( ): Activates automatic retry of failed transactions. transaction_replay true ( ): Same as the previous when a deadlock occurs. transaction_replay_retry_on_deadlock true ( ): Same as the previous when a checksum mismatch occurs. transaction_replay_retry_on_mismatch true Once the parameters are set, click on and . Done Editing Confirm Starting the simulation With everything configured, you can start the simulation. Navigate to and configure the following parameters (names are, I hope, self-explanatory): http://localhost:5173/ Product visits per minute: 6000 Orders per minute: 60 Timeout in milliseconds: 8000 But before you start the simulation, you need to create the products for the online store. Click on | . Leave the default values and click on . You should see the UI updating as products are created in the database. Data Create products... Create Now, you can finally click on and see the simulation in action. Start Simulating a server failure At this point, the primary server is handling writes (orders). What happens if you stop that server? In the command line run: docker stop server-1 Depending on multiple factors, you might get some "disappointed visitors" or even a few "missed opportunities" in the simulator. Or maybe you don't get any at all! Product visits (reads) and orders (writes) continue to happen, thanks to MaxScale. Without automatic failover, you have to reconfigure everything manually, which results in more offline time, many disappointed visitors, and missed opportunities! Start the failed server: docker start server-1 Go to the MaxScale ( ) and check that is now a functioning replica. Dashboard http://localhost:8989/ server-1 You can perform a manual to make the primary server again. Click on and then mouse hover over the section. Click on the icon and select . Click and check again in the that the new primary server is . switchover server-1 mdb_monitor MASTER pencil server-1 Swap Dashboard server-1 Conclusion Automatic failover is only one of the components in highly available systems. You can use a database proxy like MaxScale to set up automatic failover, as well as other components such as load-balancing, query routing, transaction retry, topology isolation, and more. Check out the documentation at . https://mariadb.com/kb/en/maxscale/ Also published . here