dbfailover

package module
v0.0.0-...-625b242 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2023 License: Unlicense Imports: 6 Imported by: 0

README

dbfailover

GoDoc

This is a go package for managing access to multiple MySQL/MariaDB servers. This package takes a list of DB handlers (as slice of *sql.DB) and provides methods for getting currently active master slave DB instance.

Server role detection

Server role (master or slave) is selected by periodically checking value of read_only variable in the server configuration. When read_only flag is set to true server is considered to have a slave role otherwise server role is master. This is important to take into consideration when performing server failover. If server is actually running in slave mode but have read_only flag set to false it will receive DML queries from the services using this package and this will most likely cause data replication failure.

Usage example

package main

import (
        "database/sql"
        "log"

        "github.com/advbet/dbfailover"
        _ "github.com/go-sql-driver/mysql"
)

type Service struct {
        dbs *dbfailover.DBs
}

func main() {
        dsns := []string{
                "user:pass@tcp(127.0.0.1:3306)/db",
                "user:pass@tcp(127.0.0.2:3306)/db",
                "user:pass@tcp(127.0.0.3:3306)/db",
        }

        var dbhs []*sql.DB
        for _, dsn := range dsns {
                db, err := sql.Open("mysql", dsn)
                if err != nil {
                        log.Print("failed to create db pool instance", err)
                        continue
                }
                dbhs = append(dbhs, db)
        }

        dbs, err := dbfailover.New(dbhs)
        if err != nil {
                log.Fatal("failed to create DBs", err)
        }
        defer dbs.Stop()

        svc := Service{
                dbs: dbs,
        }

        svc.Insert()
        svc.Query()
}

func (s *Service) Insert() {
        // Access master server
        _, err := s.dbs.Master().Query(`INSERT INTO user(id, name) VALUES(NULL, "John")`)
        if err != nil {
                log.Fatal("insert query on master failed", err)
        }
}

func (s *Service) Query() {
        // Access slave server
        _, err := s.dbs.Slave().Query(`SELECT id, name FROM user`)
        if err != nil {
                log.Fatal("select query on slave failed", err)
        }
}

Documentation

Overview

Package dbfailover monitors set of DB servers and provides easy access to currently alive server with desired role (master/slave).

Index

Constants

This section is empty.

Variables

View Source
var ErrNoDatabases = errors.New("empty database set provided")

ErrNoDatabases is returned from New() if empty slice of databases are provided. Without any databases to start with we can not guarantee that Master() and Slave() methods will never return nil.

Functions

This section is empty.

Types

type Config

type Config struct {
	SkipSlaveCheck      bool
	SkipGaleraCheck     bool
	CheckInterval       time.Duration // default 1.5 sec if empty
	CheckTimeout        time.Duration // default 1.5 sec if empty
	MaxReplicationDelay time.Duration // default 5 min if empty
}

Config holds configuration for DB pools.

type DBs

type DBs struct {
	// contains filtered or unexported fields
}

DBs holds a list of pools of known DB servers and provides easy access for getting currently active master or slave DB pool.

func New

func New(dbs []*sql.DB) (*DBs, error)

New creates a new instance of database pools checker.

It will block until initial databases state is detected, therefore it is safe to immediately query for master and slave pools after this function returns.

If dbs is empty slice it will return ErrNoDatabases error.

func NewWithConfig

func NewWithConfig(dbs []*sql.DB, cfg Config) (*DBs, error)

NewWithConfig is same as New but allows passing a configuration struct.

func (*DBs) Master

func (p *DBs) Master() *sql.DB

Master returns a database pool attached to the currently active master database instance.

This function will never return nil. If there are no master servers available it will return last seen master. It allows this function result to be used without additional checks, example: `dbs.Master().Query(...)`.

func (*DBs) Slave

func (p *DBs) Slave() *sql.DB

Slave returns database pool attached to a server suitable to be used for read-only non time sensitive queries. It tries to return slave instance with the lowest delay. If no slaves are detected it returns a master DB instance.

This function will never return nil. If there are no servers available it will return last seen master. It allows this function result to be used without additional checks, example: `dbs.Slave().Query(...)`.

func (*DBs) Stop

func (p *DBs) Stop()

Stop kills DB status checking go-routines. Functions to get master or slave DB pools can be safely used after Stop is called. They will return last seen state before Stop was called.

Directories

Path Synopsis
bin

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL