Merge pull request #1 from tiburon-777/mysq-57-srv-replication

Mysq 57 srv replication
main
Andrey Ivanov 2021-02-11 11:44:15 -05:00 committed by GitHub
commit 174c72dc2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 128 additions and 24 deletions

View File

@ -1,14 +1,18 @@
cdir = $(shell pwd)
up:
sudo -S docker-compose -f ./cicd/docker-compose.yml up -d --build
docker-compose -f ./cicd/docker-compose.yml up -d --build
./cicd/init.sh
down: shutdown clean
shutdown:
sudo -S docker-compose -f ./cicd/docker-compose.yml down
docker-compose -f ./cicd/docker-compose.yml down
sudo docker rmi $$(sudo docker images -a | grep '<none>' | awk '{print $$3}')
clean:
sudo docker rmi $(sudo docker images | grep '<none>' | awk '{print $3}')
rm -rf /opt/mysql_master/* ; \
rm -rf /opt/mysql_slave1/* ; \
rm -rf /opt/mysql_slave2/* ; \
sudo docker rmi $$(sudo docker images -a | grep '<none>' | awk '{print $$3}')
.PHONY: up down

View File

@ -1,2 +0,0 @@
CREATE DATABASE IF NOT EXISTS `app` CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL ON `app`.* TO 'app'@'%' identified by 'app';

View File

@ -1,22 +1,48 @@
version: '3'
services:
mysql:
image: mysql:5.6
hostname: "mysql"
container_name: mysql
command: --default-authentication-plugin=mysql_native_password
mysql_master:
image: mysql:5.7
hostname: "mysql_master"
container_name: mysql_master
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: app
MYSQL_USER: app
MYSQL_PASSWORD: app
MYSQL_PORT: 3306
MYSQL_LOWER_CASE_TABLE_NAMES: 0
volumes:
- /opt/mysql:/var/lib/mysql
- ./dbinit:/docker-entrypoint-initdb.d
ports:
- "3306:3306"
- ./mysql/mysql_master.conf:/etc/mysql/conf.d/mysql.conf.cnf
- /opt/mysql_master:/var/lib/mysql
mysql_slave1:
image: mysql:5.7
hostname: "mysql_slave1"
container_name: mysql_slave1
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_PORT: 3306
MYSQL_LOWER_CASE_TABLE_NAMES: 0
depends_on:
- mysql_master
volumes:
- ./mysql/mysql_slave1.conf:/etc/mysql/conf.d/mysql.conf.cnf
- /opt/mysql_slave1:/var/lib/mysql
mysql_slave2:
image: mysql:5.7
hostname: "mysql_slave2"
container_name: mysql_slave2
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_PORT: 3306
MYSQL_LOWER_CASE_TABLE_NAMES: 0
depends_on:
- mysql_master
volumes:
- ./mysql/mysql_slave2.conf:/etc/mysql/conf.d/mysql.conf.cnf
- /opt/mysql_slave2:/var/lib/mysql
app:
build:
@ -26,7 +52,7 @@ services:
environment:
APP_SERVER_ADDRESS: 0.0.0.0
APP_SERVER_PORT: 8080
APP_DSN_HOST: mysql
APP_DSN_HOST: mysql_master
APP_DSN_PORT: 3306
APP_DSN_USER: app
APP_DSN_PASS: app

45
cicd/init.sh Executable file
View File

@ -0,0 +1,45 @@
#!/bin/bash
until docker exec mysql_master sh -c 'export MYSQL_PWD=root; mysql -u root -e ";"'
do
echo "Waiting for mysql_master database connection..."
sleep 4
done
priv_stmt='CREATE DATABASE IF NOT EXISTS app CHARACTER SET utf8 COLLATE utf8_general_ci; GRANT ALL ON app.* TO "app"@"%" IDENTIFIED BY "app"; GRANT REPLICATION SLAVE ON *.* TO "mydb_slave_user"@"%" IDENTIFIED BY "mydb_slave_pwd"; FLUSH PRIVILEGES;'
docker exec mysql_master sh -c "export MYSQL_PWD=root; mysql -u root -e '$priv_stmt'"
until docker exec mysql_slave1 sh -c 'export MYSQL_PWD=root; mysql -u root -e ";"'
do
echo "Waiting for mysql_slave1 database connection..."
sleep 4
done
until docker exec mysql_slave2 sh -c 'export MYSQL_PWD=root; mysql -u root -e ";"'
do
echo "Waiting for mysql_slave2 database connection..."
sleep 4
done
priv_stmt='CREATE DATABASE IF NOT EXISTS app CHARACTER SET utf8 COLLATE utf8_general_ci; GRANT ALL ON app.* TO "app"@"%" IDENTIFIED BY "app"; FLUSH PRIVILEGES;'
docker exec mysql_slave1 sh -c "export MYSQL_PWD=root; mysql -u root -e '$priv_stmt'"
docker exec mysql_slave2 sh -c "export MYSQL_PWD=root; mysql -u root -e '$priv_stmt'"
docker-ip() {
docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$@"
}
MS_STATUS=`docker exec mysql_master sh -c 'export MYSQL_PWD=root; mysql -u root -e "SHOW MASTER STATUS"' | grep mysq`
CURRENT_LOG=`echo $MS_STATUS | awk '{print $1}'`
CURRENT_POS=`echo $MS_STATUS | awk '{print $2}'`
start_slave_stmt="CHANGE MASTER TO MASTER_HOST='$(docker-ip mysql_master)',MASTER_USER='mydb_slave_user',MASTER_PASSWORD='mydb_slave_pwd',MASTER_LOG_FILE='$CURRENT_LOG',MASTER_LOG_POS=$CURRENT_POS; START SLAVE;"
start_slave_cmd='export MYSQL_PWD=root; mysql -u root -e "'
start_slave_cmd+="$start_slave_stmt"
start_slave_cmd+='"'
docker exec mysql_slave1 sh -c "$start_slave_cmd"
docker exec mysql_slave1 sh -c "export MYSQL_PWD=root; mysql -u root -e 'SHOW SLAVE STATUS \G' | grep Slave_"
docker exec mysql_slave2 sh -c "$start_slave_cmd"
docker exec mysql_slave2 sh -c "export MYSQL_PWD=root; mysql -u root -e 'SHOW SLAVE STATUS \G' | grep Slave_"

View File

@ -0,0 +1,9 @@
[mysqld]
skip-host-cache
skip-name-resolve
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
# binlog_format = ROW
binlog_do_db = app

View File

@ -0,0 +1,9 @@
[mysqld]
skip-host-cache
skip-name-resolve
server-id = 2
log_bin = /var/log/mysql/mysql-bin.log
relay-log = /var/log/mysql/mysql-relay-bin.log
binlog_do_db = app

View File

@ -0,0 +1,9 @@
[mysqld]
skip-host-cache
skip-name-resolve
server-id = 3
log_bin = /var/log/mysql/mysql-bin.log
relay-log = /var/log/mysql/mysql-relay-bin.log
binlog_do_db = app

View File

@ -19,7 +19,7 @@ func New(configFile, envPrefix string) (App, error) {
return App{}, fmt.Errorf("can't apply config: %w\n", err)
}
db, err := sql.Open("mysql", conf.DSN.User+":"+conf.DSN.Pass+"@tcp("+conf.DSN.Host+":"+conf.DSN.Port+")/"+conf.DSN.Base)
db, err := sql.Open("mysql", conf.DSN.User+":"+conf.DSN.Pass+"@tcp("+conf.DSN.Host+":"+conf.DSN.Port+")/"+conf.DSN.Base+"?charset=utf8&collation=utf8_unicode_ci")
if err != nil {
return App{}, err
}
@ -60,7 +60,7 @@ func dbInit(db *sql.DB) error {
City varchar(255) DEFAULT NULL,
Interests varchar(255) DEFAULT NULL,
PRIMARY KEY (Id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8`); err != nil {
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci`); err != nil {
return err
}
if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS relations (

View File

@ -30,9 +30,13 @@ func NewPerson() (p Person) {
p.FirstName = womanNames[rand.Intn(len(womanNames))]
p.SecondName = secondNames[rand.Intn(len(secondNames))] + "а"
}
t := make([]byte, 16)
rand.Read(t)
p.Password = string(t)
charSet := "abcdedfghijklmnopqrstABCDEFGHIJKLMNOP0123456789"
var output strings.Builder
for i := 0; i < 16; i++ {
random := rand.Intn(len(charSet))
output.WriteString(string(charSet[random]))
}
p.Password = output.String()
p.City = cities[rand.Intn(len(cities))]
for i := 0; i < (rand.Intn(4) + 3); i++ {
p.Interests = append(p.Interests, interests[rand.Intn(len(interests))])