forked from le0pard/postgresql_book
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpostgresql_replication_rubyrep.tex
More file actions
178 lines (151 loc) · 6.98 KB
/
postgresql_replication_rubyrep.tex
File metadata and controls
178 lines (151 loc) · 6.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
\section{RubyRep}
\subsection{Введение}
RubyRep представляет собой движок для организации асинхронной репликации, написанный на языке ruby.
Основные принципы: простота использования и не зависить от БД.
Поддерживает как master-master, так и master-slave репликацию, может работать с PostgreSQL и MySQL.
Отличительными особенностями решения являются:
\begin{itemize}
\item возможность двухстороннего сравнения и синхронизации баз данных
\item простота установки
\end{itemize}
К недостаткам можно отнести:
\begin{itemize}
\item работа только с двумя базами данных для MySQL
\item медленная работа синхронизации
\item при больших обьемах данных <<ест>> процессор и память
\end{itemize}
\subsection{Установка}
RubyRep поддерживает два типа установки: через стандартный Ruby или JRuby.
Рекомендую ставить JRuby вариант~--- производительность будет выше.
\textbf{Установка JRuby версии}
Предварительно должна быть установлена Java (версия 1.6).
\begin{enumerate}
\item Загрузите последнюю версию JRuby rubyrep c Rubyforge\footnote{http://rubyforge.org/frs/?group\_id=7932, выберите ZIP}.
\item Распакуйте
\item Готово
\end{enumerate}
\textbf{Установка стандартной Ruby версии}
\begin{enumerate}
\item Установить Ruby, Rubygems.
\item Установить драйвера базы данных.
Для Mysql:
\begin{verbatim}
sudo gem install mysql
\end{verbatim}
Для PostgreSQL:
\begin{verbatim}
sudo gem install postgres
\end{verbatim}
\item Устанавливаем rubyrep:
\begin{verbatim}
sudo gem install rubyrep
\end{verbatim}
\end{enumerate}
\subsection{Настройка}
\subsubsection{Создание файла конфигурации}
Выполним команду:
\begin{verbatim}
rubyrep generate myrubyrep.conf
\end{verbatim}
Команда generate создала пример конфигурации в файл myrubyrep.conf:
\begin{verbatim}
RR::Initializer::run do |config|
config.left = {
:adapter => 'postgresql', # or 'mysql'
:database => 'SCOTT',
:username => 'scott',
:password => 'tiger',
:host => '172.16.1.1'
}
config.right = {
:adapter => 'postgresql',
:database => 'SCOTT',
:username => 'scott',
:password => 'tiger',
:host => '172.16.1.2'
}
config.include_tables 'dept'
config.include_tables /^e/ # regexp matches all tables starting with e
# config.include_tables /./ # regexp matches all tables
end
\end{verbatim}
В настройках просто разобраться. Базы данных делятся на <<left>> и <<right>>.
Через config.include\_tables мы указываем какие таблицы включать в репликацию (поддерживает RegEx).
\subsubsection{Сканирование баз данных}
Сканирование баз данных для поиска различий:
\begin{verbatim}
rubyrep scan -c myrubyrep.conf
\end{verbatim}
Пример вывода:
\begin{verbatim}
dept 100% ......................... 0
emp 100% ......................... 1
\end{verbatim}
Таблица dept полностью синхронизирована, а emp~--- имеет одну не синхронизированую запись.
\subsubsection{Синхронизация баз данных}
Выполним команду:
\begin{verbatim}
rubyrep sync -c myrubyrep.conf
\end{verbatim}
Также можно указать только какие таблицы в базах данных синхронизировать:
\begin{verbatim}
rubyrep sync -c myrubyrep.conf dept /^e/
\end{verbatim}
Настройки политики синхронизации позволяют указывать как решать конфликты синхронизации.
Более подробно можно почитать в документации http://www.rubyrep.org/configuration.html.
\subsubsection{Репликация}
Для запуска репликации достаточно выполнить:
\begin{verbatim}
rubyrep replicate -c myrubyrep.conf
\end{verbatim}
Данная команда установить репликацию (если она не была установлена) на базы данных и запустит её.
Чтобы остановить репликацию, достаточно просто убить процесс. Даже если репликация остановлена,
все изменения будут обработаны триггерами rubyrep. После перезагрузки, все изменения
будут автоматически востановлены.
Для удаления репликации достаточно выполнить:
\begin{verbatim}
rubyrep uninstall -c myrubyrep.conf
\end{verbatim}
\subsection{Устранение неисправностей}
\subsubsection{Ошибка при запуске репликации}
При зепуске rubyrep через Ruby может возникнуть подобная ошибка:
\begin{verbatim}
$rubyrep replicate -c myrubyrep.conf
Verifying RubyRep tables
Checking for and removing rubyrep triggers from unconfigured tables
Verifying rubyrep triggers of configured tables
Starting replication
Exception caught: Thread#join: deadlock 0xb76ee1ac - mutual join(0xb758cfac)
\end{verbatim}
Это проблема с запусками потоков в Ruby. Решается двумя способами:
\begin{enumerate}
\item Запускать rubyrep через JRuby (тут с потоками не будет проблем)
\item Пофиксить rubyrep патчем:
\begin{verbatim}
--- /Library/Ruby/Gems/1.8/gems/rubyrep-1.1.2/lib/rubyrep/
replication_runner.rb 2010-07-16 15:17:16.000000000 -0400
+++ ./replication_runner.rb 2010-07-16 17:38:03.000000000 -0400
@@ -2,6 +2,12 @@
require 'optparse'
require 'thread'
+require 'monitor'
+
+class Monitor
+ alias lock mon_enter
+ alias unlock mon_exit
+end
module RR
# This class implements the functionality of the 'replicate' command.
@@ -94,7 +100,7 @@
# Initializes the waiter thread used for replication pauses
# and processing
# the process TERM signal.
def init_waiter
- @termination_mutex = Mutex.new
+ @termination_mutex = Monitor.new
@termination_mutex.lock
@waiter_thread ||= Thread.new {@termination_mutex.lock;
self.termination_requested = true}
%w(TERM INT).each do |signal|
\end{verbatim}
\end{enumerate}