25
MySQL репликация Serge Tyatin Full-stack web developer

Mysql replication

Embed Size (px)

Citation preview

MySQL репликацияSerge Tyatin Full-stack web developer

Что такое репликация и зачем она нужна

РепликацияКак могла бы быть устроена ?

Устройство Mysql репликации Master -> Slave

• MASTER запиcывает изменения в “binary-log”

• SLAVE подключается к MASTER как клиент

• SLAVE скачивает “binary-log” в “replication-log”

• SLAVE последовательно выполняет изменения из “replication-log”

MASTER запиcывает изменения в “binary-log”

http://mysql.2rba.com:1715

> show master status\G

binlog_format

• STATEMENT

• ROW

• MIXEDPrior to MySQL 5.7.7, statement-based logging format was the default. In MySQL 5.7.7 and later, row-based logging format is the default.

mysqlbinlog

$ cd /var/log/mysql $ mysqlbinlog mysql-bin.000004

Настройка Репликации

CHANGE MASTER TO MASTER_HOST='localhost', MASTER_USER='root', MASTER_PASSWORD='q12345'

MASTER my.cnfserver_id = 1

SLAVE my.cnfserver_id = 2

log_bin = /var/log/mysql/mysql-bin.log

show slave status\G

SLAVE START;

SLAVE подключается к MASTER как клиент

master> show processlist;

slave> show processlist;

Проблемы• Два лога транзакций на мастере • Остановка репликации

• проблема в логе • проблема в отличии структур или данных

Как починить SLAVE

Исправить данные на SLAVE и запустить SLAVE

slave start;

SET GLOBAL sql_slave_skip_counter = 1;

Особенности

• Настройка баз/таблиц для записи в binary_log

• Настройка баз/таблиц для чтения из replication_log

• Ключи/формат/тип могут не совпадать

Пример настройки репликации

Таблица

Пример настройки репликации

Таблица Облегченная Таблица

Пример настройки репликации CREATE TRIGGER `table_insert` AFTER INSERT ON table FOR EACH ROW BEGIN if (‘active’=NEW.status) THEN INSERT INTO table Set id = NEW.id, …. END IF; END;

CREATE TRIGGER `table_delete` AFTER DELETE ON table FOR EACH ROW BEGIN DELETE FROM table where id=OLD.id; END;

CREATE TRIGGER `table_update` AFTER UPDATE ON table FOR EACH ROW BEGIN if (‘active’=NEW.status) THEN UPDATE table SET status=NEW.status, … WHERE id = NEW.id; ELSE DELETE FROM table where id=NEW.id; END IF; END;

Использование истории транзакций

• backup

• audit

• troubleshooting

Поиск ошибки

В базе появилась ошибка Необходимо выяснить как была создана запись в таблице payments с id=92346

bin-log файлы находятся в /log

Source

class Promo < ActiveRecord::Base belongs_to :payment def self.redeem(code) transaction do promo = where(code: code, is_used: false).first if promo promo.payment = Payment.create(amount: promo.amount) promo.is_used = true promo.save! end end endend

class Promo < ActiveRecord::Base belongs_to :payment def self.redeem(code) transaction do promo = where(code: code, is_used: false).first if promo promo.payment = Payment.create(amount: promo.amount) promo.is_used = true promo.save! end end endend

INSERT INTO `payments` (`amount`, `created_at`, `updated_at`) VALUES (12, '2016-02-11 21:12:56', '2016-02-11 21:12:56’) UPDATE `promos` SET `payment_id` = 92346, `is_used` = 1, `updated_at` = '2016-02-11 21:12:56' WHERE `promos`.`id` = 16460 INSERT INTO `payments` (`amount`, `created_at`, `updated_at`) VALUES (12, '2016-02-11 21:12:56', '2016-02-11 21:12:56’) UPDATE `promos` SET `payment_id` = 92347, `is_used` = 1, `updated_at` = '2016-02-11 21:12:56' WHERE `promos`.`id` = 16460

Решение

• Optimistic Locking • field lock_version

• Pessimistic Locking promo = where(code: code, is_used: false).lock(true).first

promo.lock!if promo && !promo.is_used

Спасибо

Serge Tyatin [email protected] skype: tyatin