Оглавление
Введение
Что такое PostgreSQL?
Настройка производительности
Введение
Настройка сервера
Диски и файловые системы
Утилиты для тюнинга PostgreSQL
Оптимизация БД и приложения
Заключение
Индексы
Типы индексов
Возможности индексов
Партиционирование
Введение
Теория
Практика использования
Pg_partman
Pgslice
Заключение
Репликация
Введение
Потоковая репликация (Streaming Replication)
PostgreSQL Bi-Directional Replication (BDR)
Pglogical
Slony-I
Londiste
Bucardo
Заключение
Шардинг
Введение
PL/Proxy
Postgres-X2
Postgres-XL
Citus
Greenplum Database
Заключение
PgPool-II
Введение
Установка и настройка
Настройка репликации
Параллельное выполнение запросов
Master-slave режим
Онлайн восстановление
Заключение
Мультиплексоры соединений
Введение
PgBouncer
PgPool-II vs PgBouncer
Кэширование в PostgreSQL
Введение
Pgmemcache
Заключение
Расширения
Введение
PostGIS
pgSphere
HStore
PLV8
Pg_repack
Pg_prewarm
Smlar
Multicorn
Pgaudit
Ltree
PostPic
Fuzzystrmatch
Pg_trgm
Cstore_fdw
Postgresql-hll
Tsearch2
PL/Proxy
Texcaller
Pgmemcache
Prefix
Dblink
Postgres_fdw
Pg_cron
PGStrom
ZomboDB
Заключение
Бэкап и восстановление PostgreSQL
Введение
SQL бэкап
Бэкап уровня файловой системы
Непрерывное резервное копирование
Утилиты для непрерывного резервного копирования
Заключение
Стратегии масштабирования для PostgreSQL
Введение
Проблема чтения данных
Проблема записи данных
Заключение
Утилиты для PostgreSQL
Введение
Pgcli
Pgloader
Postgres.app
pgAdmin
PostgREST
Ngx_postgres
Заключение
Полезные мелочи
Введение
Мелочи
Литература
Р
абот
а
с
P
ostgreSQL:
настройк
а
и
масшт
абирование
А.
Ю.
Васильев
ak
a
leopard
Creativ
e
Commons
Attribution-Noncommercial
4.0
In
ternational
2017
Ог
лавление
Ог
лавление
1
1
Введение
2
1.1
Что
т
акое
P
ostgreSQL?
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
2
2
Настройк
а
производительности
4
2.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
4
2.2
Настройк
а
сервера
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
7
2.3
Диски
и
файловые
системы
. . .
. .
. .
. .
. .
. .
. .
. .
. .
17
2.4
Утилиты
для
тюнинг
а
PostgreSQL
. .
. .
. .
. .
. .
. .
. .
.
18
2.5
Оптимизация
БД
и
прило
жения
. .
. .
. .
. .
. .
. .
. .
. .
22
2.6
Заключение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
33
3
Индек
сы
34
3.1
Типы
индек
сов
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
35
3.2
Возмо
жности
индексов
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
42
4
Партиционирование
44
4.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
44
4.2
Т
еория
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
45
4.3
Практик
а
использования
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
46
4.4
Pg_partman
. . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
53
4.5
Pgslice
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
57
4.6
Заключение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
62
5
Р
епликация
63
5.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
63
5.2
Поток
овая
репликация
(Streaming
Replication)
. .
. .
. .
. .
65
5.3
P
ostgreSQL
Bi-Directional
Replication
(BDR)
. .
. .
. .
. .
.
78
5.4
Pglogical
. . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
80
5.5
Slon
y-I
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
84
1
Ог
лавление
5.6
Londiste
. . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
94
5.7
Bucardo
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
108
5.8
Заключение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
116
6
Шар
динг
117
6.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
117
6.2
PL/Pro
xy
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
118
6.3
P
ostgres-X2
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
124
6.4
P
ostgres-XL
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
135
6.5
Citus
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
136
6.6
Greenplum
Database
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
143
6.7
Заключение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
157
7
PgP
o
ol-I
I
158
7.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
158
7.2
У
ст
ановка
и
настройк
а
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
159
7.3
Настройк
а
репликации
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
161
7.4
Параллельное
выполнение
запросов
. .
. .
. .
. .
. .
. .
. .
163
7.5
Master-sla
ve
режим
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
169
7.6
Онлайн
восст
ановление
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
170
7.7
Заключение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
173
8
Му
ль
типлексоры
соединений
174
8.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
174
8.2
PgBouncer
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
174
8.3
PgP
o
ol-I
I
vs
PgBouncer
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
176
9
Кэширование
в
P
ostgreSQL
177
9.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
177
9.2
Pgmemcac
he
. . . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
178
9.3
Заключение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
184
10 Р
асширения
185
10.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
185
10.2
P
ostGIS
. . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
185
10.3
pgSphere
. . . .
. .
. .
. .
. .
. .
.
. .
. .
. .
. .
. .
. .
. .
.
188
10.4
HStore
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
190
10.5
PL
V8
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
192
10.6
Pg_repac
k
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
198
10.7
Pg_prew
arm
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
206
10.8
Smlar
. . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
208
10.9
Multicorn
. . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
215
10.10
Pgaudit
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
222
10.11
Ltree
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
223
10.12
P
ostPic
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
229
2
Ог
лавление
10.13
F
uzzystrmatch
. . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
229
10.14
Pg_trgm
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
231
10.15
Cstore_fdw
. . . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
234
10.16
P
ostgresql-hll
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
237
10.17
T
search2
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
242
10.18
PL/Pro
xy
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
243
10.19
T
excaller
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
243
10.20
Pgmemcac
he
. .
. .
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
244
10.21
Prefix
. . . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
244
10.22
Dblink
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
246
10.23
P
ostgres_fdw
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
250
10.24
Pg_cron
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
252
10.25
PGStrom
. . . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
254
10.26
Zom
b
oDB
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
255
10.27
Заключение
. . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
258
11 Бэк
ап
и
восстановление
PostgreSQL
259
11.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
259
11.2
SQL
бэк
ап
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
260
11.3
Бэк
ап
уровня
файловой
системы
.
. .
. .
. .
. .
. .
. .
. .
.
262
11.4
Непрерывное
резервное
к
опирование
.
. .
. .
. .
. .
. .
. .
263
11.5
Утилиты
для
непрерывного
резервного
к
опирования
. .
. .
265
11.6
Заключение
. . . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
280
12 Стратегии
масшт
абирования
для
PostgreSQL
281
12.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
281
12.2
Проблема
чтения
данных
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
282
12.3
Проблема
записи
данных
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
283
12.4
Заключение
. . . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
283
13 Утилиты
для
P
ostgreSQL
284
13.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
284
13.2
Pgcli
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
284
13.3
Pgloader
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
285
13.4
P
ostgres.app
. . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
285
13.5
pgA
dmin
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
285
13.6
P
ostgREST
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
285
13.7
Ngx_p
ostgres
.
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
285
13.8
Заключение
. . . .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
286
14 Полезные
мелочи
287
14.1
Введение
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
.
287
14.2
Мелочи
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
. .
287
Литература
298
3
1
Введение
Послушайте
—
и
Вы
забу
дете,
посмотрите
—
и
Вы
запомните,
с
делайте
—
и
Вы
поймете
Конфуций
Данная
книга
не
дает
ответы
на
все
вопросы
по
работе
с
PostgreSQL.
Г
лавное её
задание
—
пок
азать возмо
жности P
ostgreSQL, мето
дики на-
стройки
и
масштабиру
емости
этой
СУБД.
В
любом
случае,
выбор
метода
решения
пост
авленной
задачи
ост
ается
за
разработчик
ом
или
администра-
тором
СУБД.
1.1
Что
так
ое
P
ostgreSQL?
P
ostgreSQL
(произноситс
я
«Пост-Грес-Кью-Эль»)
—
свобо
дная
объектно-реляционная
система
управления
базами
данных
(СУБД).
P
ostgreSQL
ведёт
свою
«родословную»
от
некоммерческ
ой
СУБД
P
ostgres,
разработ
анной,
к
ак
и
многие
op
en-source
проекты,
в
Калифор-
нийск
ом
университете
в
Беркли.
К
разработк
е
P
ostgres,
на
чавшейся
в
1986
го
ду
,
имел
непосредственное
отношение
Майкл
Стоунбрейкер,
руково
ди-
тель
более
раннего
проект
а
Ingres,
на
тот
момент
уж
е
приобретённого
ком-
панией
Computer
Asso
ciates.
Само
название
«Postgres»
расшифровывалось
к
ак
«Post
Ingres»
,
соответственно,
при
создании
Postgres
были
применены
многие
уж
е
ранее
сделанные
наработки.
Стоунбрейк
ер
и
его
сту
денты
разрабатывали
новую
СУБД
в
течение
восьми
лет
с
1986
по
1994
го
д.
За
этот
перио
д
в
синтак
сис
были
введены
процедуры,
правила,
пользовательские
типы
и
многие
другие
компоненты.
Р
абота
не
прошла
даром
—
в
1995
го
ду
разработка
снова
разделилась:
Сто-
унбрейк
ер
использовал
полученный
опыт
в
создании
коммерческ
ой
СУБД
4
1.1.
Что
так
ое
P
ostgreSQL?
Illustra,
про
двиг
аемой
его
собственной
одноимённой
компанией
(приобре-
тённой
впоследствии
к
омпанией
Informix),
а
его
сту
денты
разработ
али
но-
вую
версию
Postgres
—
Postgres95,
в
которой
язык
запросов
POSTQUEL
—
наследие
Ingres
—
был
заменен
на
SQL.
В
этот
момент
разработка
Postgres95
была
выведена
за
пределы
уни-
верситет
а
и
передана
команде
энтузиастов.
С
этого
момент
а
СУБД
полу-
чила
имя,
по
д
к
оторым
она
известна
и
развиваетс
я
в
текущий
момент
—
P
ostgreSQL.
На
данный
момент
,
в
P
ostgreSQL
имеются
следующие
ограничения:
Мак
симальный
размер
базы
данных
Нет
ограничений
Мак
симальный
размер
таблицы
32
Тбайт
Мак
симальный
размер
записи
1,6
Тбайт
Мак
симальный
размер
поля
1
Гбайт
Мак
симум
записей
в
таблице
Нет
ограничений
Мак
симум
полей
в
записи
250—1600,
в
зависимости
от
типов
полей
Мак
симум
индексов
в
таблице
Нет
ограничений
Сог
ласно
резу
ль
тат
ам
автоматизированного
исследования
различного
ПО на предмет ошибок, в ис
хо
дном к
оде P
ostgreSQL было найдено 20
проблемных
мест
на
775000
строк
исх
о
дного
к
о
да
(в
среднем,
одна
ошибка
на
39000
строк
ко
да).
Для
сравнения:
MySQL
—
97
проблем,
одна
ошибк
а
на
4000
строк
ко
да;
F
reeBSD
(целиком)
—
306
проблем,
одна
ошибк
а
на
4000
строк
к
ода;
Linux
(только
ядро)
—
950
проблем,
о
дна
ошибк
а
на
10
000
строк
к
ода.
5
2
Настройк
а
произво
дительности
Т
еперь
я
знаю
тысячу
способов,
к
ак
не
нужно
делать
лампу
накаливания
Т
омас
Алва
Эдисон
2.1
Введение
Ск
орость
работы,
вообще
говоря,
не
является
основной
причиной
ис-
пользования
реляционных
СУБД.
Более
того,
первые
реляционные
базы
работ
али
медленнее
своих
предшественников.
Выбор
этой
технологии
был
вызван
ск
орее:
∙
возмо
жностью
возложить
поддер
жку
целостности
данных
на
СУБД;
∙
независимостью
логическ
ой
структуры
данных
от
физическ
ой;
Эти
особенности
позволяют
сильно
упростить
написание
прилож
ений,
но
требуют
для
своей
реализации
дополнительных
ресурсов.
Т
аким образом,
прежде
чем иск
ать ответ
на
вопрос
«к
ак заст
авить
РСУБД
работ
ать
быстрее
в
моей зада
че?»
,
следу
ет ответить
на
вопрос
«нет
ли
более
по
дхо
дящего
средства
для
решения
моей
зада
чи,
чем
РСУБД?»
Иног
да
использование
другого
средства
потребует
меньше
уси-
лий,
чем
настройк
а
производительности.
Данная
г
лава
посвящена
возмо
жност
ям
повышения
производитель-
ности
P
ostgreSQL.
Г
лава
не
претендует
на
исчерпывающее
изло
жение
вопроса,
наиболее
полным
и
точным
рук
оводством
по
использованию
P
ostgreSQL
являетс
я,
к
онечно,
официальная
документ
ация
и
официаль-
ный
F
AQ
.
Т
акже
существу
ет
анг
ло
язычный
список
рассылки
p
ostgresql-
p
erformance,
посвящённый
именно
этим
вопросам.
Г
лава
состоит
из
двух
разделов, первый из
к
оторых ориентирован ск
орее на администратора,
6
2.1.
Введение
второй
—
на
разработчика
прило
жений.
Р
екоменду
етс
я
прочесть
оба
раз-
дела:
отнесение
многих
вопросов
к
к
акому-то
о
дному
из
них
весьма
у
слов-
но.
Не
используйте
настройки
по
умолчанию
По
умолчанию
P
ostgreSQL
ск
онфигурирован
таким
образом,
чтобы
он
мог
быть
запущен
практически
на
любом
к
омпьютере
и
не
слишком
ме-
шал
при
этом
работе
других
прилож
ений.
Это
особенно
касаетс
я
исполь-
зу
емой
памяти.
Настройки
по
умолчанию
по
дх
одят
только
для
следующе-
го
использования:
с
ними
вы
смож
ете
проверить,
работает
ли
у
становк
а
P
ostgreSQL,
создать
тестовую
базу
уровня
записной
книжки
и
потрени-
роватьс
я писать
к ней
запросы. Если
вы
собираетесь
разрабатывать
(а
тем
более
запуск
ать
в
работу)
реальные
прилож
ения,
то
настройки
при-
дётс
я радик
ально изменить.
В дистрибутиве
P
ostgreSQL, к
сож
алению,
не
пост
авляются
файлы с
«рекоменду
емыми»
настройк
ами.
Вообще
го-
вор
я,
такие
файлы
создать
весьма
сложно,
т
.к.
оптимальные
настройки
к
онкретной
уст
ановки
PostgreSQL
бу
дут
определятьс
я:
∙
к
онфигурацией
к
омпьютера;
∙
объёмом
и
типом
данных,
хранящихс
я
в
базе;
∙
отношением
числа
запросов
на
чтение
и
на
запись;
∙
тем,
запущены
ли
другие
требовательные
к
ресурсам
процессы
(на-
пример,
веб-сервер);
Используйте
акту
альную
версию
сервера
Если
у
вас
стоит
уст
аревшая
версия
P
ostgreSQL,
то
наибольшего
у
ск
о-
рения
работы
вы
смо
жете
добиться,
обновив
её
до
текущей.
Ук
аж
ем
лишь
наиболее
зна
чительные
из
связанных
с
производительностью
изменений.
∙
В
версии
7.4
была
уск
орена
работа
многих
сложных
запросов
(вклю-
чая
печально
известные
по
дзапросы
IN/NOT
IN);
∙
В
версии
8.0
были
внедрены
метки
восстановления,
у
лучшение
управления
буфером,
CHECKPOINT
и
V
A
CUUM
у
лучшены;
∙
В
версии
8.1
был
у
лучшен
о
дновременный
доступ
к
разделяемой
па-
мяти,
автоматическое
использование
индек
сов
для
MIN()
и
MAX(),
pg_auto
v
acuum
внедрен
в
сервер
(автоматизирован),
повышение
произво
дительности
для
секционированных
таблиц;
∙
В
версии
8.2
была
у
лучшена
ск
орость
множ
ества
SQL
запросов,
усо-
вершенствован
сам
язык
запросов;
∙
В
версии
8.3
внедрен
полнотек
стовый
поиск,
по
ддержк
а
SQL/XML
ст
андарта,
параметры
к
онфигурации
сервера
могут
быть
у
становле-
ны
на
основе
от
дельных
функций;
7
2.1.
Введение
∙
В
версии
8.4
были
внедрены
общие
табличные
выражения,
рекур-
сивные
запросы,
параллельное
восстановление,
у
лучшена произво-
дительность
для
EXISTS/NOT
EXISTS
запросов;
∙
В
версии
9.0
«асин
хронная
репли
к
ация
из
коробки»
,
V
A
CUUM/V
ACUUM
FULL
ст
али
быстрее,
расширены
хранимые
процедуры;
∙
В
версии 9.1
«синхронная
реплик
ация из
к
оробки»
, нелогиру
емые
т
аблицы
(очень
быстрые
на
запись,
но
при
падении
БД
данные
мо-
гут
пропасть),
новые
типы
индексов,
наследование
таблиц
в
запросах
теперь
мож
ет
вернутьс
я
многозна
чительно
отсортированные
резу
ль-
т
аты,
позволяющие
оптимизации
MIN/MAX;
∙
В
версии
9.2
«каск
адная
репликация
из
коробки»
,
сканирование
по
индек
су
,
JSON
тип
данных,
типы
данных
на
диапазоны,
сортировк
а
в
памяти
у
лучшена
на
25%,
уск
орена
команда
COPY;
∙
В
версии
9.3
materialized
view,
доступные
на
запись
внешние
табли-
цы,
перехо
д
с
использования
SysV
shared
memory
на
POSIX
shared
memory
и
mmap,
cокращено
время
распространения
реплик,
а
т
ак-
ж
е
зна
чительно
уск
орена
передача
управления
от
запасного
сервера
к первичному
, увеличена
произво
дительность и
у
лучшена система
блокировок
для
внешних
ключей;
∙
В
версии
9.4
по
явился
новый
тип
поля
JSONB
(бинарный
JSON
с
по
ддержк
ой
индек
сов),
логическ
ое
деко
дирование
для
реплик
ации,
GIN
индекс
в
2
раза
меньше
по
размеру
и
в
3
раза
быстрее,
неблоки-
руюшие
обновление
materialized
view,
по
ддержк
а
Linux
Huge
Pages;
∙
В
версии
9.5
д
обавлена
поддер
жк
а
UPSER
T,
Ro
w
Level
Securit
y
,
CUBE,
ROLLUP
,
GR
OUPING
SETS
функции,
T
ABLESAMPLE,
BRIN
индекс,
уск
орена
скорость
работы
индек
сов
для
тек
стовых
и
цифровых
полей;
∙
В
версии
9.6
добавлена
поддер
жка
параллелизации нек
оторых
за-
просов,
что
позволяет
использование
неск
олько
ядер
(CPU
core)
на
сервере,
чтобы
возвращать
резу
льт
аты
запроса
быстрее,
полнотек-
стовый
поиск
по
ддерживает
фразы,
новая
опция
«remote_apply»
для
синхронной
репликации,
которая
позволяет
дождатьс
я,
пока
запрос
завершитс
я
на
слейве;
Следу
ет
т
акже
отметить,
что
большая
часть
излож
енного
в
статье
ма-
териала
относитс
я
к
версии
сервера
не
ниже
9.0.
Стоит
ли
довер
ять
тестам
производительности
Перед тем,
как заниматьс
я
настройкой сервера, вполне
естественно
ознак
омиться
с
опубликованными
данными
по
произво
дительности,
в
том
числе в
сравнении с
другими
СУБД. К
со
жалению,
многие тесты
слу-
ж
ат
не
столько
для
облегчения
вашего
выбора,
ск
олько
для
про
движения
8
2.2.
Настройка
сервера
к
онкретных
про
дуктов
в
ка
честве
«самых
быстрых»
.
При
изучении
опуб-
лик
ованных
тестов
в
первую
очередь
обратите
внимание,
соответствует
ли
величина
и
тип
нагрузки,
объём
данных
и
сло
жность
запросов
в
те-
сте
тому
,
что
вы
собираетесь
делать
с
базой?
Пусть,
например,
обычное
использование
вашего
прилож
ения
подразумевает
нескольк
о
одновремен-
но
работающих
запросов
на
обновление
к
таблице
в
миллионы
записей.
В
этом
случае
СУБД,
которая
в
нескольк
о
раз
быстрее
всех
остальных
ищет
запись
в
т
аблице
в
тыс
ячу
записей,
мож
ет
оказатьс
я
не
лучшим
выбором.
Ну
и
нак
онец,
вещи,
которые
должны
сразу
насторожить:
∙
Т
естирование
у
ст
аревшей
версии
СУБД;
∙
Использование
настроек
по
умолчанию
(или
отсутствие
информации
о
настройк
ах);
∙
Т
естирование
в
о
днопользовательском
режиме
(если,
конечно,
вы
не
предполаг
аете
использовать
СУБД
именно
так);
∙
Использование
расширенных
возмо
жностей
одной
СУБД
при
игно-
рировании
расширенных
возмо
жностей
другой;
∙
Использование
заведомо
медленно
работ
ающих
запросов
(раздел
«
2.5
Оптимизация
к
онкретных
запросов
»);
2.2
Настройк
а
сервера
В
этом
разделе
описаны
рекоменду
емые
зна
чения
параметров,
влияю-
щих
на
производительность
СУБД.
Эти
параметры
обычно
уст
анавлива-
ютс
я
в
конфигурационном
файле
p
ostgresql.conf
и
влияют
на
все
базы
в
текущей
у
становк
е.
Использу
емая
память
Общий
буфер
сервера:
shared_buffers
P
ostgreSQL
не
чит
ает
данные
напрямую
с
диска
и
не
пишет
их
сразу
на диск. Данные загруж
аются в общий
буфер сервера, нах
одящийс
я в
разделяемой
памяти,
серверные
процессы
чит
ают
и
пишут
блоки
в
этом
буфере,
а
затем
уж
е
изменения
сбрасываются
на
диск.
Если
процессу
нуж
ен
доступ
к
таблице,
то
он
сна
чала
ищет
нужные
блоки
в
общем
буфере.
Если
блоки
присутствуют
,
то
он
мож
ет
про
дол-
ж
ать
работу
,
если
нет
—
делаетс
я
системный
вызов
для
их
загрузки.
За-
груж
аться
блоки
могут
к
ак
из
файлового
кэша
ОС,
так
и
с
диск
а,
и
эт
а
операция
мо
жет
оказатьс
я
весьма
«дорогой»
.
Если
объём
буфера
недост
аточен
для
хранения
часто
использу
емых
рабочих
данных,
то
они
бу
дут
посто
янно
писаться
и
чит
аться
из
кэша
ОС
или
с
диск
а,
что
крайне
отрицательно
скаж
ется
на
производительности.
9
2.2.
Настройка
сервера
В
то
же
время
не
следу
ет
у
ст
анавливать
это
зна
чение
слишком
боль-
шим:
это
НЕ
вся
память,
которая
нужна
для
работы
P
ostgreSQL,
это
толь-
к
о размер
разделяемой
между
процессами P
ostgreSQL
памяти,
которая
нужна
для
выполнения
активных
операций.
Она
должна
занимать
мень-
шую
часть
оперативной
памяти
вашего
компьютера,
т
ак
как
P
ostgreSQL
полаг
ается
на
то,
что
операционная
система
кэширует
файлы,
и
не
ст
ара-
етс
я
дублировать
эту
работу
.
Кроме
того,
чем
больше
памяти
бу
дет
отдано
по
д
буфер,
тем
меньше
останетс
я
операционной
системе
и
другим
прило-
ж
ениям,
что
мож
ет
привести
к
своппингу
.
К
со
жалению,
чтобы
знать
точное
число
shared_buffers
,
нужно
учесть
к
оличество
оперативной
памяти
компьютера,
размер
базы
данных,
число
соединений
и
сложность
запросов,
так
что
лучше
воспользуемс
я
неск
оль-
кими
простыми
правилами
настройки.
На
выделенных
серверах
полезным
объемом
для
shared_buffers
бу
дет
зна
чение
1/4
памяти
в
системе.
Если
у
вас
большие
активные
порции
ба-
зы
данных,
сложные
запросы,
большое
число
о
дновременных
соединений,
длительные транзакции, вам доступен большой
объем оперативной па-
мяти
или
большее
количество
процессоров,
то
мо
жно
подымать
это
зна-
чение
и
мониторить
резу
льт
ат
,
чтобы
не
привести к
«деградации» (па-
дению)
произво
дительности.
Выделив
слишк
ом
много
памяти
для
базы
данных,
мы
мож
ем
получить
уху
дшение
произво
дительности,
посколь-
ку
P
ostgreSQL
такж
е
использу
ет
кэш
операционной
системы
(увеличение
данного
параметра
более
40%
оперативной
памяти
мо
ж
ет
давать
«ну
ле-
вой»
прирост
произво
дительности).
Для
тонк
ой
настройки
параметра
уст
ановите
для
него
большое
значе-
ние
и
потестируйте
базу
при
обычной
нагрузке.
Проверяйте
использование
разделяемой
памяти
при
помощи
ip
cs
или
других
утилит(например,
free
или
vmstat
).
Рек
оменду
емое
зна
чение
параметра
бу
дет
примерно
в
1,2
–2
раза
больше,
чем
мак
симум
использованной
памяти.
Обратите
внимание,
что
память
по
д
буфер
выделяется
при
запуск
е
сервера,
и
её
объём
при
работе
не
изменяется.
Учтите
т
акж
е,
что
настройки
ядра
операционной
системы
могут
не
дать
вам
выделить
большой
объём
памяти
(для
версии
P
ostgreSQL
<
9.3).
В
рук
оводстве
администратора
P
ostgreSQL
описано,
к
ак
можно
изменить
эти
настройки.
Т
акж
е
следует
помнить,
что
на
32
битной
системе
(Linux)
каждый
про-
цесс
лимитирован
в
4
ГБ
адресного
пространства,
где
х
отя
бы
1
ГБ
за-
резервирован
ядром.
Это
озна
чает
,
что
не
зависимо,
скольк
о
на
машине
памяти,
к
аждый
P
ostgreSQL
инст
анс
смож
ет
обратитьс
я
мак
симум
к
3
ГБ
памяти.
А
значит
максимум
для
shared_buffers
в
т
ак
ой
системе
—
2–2.5
ГБ.
Хочу
обратить
внимание,
что
на
Windo
ws,
большие
зна
чения
для
shared_buffers
не
столь
эффективны,
как
на
Linux
системах,
и
в
резу
ль
т
ате
лучшие
резу
льт
аты
можно
бу
дет
получить,
если
дер
жать
это
зна
чение
от-
носительно
небольшое
(от
64
МБ
до
512
МБ)
и
использовать
кэш
системы
вместо
него.
10
2.2.
Настройка
сервера
Память
для
сортировки
резу
ль
тат
а
запроса:
w
ork_mem
w
ork_mem
параметр определяет
мак
симальное к
оличество оператив-
ной
памяти,
к
оторое
мо
жет
выделить
одна
операция
сортировки,
агрег
а-
ции и
др.
Это
не разделяемая
память,
w
ork_mem
выделяется
от
дельно
на
каждую
операцию
(от
о
дного
до
нескольких
раз
за
один
запрос).
Р
а-
зумное
значение
параметра
определяетс
я
следующим
образом:
количество
доступной
оперативной
памяти
(после
того,
как
из
общего
объема
вычли
память,
требу
емую
для
других
прилож
ений,
и
shared_buffers
)
делится
на
мак
симальное
число
одновременных
запросов
умно
женное
на
среднее
чис-
ло
операций
в
запросе,
к
оторые
требуют
памяти.
Если
объём
памяти
недост
аточен
для
сортировки
некоторого
резу
ль
та-
т
а,
то
серверный
процесс
бу
дет
использовать
временные
файлы.
Если
же
объём
памяти
слишк
ом
велик,
то
это
мож
ет
привести
к
своппингу
.
Объём
памяти
задаётс
я
параметром
w
ork_mem
в
файле
p
ostgresql.conf.
Единица
измерения
параметра
—
1
кБ.
Значение
по
умолчанию
—
1024.
В
к
ачестве
на
чального
значения
для
параметра
мо
жете
взять
2–4%
доступ-
ной
памяти.
Для
веб-прилож
ений
обычно
у
станавливают
низкие
значения
w
ork_mem
,
т
ак
к
ак
запросов
обычно
много,
но
они
простые,
обычно
хва-
т
ает
от
512
до
2048
КБ.
С
другой
стороны,
прило
жения
для
поддер
жки
принятия
решений
с
сотнями
строк
в
каждом
запросе
и
десятк
ами
мил-
лионов
столбцов
в
т
аблицах
фактов
часто
требуют
work_mem
пор
ядка
500
МБ.
Для
баз
данных,
к
оторые
используются
и
так,
и
так,
этот
параметр
мо
жно
уст
анавливать
для
каждого
запроса
индивидуально,
используя
на-
стройки
сессии.
Например,
при
памяти
1–4
ГБ
рекоменду
етс
я
уст
анавли-
вать
32–128
MB.
Мак
симальное
количество
клиентов:
max_connections
Параметр
max_connections
уст
анавливает
максимальное
к
оличество
клиентов,
которые
могут
по
дключиться
к
P
ostgreSQL.
Поскольку
для
к
аждого
клиента
требуетс
я
выделять
память
(
work_mem
),
то
этот
пара-
метр
предполагает максимально возможное использование
памяти
для
всех
клиентов.
Как
правило,
P
ostgreSQL
мо
жет
поддер
живать
нескольк
о
сотен
по
дключений,
но
создание
нового
являетс
я
дорогосто
ящей
операци-
ей.
Поэтому
,
если
требуютс
я
тысячи
по
дключений,
то
лучше
использовать
пу
л
по
дключений (от
дельная
программа
или
библиотек
а для
продукт
а,
что
использу
ет
базу).
Память
для
работы
к
оманды
V
ACUUM:
maintenance_w
ork_mem
Этот
параметр
задаёт
объём
памяти,
используемый
к
омандами
V
ACUUM
,
ANAL
YZE
,
CREA
TE
INDEX
,
и
добавления
внешних
ключей.
Что-
бы
операции
выполнялись
мак
симально
быстро,
нужно
уст
анавливать
этот
параметр
тем
выше,
чем
больше
размер
таблиц
в
вашей
базе
дан-
11
2.2.
Настройка
сервера
ных.
Непло
х
о
бы
у
ст
анавливать
его
зна
чение
от
50
до
75%
размера
вашей
самой
большой
таблицы
или
индекса
или,
если
точно
определить
невоз-
мо
жно,
от
32
до
256
МБ.
Следует
уст
анавливать
большее
значение,
чем
для
w
ork_mem
.
Слишк
ом
большие
зна
чения
приведут
к
использованию
свопа.
Например,
при
памяти
1–4
ГБ
рекоменду
ется
у
станавливать
128–512
MB.
Большие
страницы:
h
uge_pages
В P
ostgreSQL, на
чиная с
версии
9.4,
по
явилась по
ддержк
а больших
страниц.
В
ОС
Lin
ux
работа
с
памятью
основывается
на
обращении
к
стра-
ницам
размер
к
оторых
равен
4kB
(на
самом
деле
зависит
от
платформы,
проверить
можно
через
getconf
P
A
GE_SIZE
).
Т
ак
вот
,
ког
да
объем
памя-
ти
переваливает
за
нескольк
о
дес
ятков,
а
то
и
сотни
гигабайт
,
управлять
ею
становитс
я
сложнее,
увеличиваютс
я
накладные
рас
х
оды
на
адресацию
памяти
и
поддер
ж
ание
страничных
таблиц.
Для
облегчения
жизни
и
бы-
ли
придуманы
большие
страницы,
размер
к
оторых
мож
ет
быть
2MB,
а
то
и
1GB.
За
счет
использования
больших
страниц
можно
получить
ощути-
мый
прирост
скорости
работы
и
увеличение
отзывчивости
в
прило
ж
ениях
к
оторые
активно
работают
с
памятью.
Вообще
запу
стить P
ostgreSQL с
по
ддер
жкой
больших
страниц
мо
ж-
но
было
и
раньше,
с
помощью
libhugetlbfs
.
Однако
теперь
есть
встроен-
ная
по
ддержк
а.
Итак,
ниже
описание
процесса
как
настроить
и
запустить
P
ostgreSQL
с
поддер
жкой
больших
страниц.
Для
на
чала
следует
убедитьс
я,
что
ядро
поддер
живает
боль-
шие
страницы.
Проверяем
конфиг
ядра
на
предмет
наличия
опций
CONFIG_HUGETLBFS
и
CONFIG_HUGETLB_P
AGE
.
Листинг
2.1
Проверка
конфиг
а
ядра
на
поддер
жку
huge
pages
Line
1
$
g
r
e
p
H
U
G
E
T
L
B
/
b
o
o
t
/
c
o
n
f
i
g
-
$
(
u
na
m
e
-
r
)
-
C
O
N
F
I
G
_
C
G
R
O
U
P
_
H
U
G
E
T
L
B
=
y
-
C
O
N
F
I
G
_
H
U
G
E
T
L
B
F
S
=
y
-
C
O
N
F
I
G
_
H
U
G
E
T
L
B
_
P
A
G
E
=
y
В
случае
отсутствия
этих
опций,
ничего
не
заработает
и
ядро
следует
пересобрать.
Очевидно, что нам
понадобитс
я P
ostgreSQL версии не
ниж
е 9.4. За
по
ддержку
больших
страниц
отвечает
параметр
h
uge_page
,
который
мо
жет
принимать
три
значения:
off
—
не
использовать
большие
страницы,
on
—
использовать
большие
страницы,
try
—
попыт
атьс
я
использовать
большие
страницы
и
в
случае
недоступности
откатитьс
я
на
использование
обычных
страниц.
Зна
чение
try
используетс
я
по
умолчанию
и
является
безопасным
вариантом.
В
случае
on
,
P
ostgreSQL
не
запу
стится,
если
большие
страницы
не
определены
в
системе
(или
их
недост
аточно).
После
перезапу
ска
базы
с
параметром
try
потребу
ется
включить
под-
дер
жку
больших
страниц
в
системе
(по
умолчанию
они
не
задействованы).
12
2.2.
Настройка
сервера
Р
асчет
страниц
приблизительный
и
здесь
следу
ет
опиратьс
я
на
то,
ск
оль-
к
о
памяти
вы
готовы
выделить
под
нужды
СУБД.
Отмечу
,
что
зна
чение
измер
яется
в
страницах
размером
2Mb,
если
вы
х
отите
выделить
16GB,
то
это
бу
дет
8000
страниц.
Официальная
документация
предлагает
опиратьс
я
на
значение
V
mPeak
из
status
файла,
к
оторый
размещен
в
/proc/PID/
директории,
соответ-
ствующей
номеру
процесса
p
ostmaster.
V
mP
eak
к
ак
следует
из
названия
это
пик
овое
значение
использования
вирту
альной
памяти.
Этот
вариант
позволяет
определить
минимальную
планку
,
от
которой
следует
отт
алки-
ватьс
я,
но
на
мой
взг
ляд
т
акой
способ
определения
тож
е
носит
случайный
х
арактер.
Листинг
2.2
Включаем
поддер
жку
hu
ge
pages
в
системе
Line
1
$
h
e
a
d
-
1
/
v
a
r
/
l
i
b
/
p
g
s
q
l
/
9
.
5
/
d
a
t
a
/
p
o
s
t
m
a
s
t
e
r
.
p
i
d
-
3
0
7
6
-
$
g
r
e
p
^V
mPe
ak
/
p
r
o
c
/
3
0
7
6
/
s
t
a
t
u
s
-
VmP
ea
k
:
4
7
4
2
5
6
3
k
B
5
$
e
c
h
o
$
(
(
4
7
4
2
5
6
3
/
2
0
4
8
+
1
)
)
-
2
3
1
6
-
$
e
c
h
o
’
v
m
.
n
r
_
h
u
g
e
p
a
g
e
s
=
2
3
1
6
’
>
>
/
e
t
c
/
s
y
s
c
t
l
.
d
/
3
0
-
p
o
s
t
g
r
e
s
q
l
.
c
o
n
f
-
$
s
y
s
c
t
l
-
p
-
-
s
y
s
t
e
m
В
ОС
Linux
есть
такж
е
система
по
менеджменту
памяти
по
д
названи-
ем
«T
ransparen
t
HugePages»
,
которая
включена
по
умолчанию.
Она
мо
ж
ет
вызывать
проблему
при
работе
с
huge
pages
для
PostgreSQL,
поэтому
ре-
к
омендуетс
я
выключать
этот
механизм:
Листинг
2.3
Отключаем
T
ransparent
HugePages
Line
1
$
e
c
h
o
n
e
v
e
r
>
/
s
y
s
/
k
e
r
n
e
l
/
m
m
/
t
r
a
n
s
p
a
r
e
n
t
_
h
u
g
e
p
a
g
e
/
d
e
f
r
a
g
-
$
e
c
h
o
n
e
v
e
r
>
/
s
y
s
/
k
e
r
n
e
l
/
m
m
/
t
r
a
n
s
p
a
r
e
n
t
_
h
u
g
e
p
a
g
e
/
e
n
a
b
l
e
d
После
этого
перезапу
скаем
P
ostgreSQL
и
смотрим
использование
боль-
ших
страниц:
Листинг
2.4
Проверяем
использование
huge
pages
Line
1
$
g
r
e
p
^
H
u
g
e
P
a
g
e
s
/
p
r
o
c
/
m
e
m
i
n
f
o
-
H
u
g
e
P
a
g
e
s
_
T
o
t
a
l
:
2
3
1
6
-
H
u
g
e
P
a
g
e
s
_
F
r
e
e
:
2
3
0
1
-
H
u
g
e
P
a
g
e
s
_
R
s
v
d
:
1
2
8
5
H
u
g
e
P
a
g
e
s
_
S
u
r
p
:
0
13
2.2.
Настройка
сервера
Прочие
настройки
∙
temp_buffers
—
буфер
под
временные
объекты,
в
основном
для
вре-
менных
т
аблиц.
Можно
уст
ановить
порядк
а
16
МБ;
∙
max_prepared_tr
ansactions
—
к
оличество
одновременно
по
дгот
авлива-
емых
транзакций
(PREP
ARE
TRANSACTION).
Можно
оставить
по
умолчанию
—
5;
∙
v
acuum_cost_delay
—
если
у
вас
большие
таблицы,
и
производит-
с
я
много
одновременных
операций
записи,
вам
мож
ет
пригодитьс
я
функция,
которая
уменьшает
затраты
на
I/O
для
V
ACUUM,
растяги-
вая
его
по
времени.
Чтобы
включить
эту
функциональность,
нужно
по
днять
значение
v
acuum_cost_dela
y
выше
0.
Используйте
разумную
задер
жку
от
50
до
200
мс.
Для
более
тонк
ой
настройки
повышайте
v
acuum_cost_page_hit
и пониж
айте
v
acuum_cost_limit
. Это
ослабит
влияние
V
A
CUUM,
увеличив
время
его
выполнения.
В
тест
ах
с
па-
раллельными
транзакциями
Ян
Вик
(Jan
Wieck)
получил,
что
при
зна
чениях
delay
—
200,
page_hit
—
6
и
limit
—100
влияние
V
ACUUM
уменьшилось
более
чем
на 80%,
но его
длительность
увеличилась
втрое;
∙
max_stac
k_depth
—
cпециальный
стек
для
сервера,
к
оторый
в
идеале
долж
ен
совпадать
с
размером
стека,
выставленном
в
ядре
ОС.
У
ста-
новк
а
большего
значения,
чем
в
ядре,
мож
ет
привести
к
ошибк
ам.
Р
екоменду
ется
уст
анавливать
2–4
MB;
∙
max_files_per_pro
cess
—
максимальное
к
оличество
файлов,
открыва-
емых
процессом
и
его
подпроцессами
в
один
момент
времени.
Умень-
шите
данный
параметр,
если
в
процессе
работы
наблюдаетс
я
сооб-
щение
«T
o
o
many
op
en
files»;
Журнал
транзакций
и
к
онтрольные
точки
Для
обеспечения
отк
азоустойчивости
СУБД
PostgreSQL,
как
и
многие
базы
данных,
использует
специальный
журнал,
в
котором
ведет
историю
изменения
данных.
Перед
тем
как
записать
данные
в
файлы
БД,
сервер
P
ostgreSQL
аккуму
лиру
ет
изменения
в
оперативной
памяти
и
записывает
в
последовательный
файл
журнала,
чтобы
не
потер
ять
их
из-за
непредви-
денного
отключения
пит
ания.
Данные
в
журнал
пишутс
я
до
того
как
пользователь
базы
данных
по-
лучит
сообщение
об
успешном
применении
изменений.
Этот
журнал
на-
зываетс
я журналом
упреждающей
записи
(W
rite-Ahead
Log
или
просто
W
AL),
а
файлы
журнала
хранятс
я
в
к
аталоге
pg_xlog
.
Т
акже
перио
ди-
чески
PostgreSQL
сбрасывает
измененные
аккуму
лированные
данные
из
оперативной
памяти
на
диск.
Этот
процесс
сог
ласования
данных
назы-
ваетс
я
к
онтрольной
точкой
(
chec
kp
oint
).
Контрольная
точк
а
выполняетс
я
т
акже
при
каждом
штатном
выключении
PostgreSQL.
14
2.2.
Настройка
сервера
В
этом
случае
нет
необх
о
димости
сбрасывать
на
диск
изменения
дан-
ных при к
аждом успешном завершении транзакции: в случае сбо
я БД
мо
жет
быть
восст
ановлена
по
записям
в
журнале.
Т
аким
образом,
данные
из
буферов
сбрасываютс
я
на
диск
при
про
х
оде
к
онтрольной
точки:
либо
при
заполнении
нескольких
(параметр
chec
kp
oint_segmen
ts
,
по
умолчанию
3)
сегментов
журнала
транзакций,
либо
через
определённый
интервал
вре-
мени
(параметр
chec
kp
oint_timeout
,
измер
яется
в
секундах,
по
умолчанию
300).
Изменение
этих
параметров
пр
ямо
не
повлияет
на
скорость
чтения,
но
мо
жет
принести
большую
пользу
,
если
данные
в
базе
активно
изменяются.
Уменьшение
к
оличества
контрольных
точек:
chec
kp
oint_segmen
ts
Если
в
базу
занос
ятся
большие
объёмы
данных,
то
контрольные
точ-
ки
могут
проис
хо
дить
слишком
часто
(«слишком
часто»
можно
опре-
делить к
ак «чаще раза в минуту»
. Вы такж
е мо
жете задать
параметр
c
heckpoint_w
arning
(в
секундах):
в
журнал
сервера
бу
дут
писатьс
я
преду-
преждения, если к
онтрольные точки проис
х
одят чаще
заданного). При
этом
произво
дительность
упадёт
из-за
посто
янного
сбрасывания
на
диск
данных
из
буфера.
Для
увеличения
интервала
между
контрольными
точками
нужно
увеличить
к
оличество
сегментов
журнала
транзакций
через
параметр
c
heckpoint_segmen
ts
. Данный
параметр определяет
количество
сегментов
(к
аждый
по
16
МБ)
лога
транзакций
между
к
онтрольными
точк
ами.
Этот
параметр
не
имеет
особого
значения
для
базы
данных,
предназна
ченной
преимущественно
для
чтения,
но
для баз
данных
со мно
жеством
тран-
закций
увеличение
этого
параметра
мо
жет
оказатьс
я
жизненно
необх
о
ди-
мым.
В
зависимости
от
объема
данных
у
становите
этот
параметр
в
диа-
пазоне
от
12
до
256
сегментов
и,
если
в
логе
по
являютс
я
предупреждения
(w
arning)
о
том,
что
к
онтрольные
точки
проис
х
одят
слишком
часто,
по-
степенно
увеличивайте
его.
Место,
требу
емое
на
диске,
вычисляется
по
форму
ле
(
chec
kp
oint_segmen
ts
*
(2
+
chec
kp
oint_completion_target)
+
1)
*
16
МБ,
так
что
убедитесь,
что
у
вас
дост
аточно
свобо
дного
места.
Например,
если
вы
выставите
зна
чение
32,
вам
потребу
ется
больше
1
ГБ
дискового
пространства.
Следу
ет
т
акж
е
отметить,
что
чем
больше
интервал
между
к
онтроль-
ными
точк
ами,
тем
дольше
бу
дут
восст
анавливатьс
я
данные
по
журналу
транзакций
после
сбо
я.
На
чиная
с
версии
9.5
chec
kp
oint_segmen
ts
был
заменен
на
параметры
min_w
al_size
и
max_w
al_size
.
Т
еперь
система
мо
ж
ет
автоматически
сама
решать
скольк
о
chec
kp
oint_segmen
ts
требу
ется
хранить
(вычислять
по
ра-
нее
приведенной
форму
ле
от
ук
азанного
размера).
Преимуществом
этого
являетс
я
то,
что
вы
мож
ете
уст
ановить
max_w
al_size
очень
большим,
но
система
не
бу
дет
на
самом
деле
потреблять
ук
азанное
количество
места
на
ж
естк
ом
диске,
если
в
этом
нет
никак
ой
необ
х
одимости.
min_w
al_size
15
2.2.
Настройка
сервера
у
станавливает
минимальный
размер
места,
который
бу
дет
использовать-
с
я сегментами (мо
жно отключить т
акую автонастройку
, у
становив для
min_w
al_size
и
max_wal_size
одинак
овое
значение).
fsync,
sync
hronous_commit
и
стоит
ли
их
трогать
Для
увеличения
производительности
наиболее
радикальное
из
возмо
ж-
ных
решений
—
выставить
зна
чение
«off»
параметру
fsync
.
При
этом
запи-
си
в
журнале
транзакций
не
бу
дут
прину
дительно
сбрасываться
на
диск,
что
даст
большой
прирост
ск
орости
записи.
Учтите:
вы
жертву
ете
надёж-
ностью,
в
случае
сбоя
целостность
базы
бу
дет
нарушена,
и
её
придётся
восст
анавливать
из
резервной
к
опии!
Использовать
этот
параметр
реко-
менду
ется
лишь
в
том
случае,
если
вы
всецело
довер
яете
своему
«ж
елезу»
и
своему
источнику
бесперебойного
пит
ания.
Ну
или
если
данные
в
базе
не
предст
авляют
для
вас
особой
ценности.
Параметр
synchronous_commit
определяет
нужно
ли
ждать
W
AL
запи-
си
на
диск
перед
возвратом
успешного
завершения
транзакции
для
по
д-
ключенного
клиент
а.
По
умолчанию
и
для
безопасности
данный
параметр
у
становлен
в
«on»
(включен).
При
выключении
данного
параметра
(«off»)
мо
жет
существовать
задержк
а
между
моментом,
к
ог
да
клиенту
бу
дет
со-
общено
об
у
спехе
транзакции
и
ког
да
та
самая
транзакция
действительно
г
арантированно
и
безопасно
записана
на
диск
(мак
симальная
задер
жка
—
w
al_writer_delay
*
3
).
В
от
личие
от
fsync
,
отключение
этого
параметра
не
создает
риск
крах
а
базы
данных:
данные
могут
быть
потеряны
(послед-
ний
набор
транзакций),
но
базу
данных
не
придетс
я
восст
анавливать
после
сбо
я
из
бэкапа.
Т
ак
что
sync
hronous_commit
мож
ет
быть
полезной
альтер-
нативой,
ког
да
произво
дительность
важнее,
чем
точная
уверенность
в
со-
г
ласовании
данных
(данный
режим
можно
назвать
«режимом
MongoDB»:
изна
чально
все
клиенты
для
MongoDB
не
проверяли
успешность
записи
данных
в
базу
и
за
счет
этого
достигалась
хорошая
скорость
для
бенчмар-
к
ов).
Прочие
настройки
∙
commit_dela
y
(в
микросекундах,
0
по
умолчанию)
и
commit_siblings
(5
по
умолчанию)
определяют
задержку
между
попаданием запи-
си в буфер
журнала транзакций
и сбросом
её на
диск. Если при
у
спешном
завершении
транзакции
активно
не
менее
commit_siblings
транзакций,
то
запись
бу
дет
задер
жана
на
время
commit_dela
y
.
Если
за
это
время
завершитс
я
друг
ая
транзакция,
то
их
изменения
бу
дут
сброшены
на
диск
вместе,
при
помощи
о
дного
системного
вызова.
Эти
параметры
позволят
уск
орить
работу
,
если
параллельно
выпол-
няетс
я
много
«мелких»
транзакций;
16
2.2.
Настройка
сервера
∙
w
al_sync_metho
d
Метод,
который
использу
ется
для
прину
дительной
записи
данных
на
диск.
Если
fsync=off
,
то
этот
параметр
не
исполь-
зу
ется.
Возможные
значения:
–
op
en_datasync
—
запись
данных
методом
op
en()
с
параметром
O_DSYNC
;
–
fdatasync
—
вызов
мето
да
fdatasync()
после
каждого
commit;
–
fsync_writethrough
—
вызов
fsync()
после
каждого
commit,
игно-
риру
я
параллельные
процессы;
–
fsync
—
вызов
fs
ync()
после
к
аждого
commit;
–
op
en_sync
—
запись
данных
мето
дом
op
en()
с
параметром
O_SYNC
;
Не
все
эти
методы
доступны
на
разных
ОС.
По
умолчанию
уст
анав-
ливаетс
я
первый,
который
доступен
для
системы;
∙
full_page_writ
es
У
становите
данный
параметр
в
«off»
,
если
fsync=off
.
Ина
че,
ког
да
этот
параметр
«on»
,
PostgreSQL
записывает
содер
жи-
мое
каждой
записи
в
журнал
транзакций
при
первой
модифик
ации
т
аблицы.
Это
необх
о
димо,
поскольку
данные
могут
записатьс
я
лишь
частично,
если
в
х
оде
процесса
«упала»
ОС.
Это
приведет
к
тому
,
что
на
диск
е
ок
ажутс
я
новые
данные
смешанные
со
ст
арыми.
Строк
ового
уровня
записи
в
журнал
транзакций
мож
ет
быть
недостаточно,
что-
бы
полностью
восст
ановить
данные
после
«падения»
.
full_page_writes
г
арантирует
корректное
восст
ановление,
ценой
увеличения
записы-
ваемых
данных
в
журнал
транзакций
(Единственный
способ
сниж
е-
ния
объема
записи
в
журнал
транзакций
заключаетс
я
в
увеличении
c
heckpoint_in
terv
al
);
∙
w
al_buffers
Количество
памяти,
используемое
в
Shared
Memory
для
ведения
транзакционных
логов
(буфер
нах
одитс
я
в
разделяемой
па-
мяти
и
являетс
я
общим
для
всех
процессов).
Стоит
увеличить
буфер
до
256–512
кБ,
что
позволит
лучше
работа
ть
с
большими
транзакци-
ями.
Например,
при
доступной
памяти
1–4
ГБ
рек
омендуетс
я
у
ста-
навливать
256–1024
КБ;
Планировщик
запросов
Следующие настройки
помог
ают планировщику запросов
правильно
оценивать
стоимости
различных
операций
и
выбирать
оптимальный
план
выполнения
запроса.
Существуют
3
настройки
планировщика,
на
которые
стоит
обратить
внимание:
∙
default_statistics_target
—
этот
параметр
задаёт
объём
статистики,
со-
бираемой
к
омандой
ANAL
YZE
.
Увеличение
параметра
заставит
эту
к
оманду
работать
дольше,
но
мо
жет
позволить
оптимизатору
стро-
ить
более
быстрые
планы,
используя
полученные
дополнительные
данные.
Объём
статистики
для
к
онкретного
поля
мо
жет
быть
задан
к
омандой
AL
TER
T
ABLE
...
SET
ST
A
TISTICS
;
17
2.2.
Настройка
сервера
∙
effectiv
e_cac
he_size
—
этот
параметр
сообщает
PostgreSQL
примерный
объём
файлового
кэша
оп
ерационной
системы,
оптимизатор
исполь-
зу
ет
эту
оценку
для
построения
плана
запроса
(указывает
планиров-
щику
на
размер
самого
большого
объекта
в
базе
данных,
который
теоретически
мо
жет
быть
зак
еширован).
Пусть
в
вашем
к
омпьютере
1.5
ГБ
памяти,
параметр
shared_buffers
уст
ановлен
в
32
МБ,
а
па-
раметр
effective_cac
he_size
в
800
МБ.
Если
запросу
нужно
700
МБ
данных,
то
PostgreSQL
оценит
,
что
все
нужные
данные
уж
е
есть
в
памяти
и
выберет
более
агрессивный
план
с
использованием
индек-
сов
и
merge
joins.
Но
если
effectiv
e_cache_size
бу
дет
всего
200
МБ,
то
оптимизатор
вполне
мож
ет
выбрать
более
эффективный
для
диско-
вой
системы
план,
включающий
полный
просмотр
т
аблицы.
На
выделенном
сервере
имеет
смысл
выст
авлять
effective_cac
he_size
в
2/3
от
всей
оперативной
памяти;
на
сервере
с
другими
прилож
ениями
сна
чала
нужно
вычесть
из
всего
объема
RAM
размер
дискового
кэша
ОС
и
память,
занятую
ост
альными
процессами;
∙
random_page_cos
t
— переменная, ук
азывающая на
у
словную стои-
мость
индексного
доступа
к
страницам
данных.
На
серверах
с
быст-
рыми
диск
овыми
массивами
имеет
смысл
уменьшать
изначальную
настройку
до
3.0,
2.5
или
даже
до
2.0.
Если
же
активная
часть
вашей
базы
данных
намного
больше
размеров
оперативной
памяти,
попро-
буйте
по
днять
значение
параметра.
Можно
подойти
к
выбору
опти-
мального
значения
и
со
стороны
произво
дительности
запросов.
Если
планировщик
запросов
чаще,
чем
необх
о
димо,
предпочитает
после-
довательные
просмотры
(sequential
scans)
просмотрам
с
использова-
нием
индек
са
(index
scans),
понижайте
значение.
И
наоборот
,
если
планировщик
выбирает
просмотр
по
медленному
индексу
,
к
ог
да
не
долж
ен
этого
делать,
настройку
имеет
смысл
увеличить.
После
из-
менения
тщательно
тестируйте
резу
ль
таты
на
максимально
широк
ом
наборе
запросов.
Никог
да
не
опу
скайте
значение
random_page_cost
ниж
е
2.0;
если
вам
к
ажетс
я,
что
random_page_cost
нужно
еще
пони-
ж
ать,
разумнее
в
этом
случае
менять
настройки
ст
атистики
плани-
ровщик
а.
Сбор
ст
атистики
У
P
ostgreSQL
т
акж
е
есть
специальная
подсистема
—
сборщик
статисти-
ки,
—
которая
в
реальном
времени
собирает
данные
об
активности
сервера.
Поск
ольку
сбор
статистики
создает
дополнительные
накладные
расх
оды
на
базу
данных,
то
система
мо
жет
быть
настроена
к
ак
на
сбор,
так
и
не
сбор
статистики
вообще.
Эта
система
к
онтролируетс
я
следующими
пара-
метрами,
принимающими
зна
чения
true
/
false
:
∙
trac
k_coun
ts
—
включать
ли
сбор
статистики.
По
умолчанию
вклю-
чён,
поскольку
auto
v
acuum
демону
требуетс
я
сбор
ст
атистики.
От-
18
2.3.
Диски
и
файловые
системы
ключайте,
только
если
статистик
а
вас
совершенно
не
интересует
(к
ак
и
auto
v
acuum);
∙
trac
k_functions
—
отслеживание
использования
определенных
поль-
зователем
функций;
∙
track_activities
—
передавать
ли
сборщику
ст
атистики
информацию
о
текущей
выполняемой
команде
и
времени
начала
её
выполнения.
По
умолчанию
эт
а
возмо
жность
включена.
Следует
отметить,
что
эт
а
информация
бу
дет
доступна
тольк
о
привилегированным
пользо-
вателям
и
пользователям,
от
лица
которых
запущены
команды,
т
ак
что
проблем
с
безопасностью
быть
не
должно;
Данные,
полученные
сборщиком
ст
атистики,
доступны
через
специаль-
ные
системные
предст
авления.
При
уст
ановк
ах
по
умолчанию
собираетс
я
очень
мало
информации,
рек
омен
ду
ется
включить
все
возможности:
до-
полнительная
нагрузк
а
бу
дет
невелик
а,
в
то
время
как
полученные
дан-
ные
позволят
оптимизировать
использование
индек
сов
(а
т
акж
е
помогут
оптимальной
работе
auto
v
acuum
демону).
2.3
Диски
и
файловые
системы
Очевидно,
что
от
к
ачественной
дисковой
по
дсистемы
в
сервере
БД
за-
висит
немалая
часть
производительности.
Вопросы
выбора
и
тонкой
на-
стройки
«ж
елеза»
,
впрочем,
не
являются
темой
данной
г
лавы,
ограничим-
с
я
уровнем
файловой
системы.
Единого
мнения
насчёт
наиболее
подх
о
дящей
для
PostgreSQL
файло-
вой
системы
нет
,
поэтому
рекоменду
ется
использовать
ту
,
которая
лучше
всего
по
ддерживаетс
я
вашей
операционной системой.
При этом
учтите,
что
современные
журналирующие
файловые
системы
не
намного
медлен-
нее
нежурналирующих,
а
выигрыш
—
быстрое
восстановление
после
сбо-
ев
—
от
их
использования
велик.
Вы
легко
мо
жете
получить
выигрыш
в
произво
дительности
без
побоч-
ных
эффектов,
если
примонтируете
файловую
систему
,
содер
ж
ащую
базу
данных,
с
параметром
noatime
(но
при
этом
не
бу
дет
отслеживаться
время
последнего
доступа
к
файлу).
Перенос
журнала
транзакций
на
от
дельный
диск
При
доступе
к
диску
изрядное
время
занимает
не
только
собственно
чтение
данных,
но
и
перемещение
магнитной
головки.
Если
в
вашем
сервере
есть
нескольк
о
физических
диск
ов
(нескольк
о
логических
разделов
на
о
дном
диск
е
здесь,
очевидно,
не
помогут:
головк
а
всё
равно
бу
дет
одна),
то
вы
мож
ете
разнести
файлы
базы
данных
и
жур-
нал
транзакций
по
разным
дискам.
Данные
в
сегменты
журнала
пишутс
я
19
2.4.
Утилиты
для
тюнинга
PostgreSQL
последовательно,
более
того, записи
в журнале
транзакций
сразу
сбра-
сываютс
я
на
диск,
поэтому
в
случае
нах
ождения
его
на
от
дел
ьном
диске
магнитная
головк
а
не
бу
дет
лишний
раз
двигатьс
я,
что
позволит
у
скорить
запись.
Пор
ядок
действий:
∙
Ост
ановите
сервер
(!);
∙
Перенесите
кат
алоги
pg_clog
и
pg_xlog
,
нахо
дящийся
в к
аталоге
с
базами
данных,
на
другой
диск;
∙
Создайте
на
ст
аром
месте
символическую
ссылку;
∙
Запу
стите
сервер;
Примерно
таким
же
образом
мо
жно
перенести
и
часть
файлов,
со
дер-
ж
ащих
т
аблицы
и
индексы,
на
другой
диск,
но
здесь
потребу
етс
я
больше
кропот
ливой
ручной
работы,
а
при
внесении
изменений
в
сх
ему
базы
про-
цедуру
,
возмо
жно,
придётся
повторить.
CLUSTER
CLUSTER
table
[
USING
index
]
—
к
оманда
для
упорядочивания
записей
т
аблицы
на
диске
согласно
индек
су
,
что
иног
да
за
счет
уменьшения
досту-
па
к
диску
уск
ор
яет
выполнение
запроса.
Возможно
создать
только
о
дин
физический
порядок
в
таблице,
поэтому
и
таблица
мо
жет
иметь
тольк
о
о
дин
кластерный
индекс.
При
т
аком
условии
нужно
тщательно
выбирать,
к
акой
индекс
бу
дет
использоваться
для
кластерного
индекса.
Кластеризация
по
и
ндек
су
позволяет
сократить
время
поиск
а
по
дис-
ку:
во
время
поиска
по
индек
су
выборк
а
данных
мо
жет
быть
зна
чительно
быстрее,
так
как
последовательность
данных
в
так
ом
же
пор
ядке,
к
ак
и
индек
с.
Из
мину
сов
можно
отметить
то,
что
команда
CLUSTER
требу
ет
«A
CCESS EXCLUSIVE» блокировку
, что предотвращает любые другие
операции
с
данными
(чтения
и
записи)
пок
а
кластеризация
не
завершит
выполнение. Т
акже кластеризация индек
са
в PostgreSQL не утвер
жда-
ет четкий пор
ядок следования, поэтому
требу
ется
повторно выполнять
CLUSTER
для
по
ддерж
ания
таблицы
в
порядк
е.
2.4
Утилиты
для
тюнинг
а
P
ostgreSQL
Pgtune
Для
оптимизации
настроек
для
PostgreSQL
Gregory
Smith
создал
ути-
литу
pgtune
в
расчёте
на
обеспечение
максимальной
произво
дительности
для
заданной
аппаратной
к
онфигурации.
Утилит
а
прост
а
в
использовании
и
во
многих
Lin
ux
системах
мож
ет
идти
в
сост
аве
пак
етов.
Если
же
нет
,
мо
жно
просто
ска
чать
архив
и
распаковать.
Для
начала:
20
2.4.
Утилиты
для
тюнинга
PostgreSQL
Листинг
2.5
Pgtune
Line
1
$
p
g
t
u
n
e
-
i
$
P
G
D
A
T
A/
p
o
s
t
g
r
e
s
q
l
.
c
o
n
f
-
o
$
P
G
D
A
T
A
/
p
o
s
t
g
r
e
s
q
l
.
c
o
n
f
.
p
g
t
u
n
e
опцией
-
i
,
--
input-
config
указываем
текущий
файл
p
ostgresql.conf,
а
-
o
,
--
output-config
указываем
имя
файла
для
нового
p
ostgresql.conf.
Есть
т
акже
дополнительные
опции
для
настройки
конфиг
а:
∙
-
M,
--
memory
используйте
этот
параметр,
чтобы
определить
общий
объем
системной
памяти.
Если
не
указано,
pgtune
бу
дет
пыт
аться
использовать
текущий
объем
системной
памяти;
∙
-
T, --
type
ук
азывает
тип
базы
данных.
Опции:
DW,
OL
TP
,
W
eb,
Mixed,
Desktop;
∙
-
c
,
--
connections
указывает
мак
симальное
количество
соединений.
Ес-
ли
он
не
ук
азан,
то
бу
дет
браться
в
зависимости
от
типа
базы
данных;
Существу
ет
такж
е
онлайн
версия
pgtune
.
Хочетс
я
сразу
добавить,
что
pgtune
не
«серебряная
пу
ля»
для
опти-
мизации
настройки
PostgreSQL.
Многие
настройки
зависят
не
тольк
о
от
аппаратной
конфигурации,
но
и
от
размера
базы
данных,
числа
соедине-
ний
и
сло
жности
запросов,
т
ак
что
оптимально
настроить
базу
данных
возмо
жно,
только
учитывая
все
эти
параметры.
pg_buffercac
he
Pg_buffercac
he
—
расширение
для
PostgreSQL,
к
оторое
позволяет
по-
лучить
предст
авление
об
использовании
общего
буфера
(
shared_buffer
)
в
базе.
Р
асширение
позволяет
взглянуть
какие
из
данных
кэширу
ет
база,
к
оторые
активно
используютс
я
в
запросах.
Для
начала
нужно
у
становить
расширение:
Листинг
2.6
pg_buffercache
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
g
_
b
u
f
f
e
r
c
a
c
h
e
;
Т
еперь
доступно
pg_buffercac
he
представление,
которое
содер
жит:
∙
bufferid
—
ID
блок
а
в
общем
буфере;
∙
relfilenode
—
имя
папки,
г
де
данные
располож
ены;
∙
reltablespace
—
Oid
таблицы;
∙
reldatabase
—
Oid
базы
данных;
∙
relforkn
um
b
er
—
номер
ответвления;
∙
relblockn
um
b
er
—
номер
страницы;
∙
isdirty
—
грязная
страница?;
∙
usagecoun
t
—
к
оличество
LRU
страниц;
21
2.4.
Утилиты
для
тюнинга
PostgreSQL
ID
блока
в
общем
буфере
(
bufferid
)
соответствует
количеству
использу-
емого
буфера
т
аблицей,
ин
дек
сом,
прочим.
Общее
количество
доступных
буферов
определяетс
я
двумя
вещами:
∙
Р
азмер
буферного
блок
а.
Этот
размер
блока
определяется
опцией
--
with-
blocksize
при
конфигурации.
Зна
чение
по
умолчанию
—
8
КБ,
что
достаточно
в
большинстве
случаев,
но
его
возмо
жно
увеличить
или
уменьшить
в
зависимости
от
ситуации.
Для
того
чтобы
изменить
это
зна
чение,
необх
одимо
бу
дет
перек
омпилировать
PostgreSQL;
∙
Р
азмер
общего
буфера.
Определяется
опцией
shared_buffers
в
P
ostgreSQL
конфиге.
Например,
при
использовании
shared_buffers
в
128
МБ
с
8
КБ
разме-
ра
блока
получится
16384
буферов.
Представление
pg_buffercac
he
бу
дет
иметь
так
ое
ж
е
число
строк
—
16384.
С
shared_buffers
в
256
МБ
и
разме-
ром
блок
а
в
1
КБ
получим
262144
буферов.
Для
примера
рассмотрим
простой
запрос
пок
азывающий
использова-
ние
буферов
объект
ами
(таблицами,
индексами,
прочим):
Листинг
2.7
pg_buffercache
Line
1
#
S
E
L
E
C
T
c
.
r
e
l
n
a
m
e
,
c
o
u
n
t
(
*
)
A
S
b
u
f
f
e
r
s
-
F
R
O
M
p
g
_
b
u
f
f
e
r
c
a
c
h
e
b
I
N
N
E
R
JOIN
p
g
_
c
l
a
s
s
c
-
O
N
b
.
r
e
l
f
i
l
e
n
o
d
e
=
p
g
_
r
e
l
a
t
i
o
n
_
f
i
l
e
n
o
d
e
(
c
.
o
i
d
)
A
N
D
-
b
.
r
e
l
d
a
t
a
b
a
s
e
I
N
(
0
,
(
S
E
L
E
C
T
o
i
d
F
R
O
M
p
g
_
d
a
t
a
b
a
s
e
W
H
E
R
E
d
a
t
n
a
m
e
=
c
u
r
r
e
n
t
_
d
a
t
a
b
a
s
e
(
)
)
)
5
G
R
O
U
P
B
Y
c
.
r
e
l
n
a
m
e
-
O
R
D
E
R
B
Y
2
D
E
S
C
-
LIMIT
1
0
;
-
-
r
e
l
n
a
m
e
|
b
u
f
f
e
r
s
10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
p
g
b
e
n
c
h
_
a
c
c
o
u
n
t
s
|
4
0
8
2
-
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
|
5
3
-
p
g
_
a
t
t
r
i
b
u
t
e
|
2
3
-
p
g
_
p
r
o
c
|
1
4
15
p
g
_
o
p
e
r
a
t
o
r
|
1
1
-
p
g
_
p
r
o
c
_
o
i
d
_
i
n
d
e
x
|
9
-
p
g
_
c
l
a
s
s
|
8
-
p
g
_
a
t
t
r
i
b
u
t
e
_
r
e
l
i
d
_
a
t
t
n
u
m
_
i
n
d
e
x
|
7
-
p
g
_
p
r
o
c
_
p
r
o
n
a
m
e
_
a
r
g
s
_
n
s
p
_
i
n
d
e
x
|
6
20
p
g
_
c
l
a
s
s
_
o
i
d
_
i
n
d
e
x
|
5
-
(
1
0
r
o
w
s
)
Этот
запрос
пок
азывает
объекты
(таблицы
и
индексы)
в
кэше:
22
2.4.
Утилиты
для
тюнинга
PostgreSQL
Листинг
2.8
pg_buffercache
Line
1
#
S
E
L
E
C
T
c
.
r
e
l
n
a
m
e
,
c
o
u
n
t
(
*
)
A
S
b
u
f
f
e
r
s
,
u
s
a
g
e
c
o
u
n
t
-
F
R
O
M
p
g
_
c
l
a
s
s
c
-
I
N
N
E
R
JOIN
p
g
_
b
u
f
f
e
r
c
a
c
h
e
b
-
O
N
b
.
r
e
l
f
i
l
e
n
o
d
e
=
c
.
r
e
l
f
i
l
e
n
o
d
e
5
I
N
N
E
R
JOIN
p
g
_
d
a
t
a
b
a
s
e
d
-
O
N
(
b
.
r
e
l
d
a
t
a
b
a
s
e
=
d
.
o
i
d
A
N
D
d
.
d
a
t
n
a
m
e
=
c
u
r
r
e
n
t
_
d
a
t
a
b
a
s
e
(
)
)
-
G
R
O
U
P
B
Y
c
.
r
e
l
n
a
m
e
,
u
s
a
g
e
c
o
u
n
t
-
O
R
D
E
R
B
Y
c
.
r
e
l
n
a
m
e
,
u
s
a
g
e
c
o
u
n
t
;
-
10
r
e
l
n
a
m
e
|
b
u
f
f
e
r
s
|
u
s
a
g
e
c
o
u
n
t
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
p
g
_
r
e
w
r
i
t
e
|
3
|
1
-
p
g
_
r
e
w
r
i
t
e
_
r
e
l
_
r
u
l
e
n
a
m
e
_
i
n
d
e
x
|
1
|
1
-
p
g
_
r
e
w
r
i
t
e
_
r
e
l
_
r
u
l
e
n
a
m
e
_
i
n
d
e
x
|
1
|
2
15
p
g
_
s
t
a
t
i
s
t
i
c
|
1
|
1
-
p
g
_
s
t
a
t
i
s
t
i
c
|
1
|
3
-
p
g
_
s
t
a
t
i
s
t
i
c
|
2
|
5
-
p
g
_
s
t
a
t
i
s
t
i
c
_
r
e
l
i
d
_
a
t
t
_
i
n
h
_
i
n
d
e
x
|
1
|
1
-
p
g
_
s
t
a
t
i
s
t
i
c
_
r
e
l
i
d
_
a
t
t
_
i
n
h
_
i
n
d
e
x
|
3
|
5
20
p
g
b
e
n
c
h
_
a
c
c
o
u
n
t
s
|
4
0
8
2
|
2
-
p
g
b
e
n
c
h
_
a
c
c
o
u
n
t
s
_
p
k
e
y
|
1
|
1
-
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
|
5
3
|
1
-
p
g
b
e
n
c
h
_
t
e
l
l
e
r
s
|
1
|
1
Это
запрос
пок
азывает
как
ой
процент
общего
буфера
используют
обьекты
(таблицы
и
индек
сы)
и
на
скольк
о
процентов
объекты
нах
о
дятся
в
самом
кэше
(буфере):
Листинг
2.9
pg_buffercache
Line
1
#
S
E
L
E
C
T
-
c
.
r
e
l
n
a
m
e
,
-
p
g
_
s
i
z
e
_
p
r
e
t
t
y
(
c
o
u
n
t
(
*
)
*
8
1
9
2
)
a
s
b
u
f
f
e
r
e
d
,
-
r
o
u
n
d
(
1
0
0
.
0
*
c
o
u
n
t
(
*
)
/
5
(
S
E
L
E
C
T
s
e
t
t
i
n
g
F
R
O
M
p
g
_
s
e
t
t
i
n
g
s
W
H
E
R
E
n
a
me
=
’
s
h
a
r
e
d
_
b
u
f
f
e
r
s
’
)
:
:
i
n
t
e
g
e
r
,
1
)
-
A
S
b
u
f
f
e
r
s
_
p
e
r
c
e
n
t
,
-
r
o
u
n
d
(
1
0
0
.
0
*
c
o
u
n
t
(
*
)
*
8
1
9
2
/
p
g
_
t
a
b
l
e
_
s
i
z
e
(
c
.
o
i
d
)
,
1
)
-
A
S
p
e
r
c
e
n
t
_
o
f
_
r
e
l
a
t
i
o
n
-
F
R
O
M
p
g
_
c
l
a
s
s
c
10
I
N
N
E
R
JOIN
p
g
_
b
u
f
f
e
r
c
a
c
h
e
b
-
O
N
b
.
r
e
l
f
i
l
e
n
o
d
e
=
c
.
r
e
l
f
i
l
e
n
o
d
e
-
I
N
N
E
R
JOIN
p
g
_
d
a
t
a
b
a
s
e
d
-
O
N
(
b
.
r
e
l
d
a
t
a
b
a
s
e
=
d
.
o
i
d
A
N
D
d
.
d
a
t
n
a
m
e
=
c
u
r
r
e
n
t
_
d
a
t
a
b
a
s
e
(
)
)
23
2.5.
Оптимизация
БД
и
прилож
ения
-
G
R
O
U
P
B
Y
c
.
o
i
d
,
c
.
r
e
l
n
a
m
e
15
O
R
D
E
R
B
Y
3
D
E
S
C
-
LIMIT
2
0
;
-
-
-
[
R
E
C
O
R
D
1
]
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
r
e
l
n
a
m
e
|
p
g
b
e
n
c
h
_
a
c
c
o
u
n
t
s
20
b
u
f
f
e
r
e
d
|
3
2 M
B
-
b
u
f
f
e
r
s
_
p
e
r
c
e
n
t
|
2
4
.
9
-
p
e
r
c
e
n
t
_
o
f
_
r
e
l
a
t
i
o
n
|
9
9
.
9
-
-
[
R
E
C
O
R
D
2
]
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
r
e
l
n
a
m
e
|
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
25
b
u
f
f
e
r
e
d
|
4
2
4
kB
-
b
u
f
f
e
r
s
_
p
e
r
c
e
n
t
|
0
.
3
-
p
e
r
c
e
n
t
_
o
f
_
r
e
l
a
t
i
o
n
|
9
4
.
6
-
-
[
R
E
C
O
R
D
3
]
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
r
e
l
n
a
m
e
|
p
g
_
o
p
e
r
a
t
o
r
30
b
u
f
f
e
r
e
d
|
8
8
k
B
-
b
u
f
f
e
r
s
_
p
e
r
c
e
n
t
|
0
.
1
-
p
e
r
c
e
n
t
_
o
f
_
r
e
l
a
t
i
o
n
|
6
1
.
1
-
-
[
R
E
C
O
R
D
4
]
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
r
e
l
n
a
m
e
|
p
g
_
o
p
c
l
a
s
s
_
o
i
d
_
i
n
d
e
x
35
b
u
f
f
e
r
e
d
|
1
6
k
B
-
b
u
f
f
e
r
s
_
p
e
r
c
e
n
t
|
0
.
0
-
p
e
r
c
e
n
t
_
o
f
_
r
e
l
a
t
i
o
n
|
1
0
0
.
0
-
-
[
R
E
C
O
R
D
5
]
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
r
e
l
n
a
m
e
|
p
g
_
s
t
a
t
i
s
t
i
c
_
r
e
l
i
d
_
a
t
t
_
i
n
h
_
i
n
d
e
x
40
b
u
f
f
e
r
e
d
|
3
2
k
B
-
b
u
f
f
e
r
s
_
p
e
r
c
e
n
t
|
0
.
0
-
p
e
r
c
e
n
t
_
o
f
_
r
e
l
a
t
i
o
n
|
1
0
0
.
0
Использу
я
эти
данные
можно
проанализировать
для
каких
объектов
не
хват
ает
памяти
или
к
акие
из
них
потребляют
основную
часть
общего
буфера.
На
основе
этого
можно
более
правильно
настраивать
shared_buffers
параметр
для
P
ostgreSQL.
2.5
Оптимизация
БД
и
прило
ж
ения
Для
быстрой
работы
к
аждого
запроса
в
вашей
базе
в
основном
требу-
етс
я
следующее:
1. Отсутствие
в
базе
му
сора,
м
ешающего
добраться
до
актуальных
дан-
ных.
Мо
жно
сформу
лировать
две
подзада
чи:
a) Грамотное
проектирование
базы.
Освещение
этого
вопроса
вы-
х
одит
далеко
за
рамки
этой
книги;
b) Сборк
а
мусора,
возникающего
при
работе
СУБД;
2. Наличие
быстрых
путей
доступа
к
данным
—
индек
сов;
24
2.5.
Оптимизация
БД
и
прилож
ения
3. Возмо
жность
использования
оптимизатором
этих
быстрых
путей;
4. Об
хо
д
известных
проблем;
По
ддерж
ание
базы
в
пор
ядк
е
В
данном
разделе
описаны
действия,
которые
должны
периодически
выполнятьс
я
для
каждой
базы.
От
разработчика
требуетс
я
только
настро-
ить
их
автоматическ
ое
выполнение
(при
помощи
cron)
и
опытным
путём
по
добрать
оптимальную
частоту
.
Команда
ANAL
YZE
Служит
для
обновления
информации
о
распределении
данных
в
т
аб-
лице.
Эт
а
информация
используетс
я
оптимизатором
для
выбора
наиболее
быстрого
плана
выполнения
запроса.
Обычно
команда
использу
ется
в
связке
с
V
A
CUUM
ANAL
YZE
.
Если
в
базе
есть
т
аблицы,
данные
в
которых
не
изменяются
и
не
у
даляютс
я,
а
лишь
добавляются,
то
для
т
аких
т
аблиц
мо
жно
использовать
от
дельную
к
оманду
ANAL
YZE.
Т
акж
е
стоит
использовать
эту
к
оманду
для
от
дельной
т
аблицы
после
добавления
в
неё
большого
количества
записей.
Команда
REINDEX
Команда
REINDEX
использу
ется
для
перестройки
существующих
ин-
дек
сов.
Использовать
её
имеет
смысл
в
случае:
∙
порчи
индек
са;
∙
посто
янного
увеличения
его
размера;
Второй
случай
требует
пояснений.
Индекс,
к
ак
и
таблица,
содер
жит
блоки
со
ст
арыми
версиями
записей.
P
ostgreSQL
не
всегда
мо
жет
заново
использовать
эти
блоки,
и
поэтому
файл
с
индек
сом
постепенно
увеличи-
ваетс
я
в
размерах.
Если
данные
в
таблице
часто
меняются,
то
расти
он
мо
жет
весьма
быстро.
Если
вы
заметили
по
добное
поведение
к
акого-то
индекса,
то
стоит
на-
строить
для
него
перио
дическ
ое
выполнение
команды
REINDEX
.
Учтите:
к
оманда
REINDEX
,
как
и
V
A
CUUM
FULL
,
полностью
блокиру
ет
таблицу
,
поэтому
выполнять
её
надо
тог
да,
ког
да
загрузка
сервера
минимальна.
Использование
индек
сов
Опыт
показывает
,
что
наиболее
значительные
проблемы
с
произво
ди-
тельностью
вызываются
отсутствием
нужных
индексов.
Поэтому
столк-
нувшись
с
медленным
запросом,
в
первую
очередь
проверьте,
существуют
ли
индек
сы,
которые
он
мож
ет
использовать.
Если
нет
—
постройте
их.
Излишек
индек
сов,
впрочем,
тож
е
чреват
проблемами:
25
2.5.
Оптимизация
БД
и
прилож
ения
∙
Команды,
изменяющие
данные
в
таблице,
должны
изменить
т
акж
е
и
индек
сы.
Очевидно,
чем
больше
индек
сов
построено
для
таблицы,
тем
медленнее
это
бу
дет
происх
одить;
∙
Оптимизатор
перебирает
возмо
жные
пути
выполнения
запросов.
Ес-
ли
построено
много
ненужных
индексов,
то
этот
перебор
бу
дет
идти
дольше;
Единственное,
что
можно
ск
азать
с
большой
степенью определённо-
сти
—
поля,
являющиес
я
внешними
ключами,
и
поля,
по
к
оторым
объеди-
няютс
я
таблицы,
индексировать
надо
обязательно.
Команда
EXPLAIN
[ANAL
YZE]
Команда
EXPLAIN
запрос[]
показывает
,
каким
образом
PostgreSQL
со-
бираетс
я
выполнять
ваш
запрос.
Команда
EXPLAIN
ANAL
YZE
запрос[]
вы-
полняет
запрос
(и
поэтому
EXPLAIN
ANAL
YZE
DELETE
.
.
.
—
не
слиш-
к
ом
х
орошая
идея)
и
пок
азывает
как
изначальный
план,
так
и
реальный
процесс
его
выполнения.
Чтение
вывода
этих
к
оманд
—
искусство,
к
оторое
прих
одит
с
опытом.
Для
на
чала
обращайте
внимание
на
следующее:
∙
Использование
полного
просмотра
таблицы
(seq
scan);
∙
Использование
наиболее
примитивного
способа
объединения
таблиц
(nested
lo
op);
∙
Для
EXPLAIN
ANAL
YZE
: нет ли больших от
личий в предполагае-
мом
к
оличестве
записей
и
реально выбранном?
Если оптимизатор
использу
ет
у
старевшую
ст
атистику
,
то
он
мо
жет
выбирать
не
самый
быстрый
план
выполнения
запроса;
Следу
ет
отметить,
что
полный
просмотр
таблицы далек
о
не
всегда
медленнее
просмотра
по
индек
су
.
Если,
например,
в
таблице–справочник
е
неск
олько
сотен
записей,
умещающих
ся
в
одном-двух
блок
ах
на
диске,
то
использование
индек
са
приведёт
лишь
к
тому
,
что
придётс
я
читать
ещё
и пару
лишних блок
ов индек
са. Если
в
запросе придётс
я
выбрать
80%
записей
из
большой
т
аблицы,
то
полный
просмотр
опять
ж
е
получится
быстрее.
При
тестировании
запросов
с
использованием
EXPLAIN
ANAL
YZE
мо
жно воспользоваться
настройк
ами, запрещающими оптимизатору ис-
пользовать
определённые
планы
выполнения.
Например,
Листинг
2.10
enable_seqscan
Line
1
S
E
T
e
n
a
b
l
e
_
s
e
q
s
c
a
n=
f
a
l
s
e
;
26
2.5.
Оптимизация
БД
и
прилож
ения
запретит
использование
полного
просмотра
т
аблицы,
и
вы
смо
ж
ете
выяснить,
прав
ли
был
оптимизатор,
отк
азываясь
от
использования
ин-
дек
са. Ни в коем случае не следу
ет прописывать по
добные команды в
p
ostgresql.conf
!
Это
мож
ет
уск
орить
выполнение
неск
ольких
запросов,
но
сильно
замедлит
все
ост
альные!
Использование
собранной
ст
атистики
Р
езу
льт
аты
работы
сборщика
ст
атистики
доступны
через
специальные
системные
предст
авления.
Наиболее
интересны
для
наших
целей
следую-
щие:
∙
pg_stat_user_ta
bles
содер
жит
—
для
каждой
пользовательской
т
абли-
цы
в
текущей
базе
данных
—
общее
количество
полных
просмотров
и
просмотров
с
использованием
индек
сов,
общие
количества
запи-
сей,
к
оторые
были
возвращены
в
резу
ль
тате
обоих
типов
просмотра,
а
т
акже
общие
к
оличества вст
авленных,
изменённых
и у
далённых
записей;
∙
pg_stat_user_in
dexes
со
держит
—
для
каждого
пользовательского
ин-
дек
са
в
текущей
базе
данных
—
общее
к
оличество
просмотров,
ис-
пользовавших
этот
индекс,
количество
прочит
анных
записей,
коли-
чество
успешно
прочитанных
записей
в
таблице
(мож
ет
быть
меньше
предыдущего
значения,
если
в
индексе
есть
записи,
ук
азывающие
на
у
старевшие
записи
в
таблице);
∙
pg_statio_user_
tables
со
держит
—
для
каждой
пользовательск
ой
т
аб-
лицы
в
текущей
базе
данных
—
общее
количество
блок
ов,
прочитан-
ных
из
таблицы,
количество
блоков,
ок
азавших
ся
при
этом
в
буфере
(см.
пункт
2.1.1),
а
такж
е
аналогичную
статистику
для
всех
индексов
по
т
аблице
и,
возможно,
по
связанной
с
ней
таблицей
TOAST;
Из
этих
предст
авлений
можно
узнать,
в
частности:
∙
Для
к
аких
таблиц
стоит
создать
новые
индексы
(индикатором
слу-
жит
большое
к
оличество
полных
просмотров
и
большое
количество
прочит
анных
блоков);
∙
Какие
индек
сы
вообще
не
используются
в
запросах.
Их
имеет
смысл
у
далить,
если,
к
онечно,
речь
не
идёт
об
индек
сах,
обеспечивающих
выполнение
ограничений
PRIMAR
Y
KEY
и
UNIQUE;
∙
Дост
аточен
ли
объём
буфера
сервера;
Т
акж
е
возмо
жен
«дедуктивный»
по
дхо
д,
при
к
отором
сна
чала
созда-
ётс
я
большое
к
оличество
индек
сов,
а
затем
неиспользуемые
индексы
у
да-
ляютс
я.
27
2.5.
Оптимизация
БД
и
прилож
ения
Перенос
логики
на
сторону
сервера
Этот
пункт
очевиден
для
опытных
пользователей
PostrgeSQL
и
предн
а-
зна
чен
для
тех,
кто
использует
или
переносит
на
P
ostgreSQL
прило
жения,
написанные
изна
чально
для
более
примитивных
СУБД.
Р
еализация
части
логики
на
стороне
сервера
через
хранимые
проце-
дуры,
триггеры,
правила
1
часто
позволяет
у
скорить
работу
прило
ж
ения.
Действительно,
если
неск
олько
запросов
объединены
в
процедуру
,
то
не
требу
ется
∙
пересылк
а
промежуточных
запросов
на
сервер;
∙
получение
промежуточных
резу
ль
татов
на
клиент
и
их
обработка;
Кроме
того,
хранимые
процедуры
упрощают
процесс
разработки
и
под-
дер
жки:
изменения
надо
вносить
тольк
о
на
стороне
сервера,
а
не
менять
запросы
во
всех
прило
жениях.
Оптимизация
к
онкретных
запросов
В
этом
разделе
описываютс
я
запросы,
для
к
оторых
по
разным
причи-
нам
нельзя
заст
авить
оптимизатор
использовать
индек
сы,
и
к
оторые
бу-
дут
всег
да
вызывать
полный
просмотр
таблицы.
Т
аким
образом,
если
вам
требу
ется
использовать
эти
запросы
в
требовательном
к
быстро
действию
прило
жении,
то
придётся
их
изменить.
SELECT
coun
t(*)
FROM
<огромная
таблица>
Функция
count
()
работ
ает
очень
просто:
сна
чала
выбираютс
я
все
за-
писи, у
довлетвор
яющие условию, а потом к полученному набору запи-
сей
применяется
агрегатная
функция
—
считаетс
я
количество
выбранных
строк.
Информация
о
видимости
записи
для
текущей
транзакции
(а
к
он-
курентным
транзакциям
мож
ет
быть
видимо
разное
к
оличество
записей
в
т
аблице!)
не
хранитс
я
в
индек
се,
поэтому
,
даж
е
если
использовать
для
выполнения
запроса
индекс
первичного
ключа
таблицы,
всё
равно
потре-
бу
ется
чтение
записей
собственно
из
файла
таблицы.
Проблема
Запрос
вида
Листинг
2.11
SQL
Line
1
S
E
L
E
C
T
c
o
u
n
t
(
*
)
F
R
O
M
f
o
o
;
осуществляет
полный
просмотр
таблицы
fo
o,
что
весьма
долго
для
таб-
лиц
с
большим
к
оличеством
записей.
Р
ешение
Простого
решения
проблемы,
к
сож
алению,
нет
.
Возмо
жны
следующие
по
дхо
ды:
1
R
ULE
—
реализованное
в
PostgreSQL
расширение
стандарт
а
SQL,
позволяющее,
в
частности,
создавать
обновляемые
представления
28
2.5.
Оптимизация
БД
и
прилож
ения
1. Если
точное
число
записей
не
важно,
а
важ
ен
порядок
1
,
то
можно
ис-
пользовать
информацию
о
количестве
записей
в
т
аблице,
собранную
при
выполнении
к
оманды
ANAL
YZE:
Листинг
2.12
SQL
Line
1
S
E
L
E
C
T
r
e
l
t
u
p
l
e
s
F
R
O
M
p
g
_
c
l
a
s
s
W
H
E
R
E
r
e
l
n
a
m
e
=
’
f
o
o
’
;
2. Если
по
добные
выборки
выполняются
часто,
а
изменения
в
табли-
це
достаточно
редки,
то
мо
жно
завести
вспомог
ательную
таблицу
,
хранящую
число
записей
в
основной.
На
основную
же
т
аблицу
пове-
сить
триггер,
который
бу
дет
уменьшать
это
число
в
случае
у
даления
записи
и
увеличивать
в
случае
вставки.
Т
аким
образом,
для
полу-
чения
к
оличества
записей
потребу
ется
лишь
выбрать
одну
запись
из
вспомог
ательной
таблицы;
3. Вариант
предыдущего
подх
о
да,
но
данные
во
вспомогательной
таб-
лице
обновляютс
я
через
определённые
промежутки
времени
(cron);
Медленный
DISTINCT
Т
екущая
реализация
DISTINCT
для
больших
таблиц
очень
медлен-
на.
Но
возмо
жно
использовать
GR
OUP
BY
взамен
DISTINCT
.
GR
OUP
BY
мо
жет использовать агрегирующий
хэш, что зна
чительно быстрее, чем
DISTINCT
(акту
ально
до
версии
8.4
и
ниже).
Листинг
2.13
DISTINCT
Line
1
p
o
s
t
g
r
e
s=
#
s
e
l
e
c
t
c
o
u
n
t
(
*
)
f
r
o
m
(
s
e
l
e
c
t
d
i
s
t
i
n
c
t
i
f
r
o
m
g
)
a
;
-
c
o
u
n
t
-
-
-
-
-
-
-
-
-
1
9
1
2
5
5
(
1
r
o
w
)
-
-
Ti
m
e
:
5
8
0
,
5
5
3
ms
-
-
10
p
o
s
t
g
r
e
s=
#
s
e
l
e
c
t
c
o
u
n
t
(
*
)
f
r
o
m
(
s
e
l
e
c
t
d
i
s
t
i
n
c
t
i
f
r
o
m
g
)
a
;
-
c
o
u
n
t
-
-
-
-
-
-
-
-
-
1
9
1
2
5
-
(
1
r
o
w
)
15
-
T
i
m
e
:
3
6
,
2
8
1
ms
1
«на
нашем
форуме
более
10000
зарегистрированных
пользователей,
ост
авивших
более
50000
сообщений!»
29
2.5.
Оптимизация
БД
и
прилож
ения
Листинг
2.14
GROUP
BY
Line
1
p
o
s
t
g
r
e
s=
#
s
e
l
e
c
t
c
o
u
n
t
(
*
)
f
r
o
m
(
s
e
l
e
c
t
i
f
r
o
m
g
g
r
o
u
p
b
y
i
)
a
;
-
c
o
u
n
t
-
-
-
-
-
-
-
-
-
1
9
1
2
5
5
(
1
r
o
w
)
-
-
T
i
m
e
:
2
6
,
5
6
2
ms
-
-
10
p
o
s
t
g
r
e
s=
#
s
e
l
e
c
t
c
o
u
n
t
(
*
)
f
r
o
m
(
s
e
l
e
c
t
i
f
r
o
m
g
g
r
o
u
p
b
y
i
)
a
;
-
c
o
u
n
t
-
-
-
-
-
-
-
-
-
1
9
1
2
5
-
(
1
r
o
w
)
15
-
T
i
m
e
:
2
5
,
2
7
0
ms
Утилиты
для
оптимизации
запросов
pgF
ouine
pgF
ouine
—
это
анализатор
log-файлов
для
PostgreSQL,
используемый
для
генерации
дет
альных
отчетов
из
log-файлов
P
ostgreSQL.
pgF
ouine
по-
мо
жет
определить,
какие
запросы
следует
оптимизировать
в
первую
оче-
редь.
pgF
ouine
написан
на
язык
е
программирования
PHP
с
использовани-
ем
объектно-ориентированных
технологий
и
легк
о
расшир
яется
для
по
д-
дер
жки
специализированных
отчетов,
является
свобо
дным
программным
обеспечением
и
распространяется
на
условиях
GNU
General
Public
License.
Утилит
а
спроектирована
таким
образом,
чтобы
обработка
очень
больших
log-файлов
не
требовала
много
ресурсов.
Для
работы
с
pgF
ouine
сначала
нужно
сконфигурировать
PostgreSQL
для
создания
нужного
формат
а
log-файлов:
∙
Чтобы
включить
проток
олирование
в
syslog
Листинг
2.15
pgF
ouine
Line
1
l
o
g
_
d
e
s
t
i
n
a
t
i
o
n
=
’
s
y
s
l
o
g
’
-
r
e
d
i
r
e
c
t
_
s
t
d
e
r
r
=
o
f
f
-
s
i
l
e
n
t
_
m
o
d
e
=
o
n
-
∙
Для
записи
запросов,
длящихс
я
дольше
n
миллисекунд:
30
2.5.
Оптимизация
БД
и
прилож
ения
Листинг
2.16
pgF
ouine
Line
1
l
o
g
_
m
i
n
_
d
u
r
a
t
i
o
n
_
s
t
a
t
e
m
e
n
t
=
n
-
l
o
g
_
d
u
r
a
t
i
o
n
=
o
f
f
-
l
o
g
_
s
t
a
t
e
m
e
n
t
=
’
n
o
n
e
’
-
Для
записи
к
аждого
обработ
анного
запроса
у
ст
ановите
log_min_duration_statemen
t
на
0.
Чтобы
отключить
запись
запросов,
у
становите
этот
параметр
на
-1.
pgF
ouine
—
простой
в
использовании
инструмент
к
омандной
строки.
Следующая
к
оманда
создаёт
HTML-отчёт
со
стандартными
параметрами:
Листинг
2.17
pgF
ouine
Line
1
p
g
f
o
u
i
n
e
.
p
h
p
-
f
i
l
e
y
o
u
r
/
l
o
g
/
f
i
l
e
.
l
o
g
>
y
o
u
r
-
r
e
p
o
r
t
.
h
t
m
l
С
помощью
этой
строки
можно
отобразить
текстовый
отчёт
с
10
запро-
сами
на
к
аждый
экран
на
стандартном
выводе:
Листинг
2.18
pgF
ouine
Line
1
p
g
f
o
u
i
n
e
.
p
h
p
-
f
i
l
e
y
o
u
r
/
l
o
g
/
f
i
l
e
.
l
o
g
-
t
o
p
1
0
-
f
o
r
m
a
t
t
e
x
t
Более
по
дробно
о
возможност
ях,
а
такж
е
много
полез-
ных
примеров,
можно
найти
на
официальном
сайте
проект
а
pgfouine.pro
jects.pgfoundry
.org
.
pgBadger
pgBadger
—
аналогичная
утилита,
что
и
pgF
ouine,
но
написанная
на
P
erl.
Еще
одно
большое
преимущество
проекта
в
том,
что
он
более
активно
сейчас
разрабатываетс
я
(на
момент
написания
этого
текст
а
последний
ре-
лиз
pgF
ouine
был
в
24.02.2010,
а
последняя
версия
p
gBadger
—
24.01.2017).
У
ст
ановка
pgBadger
проста:
Листинг
2.19
У
становк
а
pgBadger
Line
1
$
t
a
r
x
z
f
p
g
b
a
d
g
e
r
-
2
.
x
.
t
a
r
.
g
z
-
$
c
d
p
g
b
a
d
g
e
r
-
2
.
x
/
-
$
p
e
r
l
M
a
k
e
f
i
l
e
.
P
L
-
$
m
a
ke &
&
s
u
d
o
ma
ke
i
n
s
t
a
l
l
Как
и
в
случае
с
pgF
ouine
нужно
настроить
P
ostgreSQL
логи:
Листинг
2.20
Настройка
логов
PostgreSQL
Line
1
l
o
g
g
i
n
g
_
c
o
l
l
e
c
t
o
r
=
o
n
31
2.5.
Оптимизация
БД
и
прилож
ения
-
l
o
g
_
m
i
n
_
m
e
s
s
a
g
e
s
=
d
e
b
u
g
1
-
l
o
g
_
m
i
n
_
e
r
r
o
r
_
s
t
a
t
e
m
e
n
t
=
d
e
b
u
g
1
-
l
o
g
_
m
i
n
_
d
u
r
a
t
i
o
n
_
s
t
a
t
e
m
e
n
t
=
0
5
l
o
g
_
l
i
n
e
_
p
r
e
f
i
x
=
’%t
[
%
p
]
:
[
%
l
-
1
]
u
s
e
r
=
%
u
,
db
=
%
d
’
-
l
o
g
_
c
h
e
c
k
p
o
i
n
t
s
=
o
n
-
l
o
g
_
c
o
n
n
e
c
t
i
o
n
s
=
o
n
-
l
o
g
_
d
i
s
c
o
n
n
e
c
t
i
o
n
s
=
o
n
-
l
o
g
_
l
o
c
k
_
w
a
i
t
s
=
o
n
10
l
o
g
_
t
e
m
p
_
f
i
l
e
s
=
0
Парсим
логи
P
ostgreSQL
через
pgBadger:
Листинг
2.21
Запуск
pgBadger
Line
1
$
.
/
p
g
b
a
d
g
e
r
~
/
p
g
s
q
l
/
m
a
s
t
e
r
/
p
g
_
l
o
g
/
p
o
s
t
g
r
e
s
q
l
-
2
0
1
2
-
0
8
-
3
0
_1
3
2
*
-
[
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
>
]
P
a
r
s
e
d
1
0
4
8
5
7
6
8
b
y
t
e
s
o
f
1
0
4
8
5
7
6
8
(
1
0
0
.
0
0
%
)
-
[
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
>
]
P
a
r
s
e
d
1
0
4
8
5
8
2
8
b
y
t
e
s
o
f
1
0
4
8
5
8
2
8
(
1
0
0
.
0
0
%
)
-
[
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
>
]
P
a
r
s
e
d
1
0
4
8
5
8
5
1
b
y
t
e
s
o
f
1
0
4
8
5
8
5
1
(
1
0
0
.
0
0
%
)
5
[
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
>
]
P
a
r
s
e
d
1
0
4
8
5
8
4
8
b
y
t
e
s
o
f
1
0
4
8
5
8
4
8
(
1
0
0
.
0
0
%
)
-
[
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
>
]
P
a
r
s
e
d
1
0
4
8
5
8
3
9
b
y
t
e
s
o
f
1
0
4
8
5
8
3
9
(
1
0
0
.
0
0
%
)
-
[
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
>
]
P
a
r
s
e
d
9
8
2
5
3
6
b
y
t
e
s
o
f
9
8
2
5
3
6
(
1
0
0
.
0
0
%
)
В
резу
л
ь
тате
получится
HTML
файлы,
к
оторые
содер
ж
ат
ст
атистику
по
запросам
к
PostgreSQL.
Более
по
дробно
о
возмо
жност
ях
можно
найти
на
официальном
сайте
проект
а
http://dalibo.github.io/pgbadger/
.
pg_stat_statemen
ts
Pg_stat_statemen
ts
—
расширение
для
сбора
ст
атистики
выполнения
запросов
в
рамках
всего
сервера.
Преимущество
данного расширения
в
том,
что
ему
не
требуетс
я
собирать
и
парсить
логи
P
ostgreSQL,
как
это
делает
pgF
ouine
и
pgBadger.
Для
на
чала
уст
ановим
и
настроим
его:
Листинг
2.22
Настройка
pg_stat_statements
в
p
ostgresql.conf
Line
1
s
h
a
r
e
d
_
p
r
e
l
o
a
d
_
l
i
b
r
a
r
i
e
s
=
’
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
’
-
c
u
s
t
o
m
_
v
a
r
i
a
b
l
e
_
c
l
a
s
s
e
s
=
’
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
’
#
данная
настройк
а
нужна
для
P
o
s
t
g
r
e
S
Q
L
9
.
1
и
ниж
е
-
-
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
.
max
=
1
0
0
0
0
5
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
.
t
r
a
c
k
=
a
l
l
32
2.5.
Оптимизация
БД
и
прилож
ения
После
внесения
этих
параметров
PostgreSQL
потребуетс
я
перегрузить.
Параметры
к
онфигурации
pg_stat_statements:
1.
pg_stat_statemen
ts.
max
(
in
teger
)
»
—
мак
симальное
к
оличество
sql
за-
просов,
которое
бу
дет
храниться
расширением
(у
даляютс
я
записи
с
наименьшим
к
оличеством
вызовов);
2.
pg_stat_statemen
ts.track
(en
um)
»
—
какие
SQL
запросы
требуетс
я
за-
писывать.
Возмо
жные
параметры:
top
(только
запросы
от
прило
же-
ния/клиент
а),
all
(все
запросы,
например
в
функциях)
и
none
(от-
ключить
сбор
ст
атистики);
3.
pg_stat_statemen
ts.sav
e
(b
o
olean)
»
—
следует
ли
со
хранять
собранную
ст
атистику
после
остановки
PostgreSQL.
По
умолчанию
включено;
Далее
активиру
ем
расширение:
Листинг
2.23
Активация
pg_stat_statements
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
;
Пример
собранной
ст
атистики:
Листинг
2.24
pg_stat_statements
статистик
а
Line
1
#
S
E
L
E
C
T
q
u
e
r
y
,
c
a
l
l
s ,
t
o
t
a
l
_
t
i
m
e
,
r
o
w
s
,
1
0
0
.
0
*
s
h
a
r
e
d
_
b
l
k
s
_
h
i
t
/
-
n
u
l
l
i
f
(
s
h
a
r
e
d
_
b
l
k
s
_
h
i
t
+
s
h
a
r
e
d
_
b
l
k
s
_
r
e
a
d
,
0
)
A
S
h
i
t
_
p
e
r
c
e
n
t
-
F
R
O
M
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
O
R
D
E
R
B
Y
t
o
t
a
l
_
t
i
m
e
D
E
S
C
LIMIT
1
0
;
-
-
[
R
E
C
O
R
D
1
]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
5
q
u
e
r
y
|
S
E
L
E
C
T
q
u
e
r
y
,
c
a
l
l
s ,
t
o
t
a
l
_
t
i
m
e
,
r
o
w
s
,
?
*
s
h
a
r
e
d
_
b
l
k
s
_
h
i
t
/
-
|
n
u
l
l
i
f
(
s
h
a
r
e
d
_
b
l
k
s
_
h
i
t
+
s
h
a
r
e
d
_
b
l
k
s
_
r
e
a
d
,
?
)
A
S
h
i
t
_
p
e
r
c
e
n
t
-
|
F
R
O
M
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
O
R
D
E
R
B
Y
t
o
t
a
l
_
t
i
m
e
D
E
S
C
LIMIT
?
;
-
c
a
l
l
s
|
3
-
t
o
t
a
l
_
t
i
m
e
|
0
.
9
9
4
10
r
o
w
s
|
7
-
h
i
t
_
p
e
r
c
e
n
t
|
1
0
0
.
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
-
-
[
R
E
C
O
R
D
2
]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
q
u
e
r
y
|
i
n
s
e
r
t
i
n
t
o
x
(
i
)
s
e
l
e
c
t
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
?
,
?
)
;
-
c
a
l
l
s
|
2
33
2.5.
Оптимизация
БД
и
прилож
ения
15
t
o
t
a
l
_
t
i
m
e
|
0
.
5
9
1
-
r
o
w
s
|
1
1
0
-
h
i
t
_
p
e
r
c
e
n
t
|
1
0
0
.
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
-
-
[
R
E
C
O
R
D
3
]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
q
u
e
r
y
|
s
e
l
e
c
t
*
f
r
o
m
x
w
h
e
r
e
i
=
?
;
20
c
a
l
l
s
|
2
-
t
o
t
a
l
_
t
i
m
e
|
0
.
1
5
7
-
r
o
w
s
|
6
-
h
i
t
_
p
e
r
c
e
n
t
|
1
0
0
.
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
-
-
[
R
E
C
O
R
D
4
]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
25
q
u
e
r
y
|
S
E
L
E
C
T
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
_
r
e
s
e
t
(
)
;
-
c
a
l
l
s
|
1
-
t
o
t
a
l
_
t
i
m
e
|
0
.
1
0
2
-
r
o
w
s
|
1
-
h
i
t
_
p
e
r
c
e
n
t
|
Для
сброса
ст
атистики
есть
команда
pg_stat_statements_reset
:
Листинг
2.25
Сброс
статистики
Line
1
#
S
E
L
E
C
T
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
_
r
e
s
e
t
(
)
;
-
-
[
R
E
C
O
R
D
1
]
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
_
r
e
s
e
t
|
-
5
#
S
E
L
E
C
T
q
u
e
r
y
,
c
a
l
l
s ,
t
o
t
a
l
_
t
i
m
e
,
r
o
w
s
,
1
0
0
.
0
*
s
h
a
r
e
d
_
b
l
k
s
_
h
i
t
/
-
n
u
l
l
i
f
(
s
h
a
r
e
d
_
b
l
k
s
_
h
i
t
+
s
h
a
r
e
d
_
b
l
k
s
_
r
e
a
d
,
0
)
A
S
h
i
t
_
p
e
r
c
e
n
t
-
F
R
O
M
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
O
R
D
E
R
B
Y
t
o
t
a
l
_
t
i
m
e
D
E
S
C
LIMIT
1
0
;
-
-
[
R
E
C
O
R
D
1
]
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
q
u
e
r
y
|
S
E
L
E
C
T
p
g
_
s
t
a
t
_
s
t
a
t
e
m
e
n
t
s
_
r
e
s
e
t
(
)
;
10
c
a
l
l
s
|
1
-
t
o
t
a
l
_
t
i
m
e
|
0
.
1
7
5
-
r
o
w
s
|
1
-
h
i
t
_
p
e
r
c
e
n
t
|
Хочетс
я
сразу
отметить,
что
расширение
только
с
версии
PostgreSQL
9.2
con
trib
нормализирует
SQL
запросы.
В
версиях
9.1
и
ниже
SQL
запросы
со
храняются
к
ак
есть,
а
значит
«select
*
from
table
where
id
=
3»
и
«select
*
from
table
where
id
=
21»
бу
ду
разными
запис
ями,
что
почти
бесполезно
для
сбора
полезной
ст
атистики.
34
2.6.
Заключение
2.6
Заключение
К
счастью,
PostgreSQL
не
требует
особо
сло
жной
настройки.
В
боль-
шинстве
случаев
вполне
достаточно
бу
дет
увеличить
объём
выделенной
памяти,
настроить
перио
дическ
ое
поддер
жание
базы
в
порядк
е
и
прове-
рить
наличие
необ
х
о
димых
индек
сов.
Более
сло
жные
вопросы
можно
об-
су
дить
в
специализированном
списке
рассылки.
35
3
Индек
сы
«Ну
у
вас
и
запросики»
ск
азала
база
данных
и
зависла
интернет
Что
т
акое
таблица
в
реляционной
СУБД?
Это
т
ак
ой
список
из
корте-
ж
ей
(tuple).
Каждый
кортеж
состоит
из
ячеек
(row).
Количество
ячеек
в
к
ортеже
и
их
тип
совпадают
со
сх
емой
к
олонки,
неск
ольких
колонок.
Этот
список
имеет
сквозную
нумерацию
RowId
—
пор
ядковый
номер.
Т
аким
об-
разом,
т
аблицы
можно
осознавать
как
список
пар
(RowId,
Кортеж).
Индек
сы
—
это
обратные
отношения
(Кортеж,
Ro
wId).
Кортеж
обя-
зан
содер
жать
х
отя
бы
о
дну
ячейку
(т
.
е.
быть
построенным
минимум
по
о
дной
к
олонке).
Для
индек
сов,
к
оторые
индек
сируют
более
одной
колон-
ки
—
они
ещё
называютс
я
составными,
и
участвуют
в
отношениях
вида
«многие-к
о-многим»
—
всё
написанное
верно
в
равной
степени.
Очевидно,
если
кортеж
—
не
уник
ален
(в
колонк
е
существует
два
одинак
овых
кор-
теж
а),
то
эти
отношения
выг
лядят
к
ак
(Кортеж,
Список
Ro
wId)
—
т
.
е.
к
ортежу
сопоставляетс
я
список
RowId.
Индек
сы
могут
использоваться
для
таких
операций
в
базе
данных:
∙
Поиск
данных
—
абсолютно
все
индексы
по
ддерживают
поиск
зна-
чений
по
равенству
.
А
B-T
ree
—
по
произвольным
диапазонам;
∙
Lik
e
—
B-T
ree
и
Bitmap
индек
сы
мо
жно
использовать
для
уск
орения
префик
сных
Like-предик
атов
(вида
ab
c%);
∙
Оптимизатор
—
B-T
ree
и
R-T
ree
индек
сы
предст
авляют
из
себя
ги-
стограмму
произвольной
точности;
∙
Join
—
индек
сы
могут
быть
использованы
для
Merge,
Index
алгорит-
мов;
∙
Relation
—
индексы
могут
быть
использованы
для
операций
except/in
tersect;
∙
Aggregations
—
индек
сы
позволяют
эффективно
вычислять
неко-
торые
агрегатные
функции
—
COUNT,
MIN,
MAX,
а
такж
е
их
DISTINCT
версии;
36
3.1.
Типы
индексов
∙
Grouping
—
индексы
позволяют
эффективно
вычислять
группировки
и
произвольные
агрег
атные
функции
(sort-group
алгоритм);
3.1
Типы
индек
сов
В
зависимости
от
структуры,
используемой
в
реализации
индексов,
су-
щественно
различаются
поддер
живаемые
операции,
их
стоимости,
а
т
акже
свойства
чит
аемых
данных.
Давайте
рассмотрим
к
акие
существуют
типы
индек
сов
в
PostgreSQL.
B-T
ree
B-T
ree
(Bo
eing/Bay
er/Balanced/Broad/Bush
y-T
ree)
называют
упор
ядо-
ченное
блочное
дерево.
Узлы
в
дереве
предст
авляют
из
себя
блоки
фикси-
рованного
размера.
У
каждого
узла
фик
сированное
число
детей.
Струк-
тура
B-T
ree
предст
авлена
на
рисунке
3.1
.
Рис.
3.1:
B-T
ree
индек
с
B-T
ree
для
индексов
отличаетс
я
от
представленной
на
Википедии
—
есть
дублированные
данных
в
промежуточных
блоках.
Для
i-ой
записи
в
блок
е
со
храняется
не
зна
чение,
которое
больше
мак
симума
i-го
поддерева,
и
меньше
минимума
(i+1)
поддерева,
а
максимум
i-го
поддерева.
Р
азличия
проистек
ают
из
того,
что
википедия
приво
дит
пример
B-T
ree
для
мно
ж
е-
ства,
а
нам
нуж
ен
ассоциативный
массив.
В
индексном
B-T
ree
значения
и
Ro
wId
размещаются
совместно
на
ниж-
нем
слое
дерева.
Каждый
узел
дерева
предст
авляет
из
себя
одну
страницу
(page)
в
некотором
формате.
В
на
чале
страницы
всегда
идёт
некоторый
за-
головок.
Для
к
орневого
и
промежуточного
узла
в
страницах
хранятс
я
па-
ры
(Значение,
Номер
страницы).
Для
листовых
—
пары
(Значение
,RowId)
либо
(Значение,
Список
RowId)
(в
зависимости
от
свойств
значения
—
уни-
к
ально
или
нет).
B-T
ree
деревья
имеют
крайне
маленькую
высоту
—
по-
37
3.1.
Типы
индексов
р
ядка
𝐻
=
log
𝑚
𝑁
,
г
де
m
—
к
оличество
записей
в
блоке,
N
—
количество
элементов.
B-T
ree
деревья
являются
упор
ядоченными
—
все
элементы
в
любой
странице
(блоке)
дерева
лежат
последовательно.
Предыдущие
два
свойства
позволяют
крайне
эффективно
произво
дить
поиск
—
начиная
с
первой
страницы,
половинным
делением
(binary
search)
выделяются
де-
ти,
в
которых
леж
ат
границы
поиска.
Т
аким
образом,
прочитав
всего
H,
2H
страниц
мы
нахо
дим
искомый
диапазон.
Важным
нюансом
является
т
акже
факт
,
что
страницы
в
листьях
связаны
в
о
дносвязный
либо
дву-
связный
список
-
это
озна
чает
,
что,
выполнив
поиск,
мы
мо
жем
дальше
просто
последовательно
чит
ать
страницы,
и
эффективность
чтения
боль-
шего
объёма
данных
(длинного
диапазона)
сравнима
с
эффективностью
чтения
данных
из
т
аблицы.
Сильные
стороны
B-T
ree
индек
сов:
∙
со
храняют
сортированность
данных;
∙
по
ддер
живают
поиск
по
унарным
и
бинарным
предикат
ам
(
<a;
=
b
;
>c
and
<d;
<e
and
>f
)
за
O(
log
𝑚
𝑁
),
где
m
—
количество
записей
в
блок
е,
N
—
количество
элементов;
∙
позволяют
не
сканиру
я
последовательность
данных
целиком
оценить
cardinalit
y
(к
оличество
записей)
для
всего
индекса
(а
следовательно
т
аблицы),
диапазона,
причём
с
произвольной
точностью.
Посмотре-
ли
к
орневую
страницу
—
получили
одну
точность.
Посмотрели
сле-
дующий
уровень
дерева
—
получили
точность
получше.
Просмотрели
дерево
до
к
орня
—
получили
точное
число
записей;
∙
самобалансиру
емый,
для
внесения
изменения
не
требуетс
я
полного
перестроения,
проис
хо
дит
не
более
O(
log
𝑚
𝑁
)
действий,
г
де
m
—
к
о-
личество
записей
в
блок
е,
N
—
количество
элементов;
Слабые
стороны
B-T
ree
индек
сов:
∙
занимают
много
мест
а
на
диске.
Индекс
по
уник
альным
In
teger-ам,
к
примеру
,
весит
в
два
раза
больше
аналогичной
колонки
(т
.к.
хра-
нятс
я
ещё
и
RowId);
∙
при
постоянной
записи
дерево
на
чинает
хранить
данные
р
азреж
енно
(сразу
после
построения
они
могут
лежать
очень
плотно),
и
время
доступа
увеличивается
за
счёт
увеличения
объёма
дисковой
инфор-
мации.
Поэтому
B-T
ree
индексы
требуют
присмотра
и
периодическ
о-
го
перепостроения
(REBUILD);
R-T
ree
R-T
ree
(Rectangle-T
ree)
предназначен
для
хранения
пар
(X,
Y)
значе-
ний
числового
типа
(например,
коор
динат).
По
способу
орг
анизации
R-
T
ree
очень
пох
о
же
на
B-T
ree.
Единственное
отличие
—
это
информация,
записываемая
в
промежуточные
страницы
в
дереве.
Для
i-го
значения
в
38
3.1.
Типы
индексов
узле
в
B-T
ree
мы
пишем
максимум
из
i-го
по
ддерева,
а
в
R-T
ree
—
мини-
мальный
пр
ямоугольник,
покрывающий
все
пр
ямоугольники
из
ребёнк
а.
По
дробней
можно
увидеть
на
рисунке
3.2
.
Рис.
3.2:
R-T
ree
индек
с
Сильные
стороны:
∙
поиск
произвольных
регионов,
точек
за
O(
log
𝑚
𝑁
),
где
m
—
количе-
ство
записей
в
блок
е,
N
—
количество
элементов;
∙
позволяет
оценить
к
оличество
точек
в
нек
отором
регионе
без
полного
ск
анирования
данных;
Слабые
стороны:
∙
существенная
избыточность
в
хранении
данных;
∙
медленное
обновление
данных;
В
целом,
плюсы-мину
сы
очень
напоминают
B-T
ree.
39
3.1.
Типы
индексов
Hash
индек
с
Hash
индек
с
по
сути
является
ассоциативным
хеш-к
онтейнером.
Хеш-
к
онтейнер
—
это
массив
из
разр
яж
енных
значений.
Адресуютс
я
отдель-
ные
элементы
этого
массива
нек
оторой
хеш-функцией
к
оторая
отобража-
ет
каждое
зна
чение
в
нек
оторое
целое
число.
Т
.
е.
резу
ль
т
ат
хеш-функции
являетс
я
пор
ядк
овым
номером
элемент
а
в
массиве.
Элементы
массива
в
х
еш-контейнере
называются
бак
ет
ами
(buck
et).
Обычно
один
бак
ет
—
о
д-
на
страница.
Хеш-функция
отображ
ает
более
мощное
множ
ество
в
менее
мощное, возник
ают т
ак называемые к
оллизии —
ситу
ация, к
огда о
дно-
му
зна
чению
х
еш-функции
соответству
ет
неск
ольк
о
разных
зна
чений.
В
бак
ете
хранятся
значения,
образующие
коллизию.
Разрешение
коллизий
проис
хо
дит
посредством
поиска
среди
значений,
сохранённых
в
бакете.
Рис.
3.3:
Hash
индек
с
Сильные
стороны:
∙
очень
быстрый
поиск
O(1);
∙
ст
абильность
—
индек
с
не
нужно
перестраивать;
Слабые
стороны:
∙
х
еш
очень
чувствителен
к
коллизиям
хеш-функции.
В
случае
«пло-
х
ого»
распределения
данных,
большинство
записей
бу
дет
сосредото-
чено
в
нескольких
бак
етах,
и
фактически
поиск
бу
дет
проис
хо
дить
путем
разрешения
к
оллизий;
40
3.1.
Типы
индексов
∙
из-за
нелинейности
хэш-функций
данный
индекс
нельзя
сортировать
по
зна
чению,
что
приво
дит
к
невозможности
использования
в
срав-
нениях
больше/меньше
и
«IS
NULL»;
∙
данный
индекс
в
P
ostgreSQL
транзакционно
небезопасен,
нужно
перестраивать
после
крах
а
и
не
реплициру
ется
через
потоковую
(streaming)
репликацию
(разработчики
обещают
это
исправить
к
10
версии);
Битовый
индек
с
(bitmap
index)
Битовый
индек
с
(bitmap
index)
—
метод
битовых
индек
сов
заключа-
етс
я
в
создании
отдельных
битовых
карт
(последовательность
0
и
1)
для
к
аждого
возмо
жного
зна
чения
столбца,
где
к
аждому
биту
соответству
ет
строк
а
с
индексиру
емым
значением,
а
его
значение
равное
1
озна
чает
,
что
запись,
соответствующая
позиции
бита
содер
жит
индек
сируемое
значение
для
данного
столбца
или
свойства
(
алгоритм
Хаффмана
).
Рис.
3.4:
Битовый
индек
с
Сильные
стороны:
∙
к
омпактность
предст
авления
(занимает
мало
места);
∙
быстрое
чтение
и
поиск
по
предикату
«равно»;
Слабые
стороны:
∙
невозмо
жность изменить
способ к
о
дирования зна
ч
ений в
процессе
обновления
данных;
41
3.1.
Типы
индексов
У
P
ostgreSQL
нет
возможности
создать
постоянный
битовый
индекс,
но
база
мож
ет
на
лету
создавать
данные
индексы
для
объединения
разных
индек
сов.
Чтобы
объединить
нескольк
о
индек
сов,
база
сканиру
ет
к
аждый
необ
хо
димый
индекс
и
готовит
битовую
карту
в
памяти
с
располож
ением
строк
т
аблицы.
Битовые
к
арты
затем
обрабатываются
AND/OR опера-
цией по
мере требования запроса
и после
этого выбираютс
я
к
олонки с
данными.
GiST
индек
с
GiST
(Generalized
Search
T
ree)
—
обобщение
B-T
ree,
R-T
ree
дерево
по-
иск
а
по
произвольному
предикату
.
Структура
дерева
не
меняется, по-
прежнему
в
к
аждом
нелистовом
узле
хранятс
я
пары
(Значения,
Номер
страницы),
а
к
оличество
детей
совпадает
с
к
оличеством
пар
в
узле.
Суще-
ственное
отличие
состоит
в
орг
анизации
ключа.
B-T
ree
деревья
заточены
по
д
поиск
диапазонов
и
хранят
мак
симумы
по
ддерева-ребёнк
а.
R-T
ree
—
региона
на
к
оор
динатной
плоскости.
GiST
предлаг
ает
в
ка
честве
зна
че-
ний
в
нелистовых
узлах
хранить
ту
информацию,
которую
мы
счит
аем
существенной,
и
которая
позволит
определить,
есть
ли
интересующие
нас
зна
чения
(у
довлетвор
яющие
предикату)
в
по
ддереве-ребёнке.
Конкретный
вид
хранимой
информации
зависит
от
вида
поиска,
который
мы
желаем
прово
дить.
Т
аким
образом
параметризовав
R-T
ree
и
B-T
ree
дерево
преди-
к
атами
и
значениями
мы
автоматически
получаем
специализированный
по
д
задачу
индекс
(PostGiST,
pg_trgm,
hstore,
ltree,
прочее).
Сильные
стороны:
∙
эффективный
поиск;
Слабые
стороны:
∙
большая
избыточность;
∙
необ
х
одимость
специализированной
реализации
по
д
к
аждую
группу
запросов;
Ост
альные
плюсы-минусы
совпадают
с
B-T
ree
и
R-T
ree
индексами.
GIN
индек
с
GIN (Generalized In
v
erted Index) —
обратный индек
с, использу
емым
полнотек
стовым
поиск
ом
P
ostgreSQL.
Это
означает
,
что
в
структуре
ин-
дек
сов
с
каждой
лек
семой
сопоставляетс
я
отсортированный
список
номе-
ров
документов,
в
которых
она
встречаетс
я.
Очевидно,
что
поиск
по
т
а-
к
ой
структуре
намного
эффективнее,
чем
при
использовании
GiST,
однак
о
процесс
добавления
нового
документ
а
достаточно
длителен.
42
3.1.
Типы
индексов
Cluster
индек
с
Не являетс
я индек
сом, поск
ольку произво
дит кластеризацию т
абли-
цы
по
заданному
индексу
.
Более
по
дробно
можно
почитать
в
разделе
«
2.3
CLUSTER
»
.
BRIN
индек
с
Версия
PostgreSQL
9.5
привнесла
с
собой
новый
вид
индек
сов
—
BRIN
(Blo
c
k
Range
Index,
или
индек
с
блоковых
зон).
Рис.
3.5:
BRIN
индек
с
В
отличие
от
привычного
B-T
ree,
этот
индек
с
намного
эффективнее
для
очень
больших
т
аблиц,
и
в
некоторых
ситу
ациях
позволяет
заменить
собой
партици
рование
(подробно
можно
почит
ать
в
разделе
«
4
Партицио-
нирование
»).
BRIN-индекс
имеет
смысл
применять
для
таблиц,
в
которых
часть
данных
уже
по
своей
природе
как-то
отсортирована.
Например,
это
х
арактерно
для
логов
или
для
истории
заказов
магазина,
которые
пишут-
с
я
последовательно,
а
потому
уже
на
физическом
уровне
упорядочены
по
дате/номеру
,
и
в
то
же
время
т
аблицы
с
т
акими
данными
обычно
разрас-
т
аются
до
гигантских
размеров.
По
д
блок
овой
зоной
(Blo
ck
Range)
по
дразумеваетс
я
набор
страниц,
фи-
зически
располож
енных
по
соседству
в
т
аблице.
Для
к
аждой
так
ой
зоны
создаетс
я
некий
идентификатор,
отвечающий
за
«место»
этой
зоны
в
таб-
лице.
Для
лог
а
это
мож
ет
быть
дат
а
создания
записи.
Поиск
по
т
акому
индек
су
осуществляетс
я
с
потерями
информации,
то
есть
выбираются
все
записи,
вхо
дящие
в
блоковые
зоны
с
идентификаторами,
соответствующи-
ми
запросу
,
но
среди
записей
в
этих
зонах
могут
попадаться
т
акие,
которые
43
3.2.
Возможности
индексов
на
следующем
этапе
надо
бу
дет
отфильтровать.
Размер
индек
са
при
этом
очень
маленький,
и
он
почти
не
нагружает
базу
.
Размер
индекса
обратно
пропорционален
параметру
pages_p
er_range
,
отвечающему
за
к
оличество
страниц
на
зону
.
В
то
же
время,
чем
меньше
размер
зоны,
тем
меньше
«лишних»
данных
попадёт
в
резу
ль
тат
поиска
(надо
подх
о
дить
к
этому
параметру
с
умом).
Индек
сы
BRIN
могут
иметь
один
из
неск
ольких
встроенных
классов
операторов,
по
к
оторым
бу
дет
осуществляться
разбивка
на
зоны
и
при-
своение
идентификаторов.
Например,
int8_minmax_ops
применяется
для
операций
сравнения
целых
чисел,
а
date_minmax_ops
для
сравнения
дат
.
3.2
Возмо
жности
индек
сов
Функциональный
индек
с
(functional
index)
Вы
мо
жете
построить
индек
с не
тольк
о по
полю/нескольким
полям
т
аблицы, но и по выражению,
завис
ящему от полей. Пусть, например,
в
вашей
т
аблице
foo
есть
поле
foo_name
,
и
выборки
часто
делаются
по
у
словию
«первая
буква
из
поля
fo
o_name
в
любом
регистре»
.
Вы
мож
ете
создать
индек
с
Листинг
3.1
Индекс
Line
1
C
R
E
A
T
E
I
N
D
E
X
f
o
o
_
n
a
m
e
_
f
i
r
s
t
_
i
d
x
O
N
f
o
o
(
(
l
o
w
e
r
(
s
u
b
s
t
r
(
f
o
o
_
n
a
m
e
,
1
,
1
)
)
)
)
;
и
запрос
вида
Листинг
3.2
Запрос
Line
1
S
E
L
E
C
T
*
F
R
O
M
f
o
o
W
H
E
R
E
l
o
w
e
r
(
s
u
b
s
t
r
(
f
o
o
_
n
a
m
e
,
1
,
1
)
)
=
’
а
’
;
бу
дет
его
использовать.
Частичный
индек
с
(partial
index)
По
д
частичным
индек
сом
понимается
индек
с
с
предик
атом
WHERE.
Пу
сть,
например,
у
вас
есть
в
базе
таблица
scheta
с
параметром
uplo
c
heno
типа
b
o
olean.
Записей,
где
uplo
cheno
=
false
меньше,
чем
записей
с
uplo
cheno
=
true
, а запросы по ним выполняютс
я зна
чительно чаще. Вы мо
жете
создать
индек
с
Листинг
3.3
Индекс
Line
1
C
R
E
A
T
E
I
N
D
E
X
s
c
h
e
t
a
_
n
e
u
p
l
o
c
h
e
n
o
O
N
s
c
h
e
t
a
(
i
d
)
W
H
E
R
E
N
O
T
u
p
l
o
c
h
e
n
o
;
44
3.2.
Возможности
индексов
к
оторый
бу
дет
использоваться
запросом
вида
Листинг
3.4
Запрос
Line
1
S
E
L
E
C
T
*
F
R
O
M
s
c
h
e
t
a
W
H
E
R
E
N
O
T
u
p
l
o
c
h
e
n
o
A
N
D
.
.
.
;
Достоинство
подх
о
да
в
том,
что
записи,
не
у
довлетвор
яющие
условию
WHERE,
просто
не
попадут
в
индек
с.
Уник
альный
индекс
(unique
index)
Уник
альный индекс г
арантирует
, что т
аблица не бу
дет иметь более
чем
о
дну
строку
с
тем
ж
е
зна
чением.
Это
у
добно
по
двум
причинам:
це-
лостность
данных
и
произво
дительность.
Поиск
данных
с
использованием
уник
ального
индекса,
как
правило,
очень
быстрый.
Индек
с
нескольких
столбцов
(multi-column
index)
В
PostgreSQL
возможно
создавать
индексы
на
нескольк
о
столбцов,
но
нам
г
лавное нужно
понять
к
ог
да
имеет
смысл
создавать
т
акой
индекс,
поск
ольку
планировщик
запросов
PostgreSQL
мож
ет
к
омбинировать
и
ис-
пользовать
неск
ольк
о
индек
сов
в
запросе
путем
создания
битового
индекса
(«
3.1
Битовый
индекс
(bitmap
index)
»).
Можно,
к
онечно,
создать
индек-
сы,
которые
охват
ят
все
возможные
запросы,
но
за
это
придется
платить
произво
дительностью
(индек
сы
нужно
перестраивать
при
запросах
на
мо-
дифик
ацию
данных).
Нужно
такж
е
помнить,
что
индексы
на
нескольк
о
столбцов
могут
использоваться
тольк
о
запросами,
к
оторые
ссылаются
на
эти
столбцы
в
индек
се
в
том
ж
е
порядк
е.
Индек
с
по
столбцам
(
a
,
b)
мо-
ж
ет
быть
использован
в
запросах,
которые
содер
ж
ат
a
=
x
and
b
=
y
или
a
=
x
,
но
не
бу
дет
использоваться
в
запросе
вида
b
=
y
.
Если
это
по
дхо
дит
по
д
запросы
вашего
прилож
ения,
то
данный
индек
с
мож
ет
быть
полезен.
В
т
аком
случае
создание
индекса
на
поле
a
было
бы
излишним.
Индекс
неск
ольких
столбцов
с
ук
азанием
уникальности
(
unique
)
мож
ет
быть
так-
ж
е
полезен
для
сохранения
целостности
данных
(т
.
е.
ког
да
набор
данных
в
этих
стобцах
долж
ен
быть
уникальным).
45
4
Партиционирование
Р
ешая
к
акую-либо
проблему
,
всег
да
полезно
заранее
знать
правильный
ответ
.
При
у
словии,
к
онечно,
что
вы
уверены
в
наличии
самой
проблемы
Наро
дная
му
дрость
4.1
Введение
Партиционирование
(partitioning,
секционирование)
—
это
разбиение
больших
структур
баз
данных
(таблицы,
индек
сы)
на
меньшие
кусочки.
Звучит
сло
жно,
но
на
практике
все
просто.
Ск
орее
всего
у
Вас
есть
неск
олько
огромных
таблиц
(обычно
всю
на-
грузку
обеспечивают
всего
нескольк
о
таблиц
СУБД
из
всех
имеющихс
я).
Причем
чтение
в
большинстве
случаев
прихо
дится
только
на
самую
по-
следнюю
их
часть
(т
.
е.
активно
чит
аются
те
данные,
которые
недавно
по
явились).
Примером
тому
мо
жет
служить
блог
—
на
первую
страницу
(это последние
5.
.
.
10 постов)
прих
одитс
я
40.
.
.
50%
всей
нагрузки,
или
новостной
порт
ал
(суть
одна
и
та
ж
е),
или
системы
личных
сообщений,
впрочем
понятно.
Партиционирование
т
аблицы
позволяет
базе
данных
де-
лать
интеллектуальную
выборку
—
сначала
СУБД
уточнит
,
как
ой
парти-
ции
соответству
ет
Ваш
запрос
(если
это
реально)
и
тольк
о
потом
с
делает
этот
запрос,
применительно
к
нужной
партиции
(или
нескольким
парти-
циям).
Т
аким
образом,
в
рассмотренном
случае,
Вы
распределите
нагруз-
ку
на
т
аблицу
по
ее
партициям.
Следовательно
выборк
а
типа
SELECT
*
FR
OM
articles
ORDER
BY
id
DESC
LIMIT
10
бу
дет
выполнятьс
я
только
над
последней
партицией,
к
оторая
значительно
меньше
всей
таблицы.
Ит
ак,
партиционирование
дает
ряд
преимуществ:
46
4.2.
Т
еория
∙
На
определенные
виды
запросов
(которые,
в
свою
очередь,
создают
основную
нагрузку
на
СУБД)
мы
мо
жем
у
лучшить
производитель-
ность;
∙
Массовое
у
даление
мо
ж
ет
быть
произведено
путем
у
даления
одной
или
неск
ольких
партиций
(
DR
OP
T
ABLE
гораздо
быстрее,
чем
мас-
совый
DELETE
);
∙
Р
едк
о
используемые
данные
могут
быть
перенесены
в
другое
храни-
лище;
4.2
Т
еория
На
текущий
момент
PostgreSQL
по
ддерживает
два
критерия
для
со-
здания
партиций:
∙
Партиционирование
по
диапазону
значений
(range)
—
таблица
разби-
ваетс
я
на
«диапазоны»
значений
по
полю
или
набору
полей
в
табли-
це,
без
перекрытия
диапазонов
зна
чений,
отнесенных
к
различным
партициям.
Например,
диапазоны
дат;
∙
Партиционирование
по
списку
зна
чений
(list)
—
т
аблица
разбивается
по
списк
ам
ключевых
значений
для
каждой
партиции.
Чтобы
настроить
партиционирование
т
аблицы,
дост
аточно
выполнить
следующие
действия:
∙
Создаетс
я
«мастер»
таблица,
из
которой
все
партиции
бу
дут
насле-
доватьс
я.
Эт
а
т
аблица
не
бу
дет
со
держ
ать
данные.
Т
акже
не
нужно
ст
авить
никаких
ограничений
на
т
аблицу
,
если
конечно
они
не
бу
дут
дублироватьс
я
на
партиции;
∙
Создайте
нескольк
о
«дочерних»
т
аблиц,
к
оторые
наследуют
от
«ма-
стер»
т
аблицы;
∙
Добавить
в «дочерние» т
аблицы
зна
чения, по
к
оторым они
бу
дут
партициями.
Стоить
заметить,
что
зна
чения
партиций
не
должны
пересек
аться.
Например:
Листинг
4.1
Пример
неверного
задания
значений
партиций
Line
1
C
H
E
C
K
(
o
u
t
l
e
t
I
D
B
E
T
W
E
E
N
1
0
0
A
N
D
2
0
0
)
-
C
H
E
C
K
(
o
u
t
l
e
t
I
D
B
E
T
W
E
E
N
2
0
0
A
N
D
3
0
0
)
неверно
заданы
партиции,
поскольку
непонятно
как
ой
партиции
при-
надлежит
зна
чение
200;
∙
Для
каждой
партиции
создать
индекс
по
ключевому
полю
(или
неск
ольким),
а
такж
е
указать
любые
другие
требуемые
индексы;
∙
При
необх
о
димости,
создать
триггер
или
правило
для
перенаправле-
ния
данных
с
«мастер»
т
аблицы
в
соответствующую
партицию;
47
4.3.
Практика
использования
∙
Убедитьс
я,
что
параметр
constraint_exclusion
не
отключен
в
p
ostgresql.conf.
Если
его
не
включить,
то
запросы
не
бу
дут
оптими-
зированы
при
работе
с
партиционированием;
4.3
Практик
а
использования
Т
еперь
начнем
с
практическ
ого
примера.
Предст
авим,
что
в
нашей
си-
стеме
есть
таблица,
в
которую
мы
собираем
данные
о
посещаемости
нашего
ресурса.
На
любой
запрос
пользователя
наша
система
логирует
действия
в
эту
таблицу
.
И,
например,
в
начале
каждого
мес
яца
(неделю)
нам
нуж-
но
создавать
отчет
за
предыдущий
мес
яц
(неделю).
При
этом
логи
нужно
хранить
в
течение
3
лет
.
Данные
в
т
ак
ой
т
аблице
нак
апливаются
быстро,
если
система
активно
используетс
я.
И
вот
,
к
ог
да
в
т
аблице
уже
миллионы,
а
то
и
миллиарды
записей,
создавать
отчеты
ст
ановится
все
сложнее
(да
и
чистк
а
старых
записей
ст
ановитс
я
нелегким
делом).
Работ
а
с
так
ой
т
абли-
цей
создает
огромную
нагрузку
на
СУБД.
Тут
нам
на
помощь
и
прихо
дит
партиционирование.
Настройк
а
Для
примера,
мы
имеем
следующую
т
аблицу:
Листинг
4.2
«Мастер»
таблица
Line
1
C
R
E
A
T
E
T
A
B
L
E
m
y
_
l
o
g
s
(
-
i
d
SE
RIA
L
P
R
I
M
A
R
Y
K
E
Y
,
-
u
s
e
r
_
i
d
INT
N
O
T
N
U
L
L
,
-
l
o
g
d
a
t
e
T
I
M
E
S
T
A
M
P
N
O
T
N
U
L
L
,
5
d
a
t
a
T
E
X
T,
-
s
o
m
e
_
s
t
a
t
e
INT
-
)
;
Поск
ольку
нам
нужны
отчеты
к
аждый
месяц,
мы
бу
дем
делить
пар-
тиции
по
мес
яцам.
Это
помож
ет
нам
быстрее
создавать
отчеты
и
чистить
ст
арые
данные.
«Мастер»
таблица
бу
дет
m
y_logs
,
структуру
к
оторой
мы
ук
азали
выше.
Далее
создадим
«дочерние»
т
аблицы
(партиции):
Листинг
4.3
«Дочерние»
таблицы
Line
1
C
R
E
A
T
E
T
A
B
L
E
m
y
_
l
o
g
s
2
0
1
0
m
1
0
(
-
C
H
E
C
K
(
l
o
g
d
a
t
e
>
=
D
A
T
E
’
2
0
1
0
-
1
0
-
0
1
’
A
N
D
l
o
g
d
a
t
e
<
D
A
T
E
’
2
0
1
0
-
1
1
-
0
1
’
)
-
)
IN
HERI
TS
(
m
y
_
l
o
g
s
)
;
-
C
R
E
A
T
E
T
A
B
L
E
m
y
_
l
o
g
s
2
0
1
0
m
1
1
(
48
4.3.
Практика
использования
5
C
H
E
C
K
(
l
o
g
d
a
t
e
>
=
D
A
T
E
’
2
0
1
0
-
1
1
-
0
1
’
A
N
D
l
o
g
d
a
t
e
<
D
A
T
E
’
2
0
1
0
-
1
2
-
0
1
’
)
-
)
IN
HERI
TS
(
m
y
_
l
o
g
s
)
;
-
C
R
E
A
T
E
T
A
B
L
E
m
y
_
l
o
g
s
2
0
1
0
m
1
2
(
-
C
H
E
C
K
(
l
o
g
d
a
t
e
>
=
D
A
T
E
’
2
0
1
0
-
1
2
-
0
1
’
A
N
D
l
o
g
d
a
t
e
<
D
A
T
E
’
2
0
1
1
-
0
1
-
0
1
’
)
-
)
IN
HERI
TS
(
m
y
_
l
o
g
s
)
;
10
C
R
E
A
T
E
T
A
B
L
E
m
y
_
l
o
g
s
2
0
1
1
m
0
1
(
-
C
H
E
C
K
(
l
o
g
d
a
t
e
>
=
D
A
T
E
’
2
0
1
1
-
0
1
-
0
1
’
A
N
D
l
o
g
d
a
t
e
<
D
A
T
E
’
2
0
1
0
-
0
2
-
0
1
’
)
-
)
IN
HERI
TS
(
m
y
_
l
o
g
s
)
;
Данными
к
омандами
мы
создаем
таблицы
m
y_logs2010m10
,
m
y_logs2010m11
и
т
.
д.,
которые
к
опируют
структуру
с
«мастер»
таблицы
(кроме
индексов).
Т
акж
е
с
помощью
«CHECK»
мы
задаем
диапазон
зна-
чений,
к
оторый
бу
дет
попадать
в
эту
партицию
(хочу
опять
напомнить,
что
диапазоны
зна
чений
партиций
не
должны
пересекатьс
я!).
Поскольку
партиционирование
бу
дет
работать
по
полю
logdate
,
мы
создадим
индекс
на
это
поле
на
всех
партициях:
Листинг
4.4
Создание
индексов
Line
1
C
R
E
A
T
E
I
N
D
E
X
m
y
_
l
o
g
s
2
0
1
0
m
1
0
_
l
o
g
d
a
t
e
O
N
m
y
_
l
o
g
s
2
0
1
0
m
1
0
(
l
o
g
d
a
t
e
)
;
-
C
R
E
A
T
E
I
N
D
E
X
m
y
_
l
o
g
s
2
0
1
0
m
1
1
_
l
o
g
d
a
t
e
O
N
m
y
_
l
o
g
s
2
0
1
0
m
1
1
(
l
o
g
d
a
t
e
)
;
-
C
R
E
A
T
E
I
N
D
E
X
m
y
_
l
o
g
s
2
0
1
0
m
1
2
_
l
o
g
d
a
t
e
O
N
m
y
_
l
o
g
s
2
0
1
0
m
1
2
(
l
o
g
d
a
t
e
)
;
-
C
R
E
A
T
E
I
N
D
E
X
m
y
_
l
o
g
s
2
0
1
1
m
0
1
_
l
o
g
d
a
t
e
O
N
m
y
_
l
o
g
s
2
0
1
1
m
0
1
(
l
o
g
d
a
t
e
)
;
Далее
для
у
добства
создадим
функцию,
к
оторая
бу
дет
перенаправлять
новые
данные
с
«мастер»
т
аблицы
в
соответствующую
партицию.
Листинг
4.5
Функция
для
перенаправления
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
m
y
_
l
o
g
s
_
i
n
s
e
r
t
_
t
r
i
g
g
e
r
(
)
-
R
E
T
U
R
N
S
T
R
I
G
G
E
R A
S
$
$
-
B
E
G
I
N
-
I
F
(
N
E
W.
l
o
g
d
a
t
e
>
=
D
A
T
E
’
2
0
1
0
-
1
0
-
0
1
’
A
N
D
5
N
E
W.
l
o
g
d
a
t
e
<
D
A
T
E
’
2
0
1
0
-
1
1
-
0
1
’
)
T
H
E
N
-
I
NS
ER
T
I
N
T
O
m
y
_
l
o
g
s
2
0
1
0
m
1
0
V
A
L
U
E
S
(
N
E
W.
*
)
;
-
EL
S
I
F
(
N
E
W.
l
o
g
d
a
t
e
>
=
D
A
T
E
’
2
0
1
0
-
1
1
-
0
1
’
A
N
D
-
N
E
W.
l
o
g
d
a
t
e
<
D
A
T
E
’
2
0
1
0
-
1
2
-
0
1
’
)
T
H
E
N
-
I
NS
ER
T
I
N
T
O
m
y
_
l
o
g
s
2
0
1
0
m
1
1
V
A
L
U
E
S
(
N
E
W.
*
)
;
10
EL
S
I
F
(
N
E
W.
l
o
g
d
a
t
e
>
=
D
A
T
E
’
2
0
1
0
-
1
2
-
0
1
’
A
N
D
-
N
E
W.
l
o
g
d
a
t
e
<
D
A
T
E
’
2
0
1
1
-
0
1
-
0
1
’
)
T
H
E
N
-
I
NS
ER
T
I
N
T
O
m
y
_
l
o
g
s
2
0
1
0
m
1
2
V
A
L
U
E
S
(
N
E
W.
*
)
;
49
4.3.
Практика
использования
-
EL
S
I
F
(
N
E
W.
l
o
g
d
a
t
e
>
=
D
A
T
E
’
2
0
1
1
-
0
1
-
0
1
’
A
N
D
-
N
E
W.
l
o
g
d
a
t
e
<
D
A
T
E
’
2
0
1
1
-
0
2
-
0
1
’
)
T
H
E
N
15
I
NS
ER
T
I
N
T
O
m
y
_
l
o
g
s
2
0
1
1
m
0
1
V
A
L
U
E
S
(
N
E
W.
*
)
;
-
E
L
SE
-
RAI
SE
E
X
C
E
P
T
I
O
N
’
D
a
t
e
o
u
t
o
f
r
a
n
g
e
.
F
i
x
t
h
e
m
y
_
l
o
g
s
_
i
n
s
e
r
t
_
t
r
i
g
g
e
r
(
)
f
u
n
c
t
i
o
n
!
’
;
-
E
N
D
I
F
;
-
R
E
T
U
R
N
N
U
L
L
;
20
E
N
D
;
-
$
$
-
L
A
N
G
U
A
G
E
p
l
p
g
s
q
l
;
В
функции
ничего
особенного
нет:
идет
проверк
а
поля
logdate
,
по
к
ото-
рой
направляются
данные
в
нужную
партицию.
При
ненахо
ждении
требу-
емой
партиции
—
вызываем
ошибку
.
Т
еперь
осталось
создать
триггер
на
«мастер»
т
аблицу
для
автоматического
вызова
данной
функции:
Листинг
4.6
Триггер
Line
1
C
R
E
A
T
E
T
R
I
G
G
E
R
i
n
s
e
r
t
_
m
y
_
l
o
g
s
_
t
r
i
g
g
e
r
-
B
E
F
O
R
E
I
NS
ER
T
O
N
m
y
_
l
o
g
s
-
F
O
R
E
A
C
H
R
O
W
E
X
E
C
U
T
E
P
R
O
C
E
D
U
R
E
m
y
_
l
o
g
s
_
i
n
s
e
r
t
_
t
r
i
g
g
e
r
(
)
;
Партиционирование
настроено
и
теперь
мы
готовы
приступить
к
те-
стированию.
Т
естирование
Для
на
чала
добавим
данные
в
нашу
таблицу
my_logs
:
Листинг
4.7
Данные
Line
1
IN
SE
R
T
I
N
T
O
m
y
_
l
o
g
s
(
u
s
e
r
_
i
d
,
l
o
g
d
a
t
e
,
d
a
t
a
,
s
o
m
e
_
s
t
a
t
e
)
V
A
L
U
E
S
(
1
,
’
2
0
1
0
-
1
0
-
3
0
’
,
’
3
0
.
1
0
.
2
0
1
0
d
a
t
a
’
,
1
)
;
-
I
N
SE
RT I
NT
O
m
y
_
l
o
g
s
(
u
s
e
r
_
i
d
,
l
o
g
d
a
t
e
,
d
a
t
a
,
s
o
m
e
_
s
t
a
t
e
)
V
A
L
U
E
S
(
2
,
’
2
0
1
0
-
1
1
-
1
0
’
,
’
1
0
.
1
1
.
2
0
1
0
d
a
t
a
2
’
,
1
)
;
-
I
N
SE
RT I
NT
O
m
y
_
l
o
g
s
(
u
s
e
r
_
i
d
,
l
o
g
d
a
t
e
,
d
a
t
a
,
s
o
m
e
_
s
t
a
t
e
)
V
A
L
U
E
S
(
1
,
’
2
0
1
0
-
1
2
-
1
5
’
,
’
1
5
.
1
2
.
2
0
1
0
d
a
t
a
3
’
,
1
)
;
Т
еперь
проверим
г
де
они
хранятся:
Листинг
4.8
«Мастер»
таблица
чиста
Line
1
p
a
r
t
i
t
i
o
n
i
n
g
_
t
e
s
t=
#
S
E
L
E
C
T
*
F
R
O
M
O
N
L
Y
m
y
_
l
o
g
s
;
-
i
d
|
u
s
e
r
_
i
d
|
l
o
g
d
a
t
e
|
d
a
t
a
|
s
o
m
e
_
s
t
a
t
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
(
0
r
o
w
s
)
50
4.3.
Практика
использования
Как
видим,
в
«мастер»
т
аблицу
данные
не
попали
—
она
чист
а.
Т
еперь
проверим,
а
есть
ли
вообще
данные:
Листинг
4.9
Проверка
данных
Line
1
p
a
r
t
i
t
i
o
n
i
n
g
_
t
e
s
t=
#
S
E
L
E
C
T
*
F
R
O
M
m
y
_
l
o
g
s
;
-
i
d
|
u
s
e
r
_
i
d
|
l
o
g
d
a
t
e
|
d
a
t
a
|
s
o
m
e
_
s
t
a
t
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
1
|
1
|
2
0
1
0
-
1
0
-
3
0
0
0
:
0
0
:
0
0
|
3
0
.
1
0
.
2
0
1
0
d
a
t
a
|
1
5
2
|
2
|
2
0
1
0
-
1
1
-
1
0
0
0
:
0
0
:
0
0
|
1
0
.
1
1
.
2
0
1
0
d
a
t
a
2
|
1
-
3
|
1
|
2
0
1
0
-
1
2
-
1
5
0
0
:
0
0
:
0
0
|
1
5
.
1
2
.
2
0
1
0
d
a
t
a
3
|
1
-
(
3
r
o
w
s
)
Данные
при
этом
выводятс
я без
проблем. Проверим
партиции, пра-
вильно
ли
хранятс
я
данные:
Листинг
4.10
Проверка
хранения
данных
Line
1
p
a
r
t
i
t
i
o
n
i
n
g
_
t
e
s
t=
#
S
e
l
e
c
t
*
f
r
o
m
m
y
_
l
o
g
s
2
0
1
0
m
1
0
;
-
i
d
|
u
s
e
r
_
i
d
|
l
o
g
d
a
t
e
|
d
a
t
a
|
s
o
m
e
_
s
t
a
t
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
1
|
1
|
2
0
1
0
-
1
0
-
3
0
0
0
:
0
0
:
0
0
|
3
0
.
1
0
.
2
0
1
0
d
a
t
a
|
1
5
(
1
r
o
w
)
-
-
p
a
r
t
i
t
i
o
n
i
n
g
_
t
e
s
t=
#
S
e
l
e
c
t
*
f
r
o
m
m
y
_
l
o
g
s
2
0
1
0
m
1
1
;
-
i
d
|
u
s
e
r
_
i
d
|
l
o
g
d
a
t
e
|
d
a
t
a
|
s
o
m
e
_
s
t
a
t
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
10
2
|
2
|
2
0
1
0
-
1
1
-
1
0
0
0
:
0
0
:
0
0
|
1
0
.
1
1
.
2
0
1
0
d
a
t
a
2
|
1
-
(
1
r
o
w
)
Данные
хранятся
на
требу
емых
нам
партициях.
При
этом
запросы
к
т
аблице
my_logs
менять
не
требуетс
я:
51
4.3.
Практика
использования
Листинг
4.11
Проверка
запросов
Line
1
p
a
r
t
i
t
i
o
n
i
n
g
_
t
e
s
t=
#
S
E
L
E
C
T
*
F
R
O
M
m
y
_
l
o
g
s
W
H
E
R
E
u
s
e
r
_
i
d
=
2
;
-
i
d
|
u
s
e
r
_
i
d
|
l
o
g
d
a
t
e
|
d
a
t
a
|
s
o
m
e
_
s
t
a
t
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
2
|
2
|
2
0
1
0
-
1
1
-
1
0
0
0
:
0
0
:
0
0
|
1
0
.
1
1
.
2
0
1
0
d
a
t
a
2
|
1
5
(
1
r
o
w
)
-
-
p
a
r
t
i
t
i
o
n
i
n
g
_
t
e
s
t=
#
S
E
L
E
C
T
*
F
R
O
M
m
y
_
l
o
g
s
W
H
E
R
E
d
a
t
a
LIKE
’
%0.
1%
’
;
-
i
d
|
u
s
e
r
_
i
d
|
l
o
g
d
a
t
e
|
d
a
t
a
|
s
o
m
e
_
s
t
a
t
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
10
1
|
1
|
2
0
1
0
-
1
0
-
3
0
0
0
:
0
0
:
0
0
|
3
0
.
1
0
.
2
0
1
0
d
a
t
a
|
1
-
2
|
2
|
2
0
1
0
-
1
1
-
1
0
0
0
:
0
0
:
0
0
|
1
0
.
1
1
.
2
0
1
0
d
a
t
a
2
|
1
-
(
2
r
o
w
s
)
Управление
партициями
Обычно
при
работе
с
партиционированием
ст
арые
партиции
переста-
ют
получать
данные
и ост
аютс
я неизменными.
Это дает
огромное пре-
имущество
над
работой
с
данными
через
партиции.
Например,
нам
нужно
у
далить
старые
логи
за
2014
год,
10
месяц.
Нам
достаточно
выполнить:
Листинг
4.12
Чистка
логов
Line
1
D
R
O
P
T
A
B
L
E
m
y
_
l
o
g
s
2
0
1
4
m
1
0
;
поск
ольку
DROP
T
ABLE
работ
ает
гораздо
быстрее,
чем
у
даление
мил-
лионов
записей
индивидуально
через
DELETE
.
Другой
вариант
,
к
оторый
более
предпочтителен,
просто
у
далить
партицию
из
партиционирования,
тем
самым
оставив
данные
в
СУБД,
но
уж
е
не
доступные
через
«мастер»
т
аблицу:
Листинг
4.13
У
даляем
партицию
из
партиционирования
Line
1
A
L
T
E
R
T
A
B
L
E
m
y
_
l
o
g
s
2
0
1
4
m
1
0
N
O
IN
HE
RIT
m
y
_
l
o
g
s
;
Это
у
добно,
если
мы
хотим
эти
данные
потом
перенести
в
другое
хра-
нилище
или
просто
со
хранить.
52
4.3.
Практика
использования
Важность
«constrain
t_exclusion»
для
партиционирования
Параметр
constraint_exclusion
отвечает
за
оптимизацию
запросов,
что
повышает производительность для
партиционированых
т
аблиц.
Напри-
мер,
выполним
простой
запрос:
Листинг
4.14
«constraint_exclus
ion»
OFF
Line
1
p
a
r
t
i
t
i
o
n
i
n
g
_
t
e
s
t=
#
S
E
T
c
o
n
s
t
r
a
i
n
t
_
e
x
c
l
u
s
i
o
n
=
o
f
f
;
-
p
a
r
t
i
t
i
o
n
i
n
g
_
t
e
s
t=
#
E
X
P
L
A
I
N
S
E
L
E
C
T
*
F
R
O
M
m
y
_
l
o
g
s
W
H
E
R
E
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
’
;
-
-
Q
U
E
R
Y
P
L
A
N
5
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
R
e
s
u
l
t
(
c
o
s
t
=
6
.
8
1
.
.
1
0
4
.
6
6
r
o
w
s
=
1
6
5
0
w
i
d
t
h
=
5
2
)
-
-
>
A
p
p
e
n
d
(
c
o
s
t
=
6
.
8
1
.
.
1
0
4
.
6
6
r
o
w
s
=
1
6
5
0
w
i
d
t
h
=
5
2
)
-
-
>
B
i
t
m
a
p
He
a
p
S
c
a
n
o
n
m
y
_
l
o
g
s
(
c
o
s
t
=
6
.
8
1
.
.
2
0
.
9
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
5
2
)
-
R
e
c
h
e
c
k
Con
d
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
10
-
>
B
i
t
m
a
p
I
n
d
e
x
S
c
a
n
o
n
m
y
_
l
o
g
s
_
l
o
g
d
a
t
e
(
c
o
s
t
=
0
.
0
0
.
.
6
.
7
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
0
)
-
I
n
d
e
x
Co
nd
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
-
-
>
B
i
t
m
a
p
He
a
p
S
c
a
n
o
n
m
y
_
l
o
g
s
2
0
1
0
m
1
0
m
y
_
l
o
g
s
(
c
o
s
t
=
6
.
8
1
.
.
2
0
.
9
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
5
2
)
-
R
e
c
h
e
c
k
Con
d
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
-
-
>
B
i
t
m
a
p
I
n
d
e
x
S
c
a
n
o
n
m
y
_
l
o
g
s
2
0
1
0
m
1
0
_
l
o
g
d
a
t
e
(
c
o
s
t
=
0
.
0
0
.
.
6
.
7
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
0
)
15
I
n
d
e
x
Co
nd
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
-
-
>
B
i
t
m
a
p
He
a
p
S
c
a
n
o
n
m
y
_
l
o
g
s
2
0
1
0
m
1
1
m
y
_
l
o
g
s
(
c
o
s
t
=
6
.
8
1
.
.
2
0
.
9
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
5
2
)
-
R
e
c
h
e
c
k
Con
d
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
-
-
>
B
i
t
m
a
p
I
n
d
e
x
S
c
a
n
o
n
m
y
_
l
o
g
s
2
0
1
0
m
1
1
_
l
o
g
d
a
t
e
(
c
o
s
t
=
0
.
0
0
.
.
6
.
7
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
0
)
-
I
n
d
e
x
Co
nd
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
20
-
>
B
i
t
m
a
p
He
a
p
S
c
a
n
o
n
m
y
_
l
o
g
s
2
0
1
0
m
1
2
m
y
_
l
o
g
s
(
c
o
s
t
=
6
.
8
1
.
.
2
0
.
9
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
5
2
)
-
R
e
c
h
e
c
k
Con
d
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
53
4.3.
Практика
использования
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
-
-
>
B
i
t
m
a
p
I
n
d
e
x
S
c
a
n
o
n
m
y
_
l
o
g
s
2
0
1
0
m
1
2
_
l
o
g
d
a
t
e
(
c
o
s
t
=
0
.
0
0
.
.
6
.
7
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
0
)
-
I
n
d
e
x
Co
nd
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
-
-
>
B
i
t
m
a
p
He
a
p
S
c
a
n
o
n
m
y
_
l
o
g
s
2
0
1
1
m
0
1
m
y
_
l
o
g
s
(
c
o
s
t
=
6
.
8
1
.
.
2
0
.
9
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
5
2
)
25
R
e
c
h
e
c
k
Con
d
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
-
-
>
B
i
t
m
a
p
I
n
d
e
x
S
c
a
n
o
n
m
y
_
l
o
g
s
2
0
1
1
m
0
1
_
l
o
g
d
a
t
e
(
c
o
s
t
=
0
.
0
0
.
.
6
.
7
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
0
)
-
I
n
d
e
x
Co
nd
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
-
(
2
2
r
o
w
s
)
Как
видно
через
к
оманду
EXPLAIN
,
данный
запрос
сканиру
ет
все
партиции
на
наличие данных
в них,
что не
логично, поск
ольку
данное
у
словие
logdate
>
2010-12-01
говорит
о
том,
что
данные
должны
брать-
с
я
только с партиций, где по
дхо
дит так
ое
у
словие.
А
теперь включим
constrain
t_exclusion
:
Листинг
4.15
«constraint_exclus
ion»
ON
Line
1
p
a
r
t
i
t
i
o
n
i
n
g
_
t
e
s
t=
#
S
E
T
c
o
n
s
t
r
a
i
n
t
_
e
x
c
l
u
s
i
o
n
=
o
n
;
-
S
E
T
-
p
a
r
t
i
t
i
o
n
i
n
g
_
t
e
s
t=
#
E
X
P
L
A
I
N
S
E
L
E
C
T
*
F
R
O
M
m
y
_
l
o
g
s
W
H
E
R
E
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
’
;
-
Q
U
E
R
Y
P
L
A
N
5
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
R
e
s
u
l
t
(
c
o
s
t
=
6
.
8
1
.
.
4
1
.
8
7
r
o
w
s
=
6
6
0
w
i
d
t
h
=
5
2
)
-
-
>
A
p
p
e
n
d
(
c
o
s
t
=
6
.
8
1
.
.
4
1
.
8
7
r
o
w
s
=
6
6
0
w
i
d
t
h
=
5
2
)
-
-
>
B
i
t
m
a
p
He
a
p
S
c
a
n
o
n
m
y
_
l
o
g
s
(
c
o
s
t
=
6
.
8
1
.
.
2
0
.
9
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
5
2
)
-
R
e
c
h
e
c
k
Con
d
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
10
-
>
B
i
t
m
a
p
I
n
d
e
x
S
c
a
n
o
n
m
y
_
l
o
g
s
_
l
o
g
d
a
t
e
(
c
o
s
t
=
0
.
0
0
.
.
6
.
7
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
0
)
-
I
n
d
e
x
Co
nd
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
-
-
>
B
i
t
m
a
p
He
a
p
S
c
a
n
o
n
m
y
_
l
o
g
s
2
0
1
0
m
1
2
m
y
_
l
o
g
s
(
c
o
s
t
=
6
.
8
1
.
.
2
0
.
9
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
5
2
)
-
R
e
c
h
e
c
k
Con
d
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
54
4.4.
Pg_partman
-
-
>
B
i
t
m
a
p
I
n
d
e
x
S
c
a
n
o
n
m
y
_
l
o
g
s
2
0
1
0
m
1
2
_
l
o
g
d
a
t
e
(
c
o
s
t
=
0
.
0
0
.
.
6
.
7
3
r
o
w
s
=
3
3
0
w
i
d
t
h
=
0
)
15
I
n
d
e
x
Co
nd
:
(
l
o
g
d
a
t
e
>
’
2
0
1
0
-
1
2
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
)
-
(
1
0
r
o
w
s
)
Как
мы
видим,
теперь
запрос
работает
правильно
и
сканиру
ет
тольк
о
партиции,
что
подх
о
дят
под
у
словие
запроса.
Но
включать
constrain
t_exclusion
не
ж
елательно для баз, г
де нет партиционирования,
поск
ольку
команда
CHECK
бу
дет
проверятьс
я
на
всех
запросах,
даж
е
про-
стых,
а
значит
производительность
сильно
упадет
.
На
чиная
с
8.4
версии
P
ostgreSQL
constrain
t_exclusion
мо
жет
быть
«on»
,
«off»
и
«partition»
.
По
умолчанию
(и
рек
омендуетс
я)
ставить
constraint_exclusion
«partition»
,
ко-
торый
бу
дет
проверять
CHECK
только
на
партиционированых
таблицах.
4.4
Pg_partman
Поск
ольку
реализация
партиционирования
реализована
неполноценно
в
PostgreSQL
(для
управления
партициями
и
данными
в
них
прих
одитс
я
писать
функции,
триггеры
и
правила),
то
существует
расширение,
к
ото-
рое
автоматизирует
полностью
данный
процесс.
PG
Partition
Manager
,
он
ж
е pg_partman,
это
расширение
для создания
и
управления
партиция-
ми
и
партициями
партиций
(sub-partitoning)
в
P
ostgreSQL.
Поддер
живает
партицирование
по
времени
(time-based)
или
по
последованности
(serial-
based).
Для
партицирования по
диапазону
зна
чений (range)
существу
ет
от
дельное
расширение
Range
Partitioning
(range_partitioning)
.
Т
екущая реализация
по
ддер
живает
только INSER
T
операции,
к
ото-
рые перенаправляют данные в
нужную партицию.
UPD
A
TE
операции,
к
оторые
бу
дут
перемещать
данные
из
одной
партиции
в
другую,
не
по
д-
дер
живаются.
При
попытке
вставить
данные,
на
к
оторые
нет
партиции,
pg_partman
перемещает
их
в
«мастер»
(родительскую)
т
аблицу
.
Данный
вариант
предпочтительнее,
чем
создавать
автоматически
новые
партиции,
поск
ольку
это
мо
жет
привести
к
созданию
дес
ятков
или
сотен
ненужных
дочерних
таблиц из-за
ошибки
в
самих
данных.
Функция
chec
k_parent
позволяет
проверить
попадение
подобных
данных
в
родительскую
т
аб-
лицу
и
решить,
что
с
ними
требу
ется
делать
(у
далить
или
использовать
partition_data_time/partition_data_id
для
создания
и
переноса
этих
данных
в
партиции).
Данное
расширение
использу
ет
большинство
атрибутов
родительск
ой
т
аблицы
для
создания
партиций:
индексы,
внешние
ключи
(опционально),
tablespace,
constrain
ts,
privileges
и
o
wnership.
Под
так
ое
у
словие
попадают
OID
и
UNLOGGED
т
аблицы.
Партициями
партиций
(sub-partitoning)
поддер
живаются
разных
уров-
ней:
time->time,
id->id,
time->id
и
id->time.
Нет
лимитов
на
создание
та-
55
4.4.
Pg_partman
ких
партиций,
но
стоит
помнить,
что
большое
число
партиций
влияет
на
произво
дительность
ро
дительск
ой
т
аблицы.
Если
размер
партиций
ст
анет
слишк
ом
большим,
то
придется
увеличивать
max_lo
c
ks_p
er_transaction
па-
раметр
для
базы
данных
(64
по
умолчанию).
В
PostgreSQL
9.4
появилась
возмо
жность
создания
пользовательских
фоновых
ворк
еров
и
динамически
загружать
их
во
время
работы
базы.
Благо
даря
этому
в
pg_partman
есть
собственный
фоновый
ворк
ер,
задача
к
оторого запу
ск
ать
run_main
tenance
функцию к
аждый
заданный
проме-
жуток
времени.
Если
у
Вас
версия
PostgreSQL
ниж
е
9.4,
то
придется
вос-
пользоватьс
я
внешним
планировщиком
для
выполнения
данной
функции
(например
cron).
Зада
ча данной
функции -
проверять
и
автоматически
создавать
партиции
и
опционально
чистить
ст
арые.
Пример
использования
Для
на
чала
уст
ановим
данное
расширение:
Листинг
4.16
У
становк
а
Line
1
$
g
i
t
c
l
o
n
e
h
t
t
p
s
:
/
/
g
i
t
h
u
b
.
co
m
/
k
e
i
t
h
f
4
/
p
g
_
p
a
r
t
m
a
n
.
g
i
t
-
$
c
d
p
g
_
p
a
r
t
m
a
n
/
-
$
m
a
ke
-
$
s
u
d
o
m
a
ke
i
n
s
t
a
l
l
Если
не
требуетс
я
использовать
фоновый
воркер,
то
можно
собрать
без
него:
Листинг
4.17
У
становк
а
Line
1
$
s
u
d
o
mak
e
N
O
_
B
G
W
=
1
i
n
s
t
a
l
l
Для
работы
фонового
ворк
ера
нужно
загруж
ать
его
на
ст
арте
P
ostgreSQL.
Для
этого
потребуетс
я
добавить
настройки
в
p
ostgresql.conf:
Листинг
4.18
Настройки
воркера
Line
1
s
h
a
r
e
d
_
p
r
e
l
o
a
d
_
l
i
b
r
a
r
i
e
s
=
’
p
g
_
p
ar
t
m
a
n_
b
g
w
’
#
(
c
h
a
n
g
e
r
e
q
u
i
r
e
s
r
e
s
t
a
r
t
)
-
p
g
_
p
ar
t
m
a
n_
b
g
w
.
i
n
t
e
r
v
a
l
=
3
6
0
0
-
p
g
_
p
ar
t
m
a
n_
b
g
w
.
r
o
l
e
=
’
m
y
r
o
l
e
’
-
p
g
_
p
ar
t
m
a
n_
b
g
w
.
d
b
n
a
m
e
=
’
m
y
d
a
t
a
b
a
s
e
’
г
де:
∙
pg_partman_bgw.
dbname
—
база
д
анных,
в
к
оторой
бу
дет
выполнять-
с
я
run_maintenance
функция.
Если
нужно
ук
азать
больше
одной
базы,
то
они
ук
азываются
через
запятую.
Без
этого
параметра
воркер
не
бу
дет
работать;
56
4.4.
Pg_partman
∙
pg_partman_bgw.
in
terv
al
—
к
оличество
секунд
между
вызовами
run_main
tenance
функции.
По
умолчанию
3600
(1
час);
∙
pg_partman_bgw.
role
—
роль
для
запуск
а
run_maintenance
функции.
По
умолчанию
p
ostgres.
Разрешена
тольк
о
о
дна
роль;
∙
pg_partman_bgw.
analyze
—
запу
ск
ать
или
нет
ANAL
YZE
после
созда-
ния
партиций
на
ро
дительскую
таблицу
.
По
умолчанию
включено;
∙
pg_partman_bgw.
jobmon
—
разрешить
или
нет
использовать
pg_jobmon
расширение
для
мониторинг
а,
что
партицирование
работ
ает
без
проблем.
По
умолчанию
включено;
Далее
по
дключаемся
к
базе
данных
и
активируем
расширение:
Листинг
4.19
Настройка
расширения
Line
1
#
C
R
E
A
T
E
S
C
H
E
M
A
p
a
r
t
m
a
n
;
-
C
R
E
A
T
E
S
C
H
E
M
A
-
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
g
_
p
a
r
t
m
a
n
S
C
H
E
M
A
p
a
r
t
m
a
n
;
-
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
Т
еперь
мо
жно
приступать
к
использованию
расширения.
Создадим
и
заполним
т
аблицу
тестовыми
данными:
Листинг
4.20
Данные
Line
1
#
C
R
E
A
T
E
T
A
B
L
E
u
s
e
r
s
(
-
i
d
s
e
r
i
a
l
p
r
i
m
a
r
y
k
e
y
,
-
u
s
e
r
n
a
m
e
t
e
x
t
n
o
t
n
u
l
l
u
n
i
q
u
e
,
-
p
a
s
s
w
o
r
d
t
e
x
t
,
5
c
r
e
a
t
e
d
_
o
n
t
i
m
e
s
t
a
m
p
t
z
n
o
t
n
u
l
l
,
-
l
a
s
t
_
l
o
g
g
e
d
_
o
n
t
i
m
e
s
t
a
m
p
t
z
n
o
t
n
u
l
l
-
)
;
-
-
#
IN
SE
R
T
I
NT
O
u
s
e
r
s
(
u
s
e
r
n
a
m
e
,
p
a
s
s
w
o
r
d
,
c
r
e
a
t
e
d
_
o
n
,
l
a
s
t
_
l
o
g
g
e
d
_
o
n
)
10
S
E
L
E
C
T
-
md
5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
-
md
5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
-
now
(
)
-
’
1
y
e
a
r
s
’
:
:
i
n
t
e
r
v
a
l
*
r
a
n
d
o
m
(
)
,
-
now
(
)
-
’
1
y
e
a
r
s
’
:
:
i
n
t
e
r
v
a
l
*
r
a
n
d
o
m
(
)
15
F
R
O
M
-
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
1
,
1
0
0
0
0
)
;
Далее
активируем
расширение
для
поля
created_on
с
партицией
на
каж-
дый
го
д:
Листинг
4.21
Партицирование
57
4.4.
Pg_partman
Line
1
#
S
E
L
E
C
T
p
a
r
t
m
a
n
.
c
r
e
a
t
e
_
p
a
r
e
n
t
(
’
p
u
b
l
i
c
.
u
s
e
r
s
’
,
’
c
r
e
a
t
e
d
_
o
n
’
,
’
t
i
m
e
’
,
’
y
e
a
r
l
y
’
)
;
-
c
r
e
a
t
e
_
p
a
r
e
n
t
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
t
5
(
1
r
o
w
)
Ук
азывание
сх
емы
в
имени
таблицы
об
язательно,
даже
если
она
«public»
(первый
аргумент
функции).
Поск
ольку
родительск
ая
таблица
уже
была
заполнена
данными,
пере-
несем
данные
из
нее
в
партиции
через
partition_data_time
функцию:
Листинг
4.22
Перенос
данных
в
партиции
Line
1
#
S
E
L
E
C
T
p
a
r
t
m
a
n
.
c
h
e
c
k
_
p
a
r
e
n
t
(
)
;
-
c
h
e
c
k
_
p
a
r
e
n
t
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
(
p
u
b
l
i
c
.
u
s
e
r
s
,
1
0
0
0
0
)
5
(
1
r
o
w
)
-
-
#
S
E
L
E
C
T
p
a
r
t
m
a
n
.
p
a
r
t
i
t
i
o
n
_
d
a
t
a
_
t
i
m
e
(
’
p
u
b
l
i
c
.
u
s
e
r
s
’
,
1
0
0
0
)
;
-
p
a
r
t
i
t
i
o
n
_
d
a
t
a
_
t
i
m
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
10
1
0
0
0
0
-
(
1
r
o
w
)
-
-
#
S
E
L
E
C
T
p
a
r
t
m
a
n
.
c
h
e
c
k
_
p
a
r
e
n
t
(
)
;
-
c
h
e
c
k
_
p
a
r
e
n
t
15
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
(
0
r
o
w
s
)
-
-
#
S
E
L
E
C
T
*
F
R
O
M
O
N
L
Y
u
s
e
r
s
;
-
i
d
|
u
s
e
r
n
a
m
e
|
p
a
s
s
w
o
r
d
|
c
r
e
a
t
e
d
_
o
n
|
l
a
s
t
_
l
o
g
g
e
d
_
o
n
20
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
(
0
r
o
w
s
)
-
-
#
\
d
+
u
s
e
r
s
-
T
a
b
l
e
"
p
u
b
l
i
c
.
u
s
e
r
s
"
25
Co
l
u
m
n
|
T
y
p
e
|
M
o
d
i
f
i
e
r
s
|
S
t
o
r
a
g
e
|
S
t
a
t
s
t
a
r
g
e
t
|
D
e
s
c
r
i
p
t
i
o
n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
i
d
|
i
n
t
e
g
e
r
|
n
o
t
n
u
l
l
d
e
f
a
u
l
t
n
e
x
t
v
a
l
(
’
u
s
e
r
s
_
i
d
_
s
e
q
’
:
:
r
e
g
c
l
a
s
s
)
|
p
l
a
i
n
|
|
58
4.5.
Pgslice
-
u
s
e
r
n
a
m
e
|
t
e
x
t
|
n
o
t
n
u
l
l
|
e
x
t
e
n
d
e
d
|
|
-
p
a
s
s
w
o
r
d
|
t
e
x
t
|
|
e
x
t
e
n
d
e
d
|
|
30
c
r
e
a
t
e
d
_
o
n
|
t
i
m
e
s
t
a
m
p
w
i
t
h
t
i
m
e
z
o
n
e
|
n
o
t
n
u
l
l
|
p
l
a
i
n
|
|
-
l
a
s
t
_
l
o
g
g
e
d
_
o
n
|
t
i
m
e
s
t
a
m
p
w
i
t
h
t
i
m
e
z
o
n
e
|
n
o
t
n
u
l
l
|
p
l
a
i
n
|
|
-
I
n
d
e
x
e
s
:
-
"
u
s
e
r
s
_
p
k
e
y
"
P
R
I
M
A
R
Y
K
E
Y
,
b
t
r
e
e
(
i
d
)
-
"
u
s
e
r
s
_
u
s
e
r
n
a
m
e
_
k
e
y
"
U
N
I
Q
U
E
C
O
N
S
T
R
A
I
N
T
,
b
t
r
e
e
(
u
s
e
r
n
a
m
e
)
35
T
r
i
g
g
e
r
s
:
-
u
s
e
r
s
_
p
a
r
t
_
t
r
i
g
B
E
F
O
R
E
I
N
SE
RT
O
N
u
s
e
r
s
F
O
R
E
A
C
H
R
O
W
E
X
E
C
U
T
E
P
R
O
C
E
D
U
R
E
u
s
e
r
s
_
p
a
r
t
_
t
r
i
g
_
f
u
n
c
(
)
-
C
h
i
l
d
t
a
b
l
e
s
:
u
s
e
r
s
_
p
2
0
1
2
,
-
u
s
e
r
s
_
p
2
0
1
3
,
-
u
s
e
r
s
_
p
2
0
1
4
,
40
u
s
e
r
s
_
p
2
0
1
5
,
-
u
s
e
r
s
_
p
2
0
1
6
,
-
u
s
e
r
s
_
p
2
0
1
7
,
-
u
s
e
r
s
_
p
2
0
1
8
,
-
u
s
e
r
s
_
p
2
0
1
9
,
45
u
s
e
r
s
_
p
2
0
2
0
В
резу
ль
тате
данные
в
т
абли
це
users
содер
жатс
я
в
партициях
благодар
я
pg_partman.
Более
подробно
по
функционалу
расширения,
его
настройках
и
ограничениях
доступно
в
официальной
документ
ации
.
4.5
Pgslice
Pgslice
—
утилита
для
создания
и
управления
партициями
в
P
ostgreSQL.
Утилита
разбивает
на
«куски»
к
ак
новую,
так
и
существую-
щую
т
аблицу
с
данными
c
ну
левым
временем
простоя
(«zero
down
time»).
Утилит
а
написана
на
Ruby
,
поэтому
потребуетс
я
сна
чала
уст
ановить
его.
После
этого
уст
анавливаем
pgslice
через
rubygems
(многие
rub
y
разра-
ботчики
используют
bundler
для
лучшего
управления
зависимостями,
но
в
этой
г
лаве
это
не
рассматривается):
Листинг
4.23
У
становк
а
Line
1
$
gem
i
n
s
t
a
l
l
p
g
s
l
i
c
e
Создадим
и
заполним
т
аблицу
тестовыми
данными:
59
4.5.
Pgslice
Листинг
4.24
Данные
Line
1
#
C
R
E
A
T
E
T
A
B
L
E
u
s
e
r
s
(
-
i
d
s
e
r
i
a
l
p
r
i
m
a
r
y
k
e
y
,
-
u
s
e
r
n
a
m
e
t
e
x
t
n
o
t
n
u
l
l
u
n
i
q
u
e
,
-
p
a
s
s
w
o
r
d
t
e
x
t
,
5
c
r
e
a
t
e
d
_
o
n
t
i
m
e
s
t
a
m
p
t
z
n
o
t
n
u
l
l
,
-
l
a
s
t
_
l
o
g
g
e
d
_
o
n
t
i
m
e
s
t
a
m
p
t
z
n
o
t
n
u
l
l
-
)
;
-
-
#
IN
SE
R
T
I
NT
O
u
s
e
r
s
(
u
s
e
r
n
a
m
e
,
p
a
s
s
w
o
r
d
,
c
r
e
a
t
e
d
_
o
n
,
l
a
s
t
_
l
o
g
g
e
d
_
o
n
)
10
S
E
L
E
C
T
-
md
5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
-
md
5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
-
now
(
)
+
’
1
m
o
n
t
h
’
:
:
i
n
t
e
r
v
a
l
*
r
a
n
d
o
m
(
)
,
-
now
(
)
+
’
1
m
o
n
t
h
’
:
:
i
n
t
e
r
v
a
l
*
r
a
n
d
o
m
(
)
15
F
R
O
M
-
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
1
,
1
0
0
0
0
)
;
Настройки
подключения
к
базе
задаютс
я
через
PGSLICE_URL
пере-
менную
окруж
ения:
Листинг
4.25
PGSLICE_URL
Line
1
$
e
x
p
o
r
t
P
G
S
L
I
C
E
_
U
R
L
=
p
o
s
t
g
r
e
s
:
/
/
u
s
e
r
n
a
m
e
:
p
a
s
s
w
o
r
d
@
l
o
c
a
l
h
o
s
t
/
m
y
d
a
t
a
b
a
s
e
Через к
оманду
pgslice
prep
<
table
>
<
column
>
<p
erio
d>
создадим т
аб-
лицу
<
table
>_intermediate
(
users_in
termediate
в
примере)
с
соответствую-
щим
триггером
для
разбиения данных,
где
<
table
>
- это
название т
аб-
лицы
(
users
в
примере),
<
column
>
-
поле,
по
которому
бу
дут
создаватьс
я
партиции,
а
<p
erio
d>
-
период
данных
в
партициях
(мож
ет
быть
day
или
mon
th
).
Листинг
4.26
Pgslice
prep
Line
1
$
p
g
s
l
i
c
e
p
r
e
p
u
s
e
r
s
c
r
e
a
t
e
d
_
o
n
m
o
n
t
h
-
B
E
G
I
N
;
-
-
C
R
E
A
T
E
T
A
B
L
E
u
s
e
r
s
_
i
n
t
e
r
m
e
d
i
a
t
e
(
LIKE
u
s
e
r
s
I
N
C
L
U
D
I
N
G A
L
L
)
;
5
-
C
R
E
A
T
E
F
U
N
C
T
I
O
N
u
s
e
r
s
_
i
n
s
e
r
t
_
t
r
i
g
g
e
r
(
)
-
R
E
T
U
R
N
S
t
r
i
g
g
e
r
AS
$
$
-
B
E
G
I
N
-
RAI
SE E
X
C
E
P
T
I
O
N
’
C
r
e
a
t
e
p
a
r
t
i
t
i
o
n
s
f
i
r
s
t
.
’
;
10
E
N
D
;
60
4.5.
Pgslice
-
$
$
L
A
N
G
U
A
G
E
p
l
p
g
s
q
l
;
-
-
C
R
E
A
T
E
T
R
I
G
G
E
R
u
s
e
r
s
_
i
n
s
e
r
t
_
t
r
i
g
g
e
r
-
B
E
F
O
R
E I
NS
ER
T
O
N
u
s
e
r
s
_
i
n
t
e
r
m
e
d
i
a
t
e
15
F
O
R
E
A
C
H
R
O
W
E
X
E
C
U
T
E
P
R
O
C
E
D
U
R
E
u
s
e
r
s
_
i
n
s
e
r
t
_
t
r
i
g
g
e
r
(
)
;
-
-
C
O
M
M
E
N
T
O
N
T
R
I
G
G
E
R
u
s
e
r
s
_
i
n
s
e
r
t
_
t
r
i
g
g
e
r
O
N
u
s
e
r
s
_
i
n
t
e
r
m
e
d
i
a
t
e
i
s
’
c
o
l
u
m
n
:
c
r
e
a
t
e
d
_
o
n
,
p
e
r
i
o
d
:
mo
n
t
h
,
c
a
s
t
:
t
i
m
e
s
t
a
m
p
t
z
’
;
-
-
C
O
M
M
I
T
;
Т
еперь
мо
жно
добавить
партиции:
Листинг
4.27
Pgslice
add_partitions
Line
1
$
p
g
s
l
i
c
e
a
d
d
_
p
a
r
t
i
t
i
o
n
s
u
s
e
r
s
-
-
i
n
t
e
r
m
e
d
i
a
t
e
-
-
p
a
s
t
3
-
-
f
u
t
u
r
e
3
-
B
E
G
I
N
;
-
-
C
R
E
A
T
E
T
A
B
L
E
u
s
e
r
s
_
2
0
1
6
1
1
5
(C
H
E
C
K
(
c
r
e
a
t
e
d
_
o
n >
=
’
2
0
1
6
-
1
1
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
A
N
D
c
r
e
a
t
e
d
_
o
n
<
’
2
0
1
6
-
1
2
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
)
)
-
INHE
RITS
(
u
s
e
r
s
_
i
n
t
e
r
m
e
d
i
a
t
e
)
;
-
-
A
L
T
E
R
T
A
B
L
E
u
s
e
r
s
_
2
0
1
6
1
1
A
D
D
P
R
I
M
A
R
Y
K
E
Y
(
i
d
)
;
-
10
.
.
.
-
-
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
u
s
e
r
s
_
i
n
s
e
r
t
_
t
r
i
g
g
e
r
(
)
-
R
E
T
U
R
N
S
t
r
i
g
g
e
r
AS
$
$
-
B
E
G
I
N
15
I
F
(
N
E
W.
c
r
e
a
t
e
d
_
o
n >
=
’
2
0
1
7
-
0
2
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
A
N
D
N
E
W.
c
r
e
a
t
e
d
_
o
n
<
’
2
0
1
7
-
0
3
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
)
T
H
E
N
-
IN
SE
R
T
I
N
T
O
u
s
e
r
s
_
2
0
1
7
0
2
V
A
L
U
E
S
(
N
E
W.
*
)
;
-
EL
S
I
F
(
N
E
W.
c
r
e
a
t
e
d
_
o
n
>
=
’
2
0
1
7
-
0
3
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
A
N
D
N
E
W.
c
r
e
a
t
e
d
_
o
n
<
’
2
0
1
7
-
0
4
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
)
T
H
E
N
-
IN
SE
R
T
I
N
T
O
u
s
e
r
s
_
2
0
1
7
0
3
V
A
L
U
E
S
(
N
E
W.
*
)
;
-
EL
S
I
F
(
N
E
W.
c
r
e
a
t
e
d
_
o
n
>
=
’
2
0
1
7
-
0
4
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
A
N
D
N
E
W.
c
r
e
a
t
e
d
_
o
n
<
’
2
0
1
7
-
0
5
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
)
T
H
E
N
20
IN
SE
R
T
I
N
T
O
u
s
e
r
s
_
2
0
1
7
0
4
V
A
L
U
E
S
(
N
E
W.
*
)
;
-
EL
S
I
F
(
N
E
W.
c
r
e
a
t
e
d
_
o
n
>
=
’
2
0
1
7
-
0
5
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
A
N
D
N
E
W.
c
r
e
a
t
e
d
_
o
n
<
’
2
0
1
7
-
0
6
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
)
T
H
E
N
61
4.5.
Pgslice
-
IN
SE
R
T
I
N
T
O
u
s
e
r
s
_
2
0
1
7
0
5
V
A
L
U
E
S
(
N
E
W.
*
)
;
-
EL
S
I
F
(
N
E
W.
c
r
e
a
t
e
d
_
o
n
>
=
’
2
0
1
7
-
0
1
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
A
N
D
N
E
W.
c
r
e
a
t
e
d
_
o
n
<
’
2
0
1
7
-
0
2
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
)
T
H
E
N
-
IN
SE
R
T
I
N
T
O
u
s
e
r
s
_
2
0
1
7
0
1
V
A
L
U
E
S
(
N
E
W.
*
)
;
25
EL
S
I
F
(
N
E
W.
c
r
e
a
t
e
d
_
o
n
>
=
’
2
0
1
6
-
1
2
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
A
N
D
N
E
W.
c
r
e
a
t
e
d
_
o
n
<
’
2
0
1
7
-
0
1
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
)
T
H
E
N
-
IN
SE
R
T
I
N
T
O
u
s
e
r
s
_
2
0
1
6
1
2
V
A
L
U
E
S
(
N
E
W.
*
)
;
-
EL
S
I
F
(
N
E
W.
c
r
e
a
t
e
d
_
o
n
>
=
’
2
0
1
6
-
1
1
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
A
N
D
N
E
W.
c
r
e
a
t
e
d
_
o
n
<
’
2
0
1
6
-
1
2
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
)
T
H
E
N
-
IN
SE
R
T
I
N
T
O
u
s
e
r
s
_
2
0
1
6
1
1
V
A
L
U
E
S
(
N
E
W.
*
)
;
-
E
LS
E
30
R
AI
SE
E
X
C
E
P
T
I
O
N
’
D
a
t
e
o
u
t
o
f
r
a
n
g
e
.
E
n
s
u
r
e
p
a
r
t
i
t
i
o
n
s
a
r
e
c
r
e
a
t
e
d
.
’
;
-
E
N
D
I
F
;
-
R
E
T
U
R
N
N
U
L
L
;
-
E
N
D
;
-
$
$
L
A
N
G
U
A
G
E
p
l
p
g
s
q
l
;
35
-
C
O
M
M
I
T
;
Через
--
past
и
--
future
опции
ук
азывается
к
оличество
партиций.
Далее
мо
жно
переместить
данные
в
партиции:
Листинг
4.28
Pgslice
fill
Line
1
$
p
g
s
l
i
c
e
f
i
l
l
u
s
e
r
s
-
/
*
1
o
f
1
*
/
-
I
N
SE
RT I
NT
O
u
s
e
r
s
_
i
n
t
e
r
m
e
d
i
a
t
e
(
"
i
d
"
,
"
u
s
e
r
n
a
m
e
"
,
"
p
a
s
s
w
o
r
d
"
,
"
c
r
e
a
t
e
d
_
o
n
"
,
"
l
a
s
t
_
l
o
g
g
e
d
_
o
n
"
)
-
S
E
L
E
C
T
"
i
d
"
,
"
u
s
e
r
n
a
m
e
"
,
"
p
a
s
s
w
o
r
d
"
,
"
c
r
e
a
t
e
d
_
o
n
"
,
"
l
a
s
t
_
l
o
g
g
e
d
_
o
n
" F
R
O
M
u
s
e
r
s
5
W
H
E
R
E
i
d
>
0
A
N
D
i
d
<
=
1
0
0
0
0
A
N
D
c
r
e
a
t
e
d
_
o
n >
=
’
2
0
1
6
-
1
1
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
A
N
D
c
r
e
a
t
e
d
_
o
n
<
’
2
0
1
7
-
0
6
-
0
1
0
0
:
0
0
:
0
0
U
T
C
’
:
:
t
i
m
e
s
t
a
m
p
t
z
Через
--
batch-
size
и
--
sleep
опции
можно
управлять
скоростью
переноса
данных.
После
этого
мо
жно
переключиться
на
новую
таблицу
с
партициями:
Листинг
4.29
Pgslice
swap
Line
1
$
p
g
s
l
i
c
e
s
w
a
p
u
s
e
r
s
-
B
E
G
I
N
;
-
-
SE
T
L
O
C
A
L
l
o
c
k
_
t
i
m
e
o
u
t
=
’
5
s
’
;
62
4.5.
Pgslice
5
-
A
L
T
E
R
T
A
B
L
E
u
s
e
r
s
R
E
N
A
M
E
T
O
u
s
e
r
s
_
r
e
t
i
r
e
d
;
-
-
A
L
T
E
R
T
A
B
L
E
u
s
e
r
s
_
i
n
t
e
r
m
e
d
i
a
t
e
R
E
N
A
M
E
T
O
u
s
e
r
s
;
-
10
A
L
T
E
R
S
E
Q
U
E
N
C
E
u
s
e
r
s
_
i
d
_
s
e
q
O
W
N
E
D
B
Y
u
s
e
r
s
.
i
d
;
-
-
C
O
M
M
I
T
;
Если требу
ется, то мо
жно перенести часть
данных, что накопилась
между
переключением
т
аблиц:
Листинг
4.30
Pgslice
fill
Line
1
$
p
g
s
l
i
c
e
f
i
l
l
u
s
e
r
s
-
-
s
w
a
p
p
e
d
В
резу
ль
тате
таблица
users
бу
дет
работать
через
партиции:
Листинг
4.31
Резу
льт
ат
Line
1
$
p
s
q
l
-
c
"
E
X
P
L
A
I
N S
E
L
E
C
T
*
F
R
O
M
u
s
e
r
s
"
-
Q
U
E
R
Y
P
L
A
N
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
A
p
p
e
n
d
(
c
o
s
t
=
0
.
0
0
.
.
3
3
0
.
0
0
r
o
w
s
=
1
3
6
0
1
w
i
d
t
h
=
8
6
)
5
-
>
S
e
q
S
c
a
n
o
n
u
s
e
r
s
(
c
o
s
t
=
0
.
0
0
.
.
0
.
0
0
r
o
w
s
=1
w
i
d
t
h
=
8
4
)
-
-
>
S
e
q
S
c
a
n
o
n
u
s
e
r
s
_
2
0
1
6
1
1
(
c
o
s
t
=
0
.
0
0
.
.
1
7
.
2
0
r
o
w
s
=
7
2
0
w
i
d
t
h
=
8
4
)
-
-
>
S
e
q
S
c
a
n
o
n
u
s
e
r
s
_
2
0
1
6
1
2
(
c
o
s
t
=
0
.
0
0
.
.
1
7
.
2
0
r
o
w
s
=
7
2
0
w
i
d
t
h
=
8
4
)
-
-
>
S
e
q
S
c
a
n
o
n
u
s
e
r
s
_
2
0
1
7
0
1
(
c
o
s
t
=
0
.
0
0
.
.
1
7
.
2
0
r
o
w
s
=
7
2
0
w
i
d
t
h
=
8
4
)
-
-
>
S
e
q
S
c
a
n
o
n
u
s
e
r
s
_
2
0
1
7
0
2
(
c
o
s
t
=
0
.
0
0
.
.
1
6
6
.
4
8
r
o
w
s
=
6
8
4
8
w
i
d
t
h
=
8
6
)
10
-
>
S
e
q
S
c
a
n
o
n
u
s
e
r
s
_
2
0
1
7
0
3
(
c
o
s
t
=
0
.
0
0
.
.
7
7
.
5
2
r
o
w
s
=
3
1
5
2
w
i
d
t
h
=
8
6
)
-
-
>
S
e
q
S
c
a
n
o
n
u
s
e
r
s
_
2
0
1
7
0
4
(
c
o
s
t
=
0
.
0
0
.
.
1
7
.
2
0
r
o
w
s
=
7
2
0
w
i
d
t
h
=
8
4
)
-
-
>
S
e
q
S
c
a
n
o
n
u
s
e
r
s
_
2
0
1
7
0
5
(
c
o
s
t
=
0
.
0
0
.
.
1
7
.
2
0
r
o
w
s
=
7
2
0
w
i
d
t
h
=
8
4
)
-
(
9
r
o
w
s
)
Ст
арая
т
аблица
теперь
бу
дет
называться
<
table
>_retired
(
users_retired
в
примере).
Её
мо
жно
оставить
или
у
далить
из
базы.
Листинг
4.32
У
даление
старой
таблицы
Line
1
$
p
g_d
ump
-
c
-
F
c
-
t
u
s
e
r
s
_
r
e
t
i
r
e
d
$
P
G
S
L
I
C
E
_
U
R
L
>
u
s
e
r
s
_
r
e
t
i
r
e
d
.
du
mp
63
4.6.
Заключение
-
$
p
s
q
l
-
c
"
D
R
O
P
u
s
e
r
s
_
r
e
t
i
r
e
d
"
$
P
G
S
L
I
C
E
_
U
R
L
Далее
тольк
о
требуетс
я
следить
за
количеством
партиций.
Для
этого
к
оманду
pgslice
add_partitions
мо
жно
добавить
в
cron:
Листинг
4.33
Cron
Line
1
#
d
a
y
-
0
0
*
*
*
p
g
s
l
i
c
e
a
d
d
_
p
a
r
t
i
t
i
o
n
s
<
t
a
b
l
e
>
-
-
f
u
t
u
r
e
3
-
-
u
r
l
.
.
.
-
-
#
m
o
n
t
h
5
0
0
1
*
*
p
g
s
l
i
c
e
a
d
d
_
p
a
r
t
i
t
i
o
n
s
<
t
a
b
l
e
>
-
-
f
u
t
u
r
e
3
-
-
u
r
l
.
.
.
4.6
Заключение
Партиционирование
—
о
дна
из
самых
простых
и
менее
безболезненных
мето
дов
уменьшения
нагрузки
на
СУБД.
Именно
на
этот
вариант
стоит
посмотреть сперва, и
если он не
по
дхо
дит по к
аким либо причинам —
перех
одить
к
более
сложным.
64
5
Р
еплик
ация
Ког
да
решаете
проблему
,
ни
о
чем
не
беспокойтесь.
Вот
к
огда
вы
её
решите,
тогда
и
наступит
время
беспокоитьс
я
Ричар
д
Филлипс
Фейнман
5.1
Введение
Р
епликация
(англ.
replication)
—
мех
анизм
синхронизации
со
держимо-
го
неск
ольких
копий
объекта
(например,
содер
жимого
базы
данных).
Ре-
плик
ация
—
это
процесс,
по
д
к
оторым
понимаетс
я
копирование
данных
из
о
дного
источник
а
на
мно
жество
других
и
наоборот
.
При
репликации
из-
менения,
сделанные
в
о
дной
копии
объекта,
могут
быть
распространены
в
другие
к
опии.
Реплик
ация
мож
ет
быть
синхронной
или
асинхронной.
В
случае
синхронной
репликации,
если
данная
реплика
обновляетс
я,
все
другие
реплики
того
же
фрагмента
данных
т
акже
должны
быть
об-
новлены
в
о
дной
и
той
же
транзакции.
Логически
это
означает
,
что
су-
ществу
ет
лишь
одна
версия
данных.
В
большинстве
про
дуктов
синхрон-
ная
реплик
ация
реализу
ется
с
помощью
триггерных
процедур
(возможно,
скрытых
и
управляемых
системой).
Но
синхронная
репликация
имеет
тот
недост
аток,
что
она
создаёт
дополнительную
нагрузку
при
выполнении
всех
транзакций,
в
к
оторых
обновляютс
я
к
акие-либо
реплики
(кроме
то-
го,
могут
возник
ать
проблемы,
связанные
с
доступностью
данных).
В
случае
асинхронной
репликации
обновление
одной
реплики
распро-
страняетс
я
на
другие
спуст
я
некоторое
время,
а
не
в
той
же
транзакции.
Т
аким
образом,
при
асинхронной
репликации
вводитс
я
задержк
а,
или
вре-
мя
о
жидания,
в
течение
которого
отдельные
реплики
могут
быть
факти-
чески
неидентичными
(то
есть
определение
реплика
оказываетс
я
не со-
всем
подх
о
дящим,
поск
ольку
мы
не
имеем
дело
с
точными
и
своевременно
65
5.1.
Введение
созданными
копиями).
В
большинстве
про
дуктов
асинхронная
реплик
а-
ция
реализу
етс
я
посредством
чтения
журнала
транзакций
или
постоян-
ной
очереди
тех
обновлений,
к
оторые
по
длежат
распространению.
Пре-
имущество
асинхронной
репликации
состоит
в
том,
что
дополнительные
издер
жки
реплик
ации
не
связаны
с
транзакциями
обновлений,
к
оторые
могут
иметь
важное
зна
чение
для
функционирования
всего
предприятия
и
предъявлять
высокие
требования
к
производительности.
К
недостатк
ам
этой
с
хемы
относится
то,
что
данные
могут ок
азатьс
я несовместимыми
(то
есть
несовместимыми
с
точки
зрения
пользователя).
Иными
словами,
избыточность
мо
жет
проявлятьс
я
на
логическом
уровне,
а
это,
строго
го-
вор
я,
означает
,
что
термин
к
онтролируемая
избыточность
в
т
ак
ом
случае
не
применим.
Р
ассмотрим
кратко
проблему
сог
ласованности
(или,
ск
орее,
несог
ласо-
ванности).
Дело
в
том,
что
реплики
могут
становитьс
я
несовместимыми
в
резу
ль
тате
ситу
аций,
которые
тру
дно
(или
даж
е
невозможно)
избежать
и
последствия
которых
тру
дно
исправить.
В
частности,
конфликты
могут
возник
ать
по
поводу
того,
в
к
аком
пор
ядк
е
должны
применяться
обновле-
ния.
Например,
предположим,
что
в
резу
ль
тате
выполнения
транзакции
А
происх
одит
вст
авка
строки
в
реплику
X,
после
чего
транзакция
B
у
да-
ляет
эту
строку
,
а
т
акж
е
допустим,
что
Y
—
реплика
X.
Если
обновления
распространяютс
я
на
Y,
но
вводятс
я
в
реплику
Y
в
обратном
порядк
е
(на-
пример,
из-за
разных
задер
жек
при
переда
че),
то
транзакция
B
не
нах
о
дит
в
Y
строку
,
по
длежащую
у
далению,
и
не
выполняет
своё
действие,
после
чего
транзакция
А
вст
авляет
эту
строку
.
Суммарный
эффект
состоит
в
том,
что
реплик
а
Y
содер
жит
указанную
строку
,
а
реплика
X
—
нет
.
В
целом
задачи
у
странения
к
онфликтных
ситу
аций
и
обеспечения
со-
г
ласованности
реплик
являются
весьма
сло
жными.
Следу
ет
отметить,
что,
по
крайней
мере,
в
сообществе
пользователей
к
оммерческих
баз
данных
термин
репликация
стал
озна
чать
преимущественно
(или
даже
исключи-
тельно)
асинхронную
реплик
ацию.
Основное
различие
между
репликацией
и
управлением
копированием
заключаетс
я
в
следующем:
если
используетс
я
реплик
ация,
то
обновление
о
дной
реплики
в
к
онечном
счёте
распространяется
на
все
остальные
авто-
матически.
В
режиме
управления
копированием,
напротив,
не
существу-
ет
так
ого
автоматическ
ого
распространения
обновлений.
Копии
данных
создаютс
я
и
управляютс
я
с
помощью
пакетного
или
фонового
процесса,
к
оторый
отделён
во
времени
от
транзакций
обновления.
Управление
к
о-
пированием
в
общем
более
эффективно
по
сравнению
с
репликацией,
по-
ск
ольку
за
один
раз
могут
копироватьс
я
большие
объёмы
данных.
К
недо-
ст
аткам
мо
жн
о
отнести
то,
что
большую
часть
времени
к
опии
данных
не
идентичны
базовым
данным,
поэтому
пользователи
должны
учитывать,
к
огда
именно
были синхронизированы
эти данные.
Обычно управление
к
опированием
упрощаетс
я
благо
даря
тому
требованию,
чтобы
обновления
применялись
в
соответствии
со
с
х
емой
первичной
копии
того
или
иного
66
5.2.
Потоковая
репликация
(Streaming
Replication)
вида.
Для
репликации
PostgreSQL
существу
ет
нескольк
о
решений,
как
за-
крытых,
т
ак
и
свобо
дных.
Закрытые
системы
реплик
ации
не
бу
дут
рас-
сматриватьс
я
в
этой
книге.
Вот
список
свободных
решений:
∙
Slon
y-I
—
асинхронная
Master-Sla
v
e
реплик
ация,
по
ддер
жива-
ет
каск
ады(cascading)
и
отказоу
стойчивость(failo
v
er).
Slony-I
использу
ет
триггеры
PostgreSQL
для
привязки
к
событиям
INSER
T/DELETE/UPD
A
TE
и
хранимые
процедуры
для
вы-
полнения
действий;
∙
Pgpo
ol-I/I
I
—
это
замечательный
инструмент
для
PostgreSQL
(лучше
сразу
работ
ать
с
I
I
версией).
Позволяет
делать:
– реплик
ацию
(в
том
числе,
с
автоматическим
переключением
на
резервный
stand-b
y
сервер);
– online-бэк
ап;
– p
o
oling
коннектов;
– очередь
соединений;
– балансировку
SELECT-запросов
на
неск
олько
p
ostgresql-
серверов;
– разбиение
запросов
для
параллельного
выполнения
над
боль-
шими
объемами
данных;
∙
Bucardo
—
асинхронная
реплик
ация,
к
оторая
по
ддер
живает
Multi-
Master
и
Master-Sla
v
e
режимы,
а
такж
е
нескольк
о
видов
синхрони-
зации
и
обработки
к
онфликтов;
∙
Londiste
—
асинхронная
Master-Sla
v
e
реплик
ация.
Вх
о
дит
в
сост
ав
Skyto
ols
.
Проще
в
использовании,
чем
Slony-I;
∙
Mammoth
Replicator
—
асинхронная
Multi-Master
репликация;
∙
BDR
(Bi-Directional
Replication)
—
асинхронная
Multi-Master
репли-
к
ация;
∙
Pglogical
—
асинхронная
Master-Slav
e
реплик
ация;
Это, к
онечно, не
весь список
свобо
дных систем
для реплик
ации, но
даж
е
из
этого
есть
что
выбрать
для
PostgreSQL.
5.2
Поток
овая
реплик
ация
(Streaming
Replication)
Поток
овая
реплик
ация
(Streaming
Replication,
SR)
дает
возможность
непрерывно
отправлять
и
применять
W
AL
(W
rite-Ahead
Log)
записи
на
резервные
сервера
для
создания
точной
копии
текущего.
Данная
функ-
циональность
по
явилась
у
P
ostgreSQL
на
чиная
с
9
версии.
Этот
тип
ре-
плик
ации простой, надежный и, веро
ятней всего, бу
дет использоватьс
я
в
ка
честве
стандартной
реплик
ации
в
большинстве
высоконагруж
енных
прило
жений,
что
используют
PostgreSQL.
От
личительными
особенностями
решения
являются:
67
5.2.
Потоковая
репликация
(Streaming
Replication)
∙
реплик
ация
всего
инст
анса
PostgreSQL;
∙
асинхронный
или
синхронный
механизм
реплика
ции;
∙
простот
а
у
становки;
∙
мастер
база
данных
мо
жет
обслуживать
огромное
количество
слей-
вов
из-за
минимальной
нагрузки;
К
недост
аткам
можно
отнести:
∙
невозмо
жность
реплицировать
тольк
о
определенную
базу
данных
из
всех
на
P
ostgreSQL
инстансе;
У
становк
а
Для
начала
нам
потребу
ется
P
ostgreSQL
не
ниже
9
версии.
Все
работы,
к
ак
полагаетс
я,
бу
дут
прово
дится
на
Linux.
Настройк
а
Обозна
чим
мастер
сервер
как
masterdb(192.168.0.10)
и
слейв
как
slav
edb
(192.168.0.20)
.
Предварительная
настройк
а
Для
начала
позволим
определенному
пользователю
без
пароля
хо
дить
по
ssh.
Пу
сть
это
бу
дет
p
ostgres
юзер.
Если
же
нет
,
то
создаем
набором
к
оманд:
Листинг
5.1
Создаем
пользователя
userssh
Line
1
$
s
u
d
o
g
r
o
u
p
a
d
d
u
s
e
r
s
s
h
-
$
s
u
d
o
u
s
e
r
a
d
d
-m
-
g
u
s
e
r
s
s
h
-
d
/
ho
me
/
u
s
e
r
s
s
h
-
s
/
b
i
n
/
b
a
s
h
\
-
-
c
"
u
s
e
r
s
s
h
a
l
l
o
w
"
u
s
e
r
s
s
h
Дальше
выполняем
команды
от
имени
пользователя
(в
данном
случае
p
ostgres
):
Листинг
5.2
Логинимся
под
пользователем
p
ostgres
Line
1
$
s
u
p
o
s
t
g
r
e
s
Г
енериру
ем RSA-ключ для обеспечения а
утентифик
ации в у
словиях
отсутствия
возмо
жности
использовать
пароль:
Листинг
5.3
Г
енерируем
RSA-ключ
Line
1
$
s
s
h
-
k
e
y
g
e
n
-
t
r
s
a
-
P
"
"
-
G
e
n
e
r
a
t
i
n
g
p
u
b
l
i
c
/
p
r
i
v
a
t
e
r
s
a
k
e
y
p
a
i
r
.
68
5.2.
Потоковая
репликация
(Streaming
Replication)
-
E
n
t
e
r
f
i
l
e
i
n
w
h
i
c
h
t
o
s
a
v
e
t
h
e
k
e
y
(
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
.
s
s
h
/
i
d
_
r
s
a
)
:
-
C
r
e
a
t
e
d
d
i
r
e
c
t
o
r
y
’
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
.
s
s
h
’
.
5
Y
o
u
r
i
d
e
n
t
i
f
i
c
a
t
i
o
n
h
a
s
b
e
e
n
s
a
v
e
d
i
n
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
.
s
s
h
/
i
d
_
r
s
a
.
-
Y
o
u
r
p
u
b
l
i
c
k
e
y
h
a
s
b
e
e
n
s
a
v
e
d
i
n
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
.
s
s
h
/
i
d
_
r
s
a
.
p
u
b
.
-
T
h
e
k
e
y
f
i
n
g
e
r
p
r
i
n
t
i
s
:
-
1
6
:
0
8
:
2
7
:
9
7
:
2
1
:
3
9
:
b
5
:
7
b
:
8
6
:
e
1
:
4
6
:
9
7
:
b
f
:
1
2
:
3
d
:
7
6
p
o
s
t
g
r
e
s
@
l
o
c
a
l
h
o
s
t
И
добавляем
его
в
список
авторизованных
ключей:
Листинг
5.4
Добавляем
его
в
список
авторизованных
ключей
Line
1
$
c
a
t
$
H
O
M
E
/
.
s
s
h
/
i
d
_
r
s
a
.
p
u
b >
>
$
H
O
M
E
/
.
s
s
h
/
a
u
t
h
o
r
i
z
e
d
_
k
e
y
s
Проверить
работоспособность
соединения
мо
жно
просто
написав:
Листинг
5.5
Пробуем
зайти
на
ssh
без
пароля
Line
1
$
s
s
h
l
o
c
a
l
h
o
s
t
Не
забываем
предварительно
инициализировать
sshd
:
Листинг
5.6
Запуск
sshd
Line
1
$
$
/
e
t
c
/
i
n
i
t
.
d
/
s
s
h
d
s
t
a
r
t
После
успешно
проделанной
операции
ск
опируйте
$HOME/.ssh
на
sla
vedb
.
Т
еперь
мы
должны
иметь
возможность
без
пароля
захо
дить
с
ма-
стера
на
слейв
и
со
слейва
на
мастер
через
ssh.
Т
акж
е
отредактиру
ем
pg_hba.conf
на
мастере
и
слейве,
разрешив
им
друг
к
другу
доступ
без
пароля
(тут
добавляетс
я
роль
replication
):
Листинг
5.7
Мастер
pg_hba.conf
Line
1
h
o
s
t
r
e
p
l
i
c
a
t
i
o
n
a
l
l
1
9
2
.
1
6
8
.
0
.
2
0
/
3
2
t
r
u
s
t
Листинг
5.8
Слейв
pg_hba.conf
Line
1
h
o
s
t
r
e
p
l
i
c
a
t
i
o
n
a
l
l
1
9
2
.
1
6
8
.
0
.
1
0
/
3
2
t
r
u
s
t
Не
забываем
после
этого
перегрузить
p
ostgresql
на
обоих
серверах.
Настройк
а
мастера
Для
на
чала
настроим
masterdb.
У
ст
ановим
параметры
в
p
ostgresql
.
conf
для
реплик
ации:
69
5.2.
Потоковая
репликация
(Streaming
Replication)
Листинг
5.9
Настройка
мастера
Line
1
#
To
e
n
a
b
l
e
r
e
a
d
-
o
n
l
y
q
u
e
r
i
e
s
o
n
a
s
t
a
n
d
b
y
s
e
r
v
e
r
,
w
a
l
_
l
e
v
e
l
m
u
s
t
b
e
s
e
t
t
o
-
#
"
h
o
t
_
s
t
a
n
d
b
y
"
.
B
u
t
y
o
u
c
a
n
c
h
o
o
s
e
"
a
r
c
h
i
v
e
"
i
f
y
o
u
n
e
v
e
r
c
o
n
n
e
c
t
t
o
t
h
e
-
#
s
e
r
v
e
r
i
n
s
t
a
n
d
b
y
mod
e
.
-
w
a
l
_
l
e
v
e
l
=
h
o
t
_
s
t
a
n
d
b
y
5
-
#
S
e
t
t
h
e
m
ax
im
um
n
u
m
b
e
r
o
f
c
o
n
c
u
r
r
e
n
t
c
o
n
n
e
c
t
i
o
n
s
f
r
o
m
t
h
e
s
t
a
n
d
b
y
s
e
r
v
e
r
s
.
-
m
a
x
_
w
a
l
_
s
e
n
d
e
r
s
=
5
-
-
# To
p
r
e
v
e
n
t
t
h
e
p
r
i
m
a
r
y
s
e
r
v
e
r
f
r
o
m
r
e
m
o
v
i
n
g
t
h
e
W
A
L
s
e
g
m
e
n
t
s
r
e
q
u
i
r
e
d
f
o
r
10
#
t
h
e
s
t
a
n
d
b
y
s
e
r
v
e
r
b
e
f
o
r
e
s
h
i
p
p
i
n
g
t
h
e
m
,
s
e
t
t
h
e
mi
nimum
n
u
m
b
e
r
o
f
s
e
g
m
e
n
t
s
-
#
r
e
t
a
i
n
e
d
i
n
t
h
e
p
g
_
x
l
o
g
d
i
r
e
c
t
o
r
y
.
A
t
l
e
a
s
t
w
a
l
_
k
e
e
p
_
s
e
g
m
e
n
t
s
s
h
o
u
l
d
b
e
-
#
l
a
r
g
e
r
t
h
a
n
t
h
e
n
u
m
b
e
r
o
f
s
e
g
m
e
n
t
s
g
e
n
e
r
a
t
e
d
b
e
t
w
e
e
n
t
h
e
b
e
g
i
n
n
i
n
g
o
f
-
#
o
n
l
i
n
e
-
b
a
c
k
u
p
a
n
d
t
h
e
s
t
a
r
t
u
p
o
f
s
t
r
e
a
m
i
n
g
r
e
p
l
i
c
a
t
i
o
n
.
I
f
y
o
u
e
n
a
b
l
e
W
A
L
-
#
a
r
c
h
i
v
i
n
g
t
o
a
n
a
r
c
h
i
v
e
d
i
r
e
c
t
o
r
y
a
c
c
e
s
s
i
b
l
e
f
r
o
m
t
h
e
s
t
a
n
d
b
y
,
t
h
i
s
ma
y
15
#
n
o
t
b
e
n
e
c
e
s
s
a
r
y
.
-
w
a
l
_
k
e
e
p
_
s
e
g
m
e
n
t
s
=
3
2
-
-
#
E
n
a
b
l
e
W
A
L
a
r
c
h
i
v
i
n
g
o
n
t
h
e
p
r
i
m
a
r
y
t
o
a
n
a
r
c
h
i
v
e
d
i
r
e
c
t
o
r
y
a
c
c
e
s
s
i
b
l
e
f
r
o
m
-
#
t
h
e
s
t
a
n
d
b
y
.
I
f
w
a
l
_
k
e
e
p
_
s
e
g
m
e
n
t
s
i
s
a
h
i
g
h
e
n
o
u
g
h
n
u
m
b
e
r
t
o
r
e
t
a
i
n
t
h
e
W
A
L
20
#
s
e
g
m
e
n
t
s
r
e
q
u
i
r
e
d
f
o
r
t
h
e
s
t
a
n
d
b
y
s
e
r
v
e
r
,
t
h
i
s
ma
y
n
o
t
b
e
n
e
c
e
s
s
a
r
y
.
-
a
r
c
h
i
v
e
_
m
o
d
e
=
o
n
-
a
r
c
h
i
v
e
_
c
o
m
m
a
n
d
=
’
c
p
%
p
/
p
a
t
h
_
t
o
/
a
r
c
h
i
v
e
/
%
f
’
Давайте
по
пор
ядку:
∙
w
al_lev
el
=
hot_standb
y
—
сервер
на
чнет
писать
в
W
AL
логи
т
ак
ж
е
к
ак и
при режиме
«arc
hiv
e»
, добавляя
информацию, необ
х
одимую
для
восстановления
транзакции
(можно
т
акж
е
поставить
arc
hiv
e
,
но
тог
да
сервер
не
мож
ет
быть
слейвом
при
необх
о
димости);
∙
max_w
al_senders
=
5
—
мак
симальное
к
оличество
слейвов;
∙
w
al_k
eep_segments
=
32
—
минимальное
к
оличество файлов
c W
AL
сегмент
ами
в
pg_xlog
директории;
70
5.2.
Потоковая
репликация
(Streaming
Replication)
∙
arc
hiv
e_mo
de
=
on
—
позволяем
сохранять
W
AL
сегменты
в
ук
азанное
переменной
arc
hiv
e_command
хранилище.
В
данном
случае
в
дирек-
торию
/path/to/arc
hive/
;
По
умолчанию
реплик
ация
асинхронная.
В
версии
9.1
добавили
пара-
метр
synchronous_standb
y_names
,
который
включает
синхронную
реплик
а-
цию.
В
данные
параметр
передается
application_name
,
который
использу-
етс
я
на
слейвах
в
recov
ery
.
conf
:
Листинг
5.10
recov
ery
.conf
для
синхронной
репликации
на
слейве
Line
1
r
e
s
t
o
r
e
_
c
o
m
m
a
n
d
=
’
c
p
/
mnt
/
s
e
r
v
e
r
/
a
r
c
h
i
v
e
d
i
r
/
%
f
%
p
’
#
e
.
g
.
’
c
p
/
mn
t
/
s
e
r
v
e
r
/
a
r
c
h
i
v
e
d
i
r
/
%
f
%
p
’
-
s
t
a
n
d
b
y
_
m
o
d
e
=
o
n
-
p
r
i
m
a
r
y
_
c
o
n
n
i
n
f
o
=
’
h
o
s
t=m
a
s
t
e
r
d
b
p
o
r
t
=
5
9
1
2
1
u
s
e
r=
r
e
p
l
i
c
a
t
i
o
n
p
a
s
s
w
o
r
d=
r
e
p
l
i
c
a
t
i
o
n
a
p
p
l
i
c
a
t
i
o
n
_
n
a
m
e=
n
e
w
c
l
u
s
t
e
r
’
#
e
.
g
.
’
h
o
s
t
=
l
o
c
a
l
h
o
s
t
p
o
r
t
=
5
4
3
2
’
-
t
r
i
g
g
e
r
_
f
i
l
e
=
’
/
t
mp
/
t
r
i
g
_
f
_
n
e
w
c
l
u
s
t
e
r
’
После
изменения
параметров
перегружаем
P
ostgreSQL
сервер.
Т
еперь
перейдем
к
sla
vedb
.
Настройк
а
слейва
Для
начала
нам
потребу
ется
создать
на
slav
edb
точную
копию
masterdb
.
Перенесем
данные
с
помощью
«Онлайн
бэк
апа»
.
Переместимс
я
на
masterdb
сервер
и
выполним
в
консоли:
Листинг
5.11
Выполняем
на
мастере
Line
1
$
p
s
q
l
-
c
"S
E
L
E
C
T
p
g
_
s
t
a
r
t
_
b
a
c
k
u
p
(
’
l
a
b
e
l
’
,
t
r
u
e
)
"
Т
еперь
нам
нужно
перенести
данные
с
мастера
на
слейв.
Выполняем
на
мастере:
Листинг
5.12
Выполняем
на
мастере
Line
1
$
r
s
y
n
c
-
C
-
a
-
-
d
e
l
e
t
e
-
e
s
s
h
-
-
e
x
c
l
u
d
e
p
o
s
t
g
r
e
s
q
l
.
c
o
n
f
-
-
e
x
c
l
u
d
e
p
o
s
t
m
a
s
t
e
r
.
p
i
d
\
-
-
-
e
x
c
l
u
d
e
p
o
s
t
m
a
s
t
e
r
.
o
p
t
s
-
-
e
x
c
l
u
d
e
p
g
_
l
o
g
-
-
e
x
c
l
u
d
e
p
g
_
x
l
o
g
\
-
-
-
e
x
c
l
u
d
e
r
e
c
o
v
e
r
y
.
c
o
n
f
m
a
s
t
e
r
_
d
b
_
d
a
t
a
d
i
r
/
s
l
a
v
e
d
b
_
h
o
s
t
:
s
l
a
v
e
_
d
b
_
d
a
t
a
d
i
r
/
г
де
∙
master_db_datad
ir
—
директория
с
p
ostgresql
данными
на
masterdb;
∙
sla
v
e_db_datadir
—
директория
с
p
ostgresql
данными
на
sla
vedb;
71
5.2.
Потоковая
репликация
(Streaming
Replication)
∙
sla
v
edb_host
—
хост
slav
edb(в
нашем
случае
-
192.168.1.20);
После
к
опирования
данных
с
мастера
на
слейв,
остановим
онлайн
бэк
ап.
Выполняем
на
мастере:
Листинг
5.13
Выполняем
на
мастере
Line
1
$
p
s
q
l
-
c
"S
E
L
E
C
T
p
g
_
s
t
o
p
_
b
a
c
k
u
p
(
)
"
Для
версии
PostgreSQL
9.1+
можно
воспользоватьс
я
командой
pg_basebac
kup
(копиру
ет
базу
на
slav
edb
по
добным
образом):
Листинг
5.14
Выполняем
на
слейве
Line
1
$
p
g
_
b
a
s
e
b
a
c
k
u
p
-
R
-D
/
s
r
v
/
p
g
s
q
l
/
s
t
a
n
d
b
y
-
-
h
o
s
t
=
1
9
2
.
1
6
8
.
0
.
1
0
-
-
p
o
r
t
=
5
4
3
2
У
ст
анавливаем
такие
же
данные
в
конфиге
p
ostgresql
.
conf
,
что
и
у
ма-
стера
(чтобы
при
падении
мастера
слейв
мог
его
заменить).
Т
ак
же
уст
а-
новим
дополнительный
параметр:
Листинг
5.15
Конфиг
слейва
Line
1
h
o
t
_
s
t
a
n
d
b
y
=
o
n
Внимание!
Если
на
мастере
пост
авили
wal_lev
el
=
archiv
e
,
тог
да
пара-
метр
ост
авляем
по
умолчанию
(
hot_standby
=
off
).
Далее
на
slav
edb
в
директории
с
данными
PostgreSQL
создадим
файл
reco
very
.
conf
с
таким
содер
жимым:
Листинг
5.16
Конфиг
recov
ery
.conf
Line
1
#
S
p
e
c
i
f
i
e
s
w
h
e
t
h
e
r
t
o
s
t
a
r
t
t
h
e
s
e
r
v
e
r
a
s
a
s
t
a
n
d
b
y
.
I
n
s
t
r
e
a
m
i
n
g
r
e
p
l
i
c
a
t
i
o
n
,
-
#
t
h
i
s
p
a
r
a
m
e
t
e
r
m
u
s
t
t
o
b
e
s
e
t
t
o
o
n
.
-
s
t
a
n
d
b
y
_
m
o
d
e
=
’
o
n
’
-
5
#
S
p
e
c
i
f
i
e
s
a
c
o
n
n
e
c
t
i
o
n
s
t
r
i
n
g
w
h
i
c
h
i
s
u
s
e
d
f
o
r
t
h
e
s
t
a
n
d
b
y
s
e
r
v
e
r
t
o
c
o
n
n
e
c
t
-
#
w
i
t
h
t
h
e
p
r
i
m
a
r
y
.
-
p
r
i
m
a
r
y
_
c
o
n
n
i
n
f
o
=
’
h
o
s
t
=
1
9
2
.
1
6
8
.
0
.
1
0
p
o
r
t
=
5
4
3
2
u
s
e
r
=
p
o
s
t
g
r
e
s
’
-
-
#
S
p
e
c
i
f
i
e
s
a
t
r
i
g
g
e
r
f
i
l
e
w
h
o
s
e
p
r
e
s
e
n
c
e
s
h
o
u
l
d
c
a
u
s
e
s
t
r
e
a
m
i
n
g
r
e
p
l
i
c
a
t
i
o
n
t
o
10
#
e
n
d
(
i
.
e
.
,
f
a
i
l
o
v
e
r
)
.
-
t
r
i
g
g
e
r
_
f
i
l
e
=
’
/
p
a
t
h
_
t
o
/
t
r
i
g
g
e
r
’
-
72
5.2.
Потоковая
репликация
(Streaming
Replication)
-
#
S
p
e
c
i
f
i
e
s
a
command
t
o
l
o
a
d
a
r
c
h
i
v
e
s
e
g
m
e
n
t
s
f
r
o
m
t
h
e
W
A
L
a
r
c
h
i
v
e
.
I
f
-
#
w
a
l
_
k
e
e
p
_
s
e
g
m
e
n
t
s
i
s
a
h
i
g
h
e
n
o
u
g
h
n
u
m
b
e
r
t
o
r
e
t
a
i
n
t
h
e
W
A
L
s
e
g
m
e
n
t
s
15
#
r
e
q
u
i
r
e
d
f
o
r
t
h
e
s
t
a
n
d
b
y
s
e
r
v
e
r
,
t
h
i
s
ma
y
n
o
t
b
e
n
e
c
e
s
s
a
r
y
.
B
u
t
-
#
a
l
a
r
g
e
w
o
r
k
l
o
a
d
c
a
n
c
a
u
s
e
s
e
g
m
e
n
t
s
t
o
b
e
r
e
c
y
c
l
e
d
b
e
f
o
r
e
t
h
e
s
t
a
n
d
b
y
-
#
i
s
f
u
l
l
y
s
y
n
c
h
r
o
n
i
z
e
d
,
r
e
q
u
i
r
i
n
g
y
o
u
t
o
s
t
a
r
t
a
g
a
i
n
f
r
o
m
a
ne
w
b
a
s
e
b
a
c
k
u
p
.
-
r
e
s
t
o
r
e
_
c
o
m
m
a
n
d
=
’
s
c
p
m
a
s
t
e
r
d
b
_
h
o
s
t
:
/
p
a
t
h
_
t
o
/
a
r
c
h
i
v
e
/
%
f
"
%p
"
’
г
де
∙
standb
y_mo
de=’on’
—
ук
азываем
серверу
работать
в
режиме
слейв;
∙
primary_connin
fo
—
настройки
соединения
слейва
с
мастером;
∙
trigger_file
—
указываем
триггер
файл,
при
наличии
к
оторого
бу
дет
ост
ановлена
репликация;
∙
restore_command
—
команда,
которой
бу
дут
восстанавливатьс
я
W
AL
логи.
В
нашем
случае
через
scp
копиру
ем
с
masterdb
(
masterdb_host
-
х
ост
masterdb);
Т
еперь
мо
жем
запустить
PostgreSQL
на
slav
edb
.
Т
естирование
реплик
ации
В
резу
ль
тате
мож
ем
посмотреть
отставание
слейвов
от
мастера
с
помо-
щью
т
аких
команд:
Листинг
5.17
Т
естирование
репликации
Line
1
$
p
s
q
l
-
c
"S
E
L
E
C
T
p
g
_
c
u
r
r
e
n
t
_
x
l
o
g
_
l
o
c
a
t
i
o
n
(
)
"
-
h
1
9
2
.
1
6
8
.
0
.
1
0
(
m
a
s
t
e
r
d
b
)
-
p
g
_
c
u
r
r
e
n
t
_
x
l
o
g
_
l
o
c
a
t
i
o
n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
0
/
2
0
0
0
0
0
0
5
(
1
r
o
w
)
-
-
$
p
s
q
l
-
c
"
s
e
l
e
c
t
p
g
_
l
a
s
t
_
x
l
o
g
_
r
e
c
e
i
v
e
_
l
o
c
a
t
i
o
n
(
)
"
-
h
1
9
2
.
1
6
8
.
0
.
2
0
(
s
l
a
v
e
d
b
)
-
p
g
_
l
a
s
t
_
x
l
o
g
_
r
e
c
e
i
v
e
_
l
o
c
a
t
i
o
n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
10
0
/
2
0
0
0
0
0
0
-
(
1
r
o
w
)
-
-
$
p
s
q
l
-
c
"
s
e
l
e
c
t
p
g
_
l
a
s
t
_
x
l
o
g
_
r
e
p
l
a
y
_
l
o
c
a
t
i
o
n
(
)
"
-
h
1
9
2
.
1
6
8
.
0
.
2
0
(
s
l
a
v
e
d
b
)
73
5.2.
Потоковая
репликация
(Streaming
Replication)
-
p
g
_
l
a
s
t
_
x
l
o
g
_
r
e
p
l
a
y
_
l
o
c
a
t
i
o
n
15
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
0
/
2
0
0
0
0
0
0
-
(
1
r
o
w
)
На
чиная
с
версии
9.1
добавили
дополнительные
view
для
просмотра
состо
яния
репликации.
Т
еперь
master
знает
все
состояния
slav
es:
Листинг
5.18
Состояние
слейвов
Line
1
#
S
E
L
E
C
T
*
f
r
o
m
p
g
_
s
t
a
t
_
r
e
p
l
i
c
a
t
i
o
n
;
-
p
r
o
c
p
i
d
|
u
s
e
s
y
s
i
d
|
u
s
e
n
a
m
e
|
a
p
p
l
i
c
a
t
i
o
n
_
n
a
m
e
|
c
l
i
e
n
t
_
a
d
d
r
|
c
l
i
e
n
t
_
h
o
s
t
n
a
m
e
|
c
l
i
e
n
t
_
p
o
r
t
|
b
a
c
k
e
n
d
_
s
t
a
r
t
|
s
t
a
t
e
|
s
e
n
t
_
l
o
c
a
t
i
o
n
|
w
r
i
t
e
_
l
o
c
a
t
i
o
n
|
f
l
u
s
h
_
l
o
c
a
t
i
o
n
|
r
e
p
l
a
y
_
l
o
c
a
t
i
o
n
|
s
y
n
c
_
p
r
i
o
r
i
t
y
|
s
y
n
c
_
s
t
a
t
e
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
1
7
1
3
5
|
1
6
6
7
1
|
r
e
p
l
i
c
a
t
i
o
n
|
n
e
w
c
l
u
s
t
e
r
|
1
2
7
.
0
.
0
.
1
|
|
4
3
7
4
5
|
2
0
1
1
-
0
5
-
2
2
1
8
:
1
3
:
0
4
.
1
9
2
8
3
+
0
2
|
s
t
r
e
a
m
i
n
g
|
1
/
3
0
0
0
8
7
5
0
|
1
/
3
0
0
0
8
7
5
0
|
1
/
3
0
0
0
8
7
5
0
|
1
/
3
0
0
0
8
7
5
0
|
1
|
s
y
n
c
Т
акж
е
с
версии
9.1
добавили
view
pg_stat_database_conflicts
,
с
помо-
щью
которой
на
слейв
базах
мо
жно
просмотреть
скольк
о
запросов
было
отменено
и
по
к
аким
причинам:
Листинг
5.19
Состояние
слейва
Line
1
#
S
E
L
E
C
T
*
f
r
o
m
p
g
_
s
t
a
t
_
d
a
t
a
b
a
s
e
_
c
o
n
f
l
i
c
t
s
;
-
d
a
t
i
d
|
d
a
t
n
a
m
e
|
c
o
n
f
l
_
t
a
b
l
e
s
p
a
c
e
|
c
o
n
f
l
_
l
o
c
k
|
c
o
n
f
l
_
s
n
a
p
s
h
o
t
|
c
o
n
f
l
_
b
u
f
f
e
r
p
i
n
|
c
o
n
f
l
_
d
e
a
d
l
o
c
k
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1
|
t
e
m
p
l
a
t
e
1
|
0
|
0
|
0
|
0
|
0
5
1
1
9
7
9
|
t
e
m
p
l
a
t
e
0
|
0
|
0
|
0
|
0
|
0
-
1
1
9
8
7
|
p
o
s
t
g
r
e
s
|
0
|
0
|
0
|
0
|
0
-
1
6
3
8
4
|
m
a
r
c
|
0
|
0
|
1
|
0
|
0
Еще
проверить
работу
реплик
ации
можно
с
помощью
утилиты
ps
:
74
5.2.
Потоковая
репликация
(Streaming
Replication)
Листинг
5.20
Т
естирование
репликации
Line
1
[
m
a
s
t
e
r
d
b
]
$
p
s
-
e
f
|
g
r
e
p
s
e
n
d
e
r
-
p
o
s
t
g
r
e
s
6
8
7
9
6
8
3
1
0
1
0
:
3
1
?
0
0
:
0
0
:
0
0
p
o
s
t
g
r
e
s
:
w
a
l
s
e
n
d
e
r
p
r
o
c
e
s
s
p
o
s
t
g
r
e
s
1
2
7
.
0
.
0
.
1
(
4
4
6
6
3
)
s
t
r
e
a
m
i
n
g
0
/
2
0
0
0
0
0
0
-
-
[
s
l
a
v
e
d
b
]
$
p
s
-
e
f
|
g
r
e
p
r
e
c
e
i
v
e
r
5
p
o
s
t
g
r
e
s
6
8
7
8
6
8
7
2
1
1
0
:
3
1
?
0
0
:
0
0
:
0
1
p
o
s
t
g
r
e
s
:
w
a
l
r
e
c
e
i
v
e
r
p
r
o
c
e
s
s
s
t
r
e
a
m
i
n
g
0
/
2
0
0
0
0
0
0
реплик
ацию
Давайте
проверим
реплик
ацию
и
выполним
на
мастере:
Листинг
5.21
Выполняем
на
мастере
Line
1
$
p
s
q
l
t
e
s
t
_
d
b
-
t
e
s
t
_
d
b
=
#
c
r
e
a
t
e
t
a
b
l
e
t
e
s
t
3
(
i
d
i
n
t
n
o
t
n
u
l
l
p
r
i
m
a
r
y
k
e
y
,
na
me
v
a
r
c
h
a
r
(
2
0
)
)
;
-
N
O
T
I
C
E
:
C
R
E
A
T
E
T
A
B
L
E
/
P
R
I
M
A
R
Y
K
E
Y
w
i
l
l
c
r
e
a
t
e
i
m
p
l
i
c
i
t
i
n
d
e
x
"
t
e
s
t
3
_
p
k
e
y
"
f
o
r
t
a
b
l
e
"
t
e
s
t
3
"
-
C
R
E
A
T
E
T
A
B
L
E
5
t
e
s
t
_
d
b
=
#
i
n
s
e
r
t
i
n
t
o
t
e
s
t
3
(
i
d
,
nam
e
)
v
a
l
u
e
s
(
’
1
’
,
’
t
e
s
t
1
’
)
;
-
I
N
SE
RT
0
1
-
t
e
s
t
_
d
b
=
#
Т
еперь
проверим
на
слейве
резу
ль
тат:
Листинг
5.22
Выполняем
на
слейве
Line
1
$
p
s
q
l
t
e
s
t
_
d
b
-
t
e
s
t
_
d
b
=
#
s
e
l
e
c
t
*
f
r
o
m
t
e
s
t
3
;
-
i
d
|
na
me
-
-
-
-
-
+
-
-
-
-
-
-
-
5
1
|
t
e
s
t
1
-
(
1
r
o
w
)
Как видим,
таблица с
данными успешно скопирована с мастера
на
слейв.
Более
подробно
по
настройк
е
данной
репликации
мо
жно
почит
ать
из
официальной
wiki
.
Общие
зада
чи
Переключение
на
слейв
при
падении
мастера
Дост
аточно
создать
триггер
файл
(
trigger_file
)
на
слейве,
к
оторый
пе-
рест
анет
читать
данные
с
мастера.
75
5.2.
Потоковая
репликация
(Streaming
Replication)
Ост
ановка
репликации
на
слейве
Создать
триггер
файл
(
trigger_file
)
на
слейве.
Т
акже
с
версии
9.1
доба-
вили
функции
pg_xlog_replay_pause()
и
pg_xlog_replay_resume()
для
оста-
новки
и
возобновления
реплик
ации.
Перезапу
ск
репликации
после
сбоя
Повтор
яем операции из раздела
«
Настройк
а слейва
»
. Хочется
заме-
тить,
что
мастер
при
этом
не
нуждаетс
я
в
остановк
е
при
выполнении
дан-
ной
зада
чи.
Перезапу
ск
репликации
после
сбоя
слейва
Перезагрузить
P
ostgreSQL
на
слейве
после
устранения
сбоя.
Повторно
синхронизировать
реплик
ации
на
слейве
Это
мо
ж
ет
потребоваться,
например,
после
длительного
отключения
от
мастера.
Для
этого
останавливаем
P
ostgreSQL
на
слейве
и
повторяем
операции
из
раздела
«
Настройк
а
слейва
»
.
Repmgr
Repmgr
—
набор
инструментов
для
управления
потоковой
репликацией
и
восст
ановления
после
сбоя
кластера
PostgreSQL
серверов.
Он
автомати-
зиру
ет
настройку
резервных
серверов,
мониторинг
репликации,
а
такж
е
помог
ает
выполнять
зада
чи
администрированию
кластера,
такие
как
отка-
зоу
стойчивость
(failo
ver)
или
переключение
мастера-слейва
(слейв
стано-
витс
я
мастером,
а
мастер
-
слейвом).
Repmgr
работает
с
версии
PostgreSQL
9.3
и
выше.
Repmgr
состоит
из
двух
утилит:
∙
repmgr
—
инструмент
командной
строки
(cli),
который
используетс
я
для
административных
зада
ч,
таких
как:
– создание
слейвов;
– переключение
слейва
в
режим
мастера;
– переключение
между
собой
мастер
и
слейв
серверов;
– отображ
ение
состояния
кластера;
∙
repmgrd
—
демон,
который
мониторит
кластер
серверов
и
выполняет
т
акие
задачи:
– мониторинг
и
логирование
эффективности
реплик
ации;
– автоматическ
ое
переключение
слейва
в
мастер
при
обнаруже-
нии
проблем
у
текущего
мастера
(failo
ver);
– посылк
а
сообщений
о
событиях
в
кластере
через
заданые
поль-
зователем
скрипты;
76
5.2.
Потоковая
репликация
(Streaming
Replication)
Пример
использования:
автоматическ
ое
переключение
слейва
в
мастер
Для
использования
failov
er
потребу
ется
добавить
repmgr_funcs
в
p
ostgresql
.
conf
:
Листинг
5.23
repmgr_funcs
Line
1
s
h
a
r
e
d
_
p
r
e
l
o
a
d
_
l
i
b
r
a
r
i
e
s
=
’
r
e
p
m
g
r
_
f
u
n
c
s
’
И
добавить
настройки
в
repmgr.conf
:
Листинг
5.24
repmgr.conf
Line
1
f
a
i
l
o
v
e
r
=a
u
t
o
m
a
t
i
c
-
p
r
o
m
o
t
e
_
c
o
m
m
a
n
d
=
’
r
e
p
m
g
r
s
t
a
n
d
b
y
p
r
o
m
o
t
e
-
f
/
e
t
c
/
r
e
p
m
g
r
.
c
o
n
f
-
-
l
o
g
-
t
o
-
f
i
l
e
’
-
f
o
l
l
o
w
_
c
o
m
m
a
n
d
=
’
r
e
p
m
g
r
s
t
a
n
d
b
y
f
o
l
l
o
w
-
f
/
e
t
c
/
r
e
p
m
g
r
.
c
o
n
f
-
-
l
o
g
-
t
o
-
f
i
l
e
’
Для
демонстрации
автоматического
failov
er,
настроен
кластер
с
тремя
узлами
реплик
ации
(о
дин
мастер
и
два
слейв
сервера),
т
ак
что
таблица
repl_no
des
выг
лядит
следующим
образом:
Листинг
5.25
repl_no
des
Line
1
#
S
E
L
E
C
T
i
d
,
t
y
p
e
,
u
p
s
t
r
e
a
m
_
n
o
d
e
_
i
d
,
p
r
i
o
r
i
t
y
,
a
c
t
i
v
e
F
R
O
M
r
e
p
m
g
r
_
t
e
s
t
.
r
e
p
l
_
n
o
d
e
s
O
R
D
E
R
B
Y
i
d
;
-
i
d
|
t
y
p
e
|
u
p
s
t
r
e
a
m
_
n
o
d
e
_
i
d
|
p
r
i
o
r
i
t
y
|
a
c
t
i
v
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
1
|
m
a
s
t
e
r
|
|
1
0
0
|
t
5
2
|
s
t
a
n
d
b
y
|
1
|
1
0
0
|
t
-
3
|
s
t
a
n
d
b
y
|
1
|
1
0
0
|
t
-
(
3
r
o
w
s
)
После
запу
ска
repmgrd
демона
на
к
аждом
сервере
в
режиме
о
жидания,
убеждаемс
я
что
он
мониторит
кластер:
Листинг
5.26
logs
Line
1
[
2
0
1
6
-
0
1
-
0
5
1
3
:
1
5
:
4
0
]
[
IN
F
O
]
c
h
e
c
k
i
n
g
c
l
u
s
t
e
r
c
o
n
f
i
g
u
r
a
t
i
o
n
w
i
t
h
s
c
h
e
m
a
’
r
e
p
m
g
r
_
t
e
s
t
’
-
[
2
0
1
6
-
0
1
-
0
5
1
3
:
1
5
:
4
0
]
[
IN
FO
]
c
h
e
c
k
i
n
g
n
o
d
e
2
i
n
c
l
u
s
t
e
r
’
t
e
s
t
’
-
[
2
0
1
6
-
0
1
-
0
5
1
3
:
1
5
:
4
0
]
[
IN
FO
]
r
e
l
o
a
d
i
n
g
c
o
n
f
i
g
u
r
a
t
i
o
n
f
i
l
e
a
n
d
u
p
d
a
t
i
n
g
r
e
p
m
g
r
t
a
b
l
e
s
-
[
2
0
1
6
-
0
1
-
0
5
1
3
:
1
5
:
4
0
]
[
IN
FO
]
s
t
a
r
t
i
n
g
c
o
n
t
i
n
u
o
u
s
s
t
a
n
d
b
y
n
o
d
e
m
o
n
i
t
o
r
i
n
g
Т
еперь
ост
ановим
мастер
базу:
77
5.2.
Потоковая
репликация
(Streaming
Replication)
Листинг
5.27
Остановк
а
текущего
мастера
Line
1
p
g
_
c
t
l
-D
/
p
a
t
h
/
t
o
/
n
o
d
e
1
/
d
a
t
a
-m
i
m
m
e
d
i
a
t
e
s
t
o
p
repmgrd
автоматически
замечает
падение
мастера
и
переключает
о
дин
из
слейвов
в
мастер:
Листинг
5.28
Переключение
слейва
в
мастер
Line
1
[
2
0
1
6
-
0
1
-
0
6
1
8
:
3
2
:
5
8
]
[
W
A
R
N
I
N
G
]
c
o
n
n
e
c
t
i
o
n
t
o
u
p
s
t
r
e
a
m
h
a
s
b
e
e
n
l
o
s
t
,
t
r
y
i
n
g
t
o
r
e
c
o
v
e
r
.
.
.
1
5
s
e
c
o
n
d
s
b
e
f
o
r
e
f
a
i
l
o
v
e
r
d
e
c
i
s
i
o
n
-
[
2
0
1
6
-
0
1
-
0
6
1
8
:
3
3
:
0
3
]
[
W
A
R
N
I
N
G
]
c
o
n
n
e
c
t
i
o
n
t
o
u
p
s
t
r
e
a
m
h
a
s
b
e
e
n
l
o
s
t
,
t
r
y
i
n
g
t
o
r
e
c
o
v
e
r
.
.
.
1
0
s
e
c
o
n
d
s
b
e
f
o
r
e
f
a
i
l
o
v
e
r
d
e
c
i
s
i
o
n
-
[
2
0
1
6
-
0
1
-
0
6
1
8
:
3
3
:
0
8
]
[
W
A
R
N
I
N
G
]
c
o
n
n
e
c
t
i
o
n
t
o
u
p
s
t
r
e
a
m
h
a
s
b
e
e
n
l
o
s
t
,
t
r
y
i
n
g
t
o
r
e
c
o
v
e
r
.
.
.
5
s
e
c
o
n
d
s
b
e
f
o
r
e
f
a
i
l
o
v
e
r
d
e
c
i
s
i
o
n
-
.
.
.
5
[
2
0
1
6
-
0
1
-
0
6
1
8
:
3
3
:
1
8
]
[
N
O
T
I
C
E
]
t
h
i
s
n
o
d
e
i
s
t
h
e
b
e
s
t
c
a
n
d
i
d
a
t
e
t
o
b
e
t
h
e
n
ew
m
a
s
t
e
r
,
p
r
o
m
o
t
i
n
g
.
.
.
-
.
.
.
-
[
2
0
1
6
-
0
1
-
0
6
1
8
:
3
3
:
2
0
]
[
N
O
T
I
C
E
]
S
T
A
N
D
B
Y
P
R
O
M
O
T
E
s
u
c
c
e
s
s
f
u
l
Т
акж
е
переключает
оставшийс
я
слейв
на
новый
мастер:
Листинг
5.29
Переключение
слейва
на
новый
мастер
Line
1
[
2
0
1
6
-
0
1
-
0
6
1
8
:
3
2
:
5
8
]
[
W
A
R
N
I
N
G
]
c
o
n
n
e
c
t
i
o
n
t
o
u
p
s
t
r
e
a
m
h
a
s
b
e
e
n
l
o
s
t
,
t
r
y
i
n
g
t
o
r
e
c
o
v
e
r
.
.
.
1
5
s
e
c
o
n
d
s
b
e
f
o
r
e
f
a
i
l
o
v
e
r
d
e
c
i
s
i
o
n
-
[
2
0
1
6
-
0
1
-
0
6
1
8
:
3
3
:
0
3
]
[
W
A
R
N
I
N
G
]
c
o
n
n
e
c
t
i
o
n
t
o
u
p
s
t
r
e
a
m
h
a
s
b
e
e
n
l
o
s
t
,
t
r
y
i
n
g
t
o
r
e
c
o
v
e
r
.
.
.
1
0
s
e
c
o
n
d
s
b
e
f
o
r
e
f
a
i
l
o
v
e
r
d
e
c
i
s
i
o
n
-
[
2
0
1
6
-
0
1
-
0
6
1
8
:
3
3
:
0
8
]
[
W
A
R
N
I
N
G
]
c
o
n
n
e
c
t
i
o
n
t
o
u
p
s
t
r
e
a
m
h
a
s
b
e
e
n
l
o
s
t
,
t
r
y
i
n
g
t
o
r
e
c
o
v
e
r
.
.
.
5
s
e
c
o
n
d
s
b
e
f
o
r
e
f
a
i
l
o
v
e
r
d
e
c
i
s
i
o
n
-
.
.
.
5
[
2
0
1
6
-
0
1
-
0
6
1
8
:
3
3
:
2
3
]
[
N
O
T
I
C
E
]
n
o
d
e
2
i
s
t
h
e
b
e
s
t
c
a
n
d
i
d
a
t
e
f
o
r
n
ew
m
a
s
t
e
r
,
a
t
t
e
m
p
t
i
n
g
t
o
f
o
l
l
o
w
.
.
.
-
[
2
0
1
6
-
0
1
-
0
6
1
8
:
3
3
:
2
3
]
[
IN
FO
]
c
h
a
n
g
i
n
g
s
t
a
n
d
b
y
’
s
m
a
s
t
e
r
-
.
.
.
-
[
2
0
1
6
-
0
1
-
0
6
1
8
:
3
3
:
2
5
]
[
N
O
T
I
C
E
]
n
o
d
e
3
now
f
o
l
l
o
w
i
n
g
ne
w
u
p
s
t
r
e
a
m
n
o
d
e
2
Т
аблица
repl_no
des
бу
дет
обновлена,
чтобы
отразить
новую
ситуацию
—
ст
арый
мастер
no
de1
помечен
к
ак
неактивный,
и
слейв
no
de3
теперь
рабо-
т
ает
от
нового
мастера
no
de2
:
78
5.2.
Потоковая
репликация
(Streaming
Replication)
Листинг
5.30
Резу
льт
ат
после
failov
er
Line
1
#
S
E
L
E
C
T
i
d
,
t
y
p
e
,
u
p
s
t
r
e
a
m
_
n
o
d
e
_
i
d
,
p
r
i
o
r
i
t
y
,
a
c
t
i
v
e
f
r
o
m
r
e
p
l
_
n
o
d
e
s
O
R
D
E
R
B
Y
i
d
;
-
i
d
|
t
y
p
e
|
u
p
s
t
r
e
a
m
_
n
o
d
e
_
i
d
|
p
r
i
o
r
i
t
y
|
a
c
t
i
v
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
1
|
m
a
s
t
e
r
|
|
1
0
0
|
f
5
2
|
m
a
s
t
e
r
|
|
1
0
0
|
t
-
3
|
s
t
a
n
d
b
y
|
2
|
1
0
0
|
t
-
(
3
r
o
w
s
)
В
таблицу
repl_ev
ents
бу
дут
добавлены
записи
того,
что
произошло
с
к
аждым
сервером
во
время
failov
er:
Листинг
5.31
Резу
льт
ат
после
failov
er
Line
1
#
S
E
L
E
C
T
n
o
d
e
_
i
d
,
e
v
e
n
t
,
s
u
c
c
e
s
s
f
u
l
,
d
e
t
a
i
l
s
f
r
o
m
r
e
p
m
g
r
_
t
e
s
t
.
r
e
p
l
_
e
v
e
n
t
s
w
h
e
r
e
e
v
e
n
t
_
t
i
m
e
s
t
a
m
p
>
=
’
2
0
1
6
-
0
1
-
0
6
1
8
:
3
0
’
;
-
n
o
d
e
_
i
d
|
e
v
e
n
t
|
s
u
c
c
e
s
s
f
u
l
|
d
e
t
a
i
l
s
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2
|
s
t
a
n
d
b
y
_
p
r
o
m
o
t
e
|
t
|
n
o
d
e
2
w
a
s
s
u
c
c
e
s
s
f
u
l
l
y
p
r
o
m
o
t
e
d
t
o
m
a
s
t
e
r
5
2
|
r
e
p
m
g
r
d
_
f
a
i
l
o
v
e
r
_
p
r
o
m
o
t
e
|
t
|
n
o
d
e
2
p
r
o
m
o
t
e
d
t
o
m
a
s
t
e
r
;
o
l
d
m
a
s
t
e
r
1
m
a
r
k
e
d
a
s
f
a
i
l
e
d
-
3
|
r
e
p
m
g
r
d
_
f
a
i
l
o
v
e
r
_
f
o
l
l
o
w
|
t
|
n
o
d
e
3
now
f
o
l
l
o
w
i
n
g
ne
w
u
p
s
t
r
e
a
m
n
o
d
e
2
-
(
3
r
o
w
s
)
Заключение
Более
по
дробно
по
функционалу
,
его
настройках
и
ограничениях
до-
ступно
в
официальном
репозитории
.
P
atroni
P
atroni
—
это
демон
на
Python,
позволяющий
автоматически
обслужи-
вать
кластеры
P
ostgreSQL
с
потоковой
репликацией.
Особенности:
∙
Использу
ет
потоковую
P
ostgreSQL
реплик
ацию
(асинхронная
и
син-
хронная
реплик
ация);
∙
Интеграция
с
Kub
ernetes
;
79
5.3.
PostgreSQL
Bi-Directional
Replication
(BDR)
∙
По
ддер
жания
актуальности
кластера
и
выборов
мастера
использу-
ютс
я
распределенные
DCS
хранилища
(поддер
живаютс
я
Zookeeper
,
Etcd
или
Consul
);
∙
Автоматическ
ое
«service
discov
ery»
и
динамическая
рек
онфигурация
кластера;
∙
Состо
яние
кластера
мо
жно
получить
как
запросами
в
DCS,
т
ак
и
напр
ямую
к
Patroni
через
HTTP
запросы;
Информация
по
настройке
и
использованию
P
atroni
нахо
дитс
я
в
офи-
циальной
документ
ации
проекта.
Stolon
Stolon
—
это
демон
на
Go,
позволяющий
автоматически
обслуживать
кластеры
P
ostgreSQL
с
потоковой
репликацией.
Особенности:
∙
Использу
ет
потоковую
P
ostgreSQL
реплик
ацию
(асинхронная
и
син-
хронная
реплик
ация);
∙
Интеграция
с
Kub
ernetes
;
∙
По
ддер
жания
актуальности
кластера
и
выборов
мастера
использу-
ютс
я распределенные
DCS
хранилища
(п
о
ддерживаютс
я
Etcd
или
Consul
);
∙
Автоматическ
ое
«service
discov
ery»
и
динамическая
рек
онфигурация
кластера;
∙
Состо
яние
кластера
мо
жно
получить
как
запросами
в
DCS,
т
ак
и
через
stolonctl
клиент;
Stolon
состоит
из
3
основных
к
омпонентов:
∙
k
eep
er
(хранитель):
управляет
экземпляром
P
ostgreSQL;
∙
sen
tinel:
обнаруживает
и
контролиру
ет
keeper-ров
и
вычисляет
опти-
мальное
состо
яние
кластера;
∙
pro
xy:
точк
а
доступа
клиента,
обеспечивает
подключение
к
верному
P
ostgreSQL
мастеру
в
кластере;
Информация
по
настройке
и
использованию
Stolon
нахо
дитс
я
в
офи-
циальной
документ
ации
проекта.
5.3
P
ostgreSQL
Bi-Directional
Replication
(BDR)
BDR
(Bi-Directional Replication)
это
новая
функциональность
добав-
ленная
в
ядро
PostgreSQL
к
оторая
предоставляет
расширенные
средства
для
репликации.
На
данный
момент
это
реализовано
в
виде
небольшого
патча
и
моду
ля
для
9.4
версии.
Заявлено
что
полностью
бу
дет
тольк
о
в
80
5.3.
PostgreSQL
Bi-Directional
Replication
(BDR)
Рис.
5.1:
Stolon
ар
хитектура
P
ostgreSQL
9.6
(разработчики
решили
не
заниматься
поддер
жкой
патча
для
9.5,
а
сосредоточиться
на
добавление
патчей
в
сам
PostgreSQL).
BDR
позволяет
создавать
географически
распределенные
асинхронные
му
ль
ти-
мастер
к
онфигурации
используя
для
этого
встроенную
логическую
пото-
к
овую
репликацию
LLSR
(Logical
Log
Streaming
Replication).
BDR
не
являетс
я
инструментом
для
кластеризации,
т
.к.
здесь
нет
к
аких-либо
глобальных
менеджеров
блокировок
или
коор
динаторов
тран-
закций.
Каждый
узел
не
зависит
от
других,
что
было
бы
невозмо
жно
в
случае
использования
менедж
еров
блокировки.
Каждый
из
узлов
со
дер-
жит
локальную
к
опию
данных
идентичную
данным
на
других
узлах.
За-
просы
т
акже
выполняются
только
локально.
При
этом
к
аждый
из
узлов
81
5.4.
Pglogical
внутренне
консистентен
в
любое
время,
целиком
же
группа
серверов
явля-
етс
я
сог
ласованной
в
конечном
счете
(even
tually
consistent).
Уник
альность
BDR
заключается
в
том
что
она
непох
о
жа
ни
на
встроенную
поток
овую
реплик
ацию,
ни
на
существующие
trigger-based
решения
(Londiste,
Slon
y
,
Bucardo).
Самым
заметным
от
личием
от
потоковой
репликации
являетс
я
то,
что
BDR
(LLSR)
оперирует
базами
(p
er-database
replication),
а
классическая
PLSR
реплицирует
целиком
инст
анс
(p
er-cluster
replication),
т
.
е.
все
базы
внутри
инст
анса.
Существующие
ограничения
и
особенности:
∙
Все
изменения
данных
вызываемые
INSER
T
/
DELETE
/
UPDA
TE
реп-
лицируютс
я
(
TR
UNCA
TE
на
момент
написания
статьи
пок
а
не
реа-
лизован);
∙
Большинство
операции
изменения
с
х
емы
(DDL)
реплицируются
у
спешно.
Неподдер
живаемые
DDL
фиксируютс
я
моду
лем
реплик
а-
ции
и
отклоняются
с
выда
чей
ошибкой
(на
момент
написания
не
ра-
бот
ал
CREA
TE
T
ABLE
...
AS
);
∙
Определения
таблиц,
типов,
расширений
и
т
.
п.
должны
быть
иден-
тичными
между
upstream
и
do
wnstream
мастерами;
∙
Действия
к
оторые
отраж
аются
в
W
AL,
но
не
представляютс
я
в
ви-
де
логических
изменений
не
реплицируются
на
другой
узел
(запись
полных
страниц,
вакуумация
т
аблиц
и
т
.
п.).
Т
аким
образом
логи-
ческ
ая
поток
овая
репликация
(LLSR)
избавлена
от
нек
оторой
части
накладных
расх
одов
к
оторые
присутствуют
в
физической
поток
овой
реплик
ации
PLSR
(тем
не
менее
это
не
означает
что
LLSR
требу
ется
меньшая
пропу
скная
способность
сети
чем
для
PLSR);
Небольшое
примечание:
временная
остановк
а
репликации
осуществля-
етс
я
выключением
downstream
мастера.
Однако
стоит
отметить
что
оста-
новленная
реплика
приводит
к
тому
что
upstream
мастер
про
должит
на-
к
апливать
W
AL
журналы
что
в
свою
очередь
мож
ет
привести
к
нек
он-
тролиру
емому
расх
о
ду
пространства
на
диске.
Поэтому
крайне
не
реко-
менду
ется
надолго
выключать
реплику
.
У
даление
реплики
навсегда
осу-
ществляетс
я
через
у
даление
конфигурации
BDR
на
downstream
сервере
с
последующим
перезапу
ск
ом
do
wnstream
мастера.
Затем
нужно
у
далить
со-
ответствующий
слот
репликации
на
upstream
мастере
с
помощью
функции
pg_drop_replication_slot(’slotname’)
.
Доступные
слоты
можно
просмотреть
с
помощью
функции
pg_get_replication_slots
.
На
текущий
момент
собрать
BDR
мо
жно
из
исх
одник
ов
по
данному
ману
алу
.
С
официальным
принятием
данных
патчей
в
ядро
P
ostgreSQL
данный
раздел
про
BDR
бу
дет
расширен
и
дополнен.
5.4
Pglogical
Pglogical
—
это
расширение
для P
ostgreSQL,
к
оторое
использу
ет
ло-
82
5.4.
Pglogical
гическ
ое
деко
дирование
через
publish/subscrib
e
мо
дель.
Данное
расшире-
ние
базируетс
я
на
BDR
проекте
(
5.3
PostgreSQL
Bi-Directional
Replication
(BDR)
).
Р
асширение
работ
ает
тольк
о
начиная
с
версии
PostgreSQL
9.4
и
выше
(из-за
логического
деко
дирования).
Для
разных
вариаций
обнару-
ж
ения
и
разрешения
конфликтов
требуетс
я
версия
9.5
и
выше.
Используютс
я
следующие
термины
для
описания
pglogical:
∙
Nodes(ноды,
узлы)
—
экземпляры
баз
данных
PostgreSQL;
∙
Pro
vider
и
subscrib
er
—
роли
узлов.
Provider
выполняют
выда
чу
дан-
ных
и
изменений
для
subscrib
er-ов;
∙
Replication
set
(набор
для
репликации)
—
к
оллекция
таблиц
и
после-
довательностей
для
реплик
ации;
Сценарии
использования
pglogical:
∙
Обновление
между
версиями
PostgreSQL
(например
c
9.4
на
9.5);
∙
Полная
реплик
ация
базы
данных;
∙
Выборочная
реплик
ация
т
аблиц;
∙
Сбор
данных
с
нескольких
баз
данных
в
одну;
Ар
хитектурные
детали:
∙
Pglogical
работает
на
уровне
к
аждой
базы
данных,
а
не
на
весь
сер-
вер;
∙
Pro
vider
(publisher)
мож
ет
«кормить»
нескольк
о
subscrib
er-ов
без
до-
полнительных
накладных
рас
хо
дов
записи
на
диск;
∙
Один
subscrib
er
мож
ет
объединить
изменения
из
неск
ольких
pro
vider-ов
и
использовать
систему
обнаружения
и
разрешения
кон-
фликтов
между
изменениями;
∙
Каск
адная
реплик
ация
осуществляется
в
виде
переадресации
изме-
нений;
У
становк
а
и
настройк
а
У
ст
ановить
pglogical
можно
по
данной
документ
ации
.
Далее
требуетс
я
настроить
логический
дек
одинг
в
PostgreSQL:
Листинг
5.32
p
ostgresql.conf
Line
1
w
a
l
_
l
e
v
e
l
=
’
l
o
g
i
c
a
l
’
-
m
a
x
_
w
o
r
k
e
r
_
p
r
o
c
e
s
s
e
s
=
1
0
#
o
n
e
p
e
r
d
a
t
a
b
a
s
e
n
e
e
d
e
d
o
n
p
r
o
v
i
d
e
r
n
o
d
e
-
#
o
n
e
p
e
r
n
o
d
e
n
e
e
d
e
d
o
n
s
u
b
s
c
r
i
b
e
r
n
o
d
e
-
m
a
x
_
r
e
p
l
i
c
a
t
i
o
n
_
s
l
o
t
s
=
1
0
#
o
n
e
p
e
r
n
o
d
e
n
e
e
d
e
d
o
n
p
r
o
v
i
d
e
r
n
o
d
e
83
5.4.
Pglogical
5
m
a
x
_
w
a
l
_
s
e
n
d
e
r
s
=
1
0
#
o
n
e
p
e
r
n
o
d
e
n
e
e
d
e
d
o
n
p
r
o
v
i
d
e
r
n
o
d
e
-
s
h
a
r
e
d
_
p
r
e
l
o
a
d
_
l
i
b
r
a
r
i
e
s
=
’
p
g
l
o
g
i
c
a
l
’
Если
использу
ется
PostgreSQL
9.5+
и
требуются
механизмы
разреше-
ния
к
онфликтов,
то
требуетс
я
добавить
дополнительные
опции:
Листинг
5.33
p
ostgresql.conf
Line
1
t
r
a
c
k
_
c
o
m
m
i
t
_
t
i
m
e
s
t
a
m
p
=
o
n
#
n
e
e
d
e
d
f
o
r
l
a
s
t
/
f
i
r
s
t
u
p
d
a
t
e
w
i
n
s
c
o
n
f
l
i
c
t
r
e
s
o
l
u
t
i
o
n
-
#
p
r
o
p
e
r
t
y
a
v
a
i
l
a
b
l
e
i
n
P
o
s
t
g
r
e
S
Q
L
9
.
5
+
В
pg_hba.conf
нужно
разрешить
replication
соединения
с
лок
ального
хо-
ст
а
для
пользователя
с
привилегией
репликации.
После
перезапуск
а
базы
нужно
активировать
расширение
на
всех
но
дах:
Листинг
5.34
Активируем
расширение
Line
1
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
g
l
o
g
i
c
a
l
;
Далее
на
master
(мастер)
создаем
provider
(процесс,
к
оторый
бу
дет
вы-
давать
изменения
для
subscrib
er-ов)
ноду:
Листинг
5.35
Создаем
provider
Line
1
S
E
L
E
C
T
p
g
l
o
g
i
c
a
l
.
c
r
e
a
t
e
_
n
o
d
e
(
-
no
d
e
_
n
a
m
e
:
=
’
p
r
o
v
i
d
e
r
1
’
,
-
d
s
n
:
=
’
h
o
s
t=
p
r
o
v
i
d
e
r
h
o
s
t
p
o
r
t
=
5
4
3
2
d
b
n
a
m
e
=
d
b
’
-
)
;
И
добавляем
все
т
аблицы
в
public
сх
еме:
Листинг
5.36
Добавляем
в
replication
set
все
таблицы
в
public
с
хеме
Line
1
S
E
L
E
C
T
p
g
l
o
g
i
c
a
l
.
r
e
p
l
i
c
a
t
i
o
n
_
s
e
t
_
a
d
d
_
a
l
l
_
t
a
b
l
e
s
(
’
d
e
f
a
u
l
t
’
,
A
R
R
A
Y
[
’
p
u
b
l
i
c
’
]
)
;
Далее
перех
одим
на
slav
e
(слейв)
и
создаем
subscrib
er
ноду:
Листинг
5.37
Создаем
subscrib
er
Line
1
S
E
L
E
C
T
p
g
l
o
g
i
c
a
l
.
c
r
e
a
t
e
_
n
o
d
e
(
-
no
d
e
_
n
a
m
e
:
=
’
s
u
b
s
c
r
i
b
e
r
1
’
,
-
d
s
n
:
=
’
h
o
s
t=
t
h
i
s
h
o
s
t
p
o
r
t
=
5
4
3
2
d
b
n
a
m
e
=
d
b
’
-
)
;
84
5.4.
Pglogical
После
этого
создаем
«по
дписку»
на
provider
но
ду
,
которая
на
чнет
син-
хронизацию
и
реплик
ацию
в
фоне:
Листинг
5.38
Активируем
subscrib
er
Line
1
S
E
L
E
C
T
p
g
l
o
g
i
c
a
l
.
c
r
e
a
t
e
_
s
u
b
s
c
r
i
p
t
i
o
n
(
-
s
u
b
s
c
r
i
p
t
i
o
n
_
n
a
m
e
:
=
’
s
u
b
s
c
r
i
p
t
i
o
n
1
’
,
-
p
r
o
v
i
d
e
r
_
d
s
n
:
=
’
h
o
s
t
=
p
r
o
v
i
d
e
r
h
o
s
t
p
o
r
t
=
5
4
3
2
db
n
a
m
e
=
db
’
-
)
;
Если
все
про
делано
верно,
subscrib
er
через
определенный
интервал
вре-
мени
subscrib
er
нода
должна
получить
точную
к
опию
всех
таблиц
в
public
с
хеме
с
master
хост
а.
Р
азрешение
конфликтов
Если
использу
ется
с
хема,
где
subscrib
er
но
да
по
дписана
на
данные
из
неск
ольких
provider-ов,
или
ж
е
на
subscrib
er
дополнительно
производятс
я
лок
альные
изменения
данных,
могут
возникать
к
онфликты
для
новых
из-
менений. В
pglogical встроен
мех
анизм для
обнаруж
ения и
разрешения
к
онфликтов.
Настройк
а данного
мех
анизма
проис
хо
дит через
pglogical
.
conflict_resolution
ключ.
Поддер
живаются
следующие
значения:
∙
error
-
репликация
остановитс
я
на
ошибке,
если
обнаруживается
кон-
фликт
и
потребу
ется
ручное
действие
для
его
разрешения;
∙
apply_remote
-
всег
да
применить
изменения,
который
к
онфликтуют
с
лок
альными
данными.
Значение
по
умолчанию;
∙
k
eep_lo
cal
-
со
хранить
локальную версию
данных
и
игнорировать
к
онфликтующие
изменения,
которые
исх
одят
от
provider-а;
∙
last_update_wins
-
версия
данных
с
самым
новым
коммитом
(newest
commit
timestamp)
бу
дет
сохранена;
∙
first_update_wins
-
версия
данных
с
самым
ст
арым
коммитом
(oldest
commit
timestamp)
бу
дет
сохранена;
Ког
да опция
trac
k_commit_timestamp
отключена, единственное допу-
стимое
значение
для
pglogical
.
conflict_resolution
мож
ет
быть
apply_remote
.
Поск
ольку
track_commit_timestamp
не
доступен
в
PostgreSQL
9.4,
данная
опция
у
становлена
по
умолчанию
в
apply_remote
.
Ограничения
и
недост
атки
∙
Для
работы
требу
етс
я
суперпользователь;
∙
UNLOGGED
и
TEMPORAR
Y
таблицы
не
реплицируются;
∙
Для
к
аждой базы
данных
нужно настроить
от
дельный pro
vider и
subscrib
er;
∙
Требу
етс
я
primary
key
или
replica
identit
y
для
реплик
ации;
85
5.5.
Slony-I
∙
Р
азрешен
только
о
дин
уник
альный
индек
с/ограничение/основной
ключ
на
та
блицу
(из-за
возможных
конфликтов).
Возможно
исполь-
зовать
больше,
но
только
в
случае
если
subscrib
er
чит
ает
только
с
о
дного
pro
vider
и
не
производитс
я
локальных
изменений
данных
на
нем;
∙
Автоматическ
ая
реплик
ация
DDL
не
поддер
живаетс
я.
У
pglogical
есть команда
pglogical
.
replicate_ddl_command
для запуск
а
DDL на
pro
vider
и
subscrib
er;
∙
Ограничения
на
foreign
ключи
не
выполняются
на
subscrib
er-рах;
∙
При
использовании
TR
UNCA
TE
...
CASCADE
бу
дет
выполнен
CASCADE
тольк
о
на
provider;
∙
Последовательности
реплицируютс
я периодически, а
не в режиме
реального
времени;
5.5
Slon
y-I
Slon
y
это
система
репликации
реального
времени,
позволяющая
орг
анизовать
синхронизацию
нескольких
серверов
PostgreSQL
по
се-
ти.
Slon
y
использу
ет
триггеры
P
ostgreSQL
для
привязки
к
событиям
INSER
T/DELETE/UPD
A
TE
и
хранимые
процедуры
для
выполнения
дей-
ствий.
Система
Slony
с
точки
зрения
администратора
состоит
из
двух
глав-
ных
компонент:
реплик
ационного
демона
slony
и
административной
к
онсо-
ли
slonik
.
Администрирование
системы
сво
дится
к
общению
со
slonik
-ом,
демон
slon
тольк
о
следит
за
собственно
процессом
репликации.
Все
к
оманды
slonik
принимает
на
свой
stdin.
До
начала
выполнения
скрипт
slonik-a
проверяетс
я
на
соответствие
синтак
сису
,
если
обнаружи-
ваютс
я
ошибки,
скрипт
не
выполняется,
так
что
можно
не
волноватьс
я
если
slonik
сообщает
о
syntax
error,
ничего
страшного
не
произошло.
И
он
ещё
ничего
не
с
делал.
Скорее
всего.
У
становк
а
У
ст
ановка
на
Ubuntu
производитс
я
простой
командой:
Листинг
5.39
У
становк
а
Line
1
$
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
s
l
o
n
y
1
-
2
-
b
i
n
Настройк
а
Р
ассмотрим
уст
ановку
на
гипотетическую
базу
данных
customers.
Ис-
х
одные
данные:
86
5.5.
Slony-I
∙
customers
—
база
данных;
∙
master_host
—
х
ост
master
базы;
∙
sla
v
e_host
—
хост
slav
e
базы;
∙
customers_rep
—
имя
кластера;
По
дготовка
master
базы
Для
на
чала
нужно
создать пользователя
в
базе,
под
которым
бу
дет
действовать
Slony
.
По
умолчанию,
и
отдавая
должное
системе,
этого
поль-
зователя
обычно
называют
slon
y
.
Листинг
5.40
Подготовк
а
master-сервера
Line
1
$
c
r
e
a
t
e
u
s
e
r
-
a
-
d
s
l
o
n
y
-
$
p
s
q
l
-
d
t
e
m
p
l
a
t
e
1
-
c
"A
L
T
E
R
U
S
E
R
s
l
o
n
y
W
I
T
H
P
A
S
S
W
O
R
D
’
s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
w
o
r
d
’
;
"
Т
акж
е на к
аждом из
узлов
лучше завести
системного
пользователя
slon
y
,
чтобы
запу
скать
от
его
имени
репликационного
демона
slon.
В
даль-
нейшем
подразумеваетс
я,
что
он
(и
пользователь
и
slon)
есть
на
к
аждом
из
узлов
кластера.
По
дготовка
slav
e
базы
Здесь
рассматривается,
что
серверы
кластера
соединены
посредством
сети.
Необх
о
димо
чтобы
с
каждого
из
серверов
можно
было
уст
ановить
соединение
с
P
ostgreSQL
на
master
хосте,
и
наоборот
.
Т
о
есть,
команда:
Листинг
5.41
Подготовк
а
о
дного
sla
v
e-сервера
Line
1
a
n
y
u
s
e
r
@
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
$
p
s
q
l
-
d
c
u
s
t
o
m
e
r
s
\
-
-
h
c
u
s
t
o
m
e
r
s
_
m
a
s
t
e
r
.
com
-
U
s
l
o
n
y
должна
подключать
нас
к
мастер-серверу
(после
вво
да
пароля,
ж
ела-
тельно).
Т
еперь у
станавливаем
на sla
ve-х
ост сервер P
ostgreSQL. Следующего
обычно
не
требу
ется,
сразу
после
у
становки
Postgres
«up
and
ready»
,
но
в
случае
каких-то
ошибок
мо
жно
на
чать
«с
чистого
лист
а»
,
выполнив
сле-
дующие
к
оманды
(предварительно
со
хранив
конфигурационные
файлы
и
ост
ановив
p
ostmaster):
Листинг
5.42
Подготовк
а
о
дного
sla
v
e-сервера
Line
1
p
g
s
q
l
@
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
$
rm
-
r
f
$
P
G
D
A
T
A
-
p
g
s
q
l
@
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
$
m
k
d
i
r
$
P
G
D
A
T
A
-
p
g
s
q
l
@
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
$
i
n
i
t
d
b
-
E
U
T
F
8
-D
$
P
G
D
A
T
A
-
p
g
s
q
l
@
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
$
c
r
e
a
t
e
u
s
e
r
-
a
-
d
s
l
o
n
y
87
5.5.
Slony-I
5
p
g
s
q
l
@
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
$
p
s
q
l
-
d
t
e
m
p
l
a
t
e
1
-
c
"
a
l
t
e
r
\
-
u
s
e
r
s
l
o
n
y
w
i
t
h
p
a
s
s
w
o
r
d
’
s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
w
o
r
d
’
;
"
Далее
запуск
аем
p
ostmaster.
Обычно
требуетс
я
определённый
владелец
для
реплициру
емой
БД.
В
этом
случае
необх
одимо
создать
его
тож
е:
Листинг
5.43
Подготовк
а
о
дного
sla
v
e-сервера
Line
1
p
g
s
q
l
@
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
$
c
r
e
a
t
e
u
s
e
r
-
a
-
d
c
u
s
t
o
m
e
r
s
_
o
w
n
e
r
-
p
g
s
q
l
@
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
$
p
s
q
l
-
d
t
e
m
p
l
a
t
e
1
-
c
"
a
l
t
e
r
\
-
u
s
e
r
c
u
s
t
o
m
e
r
s
_
o
w
n
e
r
w
i
t
h
p
a
s
s
w
o
r
d
’
c
u
s
t
o
m
e
r
s
_
o
w
n
e
r
_
p
a
s
s
w
o
r
d
’
;
"
Эти две к
оманды мо
жно запу
скать с
customers_master
, к
к
омандной
строк
е
в
этом
случае
нужно
добавить
-
h
customers_sla
v
e
,
чтобы
все
опера-
ции
выполнялись
на
sla
ve.
На
sla
ve,
как
и
на
master,
такж
е
нужно
уст
ановить
Slon
y
.
Инициализация
БД
и
plpgsql
на
sla
ve
Следующие
команды
выполняются
от
пользователя
slony
.
Скорее
всего
для
выполнения
каждой
из
них
потребу
ется
ввести
пароль
(
slon
y_user_password
):
Листинг
5.44
Инициализация
БД
и
plpgsql
на
slav
e
Line
1
s
l
o
n
y
@
c
u
s
t
o
m
e
r
s
_
m
a
s
t
e
r
$
c
r
e
a
t
e
d
b
-O
c
u
s
t
o
m
e
r
s
_
o
w
n
e
r
\
-
-
h
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
.
co
m
c
u
s
t
o
m
e
r
s
-
s
l
o
n
y
@
c
u
s
t
o
m
e
r
s
_
m
a
s
t
e
r
$
c
r
e
a
t
e
l
a
n
g
-
d
c
u
s
t
o
m
e
r
s
\
-
-
h
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
.
co
m
p
l
p
g
s
q
l
Внимание!
Все
т
абли
цы,
к
оторые
бу
дут
добавлены
в
replication
set
должны
иметь
primary
key
.
Если
как
ая-то
из
т
аблиц
не
у
довлетвор
яет
это-
му
у
словию,
задержитесь
на
этом
шаге
и
дайте
каждой
т
аблице
primary
k
ey
командой
AL
TER
T
ABLE
ADD
PRIMAR
Y
KEY
.
Если
столбца
к
оторый
мог
бы
стать
primary
key
не
нахо
дится,
добавьте
новый
столбец
типа
serial
(
AL
TER
T
ABLE
ADD
COLUMN
),
и
заполните
его
значениями.
Настоятель-
но
НЕ
рек
омендую
использовать
table add
k
ey
slonik-a.
Далее
создаём
т
аблицы
и
всё
остальное
на
slav
e
базе:
Листинг
5.45
Инициализация
БД
и
plpgsql
на
slav
e
Line
1
s
l
o
n
y
@
c
u
s
t
o
m
e
r
s
_
m
a
s
t
e
r
$
pg_
dum
p
-
s
c
u
s
t
o
m
e
r
s
|
\
-
p
s
q
l
-U
s
l
o
n
y
-
h
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
.
c
om
c
u
s
t
o
m
e
r
s
pg_dump
-s
с
дампит
только
структуру
нашей
БД.
pg_dump
-s
customers
долж
ен
пу
скать
без
пароля,
а
вот
для
psql
-
U
slony
-
h
customers_sla
ve.com
customers
придётся
набрать
пароль
(
slony_user_pass
).
Важно:
подразумеваетс
я
что
сейчас
на
мастер-хосте
ещё
не
уст
ановлен
88
5.5.
Slony-I
Slon
y
(речь
не
про
make
install
),
то
есть
в
БД
нет
таблиц
sl_*
,
триггеров
и
прочего.
Инициализация
кластера
Сейчас
мы
имеем
два
сервера
P
ostgreSQL
которые
свободно
«видят»
друг
друг
а
по
сети,
на
одном
из
них
нахо
дится
мастер-база
с
данными,
на
другом
—
тольк
о
структура
базы.
Далее
мастер-хосте
запуск
аем
скрипт:
Листинг
5.46
Инициализация
кластера
Line
1
#
!
/
b
i
n
/
s
h
-
-
C
L
U
S
T
E
R
=c
u
s
t
o
m
e
r
s
_
r
e
p
-
5
D
B
N
A
M
E
1
=c
u
s
t
o
m
e
r
s
-
D
B
N
A
M
E
2
=c
u
s
t
o
m
e
r
s
-
-
H
O
S
T
1
=c
u
s
t
o
m
e
r
s
_
m
a
s
t
e
r
.
com
-
H
O
S
T
2
=
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
.
com
10
-
P
O
R
T
1=5
4
3
2
-
P
O
R
T
2=5
4
3
2
-
-
S
L
O
N
Y
_
U
S
E
R
=
s
l
o
n
y
15
-
s
l
o
n
i
k
<
<
E
O
F
-
c
l
u
s
t
e
r
n
am
e
=
$
C
L
U
S
T
E
R
;
-
n
o
d
e
1
a
d
m
i
n
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
1
h
o
s
t
=
$H
O
ST
1
p
o
r
t
=
$
P
O
R
T
1
-
u
s
e
r=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
w
o
r
d
’
;
20
n
o
d
e
2
a
d
m
i
n
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
2
h
o
s
t
=
$
H
OS
T2
-
p
o
r
t
=
$
P
O
R
T
2
u
s
e
r
=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
w
o
r
d
’
;
-
i
n
i
t
c
l
u
s
t
e
r
(
i
d
=
1
,
c
o
m
m
e
n
t
=
’
C
u
s
t
o
m
e
r
s
D
B
-
r
e
p
l
i
c
a
t
i
o
n
c
l
u
s
t
e
r
’
)
;
-
25
e
c
h
o
’
C
r
e
a
t
e
s
e
t
’
;
-
-
c
r
e
a
t
e
s
e
t
(
i
d
=
1
,
o
r
i
g
i
n
=
1
,
c
o
m
m
e
n
t
=
’
C
u
s
t
o
m
e
r
s
-
D
B
r
e
p
l
i
c
a
t
i
o
n
s
e
t
’
)
;
-
30
e
c
h
o
’
A
d
d
i
n
g
t
a
b
l
e
s
t
o
t
h
e
s
u
b
s
c
r
i
p
t
i
o
n
s
e
t
’
;
-
-
e
c
h
o
’
A
d
d
i
n
g
t
a
b
l
e
p
u
b
l
i
c
.
c
u
s
t
o
m
e
r
s
_
s
a
l
e
s
.
.
.
’
;
-
s
e
t
a
d
d
t
a
b
l
e
(
s
e
t
i
d
=
1
,
o
r
i
g
i
n
=
1
,
i
d
=
4
,
f
u
l
l
q
u
a
l
i
f
i
e
d
89
5.5.
Slony-I
-
n
am
e
=
’
p
u
b
l
i
c
.
c
u
s
t
o
m
e
r
s
_
s
a
l
e
s
’
,
c
o
m
m
e
n
t
=
’
T
a
b
l
e
p
u
b
l
i
c
.
c
u
s
t
o
m
e
r
s
_
s
a
l
e
s
’
)
;
35
e
c
h
o
’
d
o
n
e
’
;
-
-
e
c
h
o
’
A
d
d
i
n
g
t
a
b
l
e
p
u
b
l
i
c
.
c
u
s
t
o
m
e
r
s
_
s
o
m
e
t
h
i
n
g
.
.
.
’
;
-
s
e
t
a
d
d
t
a
b
l
e
(
s
e
t
i
d
=
1
,
o
r
i
g
i
n
=
1
,
i
d
=
5
,
f
u
l
l
q
u
a
l
i
f
i
e
d
-
n
am
e
=
’
p
u
b
l
i
c
.
c
u
s
t
o
m
e
r
s
_
s
o
m
e
t
h
i
n
g
,
40
c
o
m
m
e
n
t
=
’
T
a
b
l
e
p
u
b
l
i
c
.
c
u
s
t
o
m
e
r
s
_
s
o
m
e
t
h
i
n
g
)
;
-
e
c
h
o
’
d
o
n
e
’
;
-
-
e
c
h
o
’
d
o
n
e
a
d
d
i
n
g
’
;
-
s
t
o
r
e
n
o
d
e
(
i
d
=
2
,
c
o
m
m
e
n
t
=
’
No
d
e
2
,
$H
O
ST
2
’
)
;
45
e
c
h
o
’
s
t
o
r
e
d
n
o
d
e
’
;
-
s
t
o
r
e
p
a
t
h
(
s
e
r
v
e
r
=
1
,
c
l
i
e
n
t
=
2
,
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
1
h
o
s
t
=
$H
O
ST
1
-
p
o
r
t
=
$
P
O
R
T
1
u
s
e
r
=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
w
o
r
d
’
)
;
-
e
c
h
o
’
s
t
o
r
e
d
p
a
t
h
’
;
-
s
t
o
r
e
p
a
t
h
(
s
e
r
v
e
r
=
2
,
c
l
i
e
n
t
=
1
,
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
2
h
o
s
t
=
$H
O
ST
2
50
p
o
r
t
=
$
PO
R
T
2
u
s
e
r=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
w
o
r
d
’
)
;
-
-
s
t
o
r
e
l
i
s
t
e
n
(
o
r
i
g
i
n
=
1
,
p
r
o
v
i
d
e
r
=
1
,
r
e
c
e
i
v
e
r
=
2
)
;
-
s
t
o
r
e
l
i
s
t
e
n
(
o
r
i
g
i
n
=
2
,
p
r
o
v
i
d
e
r
=
2
,
r
e
c
e
i
v
e
r
=
1
)
;
-
E
O
F
Здесь
инициализируетс
я
кластер,
создаетс
я
replication
set,
включаютс
я
в
него
две
таблицы.
Нужно
перечислить
все
таблицы,
которые
нужно
реп-
лицировать.
Replication
set
запоминается
раз
и
навсег
да.
Чтобы
добавить
узел
в
с
хему
репликации
не
нужно
заново
инициализировать
set.
Если
в
набор
добавляется
или
у
даляетс
я
т
аблица
нужно
переподписать
все
узлы.
Т
о
есть
с
делать
unsubscrib
e
и
subscrib
e
заново.
По
дписываем
slav
e-узел
на
replication
set
Далее
запу
скаем
на
слейве:
Листинг
5.47
Подписываем
slav
e-узел
на
replication
set
Line
1
#
!
/
b
i
n
/
s
h
-
-
C
L
U
S
T
E
R
=c
u
s
t
o
m
e
r
s
_
r
e
p
-
5
D
B
N
A
M
E
1
=c
u
s
t
o
m
e
r
s
-
D
B
N
A
M
E
2
=c
u
s
t
o
m
e
r
s
-
-
H
O
S
T
1
=c
u
s
t
o
m
e
r
s
_
m
a
s
t
e
r
.
com
90
5.5.
Slony-I
-
H
O
S
T
2
=
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
.
com
10
-
P
O
R
T
1=5
4
3
2
-
P
O
R
T
2=5
4
3
2
-
-
S
L
O
N
Y
_
U
S
E
R
=
s
l
o
n
y
15
-
s
l
o
n
i
k
<
<
E
O
F
-
c
l
u
s
t
e
r
n
am
e
=
$
C
L
U
S
T
E
R
;
-
n
o
d
e
1
a
d
m
i
n
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
1
h
o
s
t
=
$H
O
ST
1
-
p
o
r
t
=
$
P
O
R
T
1
u
s
e
r
=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
w
o
r
d
’
;
20
n
o
d
e
2
a
d
m
i
n
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
2
h
o
s
t
=
$
H
OS
T2
-
p
o
r
t
=
$
P
O
R
T
2
u
s
e
r
=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
w
o
r
d
’
;
-
-
e
c
h
o
’
s
u
b
s
c
r
i
b
i
n
g
’
;
-
s
u
b
s
c
r
i
b
e
s
e
t
(
i
d
=
1
,
p
r
o
v
i
d
e
r
=
1
,
r
e
c
e
i
v
e
r
=
2
,
f
o
r
w
a
r
d
=
n
o
)
;
25
-
E
O
F
Ст
арт
репликации
Т
еперь,
на
обоих
узлах
необ
хо
димо
запустить
демона
репликации.
Листинг
5.48
Старт
репликации
Line
1
s
l
o
n
y
@
c
u
s
t
o
m
e
r
s
_
m
a
s
t
e
r
$
s
l
o
n
c
u
s
t
o
m
e
r
s
_
r
e
p
\
-
"
db
n
a
m
e
=c
u
s
t
o
m
e
r
s
u
s
e
r=
s
l
o
n
y
"
и
Листинг
5.49
Старт
репликации
Line
1
s
l
o
n
y
@
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
$
s
l
o
n
c
u
s
t
o
m
e
r
s
_
r
e
p
\
-
"
db
n
a
m
e
=c
u
s
t
o
m
e
r
s
u
s
e
r=
s
l
o
n
y
"
Cлоны
обменяютс
я
сообщениями
и
начнут
переда
чу
данных.
Началь-
ное
наполнение
проис
хо
дит
с
помощью
COPY
команды,
слейв
база
в
это
время
полностью
блокиру
ется.
Общие
зада
чи
Добавление
ещё
о
дного
узла
в
работающую
сх
ему
репликации
Требу
ется
выполнить
5.5
и
5.5
этапы.
Новый
узел
имеет
id
=
3.
Нахо-
дитс
я
на
хосте
customers_slav
e3.com
,
«видит»
мастер-сервер
по
сети
и
ма-
стер
мо
жет
подключитьс
я
к
его
P
ostgreSQL.
После
дублирования
струк-
туры
(п
5.5
.2)
делаетс
я
следующее:
91
5.5.
Slony-I
Листинг
5.50
Общие
задачи
Line
1
s
l
o
n
i
k
<
<
E
O
F
-
c
l
u
s
t
e
r
n
am
e
=
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
;
-
n
o
d
e
3
a
d
m
i
n
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=c
u
s
t
o
m
e
r
s
h
o
s
t
=
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
3
.
co
m
-
p
o
r
t
=
5
4
3
2
u
s
e
r
=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
’
;
5
u
n
i
n
s
t
a
l
l
n
o
d
e
(
i
d
=
3
)
;
-
e
c
h
o
’
o
k
a
y
’
;
-
E
O
F
Это
нужно
чтобы
у
далить
сх
ему
,
триггеры
и
процедуры,
к
оторые
были
с
дублированы
вместе
с
таблицами
и
структурой
БД.
Инициализировать
кластер
не
надо.
Вместо
этого
записываем
информацию
о
новом
узле
в
сети:
Листинг
5.51
Общие
задачи
Line
1
#
!
/
b
i
n
/
s
h
-
-
C
L
U
S
T
E
R
=c
u
s
t
o
m
e
r
s
_
r
e
p
-
5
D
B
N
A
M
E
1
=c
u
s
t
o
m
e
r
s
-
D
B
N
A
M
E
3
=c
u
s
t
o
m
e
r
s
-
-
H
O
S
T
1
=c
u
s
t
o
m
e
r
s
_
m
a
s
t
e
r
.
com
-
H
O
S
T
3
=
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
3
.
com
10
-
P
O
R
T
1=5
4
3
2
-
P
O
R
T
2=5
4
3
2
-
-
S
L
O
N
Y
_
U
S
E
R
=
s
l
o
n
y
15
-
s
l
o
n
i
k
<
<
E
O
F
-
c
l
u
s
t
e
r
n
am
e
=
$
C
L
U
S
T
E
R
;
-
n
o
d
e
1
a
d
m
i
n
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
1
h
o
s
t
=
$H
O
ST
1
-
p
o
r
t
=
$
P
O
R
T
1
u
s
e
r
=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
’
;
20
n
o
d
e
3
a
d
m
i
n
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
3
-
h
o
s
t=
$H
OS
T
3
p
o
r
t
=
$
P
O
R
T
2
u
s
e
r=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
’
;
-
-
e
c
h
o
’
d
o
n
e
a
d
d
i
n
g
’
;
-
25
s
t
o
r
e
n
o
d
e
(
i
d
=
3
,
c
o
m
m
e
n
t
=
’
No
d
e
3
,
$H
O
ST
3
’
)
;
-
e
c
h
o
’
s
o
r
e
d
n
o
d
e
’
;
-
s
t
o
r
e
p
a
t
h
(
s
e
r
v
e
r
=
1
,
c
l
i
e
n
t
=
3
,
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
1
92
5.5.
Slony-I
-
h
o
s
t=
$H
OS
T
1
p
o
r
t
=
$
P
O
R
T
1
u
s
e
r=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
’
)
;
-
e
c
h
o
’
s
t
o
r
e
d
p
a
t
h
’
;
30
s
t
o
r
e
p
a
t
h
(
s
e
r
v
e
r
=
3
,
c
l
i
e
n
t
=
1
,
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
3
-
h
o
s
t=
$H
OS
T
3
p
o
r
t
=
$
P
O
R
T
2
u
s
e
r=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
’
)
;
-
-
e
c
h
o
’
a
g
a
i
n
’
;
-
s
t
o
r
e
l
i
s
t
e
n
(
o
r
i
g
i
n
=
1
,
p
r
o
v
i
d
e
r
=
1
,
r
e
c
e
i
v
e
r
=
3
)
;
35
s
t
o
r
e
l
i
s
t
e
n
(
o
r
i
g
i
n
=
3
,
p
r
o
v
i
d
e
r
=
3
,
r
e
c
e
i
v
e
r
=
1
)
;
-
-
E
O
F
Новый
узел
имеет
id
3,
потому
что
2
уж
е
работ
ает
.
По
дписываем
новый
узел
3
на
replication
set:
Листинг
5.52
Общие
задачи
Line
1
#
!
/
b
i
n
/
s
h
-
-
C
L
U
S
T
E
R
=c
u
s
t
o
m
e
r
s
_
r
e
p
-
5
D
B
N
A
M
E
1
=c
u
s
t
o
m
e
r
s
-
D
B
N
A
M
E
3
=c
u
s
t
o
m
e
r
s
-
-
H
O
S
T
1
=c
u
s
t
o
m
e
r
s
_
m
a
s
t
e
r
.
com
-
H
O
S
T
3
=
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
3
.
com
10
-
P
O
R
T
1=5
4
3
2
-
P
O
R
T
2=5
4
3
2
-
-
S
L
O
N
Y
_
U
S
E
R
=
s
l
o
n
y
15
-
s
l
o
n
i
k
<
<
E
O
F
-
c
l
u
s
t
e
r
n
am
e
=
$
C
L
U
S
T
E
R
;
-
n
o
d
e
1
a
d
m
i
n
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
1
h
o
s
t
=
$H
O
ST
1
-
p
o
r
t
=
$
P
O
R
T
1
u
s
e
r
=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
’
;
20
n
o
d
e
3
a
d
m
i
n
c
o
n
n
i
n
f
o
=
’
db
n
a
m
e
=
$
D
B
N
A
M
E
3
h
o
s
t
=
$
H
OS
T3
-
p
o
r
t
=
$
P
O
R
T
2
u
s
e
r
=
s
l
o
n
y
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
’
;
-
-
e
c
h
o
’
s
u
b
s
c
r
i
b
i
n
g
’
;
-
s
u
b
s
c
r
i
b
e
s
e
t
(
i
d
=
1
,
p
r
o
v
i
d
e
r
=
1
,
r
e
c
e
i
v
e
r
=
3
,
f
o
r
w
a
r
d
=
n
o
)
;
25
-
E
O
F
93
5.5.
Slony-I
Т
еперь
запуск
аем
slon
на
новом
узле,
т
ак
ж
е
как
и
на
ост
альных.
Пе-
резапу
скать
slon
на
мастере
не
надо.
Листинг
5.53
Общие
задачи
Line
1
s
l
o
n
y
@
c
u
s
t
o
m
e
r
s
_
s
l
a
v
e
3
$
s
l
o
n
c
u
s
t
o
m
e
r
s
_
r
e
p
\
-
"
db
n
a
m
e
=c
u
s
t
o
m
e
r
s
u
s
e
r=
s
l
o
n
y
"
Р
епликация
должна
начатьс
я
как
обычно.
У
странение
неисправностей
Ошибк
а
при
добавлении
узла
в
систему
репликации
Перио
дически,
при
добавлении
новой
машины
в
кластер
возникает
сле-
дующая
ошибка:
на
новой
ноде
всё
начинает
жужж
ать
и
работ
ать,
имею-
щиес
я
же
отваливаются
с
примерно
следующей
диагностикой:
Листинг
5.54
У
странение
неисправностей
Line
1
%s
l
o
n
c
u
s
t
o
m
e
r
s
_
r
e
p
"
db
n
a
m
e
=c
u
s
t
o
m
e
r
s
u
s
e
r
=s
l
o
n
y
_
u
s
e
r
"
-
C
O
N
F
I
G
m
a
i
n
:
s
l
o
n
v
e
r
s
i
o
n
1
.
0
.
5
s
t
a
r
t
i
n
g
u
p
-
C
O
N
F
I
G
m
a
i
n
:
l
o
c
a
l
n
o
d
e
i
d
=
3
-
C
O
N
F
I
G
m
a
i
n
:
l
o
a
d
i
n
g
c
u
r
r
e
n
t
c
l
u
s
t
e
r
c
o
n
f
i
g
u
r
a
t
i
o
n
5
C
O
N
F
I
G
s
t
o
r
e
N
o
d
e
:
n
o
_
i
d
=
1
no
_
co
mm
e
nt
=
’
C
u
s
t
o
m
e
r
s
D
B
-
r
e
p
l
i
c
a
t
i
o
n
c
l
u
s
t
e
r
’
-
C
O
N
F
I
G
s
t
o
r
e
N
o
d
e
:
n
o
_
i
d
=
2
no
_
co
mm
e
nt
=
’
N
o
d
e
2
,
-
n
o
d
e
2
.
e
x
a
m
p
l
e
.
co
m
’
-
C
O
N
F
I
G
s
t
o
r
e
N
o
d
e
:
n
o
_
i
d
=
4
no
_
co
mm
e
nt
=
’
N
o
d
e
4
,
10
n
o
d
e
4
.
e
x
a
m
p
l
e
.
com
’
-
C
O
N
F
I
G
s
t
o
r
e
P
a
t
h
:
p
a
_
s
e
r
v
e
r
=
1
p
a
_
c
l
i
e
n
t
=3
-
p
a
_
c
o
n
n
i
n
f
o=
"
d
b
n
am
e
=c
u
s
t
o
m
e
r
s
-
h
o
s
t=m
a
i
n
h
o
s
t
.
com
p
o
r
t
=
5
4
3
2
u
s
e
r=
s
l
o
n
y
_
u
s
e
r
-
p
a
s
s
w
o
r
d=
s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
"
p
a
_
c
o
n
n
r
e
t
r
y
=1
0
15
C
O
N
F
I
G
s
t
o
r
e
L
i
s
t
e
n
:
l
i
_
o
r
i
g
i
n
=1
l
i
_
r
e
c
e
i
v
e
r
=
3
-
l
i
_
p
r
o
v
i
d
e
r
=1
-
C
O
N
F
I
G
s
t
o
r
e
S
e
t
:
s
e
t
_
i
d
=1
s
e
t
_
o
r
i
g
i
n
=1
-
s
e
t
_
c
o
m
m
e
n
t
=
’
C
u
s
t
o
m
e
r
s
D
B
r
e
p
l
i
c
a
t
i
o
n
s
e
t
’
-
W
A
R
N
r
e
m
o
t
e
W
o
r
k
e
r
_
w
a
k
e
u
p
:
n
o
d
e
1
-
n
o
w
o
r
k
e
r
t
h
r
e
a
d
20
C
O
N
F
I
G
s
t
o
r
e
S
u
b
s
c
r
i
b
e
:
s
u
b
_
s
e
t
=1
s
u
b
_
p
r
o
v
i
d
e
r
=
1
s
u
b
_
f
o
r
w
a
r
d=
’
f
’
-
W
A
R
N
r
e
m
o
t
e
W
o
r
k
e
r
_
w
a
k
e
u
p
:
n
o
d
e
1
-
n
o
w
o
r
k
e
r
t
h
r
e
a
d
-
C
O
N
F
I
G
e
n
a
b
l
e
S
u
b
s
c
r
i
p
t
i
o
n
:
s
u
b
_
s
e
t
=1
-
W
A
R
N
r
e
m
o
t
e
W
o
r
k
e
r
_
w
a
k
e
u
p
:
n
o
d
e
1
-
n
o
w
o
r
k
e
r
t
h
r
e
a
d
-
C
O
N
F
I
G
m
a
i
n
:
c
o
n
f
i
g
u
r
a
t
i
o
n
c
o
m
p
l
e
t
e
-
s
t
a
r
t
i
n
g
t
h
r
e
a
d
s
25
C
O
N
F
I
G
e
n
a
b
l
e
N
o
d
e
:
n
o
_
i
d
=
1
-
C
O
N
F
I
G
e
n
a
b
l
e
N
o
d
e
:
n
o
_
i
d
=
2
-
C
O
N
F
I
G
e
n
a
b
l
e
N
o
d
e
:
n
o
_
i
d
=
4
94
5.5.
Slony-I
-
E
R
R
O
R
r
e
m
o
t
e
W
o
r
k
e
r
T
h
r
e
a
d
_
1
:
"
b
e
g
i
n
t
r
a
n
s
a
c
t
i
o
n
;
s
e
t
-
t
r
a
n
s
a
c
t
i
o
n
i
s
o
l
a
t
i
o
n
l
e
v
e
l
30
s
e
r
i
a
l
i
z
a
b
l
e
;
l
o
c
k
t
a
b
l
e
"
_
c
u
s
t
o
m
e
r
s
_
r
e
p
"
.
s
l
_
c
o
n
f
i
g
_
l
o
c
k
;
s
e
l
e
c
t
-
"
_
c
u
s
t
o
m
e
r
s
_
r
e
p
"
.
e
n
a
b
l
e
S
u
b
s
c
r
i
p
t
i
o
n
(
1
,
1
,
4
)
;
-
n
o
t
i
f
y
"
_
c
u
s
t
o
m
e
r
s
_
r
e
p
_
E
v
e
n
t
"
;
n
o
t
i
f
y
"
_
c
u
s
t
o
m
e
r
s
_
r
e
p
_
C
o
n
f
i
r
m
"
;
-
i
n
s
e
r
t
i
n
t
o
"
_
c
u
s
t
o
m
e
r
s
_
r
e
p
"
.
s
l
_
e
v
e
n
t
(
e
v
_
o
r
i
g
i
n
,
e
v
_
s
e
q
n
o
,
-
e
v
_
t
i
m
e
s
t
a
m
p
,
e
v
_
m
i
n
x
i
d
,
e
v
_
m
a
x
x
i
d
,
e
v
_
x
i
p
,
35
e
v
_
t
y
p
e
,
e
v
_
d
a
t
a
1
,
e
v
_
d
a
t
a
2
,
e
v
_
d
a
t
a
3
,
e
v
_
d
a
t
a
4
)
v
a
l
u
e
s
-
(
’
1
’
,
’
2
1
9
4
4
0
’
,
-
’
2
0
0
5
-
0
5
-
0
5
1
8
:
5
2
:
4
2
.
7
0
8
3
5
1
’
,
’
5
2
5
0
1
2
8
3
’
,
’
5
2
5
0
1
2
9
2
’
,
-
’
’
’
5
2
5
0
1
2
8
3
’
’
’
,
’
E
N
A
B
L
E
_
S
U
B
S
C
R
I
P
T
I
O
N
’
,
-
’
1
’
,
’
1
’
,
’
4
’
,
’
f
’
)
;
i
n
s
e
r
t
i
n
t
o
"
_
c
u
s
t
o
m
e
r
s
_
r
e
p
"
.
40
s
l
_
c
o
n
f
i
r
m
(
c
o
n
_
o
r
i
g
i
n
,
c
o
n
_
r
e
c
e
i
v
e
d
,
-
c
o
n
_
s
e
q
n
o
,
c
o
n
_
t
i
m
e
s
t
a
m
p
)
v
a
l
u
e
s
(
1
,
3
,
’
2
1
9
4
4
0
’
,
-
C
U
R
R
E
N
T
_
T
I
M
E
S
T
A
M
P)
;
c
o
m
m
i
t
t
r
a
n
s
a
c
t
i
o
n
;
"
-
P
G
R
E
S
_
F
A
T
A
L
_
E
R
R
O
R
E
R
R
O
R
:
i
n
s
e
r
t
o
r
u
p
d
a
t
e
o
n
t
a
b
l
e
-
"
s
l
_
s
u
b
s
c
r
i
b
e
"
v
i
o
l
a
t
e
s
f
o
r
e
i
g
n
k
e
y
45
c
o
n
s
t
r
a
i
n
t
"
s
l
_
s
u
b
s
c
r
i
b
e
-
s
l
_
p
a
t
h
-
r
e
f
"
-
D
ET
A
I
L
:
K
ey
(
s
u
b
_
p
r
o
v
i
d
e
r
,
s
u
b
_
r
e
c
e
i
v
e
r
)
=
(
1
,
4
)
-
i
s
n
o
t
p
r
e
s
e
n
t
i
n
t
a
b
l
e
"
s
l
_
p
a
t
h
"
.
-
IN
F
O
r
e
m
o
t
e
L
i
s
t
e
n
T
h
r
e
a
d
_
1
:
d
i
s
c
o
n
n
e
c
t
i
n
g
f
r
o
m
-
’
d
b
n
a
m
e
=c
u
s
t
o
m
e
r
s
h
o
s
t
=m
a
i
n
h
o
s
t
.
com
50
p
o
r
t
=
5
4
3
2
u
s
e
r
=
s
l
o
n
y
_
u
s
e
r
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
’
-
%
Это
означает
что
в
служ
ебной
т
аблице
_имя<
кластера>.sl_path
,
на-
пример
_customers_rep.sl_path
на
уже
имеющихс
я
узлах
отсутству
ет
ин-
формация
о
новом
узле.
В
данном
случае,
id
нового
узла
4,
пара
(1,4)
в
sl_path
отсутствует
.
Чтобы
это
у
странить,
нужно
выполнить
на
к
аждом
из
имеющих
ся
узлов
приблизительно
следующий
запрос:
Листинг
5.55
У
странение
неисправностей
Line
1
$
p
s
q
l
-
d
c
u
s
t
o
m
e
r
s
-
h
_
e
v
e
r
y
_
o
n
e
_
o
f
_
s
l
a
v
e
s
-
U
s
l
o
n
y
-
c
u
s
t
o
m
e
r
s
=
#
i
n
s
e
r
t
i
n
t
o
_
c
u
s
t
o
m
e
r
s
_
r
e
p
.
s
l
_
p
a
t
h
-
v
a
l
u
e
s
(
’
1
’
,
’
4
’
,
’
d
b
n
a
me
=c
u
s
t
o
m
e
r
s
h
o
s
t
=m
a
i
n
h
o
s
t
.
com
-
p
o
r
t
=
5
4
3
2
u
s
e
r
=
s
l
o
n
y
_
u
s
e
r
p
a
s
s
w
o
r
d=s
l
o
n
y
_
u
s
e
r
_
p
a
s
s
w
o
r
d
,
’
1
0
’
)
;
Если
возникают
затру
днения,
то
можно
посмотреть
на
служ
ебные
т
аб-
лицы
и
их
со
дер
жимое.
Они
не
вид
ны
обычно
и
нах
одятс
я
в
рамк
ах
про-
странства
имён
_имя<
кластера>
,
например
_customers_rep
.
95
5.6.
Londiste
Что
делать
если
реплик
ация
со
временем
начинает
тормозить
В
процессе
эк
сплуат
ации
мож
ет
наблю
даться
как
со
временем
растёт
нагрузк
а на
master-сервере,
в списк
е
активных
бек
ендов —
посто
янные
SELECT-ы
со
слейвов.
В
pg_stat_activity
видны
примерно
т
акие
запросы:
Листинг
5.56
У
странение
неисправностей
Line
1
s
e
l
e
c
t
e
v
_
o
r
i
g
i
n
,
e
v
_
s
e
q
n
o
,
e
v
_
t
i
m
e
s
t
a
m
p
,
e
v
_
m
i
n
x
i
d
,
e
v
_
m
a
x
x
i
d
,
e
v
_
x
i
p
,
-
e
v
_
t
y
p
e
,
e
v
_
d
a
t
a
1
,
e
v
_
d
a
t
a
2
,
e
v
_
d
a
t
a
3
,
e
v
_
d
a
t
a
4
,
e
v
_
d
a
t
a
5
,
e
v
_
d
a
t
a
6
,
-
e
v
_
d
a
t
a
7
,
e
v
_
d
a
t
a
8
f
r
o
m
"
_
c
u
s
t
o
m
e
r
s
_
r
e
p
"
.
s
l
_
e
v
e
n
t
e
w
h
e
r
e
-
(
e
.
e
v
_
o
r
i
g
i
n
=
’
2
’
a
n
d
e
.
e
v
_
s
e
q
n
o
>
’
3
3
6
9
9
6
’
)
o
r
5
(
e
.
e
v
_
o
r
i
g
i
n
=
’
3
’
a
n
d
e
.
e
v
_
s
e
q
n
o
>
’
1
7
1
2
8
7
1
’
)
o
r
-
(
e
.
e
v
_
o
r
i
g
i
n
=
’
4
’
a
n
d
e
.
e
v
_
s
e
q
n
o
>
’
7
2
1
2
8
5
’
)
o
r
-
(
e
.
e
v
_
o
r
i
g
i
n
=
’
5
’
a
n
d
e
.
e
v
_
s
e
q
n
o
>
’
8
0
7
7
1
5
’
)
o
r
-
(
e
.
e
v
_
o
r
i
g
i
n
=
’
1
’
a
n
d
e
.
e
v
_
s
e
q
n
o
>
’
3
5
4
4
7
6
3
’
)
o
r
-
(
e
.
e
v
_
o
r
i
g
i
n
=
’
6
’
a
n
d
e
.
e
v
_
s
e
q
n
o
>
’
2
5
2
9
4
4
5
’
)
o
r
10
(
e
.
e
v
_
o
r
i
g
i
n
=
’
7
’
a
n
d
e
.
e
v
_
s
e
q
n
o
>
’
2
5
1
2
5
3
2
’
)
o
r
-
(
e
.
e
v
_
o
r
i
g
i
n
=
’
8
’
a
n
d
e
.
e
v
_
s
e
q
n
o
>
’
2
5
0
0
4
1
8
’
)
o
r
-
(
e
.
e
v
_
o
r
i
g
i
n
=
’
1
0
’
a
n
d
e
.
e
v
_
s
e
q
n
o
>
’
1
6
9
2
3
1
8
’
)
-
o
r
d
e
r
b
y
e
.
e
v
_
o
r
i
g
i
n
,
e
.
e
v
_
s
e
q
n
o
;
г
де
_customers_rep
—
имя
сх
емы
из
примера.
Т
аблица
sl_even
t
почему-
то
разраст
аетс
я
со
временем,
замедляя
выполнение
этих
запросов
до
неприемлемого
времени.
У
даляем
ненужные
записи:
Листинг
5.57
У
странение
неисправностей
Line
1
d
e
l
e
t
e
f
r
o
m
_
c
u
s
t
o
m
e
r
s
_
r
e
p
.
s
l
_
e
v
e
n
t
w
h
e
r
e
-
e
v
_
t
i
m
e
s
t
a
m
p<
N
O
W
(
)
-
’
1
D
A
Y
’
:
:
i
n
t
e
r
v
a
l
;
Произво
дительность
должна
вернуться
к
изначальным
зна
чениям.
Возмо
жно
имеет
смысл
почистить
таблицы
_customers_rep.sl_log_*
г
де
вместо
звёздочки
по
дст
авляются
натуральные
числа,
по-видимому
по
ко-
личеству репликационных сетов, так что
_customers_rep.sl_log_1
точно
должна
существовать.
5.6
Londiste
Londiste
представляет
собой
движок
для
организации
репликации,
на-
писанный
на
языке
Python.
Основные
принцип
ы:
надежность
и
простота
использования.
Из-за
этого
данное
решение
имеет
меньше
функциональ-
ности,
чем
Slony-I.
Londiste
использует
в
ка
честве
транспортного
механиз-
ма
очередь
PgQ
(описание
этого
более
чем
интересного
проекта
ост
аетс
я
за
рамками
данной
г
лавы,
поскольку
он
предст
авляет
интерес
скорее
для
96
5.6.
Londiste
низк
оуровневых
программистов
баз
данных,
чем
для
к
онечных
пользова-
телей
—
администраторов
СУБД
PostgreSQL).
От
личительными
особен-
ност
ями
решения
являются:
∙
возмо
жность
пот
абличной
репликации;
∙
на
чальное
к
опирование
ничего
не
блокирует;
∙
возмо
жность
двух
стороннего
сравнения
таблиц;
∙
простот
а
у
становки;
К
недост
аткам
можно
отнести:
∙
триггерная
реплик
ация,
что
уху
дшает
производительность
базы;
У
становк
а
У
ст
ановка
бу
дет
проводитьс
я
на
Debian
сервере.
Поск
ольку
Londiste
—
это
часть
Skyto
ols,
то
нам
нужно
ставить
этот
пакет:
Листинг
5.58
У
становк
а
Line
1
%
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
s
k
y
t
o
o
l
s
В
нек
оторых
системах
мож
ет
содер
ж
аться
пак
ет
версии
2.x,
кото
рый
не
по
д
дер
живает
каск
адную
репликацию,
отказоу
стойчивость(failo
ver)
и
переключение
между
серверами
(switcho
v
er).
По
этой
причине
он
не
бу-
дет
рассматриваться.
Ск
ачать
самую
последнюю
версию
пакет
а
можно
с
официального
сайта
.
На
момент
написания
г
лавы
последняя
версия
была
3.2.
На
чнем
уст
ановку:
Листинг
5.59
У
становк
а
Line
1
$
w
g
e
t
h
t
t
p
:
/
/
p
g
f
o
u
n
d
r
y
.
o
r
g
/
f
r
s
/
d
o
w
n
l
o
a
d
.
p
h
p
/
3
6
2
2
/
s
k
y
t
o
o
l
s
-
3
.
2
.
t
a
r
.
g
z
-
$
t
a
r
z
x
v
f
s
k
y
t
o
o
l
s
-
3
.
2
.
t
a
r
.
g
z
-
$
c
d
s
k
y
t
o
o
l
s
-
3
.
2
/
-
# пак
еты
для
сборки
d
e
b
5
$
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
b
u
i
l
d
-
e
s
s
e
n
t
i
a
l
a
u
t
o
c
o
n
f
\
-
a
u
t
o
m
a
k
e
a
u
t
o
t
o
o
l
s
-
d
e
v
d
h
-
ma
k
e
\
-
d
e
b
h
e
l
p
e
r
d
e
v
s
c
r
i
p
t
s
f
a
k
e
r
o
o
t
x
u
t
i
l
s
l
i
n
t
i
a
n
p
b
u
i
l
d
e
r
\
-
p
y
t
h
o
n
-
a
l
l
-
d
e
v
p
y
t
h
o
n
-
s
u
p
p
o
r
t
x
m
l
t
o
a
s
c
i
i
d
o
c
\
-
l
i
b
e
v
e
n
t
-
d
e
v
l
i
b
p
q
-
d
e
v
l
i
b
t
o
o
l
10
#
p
y
t
h
o
n
-
p
s
y
c
o
p
g
нуж
ен
для
работы
L
o
n
d
i
s
t
e
-
$
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
p
y
t
h
o
n
-
p
s
y
c
o
p
g
2
p
o
s
t
g
r
e
s
q
l
-
s
e
r
v
e
r
-
d
e
v
-
a
l
l
-
# данной
командой
собираем
d
e
b
пакет
-
$
m
a
ke
d
e
b
-
$
c
d
.
.
/
97
5.6.
Londiste
15
# ст
авим
s
k
y
t
o
o
l
s
-
$
d
p
k
g
-
i
*
.
d
e
b
Для
других
систем
мо
жно
собрать
Skyto
ols
к
омандами:
Листинг
5.60
У
становк
а
Line
1
$
.
/
c
o
n
f
i
g
u
r
e
-
$
m
a
ke
-
$
m
a
ke
i
n
s
t
a
l
l
Далее
провер
яем
правильность
уст
ановки:
Листинг
5.61
У
становк
а
Line
1
$
l
o
n
d
i
s
t
e
3
-
V
-
l
o
n
d
i
s
t
e
3
,
S
k
y
t
o
o
l
s
v
e
r
s
i
o
n
3
.
2
-
$
p
g
q
d
-V
-
b
a
d
s
w
i
t
c
h
:
u
s
a
g
e
:
p
g
q
-
t
i
c
k
e
r
[
s
w
i
t
c
h
e
s
]
c
o
n
f
i
g
.
f
i
l
e
5
S
w
i
t
c
h
e
s
:
-
-
v
I
n
c
r
e
a
s
e
v
e
r
b
o
s
i
t
y
-
-
q
No
o
u
t
p
u
t
t
o
c
o
n
s
o
l
e
-
-
d
D
a
e
m
o
n
i
z
e
-
-
h
Sh
ow
h
e
l
p
10
-V
Sh
ow
v
e
r
s
i
o
n
-
-
-
i
n
i
Sh
ow
s
a
m
p
l
e
c
o
n
f
i
g
f
i
l
e
-
-
s
S
t
o
p
-
s
e
n
d
SIG
IN
T
t
o
r
u
n
n
i
n
g
p
r
o
c
e
s
s
-
-
k
K
i
l
l
-
s
e
n
d
S
I
G
T
E
R
M
t
o
r
u
n
n
i
n
g
p
r
o
c
e
s
s
-
-
r
R
e
l
o
a
d
-
s
e
n
d
S
I
GH
U
P
t
o
r
u
n
n
i
n
g
p
r
o
c
e
s
s
Настройк
а
Обозна
чения:
∙
master-host
—
мастер
база
данных;
∙
slav
e1
-
host
,
sla
ve2
-
host
,
sla
ve3
-
host
,
slav
e4
-
host
—
слейв
базы
данных;
∙
l3simple
—
название
реплицируемой
базы
данных;
Конфигурация
реплик
аторов
Сна
чала
создается
к
онфигурационный
файл
для
master
базы
(к
онфиг
бу
дет
/
etc/skyto
ols/master-londiste
.
ini
):
Листинг
5.62
Конфигурация
репликаторов
Line
1
[
l
o
n
d
i
s
t
e
3
]
-
j
o
b
_
n
a
m
e
=
m
a
s
t
e
r
_
l
3
s
i
m
p
l
e
-
d
b
=
d
b
n
a
m
e
=
l
3
s
i
m
p
l
e
98
5.6.
Londiste
-
q
u
e
u
e
_
n
a
m
e
=
r
e
p
l
i
k
a
5
l
o
g
f
i
l
e
=
/
v
a
r
/
l
o
g
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
_
l
3
s
i
m
p
l
e
.
l
o
g
-
p
i
d
f
i
l
e
=
/
v
a
r
/
p
i
d
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
_
l
3
s
i
m
p
l
e
.
p
i
d
-
-
# Задер
жка
между
проверками
наличия
активности
-
# новых
(
пакетов
данных
)
в
секундах
10
l
o
o
p
_
d
e
l
a
y
=
0
.
5
Инициализиру
ем
Londiste
для
master
базы:
Листинг
5.63
Инициализируем
Londiste
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
c
r
e
a
t
e
-
r
o
o
t
m
a
s
t
e
r
-
n
o
d
e
"
db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t
=m
a
s
t
e
r
-
h
o
s
t
"
-
IN
F
O
p
l
p
g
s
q
l
i
s
i
n
s
t
a
l
l
e
d
-
IN
F
O
I
n
s
t
a
l
l
i
n
g
p
g
q
-
IN
F
O
R
e
a
d
i
n
g
f
r
o
m
/
u
s
r
/
s
h
a
r
e
/
s
k
y
t
o
o
l
s
3
/
p
g
q
.
s
q
l
5
IN
F
O
p
g
q
.
g
e
t
_
b
a
t
c
h
_
c
u
r
s
o
r
i
s
i
n
s
t
a
l
l
e
d
-
IN
F
O
I
n
s
t
a
l
l
i
n
g
p
g
q
_
e
x
t
-
IN
F
O
R
e
a
d
i
n
g
f
r
o
m
/
u
s
r
/
s
h
a
r
e
/
s
k
y
t
o
o
l
s
3
/
p
g
q
_
e
x
t
.
s
q
l
-
IN
F
O
I
n
s
t
a
l
l
i
n
g
p
g
q
_
n
o
d
e
-
IN
F
O
R
e
a
d
i
n
g
f
r
o
m
/
u
s
r
/
s
h
a
r
e
/
s
k
y
t
o
o
l
s
3
/
p
g
q
_
n
o
d
e
.
s
q
l
10
IN
F
O
I
n
s
t
a
l
l
i
n
g
l
o
n
d
i
s
t
e
-
IN
F
O
R
e
a
d
i
n
g
f
r
o
m
/
u
s
r
/
s
h
a
r
e
/
s
k
y
t
o
o
l
s
3
/
l
o
n
d
i
s
t
e
.
s
q
l
-
IN
F
O
l
o
n
d
i
s
t
e
.
g
l
o
b
a
l
_
a
d
d
_
t
a
b
l
e
i
s
i
n
s
t
a
l
l
e
d
-
IN
F
O
I
n
i
t
i
a
l
i
z
i
n
g
n
o
d
e
-
IN
F
O
L
o
c
a
t
i
o
n
r
e
g
i
s
t
e
r
e
d
15
IN
F
O
N
o
d
e
"
m
a
s
t
e
r
-
n
o
d
e
"
i
n
i
t
i
a
l
i
z
e
d
f
o
r
q
u
e
u
e
"
r
e
p
l
i
k
a
"
w
i
t
h
t
y
p
e
"
r
o
o
t
"
-
IN
F
O
D
o
n
e
г
де
master-server
—
это
имя
провайдера
(мастера
базы).
Т
еперь
запу
стим
демон:
Листинг
5.64
Запуск
аем
демон
для
master
базы
Line
1
$
l
o
n
d
i
s
t
e
3
-
d
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
w
o
r
k
e
r
-
$
t
a
i
l
-
f
/
v
a
r
/
l
o
g
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
_
l
3
s
i
m
p
l
e
.
l
o
g
-
IN
F
O
{
s
t
a
n
d
b
y
:
1
}
-
IN
F
O
{
s
t
a
n
d
b
y
:
1
}
Если
нужно
перегрузить
демон
(например
при
изменении
конфигура-
ции),
то
мо
жно
воспользоваться
параметром
-
r
:
Листинг
5.65
Перегрузка
демона
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
-
r
Для
ост
ановки
демона
есть
параметр
-
s
:
99
5.6.
Londiste
Листинг
5.66
Остановк
а
демона
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
-
s
или
если
потребу
ется
«убить»
(
kill
)
демон:
Листинг
5.67
Остановк
а
демона
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
-
k
Для
автоматизации
данного
процесса
skyto
ols3
имеет
встроенный
де-
мон,
к
оторый
запу
скает
все
ворк
еры
из
директории
/
etc/skyto
ols/
.
Сама
к
онфигурация
демона
нахо
дитс
я
в
/
etc/skyto
ols
.
ini
.
Что
бы
запустить
все
демоны
londiste
дост
аточно
выполнить:
Листинг
5.68
Демон
для
tick
er
Line
1
$
/
e
t
c
/
i
n
i
t
.
d
/
s
k
y
t
o
o
l
s
3
s
t
a
r
t
-
IN
F
O
S
t
a
r
t
i
n
g
m
a
s
t
e
r
_
l
3
s
i
m
p
l
e
Перейдем
к
sla
ve
базе.
Для
начала
нужно
создать
базу
данных:
Листинг
5.69
Копирования
структуры
базы
Line
1
$
p
s
q
l
-
h
s
l
a
v
e
1
-
h
o
s
t
-
U
p
o
s
t
g
r
e
s
-
#
C
R
E
A
T
E
D
A
T
A
B
A
S
E
l
3
s
i
m
p
l
e
;
По
дключение
должно
быть
«trust»
(без
паролей)
между
master
и
slav
e
базами
данных.
Далее
создадим
конфиг
для
sla
ve
базы
(
/etc
/skyto
ols/
sla
ve1
-
londiste
.
ini
):
Листинг
5.70
Создаём
конфигурацию
для
slav
e
Line
1
[
l
o
n
d
i
s
t
e
3
]
-
j
o
b
_
n
a
m
e
=
s
l
a
v
e
1
_
l
3
s
i
m
p
l
e
-
d
b
=
d
b
n
a
m
e
=
l
3
s
i
m
p
l
e
-
q
u
e
u
e
_
n
a
m
e
=
r
e
p
l
i
k
a
5
l
o
g
f
i
l
e
=
/
v
a
r
/
l
o
g
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
1
_
l
3
s
i
m
p
l
e
.
l
o
g
-
p
i
d
f
i
l
e
=
/
v
a
r
/
p
i
d
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
1
_
l
3
s
i
m
p
l
e
.
p
i
d
-
-
# Задер
жка
между
проверками
наличия
активности
-
# новых
(
пакетов
данных
)
в
секундах
10
l
o
o
p
_
d
e
l
a
y
=
0
.
5
Инициализиру
ем
Londiste
для
slav
e
базы:
Листинг
5.71
Инициализируем
Londiste
для
slav
e
100
5.6.
Londiste
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
1
-
l
o
n
d
i
s
t
e
.
i
n
i
c
r
e
a
t
e
-
l
e
a
f
s
l
a
v
e
1
-
n
o
d
e
"
db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t
=
s
l
a
v
e
1
-
h
o
s
t
"
-
-
p
r
o
v
i
d
e
r
=
"db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t=m
a
s
t
e
r
-
h
o
s
t
"
Т
еперь
мо
жем
запустить
демон:
Листинг
5.72
Запуск
аем
демон
для
slav
e
базы
Line
1
$
l
o
n
d
i
s
t
e
3
-
d
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
1
-
l
o
n
d
i
s
t
e
.
i
n
i
w
o
r
k
e
r
Или
ж
е
через
главный
демон:
Листинг
5.73
Запуск
аем
демон
для
slav
e
базы
Line
1
$
/
e
t
c
/
i
n
i
t
.
d
/
s
k
y
t
o
o
l
s
3
s
t
a
r
t
-
IN
F
O
S
t
a
r
t
i
n
g
m
a
s
t
e
r
_
l
3
s
i
m
p
l
e
-
IN
F
O
S
t
a
r
t
i
n
g
s
l
a
v
e
1
_
l
3
s
i
m
p
l
e
Создаём
к
онфигурацию
для
PgQ
tick
er
Londiste
требу
ется
PgQ
tick
er
для
работы
с
мастер
базой
данных,
ко-
торый
мож
ет
быть
запущен
и
на
другой
машине.
Но,
конечно,
лучше
его
запу
скать
на
той
ж
е,
где
и
master
база
данных.
Для
этого
мы
настраиваем
специальный
конфиг
для
tick
er
демона
(конфиг
бу
дет
/
etc/
skyto
ols/pgqd.ini
):
Листинг
5.74
PgQ
tick
er
конфиг
Line
1
[
p
g
q
d
]
-
l
o
g
f
i
l
e
=
/
v
a
r
/
l
o
g
/
s
k
y
t
o
o
l
s
/
p
g
q
d
.
l
o
g
-
p
i
d
f
i
l
e
=
/
v
a
r
/
p
i
d
/
s
k
y
t
o
o
l
s
/
p
g
q
d
.
p
i
d
Запу
скаем
демон:
Листинг
5.75
Запуск
аем
PgQ
tick
er
Line
1
$
p
g
q
d
-
d
/
e
t
c
/
s
k
y
t
o
o
l
s
/
p
g
q
d
.
i
n
i
-
$
t
a
i
l
-
f
/
v
a
r
/
l
o
g
/
s
k
y
t
o
o
l
s
/
p
g
q
d
.
l
o
g
-
L
O
G
S
t
a
r
t
i
n
g
p
g
q
d
3
.
2
-
L
O
G
a
u
t
o
-
d
e
t
e
c
t
i
n
g
d
b
s
.
.
.
5
L
O
G
l
3
s
i
m
p
l
e
:
p
g
q
v
e
r
s
i
o
n
o
k
:
3
.
2
Или
ж
е
через
глобальный
демон:
Листинг
5.76
Запуск
аем
PgQ
tick
er
Line
1
$
/
e
t
c
/
i
n
i
t
.
d
/
s
k
y
t
o
o
l
s
3
r
e
s
t
a
r
t
-
IN
F
O
S
t
a
r
t
i
n
g
m
a
s
t
e
r
_
l
3
s
i
m
p
l
e
101
5.6.
Londiste
-
IN
F
O
S
t
a
r
t
i
n
g
s
l
a
v
e
1
_
l
3
s
i
m
p
l
e
-
IN
F
O
S
t
a
r
t
i
n
g
p
g
q
d
5
L
O
G
S
t
a
r
t
i
n
g
p
g
q
d
3
.
2
Т
еперь
мо
жно
увидеть
стату
с
кластера:
Листинг
5.77
Стату
с
кластера
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
s
t
a
t
u
s
-
Q
u
e
u
e
:
r
e
p
l
i
k
a
L
o
c
a
l
n
o
d
e
:
s
l
a
v
e
1
-
n
o
d
e
-
-
m
a
s
t
e
r
-
n
o
d
e
(
r
o
o
t
)
5
|
T
a
b
l
e
s
:
0
/
0
/
0
-
|
L
a
g
:
4
4
s
,
T
i
c
k
:
5
-
+
-
-
:
s
l
a
v
e
1
-
n
o
d
e
(
l
e
a
f
)
-
T
a
b
l
e
s
:
0
/
0
/
0
-
L
a
g
:
4
4
s
,
T
i
c
k
:
5
10
-
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
m
e
m
b
e
r
s
-
Member
i
n
f
o
o
n
m
a
s
t
e
r
-
n
o
d
e
@
r
e
p
l
i
k
a
:
-
n
o
d
e_
n
a
m
e
d
e
a
d
n
o
d
e
_
l
o
c
a
t
i
o
n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
15
m
a
s
t
e
r
-
n
o
d
e
F
a
l
s
e
db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t=
m
a
s
t
e
r
-
h
o
s
t
-
s
l
a
v
e
1
-
n
o
d
e
F
a
l
s
e
db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t
=
s
l
a
v
e
1
-
h
o
s
t
Но
реплик
ация
еще
не
запущенна:
требуетс
я
добавить
таблицы
в
оче-
редь,
к
оторые
мы
хотим
репли
цировать.
Для
этого
использу
ем
команду
add
-
table
:
Листинг
5.78
Добавляем
таблицы
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
a
d
d
-
t
a
b
l
e
-
-
a
l
l
-
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
1
-
l
o
n
d
i
s
t
e
.
i
n
i
a
d
d
-
t
a
b
l
e
-
-
a
l
l
-
-
c
r
e
a
t
e
-
f
u
l
l
В
данном
примере
используетс
я
параметр
--
all
,
который
озна
чает
все
т
аблицы,
но
вместо
него
вы
мож
ете
перечислить
список
к
онкретных
таб-
лиц,
если
не
х
отите
реплицировать
все.
Если
имена
т
аблиц
отличаютс
я
на
master
и
sla
v
e,
то
мо
жно
использовать
--
dest
-
table
параметр
при
добавле-
нии
т
аблиц
на
slav
e
базе.
Т
акже,
если
вы
не
перенесли
структуру
т
аблиц
заранее
с
master
на
slav
e
базы,
то
это
можно
с
делать
автоматически
через
--
create
параметр
(или
--
create
-
full
,
если
нужно
перенести
полностью
всю
с
хему
таблицы).
102
5.6.
Londiste
По
добным
образом
добавляем
последовательности
(
sequences
)
для
ре-
плик
ации:
Листинг
5.79
Добавляем
последовательности
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
a
d
d
-
s
e
q
-
-
a
l
l
-
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
1
-
l
o
n
d
i
s
t
e
.
i
n
i
a
d
d
-
s
e
q
-
-
a
l
l
Но
последовательности
должны
на
slav
e
базе
созданы
заранее
(тут
не
помо
жет
--
create
-
full
для
таблиц).
Поэтому
иног
да
проще
перенести
точ-
ную
к
опию
структуры
master
базы
на
slav
e:
Листинг
5.80
Клонирование
структуры
базы
Line
1
$
p
g_d
ump
-
s
-
n
p
u
b
l
i
c
l
3
s
i
m
p
l
e
|
p
s
q
l
-
h
s
l
a
v
e
1
-
h
o
s
t
l
3
s
i
m
p
l
e
Далее
провер
яем
состояние
репликации:
Листинг
5.81
Стату
с
кластера
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
s
t
a
t
u
s
-
Q
u
e
u
e
:
r
e
p
l
i
k
a
L
o
c
a
l
n
o
d
e
:
m
a
s
t
e
r
-
n
o
d
e
-
-
m
a
s
t
e
r
-
n
o
d
e
(
r
o
o
t
)
5
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
1
8
s
,
T
i
c
k
:
1
2
-
+
-
-
:
s
l
a
v
e
1
-
n
o
d
e
(
l
e
a
f
)
-
T
a
b
l
e
s
:
0
/
4
/
0
-
L
a
g
:
1
8
s
,
T
i
c
k
:
1
2
Как
мо
жно
заметить,
возле
«T
able»
содер
жится
три
цифры
(x/y/z).
Каждая
обозна
чает:
∙
x
-
к
оличество
таблиц
в
состоянии
«ok»
(replicated).
На
master
базе
ук
азывает
,
что
она
в
норме,
а
на
slav
e
базах
-
т
аблица
синхронизи-
рована
с
master
базой;
∙
y
-
количество
таблиц
в
состо
янии
half
(initial
copy
,
not
finnished),
у
master
должно
быть
0,
а
у
slav
e
базах
это
ук
азывает
к
оличество
т
аблиц
в
процессе
копирования;
∙
z
-
количество
т
аблиц
в
состо
янии
ignored
(table
not
replicated
lo
cally),
у
master
должно
быть
0,
а
у
slav
e
базах
это
количество
таблиц,
к
ото-
рые
не
добавлены
для
реплик
ации
с
мастера
(т
.
е.
master
от
дает
на
реплик
ацию
эту
таблицу
,
но
slav
e
их
просто
не
забирает).
Через
небольшой
интервал
времени
все
таблицы
должны
синхронизи-
роватьс
я:
103
5.6.
Londiste
Листинг
5.82
Стату
с
кластера
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
s
t
a
t
u
s
-
Q
u
e
u
e
:
r
e
p
l
i
k
a
L
o
c
a
l
n
o
d
e
:
m
a
s
t
e
r
-
n
o
d
e
-
-
m
a
s
t
e
r
-
n
o
d
e
(
r
o
o
t
)
5
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
3
1
s
,
T
i
c
k
:
2
0
-
+
-
-
:
s
l
a
v
e
1
-
n
o
d
e
(
l
e
a
f
)
-
T
a
b
l
e
s
:
4
/
0
/
0
-
L
a
g
:
3
1
s
,
T
i
c
k
:
2
0
Дополнительно
Londiste
позволяет
просмотреть
состояние
таблиц
и
по-
следовательностей
на
master
и
sla
ve
базах:
Листинг
5.83
Стату
с
т
аблиц
и
последовательностей
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
t
a
b
l
e
s
-
T
a
b
l
e
s
o
n
n
o
d
e
-
t
a
b
l
e
_
n
a
m
e
m
e
r
g
e
_
s
t
a
t
e
t
a
b
l
e
_
a
t
t
r
s
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
5
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
a
c
c
o
u
n
t
s
o
k
-
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
b
r
a
n
c
h
e
s
o
k
-
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
o
k
-
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
t
e
l
l
e
r
s
o
k
-
10
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
m
a
s
t
e
r
-
l
o
n
d
i
s
t
e
.
i
n
i
s
e
q
s
-
S
e
q
u
e
n
c
e
s
o
n
n
o
d
e
-
s
e
q
_
n
a
m
e
l
o
c
a
l
l
a
s
t
_
v
a
l
u
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
_
h
i
d
_
s
e
q
T
r
u
e
3
3
3
4
5
Проверк
а
Для
проверки
бу
дем
использовать
pgb
ench
утилиту
.
Запустим
добавле-
ние
данных
в
т
аблицу
и
смотрим
в
логи
одновременно:
Листинг
5.84
Проверка
Line
1
$
p
g
b
e
n
c
h
-
T
1
0
-
c
5
l
3
s
i
m
p
l
e
-
$
t
a
i
l
-
f
/
v
a
r
/
l
o
g
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
1
_
l
3
s
i
m
p
l
e
.
l
o
g
-
IN
F
O
{
c
o
u
n
t
:
1
5
0
8
,
d
u
r
a
t
i
o
n
:
0
.
3
0
7
,
i
d
l
e
:
0
.
0
0
2
6
}
-
IN
F
O
{
c
o
u
n
t
:
1
5
7
2
,
d
u
r
a
t
i
o
n
:
0
.
3
0
8
5
,
i
d
l
e
:
0
.
0
0
2
}
5
IN
F
O
{
c
o
u
n
t
:
1
6
0
0
,
d
u
r
a
t
i
o
n
:
0
.
3
0
8
6
,
i
d
l
e
:
0
.
0
0
2
6
}
-
IN
F
O
{
c
o
u
n
t
:
3
6
,
d
u
r
a
t
i
o
n
:
0
.
0
1
5
7
,
i
d
l
e
:
2
.
0
1
9
1
}
Как
видно
по
лог
ам
slav
e
база
успешно
реплицируетс
я
с
master
базой.
104
5.6.
Londiste
Каск
адная
репликация
Каск
адная
реплик
ация
позволяет
реплицировать
данные
с
одного
слей-
ва на другой. Создадим к
онфиг для второго sla
v
e (конфиг бу
дет
/
etc/
skyto
ols/
slav
e2
-
londiste
.
ini
):
Листинг
5.85
Конфиг
для
slav
e2
Line
1
[
l
o
n
d
i
s
t
e
3
]
-
j
o
b
_
n
a
m
e
=
s
l
a
v
e
2
_
l
3
s
i
m
p
l
e
-
d
b
=
d
b
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t
=
s
l
a
v
e
2
-
h
o
s
t
-
q
u
e
u
e
_
n
a
m
e
=
r
e
p
l
i
k
a
5
l
o
g
f
i
l
e
=
/
v
a
r
/
l
o
g
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
2
_
l
3
s
i
m
p
l
e
.
l
o
g
-
p
i
d
f
i
l
e
=
/
v
a
r
/
p
i
d
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
2
_
l
3
s
i
m
p
l
e
.
p
i
d
-
-
# Задер
жка
между
проверками
наличия
активности
-
# новых
(
пакетов
данных
)
в
секундах
10
l
o
o
p
_
d
e
l
a
y
=
0
.
5
Для создания sla
v
e, от к
оторого можно
реплицировать другие базы
данных
используетс
я
команда
create
-
branch
вместо
create
-
leaf
(ro
ot,
корень
-
master
нода,
предоставляет
информацию
для
репликации;
branch,
ветка
-
но
да
с
к
опией
данных,
с
которой
можно
реплицировать;
leaf,
лист
-
но
да
с
к
опией
данными,
но
реплицировать
с
нее
уже
не
возможно):
Листинг
5.86
Инициализируем
slav
e2
Line
1
$
p
s
q
l
-
h
s
l
a
v
e
2
-
h
o
s
t
-
d
p
o
s
t
g
r
e
s
-
c
"
C
R
E
A
T
E
D
A
T
A
B
A
S
E
l
3
s
i
m
p
l
e
;
"
-
$
pg_
dum
p
-
s
-
n
p
u
b
l
i
c
l
3
s
i
m
p
l
e
|
p
s
q
l
-
h
s
l
a
v
e
2
-
h
o
s
t
l
3
s
i
m
p
l
e
-
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
2
-
l
o
n
d
i
s
t
e
.
i
n
i
c
r
e
a
t
e
-
b
r
a
n
c
h
s
l
a
v
e
2
-
n
o
d
e
"
db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t
=
s
l
a
v
e
2
-
h
o
s
t
"
-
-
p
r
o
v
i
d
e
r
=
"db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t=m
a
s
t
e
r
-
h
o
s
t
"
-
IN
F
O
p
l
p
g
s
q
l
i
s
i
n
s
t
a
l
l
e
d
5
IN
F
O
I
n
s
t
a
l
l
i
n
g
p
g
q
-
IN
F
O
R
e
a
d
i
n
g
f
r
o
m
/
u
s
r
/
s
h
a
r
e
/
s
k
y
t
o
o
l
s
3
/
p
g
q
.
s
q
l
-
IN
F
O
p
g
q
.
g
e
t
_
b
a
t
c
h
_
c
u
r
s
o
r
i
s
i
n
s
t
a
l
l
e
d
-
IN
F
O
I
n
s
t
a
l
l
i
n
g
p
g
q
_
e
x
t
-
IN
F
O
R
e
a
d
i
n
g
f
r
o
m
/
u
s
r
/
s
h
a
r
e
/
s
k
y
t
o
o
l
s
3
/
p
g
q
_
e
x
t
.
s
q
l
10
IN
F
O
I
n
s
t
a
l
l
i
n
g
p
g
q
_
n
o
d
e
-
IN
F
O
R
e
a
d
i
n
g
f
r
o
m
/
u
s
r
/
s
h
a
r
e
/
s
k
y
t
o
o
l
s
3
/
p
g
q
_
n
o
d
e
.
s
q
l
-
IN
F
O
I
n
s
t
a
l
l
i
n
g
l
o
n
d
i
s
t
e
-
IN
F
O
R
e
a
d
i
n
g
f
r
o
m
/
u
s
r
/
s
h
a
r
e
/
s
k
y
t
o
o
l
s
3
/
l
o
n
d
i
s
t
e
.
s
q
l
-
IN
F
O
l
o
n
d
i
s
t
e
.
g
l
o
b
a
l
_
a
d
d
_
t
a
b
l
e
i
s
i
n
s
t
a
l
l
e
d
15
IN
F
O
I
n
i
t
i
a
l
i
z
i
n
g
n
o
d
e
-
IN
F
O
L
o
c
a
t
i
o
n
r
e
g
i
s
t
e
r
e
d
-
IN
F
O
L
o
c
a
t
i
o
n
r
e
g
i
s
t
e
r
e
d
-
IN
F
O
S
u
b
s
c
r
i
b
e
r
r
e
g
i
s
t
e
r
e
d
:
s
l
a
v
e
2
-
n
o
d
e
105
5.6.
Londiste
-
IN
F
O
L
o
c
a
t
i
o
n
r
e
g
i
s
t
e
r
e
d
20
IN
F
O
L
o
c
a
t
i
o
n
r
e
g
i
s
t
e
r
e
d
-
IN
F
O
L
o
c
a
t
i
o
n
r
e
g
i
s
t
e
r
e
d
-
IN
F
O
N
o
d
e
"
s
l
a
v
e
2
-
n
o
d
e
"
i
n
i
t
i
a
l
i
z
e
d
f
o
r
q
u
e
u
e
"
r
e
p
l
i
k
a
"
w
i
t
h
t
y
p
e
"
b
r
a
n
c
h
"
-
IN
F
O
D
o
n
e
Далее
добавляем
все
т
аблицы
и
последовательности:
Листинг
5.87
Инициализируем
slav
e2
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
2
-
l
o
n
d
i
s
t
e
.
i
n
i
a
d
d
-
t
a
b
l
e
-
-
a
l
l
-
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
2
-
l
o
n
d
i
s
t
e
.
i
n
i
a
d
d
-
s
e
q
-
-
a
l
l
И
запу
скаем
новый
демон:
Листинг
5.88
Инициализируем
slav
e2
Line
1
$
/
e
t
c
/
i
n
i
t
.
d
/
s
k
y
t
o
o
l
s
3
s
t
a
r
t
-
IN
F
O
S
t
a
r
t
i
n
g
m
a
s
t
e
r
_
l
3
s
i
m
p
l
e
-
IN
F
O
S
t
a
r
t
i
n
g
s
l
a
v
e
1
_
l
3
s
i
m
p
l
e
-
IN
F
O
S
t
a
r
t
i
n
g
s
l
a
v
e
2
_
l
3
s
i
m
p
l
e
5
IN
F
O
S
t
a
r
t
i
n
g
p
g
q
d
-
L
O
G
S
t
a
r
t
i
n
g
p
g
q
d
3
.
2
Повторим
вышеперечисленные
операции
для
slav
e3
и
slav
e4,
только
по-
меняем
pro
vider
для
них:
Листинг
5.89
Инициализируем
slav
e3
и
slav
e4
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
3
-
l
o
n
d
i
s
t
e
.
i
n
i
c
r
e
a
t
e
-
b
r
a
n
c
h
s
l
a
v
e
3
-
n
o
d
e
"
db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t
=
s
l
a
v
e
3
-
h
o
s
t
"
-
-
p
r
o
v
i
d
e
r
=
"db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t=
s
l
a
v
e
2
-
h
o
s
t
"
-
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
4
-
l
o
n
d
i
s
t
e
.
i
n
i
c
r
e
a
t
e
-
b
r
a
n
c
h
s
l
a
v
e
4
-
n
o
d
e
"
db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t
=
s
l
a
v
e
4
-
h
o
s
t
"
-
-
p
r
o
v
i
d
e
r
=
"db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t=
s
l
a
v
e
3
-
h
o
s
t
"
В
резу
ль
тате
получаем
такую
картину
с
кластером:
Листинг
5.90
Кластер
с
каск
адной
репликацией
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
4
-
l
o
n
d
i
s
t
e
.
i
n
i
s
t
a
t
u
s
-
Q
u
e
u
e
:
r
e
p
l
i
k
a
L
o
c
a
l
n
o
d
e
:
s
l
a
v
e
4
-
n
o
d
e
-
-
m
a
s
t
e
r
-
n
o
d
e
(
r
o
o
t
)
5
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
9
s
,
T
i
c
k
:
4
9
-
+
-
-
:
s
l
a
v
e
1
-
n
o
d
e
(
l
e
a
f
)
106
5.6.
Londiste
-
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
9
s
,
T
i
c
k
:
4
9
10
+
-
-
:
s
l
a
v
e
2
-
n
o
d
e
(
b
r
a
n
c
h
)
-
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
9
s
,
T
i
c
k
:
4
9
-
+
-
-
:
s
l
a
v
e
3
-
n
o
d
e
(
b
r
a
n
c
h
)
-
|
T
a
b
l
e
s
:
4
/
0
/
0
15
|
L
a
g
:
9
s
,
T
i
c
k
:
4
9
-
+
-
-
:
s
l
a
v
e
4
-
n
o
d
e
(
b
r
a
n
c
h
)
-
T
a
b
l
e
s
:
4
/
0
/
0
-
L
a
g
:
9
s
,
T
i
c
k
:
4
9
Londiste
позволяет
«на
лету»
изменять
топологию
кластера.
Например,
изменим
«pro
vider»
для
slav
e4:
Листинг
5.91
Изменяем
топологию
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
4
-
l
o
n
d
i
s
t
e
.
i
n
i
c
h
a
n
g
e
-
p
r
o
v
i
d
e
r
-
-
p
r
o
v
i
d
e
r
="db
n
a
m
e
=
l
3
s
i
m
p
l
e
h
o
s
t
=
s
l
a
v
e
2
-
h
o
s
t
"
-
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
4
-
l
o
n
d
i
s
t
e
.
i
n
i
s
t
a
t
u
s
-
Q
u
e
u
e
:
r
e
p
l
i
k
a
L
o
c
a
l
n
o
d
e
:
s
l
a
v
e
4
-
n
o
d
e
-
5
m
a
s
t
e
r
-
n
o
d
e
(
r
o
o
t
)
-
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
1
2
s
,
T
i
c
k
:
5
6
-
+
-
-
:
s
l
a
v
e
1
-
n
o
d
e
(
l
e
a
f
)
-
|
T
a
b
l
e
s
:
4
/
0
/
0
10
|
L
a
g
:
1
2
s
,
T
i
c
k
:
5
6
-
+
-
-
:
s
l
a
v
e
2
-
n
o
d
e
(
b
r
a
n
c
h
)
-
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
1
2
s
,
T
i
c
k
:
5
6
-
+
-
-
:
s
l
a
v
e
3
-
n
o
d
e
(
b
r
a
n
c
h
)
15
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
1
2
s
,
T
i
c
k
:
5
6
-
+
-
-
:
s
l
a
v
e
4
-
n
o
d
e
(
b
r
a
n
c
h
)
-
T
a
b
l
e
s
:
4
/
0
/
0
-
L
a
g
:
1
2
s
,
T
i
c
k
:
5
6
Т
акж
е
топологию
можно
менять
с
стороны
репликатора
через
к
оманду
tak
eov
er
:
Листинг
5.92
Изменяем
топологию
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
3
-
l
o
n
d
i
s
t
e
.
i
n
i
t
a
k
e
o
v
e
r
s
l
a
v
e
4
-
n
o
d
e
-
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
4
-
l
o
n
d
i
s
t
e
.
i
n
i
s
t
a
t
u
s
-
Q
u
e
u
e
:
r
e
p
l
i
k
a
L
o
c
a
l
n
o
d
e
:
s
l
a
v
e
4
-
n
o
d
e
-
107
5.6.
Londiste
5
m
a
s
t
e
r
-
n
o
d
e
(
r
o
o
t
)
-
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
9
s
,
T
i
c
k
:
4
9
-
+
-
-
:
s
l
a
v
e
1
-
n
o
d
e
(
l
e
a
f
)
-
|
T
a
b
l
e
s
:
4
/
0
/
0
10
|
L
a
g
:
9
s
,
T
i
c
k
:
4
9
-
+
-
-
:
s
l
a
v
e
2
-
n
o
d
e
(
b
r
a
n
c
h
)
-
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
9
s
,
T
i
c
k
:
4
9
-
+
-
-
:
s
l
a
v
e
3
-
n
o
d
e
(
b
r
a
n
c
h
)
15
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
9
s
,
T
i
c
k
:
4
9
-
+
-
-
:
s
l
a
v
e
4
-
n
o
d
e
(
b
r
a
n
c
h
)
-
T
a
b
l
e
s
:
4
/
0
/
0
-
L
a
g
:
9
s
,
T
i
c
k
:
4
9
Через
к
оманду
drop
-no
de
мо
жно
у
далить
slav
e
из
кластера:
Листинг
5.93
У
даляем
ноду
Line
1
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
4
-
l
o
n
d
i
s
t
e
.
i
n
i
d
r
o
p
-
n
o
d
e
s
l
a
v
e
4
-
n
o
d
e
-
$
l
o
n
d
i
s
t
e
3
/
e
t
c
/
s
k
y
t
o
o
l
s
/
s
l
a
v
e
3
-
l
o
n
d
i
s
t
e
.
i
n
i
s
t
a
t
u
s
-
Q
u
e
u
e
:
r
e
p
l
i
k
a
L
o
c
a
l
n
o
d
e
:
s
l
a
v
e
3
-
n
o
d
e
-
5
m
a
s
t
e
r
-
n
o
d
e
(
r
o
o
t
)
-
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
9
s
,
T
i
c
k
:
4
9
-
+
-
-
:
s
l
a
v
e
1
-
n
o
d
e
(
l
e
a
f
)
-
|
T
a
b
l
e
s
:
4
/
0
/
0
10
|
L
a
g
:
9
s
,
T
i
c
k
:
4
9
-
+
-
-
:
s
l
a
v
e
2
-
n
o
d
e
(
b
r
a
n
c
h
)
-
|
T
a
b
l
e
s
:
4
/
0
/
0
-
|
L
a
g
:
9
s
,
T
i
c
k
:
4
9
-
+
-
-
:
s
l
a
v
e
3
-
n
o
d
e
(
b
r
a
n
c
h
)
15
T
a
b
l
e
s
:
4
/
0
/
0
-
L
a
g
:
9
s
,
T
i
c
k
:
4
9
Команда
tag
-
dead
мож
ет
использоваться,
что
бы
указать
sla
ve
как
не
живой
(прекратить
на него
репликацию),
а через
команду
tag
-
aliv
e
его
мо
жно
вернуть
в
кластер.
Общие
зада
чи
Проверк
а
состояния
слейвов
Данный
запрос
на
мастере
дает
нек
оторую
информацию
о
каждой
оче-
реди
и
слейве:
108
5.6.
Londiste
Листинг
5.94
Проверка
состояния
слейвов
Line
1
#
S
E
L
E
C
T
q
u
e
u
e
_
n
a
m
e
,
c
o
n
s
u
m
e
r
_
n
a
m
e
,
l
a
g
,
l
a
s
t
_
s
e
e
n
F
R
O
M
p
g
q
.
g
e
t
_
c
o
n
s
u
m
e
r
_
i
n
f
o
(
)
;
-
q
u
e
u
e
_
n
a
m
e
|
c
o
n
s
u
m
e
r
_
n
a
m
e
|
l
a
g
|
l
a
s
t
_
s
e
e
n
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
r
e
p
l
i
k
a
|
.
g
l
o
b
a
l
_
w
a
t
e
r
m
a
r
k
|
0
0
:
0
3
:
3
7
.
1
0
8
2
5
9
|
0
0
:
0
2
:
3
3
.
0
1
3
9
1
5
5
r
e
p
l
i
k
a
|
s
l
a
v
e
1
_
l
3
s
i
m
p
l
e
|
0
0
:
0
0
:
3
2
.
6
3
1
5
0
9
|
0
0
:
0
0
:
3
2
.
5
3
3
9
1
1
-
r
e
p
l
i
k
a
|
.
s
l
a
v
e
1
-
n
o
d
e
.
w
a
t
e
r
m
a
r
k
|
0
0
:
0
3
:
3
7
.
1
0
8
2
5
9
|
0
0
:
0
3
:
0
5
.
0
1
4
3
1
г
де
lag
столбец
пок
азывает отст
авание от
мастера
в
синхронизации,
last_seen
—
время
последней
запроса
от
слейва.
Значение
этого
столбца
не
должно
быть
больше,
чем
60
секунд
для
к
онфигурации
по
умолчанию.
У
даление
очереди
всех
событий
из
мастера
При
работе
с
Londiste
мож
ет
потребоваться
у
далить
все
ваши
настрой-
ки
для
того,
чтобы
на
чать
все
заново.
Для
PGQ,
чтобы
остановить
накоп-
ление
данных,
используйте
следующие
API:
Листинг
5.95
У
даление
очереди
всех
событий
из
мастера
Line
1
S
E
L
E
C
T
p
g
q
.
u
n
r
e
g
i
s
t
e
r
_
c
o
n
s
u
m
e
r
(
’
qu
e
u
e
_
n
a
m
e
’
,
’
c
o
n
s
u
m
e
r
_
n
a
m
e
’
)
;
Добавление
столбца
в
т
аблицу
Добавляем
в
следующей
последовательности:
1. добавить
поле
на
все
слейвы;
2. BEGIN;
–
на
мастере;
3. добавить
поле
на
мастере;
4. COMMIT;
У
даление
столбца
из
т
аблицы
1. BEGIN;
–
на
мастере;
2. у
далить
поле
на
мастере;
3. COMMIT;
4. Проверить
lag
,
к
огда
londiste
пройдет
момент
у
даления
поля;
109
5.7.
Bucardo
5. у
далить
поле
на
всех
слейвах;
Хитрость
тут
в
том,
чтобы
у
далить
поле
на
слейвах
только
тогда,
к
огда
больше
нет
событий
в
очереди
на
это
поле.
У
странение
неисправностей
Londiste
по
жирает
процессор
и
lag
растет
Это
происх
о
дит
,
например,
если
во
время
сбоя
забыли
перезапустить
tic
ker.
Или
ког
да
с
делали
большой
UPDA
TE
или
DELETE
в
одной
тран-
закции, но теперь что бы реализовать к
аждое событие в этом запросе
создаютс
я
транзакции
на
слейвах
.
.
.
Следующий
запрос
позволяет
по
дсчитать,
скольк
о
событий
пришло
в
pgq.
subscription
в
к
олонках
sub_last_tick
и
sub_next_tick
.
Листинг
5.96
У
странение
неисправностей
Line
1
S
E
L
E
C
T
c
o
u
n
t
(
*
)
-
F
R
O
M
p
g
q
.
e
v
e
n
t
_
1
,
-
(
S
E
L
E
C
T
t
i
c
k
_
s
n
a
p
s
h
o
t
-
F
R
O
M
p
g
q
.
t
i
c
k
5
W
H
E
R
E
t
i
c
k
_
i
d
B
E
T
W
E
E
N
5
7
1
5
1
3
8
A
N
D
5
7
1
5
1
3
9
-
)
a
s
t
(
s
n
a
p
s
h
o
t
s
)
-
W
H
E
R
E
t
x
i
d
_
v
i
s
i
b
l
e
_
i
n
_
s
n
a
p
s
h
o
t
(
e
v
_
t
x
i
d
,
s
n
a
p
s
h
o
t
s
)
;
На
практике
это
было
более
чем
5
миллионов
и
400
тысяч
событий.
Чем
больше
событий
с
базы
данных
требуетс
я
обработать
Londiste,
тем
больше
ему
требу
ется
памяти
для
этого.
Возможно
сообщить
Londiste
не
загру-
ж
ать все
события
сразу
.
Дост
аточно
добавить
в INI
конфиг
PgQ
tic
ker
следующую
настройку:
Листинг
5.97
У
странение
неисправностей
Line
1
p
g
q
_
l
a
z
y
_
f
e
t
c
h
=
5
0
0
Т
еперь
Londiste
бу
дет
брать
максимум
500
событий
в
один
пакет
за-
просов.
Ост
альные
попадут
в
следующие
пакеты
запросов.
5.7
Bucardo
Bucardo
—
асинхронная
master-master
или
master-sla
ve
реплик
ация
P
ostgreSQL,
к
оторая
написана
на
P
erl.
Система
очень
гибкая,
поддер
жи-
вает
неск
олько
видов
синхронизации
и
обработки
конфликтов.
110
5.7.
Bucardo
У
становк
а
У
ст
ановка
бу
дет
проводитьс
я
на
Debian
сервере.
Сначала
нужно
у
ст
а-
новить
DBIx::Safe
P
erl
мо
ду
ль.
Листинг
5.98
У
становк
а
Line
1
$
a
p
t
-
g
e
t
i
n
s
t
a
l
l
l
i
b
d
b
i
x
-
s
a
f
e
-
p
e
r
l
Для
других
систем
мо
жно
поставить
из
исх
одник
ов
:
Листинг
5.99
У
становк
а
Line
1
$
t
a
r
x
v
f
z
d
b
i
x
_
s
a
f
e
.
t
a
r
.
g
z
-
$
c
d
DB
Ix
-
S
a
f
e
-
1
.
2
.
5
-
$
p
e
r
l
M
a
k
e
f
i
l
e
.
P
L
-
$
m
a
ke
5
$
m
a
ke
t
e
s
t
-
$
s
u
d
o
m
a
ke
i
n
s
t
a
l
l
Т
еперь
ст
авим
сам
Bucardo.
Ска
чиваем
его
и
инсталлиру
ем:
Листинг
5.100
У
становк
а
Line
1
$
w
g
e
t
h
t
t
p
:
/
/
b
u
c
a
r
d
o
.
o
r
g
/
d
o
w
n
l
o
a
d
s
/
B
u
c
a
r
d
o
-
5
.
4
.
1
.
t
a
r
.
g
z
-
$
t
a
r
x
v
f
z
B
u
c
a
r
d
o
-
5
.
4
.
1
.
t
a
r
.
g
z
-
$
c
d
B
u
c
a
r
d
o
-
5
.
4
.
1
-
$
p
e
r
l
M
a
k
e
f
i
l
e
.
P
L
5
$
m
a
ke
-
$
s
u
d
o
m
a
ke
i
n
s
t
a
l
l
Для
работы
Bucardo
потребу
ется
уст
ановить
по
ддержку
pl/p
erl
язык
а
в
P
ostgreSQL.
Листинг
5.101
У
становк
а
Line
1
$
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
p
o
s
t
g
r
e
s
q
l
-
p
l
p
e
r
l
-
9
.
5
и
дополнительные
пакеты
для
Perl
(DBI,
DBD::Pg,
T
est::Simple,
b
o
olean):
Листинг
5.102
У
становк
а
Line
1
$
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
l
i
b
d
b
d
-
p
g
-
p
e
r
l
l
i
b
b
o
o
l
e
a
n
-
p
e
r
l
Т
еперь
мо
жем
приступать
к
настройке
репликации.
111
5.7.
Bucardo
Настройк
а
Инициализация
Bucardo
Запу
скаем
уст
ановку
Bucardo:
Листинг
5.103
Инициализация
Bucardo
Line
1
$
b
u
c
a
r
d
o
i
n
s
t
a
l
l
Во
время
у
ст
ановки
бу
дут
показаны
настройки
подключения
к
P
ostgreSQL,
которые
можно
бу
дет
изменить:
Листинг
5.104
Инициализация
Bucardo
Line
1
T
h
i
s
w
i
l
l
i
n
s
t
a
l
l
t
h
e
b
u
c
a
r
d
o
d
a
t
a
b
a
s
e
i
n
t
o
a
n
e
x
i
s
t
i
n
g
P
o
s
t
g
r
e
s
c
l
u
s
t
e
r
.
-
P
o
s
t
g
r
e
s
m
u
s
t
h
a
v
e
b
e
e
n
c
o
m
p
i
l
e
d
w
i
t
h
P
e
r
l
s
u
p
p
o
r
t
,
-
a
n
d
y
o
u
m
u
s
t
c
o
n
n
e
c
t
a
s
a
s
u
p
e
r
u
s
e
r
-
5
W
e
w
i
l
l
c
r
e
a
t
e
a
n
e
w
s
u
p
e
r
u
s
e
r
na
m
e
d
’
b
u
c
a
r
d
o
’
,
-
a
n
d
ma
k
e
i
t
t
h
e
o
w
n
e
r
o
f
a
new
d
a
t
a
b
a
s
e
na
m
e
d
’
b
u
c
a
r
d
o
’
-
-
C
u
r
r
e
n
t
c
o
n
n
e
c
t
i
o
n
s
e
t
t
i
n
g
s
:
-
1
.
H
o
s
t
:
<n
o
n
e
>
10
2
.
P
o
r
t
:
5
4
3
2
-
3
.
U
s
e
r
:
p
o
s
t
g
r
e
s
-
4
.
D
a
t
a
b
a
s
e
:
p
o
s
t
g
r
e
s
-
5
.
PID
d
i
r
e
c
t
o
r
y
:
/
v
a
r
/
r
u
n
/
b
u
c
a
r
d
o
После
подтвер
ждения
настроек,
Bucardo
создаст
пользователя
bucardo
и
базу
данных
bucardo
.
Данный
пользователь
должен
иметь
право
логи-
нитьс
я
через
Unix
sock
et,
поэтому
лучше
заранее
дать
ему
т
акие
права
в
pg_hda.conf
.
После
успешной
у
становки
можно
проверить
конфигурацию
через
ко-
манду
bucardo
sho
w
all
:
Листинг
5.105
Инициализация
Bucardo
Line
1
$
b
u
c
a
r
d
o
s
h
o
w
a
l
l
-
a
u
t
o
s
y
n
c
_
d
d
l
=
n
e
w
c
o
l
-
b
u
c
a
r
d
o
_
i
n
i
t
i
a
l
_
v
e
r
s
i
o
n
=
5
.
0
.
0
-
b
u
c
a
r
d
o
_
v
a
c
=
1
5
b
u
c
a
r
d
o
_
v
e
r
s
i
o
n
=
5
.
0
.
0
-
c
t
l
_
c
h
e
c
k
o
n
k
i
d
s
_
t
i
m
e
=
1
0
-
c
t
l
_
c
r
e
a
t
e
k
i
d
_
t
i
m
e
=
0
.
5
-
c
t
l
_
s
l
e
e
p
=
0
.
2
-
d
e
f
a
u
l
t
_
c
o
n
f
l
i
c
t
_
s
t
r
a
t
e
g
y
=
b
u
c
a
r
d
o
_
l
a
t
e
s
t
112
5.7.
Bucardo
10
d
e
f
a
u
l
t
_
e
m
a
i
l
_
f
r
o
m
=
n
o
b
o
d
y
@
e
x
a
m
p
l
e
.
c
om
-
d
e
f
a
u
l
t
_
e
m
a
i
l
_
h
o
s
t
=
l
o
c
a
l
h
o
s
t
-
d
e
f
a
u
l
t
_
e
m
a
i
l
_
t
o
=
n
o
b
o
d
y
@
e
x
a
m
p
l
e
.
c
om
-
.
.
.
Настройк
а
баз
данных
Т
еперь
нужно
настроить
базы
данных,
с
которыми
бу
дет
работ
ать
Bucardo.
Обозна
чим
базы
к
ак
master_db
и
slav
e_db
.
Р
еплицировать
бу
дем
simple_database
базу
.
Сна
чала
настроим
мастер
базу:
Листинг
5.106
Настройка
баз
данных
Line
1
$
b
u
c
a
r
d
o
a
d
d
d
b
m
a
s
t
e
r
_
d
b
db
n
a
m
e
=s
i
m
p
l
e
_
d
a
t
a
b
a
s
e
h
o
s
t
=
m
a
s
t
e
r
_
h
o
s
t
-
A
d
de
d
d
a
t
a
b
a
s
e
"
m
a
s
t
e
r
_
d
b
"
Данной
к
омандой
ук
азали
базу
данных
и
дали
ей
имя
master_db
(для
того,
что
в
реальной
жизни
master_db
и
sla
ve_db
имеют
о
динаковое
назва-
ние
базы
simple_database
и
их
нужно
от
личать
в
Bucardo).
Дальше
добавляем
sla
ve_db
:
Листинг
5.107
Настройка
баз
данных
Line
1
$
b
u
c
a
r
d
o
a
d
d
d
b
s
l
a
v
e
_
d
b
d
bn
a
m
e
=s
i
m
p
l
e
_
d
a
t
a
b
a
s
e
p
o
r
t
=
5
4
3
2
h
o
s
t
=
s
l
a
v
e
_
h
o
s
t
Настройк
а
репликации
Т
еперь
требу
ется
настроить
синхронизацию
между
этими
базами
дан-
ных.
Делаетс
я
это
командой
sync
:
Листинг
5.108
Настройка
репликации
Line
1
$
b
u
c
a
r
d
o
a
d
d
s
y
n
c
d
e
l
t
a
d
b
s=
m
a
s
t
e
r
_
d
b
:
s
o
u
r
c
e
,
s
l
a
v
e
_
d
b
:
t
a
r
g
e
t
c
o
n
f
l
i
c
t
_
s
t
r
a
t
e
g
y
=
b
u
c
a
r
d
o
_
l
a
t
e
s
t
t
a
b
l
e
s
=
a
l
l
-
A
d
de
d
s
y
n
c
"
d
e
l
t
a
"
-
C
r
e
a
t
e
d
a
ne
w
r
e
l
g
r
o
u
p
n
a
m
e
d
"
d
e
l
t
a
"
-
C
r
e
a
t
e
d
a
ne
w
d
b
g
r
o
u
p
n
am
e
d
"
d
e
l
t
a
"
5
A
dd
e
d
t
a
b
l
e
"
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
a
c
c
o
u
n
t
s
"
-
A
dd
e
d
t
a
b
l
e
"
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
b
r
a
n
c
h
e
s
"
-
A
dd
e
d
t
a
b
l
e
"
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
"
-
A
dd
e
d
t
a
b
l
e
"
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
t
e
l
l
e
r
s
"
Данная к
оманда у
ст
анавливает Bucardo
триггеры
в P
ostgreSQL для
master-sla
ve
репликации.
Значения
параметров:
113
5.7.
Bucardo
∙
dbs
—
список
баз
данных,
к
оторые
следу
ет
синхронизировать.
Значе-
ние
source
или
target
указывает
,
что
это
master
или
sla
ve
база
данных
соответственно
(их
мо
жет
быть
больше
одной);
∙
conflict_strategy
—
для
работы
в
режиме
master-master
нужно
указать
к
ак
Bucardo
долж
ен
решать
к
онфликты
синхронизации.
Существуют
следующие
стратегии:
–
bucardo_source
—
при
к
онфликте
мы
копиру
ем
данные
с
source;
–
bucardo_target
—
при
к
онфликте
мы
копиру
ем
данные
с
target;
–
bucardo_skip
—
конфликт
мы
просто
не
реплицируем.
Не
рек
о-
менду
ется
для
продакшен
систем;
–
bucardo_random
—
к
аждая
БД
имеет
одинак
овый
шанс,
что
её
изменение
бу
дет
взято
для
решение
конфликт
а;
–
bucardo_latest
—
запись,
к
оторая
была
последней
изменена
ре-
шает
к
онфликт;
–
bucardo_ab
ort
—
синхронизация
прерываетс
я;
∙
tables
—
таблицы,
к
оторые
требу
ется
синхронизировать.
Через
«all»
ук
азываем
все;
Для
master-master
реплик
ации
требуетс
я
выполнить:
Листинг
5.109
Настройка
репликации
Line
1
$
b
u
c
a
r
d
o
a
d
d
s
y
n
c
d
e
l
t
a
d
b
s=
m
a
s
t
e
r
_
d
b
:
s
o
u
r
c
e
,
s
l
a
v
e
_
d
b
:
s
o
u
r
c
e
c
o
n
f
l
i
c
t
_
s
t
r
a
t
e
g
y
=
b
u
c
a
r
d
o
_
l
a
t
e
s
t
t
a
b
l
e
s
=
a
l
l
Пример
для
создания
master-master
и
master-sla
ve
репликации:
Листинг
5.110
Настройка
репликации
Line
1
$
b
u
c
a
r
d
o
a
d
d
s
y
n
c
d
e
l
t
a
d
b
s=
m
a
s
t
e
r
_
d
b
1
:
s
o
u
r
c
e
,
m
a
s
t
e
r
_
d
b
2
:
s
o
u
r
c
e
,
s
l
a
v
e
_
d
b
1
:
t
a
r
g
e
t
,
s
l
a
v
e
_
d
b
2
:
t
a
r
g
e
t
c
o
n
f
l
i
c
t
_
s
t
r
a
t
e
g
y
=
b
u
c
a
r
d
o
_
l
a
t
e
s
t
t
a
b
l
e
s
=
a
l
l
Для
проверки
состо
яния
репликации:
Листинг
5.111
Проверка
состояния
репликации
Line
1
$
b
u
c
a
r
d
o
s
t
a
t
u
s
-
PID
o
f
B
u
c
a
r
d
o
M
C
P:
1
2
1
2
2
-
Na
m
e
S
t
a
t
e
L
a
s
t
g
o
o
d
Ti
m
e
L
a
s
t
I
/D
L
a
s
t
b
a
d
T
i
m
e
-
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
5
d
e
l
t
a
|
G
oo
d
|
1
3
:
2
8
:
5
3
|
1
3
m
6
s
|
3
6
8
5
/
7
3
8
4
|
n
o
n
e
|
114
5.7.
Bucardo
Запу
ск/Остановк
а
репликации
Запу
ск
репликации:
Листинг
5.112
Запуск
репликации
Line
1
$
b
u
c
a
r
d
o
s
t
a
r
t
Ост
ановка
репликации:
Листинг
5.113
Остановк
а
реплик
ации
Line
1
$
b
u
c
a
r
d
o
s
t
o
p
Общие
зада
чи
Просмотр
зна
чений
конфигурации
Листинг
5.114
Просмотр
значений
конфигурации
Line
1
$
b
u
c
a
r
d
o
s
h
o
w
a
l
l
Изменения
зна
чений
конфигурации
Листинг
5.115
Изменения
значений
конфигурации
Line
1
$
b
u
c
a
r
d
o
s
e
t
n
am
e
=
v
a
l
u
e
Например:
Листинг
5.116
Изменения
значений
конфигурации
Line
1
$
b
u
c
a
r
d
o
_
c
t
l
s
e
t
s
y
s
l
o
g
_
f
a
c
i
l
i
t
y
=
L
O
G
_
L
O
C
A
L
3
Перегрузк
а
конфигурации
Листинг
5.117
Перегрузка
конфигурации
Line
1
$
b
u
c
a
r
d
o
r
e
l
o
a
d
_
c
o
n
f
i
g
Более
по
дробную
информацию
можно
найти
на
официальном
сайте
.
115
5.7.
Bucardo
Р
епликация
в
другие
типы
баз
данных
На
чиная
с
версии
5.0
Bucardo
поддер
живает
репликацию
в
другие
ис-
точники
данных:
drizzle,
mongo,
mysql,
oracle,
redis
и
sqlite
(тип
базы
за-
даетс
я
при
использовании
команды
bucardo
add
db
через
ключ
«type»
,
ко-
торый
по
умолчанию
p
ostgres).
Давайте
рассмотрим
пример
с
redis
базой.
Для
начала
потребуетс
я
у
становить
redis
адаптер
для
P
erl
(для
других
баз
у
станавливаютс
я
соответствующие):
Листинг
5.118
У
становк
а
redis
Line
1
$
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
l
i
b
r
e
d
i
s
-
p
e
r
l
Далее
зарегистриру
ем
redis
базу
в
Bucardo:
Листинг
5.119
Добавление
redis
базы
Line
1
$
b
u
c
a
r
d
o
a
d
d
d
b
R
db
n
a
m
e
=s
i
m
p
l
e
_
d
a
t
a
b
a
s
e
t
y
p
e
=
r
e
d
i
s
-
A
d
de
d
d
a
t
a
b
a
s
e
"R"
Создадим
группу
баз
данных
по
д
названием
pg_to_redis
:
Листинг
5.120
Группа
баз
данных
Line
1
$
b
u
c
a
r
d
o
a
d
d
d
b
g
r
o
u
p
p
g
_
t
o
_
r
e
d
i
s
m
a
s
t
e
r
_
d
b
:
s
o
u
r
c
e
s
l
a
v
e
_
d
b
:
s
o
u
r
c
e
R
:
t
a
r
g
e
t
-
C
r
e
a
t
e
d
d
b
g
r
o
u
p
"
p
g
_
t
o
_
r
e
d
i
s
"
-
A
d
de
d
d
a
t
a
b
a
s
e
"
m
a
s
t
e
r
_
d
b
"
t
o
d
b
g
r
o
u
p
"
p
g
_
t
o
_
r
e
d
i
s
"
a
s
s
o
u
r
c
e
-
A
d
de
d
d
a
t
a
b
a
s
e
"
s
l
a
v
e
_
d
b
"
t
o
d
b
g
r
o
u
p
"
p
g
_
t
o
_
r
e
d
i
s
"
a
s
s
o
u
r
c
e
5
A
d
de
d
d
a
t
a
b
a
s
e
"R"
t
o
d
b
g
r
o
u
p
"
p
g
_
t
o
_
r
e
d
i
s
"
a
s
t
a
r
g
e
t
И
создадим
реплик
ацию:
Листинг
5.121
У
становк
а
sync
Line
1
$
b
u
c
a
r
d
o
a
d
d
s
y
n
c
p
g
_
t
o
_
r
e
d
i
s
_
s
y
n
c
t
a
b
l
e
s
=
a
l
l
d
b
s=
p
g
_
t
o
_
r
e
d
i
s
s
t
a
t
u
s
=
a
c
t
i
v
e
-
A
d
de
d
s
y
n
c
"
p
g
_
t
o
_
r
e
d
i
s
_
s
y
n
c
"
-
A
dd
e
d
t
a
b
l
e
"
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
a
c
c
o
u
n
t
s
"
-
A
dd
e
d
t
a
b
l
e
"
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
b
r
a
n
c
h
e
s
"
5
A
dd
e
d
t
a
b
l
e
"
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
"
-
A
dd
e
d
t
a
b
l
e
"
p
u
b
l
i
c
.
p
g
b
e
n
c
h
_
t
e
l
l
e
r
s
"
После
перезапу
ск
а
Bucardo
данные
с
P
ostgreSQL
т
аблиц
начнут
репли-
цироватьс
я
в
Redis:
116
5.7.
Bucardo
Листинг
5.122
Реплик
ация
в
redis
Line
1
$
p
g
b
e
n
c
h
-
T
1
0
-
c
5
s
i
m
p
l
e
_
d
a
t
a
b
a
s
e
-
$
r
e
d
i
s
-
c
l
i
m
o
n
i
t
o
r
-
"
H
M
S
E
T
"
"
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
:
6
"
"
b
i
d
"
"
2
"
"
a
i
d
"
"
3
6
2
9
1
"
"
d
e
l
t
a
"
"
3
7
1
6
"
"
m
t
i
m
e
"
"
2
0
1
4
-
0
7
-
1
1
1
4
:
5
9
:
3
8
.
4
5
4
8
2
4
"
"
h
i
d
"
"
4
3
3
1
"
-
"
H
M
S
E
T
"
"
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
:
2
"
"
b
i
d
"
"
1
"
"
a
i
d
"
"
6
5
1
7
9
"
"
d
e
l
t
a
"
"
2
4
3
6
"
"
m
t
i
m
e
"
"
2
0
1
4
-
0
7
-
1
1
1
4
:
5
9
:
3
8
.
5
0
0
8
9
6
"
"
h
i
d
"
"
4
3
3
2
"
5
"
H
M
S
E
T
"
"
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
:
1
4
"
"
b
i
d
"
"
2
"
"
a
i
d
"
"
1
5
3
0
0
1
"
"
d
e
l
t
a
"
"
-
2
6
4
"
"
m
t
i
m
e
"
"
2
0
1
4
-
0
7
-
1
1
1
4
:
5
9
:
3
8
.
4
7
2
7
0
6
"
"
h
i
d
"
"
4
3
3
3
"
-
"
H
M
S
E
T
"
"
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
:
1
5
"
"
b
i
d
"
"
1
"
"
a
i
d
"
"
1
9
5
7
4
7
"
"
d
e
l
t
a
"
"
-
1
6
7
1
"
"
m
t
i
m
e
"
"
2
0
1
4
-
0
7
-
1
1
1
4
:
5
9
:
3
8
.
5
0
9
8
3
9
"
"
h
i
d
"
"
4
3
3
4
"
-
"
H
M
S
E
T
"
"
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
:
3
"
"
b
i
d
"
"
2
"
"
a
i
d
"
"
1
4
7
6
5
0
"
"
d
e
l
t
a
"
"
3
2
3
7
"
"
m
t
i
m
e
"
"
2
0
1
4
-
0
7
-
1
1
1
4
:
5
9
:
3
8
.
4
8
9
8
7
8
"
"
h
i
d
"
"
4
3
3
5
"
-
"
H
M
S
E
T
"
"
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
:
1
5
"
"
b
i
d
"
"
1
"
"
a
i
d
"
"
3
9
5
2
1
"
"
d
e
l
t
a
"
"
-
2
1
2
5
"
"
m
t
i
m
e
"
"
2
0
1
4
-
0
7
-
1
1
1
4
:
5
9
:
3
8
.
5
2
6
3
1
7
"
"
h
i
d
"
"
4
3
3
6
"
-
"
H
M
S
E
T
"
"
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
:
1
4
"
"
b
i
d
"
"
2
"
"
a
i
d
"
"
6
0
1
0
5
"
"
d
e
l
t
a
"
"
2
5
5
5
"
"
m
t
i
m
e
"
"
2
0
1
4
-
0
7
-
1
1
1
4
:
5
9
:
3
8
.
6
1
6
9
3
5
"
"
h
i
d
"
"
4
3
3
7
"
10
"
H
M
S
E
T
"
"
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
:
1
5
"
"
b
i
d
"
"
2
"
"
a
i
d
"
"
1
8
6
6
5
5
"
"
d
e
l
t
a
"
"
9
3
0
"
"
m
t
i
m
e
"
"
2
0
1
4
-
0
7
-
1
1
1
4
:
5
9
:
3
8
.
5
4
1
2
9
6
"
"
h
i
d
"
"
4
3
3
8
"
-
"
H
M
S
E
T
"
"
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
:
1
5
"
"
b
i
d
"
"
1
"
"
a
i
d
"
"
1
0
1
4
0
6
"
"
d
e
l
t
a
"
"
6
6
8
"
"
m
t
i
m
e
"
"
2
0
1
4
-
0
7
-
1
1
1
4
:
5
9
:
3
8
.
5
6
0
9
7
1
"
"
h
i
d
"
"
4
3
3
9
"
-
"
H
M
S
E
T
"
"
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
:
1
5
"
"
b
i
d
"
"
2
"
"
a
i
d
"
"
1
2
6
3
2
9
"
"
d
e
l
t
a
"
"
-
4
2
3
6
"
"
m
t
i
m
e
"
"
2
0
1
4
-
0
7
-
1
1
1
4
:
5
9
:
3
8
.
5
9
0
7
"
"
h
i
d
"
"
4
3
4
0
"
-
"D
E
L
"
"
p
g
b
e
n
c
h
_
t
e
l
l
e
r
s
:
2
0
"
Данные
в
Redis
хранятс
я
в
виде
хешей:
Листинг
5.123
Данные
в
redis
Line
1
$
r
e
d
i
s
-
c
l
i
"
H
G
E
T
A
L
L
"
"
p
g
b
e
n
c
h
_
h
i
s
t
o
r
y
:
1
5
"
-
1
)
"
b
i
d
"
-
2
)
"
2
"
-
3
)
"
a
i
d
"
5
4
)
"
1
2
6
3
2
9
"
-
5
)
"
d
e
l
t
a
"
-
6
)
"
-
4
2
3
6
"
-
7
)
"
m
t
i
m
e
"
-
8
)
"
2
0
1
4
-
0
7
-
1
1
1
4
:
5
9
:
3
8
.
5
9
0
7
"
10
9
)
"
h
i
d
"
-
1
0
)
"
4
3
4
0
"
Т
акж
е
можно
проверить
состояние
репликации:
Листинг
5.124
У
становк
а
redis
117
5.8.
Заключение
Line
1
$
b
u
c
a
r
d
o
s
t
a
t
u
s
-
PID
o
f
B
u
c
a
r
d
o
M
C
P:
4
6
5
5
-
Na
m
e
S
t
a
t
e
L
a
s
t
g
o
o
d
Ti
m
e
L
a
s
t
I
/D
L
a
s
t
b
a
d
Ti
m
e
-
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
=
=
=
=
+
=
=
=
=
=
=
=
=
5
d
e
l
t
a
|
Go
od
|
1
4
:
5
9
:
3
9
|
8
m
1
5
s
|
0
/
0
|
n
o
n
e
|
-
p
g
_
t
o
_
r
e
d
i
s
_
s
y
n
c
|
Goo
d
|
1
4
:
5
9
:
4
0
|
8
m
1
4
s
|
6
4
6
/
2
5
4
6
|
1
4
:
5
9
:
3
9
|
8
m
1
5
s
Т
еперь
данные
из
redis
могут
использоватьс
я
для
прило
жения
в
виде
быстрого
кэш
хранилища.
5.8
Заключение
Р
епликация
—
одна
из
важнейших
частей
крупных
прил
о
жений,
к
ото-
рые
работаю
т
на
PostgreSQL.
Она
п
омог
ает
распределять
нагрузку
на
базу
данных,
делать
фоновый
бэкап
одной
из
к
опий
без
нагрузки
на
централь-
ный
сервер,
создавать
отдельный
сервер
для
логирования
или
аналитики,
прочее.
В
г
лаве было
рассмотрено неск
олько
видов реплик
ации
P
ostgreSQL.
Нельзя
четко
ск
азать
как
ая
лучше
всех.
Поток
овая
репликация
—
один
из
самых
лучших
вариантов
для
по
ддер
жки
идентичных
кластеров
баз
данных.
Slon
y-I
—
громоздк
ая
и
сложная
в
настройк
е
система,
но
имею-
щая
в
своем
арсенале
мно
ж
ество
функций,
т
аких
к
ак
отк
азоу
стойчиво-
сти
(failo
v
er)
и
переключение
между
серверами
(switcho
ver).
В
тож
е
время
Londiste
имея
в
своем
арсенале
подобный
функционал,
мо
жет
по
хваст
ать-
с
я
еще
компактностью
и
простой
в
у
становк
е.
Bucardo
—
система
к
оторая
мо
жет
быть
или
master-master,
или
master-slav
e
репликацией.
118
6
Шар
динг
Если
ешь
слона,
не
пытайс
я
запих
ать
его
в
рот
целик
ом
Наро
дная
му
дрость
6.1
Введение
Шар
динг
—
разделение
данных
на
уровне
ресурсов.
Концепция
шар-
динг
а
заключаетс
я
в
логическ
ом
разделении
данных
по
различным
ресур-
сам,
ис
хо
дя
из
требований
к
нагрузке.
Р
ассмотрим
пример.
Пусть
у
нас
есть
прило
ж
ение
с
регистрацией
поль-
зователей,
которое
позволяет
писать
друг
другу
личные
сообщения.
До-
пу
стим
оно
очень
попу
лярно,
и
много
лю
дей
им
пользуютс
я
ежедневно.
Естественно,
что
т
аблица
с
личными
сообщениями
бу
дет
намного
больше
всех
остальных
т
аблиц
в
базе
(ск
ажем,
бу
дет
занимать
90%
всех
ресур-
сов).
Зная
это,
мы
мож
ем
подготовить
для
этой
(тольк
о
о
дной!)
таблицы
выделенный сервер
помощнее,
а
ост
альные ост
авить на
другом
(посла-
бее).
Т
еперь
мы
мож
ем
идеально
по
дстроить
сервер
для
работы
с
одной
специфическ
ой
т
аблицей,
пост
араться
уместить
ее
в
память,
возможно,
до-
полнительно
партиционировать
ее
и
т
.
д.
Т
ак
ое
распределение
называетс
я
вертик
альным
шардингом.
Что
делать,
если
наша
т
аблица
с
сообщениями
ст
ала
настольк
о
боль-
шой,
что
даж
е
выделенный
сервер
под
нее
одну
уж
е
не
спасает?
Необ
хо-
димо
делать
горизонтальный
шардинг
—
т
.
е.
разделение
о
дной
т
аблицы
по
разным
ресурсам.
Как
это
выглядит
на
практике?
На
разных
серверах
у
нас
бу
дет
т
аблица
с
одинак
овой
структурой,
но
разными
данными.
Для
нашего
случая
с
сообщениями,
мы
мо
жем
хранить
первые
10
миллионов
сообщений
на
одном
сервере,
вторые
10
-
на
втором
и
т
.
д.
Т
.
е.
необ
хо-
димо
иметь
критерий
шар
динга
—
как
ой-то
параметр,
который
позволит
определить,
на
к
аком
именно
сервере
лежат
те
или
иные
данные.
119
6.2.
PL/Proxy
Обычно,
в
ка
честве
параметра
шардинг
а
выбирают
ID
пользователя
(
user_id
)
—
это
позволяет
делить
данные
по
серверам
равномерно
и
просто.
Т
.о.
при
получении
личных сообщений
пользователей алгоритм
работы
бу
дет
так
ой:
∙
Определить,
на
как
ом
сервере
БД
лежат
сообщения
пользователя,
ис
хо
дя
из
user_id
;
∙
Инициализировать
соединение
с
этим
сервером;
∙
Выбрать
сообщения;
Зада
чу
определения
конкретного
сервера
мо
жно
решать
двумя
путями:
∙
Хранить
в о
дном месте х
еш-таблицу
с соответствиями «пользова-
тель=сервер»
.
Т
огда,
при
определении
сервера,
нужно
бу
дет
выбрать
сервер
из
этой
таблицы.
В
этом
случае
узк
ое
место
—
это
большая
т
аблица
соответствия,
к
оторую
нужно
хранить
в
о
дном
месте.
Для
т
аких
целей
очень
хорошо
подх
о
дят
базы
данных
«ключ=зна
чение»;
∙
Определять
имя
сервера
с
помощью
числового
(буквенного)
преобра-
зования.
Например,
можно
вычислять
номер
сервера,
как
остаток
от
деления
на
определенное
число
(к
оличество
серверов,
между
которы-
ми
Вы
делите
т
аблицу).
В
этом
случае
узк
ое
место
—
это
проблема
добавления
новых
серверов
—
придетс
я делать
перераспределение
данных
между
новым
к
оличеством
серверов;
Естественно,
делая
горизонтальный
шардинг
,
Вы
ограничиваете
себя
в
возмо
жности
выборок,
к
оторые
требуют
пересмотра
всей
таблицы
(на-
пример,
последние
посты
в
блог
ах
людей
бу
дет
достать
невозможно,
если
т
аблица
постов
шардитс
я).
Т
акие
задачи
придетс
я
решать
другими
по
дхо-
дами.
Например,
для
описанного
примера,
мо
жно
при
появлении
нового
пост
а,
заносить
его
ID
в
общий
стек,
размером
в
100
элементом.
Г
оризонт
альный
шар
динг
имеет
о
дно
явное
преимущество
—
он
бес-
к
онечно
масштабиру
ем.
Для
создания
шардинг
а
PostgreSQL
существует
неск
олько
решений:
∙
P
ostgres-X
C
∙
Greenplum
Database
∙
Citus
∙
PL/Pro
xy
∙
Stado
(sequel
to
GridSQL)
6.2
PL/Pro
xy
PL/Pro
xy
предст
авляет
собой
прок
си-язык
для
у
даленного
вызова
про-
цедур
и
партицирования
данных
между
разными
базами.
Основная
идея
120
6.2.
PL/Proxy
его
использования
заключаетс
я
в
том,
что
по
является
возмо
жность
вызы-
вать
функции,
располо
женные
в
у
даленных
базах,
а
такж
е
свободно
рабо-
т
ать
с
кластером
баз
данных
(например,
вызвать
функцию
на
всех
узлах
кластера,
или
на
случайном
узле,
или
на
к
аком-то
одном
определенном).
Чем
PL/Proxy
мож
ет
быть
полезен?
Он
существенно
упрощает
го-
ризонт
альное
масшт
абирование
системы.
Ст
ановится
у
добным
разделять
т
аблицу
с
пользователями,
например,
по
первой
латинской
букве
имени
—
на
26
узлов.
При
этом
прилож
ение,
к
оторое
работ
ает
непосредственно
с
прок
си-базой,
ничего
не
бу
дет
замечать:
запрос
на
авторизацию,
напри-
мер,
сам
бу
дет
направлен
прок
си-сервером
на
нужный
узел.
Т
о
есть
адми-
нистратор
баз
данных
мож
ет
прово
дить
масштабирование
системы
прак-
тически
независимо
от
разработчик
ов
прилож
ения.
PL/Pro
xy
позволяет
полностью
решить
проблемы
масшт
абирования
OL
TP
систем.
В
систему
легко
вводитс
я
резервирование
с
failov
er-ом
не
тольк
о
по
узлам,
но
и
по
самим
прокси-серверам,
к
аждый
из
которых
ра-
бот
ает
со
всеми
узлами.
Недост
атки
и
ограничения:
∙
все
запросы
и
вызовы
функций
вызываются
в
auto
commit-режиме
на
у
даленных
серверах;
∙
в
теле
функции
разрешен
только
о
дин
SELECT
.
При
необх
о
димости
нужно
писать
от
дельную
процедуру;
∙
при
к
аждом
вызове
прокси-сервер
ст
артует
новое
соединение
к
бэк
енд-серверу
. В
высок
онагруж
енных
системах
целесообразно
ис-
пользовать
менедж
ер
для
кеширования
соединений
к
бэк
енд-
серверам
(для
этой
цели
идеально
по
дхо
дит
PgBouncer);
∙
изменение
к
онфигурации
кластера
(например
к
оличества
партиций)
требу
ет
перезапуск
а
прокси-сервера;
У
становк
а
1. Ск
ачать
PL/Proxy
и
распаковать;
2. Собрать
PL/Pro
xy
командами
make
и
make
install
;
Т
ак
ж
е
мо
жно
у
становить
PL/Proxy
из
репозитория
пак
етов.
Например
в
Ubun
tu
Server
достаточно
выполнить
команду
для
PostgreSQL
9.6:
Листинг
6.1
У
становк
а
Line
1
$
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
p
o
s
t
g
r
e
s
q
l
-
9
.
6
-
p
l
p
r
o
x
y
Настройк
а
Для
примера
настройки
используетс
я
3
сервера
PostgreSQL.
2
сервера
пу
сть бу
дут
node1
и
node2
, а
главный,
что бу
дет прок
сировать
запросы
121
6.2.
PL/Proxy
на
два
других
—
proxy
.
Для
к
орректной
работы
pl/pro
xy
рекоменду
етс
я
использовать
к
оличество
нод
равное
степеням
двойки.
База
данных
бу
дет
называтьс
я
plproxytest
,
а
т
аблица
в
ней
—
users
.
Для
начала
настроим
no
de1
и
no
de2
.
Команды,
написанные
ниже,
нуж-
но
выполнять
на
каждой
но
де.
Сна
чала
создадим
базу
данных
plproxytest
(если
её
ещё
нет):
Листинг
6.2
Настройка
Line
1
C
R
E
A
T
E
D
A
T
A
B
A
S
E
p
l
p
r
o
x
y
t
e
s
t
-
W
I
T
H
O
W
N
E
R
=
p
o
s
t
g
r
e
s
-
E
N
C
O
D
I
N
G
=
’
U
T
F
8
’
;
Добавляем
т
абличку
users
:
Листинг
6.3
Настройка
Line
1
C
R
E
A
T
E
T
A
B
L
E
p
u
b
l
i
c
.
u
s
e
r
s
-
(
-
u
s
e
r
n
a
m
e
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
(
2
5
5
)
,
-
e
m
a
i
l
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
(
2
5
5
)
5
)
-
W
I
T
H
(
OID
S
=
F
A
L
S
E
)
;
-
A
L
T
E
R
T
A
B
L
E
p
u
b
l
i
c
.
u
s
e
r
s
O
W
N
E
R
T
O
p
o
s
t
g
r
e
s
;
Т
еперь
создадим
функцию
для
добавления
данных
в
т
аблицу
users
:
Листинг
6.4
Настройка
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
p
u
b
l
i
c
.
i
n
s
e
r
t
_
u
s
e
r
(
i
_
u
s
e
r
n
a
m
e
t
e
x
t
,
-
i
_
e
m
a
i
l
a
d
d
r
e
s
s
t
e
x
t
)
-
R
E
T
U
R
N
S
i
n
t
e
g
e
r
A
S
-
$
B
O
D
Y
$
5
I
N
SE
RT I
NT
O
p
u
b
l
i
c
.
u
s
e
r
s
(
u
s
e
r
n
a
m
e
,
e
m
a
i
l
)
V
A
L
U
E
S
(
$
1
,
$
2
)
;
-
S
E
L
E
C
T
1
;
-
$
B
O
D
Y
$
-
L
A
N
G
U
A
G
E
’
s
q
l
’
V
O
L
A
T
I
L
E
;
-
A
L
T
E
R
F
U
N
C
T
I
O
N
p
u
b
l
i
c
.
i
n
s
e
r
t
_
u
s
e
r
(
t
e
x
t
,
t
e
x
t
)
O
W
N
E
R
T
O
p
o
s
t
g
r
e
s
;
С
настройк
ой
нод
закончено.
Приступим
к
серверу
pro
xy
.
Как
и
на
всех
но
дах,
на
главном
сервере
(
proxy
)
должна
присутствовать
база
данных:
Листинг
6.5
Настройка
Line
1
C
R
E
A
T
E
D
A
T
A
B
A
S
E
p
l
p
r
o
x
y
t
e
s
t
-
W
I
T
H
O
W
N
E
R
=
p
o
s
t
g
r
e
s
-
E
N
C
O
D
I
N
G
=
’
U
T
F
8
’
;
122
6.2.
PL/Proxy
Т
еперь
надо
ук
азать
серверу
что
эта
база
данных
управляется
с
помо-
щью
pl/pro
xy:
Листинг
6.6
Настройка
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
p
u
b
l
i
c
.
p
l
p
r
o
x
y
_
c
a
l
l
_
h
a
n
d
l
e
r
(
)
-
R
E
T
U
R
N
S
l
a
n
g
u
a
g
e
_
h
a
n
d
l
e
r
A
S
-
’
$
l
i
b
d
i
r
/
p
l
p
r
o
x
y
’
,
’
p
l
p
r
o
x
y
_
c
a
l
l
_
h
a
n
d
l
e
r
’
-
L
A
N
G
U
A
G
E
’
c
’
V
O
L
A
T
I
L
E
5
C
O
S
T
1
;
-
A
L
T
E
R
F
U
N
C
T
I
O
N
p
u
b
l
i
c
.
p
l
p
r
o
x
y
_
c
a
l
l
_
h
a
n
d
l
e
r
(
)
-
O
W
N
E
R
T
O
p
o
s
t
g
r
e
s
;
-
-
-
l
a
n
g
u
a
g
e
-
C
R
E
A
T
E
L
A
N
G
U
A
G
E
p
l
p
r
o
x
y
H
A
N
D
L
E
R
p
l
p
r
o
x
y
_
c
a
l
l
_
h
a
n
d
l
e
r
;
10
C
R
E
A
T
E
L
A
N
G
U
A
G
E
p
l
p
g
s
q
l
;
Т
акж
е, для того
что бы
сервер
знал г
де и
к
акие но
ды у него
есть,
надо
создать
3
сервисные
функции,
к
оторые
pl/proxy
бу
дет
использовать
в
своей
работе.
Первая
функция
—
конфиг
для
кластера
баз
данных.
Тут
ук
азываются
параметры
через
key-v
alue:
Листинг
6.7
Настройка
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
p
u
b
l
i
c
.
g
e
t
_
c
l
u
s
t
e
r
_
c
o
n
f
i
g
-
(
I
N
c
l
u
s
t
e
r
_
n
a
m
e
t
e
x
t
,
O
U
T
"
k
e
y
"
t
e
x
t
,
O
U
T
v
a
l
t
e
x
t
)
-
R
E
T
U
R
N
S
S
E
T
O
F
r
e
c
o
r
d
AS
-
$
B
O
D
Y
$
5
B
E
G
I
N
-
-
-
l
e
t
s
u
s
e
s
a
m
e
c
o
n
f
i
g
f
o
r
a
l
l
c
l
u
s
t
e
r
s
-
k
e
y
:
=
’
c
o
n
n
e
c
t
i
o
n
_
l
i
f
e
t
i
m
e
’
;
-
v
a
l
:
=
3
0
*
6
0
;
-
-
3
0
m
-
R
E
T
U
R
N
N
E
X
T
;
10
R
E
T
U
R
N
;
-
E
N
D
;
-
$
B
O
D
Y
$
-
L
A
N
G
U
A
G
E
’
p
l
p
g
s
q
l
’
V
O
L
A
T
I
L
E
-
C
O
S
T
1
0
0
15
R
O
W
S
1
0
0
0
;
-
A
L
T
E
R
F
U
N
C
T
I
O
N
p
u
b
l
i
c
.
g
e
t
_
c
l
u
s
t
e
r
_
c
o
n
f
i
g
(
t
e
x
t
)
-
O
W
N
E
R
T
O
p
o
s
t
g
r
e
s
;
Вторая
важная
функция,
к
од
которой
надо
бу
дет
подправить.
В
ней
надо
бу
дет
указать
DSN
нод:
Листинг
6.8
Настройка
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
-
p
u
b
l
i
c
.
g
e
t
_
c
l
u
s
t
e
r
_
p
a
r
t
i
t
i
o
n
s
(
c
l
u
s
t
e
r
_
n
a
m
e
t
e
x
t
)
123
6.2.
PL/Proxy
-
R
E
T
U
R
N
S
S
E
T
O
F
t
e
x
t
AS
-
$
B
O
D
Y
$
5
B
E
G
I
N
-
I
F
c
l
u
s
t
e
r
_
n
a
m
e
=
’
u
s
e
r
c
l
u
s
t
e
r
’
T
H
E
N
-
R
E
T
U
R
N
N
E
X
T
’
d
b
n
a
m
e
=
p
l
p
r
o
x
y
t
e
s
t
h
o
s
t
=n
o
d
e
1
u
s
e
r
=
p
o
s
t
g
r
e
s
’
;
-
R
E
T
U
R
N
N
E
X
T
’
d
b
n
a
m
e
=
p
l
p
r
o
x
y
t
e
s
t
h
o
s
t
=n
o
d
e
2
u
s
e
r
=
p
o
s
t
g
r
e
s
’
;
-
R
E
T
U
R
N
;
10
E
N
D
I
F
;
-
RAI
SE
E
X
C
E
P
T
I
O
N
’
Unkn
own
c
l
u
s
t
e
r
’
;
-
E
N
D
;
-
$
B
O
D
Y
$
-
L
A
N
G
U
A
G
E
’
p
l
p
g
s
q
l
’
V
O
L
A
T
I
L
E
15
C
O
S
T
1
0
0
-
R
O
W
S
1
0
0
0
;
-
A
L
T
E
R
F
U
N
C
T
I
O
N
p
u
b
l
i
c
.
g
e
t
_
c
l
u
s
t
e
r
_
p
a
r
t
i
t
i
o
n
s
(
t
e
x
t
)
-
O
W
N
E
R
T
O
p
o
s
t
g
r
e
s
;
И
последняя:
Листинг
6.9
Настройка
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
-
p
u
b
l
i
c
.
g
e
t
_
c
l
u
s
t
e
r
_
v
e
r
s
i
o
n
(
c
l
u
s
t
e
r
_
n
a
m
e
t
e
x
t
)
-
R
E
T
U
R
N
S
i
n
t
e
g
e
r
A
S
-
$
B
O
D
Y
$
5
B
E
G
I
N
-
I
F
c
l
u
s
t
e
r
_
n
a
m
e
=
’
u
s
e
r
c
l
u
s
t
e
r
’
T
H
E
N
-
R
E
T
U
R
N
1
;
-
E
N
D
I
F
;
-
RAI
SE
E
X
C
E
P
T
I
O
N
’
Unkn
own
c
l
u
s
t
e
r
’
;
10
E
N
D
;
-
$
B
O
D
Y
$
-
L
A
N
G
U
A
G
E
’
p
l
p
g
s
q
l
’
V
O
L
A
T
I
L
E
-
C
O
S
T
1
0
0
;
-
A
L
T
E
R
F
U
N
C
T
I
O
N
p
u
b
l
i
c
.
g
e
t
_
c
l
u
s
t
e
r
_
v
e
r
s
i
o
n
(
t
e
x
t
)
15
O
W
N
E
R
T
O
p
o
s
t
g
r
e
s
;
Ну
и
собственно
самая
главная
функция,
которая
бу
дет
вызываться
уж
е
непосредственно
в
прилож
ении:
Листинг
6.10
Настройка
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
-
p
u
b
l
i
c
.
i
n
s
e
r
t
_
u
s
e
r
(
i
_
u
s
e
r
n
a
m
e
t
e
x
t
,
i
_
e
m
a
i
l
a
d
d
r
e
s
s
t
e
x
t
)
-
R
E
T
U
R
N
S
i
n
t
e
g
e
r
A
S
-
$
B
O
D
Y
$
124
6.2.
PL/Proxy
5
C
L
U
S
T
E
R
’
u
s
e
r
c
l
u
s
t
e
r
’
;
-
R
U
N
O
N
h
a
s
h
t
e
x
t
(
i
_
u
s
e
r
n
a
m
e
)
;
-
$
B
O
D
Y
$
-
L
A
N
G
U
A
G
E
’
p
l
p
r
o
x
y
’
V
O
L
A
T
I
L
E
-
C
O
S
T
1
0
0
;
10
A
L
T
E
R
F
U
N
C
T
I
O
N
p
u
b
l
i
c
.
i
n
s
e
r
t
_
u
s
e
r
(
t
e
x
t
,
t
e
x
t
)
-
O
W
N
E
R
T
O
p
o
s
t
g
r
e
s
;
Все
готово.
По
дключаемся
к
серверу
proxy
и
заносим
данные
в
базу:
Листинг
6.11
Настройка
Line
1
S
E
L
E
C
T
i
n
s
e
r
t
_
u
s
e
r
(
’
S
v
e
n
’
,
’
s
v
e
n
@
s
o
m
e
w
h
e
r
e
.
com
’
)
;
-
S
E
L
E
C
T
i
n
s
e
r
t
_
u
s
e
r
(
’
M
a
r
k
o
’
,
’
m
a
r
k
o
@
s
o
m
e
w
h
e
r
e
.
co
m
’
)
;
-
S
E
L
E
C
T
i
n
s
e
r
t
_
u
s
e
r
(
’
S
t
e
v
e
’
,
’
s
t
e
v
e
@
s
o
m
e
w
h
e
r
e
.
com
’
)
;
Пробу
ем
извлечь
данные.
Для
этого
напишем
новую
серверную
функ-
цию:
Листинг
6.12
Настройка
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
-
p
u
b
l
i
c
.
g
e
t
_
u
s
e
r
_
e
m
a
i
l
(
i
_
u
s
e
r
n
a
m
e
t
e
x
t
)
-
R
E
T
U
R
N
S
S
E
T
O
F
t
e
x
t
A
S
-
$
B
O
D
Y
$
5
C
L
U
S
T
E
R
’
u
s
e
r
c
l
u
s
t
e
r
’
;
-
R
U
N
O
N
h
a
s
h
t
e
x
t
(
i
_
u
s
e
r
n
a
m
e
)
;
-
S
E
L
E
C
T
e
m
a
i
l
F
R
O
M
p
u
b
l
i
c
.
u
s
e
r
s
-
W
H
E
R
E
u
s
e
r
n
a
m
e
=
i
_
u
s
e
r
n
a
m
e
;
-
$
B
O
D
Y
$
10
L
A
N
G
U
A
G
E
’
p
l
p
r
o
x
y
’
V
O
L
A
T
I
L
E
-
C
O
S
T
1
0
0
-
R
O
W
S
1
0
0
0
;
-
A
L
T
E
R
F
U
N
C
T
I
O
N
p
u
b
l
i
c
.
g
e
t
_
u
s
e
r
_
e
m
a
i
l
(
t
e
x
t
)
-
O
W
N
E
R
T
O
p
o
s
t
g
r
e
s
;
И
попробу
ем
её
вызвать:
Листинг
6.13
Настройка
Line
1
S
E
L
E
C
T
p
l
p
r
o
x
y
.
g
e
t
_
u
s
e
r
_
e
m
a
i
l
(
’
S
t
e
v
e
’
)
;
Если
потом
по
дключиться
к
каждой
ноде
отдельно,
то
мо
жно
четк
о
увидеть,
что
данные
users
разбросаны
по
таблицам
каждой
ноды.
Все
ли
т
ак
просто?
Как
видно
на
тестовом
примере
ничего
сложного
в
работе
с
pl/pro
xy
нет
.
Но
в
реальной
жизни
все
не
так
просто.
Предст
авьте
что
у
вас
16
нод.
125
6.3.
Postgres-X2
Это
же
надо
к
ак-то
синхронизировать
ко
д
функций.
А
что
если
ошибка
закрадётс
я
—
как
её
оперативно
исправлять?
Этот вопрос
был задан и
на к
онференции Highload++
2008,
на что
Аск
о
Ойя
ответил
что
соответствующие
средства
уж
е
реализованы
внутри
самого
Skyp
e,
но
ещё
не
достаточно
готовы
для
того
что
бы
отдавать
их
на
су
д
сообществу
op
ensource.
Вторая
проблема,
которая
не
дай
бог
к
оснётс
я
вас
при
разработк
е
та-
к
ого рода системы,
это проблема перераспределения данных
в тот мо-
мент
,
ког
да
нам
захочетс
я
добавить
ещё
но
д
в
кластер.
Планировать
эту
масшт
абную
операцию
придётс
я
очень
тщательно,
по
дготовив
все
серве-
ра
заранее,
занес
я
данные
и
потом
в
один
момент
по
дменив
ко
д
функции
get_cluster_partitions
.
6.3
P
ostgres-X2
P
ostgres-X2
–
система
для
создания
му
ль
ти-мастер
кластеров,
работ
а-
ющих
в
синхронном
режиме
–
все
узлы
всег
да
содер
ж
ат
акту
альные
дан-
ные.
Postgres-X2
поддер
живает
опции
для
увеличения
масшт
абирования
кластера
как
при
преобладании
операций
записи,
так
и
при
основной
на-
грузк
е
на
чтение
данных:
по
ддер
живается
выполнение
транзакций
с
рас-
параллеливанием
на
нескольк
о
узлов,
за
целостностью
транзакций
в
пре-
делах
всего
кластера
отвечает
специальный
узел
GTM
(Global
T
ransaction
Manager).
Измерение
произво
дительности
показало,
что
КПД
кластера
Postgres-
X2
составляет
примерно
64%,
т
.
е.
кластер
из
10
серверов
позволяет
до-
битьс
я
увеличения
производительности
системы
в
целом
в
6.4
раза,
отно-
сительно
произво
дительности
одного
сервера
(цифры
приблизительные).
Система
не
использует
в
своей
работе
триггеры
и
предст
авляет
собой
набор
дополнений
и
патчей
к
PostgreSQL,
дающих
возмо
жность
в
про-
зра
чном
режиме
обеспечить
работу
в
кластере
стандартных
прилож
ений,
без
их
дополнительной
мо
дификации
и
адапт
ации
(полная
совместимость
с
PostgreSQL
API).
Кластер
состоит
из
одного
управляющего
узла
(GTM),
предост
авляющего
информацию
о
состоянии
транзакций,
и
произвольно-
го
набора
рабочих
узлов,
каждый
из
к
оторых
в
свою
очередь
состоит
из
к
оординатора
и
обработчик
а
данных
(обычно
эти
элементы
реализуются
на
о
дном
сервере,
но
могут
быть
и
разделены).
Хоть P
ostgres-X2 и
выг
лядит по
хо
жим на
MultiMaster,
но он
им
не
являетс
я.
Все
сервера
кластера
должны
быть
соединены
сетью
с
мини-
мальными
задержк
ами,
никак
ое
географически-распределенное
решение
с
разумной
производительностью
построить
на
нем
невозмо
жно
(это
важ-
ный
момент).
126
6.3.
Postgres-X2
Рис.
6.1:
Ар
хитектура
Postgres-X2
Ар
хитектура
Рис.
6.1
пок
азывает ар
хитектуру P
ostgres-X2 с тремя её основными
к
омпонентами:
1. Г
лобальный
менеджер
транзакций
(GTM)
—
собирает
и
обрабатыва-
ет
информацию
о
транзакциях
в
P
ostgres-X2,
решает
вопросы
г
ло-
бального
идентификатора
транзакции
по
операциям
(для
по
ддерж
а-
ния
сог
ласованного
предст
авления
базы
данных
на
всех
узлах).
Он
обеспечивает
по
ддержку
других
г
лобальных
данных,
т
аких
как
по-
следовательности
и
временные
метки.
Он
хранит
данные
пользова-
теля,
за
исключением
управляющей
информации;
2. Коор
динаторы
(co
ordinators)
—
обеспечивают
точку
подключения
для
клиент
а
(прилож
ения).
Они
несут
ответственность
за
разбор
и
выполнение
запросов
от
клиентов
и
возвращение
резу
льт
атов
(при
необ
хо
димости). Они не хранят пользовательские
данные, а соби-
рают
их
из
обработчиков
данных
(datano
des)
с
помощью
запросов
SQL
через
PostgreSQL
интерфейс.
Координаторы
т
акже
обрабаты-
вают
данные,
если
требуетс
я,
и
даж
е
управляют
двухфазной
фик-
127
6.3.
Postgres-X2
сацией.
Коор
динаторы
используютс
я
т
акж
е
для
разбора
запросов,
сост
авления
планов
запросов,
поиска
данных
и
т
.д;
3. Обработчики
данных
(datano
des)
—
обеспечивают
со
хранение
поль-
зовательских
данных.
Datano
des
выполняют
запросы
от
коор
дина-
торов
и
возвращают
им
полученный
резу
ль
тат;
У
становк
а
У
ст
ановить
Postgres-X2
можно
из
исх
одник
ов
.
Р
аспределение
данных
и
масштабиру
емость
P
ostgres-X2
предусматривает
два
способа
хранения
данных
в
т
аблицах:
Рис.
6.2:
Р
аспределенные
таблицы
Рис.
6.3:
Р
еплицированные
таблицы
128
6.3.
Postgres-X2
1. Р
аспределенные
таблицы
(distributed
tables,
рис.
6.2
):
данные
по
т
аб-
лице
распределяются
на
ук
азанный
набор
обработчиков
данных
с
ис-
пользованием
указанной
стратегии
(hash,
round-robin,
mo
dulo).
Каж-
дая
запись
в
т
аблице
нах
о
дится
только
на
одном
обработчике
дан-
ных.
Параллельно
могут
быть записаны
или прочит
аны данные
с
различных
обработчиков
данных.
За
счет
этого
значительно
у
луч-
шена
произво
дительность
на
запись
и
чтение;
2. Р
еплицированные
таблицы
(replicated
tables,
рис.
6.3
):
данные
по
т
аб-
лице
реплицируетс
я
(клонируются)
на
указанный
набор
обработчи-
к
ов
данных.
Каждая
запись
в
т
аблице
нах
одитс
я
на
всех
обработчи-
к
ах
данных
(которые
были
ук
азаны)
и
любые
изменения
дублиру-
ютс
я
на
все
обработчики
данных.
Т
ак
как
все
данные
доступны
на
любом
обработчике
данных,
к
оординатор
мо
жет
собрать
все
данные
из
о
дного
узла,
что
позволяет
направить
различные
запросы
на
раз-
личные
обработчики
данных.
Т
аким
образом
создаетс
я
балансировка
нагрузки
и
увеличения
пропу
скной
способности
на
чтение;
Т
аблицы
и
запросы
к
ним
После
у
становки работа с
Postgres-X2 ведетс
я
как с
обыкновенным
P
ostgreSQL. По
дключаться
для работы
с
данными нужно
тольк
о к
ко-
ор
динаторам
(по
умолчанию
коор
динатор
работает
на
порту
5432).
Для
на
чала
создадим
распределенные
таблицы:
Листинг
6.14
Создание
распределенных
таблиц
Line
1
C
R
E
A
T
E
T
A
B
L
E
-
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
(
i
d
SER
IAL
,
t
y
p
e
IN
T
,
.
.
.
)
-
D
IS
T
RI
B
UT
E
b
y
H
A
S
H(
i
d
)
;
-
5
C
R
E
A
T
E
T
A
B
L
E
-
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
(
i
d
SE
RIAL
,
t
y
p
e
INT
,
.
.
.
)
-
D
IS
T
RI
B
UT
E
b
y
M
O
D
U
L
O
(
i
d
)
;
-
-
C
R
E
A
T
E
T
A
B
L
E
10
u
s
e
r
s
_
w
i
t
h
_
r
r
o
b
i
n
(
i
d
SE
RI
AL
,
t
y
p
e
IN
T
,
.
.
.
)
-
D
IS
T
RI
B
UT
E
b
y
R
O
U
N
D
R
O
B
I
N
;
На
листинге
6.14
создано
3
распределенные
т
аблицы:
1. Т
аблица
users_with_hash
распределяется
по
хешу
значения
из
указан-
ного
поля
в
таблице
(тут
указано
поле
id)
по
обработчикам
данных.
Вот
к
ак
распределились
первые
15
значений:
Листинг
6.15
Данные
с
коор
динатора
и
обработчиков
данных
129
6.3.
Postgres-X2
Line
1
# к
оор
динатор
-
$
p
s
q
l
-
#
S
E
L
E
C
T
i
d
,
t
y
p
e
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
O
R
D
E
R
B
Y
i
d
;
-
i
d
|
t
y
p
e
5
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
1
|
9
4
6
-
2
|
1
5
3
-
3
|
4
8
4
-
4
|
4
2
2
10
5
|
7
8
5
-
6
|
9
0
6
-
7
|
9
7
3
-
8
|
6
9
9
-
9
|
4
3
4
15
1
0
|
9
8
6
-
1
1
|
1
3
5
-
1
2
|
1
0
1
2
-
1
3
|
3
9
5
-
1
4
|
6
6
7
20
1
5
|
3
2
4
-
-
# первый
обработчик
данных
-
$
p
s
q
l
-
p
1
5
4
3
2
-
#
S
E
L
E
C
T
i
d
,
t
y
p
e
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
O
R
D
E
R
B
Y
i
d
;
25
i
d
|
t
y
p
e
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
1
|
9
4
6
-
2
|
1
5
3
-
5
|
7
8
5
30
6
|
9
0
6
-
8
|
6
9
9
-
9
|
4
3
4
-
1
2
|
1
0
1
2
-
1
3
|
3
9
5
35
1
5
|
3
2
4
-
-
# второй
обработчик
данных
-
$
p
s
q
l
-
p
1
5
4
3
3
-
#
S
E
L
E
C
T
i
d
,
t
y
p
e
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
O
R
D
E
R
B
Y
i
d
;
40
i
d
|
t
y
p
e
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
3
|
4
8
4
-
4
|
4
2
2
-
7
|
9
7
3
45
1
0
|
9
8
6
-
1
1
|
1
3
5
-
1
4
|
6
6
7
130
6.3.
Postgres-X2
2. Т
аблица
users_with_mo
dulo
распределяется
по
моду
лю
зна
чения
из
ук
азанного
поля
в
таблице
(тут
указано
поле
id)
по
обработчикам
данных.
Вот
к
ак
распределились
первые
15
значений:
Листинг
6.16
Данные
с
коор
динатора
и
обработчиков
данных
Line
1
# к
оор
динатор
-
$
p
s
q
l
-
#
S
E
L
E
C
T
i
d
,
t
y
p
e
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
O
R
D
E
R
B
Y
i
d
;
-
i
d
|
t
y
p
e
5
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
1
|
8
8
3
-
2
|
7
1
9
-
3
|
2
9
-
4
|
6
3
8
10
5
|
3
6
3
-
6
|
9
4
6
-
7
|
4
4
0
-
8
|
3
3
1
-
9
|
8
8
4
15
1
0
|
1
9
9
-
1
1
|
7
8
-
1
2
|
7
9
1
-
1
3
|
3
4
5
-
1
4
|
4
7
6
20
1
5
|
8
6
0
-
-
# первый
обработчик
данных
-
$
p
s
q
l
-
p
1
5
4
3
2
-
#
S
E
L
E
C
T
i
d
,
t
y
p
e
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
O
R
D
E
R
B
Y
i
d
;
25
i
d
|
t
y
p
e
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
2
|
7
1
9
-
4
|
6
3
8
-
6
|
9
4
6
30
8
|
3
3
1
-
1
0
|
1
9
9
-
1
2
|
7
9
1
-
1
4
|
4
7
6
-
35
# второй
обработчик
данных
-
$
p
s
q
l
-
p
1
5
4
3
3
-
#
S
E
L
E
C
T
i
d
,
t
y
p
e
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
O
R
D
E
R
B
Y
i
d
;
-
i
d
|
t
y
p
e
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
40
1
|
8
8
3
-
3
|
2
9
131
6.3.
Postgres-X2
-
5
|
3
6
3
-
7
|
4
4
0
-
9
|
8
8
4
45
1
1
|
7
8
-
1
3
|
3
4
5
-
1
5
|
8
6
0
3. Т
аблица
users_with_rrobin
распределяетс
я
циклическим
способом(round-robin)
по
обработчик
ам
данных.
Вот
как
рас-
пределились
первые
15
зна
чений:
Листинг
6.17
Данные
с
коор
динатора
и
обработчиков
данных
Line
1
# к
оор
динатор
-
$
p
s
q
l
-
#
S
E
L
E
C
T
i
d
,
t
y
p
e
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
r
r
o
b
i
n
O
R
D
E
R
B
Y
i
d
;
-
i
d
|
t
y
p
e
5
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
1
|
8
9
0
-
2
|
1
9
8
-
3
|
8
1
5
-
4
|
4
4
6
10
5
|
6
1
-
6
|
3
3
7
-
7
|
9
4
8
-
8
|
4
4
6
-
9
|
7
9
6
15
1
0
|
4
2
2
-
1
1
|
2
4
2
-
1
2
|
7
9
5
-
1
3
|
3
1
4
-
1
4
|
2
4
0
20
1
5
|
7
3
3
-
-
# первый
обработчик
данных
-
$
p
s
q
l
-
p
1
5
4
3
2
-
#
S
E
L
E
C
T
i
d
,
t
y
p
e
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
r
r
o
b
i
n
O
R
D
E
R
B
Y
i
d
;
25
i
d
|
t
y
p
e
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
2
|
1
9
8
-
4
|
4
4
6
-
6
|
3
3
7
30
8
|
4
4
6
-
1
0
|
4
2
2
-
1
2
|
7
9
5
-
1
4
|
2
4
0
-
132
6.3.
Postgres-X2
35
# второй
обработчик
данных
-
$
p
s
q
l
-
p
1
5
4
3
3
-
#
S
E
L
E
C
T
i
d
,
t
y
p
e
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
r
r
o
b
i
n
O
R
D
E
R
B
Y
i
d
;
-
i
d
|
t
y
p
e
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
40
1
|
8
9
0
-
3
|
8
1
5
-
5
|
6
1
-
7
|
9
4
8
-
9
|
7
9
6
45
1
1
|
2
4
2
-
1
3
|
3
1
4
-
1
5
|
7
3
3
Т
еперь
создадим
реплицированную
т
аблицу:
Листинг
6.18
Создание
реплицированной
таблицы
Line
1
C
R
E
A
T
E
T
A
B
L
E
-
u
s
e
r
s
_
r
e
p
l
i
c
a
t
e
d
(
i
d
SERI
AL
,
t
y
p
e
INT
,
.
.
.
)
-
D
IS
T
RI
B
UT
E
b
y
R
E
P
L
I
C
A
T
I
O
N
;
Естественно
данные
идентичны
на
всех
обработчик
ах
данных:
Листинг
6.19
Данные
с
коор
динатора
и
обработчиков
данных
Line
1
#
S
E
L
E
C
T
i
d
,
t
y
p
e
f
r
o
m
u
s
e
r
s
_
r
e
p
l
i
c
a
t
e
d
O
R
D
E
R
B
Y
i
d
;
-
i
d
|
t
y
p
e
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
1
|
7
5
5
2
|
2
6
2
-
3
|
4
5
8
-
4
|
7
7
9
-
5
|
3
5
7
-
6
|
5
1
10
7
|
2
4
9
-
8
|
4
4
4
-
9
|
8
9
0
-
1
0
|
8
1
0
-
1
1
|
8
0
9
15
1
2
|
1
6
6
-
1
3
|
6
0
5
-
1
4
|
4
0
1
-
1
5
|
5
8
Р
ассмотрим
к
ак
выполняются
запросы
для
таблиц.
Выберем
все
записи
из
распределенной
т
аблицы:
133
6.3.
Postgres-X2
Листинг
6.20
Выборка
записей
из
распределенной
таблицы
Line
1
#
E
X
P
L
A
I
N V
E
R
B
O
S
E
S
E
L
E
C
T
*
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
O
R
D
E
R
B
Y
i
d
;
-
Q
U
E
R
Y
P
L
A
N
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
S
o
r
t
(
c
o
s
t
=
4
9
.
8
3
.
.
5
2
.
3
3
r
o
w
s
=
1
0
0
0
w
i
d
t
h
=
8
)
5
O
u
t
p
u
t
:
i
d
,
t
y
p
e
-
S
o
r
t
K
ey
:
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
i
d
-
-
>
R
e
s
u
l
t
(
c
o
s
t
=
0
.
0
0
.
.
0
.
0
0
r
o
w
s
=
1
0
0
0
w
i
d
t
h
=
8
)
-
O
u
t
p
u
t
:
i
d
,
t
y
p
e
-
-
>
D
a
t
a
N
o
d
e
S
c
a
n
o
n
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
(
c
o
s
t
=
0
.
0
0
.
.
0
.
0
0
r
o
w
s
=
1
0
0
0
w
i
d
t
h
=
8
)
10
O
u
t
p
u
t
:
i
d
,
t
y
p
e
-
N
o
d
e
/
s
:
d
n
1
,
d
n
2
-
R
e
m
o
t
e
q
u
e
r
y
:
S
E
L
E
C
T
i
d
,
t
y
p
e
F
R
O
M
O
N
L
Y
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
W
H
E
R
E
t
r
u
e
-
(
9
r
o
w
s
)
Как
видно
на
листинге
6.20
коор
динатор
собирает
данные
из
обработ-
чик
ов
данных,
а
потом
собирает
их
вместе.
По
дсчет
суммы
с
группировкой
по
полю
из
распределенной
таблицы:
Листинг
6.21
Выборка
записей
из
распределенной
таблицы
Line
1
#
E
X
P
L
A
I
N V
E
R
B
O
S
E
S
E
L
E
C
T
sum
(
i
d
)
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
G
R
O
U
P
B
Y
t
y
p
e
;
-
Q
U
E
R
Y
P
L
A
N
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
H
a
s
h
A
g
g
r
e
g
a
t
e
(
c
o
s
t
=
5
.
0
0
.
.
5
.
0
1
r
o
w
s
=
1
w
i
d
t
h
=
8
)
5
O
u
t
p
u
t
:
p
g
_
c
a
t
a
l
o
g
.
sum
(
(
sum
(
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
i
d
)
)
)
,
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
t
y
p
e
-
-
>
M
a
t
e
r
i
a
l
i
z
e
(
c
o
s
t
=
0
.
0
0
.
.
0
.
0
0
r
o
w
s
=
0
w
i
d
t
h
=
0
)
-
O
u
t
p
u
t
:
(
sum
(
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
i
d
)
)
,
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
t
y
p
e
-
-
>
D
a
t
a
N
o
d
e
S
c
a
n
o
n
"
_
_
R
E
M
O
T
E
_
G
R
O
U
P
_
Q
U
E
R
Y
_
_
"
(
c
o
s
t
=
0
.
0
0
.
.
0
.
0
0
r
o
w
s
=
1
0
0
0
w
i
d
t
h
=
8
)
-
O
u
t
p
u
t
:
s
um
(
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
i
d
)
,
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
t
y
p
e
10
N
o
d
e
/
s
:
d
n
1
,
d
n
2
-
R
e
m
o
t
e
q
u
e
r
y
:
S
E
L
E
C
T
sum
(
g
r
o
u
p
_
1
.
i
d
)
,
g
r
o
u
p
_
1
.
t
y
p
e
F
R
O
M
(
S
E
L
E
C
T
i
d
,
t
y
p
e
F
R
O
M
O
N
L
Y
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
W
H
E
R
E
t
r
u
e
)
g
r
o
u
p
_
1
G
R
O
U
P
B
Y
2
134
6.3.
Postgres-X2
-
(
8
r
o
w
s
)
JOIN между и с участием реплицированных т
аблиц, а такж
е JOIN
между
распределенными
по
о
дному
и
тому
ж
е
полю
в
т
аблицах
бу
дет
вы-
полняютс
я
на
обработчик
ах
данных.
Но
JOIN
с
участием
распределенных
т
аблиц
по
другим
ключам
бу
дут
выполнены
на
к
оординаторе
и
скорее
все-
го
это
бу
дет
медленно
(листинг
6.22
).
Листинг
6.22
Выборка
записей
из
распределенной
таблицы
Line
1
#
E
X
P
L
A
I
N V
E
R
B
O
S
E
S
E
L
E
C
T
*
f
r
o
m
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
,
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
W
H
E
R
E
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
i
d
=
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
.
i
d
;
-
Q
U
E
R
Y
P
L
A
N
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
N
e
s
t
e
d
L
o
o
p
(
c
o
s
t
=
0
.
0
0
.
.
0
.
0
1
r
o
w
s
=1
w
i
d
t
h
=
1
6
)
5
O
u
t
p
u
t
:
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
i
d
,
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
t
y
p
e
,
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
.
i
d
,
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
.
t
y
p
e
-
J
o
i
n
F
i
l
t
e
r
:
(
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
i
d
=
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
.
i
d
)
-
-
>
D
a
t
a
N
o
d
e
S
c
a
n
o
n
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
(
c
o
s
t
=
0
.
0
0
.
.
0
.
0
0
r
o
w
s
=
1
0
0
0
w
i
d
t
h
=
8
)
-
O
u
t
p
u
t
:
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
i
d
,
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
.
t
y
p
e
-
N
o
d
e
/
s
:
d
n
1
,
d
n
2
10
R
e
m
o
t
e
q
u
e
r
y
:
S
E
L
E
C
T
i
d
,
t
y
p
e
F
R
O
M
O
N
L
Y
u
s
e
r
s
_
w
i
t
h
_
m
o
d
u
l
o
W
H
E
R
E
t
r
u
e
-
-
>
D
a
t
a
N
o
d
e
S
c
a
n
o
n
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
(
c
o
s
t
=
0
.
0
0
.
.
0
.
0
0
r
o
w
s
=
1
0
0
0
w
i
d
t
h
=
8
)
-
O
u
t
p
u
t
:
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
.
i
d
,
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
.
t
y
p
e
-
N
o
d
e
/
s
:
d
n
1
,
d
n
2
-
R
e
m
o
t
e
q
u
e
r
y
:
S
E
L
E
C
T
i
d
,
t
y
p
e
F
R
O
M
O
N
L
Y
u
s
e
r
s
_
w
i
t
h
_
h
a
s
h
W
H
E
R
E
t
r
u
e
15
(
1
1
r
o
w
s
)
Пример
выборки
данных
из
реплицированной
т
аблицы:
Листинг
6.23
Выборка
записей
из
реплицированной
таблицы
Line
1
#
E
X
P
L
A
I
N V
E
R
B
O
S
E
S
E
L
E
C
T
*
f
r
o
m
u
s
e
r
s
_
r
e
p
l
i
c
a
t
e
d
;
-
Q
U
E
R
Y
P
L
A
N
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
D
a
t
a
No
d
e
S
c
a
n
o
n
"
_
_
R
E
M
O
T
E
_
F
Q
S
_
Q
U
E
R
Y
_
_
"
(
c
o
s
t
=
0
.
0
0
.
.
0
.
0
0
r
o
w
s
=0
w
i
d
t
h
=
0
)
5
O
u
t
p
u
t
:
u
s
e
r
s
_
r
e
p
l
i
c
a
t
e
d
.
i
d
,
u
s
e
r
s
_
r
e
p
l
i
c
a
t
e
d
.
t
y
p
e
135
6.3.
Postgres-X2
-
N
o
d
e
/
s
:
d
n
1
-
R
e
m
o
t
e
q
u
e
r
y
:
S
E
L
E
C
T
i
d
,
t
y
p
e
F
R
O
M
u
s
e
r
s
_
r
e
p
l
i
c
a
t
e
d
-
(
4
r
o
w
s
)
Как
видно
из
запроса
для
выборки
данных
использу
етс
я
один
обработ-
чик
данных,
а
не
все
(что
логично).
Высок
ая
доступность
(HA)
По
архитектуре
у
Postgres-X2
всегда
есть
согласованность
данных.
По
теореме
CAP
в
т
акой
системе
т
яжело
обеспечить
высокую
доступность.
Для достиж
ения
высок
ой доступности
в
распределенных
системах
тре-
бу
ется
избыточность
данных,
резервные
к
опии
и
автоматическое
восст
а-
новление.
В
Postgres-X2
избыточность
данных
мож
ет
быть
достигнута
с
помощью
PostgreSQL
потоковой
(streaming)
репликации
с
hot-standby
для
обработчик
ов
данных.
Каждый
к
оор
динатор
способен
записывать
и
чи-
т
ать
данные
независимо
от
другого,
поэтому
к
оординаторы
способны
за-
менять
друг
друг
а. Поск
ольку
GTM
от
дельный
процесс
и
мо
ж
ет
ст
ать
точк
ой
отк
аза,
лучше
создать
GTM-standb
y
к
ак
резервную
к
опию.
Ну
а
вот
для
автоматического
восстановления
придется
использовать
сторон-
ние
утилиты.
Ограничения
1. P
ostgres-X2
базируетс
я
на
PostgreSQL
9.3;
2. Нет системы репартиционирования
при добавлении
или у
далении
но
д;
3. Нет
г
лобальных
UNIQUE
на
распределенных
таблицах;
4. Не
поддер
живаютс
я
foreign
k
eys
между
но
дами
поскольку
т
акой
ключ
долж
ен
вести
на
данные
располо
ж
енные
на
том
ж
е
обработ-
чик
е
данных;
5. Не
по
ддерживаютс
я
курсоры;
6. Не
по
ддерживаетс
я
INSER
T
...
RETURNING
;
7. Невозмо
жно
у
даление
и
добавление
нод
в
кластер
без
полной
реини-
циализации
кластера;
Заключение
P
ostgres-X2 очень
перспективное
решение
для
создания
кластера на
основе
PostgreSQL.
И
хоть
это
решение
имеет
ряд
недостатк
ов,
нестабиль-
но
(очень
часты
случаи
падения
к
оординаторов
при
тяж
елых
запросах)
и
еще
очень
молодое,
со
временем
это
решение
мож
ет
ст
ать
ст
андартом
для
масшт
абирования
систем
на
PostgreSQL.
136
6.4.
Postgres-XL
6.4
P
ostgres-XL
P
ostgres-XL
–
система
для
создания
му
льти-мастер
кластеров,
работ
аю-
щих
в
синхронном
режиме
–
все
узлы
всегда
со
держ
ат
актуальные
данные.
Проект
построен
на
основе
ко
довой
базы
Postgres-X2,
поэтому
ар
хитек-
турный
по
дхо
д
полностью
идентичен
(глобальный
менеджер
транзакций
(GTM),
коор
динаторы
(co
ordinators)
и
обработчики
данных
(datano
des)).
Более
по
дробно
про
архитектуру
можно
почитать
в «
6.3
Архитектура
»
разделе.
Поэтому
рассмотрим
тольк
о
отличие
Postgres-X2
и
Postgres-XL.
P
ostgres-X2
и
Postgres-XL
Одно
из
главных
отличий
P
ostgres-XL
от
Postgres-X2
является
у
луч-
шенный
мех
анизм
массово-параллельной
ар
хитектуры
(massive
parallel
pro
cessing,
MPP).
Чтобы
понять
разницу
,
давайте
рассмотрим
как
P
ostgres-X2
и
P
ostgres-XL
бу
дет
обрабатывать
разные
SQL
запросы.
Оба
этих
кластера
бу
дут
содер
ж
ать
три
таблицы
T1
,
T2
и
R1
.
T1
имеет
к
олонки
a1
и
a2
,
T2
—
b1
и
b2
.
T1
распределена
в
кластере
по
a1
полю
и
T2
распре-
делена
по
b1
полю.
R1
т
аблица
имеет
к
олонки
c1
и
c2
и
реплициру
ется
в
кластере
(
DISTRIBUTE
b
y
REPLICA
TION
).
Для
на
чала,
простой
запрос
вида
SELECT
*
FROM
T1
бу
дет
параллель-
но
выполняться
на
но
дах
к
ак
у
P
ostgres-X2,
так
и
у
Postgres-XL.
Другой
пример
запроса
SELECT
*
FR
OM
T1
INNER
JOIN
R1
ON
T1.a1
=
R1.c1
бу-
дет
т
акже
выполняться
параллельно
обоими
кластерами,
потому
что
бу
дет
передан
(«pushed
do
wn»)
на
обработчики
данных
(datano
des)
для
выпол-
нения
и
к
оординатор
(co
ordinators)
бу
дет
только
агрегировать
(собирать)
резу
ль
таты
запросов.
Это
бу
дет
работ
ать
благодар
я
тому
,
что
R1
таблица
дублициру
ется
на
каждом
обработчике
данных.
Этот
тип
запросов
бу
дет
работ
ать
хорошо,
к
огда
T1
является
таблицей
фактов
(основной
таблицей
хранилища
данных),
в
то
время
к
ак
R1
—
таблицей
измерений
(содер
жит
атрибуты
событий,
со
храненных
в
таблице
фактов).
Т
еперь
рассмотрим
другой
вариант
SQL
запроса:
Листинг
6.24
Запрос
на
распределенные
таблицы
Line
1
#
S
E
L
E
C
T
*
F
R
O
M
T1
I
N
N
E
R
JOIN
T2
O
N
T1
.
a
1
= T2
.
b
2
Данный
запрос
делает
JOIN
по
распределенной
к
олонке
a1
в
т
аблице
T1
и
по
НЕ
распределенной
колонк
е
b2
в
т
аблице
T2
.
В
кластере,
к
оторый
состоит
из
4
обработчиков
данных,
к
олонк
а
в
таблице
T1
на
первом
из
них
потенциально
требу
етс
я
объединить
с
к
олонками
таблицы
T2
на
всех
обработчик
ах
данных
в
кластере.
У
P
ostgres-X2
в
данном
случае
обработчики
данных
отправляют
все
данные
по
заданному
условию
в
запросе
к
коор
динатору
,
к
оторый
и
за-
нимаетс
я
объединением
данных
с
таблиц.
В
данном
примере
отсутствует
137
6.5.
Citus
у
словие
WHERE
,
что
зна
чит
,
что
все
обработчики
данных
отправят
все
со
держимое
т
аблиц
T1
и
T2
на
к
оординатор,
к
оторый
и
бу
дет
делать
JOIN
данных.
В
данной
операции
бу
дет
отсутствовать
параллельное
выполне-
ние
JOIN
запроса
и
бу
дут
дополнительные
накладные
рас
хо
ды
на
дост
авку
всех
данных
к
коор
динатору
.
Поэтому
в
данном
случае
Postgres-X2
фак-
тически
бу
дет
медленнее,
чем
выполнение
по
добного
запроса
на
обычном
P
ostgreSQL
сервере
(особенно,
если
таблицы
очень
большие).
P
ostgres-XL
бу
дет
обрабатывать
подобный
запрос
по-другому
.
У
словие
T1.a1
=
T2.b2
говорит
о
том,
что
мы
объединяем
к
олонку
b2
с
колонк
ой
a1
,
к
оторая
являетс
я
ключом
распределения для
т
аблицы
T1
.
Поэтому
,
выбрав
значения
поля
b2
,
кластер
бу
дет
точно
знать
для
каких
обработчи-
к
ов
данных
требуетс
я
полученный
резу
ль
тат
для
объединения
с
таблицей
T1
(поскольку
возможно
применить
х
еш
функцию
распределения
на
полу-
ченные
значения).
Поэтому
каждый
обработчик
данных
считает
с
другого
обработчик
а
данных
требуемые
данные
по
таблице
T2
для
объединения
со
своей
т
аблицей
T1
без
участия
коор
динатора.
Данная
возмо
жность
пря-
мой
к
оммуникации
обработчик
ов
данных
с
другими
обработчик
ами
дан-
ных
позволяет
распараллеливать
более
сло
жные
запросы
в
Postgres-XL.
P
ostgres-XL
имеет
т
акже
другие
у
лучшения
производительности
(более
оптимально
обрабатываютс
я
последовательности,
прочее).
Заключение
P
ostgres-XL
-
еще
одно
перспективное
решение
для
создания
кластера
на
основе
Postgres-X2.
Р
азработчики
данного
решения
больше
нацелены
на
у
лучшение
производительности
и
ст
абильности
кластера,
вместо
добав-
ления
нового
функционала.
6.5
Citus
Citus
—
горизонтально
масшт
абируемый
P
ostgreSQL
кластер.
Citus
ис-
пользу
ет
механизм
расширений
PostgreSQL
вместо
того,
что
бы
исполь-
зовать модифицированную версию
базы
(как это
делает
«
6.3 Postgres-
X2
» или «
6.4
Postgres-XL
»), что позволяет использовать новые
версии
P
ostgreSQL
с
новыми
возможност
ями,
сохраняя
при
этом
совместимость
с
существующими
PostgreSQL
инструмент
ами.
Кластер
предоставляет
пользователям
резу
ль
таты
запросов
в
режиме
«реального
времени»
для
большого
и
растущего
объема
данных
(благо
даря
параллелизации
запро-
сов
между
но
дами).
Примеры
использования:
∙
аналитик
а
и
выво
д
данных
в
реальном
времени
на
графики;
∙
хранение
большого
набора
данных
для
архива
и
создание
отчетов
по
ним;
∙
анализ
и
сегмент
ация
большого
объема
данных;
138
6.5.
Citus
Нагрузки,
к
оторые
требуют
большой
поток
данных
между
узлами
кла-
стера,
как
правило,
не
бу
дет
хорошо
работ
ать
с
Citus
кластером.
Напри-
мер:
∙
традиционные
хранилища
данных
с
длительными
и
в
свобо
дном
фор-
мате
SQL
запросами
(data
w
arehousing);
∙
мно
ж
ественные
распределенные
транзакции
между
неск
олькими
шар
дами;
∙
запросы,
к
оторые
возвращают
данные
по
т
яжелым
ETL
запросам;
Ар
хитектура
На
верхнем
уровне
Citus
кластер
распределяет
данные
по
PostgreSQL
экземплярам.
Вхо
дящие
SQL
запросы
затем
обрабатываютс
я
параллельно
через
эти
сервера.
Рис.
6.4:
Ар
хитектура
Citus
кластера
При
разворачивании
кластера
один
из
экземпляров
PostgreSQL
выби-
раетс
я в к
а
честве мастер (master)
но
ды. Затем
ост
альные добавляютс
я
к
ак
P
ostgreSQL
ворк
еры
(w
ork
er)
в
к
онфигурационном
файле
мастер
но-
ды.
После
этого
все
взаимо
действие
с
кластером
ведетс
я
через
мастер
но
ду
с
помощью
стандартных
P
ostgreSQL
интерфейсов.
Все
данные
распреде-
лены
по
ворк
ерам.
Мастер
хранит
только
метаданные
о
воркерах.
Citus использу
ет моду
льную архитектуру для блок
ов данных, кото-
рая
по
хо
жа
на
HDFS
(Hado
op
Distributed
File
System),
но
использует
P
ostgreSQL
таблицы
вместо
файлов.
Каждая
из
этих
таблиц
предст
авля-
ет
собой
горизонтальный
раздел
ил
и
логический
«шард»
(shard).
Каждый
139
6.5.
Citus
шар
д
дублируетс
я,
по
крайней
мере,
на
двух
воркерах
(мо
жно
настроить
на
более
высокое
зна
чение).
В
резу
ль
тате,
потеря
одной
машины
не
вли-
яет на
доступность
данных.
Логическ
ая ар
хитектура шар
динга
в Citus
т
акже
позволяет
добавлять
новые
ворк
еры,
чтобы
увеличить
пропу
скную
способность
и
вычислительную
мощность
кластера.
Citus
мастер
со
держит
таблицы
мет
аданных
для
отслеживания
всех
ворк
еров
и
располож
ение
шар
дов
базы
данных
на
них.
Эти
таблицы
т
акж
е
ведут
статистику
,
т
акую
к
ак
размер
и
минимальное/мак
симальное
зна-
чений
в
шар
дах,
к
оторые
помог
ают
распределению
SQL
запросов
Citus
планировщику
.
Т
аблицы
метаданных
небольшие
(обычно
неск
олько
мега-
байт),
и
могут
быть
дублированы
и
быстро
восстановлены,
если
с
масте-
ром
ког
да-либо
произойдет
сбой.
Подробнее
о
таблицах
метаданных
мо
жно
г
лянуть
в
документации
.
Ког
да
кластер
получает
SQL
запрос,
Citus
мастер
делит
его
на
более
мелкие
фрагменты
запросов,
г
де
каждый
фрагмент
мож
ет
выполнятьс
я
независимо
на
ворк
ере.
Это
позволяет
Citus
распределять
к
аждый
запрос
в
кластере,
используя
вычислительные
мощности
всех
задействованных
узлов,
а
т
акже
от
дельных
ядер
на
к
аждом
узле.
Мастер
затем
поруча-
ет
воркерам
выполнить
запрос,
осуществляет
контроль
за
их
исполнени-
ем,
объединяет
резу
ль
т
аты
по
запросам
и
возвращает
к
онечный
резу
ль
тат
пользователю.
Для
того,
чтобы
г
арантировать,
что
все
запросы
выполня-
ютс
я
в
масшт
абируемой
манере,
мастер
т
акж
е
применяет
оптимизации,
к
оторые
сводят
к
минимуму
объем
данных,
передаваемых
по
сети.
Citus
кластер
мо
ж
ет
легко
переносить
сбои
ворк
еров
из-за
своей
логи-
ческ
ой
шардинг
архитектуры.
Если
воркер
терпит
неу
да
чу
во
время
вы-
полнения запроса,
Citus завершает
запрос, направляя
неу
да
чные части
запроса
другим
ворк
ерам,
к
оторые
имеют
копию
данных.
Если
ворк
ер
на-
х
одитс
я
в
нерабочем
состоянии
(сервер
упал),
пользователь
мо
ж
ет
легк
о
произвести
ребалансировку
кластера,
чтобы
поддер
живать
тот
ж
е
уровень
доступности.
У
становк
а
У
ст
ановка
Citus
кластера
не
требу
ет
особых
у
силий.
Для
использова-
ния
в
боевом
окружении
лучше
изучить
данную
документацию
.
Для
про-
верки,
что
кластер
работ
ает
и
мастер
видит
воркеры
можно
выполнить
к
оманду
master_get_active_w
orker_nodes
,
которая
покаж
ет
список
ворке-
ров:
Листинг
6.25
Список
воркеров
Line
1
p
o
s
t
g
r
e
s=
#
s
e
l
e
c
t
*
f
r
o
m
m
a
s
t
e
r
_
g
e
t
_
a
c
t
i
v
e
_
w
o
r
k
e
r
_
n
o
d
e
s
(
)
;
-
no
d
e
_
n
a
m
e
|
n
o
d
e
_
p
o
r
t
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
l
o
c
a
l
h
o
s
t
|
9
7
0
2
140
6.5.
Citus
5
l
o
c
a
l
h
o
s
t
|
9
7
0
1
-
(
2
r
o
w
s
)
Р
аспределенные
таблицы
Каждая
распределенная
таблица
в
Citus
содер
жит
стоблец,
который
долж
ен
быть
выбран
в
к
ачестве
значения
для
распределения
по
шар
дам
(возмо
жно
выбрать
тольк
о
один
столбец).
Это
информирует
базу
данных
к
ак
хранить
статистику
и
распределять
запросы
по
кластеру
.
Как
прави-
ло,
требу
етс
я
выбрать
столбец,
который
являетс
я
наиболее
часто
исполь-
зу
емым
в
запросах
WHERE
.
В
так
ом
случае
запросы,
которые
в
фильтре
используют
данный
столбец,
бу
дут
выполняться
на
шардах,
которые
вы-
бираютс
я
по
условию
фильтрации.
Это
помогает
зна
чительно
уменьшить
к
оличество
вычислений
на
шардах.
Следующим
шагом
после
выбора
столбца
на
распределения
бу
дет
опре-
деление
правильного
метода
распределения
данных
в
т
аблицу
.
В
целом,
существу
ет
два
шаблона
т
аблиц:
распределенные
по
времени
(время
со-
здания
заказ
а,
запись
логов,
прочее)
и
распределение
по
идентифик
атору
(ID
пользователя,
ID
прилож
ения,
прочее).
Citus
поддер
живает
оба
мето
да
распределения:
app
end
и
hash
соответственно.
App
end
мето
д
подх
о
дит
для
т
аблиц,
в
которые
записываютс
я
данные
по
времени
(упорядочены
по
времени).
Т
ак
ой
тип
т
аблиц
от
лично
справляет-
с
я
с
запросами,
которые
используют
фильтры
с
диапазонами
значений
по
распределенному
столбцу
(
BETWEEN
x
AND
y
).
Это
объясняетс
я
тем,
что
мастер
хранит
диапазоны
значений,
к
оторые
хранятся
на
шар
дах,
и
пла-
нировщик
мо
жет
эффективно
выбирать
шарды,
к
оторые
содер
жат
данные
для
SQL
запроса.
Hash
метод
распределения
подх
одит для
неупорядоченного столбца
(user
UUID)
или
по
данным,
которые
могут
записываться
в
любом по-
р
ядке.
В
так
ом
случае
Citus
кластер
бу
дет
хранить
минимальные
и
мак-
симальные
значения
для
хеш
функций
на
всех
шардах.
Эт
а
мо
дель
лучше
по
дхо
дит
для
SQL
запросов,
включающих
фильтры
на
основе
равенства
по
к
олонке
распределения
(
user_uuid=’a0eeb
c99-9c0b-4ef8-bb6d-6bb9b
d380a11’
).
Hash
распределение
Для
примера
создадим
и
распределим
т
аблицу
по
hash
мето
ду
.
Листинг
6.26
Создание
таблицы
Line
1
#
C
R
E
A
T
E
T
A
B
L
E
g
i
t
h
u
b
_
e
v
e
n
t
s
-
(
-
e
v
e
n
t
_
i
d
b
i
g
i
n
t
,
-
e
v
e
n
t
_
t
y
p
e
t
e
x
t
,
5
e
v
e
n
t
_
p
u
b
l
i
c
b
o
o
l
e
a
n
,
141
6.5.
Citus
-
r
e
p
o
_
i
d
b
i
g
i
n
t
,
-
p
a
y
l
o
a
d
j
s
o
n
b
,
-
r
e
p
o
j
s
o
n
b
,
-
a
c
t
o
r
j
s
o
n
b
,
10
o
r
g
j
s
o
n
b
,
-
c
r
e
a
t
e
d
_
a
t
t
i
m
e
s
t
a
m
p
-
)
;
Далее
ук
ажем
Citus
кластеру
использовать
rep
o_id
с
hash
распределе-
нием
для
gith
ub_even
ts
таблицы.
Листинг
6.27
Создание
hash
распределения
Line
1
#
S
E
L
E
C
T
m
a
s
t
e
r
_
c
r
e
a
t
e
_
d
i
s
t
r
i
b
u
t
e
d
_
t
a
b
l
e
(
’
g
i
t
h
u
b
_
e
v
e
n
t
s
’
,
’
r
e
p
o
_
i
d
’
,
’
h
a
s
h
’
)
;
И
создадим
шар
ды
для
таблицы:
Листинг
6.28
Создание
шардов
Line
1
#
S
E
L
E
C
T
m
a
s
t
e
r
_
c
r
e
a
t
e
_
w
o
r
k
e
r
_
s
h
a
r
d
s
(
’
g
i
t
h
u
b
_
e
v
e
n
t
s
’
,
1
6
,
1
)
;
Данный
мето
д
принимает
два
аргумента
в
дополнение
к
имени
табли-
цы:
к
оличество
шардов
и
к
оэффициент
реплик
ации.
Этот
пример
позво-
лит
создать
в
общей
сло
жности
шестнадцать
шардов,
г
де
к
аждый
бу
дет
владеть
частью
символическ
ого
пространства
хэша,
а
данные
бу
дут
реп-
лицироватьс
я
на
один
воркер.
Далее
мы
мо
жем
заполнить
таблицу
данными:
Листинг
6.29
Загрузка
данных
Line
1
$
w
g
e
t
h
t
t
p
:
/
/
e
x
a
m
p
l
e
s
.
c
i
t
u
s
d
a
t
a
.
com
/
g
i
t
h
u
b
_
a
r
c
h
i
v
e
/
g
i
t
h
u
b
_
e
v
e
n
t
s
-
2
0
1
5
-
0
1
-
0
1
-
{
0
.
.
5
}
.
c
s
v
.
g
z
-
$
g
z
i
p
-
d
g
i
t
h
u
b
_
e
v
e
n
t
s
-
2
0
1
5
-
0
1
-
0
1
-
*
.
g
z
Листинг
6.30
Загрузка
данных
Line
1
#
\
C
O
P
Y
g
i
t
h
u
b
_
e
v
e
n
t
s
F
R
O
M
’
g
i
t
h
u
b
_
e
v
e
n
t
s
-
2
0
1
5
-
0
1
-
0
1
-
0
.
c
s
v
’
W
I
T
H
(
f
o
r
m
a
t
C
S
V
)
-
#
IN
SE
R
T
I
NT
O
g
i
t
h
u
b
_
e
v
e
n
t
s
V
A
L
U
E
S
(
2
4
8
9
3
7
3
1
1
8
,
’
P
u
b
l
i
c
E
v
e
n
t
’
,
’
t
’
,
2
4
5
0
9
0
4
8
,
’
{
}
’
,
’
{
"
i
d
"
:
2
4
5
0
9
0
4
8
,
"
u
r
l
"
:
"
h
t
t
p
s
:
/
/
a
p
i
.
g
i
t
h
u
b
.
com
/
r
e
p
o
s
/
S
a
b
i
n
a
S
/
c
s
e
e
6
8
6
8
"
,
"
n
am
e
"
:
"
S
a
b
i
n
a
S
/
c
s
e
e
6
8
6
8
"
}
’
,
’
{
"
i
d
"
:
2
9
5
5
0
0
9
,
"
u
r
l
"
:
"
h
t
t
p
s
:
/
/
a
p
i
.
g
i
t
h
u
b
.
com
/
u
s
e
r
s
/
S
a
b
i
n
a
S
"
,
"
l
o
g
i
n
"
:
"
S
a
b
i
n
a
S
"
,
"
a
v
a
t
a
r
_
u
r
l
"
:
"
h
t
t
p
s
:
/
/
a
v
a
t
a
r
s
.
g
i
t
h
u
b
u
s
e
r
c
o
n
t
e
n
t
.
co
m
/
u
/
2
9
5
5
0
0
9
?
"
,
"
g
r
a
v
a
t
a
r
_
i
d
"
:
"
"
}
’
,
N
U
L
L
,
’
2
0
1
5
-
0
1
-
0
1
0
0
:
0
9
:
1
3
’
)
;
142
6.5.
Citus
Т
еперь
мы
мо
жем
обновлять
и
у
далять
данные
с
таблицы:
Листинг
6.31
Изменение
данных
Line
1
#
U
P
D
A
T
E
g
i
t
h
u
b
_
e
v
e
n
t
s
S
E
T
o
r
g
=
N
U
L
L
W
H
E
R
E
r
e
p
o
_
i
d
=
2
4
5
0
9
0
4
8
;
-
#
D
E
L
E
T
E
F
R
O
M
g
i
t
h
u
b
_
e
v
e
n
t
s
W
H
E
R
E
r
e
p
o
_
i
d
=
2
4
5
0
9
0
4
8
;
Для
работы
UPD
A
TE
и
DELETE
запросов
требу
етс
я,
что
бы
он
«затра-
гивал»
о
дин
шар
д.
Это
означает
,
что
условие
WHERE
должно
содер
ж
ать
у
словие,
что
ограничит
выполнение
запроса
на
о
дин
шард
по
распреде-
ленному
столбцу
. Для
обновления или
у
даления
данных
на
нескольких
шар
дах
требуетс
я
использовать
команду
master_mo
dify_multiple_shards
:
Листинг
6.32
Изменение
данных
на
нескольких
шардах
Line
1
#
S
E
L
E
C
T
m
a
s
t
e
r
_
m
o
d
i
f
y
_
m
u
l
t
i
p
l
e
_
s
h
a
r
d
s
(
-
’
D
E
L
E
T
E
F
R
O
M
g
i
t
h
u
b
_
e
v
e
n
t
s
W
H
E
R
E
r
e
p
o
_
i
d
I
N
(
2
4
5
0
9
0
4
8
,
2
4
5
0
9
0
4
9
)
’
)
;
Для
у
даления
таблицы
дост
аточно
выполнить
DROP
T
ABLE
на
масте-
ре:
Листинг
6.33
У
даление
таблицы
Line
1
#
D
R
O
P
T
A
B
L
E
g
i
t
h
u
b
_
e
v
e
n
t
s
;
App
end
распределение
Для
примера
создадим
и
распределим
т
аблицу
по
app
end
мето
ду
.
Листинг
6.34
Создание
таблицы
Line
1
#
C
R
E
A
T
E
T
A
B
L
E
g
i
t
h
u
b
_
e
v
e
n
t
s
-
(
-
e
v
e
n
t
_
i
d
b
i
g
i
n
t
,
-
e
v
e
n
t
_
t
y
p
e
t
e
x
t
,
5
e
v
e
n
t
_
p
u
b
l
i
c
b
o
o
l
e
a
n
,
-
r
e
p
o
_
i
d
b
i
g
i
n
t
,
-
p
a
y
l
o
a
d
j
s
o
n
b
,
-
r
e
p
o
j
s
o
n
b
,
-
a
c
t
o
r
j
s
o
n
b
,
10
o
r
g
j
s
o
n
b
,
-
c
r
e
a
t
e
d
_
a
t
t
i
m
e
s
t
a
m
p
-
)
;
Далее
ук
ажем
Citus
кластеру
использовать
created_at
с
app
end
распре-
делением
для
gith
ub_even
ts
таблицы.
143
6.5.
Citus
Листинг
6.35
Создание
hash
распределения
Line
1
#
S
E
L
E
C
T
m
a
s
t
e
r
_
c
r
e
a
t
e
_
d
i
s
t
r
i
b
u
t
e
d
_
t
a
b
l
e
(
’
g
i
t
h
u
b
_
e
v
e
n
t
s
’
,
’
c
r
e
a
t
e
d
_
a
t
’
,
’
a
p
p
e
n
d
’
)
;
После
этого
мы
мо
жем
использовать
т
аблицу
и
загруж
ать
в
нее
данные:
Листинг
6.36
Загрузка
данных
Line
1
#
S
E
T
c
i
t
u
s
.
s
h
a
r
d
_
m
a
x
_
s
i
z
e
T
O
’
6
4
M
B
’
;
-
#
\
c
o
p
y
g
i
t
h
u
b
_
e
v
e
n
t
s
f
r
o
m
’
g
i
t
h
u
b
_
e
v
e
n
t
s
-
2
0
1
5
-
0
1
-
0
1
-
0
.
c
s
v
’
W
I
T
H
(
f
o
r
m
a
t
C
S
V
)
По
умолчанию
к
оманда
\copy
требу
ет
два
к
онфигурационных
парамет-
ра
для
работы:
citus
.
shard_max_size
и
citus
.
shard_replication_factor
.
∙
citus
.
shard_max_size
параметр
ук
азывает
максимальный
размер
шар
да
при
использовании
команды
\copy
(1Гб
по
умолчанию).
Если
файл
больше
данного
параметра,
то
команда
автоматически
разо-
бьет
файл
по
неск
ольким
шардам;
∙
citus
.
shard_replication_factor
параметр
количество
ворк
еров,
на
к
ото-
рые
шар
ды
бу
дут
реплицироваться
(2
по
умолчанию);
По
умолчанию
к
оманда
\copy
создает
каждый
раз
новый
шар
д
для
дан-
ных.
Если
требуетс
я
добавлять
данные
в
один
и
тот
же
шард,
существуют
к
оманды
master_create_empty_shard
,
которая
вернет
идентификатор
на
но-
вый
шар
д,
и
к
оманда
master_app
end_table_to_shard
для
добавления
д
ан-
ных
в
этот
шар
д
по
идентификатору
.
Для
у
даления
старых
данных
мо
жно
использовать
к
оманду
master_apply_delete_command
,
которая
у
даляет
ст
арые
шар
ды,
кото-
рые
попадают
в
переданное
у
словие
на
у
даление:
Листинг
6.37
У
даление
старых
шардов
Line
1
#
S
E
L
E
C
T
*
f
r
o
m
m
a
s
t
e
r
_
a
p
p
l
y
_
d
e
l
e
t
e
_
c
o
m
m
a
n
d
(
’
D
E
L
E
T
E
F
R
O
M
g
i
t
h
u
b
_
e
v
e
n
t
s
W
H
E
R
E
c
r
e
a
t
e
d
_
a
t
>
=
’
’
2
0
1
5
-
0
1
-
0
1
0
0
:
0
0
:
0
0
’
’
’
)
;
-
m
a
s
t
e
r
_
a
p
p
l
y
_
d
e
l
e
t
e
_
c
o
m
m
a
n
d
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
3
5
(
1
r
o
w
)
Для
у
даления
таблицы
дост
аточно
выполнить
DROP
T
ABLE
на
масте-
ре:
Листинг
6.38
У
даление
таблицы
Line
1
#
D
R
O
P
T
A
B
L
E
g
i
t
h
u
b
_
e
v
e
n
t
s
;
144
6.6.
Greenplum
Database
Р
ебалансировка
кластера
Логическ
ая
ар
хитектура
шардинг
а
Citus
позволяет
масштабировать
кластер
без
каких-либо
простоев
(no
do
wn
time!).
Для
добавления
нового
ворк
ера
дост
аточно
добавить
его
в
pg_work
er_list.conf
и
вызвать
на
мастере
pg_reload_conf
для
загрузки
новой
к
онфигурации:
Листинг
6.39
Загрузка
новой
конфигурации
Line
1
#
S
E
L
E
C
T
p
g
_
r
e
l
o
a
d
_
c
o
n
f
(
)
;
После
этого
Citus
автоматически
начнет использовать
данный
вор-
к
ер
для
новых
распределенных
т
аблиц.
Если
требуетс
я
ребалансиро-
вать
существующие
т
аблицы
на
новый
воркер,
то
для
этого
есть
к
оман-
да
rebalance_table_shards
,
но,
к
со
жалению,
она
доступна
только
в
Citus
En
terprise
(платное
решение).
Ограничения
Мо
дель расширения P
ostgreSQL в
Citus позволяет
использовать
до-
ступные типы данных (JSON,
JSONB, другие) и
другие расширения в
кластере.
Но
не
весь
спектр
SQL
запросов
доступен
для
распределенных
т
аблиц.
На
текущий
момент
распределенные
таблицы
не
поддер
живают:
∙
Ок
онные
функции
(windo
w
functions);
∙
Общие
т
абличные
выраж
ения
(CTE);
∙
UNION
операции
(
UNION
/
INTERSECT
/
EXCEPT
);
∙
Транзакционная
семантика
для
запросов,
которые
распределены
по
неск
ольким
шардам;
Заключение
Citus
кластер
достаточно
гибк
ое
и
мощное
решение
для
горизонт
ально-
го
масшт
абирования
PostgreSQL.
Зрелость
данного
решения
пок
азывает
его
использование
т
акими
игрок
ами
на
рынк
е,
к
ак
CloudFlare,
Heap
и
мно-
гими
другими.
6.6
Greenplum
Database
Greenplum
Database (GP)
—
реляционная
СУБД,
имеющая
массово-
параллельную
(massiv
e
parallel
pro
cessing)
архитектуру
без
разделения
ресурсов
(shared
nothing).
Для
по
дробного
понимания
принципов
работы
Greenplum
необ
хо
димо
обозначить
основные
термины:
145
6.6.
Greenplum
Database
∙
Master
instance
(«мастер»)
—
инст
анс
P
ostgreSQL,
являющийся
од-
новременно
коор
динатором
и
вхо
дной
точкой
для
пользователей
в
кластере;
∙
Master
host
(«сервер-мастер»)
—
сервер,
на
котором
работ
ает
master
instance;
∙
Secondary
master instance — инст
анс PostgreSQL, являющийс
я ре-
зервным
мастером,
включается
в
работу
в
случае
недоступности
ос-
новного
мастера
(переключение
проис
хо
дит
вручную);
∙
Primary
segmen
t
instance
(«сегмент»)
—
инст
анс
PostgreSQL,
являю-
щийс
я
о
дним
из
сегментов.
Именно
сегменты
непосредственно
хра-
нят
данные,
выполняют
с
ними
операции
и
отдают
резу
льт
аты
ма-
стеру
(в
общем
случае).
По
сути
сегмент
—
самый
обычный
инстанс
P
ostgreSQL
8.3.23
с
настроенной
реплик
ацией
в
своё
зеркало
на
дру-
гом
сервере;
∙
Mirror
segment
instance
(«зерк
ало»)
—
инстанс
P
ostgreSQL,
являю-
щийс
я
зерк
алом
одного
из
primary
сегментов,
автоматически
прини-
мает
на
себ
я
роль
primary
в
случае
падения
оного.
Greenplum
по
ддер-
живает
только
1-to-1
реплик
ацию
сегментов:
для
каждого
из
primary
мо
жет
быть
только
одно
зеркало;
∙
Segmen
t
host
(«сервер-сегмент»)
—
сервер,
на
к
отором
работ
ает
один
или
неск
олько
сегментов
и/или
зеркал;
В
общем
случае
кластер
GP
состоит
из
нескольких
серверов-сегментов,
о
дного
сервера-мастера,
и
о
дного
сервера-секондари-мастера,
соединённых
между
собой
о
дной
или
несколькими
быстрыми
(10g,
infiniband)
сет
ями,
обычно
обособленными
(in
terconnect)
(рис
6.5
).
Рис.
6.5:
Состав
кластера
и
сетевое
взаимодействие
элементов.
Зелёная
и
красная
линии
—
обособленные
сети
interconnect,
синяя
линия
—
внешняя,
клиентск
ая
сеть
146
6.6.
Greenplum
Database
Использование
неск
ольких
in
terconnect-сетей
позволяет
,
во-первых,
по-
высить
пропу
скную
способность
канала
взаимодействия
сегментов
между
собой,
и
во-вторых,
обеспечить
отк
азоустойчивость
кластера
(в
случае
от-
к
аза
одной
из
сетей
весь
трафик
перераспределяетс
я
между
ост
авшимися).
При
выборе
числа
серверов-сегментов
важно
правильно
выбрать
со-
отношение кластера
«число процессоров/Тб
данных» в
зависимости
от
планиру
емого
профиля
нагрузки
на
БД
—
чем
больше
процессорных
ядер
прих
одитс
я
на
единицу
данных,
тем
быстрее
кластер
бу
дет
выполнять
«тя-
ж
ёлые»
операции,
а
такж
е
работать
со
сж
атыми
т
аблицами.
При
выборе
числа
сегментов
в
кластере
(к
оторое в
общем
случае
к
числу
серверов
ник
ак
не
привязано)
необх
одимо
помнить
следующее:
∙
все
ресурсы
сервера
делятся
между
всеми
сегментами
на
сервере
(на-
грузк
ой
зерк
ал,
в
случае
если
они
располагаютс
я
на
этих
же
серве-
рах,
мо
жно
условно
пренебречь);
∙
к
аждый
запрос
на
о
дном
сегменте
не
мо
жет
потреблять
процессор-
ных
ресурсов
больше,
чем
о
дно
ядро
CPU.
Это
означает
,
например,
что,
если
кластер
состоит
из
32-ядерных
серверов
с
4-я
сегментами
GP
на
борту
и
используетс
я
в
среднем
для
обработки
3-4
одновремен-
ных
тяж
ёлых,
х
орошо
утилизирующих
CPU,
запросов,
«в
среднем
по
больнице»
CPU
не
бу
дет
утилизироваться
оптимально.
В
данной
си-
ту
ации
лучше
увеличить
число
сегментов
на
сервере
до
6-8;
∙
шт
атный
процесс
бэкапа
и
рестора
данных
«из
коробки»
работает
тольк
о
на
кластерах,
имеющих
о
динаковое
число
сегментов.
Восста-
новить
данные,
забэкапленные
на
кластере
из
96
сегментов,
в
кластер
из
100
сегментов
без
напильник
а
бу
дет
невозможно;
Хранение
данных
В
Greenplum
реализуетс
я
классическ
ая
сх
ема
шардирования
данных.
Каждая
т
аблица
предст
авляет
из
себя
N+1
таблиц
на
всех
сегмент
ах
кла-
стера,
г
де
N
—
число
сегментов
(+1
в
этом
случае
—
это
таблица
на
масте-
ре,
данных
в
ней
нет).
На
каждом
сегменте
хранитс
я
1/N
строк
т
аблицы.
Логик
а
разбиения
таблицы
на
сегменты
задаётс
я
ключом
(полем)
дистри-
буции
—
т
аким
полем,
на
основе
данных
к
оторого
любую
строку
мо
жно
отнести
к
о
дному
из
сегментов.
Ключ
(поле
или
набор
полей)
дистрибуции
—
очень
важное
понятие
в
GP
.
Как
было
сказано
выше,
Greenplum
работает
со
скоростью
самого
мед-
ленного
сегмента,
это
озна
чает
,
что
любой
перекос
в
к
оличестве
данных
(к
ак
в
рамках
о
дной
таблицы,
так
и
в
рамках
всей
базы)
между
сегмен-
т
ами
ведёт
к
деградации
произво
дительности
кластера,
а
такж
е
к
другим
проблемам.
Именно
поэтому
следу
ет
тщательно
выбирать
поле
для
дис-
трибуции
—
распределение
количества
вх
ождений
зна
чений
в
нём
должно
быть
как
можно
более
равномерным.
Правильно
ли
вы
выбрали
ключ
дис-
трибуции
вам
по
дскаж
ет
служ
ебное
поле
gp_segment_id
,
существующее
в
147
6.6.
Greenplum
Database
к
аждой т
аблице
—
оно
содер
жит номер
сегмента,
на к
отором
хранитс
я
к
онкретная
строк
а.
Важный
нюанс:
GP
не
поддер
живает
UPD
A
TE
поля,
по
к
оторому
распределена
таблица.
Р
ассмотрим
пример
(здесь
и
далее
в
примерах
кластер
состоит
из
96
сегментов):
Листинг
6.40
Создание
распределенной
таблицы
Line
1
d
b
=
#
c
r
e
a
t
e
t
a
b
l
e
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
a
s
s
e
l
e
c
t
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
1
,
2
0
)
a
s
n
u
m
_
f
i
e
l
d
d
i
s
t
r
i
b
u
t
e
d
b
y
(
n
u
m
_
f
i
e
l
d
)
;
-
S
E
L
E
C
T
2
0
-
d
b
=
#
s
e
l
e
c
t
c
o
u
n
t
(
1
)
,
g
p
_
s
e
g
m
e
n
t
_
i
d
f
r
o
m
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
g
r
o
u
p
b
y
g
p
_
s
e
g
m
e
n
t
_
i
d
o
r
d
e
r
b
y
g
p
_
s
e
g
m
e
n
t
_
i
d
;
-
c
o
u
n
t
|
g
p
_
s
e
g
m
e
n
t
_
i
d
5
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1
|
4
-
1
|
6
-
1
|
1
5
-
1
|
2
1
10
1
|
2
3
-
1
|
2
5
-
1
|
3
1
-
1
|
4
0
-
1
|
4
2
15
1
|
4
8
-
1
|
5
0
-
1
|
5
2
-
1
|
6
5
-
1
|
6
7
20
1
|
7
3
-
1
|
7
5
-
1
|
7
7
-
1
|
9
0
-
1
|
9
2
25
1
|
9
4
-
-
d
b
=
#
t
r
u
n
c
a
t
e
t
a
b
l
e
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
;
-
T
R
U
N
C
A
T
E
T
A
B
L
E
-
d
b
=
#
i
n
s
e
r
t
i
n
t
o
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
v
a
l
u
e
s
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
,
(
1
)
;
30
I
N
SE
RT
0
2
0
-
d
b
=
#
s
e
l
e
c
t
c
o
u
n
t
(
1
)
,
g
p
_
s
e
g
m
e
n
t
_
i
d
f
r
o
m
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
g
r
o
u
p
b
y
g
p
_
s
e
g
m
e
n
t
_
i
d
o
r
d
e
r
b
y
g
p
_
s
e
g
m
e
n
t
_
i
d
;
-
c
o
u
n
t
|
g
p
_
s
e
g
m
e
n
t
_
i
d
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
148
6.6.
Greenplum
Database
-
2
0
|
4
2
В
обоих
случаях
распределена
таблица
по
полю
num_field
.
В
первом
случае
вставили
в
это
поле
20
уник
альных
зна
чений,
и,
как
видно,
GP
разло
жил
все
строки
на
разные
сегменты.
Во
втором
случае
в
поле
было
вст
авлено
20
одинак
овых
значений,
и
все
строки
были
помещены
на
о
дин
сегмент
.
В
случае,
если
в
т
аблице
нет
по
дхо
дящих
полей
для
использования
в
к
ачестве
ключа
дистрибуции,
можно
воспользоваться
случайной
дистри-
буцией (
DISTRIBUTED
RANDOML
Y
). Поле для дистрибуции мо
жно ме-
нять
в
уж
е
созданной
т
аблице,
о
днак
о после
этого
её
необх
о
димо пере-
распределить.
Именно
по
полю
дистрибуции
Greenplum
совершает
самые
оптимальные
JOIN
:
в
случае, если
в
обоих
т
аблицах поля, по
к
оторым
совершаетс
я
JOIN
, являются ключами дистрибуции,
JOIN
выполняетс
я
лок
ально
на
сегменте.
Если
же
это
у
словие
не
верно,
GP
придётся
и
ли
перераспределить
обе
таблицы
по
искомому
полю,
или
закинуть
о
дну
из
т
аблиц
целик
ом
на
к
аждый
сегмент
(операция
BRO
ADCAST
)
и
уж
е
затем
дж
ойнить
таблицы
локально
на
сегментах.
Листинг
6.41
JOIN
по
ключу
дистрибуции
Line
1
d
b
=
#
c
r
e
a
t
e
t
a
b
l
e
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
a
s
s
e
l
e
c
t
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
1
,
1
9
2
)
a
s
n
u
m
_
f
i
e
l
d
,
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
1
,
1
9
2
)
a
s
n
u
m
_
f
i
e
l
d
_
2
d
i
s
t
r
i
b
u
t
e
d
b
y
(
n
u
m
_
f
i
e
l
d
)
;
-
S
E
L
E
C
T
1
9
2
-
d
b
=
#
c
r
e
a
t
e
t
a
b
l
e
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
_
2
a
s
s
e
l
e
c
t
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
1
,
1
0
0
0
)
a
s
n
u
m
_
f
i
e
l
d
,
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
1
,
1
0
0
0
)
a
s
n
u
m
_
f
i
e
l
d
_
2
d
i
s
t
r
i
b
u
t
e
d
b
y
(
n
u
m
_
f
i
e
l
d
)
;
-
S
E
L
E
C
T
1
0
0
0
5
d
b
=
#
e
x
p
l
a
i
n
s
e
l
e
c
t
*
f
r
o
m
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
s
q
-
db
-#
l
e
f
t
j
o
i
n
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
_
2
s
q
2
-
db
-#
o
n
s
q
.
n
u
m
_
f
i
e
l
d
=
s
q
2
.
n
u
m
_
f
i
e
l
d
;
-
Q
U
E
R
Y
P
L
A
N
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
10
G
a
t
h
e
r
M
o
t
i
o
n
9
6
:
1
(
s
l
i
c
e
1
;
s
e
g
m
e
n
t
s
:
9
6
)
(
c
o
s
t
=
2
0
.
3
7
.
.
4
2
.
9
0
r
o
w
s
=
8
6
1
w
i
d
t
h
=
1
6
)
-
-
>
H
a
s
h
L
e
f
t
J
o
i
n
(
c
o
s
t
=
2
0
.
3
7
.
.
4
2
.
9
0
r
o
w
s
=
9
w
i
d
t
h
=
1
6
)
-
H
a
s
h
Con
d
:
s
q
.
n
u
m
_
f
i
e
l
d
=
s
q
2
.
n
u
m
_
f
i
e
l
d
-
-
>
S
e
q
S
c
a
n
o
n
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
s
q
(
c
o
s
t
=
0
.
0
0
.
.
9
.
6
1
r
o
w
s
=9
w
i
d
t
h
=
8
)
-
-
>
H
a
s
h
(
c
o
s
t
=
9
.
6
1
.
.
9
.
6
1
r
o
w
s
=9
w
i
d
t
h
=
8
)
15
-
>
S
e
q
S
c
a
n
o
n
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
_
2
s
q
2
(
c
o
s
t
=
0
.
0
0
.
.
9
.
6
1
r
o
w
s
=9
w
i
d
t
h
=
8
)
149
6.6.
Greenplum
Database
Листинг
6.42
JOIN
не
по
ключу
дистрибуции
Line
1
d
b
_
d
e
v
=
#
e
x
p
l
a
i
n
s
e
l
e
c
t
*
f
r
o
m
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
s
q
l
e
f
t
j
o
i
n
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
_
2
s
q
2
-
o
n
s
q
.
n
u
m
_
f
i
e
l
d
_
2
=
s
q
2
.
n
u
m
_
f
i
e
l
d
_
2
;
-
Q
U
E
R
Y
P
L
A
N
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
5
G
a
t
h
e
r
M
o
t
i
o
n
9
6
:
1
(
s
l
i
c
e
3
;
s
e
g
m
e
n
t
s
:
9
6
)
(
c
o
s
t
=
3
7
.
5
9
.
.
7
7
.
3
4
r
o
w
s
=
8
6
1
w
i
d
t
h
=
1
6
)
-
-
>
H
a
s
h
L
e
f
t
J
o
i
n
(
c
o
s
t
=
3
7
.
5
9
.
.
7
7
.
3
4
r
o
w
s
=
9
w
i
d
t
h
=
1
6
)
-
H
a
s
h
Con
d
:
s
q
.
n
u
m
_
f
i
e
l
d
_
2
=
s
q
2
.
n
u
m
_
f
i
e
l
d
_
2
-
-
>
R
e
d
i
s
t
r
i
b
u
t
e
M
o
t
i
o
n
9
6
:
9
6
(
s
l
i
c
e
1
;
s
e
g
m
e
n
t
s
:
9
6
)
(
c
o
s
t
=
0
.
0
0
.
.
2
6
.
8
3
r
o
w
s
=9
w
i
d
t
h
=
8
)
-
H
a
s
h
Key
:
s
q
.
n
u
m
_
f
i
e
l
d
_
2
10
-
>
S
e
q
S
c
a
n
o
n
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
s
q
(
c
o
s
t
=
0
.
0
0
.
.
9
.
6
1
r
o
w
s
=9
w
i
d
t
h
=
8
)
-
-
>
H
a
s
h
(
c
o
s
t
=
2
6
.
8
3
.
.
2
6
.
8
3
r
o
w
s
=9
w
i
d
t
h
=
8
)
-
-
>
R
e
d
i
s
t
r
i
b
u
t
e
M
o
t
i
o
n
9
6
:
9
6
(
s
l
i
c
e
2
;
s
e
g
m
e
n
t
s
:
9
6
)
(
c
o
s
t
=
0
.
0
0
.
.
2
6
.
8
3
r
o
w
s
=9
w
i
d
t
h
=
8
)
-
H
a
s
h
K
ey
:
s
q
2
.
n
u
m
_
f
i
e
l
d
_
2
-
-
>
S
e
q
S
c
a
n
o
n
d
i
s
t
r
i
b
_
t
e
s
t
_
t
a
b
l
e
_
2
s
q
2
(
c
o
s
t
=
0
.
0
0
.
.
9
.
6
1
r
o
w
s
=
9
w
i
d
t
h
=
8
)
Как
видно
в
примере
«
JOIN
не
по
ключу
дистрибуции
»
в
плане
запроса
по
являются
два
дополнительных
шага
(по
о
дн
ому
для
каждой
из
участву-
ющих
в
запросе
таблиц):
Redistribute
Motion
.
По
сути,
перед
выполнением
запроса
GP
перераспределяет
обе
таблицы
по
сегмент
ам,
использу
я
логику
поля
num_field_2
,
а
не
изна
чального
ключа
дистрибуции
—
поля
n
um_field
.
Взаимо
действие
с
клиентами
В
общем
случае
всё
взаимодействие
клиентов
с
кластером
ведётся
толь-
к
о через
мастер —
именно он
отвечает клиент
ам,
выдаёт им
резу
льт
ат
запроса
и
т
.
д.
Обычные
клиенты
не
имеют
сетевого
доступа
к
серверам-
сегмент
ам.
Для
уск
орения
загрузки
данных
в
кластер
используетс
я
bulk
load
—
параллельная
загрузка
данных
с/на
клиент
о
дновременно
с
неск
ольких
сегментов.
Bulk
load
возмож
ен
тольк
о
с
клиентов,
имеющих
доступ
в
ин-
терк
оннекты.
Обычно
в
роли
т
аких
клиентов
выступают
ETL-сервера
и
другие
системы,
к
оторым
необ
х
одима
загрузка
большого
объёма
данных
(на
рис
6.5
они
обозна
чены
как
ETL/Pro
client).
Для
параллельной
загрузки
данных
на
сегменты
используетс
я
утили-
т
а
gpfdist
.
По
сути,
утилита
по
днимает
на
у
далённом
сервере
w
eb-сервер,
к
оторый
предост
авляет
доступ
по
протоколам
gpfdist
и
h
ttp
к
ук
азанной
папк
е.
После
запу
ска
директория
и
все
файлы
в
ней
становятс
я
доступны
150
6.6.
Greenplum
Database
обычным
wget
.
Создадим
для
примера
файл
в
директории,
обслуживаемой
gpfdist
,
и
обратимс
я
к
нему
как
к
обычной
таблице.
Листинг
6.43
Пример
с
gpfdist
Line
1
# На
E
T
L
сервере
-
:
-
b
a
s
h#
f
o
r
i
i
n
{
1
.
.
1
0
0
0
}
;
d
o
e
c
h
o
"
$
i
,
$
(
c
a
t
/
d
e
v
/
u
r
a
n
d
o
m
|
t
r
-
d
c
’
a
-
zA
-
Z0
-
9
’
|
f
o
l
d
-
w
8
|
h
e
a
d
-
n
1
)
"
;
d
o
n
e
>
/
tmp
/
w
o
r
k
/
g
p
f
d
i
s
t
_
h
o
m
e
/
t
e
s
t
_
t
a
b
l
e
.
c
s
v
-
-
# Т
еперь
создадим
внешнюю
таблицу
и
прочит
аем
данные
из
файла
5
# В
G
r
e
e
n
p
l
u
m
D
B
:
-
d
b
=
#
c
r
e
a
t
e
e
x
t
e
r
n
a
l
t
a
b
l
e
e
x
t
_
t
e
s
t
_
t
a
b
l
e
-
db
-#
(
i
d
i
n
t
e
g
e
r
,
r
a
n
d
v
a
r
c
h
a
r
(
8
)
)
-
db
-#
l
o
c
a
t
i
o
n
(
’
g
p
f
d
i
s
t
:
/
/
e
t
l
_
h
o
s
t
n
a
m
e
:
8
0
8
1
/
t
e
s
t
_
t
a
b
l
e
.
c
s
v
’
)
-
db
-#
f
o
r
m
a
t
’T
E
X
T
’
(
d
e
l
i
m
i
t
e
r
’
,
’
N
U
L
L
’
’
)
;
10
C
R
E
A
T
E
E
X
T
E
R
N
A
L
T
A
B
L
E
-
d
b
_
d
e
v
=
#
s
e
l
e
c
t
*
f
r
o
m
e
x
t
_
t
e
s
t
_
t
a
b
l
e
l
i
m
i
t
1
0
0
;
-
N
O
T
I
C
E
:
E
x
t
e
r
n
a
l
s
c
a
n
f
r
o
m
g
p
f
d
i
s
t
(
s
)
s
e
r
v
e
r
w
i
l
l
u
t
i
l
i
z
e
6
4
o
u
t
o
f
9
6
s
e
g
m
e
n
t
d
a
t
a
b
a
s
e
s
-
i
d
|
r
a
n
d
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
15
1
|
U
W
l
o
nJ
H
O
-
2
|
HT
y
J
N
A4
1
-
3
|
CBP
1Q
Sn
1
-
4
|
0
K
9
y
5
1
a
3
-
.
.
.
Т
акж
е,
но
с
немного
другим
синт
ак
сисом,
создаютс
я
внешние
web-
т
аблицы.
Их
особенность
заключается
в
том,
что
они
ссылаютс
я
на
http
проток
ол, и
могут
работать
с
данными, предост
авляемыми сторонними
w
eb-серверами
(apache,
nginx
и
другие).
В
Greenplum
такж
е
существу
ет
возмо
жность
создавать
внешние
т
аб-
лицы
на
данные,
лежащие
на
распределённ
ой
файловой
системе
Hado
op
(hdfs)
—
за
это
в
GP
ответственна
от
дельная
компонент
а
gphdfs
.
Для
обес-
печения
её
работы
на
к
аждый
сервер,
вх
одящий
в
состав
кластера
GP
,
необ
хо
димо
уст
ановить
библиотеки
Hado
op
и
прописать
к
ним
путь
в
о
д-
ной
из
системных
переменных
базы.
Создание
внешней
т
аблицы,
обраща-
ющейс
я
к
данным
на
hdfs,
бу
дет
выглядеть
примерно
так:
Листинг
6.44
Пример
с
gphdfs
Line
1
d
b
=
#
c
r
e
a
t
e
e
x
t
e
r
n
a
l
t
a
b
l
e
h
d
f
s
_
t
e
s
t
_
t
a
b
l
e
-
d
b
=
#
(
i
d
i
n
t
,
r
a
n
d
t
e
x
t
)
-
d
b
=
#
l
o
c
a
t
i
o
n
(
’
g
p
h
d
f
s
:
/
/
h
a
d
o
o
p
_
n
a
m
e
_
n
o
d
e
:
8
0
2
0
/
tm
p
/
t
e
s
t
_
f
i
l
e
.
c
s
v
’
)
-
d
b
=
#
f
o
r
m
a
t
’T
E
X
T
’
(
d
e
l
i
m
i
t
e
r
’
,
’
)
;
151
6.6.
Greenplum
Database
г
де
hado
op_name_no
de
— адрес
хост
а
неймно
ды,
/tmp/test_file
.csv
—
путь
до
иск
омого
файла
на
hdfs.
При
обращении
к
т
акой
таблице
Greenplum
выясняет
у
неймно
ды
Hado
op
располож
ение
нужных
блок
ов
данных
на
дат
анодах,
к
которым
затем
обращается
с
серверов-сегментов
параллельно.
Естественно,
все
но
ды
кластера
Hado
op
должны
быть
в
сетях
интерк
оннекта
кластера
Greenplum.
Т
ак
ая
сх
ема
работы
позволяет
достичь
значительного
приро-
ст
а
ск
орости
даже
по
сравнению
с
gpfdist
.
Что
интересно,
логик
а
выбора
сегментов
для
чтения
данных
с
датано
д
hdfs
является
весьма
нетривиаль-
ной.
Например,
GP
мо
жет
начать
тянуть
данные
со
всех
дат
ано
д
толь-
к
о
двумя
сегмент-серверами,
причём
при
повторном
аналогичном
запросе
с
хема
взаимодействия
мож
ет
поменятьс
я.
Т
акж
е
есть
тип
внешних
т
аблиц,
к
оторые
ссылаютс
я
на
файлы
на
сегмент-серверах
или
файл
на
мастере,
а
т
акж
е
на
резу
ль
тат
выполнения
к
оманды
на
сегмент-серверах
или
на
мастере.
К
слову
ск
азать,
ст
арый
доб-
рый
COPY
FROM
нику
да
не
делс
я
и
такж
е
мо
жет
использоватьс
я,
однак
о
по
сравнению
с
описанным
выше
работ
ает
он
медленней.
Надёжность
и
резервирование
Р
езервирование
мастера
Как
было
сказано
ранее,
в
кластере
GP
использу
етс
я
полное
резервиро-
вание
мастера
с
помощью
механизма
реплик
ации
транзакционных
логов,
к
онтролируемого
специальным
агентом
(
gpsyncagent
).
При
этом
автомати-
ческ
ое
переключение
роли
мастера
на
резервный
инст
анс
не
по
ддержива-
етс
я.
Для
переключения
на
резервный
мастер
необх
одимо:
∙
убедитьс
я,
что
основной
мастер
ост
ановлен
(процесс
убит
и
в
рабочей
директории
инст
анса
мастера
отсутствует
файл
p
ostmaster.pid);
∙
на
сервере
резервного
мастера
выполнить
команду
gpactiv
atestandby
-d
/master_instance_directory
;
∙
переключить
вирту
альный
ip-адрес
на
сервер
нового
мастера
(меха-
низм
виртуального
ip
в
Greenplum
отсутству
ет
,
необх
одимо
исполь-
зовать
сторонние
инструменты);
Как
видно,
переключение
выполняется
совсем
не
сло
жно
и
при
приня-
тии
определённых
риск
ов
мож
ет
быть
автоматизировано.
Р
езервирование
сегментов
Сх
ема
резервирования
сегментов
пох
о
жа
на
так
овую
для
мастера,
от-
личия
совсем
небольшие.
В
случае
падения
одного
из
сегментов
(инст
анс
P
ostgreSQL
перестаёт
отвечать
мастеру
в
течении
т
айма
ута)
сегмент
поме-
чаетс
я
к
ак
сбойный,
и
вместо
него
автоматически
запу
ск
ается
его
зеркало
152
6.6.
Greenplum
Database
(по
сути,
абсолютно
аналогичный
инст
анс
P
ostgreSQL).
Реплик
ация
дан-
ных
сегмент
а
в
его
зеркало
происх
одит
на
основе
кастомной
синхронной
реплик
ации
на
уровне
файлов.
Cтоит
отметить,
что
довольно
важное
место
в
процессе
планирования
ар
хитектуры
кластера
GP
занимает
вопрос
располо
ж
ения
зерк
ал
сегмен-
тов
на
серверах,
благо
GP
даёт
полную
свободу
в
вопросе
выбора
мест
располо
жения
сегментов
и
их
зерк
ал:
с
помощью
специальной
к
арты
рас-
поло
жения
сегментов
их
мо
жно
разместить
на
разных
серверах,
в
разных
директориях
и
заст
авить
использовать
разные
порты.
Рассмотрим
два
ва-
риант
а:
Рис.
6.6:
Все
зеркала
сегментов,
располагающих
ся
на
х
осте
N,
нахо
дятся
на
х
осте
N+1
При
использовании
с
хемы
6.6
при
отказе
одного
из
серверов
на
сервере-
соседе
оказываетс
я
в
два
раза
больше
работ
ающих
сегментов.
Как
было
ск
азано
выше,
производительность
кластера
равняется
производительно-
сти
самого
медленного
из
сегментов,
а
зна
чит
,
в
случае
отк
аза
одного
сер-
вера
производительность
базы
сниж
ается
минимум
вдвое.
Однак
о,
т
акая
с
хема
имеет
и
положительные
стороны:
при
работе
с
отказавшим
сервером
у
язвимым
местом
кластера
ст
ановится
тольк
о
один
сервер
—
тот
самый,
ку
да
переехали
сегменты.
При
использовании
с
х
емы
6.7
в
случае
отк
аза
сервера
возросшая
на-
грузк
а
равномерно
распределяетс
я
между
неск
олькими
серверами,
не
сильно
влияя
на
общую
произво
дительность
кластера.
Однако,
существен-
но
повышаетс
я
риск
выхо
да
из
строя
всего
кластера
—
достаточно
выйти
из
стро
я
одному
из
M
серверов,
соседствующих
с
вышедшим
из
строя
из-
на
чально.
Истина, к
ак это
часто бывает
, г
де-то посередине
— мо
жно располо-
жить
по
нескольк
о
зерк
ал
сегментов
одного
сервера
на
неск
ольких
других
153
6.6.
Greenplum
Database
Рис.
6.7:
Все
зерк
ала
сегментов,
располагающих
ся
на
х
осте
N,
равномерно
«мажутс
я»
на
сервера
N+1,
N+2
...
N+M,
г
де
M
–
число
сегментов
на
сервере
серверах,
можно
объединять
сервера
в
группы
отказоу
стойчивости,
и
т
ак
далее.
Оптимальную
конфигурацию
зеркал
следует
подбирать
исх
одя
из
к
онкретных
аппаратных
данных
кластера,
критичности
просто
я
и
т
ак
да-
лее.
Т
акж
е
в
механизме
резервирования
сегментов
есть
ещё
один
нюанс,
влияющий
на
производительность
кластера.
В
случае
вых
ода
из
стро
я
зер-
к
ала
о
дного
из
сегментов
последний
перехо
дит
в
режим
c
hange
tracking
—
сегмент
логирует
все
изменения,
чтобы
затем
при
восст
ановлении
упав-
шего
зеркала
применить
их
к
нему
,
и
получить
свежую,
к
онсистентную
к
опию
данных.
Другими
словами,
при
падении
зеркала
нагрузка,
создава-
емая
на
дисковую
подсистему
сервера
сегментом,
оставшимс
я
без
зерк
ала,
существенно
возраст
ает
.
При
устранении
причины
отказа
сегмент
а
(аппаратные
проблемы,
к
он-
чившеес
я
место
на
устройстве
хранения
и
прочее)
его
н
еоб
хо
димо
вернуть
в
работу
вручную,
с
помощью
специальной
утилиты
gprecov
erseg
(даун-
т
айм
СУБД
не
требуетс
я).
По
факту
эта
утилита
скопиру
ет
скопившиес
я
на
сегменте
W
A-логи
на
зеркало
и
поднимет
упавший
сегмент/зеркало.
В
случае,
если
речь
идёт
о
primary-сегменте,
изначально
он
включится
в
ра-
боту
к
ак
зеркало
для
своего
зеркала,
ставшего
primary
(зерк
ало
и
основной
сегмент
бу
дут
работ
ать
поменявшись
ролями).
Для
того,
чтобы
вернуть
всё
на
круги
своя,
потребуетс
я
процедура
ребаланса
—
смены
ролей.
Т
акая
процедура
такж
е
не
требу
ет
даунт
айма
СУБД,
о
днак
о
на
время
ребаланса
все
сессии
в
БД
по
двиснут
.
154
6.6.
Greenplum
Database
В
случае,
если
повреждения
упавшего
сегмент
а
настолько
серьёзны,
что
простым
к
опированием
данных
из
W
A-логов
не
обойтись,
есть
воз-
мо
жность
использовать
полное
восстановление
упавшего
сегмента
—
в
та-
к
ом
случае,
по
факту
,
инстанс
P
ostgreSQL
бу
дет
создан
заново,
о
днако
за
счёт
того,
что
восст
ановление
бу
дет
не
инкремент
альным,
процесс
восста-
новления
мо
жет
занять
продолжительное
время.
Произво
дительность
Оценк
а
производительности
кластера
Greenplum
–
понятие
довольно
раст
яжимое.
Ис
хо
дные
данные:
кластер
из
24
сегмент-серверов,
каждый
сервер
—
192
Гб
памяти,
40
ядер.
Число
primary-сегментов
в
кластере:
96.
В
первом
примере
мы
создаём
т
аблицу
с
4-я
полями
+
первичный
ключ
по
о
дному
из
полей.
Затем
мы
наполняем
таблицу
данными
(10
000
000
строк)
и
пробу
ем
выполнить
простой
SELECT
с
несколькими
условиями.
Листинг
6.45
SELECT
с
условиями
Line
1
d
b
=
#
C
R
E
A
T
E
T
A
B
L
E
t
e
s
t
3
-
db
-#
(
i
d
b
i
g
i
n
t
N
O
T
N
U
L
L
,
-
d
b
(#
p
r
o
f
i
l
e
b
i
g
i
n
t
N
O
T
N
U
L
L
,
-
d
b
(#
s
t
a
t
u
s
i
n
t
e
g
e
r
N
O
T
N
U
L
L
,
5
d
b
(#
s
w
i
t
c
h
_
d
a
t
e
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
N
O
T
N
U
L
L
,
-
d
b
(#
C
O
N
S
T
R
A
I
N
T
t
e
s
t
3
_
i
d
_
p
k
e
y
P
R
I
M
A
R
Y
K
E
Y
(
i
d
)
)
-
db
-#
d
i
s
t
r
i
b
u
t
e
d
b
y
(
i
d
)
;
-
N
O
T
I
C
E
:
C
R
E
A
T
E
T
A
B
L
E
/
P
R
I
M
A
R
Y
K
E
Y
w
i
l
l
c
r
e
a
t
e
i
m
p
l
i
c
i
t
i
n
d
e
x
"
t
e
s
t
3
_
p
k
e
y
"
f
o
r
t
a
b
l
e
"
t
e
s
t
3
"
-
C
R
E
A
T
E
T
A
B
L
E
10
-
d
b
=
#
i
n
s
e
r
t
i
n
t
o
t
e
s
t
3
(
i
d
,
p
r
o
f
i
l
e
,
s
t
a
t
u
s
,
s
w
i
t
c
h
_
d
a
t
e
)
s
e
l
e
c
t
a
,
r
o
u
n
d
(
r
a
n
d
o
m
(
)
*
1
0
0
0
0
0
)
,
r
o
u
n
d
(
r
a
n
d
o
m
(
)
*
4
)
,
now
(
)
-
’
1
y
e
a
r
’
:
:
i
n
t
e
r
v
a
l
*
r
o
u
n
d
(
r
a
n
d
o
m
(
)
*
4
0
)
f
r
o
m
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
1
,
1
0
0
0
0
0
0
0
)
a
;
-
I
N
SE
RT
0
1
0
0
0
0
0
0
0
-
-
d
b
=
#
e
x
p
l
a
i
n
a
n
a
l
y
z
e
s
e
l
e
c
t
p
r
o
f
i
l
e ,
c
o
u
n
t
(
s
t
a
t
u
s
)
f
r
o
m
t
e
s
t
3
15
d
b
=
#
w
h
e
r
e
s
t
a
t
u
s
<
>
2
-
d
b
=
#
a
n
d
s
w
i
t
c
h
_
d
a
t
e
b
e
t
w
e
e
n
’
1
9
7
0
-
0
1
-
0
1
’
a
n
d
’
2
0
1
5
-
0
1
-
0
1
’
g
r
o
u
p
b
y
p
r
o
f
i
l
e
;
-
-
G
a
t
h
e
r
M
o
t
i
o
n
9
6
:
1
(
s
l
i
c
e
2
;
s
e
g
m
e
n
t
s
:
9
6
)
(
c
o
s
t
=
2
0
9
2
.
8
0
.
.
2
0
9
2
.
9
3
r
o
w
s
=
10
w
i
d
t
h
=
1
6
)
-
Ro
ws
o
u
t
:
1
0
0
0
0
1
r
o
w
s
a
t
d
e
s
t
i
n
a
t
i
o
n
w
i
t
h
1
4
1
ms
t
o
f
i
r
s
t
r
o
w
,
1
6
9
ms
t
o
e
n
d
,
s
t
a
r
t
o
f
f
s
e
t
b
y
0
.
7
7
8
ms
.
20
-
>
H
a
s
h
A
g
g
r
e
g
a
t
e
(
c
o
s
t
=
2
0
9
2
.
8
0
.
.
2
0
9
2
.
9
3
r
o
w
s
=
1
w
i
d
t
h
=
1
6
)
155
6.6.
Greenplum
Database
-
G
r
o
u
p
B
y
:
t
e
s
t
3
.
p
r
o
f
i
l
e
-
Ro
ws
o
u
t
:
Avg
1
0
4
1
.
7
r
o
w
s
x
9
6
w
o
r
k
e
r
s
.
M
ax
1
0
6
1
r
o
w
s
(
s
e
g
2
0
)
w
i
t
h
1
4
1
ms
t
o
e
n
d
,
s
t
a
r
t
o
f
f
s
e
t
b
y
2
.
2
8
1
ms
.
-
E
x
e
c
u
t
o
r
mem
or
y
:
4
2
3
3K
b
y
t
e
s
a
v
g
,
4
2
3
3K
b
y
t
e
s
ma
x
(
s
e
g
0
)
.
-
-
>
R
e
d
i
s
t
r
i
b
u
t
e
M
o
t
i
o
n
9
6
:
9
6
(
s
l
i
c
e
1
;
s
e
g
m
e
n
t
s
:
9
6
)
(
c
o
s
t
=
2
0
9
2
.
4
5
.
.
2
0
9
2
.
6
5
r
o
w
s
=
1
w
i
d
t
h
=
1
6
)
25
H
a
s
h
Ke
y
:
t
e
s
t
3
.
p
r
o
f
i
l
e
-
Rows
o
u
t
:
Avg
5
3
7
7
0
.
2
r
o
w
s
x
9
6
w
o
r
k
e
r
s
a
t
d
e
s
t
i
n
a
t
i
o
n
.
Ma
x
5
4
8
9
6
r
o
w
s
(
s
e
g
2
0
)
w
i
t
h
7
1
ms
t
o
f
i
r
s
t
r
o
w
,
1
1
7
ms
t
o
e
n
d
,
s
t
a
r
t
o
f
f
s
e
t
b
y
5
.
2
0
5
ms
.
-
-
>
H
a
s
h
A
g
g
r
e
g
a
t
e
(
c
o
s
t
=
2
0
9
2
.
4
5
.
.
2
0
9
2
.
4
5
r
o
w
s
=1
w
i
d
t
h
=
1
6
)
-
G
r
o
u
p
By
:
t
e
s
t
3
.
p
r
o
f
i
l
e
-
Rows
o
u
t
:
Avg
5
3
7
7
0
.
2
r
o
w
s
x
9
6
w
o
r
k
e
r
s
.
M
a
x
5
4
0
2
0
r
o
w
s
(
s
e
g
6
9
)
w
i
t
h
7
1
ms
t
o
f
i
r
s
t
r
o
w
,
9
0
ms
t
o
e
n
d
,
s
t
a
r
t
o
f
f
s
e
t
b
y
7
.
0
1
4
ms
.
30
E
x
e
c
u
t
o
r
me
mo
ry
:
7
8
8
2K
b
y
t
e
s
a
v
g
,
7
8
8
2K
b
y
t
e
s
ma
x
(
s
e
g
0
)
.
-
-
>
S
e
q
S
c
a
n
o
n
t
e
s
t
3
(
c
o
s
t
=
0
.
0
0
.
.
2
0
8
7
.
0
4
r
o
w
s
=12
w
i
d
t
h
=
1
2
)
-
F
i
l
t
e
r
:
s
t
a
t
u
s
<
>
2
A
N
D
s
w
i
t
c
h
_
d
a
t
e
>
=
’
1
9
7
0
-
0
1
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
A
N
D
s
w
i
t
c
h
_
d
a
t
e
<
=
’
2
0
1
5
-
0
1
-
0
1
0
0
:
0
0
:
0
0
’
:
:
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
-
Ro
ws
o
u
t
:
Avg
7
7
1
5
5
.
1
r
o
w
s
x
9
6
w
o
r
k
e
r
s
.
M
a
x
7
7
7
4
3
r
o
w
s
(
s
e
g
2
6
)
w
i
t
h
0
.
0
9
2
ms
t
o
f
i
r
s
t
r
o
w
,
3
1
ms
t
o
e
n
d
,
s
t
a
r
t
o
f
f
s
e
t
b
y
7
.
8
8
1
ms
.
-
S
l
i
c
e
s
t
a
t
i
s
t
i
c
s
:
35
(
s
l
i
c
e
0
)
E
x
e
c
u
t
o
r
m
em
or
y
:
3
6
4
K
b
y
t
e
s
.
-
(
s
l
i
c
e
1
)
E
x
e
c
u
t
o
r
m
em
or
y
:
9
6
7
5K
b
y
t
e
s
a
v
g
x
9
6
w
o
r
k
e
r
s
,
9
6
7
5
K
b
y
t
e
s
m
ax
(
s
e
g
0
)
.
-
(
s
l
i
c
e
2
)
E
x
e
c
u
t
o
r
m
em
or
y
:
4
5
2
6K
b
y
t
e
s
a
v
g
x
9
6
w
o
r
k
e
r
s
,
4
5
2
6
K
b
y
t
e
s
m
ax
(
s
e
g
0
)
.
-
S
t
a
t
e
m
e
n
t
s
t
a
t
i
s
t
i
c
s
:
-
Memory
u
s
e
d
:
1
2
8
0
0
0K
b
y
t
e
s
40
T
o
t
a
l
r
u
n
t
i
m
e
:
1
7
5
.
8
5
9
ms
Как
видно,
время
выполнения
запроса
составило
175
мс.
Т
еперь
по-
пробу
ем
пример
с
джойном
по
ключу
дистрибуции
одной
т
аблицы
и
по
обычному
полю
другой
т
аблицы.
Листинг
6.46
JOIN
по
ключу
дистрибуции
одной
таблицы
и
по
обычному
полю
другой
Line
1
d
b
=
#
c
r
e
a
t
e
t
a
b
l
e
t
e
s
t
3
_
1
(
i
d
b
i
g
i
n
t
N
O
T
N
U
L
L
,
nam
e
t
e
x
t
,
C
O
N
S
T
R
A
I
N
T
t
e
s
t
3
_
1
_
i
d
_
p
k
e
y
P
R
I
M
A
R
Y
K
E
Y
(
i
d
)
)
d
i
s
t
r
i
b
u
t
e
d
b
y
(
i
d
)
;
-
N
O
T
I
C
E
:
C
R
E
A
T
E
T
A
B
L
E
/
P
R
I
M
A
R
Y
K
E
Y
w
i
l
l
c
r
e
a
t
e
i
m
p
l
i
c
i
t
i
n
d
e
x
"
t
e
s
t
3
_
1
_
p
k
e
y
"
f
o
r
t
a
b
l
e
"
t
e
s
t
3
_
1
"
156
6.6.
Greenplum
Database
-
C
R
E
A
T
E
T
A
B
L
E
-
d
b
=
#
i
n
s
e
r
t
i
n
t
o
t
e
s
t
3
_
1
(
i
d
,
n
a
me
)
s
e
l
e
c
t
a
,
md
5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
f
r
o
m
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
1
,
1
0
0
0
0
0
)
a
;
5
I
N
SE
RT
0
1
0
0
0
0
0
-
d
b
=
#
e
x
p
l
a
i
n
a
n
a
l
y
z
e
s
e
l
e
c
t
t
e
s
t
3
.
*
,
t
e
s
t
3
_
1
.
na
me
f
r
o
m
t
e
s
t
3
j
o
i
n
t
e
s
t
3
_
1
o
n
t
e
s
t
3
.
p
r
o
f
i
l
e
=t
e
s
t
3
_
1
.
i
d
;
-
-
-
>
H
a
s
h
J
o
i
n
(
c
o
s
t
=
3
4
.
5
2
.
.
5
0
9
9
.
4
8
r
o
w
s
=
1
1
2
8
w
i
d
t
h
=
6
0
)
-
H
a
s
h
Con
d
:
t
e
s
t
3
.
p
r
o
f
i
l
e
=
t
e
s
t
3
_
1
.
i
d
10
Ro
ws
o
u
t
:
Avg
1
0
4
1
6
6
.
2
r
o
w
s
x
9
6
w
o
r
k
e
r
s
.
M
ax
1
0
6
0
9
3
r
o
w
s
(
s
e
g
2
0
)
w
i
t
h
7
.
6
4
4
ms
t
o
f
i
r
s
t
r
o
w
,
1
0
3
ms
t
o
e
n
d
,
s
t
a
r
t
o
f
f
s
e
t
b
y
2
2
3
ms
.
-
E
x
e
c
u
t
o
r
mem
or
y
:
7
4
K
b
y
t
e
s
a
v
g
,
7
5K
b
y
t
e
s
max
(
s
e
g
2
0
)
.
-
W
o
r
k
_
m
e
m
u
s
e
d
:
7
4K
b
y
t
e
s
a
v
g
,
7
5K
b
y
t
e
s
m
ax
(
s
e
g
2
0
)
.
W
o
r
k
f
i
l
e
:
(
0
s
p
i
l
l
i
n
g ,
0
r
e
u
s
e
d
)
-
(
s
e
g
2
0
)
H
a
s
h
c
h
a
i
n
l
e
n
g
t
h
1
.
0
a
v
g
,
1
m
ax
,
u
s
i
n
g
1
0
6
1
o
f
2
6
2
1
5
1
b
u
c
k
e
t
s
.
-
-
>
R
e
d
i
s
t
r
i
b
u
t
e
M
o
t
i
o
n
9
6
:
9
6
(
s
l
i
c
e
1
;
s
e
g
m
e
n
t
s
:
9
6
)
(
c
o
s
t
=
0
.
0
0
.
.
3
4
4
0
.
6
4
r
o
w
s
=
1
1
2
8
w
i
d
t
h
=
2
8
)
15
H
a
s
h
Ke
y
:
t
e
s
t
3
.
p
r
o
f
i
l
e
-
Rows
o
u
t
:
Avg
1
0
4
1
6
6
.
7
r
o
w
s
x
9
6
w
o
r
k
e
r
s
a
t
d
e
s
t
i
n
a
t
i
o
n
.
M
a
x
1
0
6
0
9
3
r
o
w
s
(
s
e
g
2
0
)
w
i
t
h
3
.
1
6
0
ms
t
o
f
i
r
s
t
r
o
w
,
4
4
ms
t
o
e
n
d
,
s
t
a
r
t
o
f
f
s
e
t
b
y
2
2
8
m
s
.
-
-
>
S
e
q
S
c
a
n
o
n
t
e
s
t
3
(
c
o
s
t
=
0
.
0
0
.
.
1
2
7
4
.
8
8
r
o
w
s
=
1
1
2
8
w
i
d
t
h
=
2
8
)
-
Rows
o
u
t
:
Avg
1
0
4
1
6
6
.
7
r
o
w
s
x
9
6
w
o
r
k
e
r
s
.
M
ax
1
0
4
2
0
9
r
o
w
s
(
s
e
g
6
6
)
w
i
t
h
0
.
1
6
5
ms
t
o
f
i
r
s
t
r
o
w
,
1
6
ms
t
o
e
n
d
,
s
t
a
r
t
o
f
f
s
e
t
b
y
2
2
8
ms
.
-
-
>
H
a
s
h
(
c
o
s
t
=
1
7
.
0
1
.
.
1
7
.
0
1
r
o
w
s
=1
5
w
i
d
t
h
=
4
0
)
20
Rows
i
n
:
Avg
1
0
4
1
.
7
r
o
w
s
x
9
6
w
o
r
k
e
r
s
.
M
ax
1
0
6
1
r
o
w
s
(
s
e
g
2
0
)
w
i
t
h
1
.
0
5
9
ms
t
o
e
n
d
,
s
t
a
r
t
o
f
f
s
e
t
b
y
2
2
7
ms
.
-
-
>
S
e
q
S
c
a
n
o
n
t
e
s
t
3
_
1
(
c
o
s
t
=
0
.
0
0
.
.
1
7
.
0
1
r
o
w
s
=1
5
w
i
d
t
h
=
4
0
)
-
Ro
ws
o
u
t
:
Avg
1
0
4
1
.
7
r
o
w
s
x
9
6
w
o
r
k
e
r
s
.
M
ax
1
0
6
1
r
o
w
s
(
s
e
g
2
0
)
w
i
t
h
0
.
1
2
6
ms
t
o
f
i
r
s
t
r
o
w
,
0
.
4
9
8
ms
t
o
e
n
d
,
s
t
a
r
t
o
f
f
s
e
t
b
y
2
2
7
ms
.
-
S
l
i
c
e
s
t
a
t
i
s
t
i
c
s
:
-
(
s
l
i
c
e
0
)
E
x
e
c
u
t
o
r
m
em
or
y
:
3
6
4
K
b
y
t
e
s
.
25
(
s
l
i
c
e
1
)
E
x
e
c
u
t
o
r
m
em
or
y
:
1
8
0
5K
b
y
t
e
s
a
v
g
x
9
6
w
o
r
k
e
r
s
,
1
8
0
5
K
b
y
t
e
s
m
ax
(
s
e
g
0
)
.
-
(
s
l
i
c
e
2
)
E
x
e
c
u
t
o
r
m
em
or
y
:
4
7
1
0K
b
y
t
e
s
a
v
g
x
9
6
w
o
r
k
e
r
s
,
4
7
1
0
K
b
y
t
e
s
m
ax
(
s
e
g
0
)
.
W
o
r
k
_
m
e
m
:
7
5
K
b
y
t
e
s
ma
x
.
-
S
t
a
t
e
m
e
n
t
s
t
a
t
i
s
t
i
c
s
:
-
Memory
u
s
e
d
:
1
2
8
0
0
0K
b
y
t
e
s
-
T
o
t
a
l
r
u
n
t
i
m
e
:
4
5
2
6
.
0
6
5
ms
Время
выполнения
запроса
сост
авило
4.6
секунды.
Много
это
или
мало
для
т
акого
объёма
данных
—
вопрос
спорный
и
лежащий
вне
этой
книги.
157
6.6.
Greenplum
Database
Р
асширение
кластера
В
жизненном
цикле
распределённой
аналитической
БД
рано
или
позд-
но
возник
ает
ситу
ация,
к
ог
да
объём
доступного
дискового
пространства
уж
е
не
мо
ж
ет
вместить
всех
необ
хо
димых
данных,
а
добавление
устройств
хранения
в
имеющиеся
сервера
либо
невозмо
жна,
либо
слишком
дорог
а
и
сло
жна
(потребуетс
я,
как
минимум,
расширение
существующих
разде-
лов).
Кроме
того,
добавление
одних
лишь
диск
овых
мощностей
негативно
ск
ажетс
я
на
соотношении
«число
процессоров/Тб
данных»
,
о
к
отором
мы
говорили
в
«
6.6
Хранение
данных
»
.
Г
овор
я
простым
язык
ом,
в
кластер
рано
или
поздно
понадобится
вводить
новые
сервера.
Greenplum
позволя-
ет
добавлять
как
новые
сервера,
так
и
новые
сегменты
практически
без
просто
я
СУБД.
Последовательность
этого
действа
примерно
так
ая:
∙
разработ
ать
карту
сегментов,
сог
ласно
которой
GP
бу
дет
размещать
новые
сегменты
и
зерк
ала
на
новых
серверах;
∙
с
делать
бэкап
необх
о
димых
критичных
данных
(как
минимум
всех
мет
аданных);
∙
у
ст
ановить
ПО
СУБД
на
новые
сервера;
∙
ост
ановить
СУБД
(следующий
пункт
выполняетс
я
в
даунт
айм);
∙
инициализировать
новые
сегменты
утилитой
gpexpand
(занимает
от
5
до
10
минут);
∙
по
днять
СУБД
(да
унтайм
окончен);
∙
перераспределить
(redistribute)
все
таблицы;
∙
собрать
ст
атистику
(analyze)
по
всем
т
аблицам;
Как
видно,
х
от
я
процедура
расширения
и
продолжительна, полная
недоступность
БД
при
правильных
действиях
администратора
не
превы-
сит
20-30
минут
.
Особенности
эк
сплуат
ации
Как
обычно,
практика
вносит
в
красивую
теорию
свои
коррективы.
По-
делюсь
нек
оторыми
нюансами
эк
сплуат
ации,
выявленными
нами
за
дол-
гое
время
использования
GP
.
Сразу
оговорюсь,
что
стандартные
нюансы
P
ostgreSQL
(необх
одимость
V
ACUUM
,
особенности
реплик
ации)
в
этот
пе-
речень
не
попали:
∙
Автоматический failo
ver не даёт
100%
гарантии переключения на
зерк
ало.
Увы,
но
это
т
ак,
особенно
под
нагрузкой,
есть
риск
зави-
сания
процессов базы
при
попытк
е
переключения
на
зерк
ало.
Ча-
стично
проблему
решает
уменьшение
т
аймаут
а
ответ
а
от
сегментов
до неск
ольких минут
, о
днако
даж
е в т
ак
ом случае
риск
ост
аётся.
Как
частное
решение
проблемы
зависания
при
переключении
можно
использовать
ручное
убийство
зависшего
сегмента
или
перезагрузку
базы;
158
6.7.
Заключение
∙
Greenplum
и
OL
TP
несовместимы.
GP
—
аналитическ
ая
БД,
предна-
зна
ченная
для
небольшого
числа
о
дновременных
запросов,
выпол-
няющих
т
яж
ёлые
операции
над
большим
объёмом
данных.
Большое
число (более
600 queries
p
er
second) лёгких
запросов/транзакций,
выполняющих о
дну операцию, нег
ативно сказываетс
я на произво-
дительности
базы
из-за
её
распределённой
архитектуры
—
каждая
транзакция
на
мастере
порождает
N
транзакций
на
сегмент
ах.
Хоро-
шей
практикой
являетс
я
агрегация
большого
числа
UPDA
TE
/
INSER
T
в
батчи;
∙
Отсутствие
мех
анизма
инкремент
ального
бэкапа;
∙
Свой
синт
аксис.
Несмотря
на
то,
что
для
клиента
Greenplum
по
су-
ти
является
PostgreSQL
DB,
небольшие
различия
в
синт
ак
сисе
SQL
заст
авляют
использовать
стандартный
клиентский
PostgreSQL-софт
с
большой
осторо
жностью;
∙
Отсутствие
возмо
жности пометить сегменты к
ак «ар
хивные»
. Ча-
стично
этот
недост
аток
мо
жно
решить
путём
использования
ар
хив-
ных
партиций,
нахо
дящих
ся
на
медленном
дешевом
tablespace,
а
т
ак-
ж
е
c
помощью
по
явившейся
в
последней
на
момент
написания
главы
версии GP
4.3.6.0 возмо
жности располаг
ать партиции
т
аблицы во
внешних
источниках
(например,
внешних
таблицах
gphdfs
,
леж
ащих
в
кластере
Hado
op);
∙
Greenplum
использует
PostgreSQL
версии
8.3.23,
а
зна
чит
о
многих
современных
плюшк
ах
этой
замечательной
БД
придётся
забыть;
Заключение
Greenplum
—
мощный
и
гибкий
инструмент
для
аналитическ
ой
обра-
ботки
больших
объёмов
данных.
Он
требует
к
себе
немного
другого
по
дх
о-
да,
чем
остальные
en
terprise-lev
el
решения
для
Data
W
arehouse
(«напиль-
ник»
—
любимый
инструмент
администратора
GP).
Однако
при
дост
аточ-
но
низк
ом
пороге
вхо
ждения
и
большой
унифицированности
с
P
ostgreSQL
Greenplum
являетс
я
сильным
игроком
на
поле
Data
W
arehouse
DB.
6.7
Заключение
В
данной
г
лаве
рассмотрены
лишь
базовые
настройки
кластеров
БД.
Про
кластеры
PostgreSQL
потребуетс
я
написать
отдельную
книгу
,
чтобы
рассмотреть
все
шаги
с
уст
ановкой,
настройк
ой
и
работой
кластеров.
Наде-
юсь,
что
несмотр
я
на
это,
информация
бу
дет
полезна
многим
чит
ателям.
159
7
PgP
o
ol-I
I
Имеетс
я
способ
с
делать
лучше
—
найди
его
Т
омас
Алва
Эдисон
7.1
Введение
Pgp
o
ol-I
I
—
это
прослойка,
работающая
между
серверами
PostgreSQL
и
клиент
ами
СУБД
PostgreSQL.
Она
предост
авляет
следующие
функции:
∙
Объединение
соединений
Pgp
o
ol-I
I
со
храняет
соединения
с серверами
P
ostgreSQL и
исполь-
зу
ет их
повторно
в
случае
если
новое
соединение
у
ст
анавливаетс
я
с
теми
же
параметрами
(т
.
е.
имя
пользователя,
база
данных,
вер-
сия
проток
ола).
Это
уменьшает
накладные
рас
хо
ды
на
соединения
и
увеличивает
произво
дительность
системы
в
целом;
∙
Р
еплик
ация
Pgp
o
ol-I
I
мо
ж
ет
управлять
мно
жеством серверов PostgreSQL. Ис-
пользование функции репликации данных позволяет
создание ре-
зервной к
опии данных в реальном
времени на
2 или более
физи-
ческих
дисков,
т
ак
что
сервис
мо
ж
ет
про
долж
ать
работ
ать
без
ост
а-
новки
серверов
в
случае
вых
ода
из
строя
диска;
∙
Балансировк
а
нагрузки
Если
база
данных
реплициру
етс
я,
то
выполнение
запроса
SELECT
на
любом
из
серверов
вернет
одинак
овый
резу
ль
тат
.
pgp
o
ol-I
I
исполь-
зу
ет
преимущество
функции
репликации
для
уменьшения
нагрузки
на к
аждый из
серверов
P
ostgreSQL распределяя
запросы
SELECT
на
неск
ольк
о
серверов,
тем
самым
увеличивая
произво
дительность
системы
в
целом.
В
лучшем
случае
произво
дительность
возраст
ает
160
7.2.
У
становк
а
и
настройк
а
пропорционально
числу
серверов
PostgreSQL.
Балансировк
а
нагруз-
ки
лучше
всего
работ
ает
в
случае
ког
да
много
пользователей
выпол-
няют
много
запросов
в
о
дно
и
то
же
время.
∙
Ограничение
лишних
соединений
Существу
ет ограничение максимального числа о
дновременных со-
единений
с
PostgreSQL,
при
превышении
к
оторого
новые
соединения
отклоняютс
я.
У
ст
ановк
а
мак
симального
числа
соединений,
в
то
же
время,
увеличивает
потребление
ресурсов
и
снижает
произво
дитель-
ность
системы.
pgp
o
ol-I
I
т
акж
е
имеет
ограничение
на
мак
симальное
число
соединений,
но
«лишние»
соединения
бу
дут
пост
авлены
в
оче-
редь
вместо
немедленного
возврат
а
ошибки.
∙
Параллельные
запросы
Использу
я
функцию
параллельных
запросов
можно
разнести
данные
на
множ
ество
серверов,
благо
дар
я
чему
запрос
мож
ет
быть
выполнен
на
всех
серверах
о
дновременно
для
уменьшения
общего
времени
вы-
полнения.
Параллельные
запросы
работ
ают
лучше
всего
при
поиск
е
в
больших
объемах
данных.
Pgp
o
ol-I
I
общается
по
протоколу
бэк
енда
и
фронтенда
PostgreSQL
и
располаг
ается
между
ними.
Т
аким
образом,
прило
жение
базы
данных
счи-
т
ает
что
pgp
o
ol-I
I
—
насто
ящий
сервер
P
ostgreSQL,
а
сервер
видит
pgp
o
ol-
I
I
к
ак
о
дного
из
своих
клиентов.
Поск
ольку
pgp
o
ol-I
I
прозрачен
к
ак
для
сервера,
т
ак
и
для
клиента,
существующие
прило
ж
ения,
работ
ающие
с
ба-
зой
данных,
могут
использоваться
с
pgp
o
ol-I
I
практически
без
изменений
в
ис
хо
дном
ко
де.
7.2
У
ст
ановк
а
и
настройк
а
Во
многих
Lin
ux
системах
pgp
o
ol-I
I
мож
ет
нах
о
диться
в
репозитории
пак
етов.
Для
Ubuntu
Linux,
например,
достаточно
бу
дет
выполнить:
Листинг
7.1
У
становк
а
pgp
o
ol-I
I
Line
1
$
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
p
g
p
o
o
l
2
Настройк
а
Параметры
конфигурации
pgp
o
ol-I
I
хранятс
я
в
файле
pgp
o
ol.conf
.
Фор-
мат
файла:
о
дна
пара
параметр
=
значение
в
строке.
При
у
ст
ановке
pgp
o
ol-
I
I
автоматически
создаетс
я
файл
pgp
o
ol.conf
.
sample
:
Листинг
7.2
Файлы
конфигурации
161
7.2.
У
становк
а
и
настройк
а
Line
1
$
c
p
/
u
s
r
/
l
o
c
a
l
/
e
t
c
/
p
g
p
o
o
l
.
c
o
n
f
.
s
a
m
p
l
e
/
u
s
r
/
l
o
c
a
l
/
e
t
c
/
p
g
p
o
o
l
.
c
o
n
f
Pgp
o
ol-I
I
принимает
соединения
тольк
о
с
lo
calhost
на
порт
9999.
Если
требу
ется
принимать
соединения
с
других
х
остов,
уст
ановите
для
пара-
метра
listen_addresses
значение
«*»
.
Листинг
7.3
Файлы
конфигурации
Line
1
l
i
s
t
e
n
_
a
d
d
r
e
s
s
e
s
=
’
l
o
c
a
l
h
o
s
t
’
-
p
o
r
t
=
9
9
9
9
Настройк
а
команд
PCP
У
pgp
o
ol-I
I
есть
PCP
интерфейс
для
административных
целей
(полу-
чить
информацию
об
узлах
базы
данных,
остановить
pgp
o
ol-I
I,
прочее).
Чтобы
использовать
к
оманды
PCP
,
необ
хо
дима
идентификация
пользова-
теля.
Эта
идентифик
ация
отличаетс
я
от
идентифик
ации
пользователей
в
P
ostgreSQL.
Имя
пользователя
и
пароль
нужно
ук
азывать
в
файле
pcp
.conf
. В
этом
файле имя
пользователя
и
пароль ук
азываютс
я к
ак пара
зна
чений, разделенных двоеточием
(:). Одна пара
в
строк
е, пароли
за-
шифрованы
в
формате
хэша
md5:
Листинг
7.4
Настройка
команд
PCP
Line
1
p
o
s
t
g
r
e
s
:
e
8
a
4
8
6
5
3
8
5
1
e
2
8
c
6
9
d
0
5
0
6
5
0
8
f
b
2
7
f
c
5
Для
того
чтобы
зашифровать
пароль
в
формате
md5
хэша
использу-
етс
я
к
оманда
pg_md5
,
к
оторая
уст
анавливаетс
я
как
о
дин
из
исполняемых
файлов
pgp
o
ol-I
I.
pg_md5
принимает
текст
в
параметре
командной
строки
и
отображ
ает
md5
хэш
как
резу
льт
ат
.
Листинг
7.5
Настройка
команд
PCP
Line
1
$
/
u
s
r
/
b
i
n
/
pg_
md5
p
o
s
t
g
r
e
s
-
e
8
a
4
8
6
5
3
8
5
1
e
2
8
c
6
9
d
0
5
0
6
5
0
8
f
b
2
7
f
c
5
Команды
PCP
выполняются
по
сети,
т
ак
что
в
файле
pgpo
ol.conf
дол-
ж
ен
быть
указан
номер
порта
в
параметре
p
cp_p
ort
:
Листинг
7.6
Настройка
команд
PCP
Line
1
p
c
p
_
p
o
r
t
=
9
8
9
8
162
7.3.
Настройка
репликации
По
дготовка
узлов
баз
данных
Далее
требуетс
я
настроить
серверы
бэкендов
P
ostgreSQL
для
pgp
o
ol-
I
I.
Эти
серверы
могут
быть
размещены
на
одном
хосте
с
pgp
o
ol-I
I
или
на
от
дельных
машинах.
Если
вы
решите
разместить
серверы
на
том
же
хосте,
для
всех
серверов
должны
быть
уст
ановлены
разные
номера
портов.
Если
серверы
размещены
на
отдельных
машинах,
они
должны
быть
настроены
т
ак
чтобы
могли
принимать
сетевые
соединения
от
pgp
o
ol-I
I.
В
данном
примере
три
сервера
PostgreSQL
размещено
в
рамк
ах
одного
хост
а
вместе
с
pgp
o
ol-I
I
(5432,
5433,
5434
порты
соответственно):
Листинг
7.7
Подготовк
а
узлов
баз
данных
Line
1
b
a
c
k
e
n
d
_
h
o
s
t
n
a
m
e
0
=
’
l
o
c
a
l
h
o
s
t
’
-
b
a
c
k
e
n
d
_
p
o
r
t
0
=
5
4
3
2
-
b
a
c
k
e
n
d
_
w
e
i
g
h
t
0
=
1
-
b
a
c
k
e
n
d
_
h
o
s
t
n
a
m
e
1
=
’
l
o
c
a
l
h
o
s
t
’
5
b
a
c
k
e
n
d
_
p
o
r
t
1
=
5
4
3
3
-
b
a
c
k
e
n
d
_
w
e
i
g
h
t
1
=
1
-
b
a
c
k
e
n
d
_
h
o
s
t
n
a
m
e
2
=
’
l
o
c
a
l
h
o
s
t
’
-
b
a
c
k
e
n
d
_
p
o
r
t
2
=
5
4
3
4
-
b
a
c
k
e
n
d
_
w
e
i
g
h
t
2
=
1
В
параметрах
bac
kend_hostname
,
back
end_p
ort
,
back
end_weigh
t
указыва-
етс
я
имя
х
оста
узла
базы
данных,
номер
порта
и
к
оэффициент
для
балан-
сировки
нагрузки.
В
к
онце
имени
каждого
параметра
должен
быть
ук
а-
зан
идентифик
атор
узла
путем
добавления
поло
жительного
целого
числа
на
чиная
с
0.
Параметры
back
end_w
eight
все
равны
1,
что
означает
что
за-
просы
SELECT
равномерно
распределены
по
трем
серверам.
7.3
Настройк
а
реплик
ации
Pgp
o
ol-I
I
реплик
ация
включает
к
опирование
одних
и
тех
ж
е
данных
на
мно
ж
ество
узлов
базы
данных
(синхронная
реплик
ация).
Но
данная
ре-
плик
ация
имеет
тот
недост
аток,
что
она
создаёт
дополнительную
нагрузку
при
выполнении
всех
транзакций,
в
которых
обновляются
какие-либо
ре-
плики
(кроме
того,
могут
возникать
проблемы,
связанные
с
доступностью
данных).
Настройк
а
репликации
Чтобы
включить
функцию
реплик
ации
базы
данных
уст
ановите
зна-
чение
true
для
параметра
replication_mo
de
в
файле
pgp
o
ol.conf
.
Листинг
7.8
Настройка
репликации
163
7.3.
Настройка
репликации
Line
1
r
e
p
l
i
c
a
t
i
o
n
_
m
o
d
e
=
t
r
u
e
Если
параметр
replication_mo
de
равен
true
,
pgp
o
ol-I
I
бу
дет
отправлять
к
опию
принятого
запроса
на
все
узлы
базы
данных.
Если
параметр
load_balance_mo
de
равен
true
,
pgp
o
ol-I
I
бу
дет
распреде-
лять
запросы
SELECT
между
узлами
базы
данных.
Листинг
7.9
Настройка
репликации
Line
1
l
o
a
d
_
b
a
l
a
n
c
e
_
m
o
d
e
=
t
r
u
e
Проверк
а
репликации
После
настройки
pgp
o
ol.conf
и
перезапу
ска
pgp
o
ol-I
I,
мо
жно
проверить
реплик
ацию
в
действии.
Для
этого
создадим
базу
данных,
которую
бу
дем
реплицировать
(базу
данных
нужно
создать
на
всех
узлах):
Листинг
7.10
Проверка
репликации
Line
1
$
c
r
e
a
t
e
d
b
-
p
9
9
9
9
b
e
n
c
h
_
r
e
p
l
i
c
a
t
i
o
n
Затем
запу
стим
pgb
ench
с
параметром
-
i
.
Параметр
-
i
инициализирует
базу
данных
предопределенными
т
аблицами
и
данными
в
н
их.
Листинг
7.11
Проверка
репликации
Line
1
$
p
g
b
e
n
c
h
-
i
-
p
9
9
9
9
b
e
n
c
h
_
r
e
p
l
i
c
a
t
i
o
n
Ук
азанная
ниже
таблица
со
дер
жит
сводную
информацию
о
таблицах
и
данных,
которые
бу
дут
созданы
при
помощи
pgb
enc
h
-i
.
Если
на
всех
узлах
базы
данных
перечисленные
таблицы
и
данные
были
созданы,
репликация
работ
ает
корректно.
Имя
т
аблицы
Число
строк
branc
hes
1
tellers
10
accoun
ts
100000
history
0
Для
проверки
указанной
выше
информации
на
всех
узлах
используем
простой
скрипт
на
shell:
Листинг
7.12
Проверка
репликации
Line
1
f
o
r
p
o
r
t
i
n
5
4
3
2
5
4
3
3
5
4
3
4
;
d
o
-
>
e
c
h
o
$
p
o
r
t
-
>
f
o
r
t
a
b
l
e
_
n
a
m
e
i
n
b
r
a
n
c
h
e
s
t
e
l
l
e
r
s
a
c
c
o
u
n
t
s
h
i
s
t
o
r
y
;
d
o
-
>
e
c
h
o
$
t
a
b
l
e
_
n
a
m
e
164
7.4.
Параллельное
выполнение
запросов
5
>
p
s
q
l
-
c
"S
E
L
E
C
T
c
o
u
n
t
(
*
)
F
R
O
M
$
t
a
b
l
e
_
n
a
m
e
"
-
p
\
-
>
$
p
o
r
t
b
e
n
c
h
_
r
e
p
l
i
c
a
t
i
o
n
-
>
d
o
n
e
-
>
d
o
n
e
7.4
Параллельное
выполнение
запросов
Pgp
o
ol-I
I
позволяет
использовать
распределение
для
таблиц.
Данные
из
разных
диапазонов со
храняютс
я
на
двух или
более узлах
базы дан-
ных
параллельным
запросом.
Более
того,
одни
и
те
же
данные
на
двух
и
более
узлах
базы
данных
могут
быть
воспроизведены
с
использованием
распределения.
Чтобы
включить
параллельные
запросы
в
pgp
o
ol-I
I
вы
должны
у
ста-
новить еще о
дну базу данных, называемую «системной базой данных»
(«System
Database»)
(далее
бу
дет
называтьс
я
SystemDB).
SystemDB
хра-
нит
определяемые
пользователем
правила,
определяющие
какие
данные
бу
дут
сохранятьс
я
на
к
аких
узлах
базы
данных.
Т
акже
SystemDB
исполь-
зу
ется
чтобы
объединить
резу
льт
аты
возвращенные
узлами
базы
данных
посредством
dblink.
Настройк
а
Чтобы
включить
функцию
выполнения
параллельных
запросов
требу-
етс
я
у
ст
ановить
для
параметра
parallel_mo
de
зна
чение
true
в
файле
pgp
o
ol
.conf
:
Листинг
7.13
Настройка
параллельного
запроса
Line
1
p
a
r
a
l
l
e
l
_
m
o
d
e
=
t
r
u
e
У
ст
ановка
параметра
parallel_mo
de
равным
true
не
запу
стит
параллель-
ные
запросы
автоматически.
Для
этого
pgp
o
ol-I
I
нужна
SystemDB
и
пра-
вила
определяющие
к
ак
распределять
данные
по
узлам
базы
данных.
Т
ак-
ж
е
SystemDB
использует
dblink
для
создания
соединений
с
pgp
o
ol-I
I.
Т
а-
ким
образом,
нужно
уст
ановить
зна
чение
параметра
listen_addresses
таким
образом
чтобы
pgp
o
ol-I
I
принимал
эти
соединения:
Листинг
7.14
Настройка
параллельного
запроса
Line
1
l
i
s
t
e
n
_
a
d
d
r
e
s
s
e
s
=
’
*
’
Нужно
обратить
внимание,
что
репликация
не
реализована
для
таблиц,
к
оторые
распределяются
посредством
параллельных
запросов.
Поэтому:
165
7.4.
Параллельное
выполнение
запросов
Листинг
7.15
Настройка
параллельного
запроса
Line
1
r
e
p
l
i
c
a
t
i
o
n
_
m
o
d
e
=
t
r
u
e
-
l
o
a
d
_
b
a
l
a
n
c
e
_
m
o
d
e
=
f
a
l
s
e
или
Листинг
7.16
Настройка
параллельного
запроса
Line
1
r
e
p
l
i
c
a
t
i
o
n
_
m
o
d
e
=
f
a
l
s
e
-
l
o
a
d
_
b
a
l
a
n
c
e
_
m
o
d
e
=
t
r
u
e
Настройк
а
SystemDB
В
основном,
нет
отличий
между
простой
и
системной
базами
данных.
Однак
о, в
системной
базе
данных определяетс
я
функция
dblink и
при-
сутству
ет т
аблица,
в к
оторой
хранятся
правила
распределения
данных.
Т
аблицу
dist_def
необх
одимо
определять.
Более
того,
один
из
узлов
базы
данных
мо
жет
хранить
системную
базу
данных,
а
pgp
o
ol-I
I
мож
ет
исполь-
зоватьс
я
для
распределения
нагрузки
каск
адным
подключением.
Создадим SystemDB
на узле с
портом 5432. Далее
приведен список
параметров
к
онфигурации
для
SystemDB:
Листинг
7.17
Настройка
SystemDB
Line
1
s
y
s
t
e
m
_
d
b
_
h
o
s
t
n
a
m
e
=
’
l
o
c
a
l
h
o
s
t
’
-
s
y
s
t
e
m
_
d
b
_
p
o
r
t
=
5
4
3
2
-
s
y
s
t
e
m
_
d
b
_
d
b
n
a
m
e
=
’
p
g
p
o
o
l
’
-
s
y
s
t
e
m
_
d
b
_
s
c
h
e
m
a
=
’
p
g
p
o
o
l
_
c
a
t
a
l
o
g
’
5
s
y
s
t
e
m
_
d
b
_
u
s
e
r
=
’
p
g
p
o
o
l
’
-
s
y
s
t
e
m
_
d
b
_
p
a
s
s
w
o
r
d
=
’
’
На
самом
деле,
указанные
выше
параметры
являются
параметрами
по
умолчанию
в
файле
pgp
o
ol.conf
.
Т
еперь
требу
ется
создать
пользователя
с
именем
«pgp
o
ol»
и
базу
данных
с
именем
«pgp
o
ol»
и
владельцем
«pgp
o
ol»:
Листинг
7.18
Настройка
SystemDB
Line
1
$
c
r
e
a
t
e
u
s
e
r
-
p
5
4
3
2
p
g
p
o
o
l
-
$
c
r
e
a
t
e
d
b
-
p
5
4
3
2
-O
p
g
p
o
o
l
p
g
p
o
o
l
У
ст
ановка
dblink
Далее
требуетс
я
уст
ановить
dblink
в
базу
данных
«pgp
o
ol»
.
Dblink
—
о
дин
из
инструментов
включенных
в
к
ат
алог
contrib
ис
х
одного
ко
да
P
ostgreSQL.
После
того
как
dblink
был
уст
ановлен
в
вашей
системе
мы
добавим
функции
dblink
в
базу
данных
«pgp
o
ol»
.
166
7.4.
Параллельное
выполнение
запросов
Листинг
7.19
У
становк
а
dblink
Line
1
$
p
s
q
l
-
c
"
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
d
b
l
i
n
k
;
"
-
p
5
4
3
2
p
g
p
o
o
l
Создание
т
аблицы
dist_def
Следующим
шагом
мы
создадим
т
аблицу
с
именем
dist_def
,
в
к
оторой
бу
дут
хранитьс
я
правила
распределения
данных.
Поскольку
pgp
o
ol-I
I
уже
был
уст
ановлен,
файл
с
именем
system_db.sql
должен
быть
у
становлен
в
/
usr/
lo
cal
/share/system_db.sql
(имейте
в
виду
,
что
на
вашей
системе
кат
алог
у
становки
мо
жет
быть
другой).
Файл
system_db.sql
со
держит
директивы
для
создания
специальных
таблиц,
включая
и
таблицу
dist_def
.
Выполним
следующую
к
оманду
для
создания
таблицы
dist_def
:
Листинг
7.20
Создание
таблицы
dist_def
Line
1
$
p
s
q
l
-
f
/
u
s
r
/
l
o
c
a
l
/
s
h
a
r
e
/
s
y
s
t
e
m
_
d
b
.
s
q
l
-
p
5
4
3
2
-
U
p
g
p
o
o
l
p
g
p
o
o
l
Все
таблицы
в
файле
system_db.sql
,
включая
dist_def
,
создаются
в
с
х
еме
pgp
o
ol_catalog
.
Если
вы
уст
ановили
параметр
system_db_schema
на
исполь-
зование
другой
с
хемы,
вам
нужно,
соответственно,
отредактировать
файл
system_db.sql
.
Описание
таблицы
dist_def
выглядит
так
как
показано
ниже:
Листинг
7.21
Создание
таблицы
dist_def
Line
1
C
R
E
A
T
E
T
A
B
L
E
p
g
p
o
o
l
_
c
a
t
a
l
o
g
.
d
i
s
t
_
d
e
f
(
-
db
n
a
m
e
t
e
x
t
,
-
-
имя
базы
данных
-
s
c
h
e
m
a
_
n
a
m
e
t
e
x
t
,
-
-
имя
сх
емы
-
t
a
b
l
e
_
n
a
m
e
t
e
x
t
,
-
-
имя
т
аблицы
5
c
o
l
_
n
a
m
e
t
e
x
t
N
O
T
N
U
L
L
C
H
E
C
K
(
c
o
l
_
n
a
m
e
=
A
N
Y
(
c
o
l
_
l
i
s
t
)
)
,
-
-
-
столбец
ключ
для
распределения
данных
-
c
o
l
_
l
i
s
t
t
e
x
t
[
]
N
O
T
N
U
L
L
,
-
-
список
имен
столбцов
-
t
y
p
e
_
l
i
s
t
t
e
x
t
[
]
N
O
T
N
U
L
L
,
-
-
список
типов
столбцов
-
d
i
s
t
_
d
e
f
_
f
u
n
c
t
e
x
t
N
O
T
N
U
L
L
,
10
-
-
имя
функции
распределения
данных
-
P
R
I
M
A
R
Y
K
E
Y
(
db
n
am
e
,
s
c
h
e
m
a
_
n
a
m
e
,
t
a
b
l
e
_
n
a
m
e
)
-
)
;
Записи,
хранимые
в
т
аблице
dist_def
,
могут
быть
двух
типов:
∙
Правило
распределения
данных
(
col_name
,
dist_def_func
);
∙
Мет
а-информация
о
таблицах
(
dbname
,
sc
hema_name
,
table_name
,
col_list
,
type_list
);
Правило
распределения
данных
определяет
как
бу
дут
распределены
данные
на
конкретный
узел
базы
данных.
Данные
бу
дут
распределены
в
167
7.4.
Параллельное
выполнение
запросов
зависимости
от
значения
столбца
col_name
.
dist_def_func
—
это
функция,
к
оторая
принимает
зна
чение
col_name
в
ка
честве
аргумент
а
и
возвращает
целое
число,
к
оторое
соответству
ет
идентифик
атору
узла
базы
данных,
на
к
отором
должны
быть
со
хранены
данные.
Мет
а-информация
исполь-
зу
ется
для
того
чтобы
переписывать
запросы.
Параллельный
запрос
дол-
ж
ен
переписывать
ис
х
одные
запросы
т
ак
чтобы
резу
ль
таты,
возвращаемые
узлами-бэк
ендами,
могли
быть
объединены
в
единый
резу
льт
ат
.
Создание
т
аблицы
replicate_def
В
случае
если
указана
таблица,
для
к
оторой
производитс
я
реплик
ация
в
выраж
ение
SQL,
использующее
зарегистрированную
в
dist_def
таблицу
путем
объединения
таблиц,
информация
о
таблице,
для
которой
необх
о-
димо
производить
репликацию,
предварительно
регистрируетс
я
в
т
аблице
с
именем
replicate_def
.
Т
аблица
replicate_def
бу
дет
создана
при
обработке
файла
system_db.sql
.
Т
аблица
replicate_def
описана
так
как
пок
азано
ниже:
Листинг
7.22
Создание
таблицы
replicate_def
Line
1
C
R
E
A
T
E
T
A
B
L
E
p
g
p
o
o
l
_
c
a
t
a
l
o
g
.
r
e
p
l
i
c
a
t
e
_
d
e
f
(
-
db
n
a
m
e
t
e
x
t
,
-
-
имя
базы
данных
-
s
c
h
e
m
a
_
n
a
m
e
t
e
x
t
,
-
-
имя
сх
емы
-
t
a
b
l
e
_
n
a
m
e
t
e
x
t
,
-
-
имя
т
аблицы
5
c
o
l
_
l
i
s
t
t
e
x
t
[
]
N
O
T
N
U
L
L
,
-
-
список
имен
столбцов
-
t
y
p
e
_
l
i
s
t
t
e
x
t
[
]
N
O
T
N
U
L
L
,
-
-
список
типов
столбцов
-
P
R
I
M
A
R
Y
K
E
Y
(
db
n
am
e
,
s
c
h
e
m
a
_
n
a
m
e
,
t
a
b
l
e
_
n
a
m
e
)
-
)
;
У
становк
а
правил
распределения
данных
В
данном
примере
бу
дут
определены
правила
распределения
данных,
созданных
программой
pgb
ench,
на
три
узла
базы
данных.
Т
естовые
дан-
ные
бу
дут
созданы
к
омандой
pgb
enc
h
-i
-
s 3
(т
.
е.
масштабный
к
оэффици-
ент
равен
3).
Для
этого
раздела
мы
создадим
новую
базу
данных
с
именем
b
enc
h_parallel
.
В
кат
алоге
sample
исх
одного
ко
да
pgp
o
ol-I
I
вы
мож
ете
най-
ти
файл
dist_def_pgb
ench.sql
.
Бу
дем
использоватьс
я
этот
файл
с
примером
для
создания
правил
распределения
для
pgb
ench.
Выполним
следующую
к
оманду
в
кат
алоге
с
распакованным
исх
о
дным
ко
дом
pgp
o
ol-I
I:
Листинг
7.23
У
становк
а
правил
распределения
данных
Line
1
$
p
s
q
l
-
f
s
a
m
p
l
e
/
d
i
s
t
_
d
e
f
_
p
g
b
e
n
c
h
.
s
q
l
-
p
5
4
3
2
p
g
p
o
o
l
В
файле
dist_def_pgb
enc
h.sql
мы
добавляем
одну
строку
в
т
аблицу
dist_def
.
Это
функция
распределения
данных
для
таблицы
accounts
.
В
к
а-
честве
столбца-ключа
ук
азан
столбец
aid
.
168
7.4.
Параллельное
выполнение
запросов
Листинг
7.24
У
становк
а
правил
распределения
данных
Line
1
IN
SE
R
T
I
N
T
O
p
g
p
o
o
l
_
c
a
t
a
l
o
g
.
d
i
s
t
_
d
e
f
V
A
L
U
E
S
(
-
’
b
e
n
c
h
_
p
a
r
a
l
l
e
l
’
,
-
’
p
u
b
l
i
c
’
,
-
’
a
c
c
o
u
n
t
s
’
,
5
’
a
i
d
’
,
-
A
R
R
A
Y
[
’
a
i
d
’
,
’
b
i
d
’
,
’
a
b
a
l
a
n
c
e
’
,
’
f
i
l
l
e
r
’
]
,
-
A
R
R
A
Y
[
’
i
n
t
e
g
e
r
’
,
’
i
n
t
e
g
e
r
’
,
’
i
n
t
e
g
e
r
’
,
-
’
c
h
a
r
a
c
t
e
r
(
8
4
)
’
]
,
-
’
p
g
p
o
o
l
_
c
a
t
a
l
o
g
.
d
i
s
t
_
d
e
f
_
a
c
c
o
u
n
t
s
’
10
)
;
Т
еперь
мы
должны
создать
функцию
распределения
данных
для
таб-
лицы
accounts
.
Возможно
использовать
о
дну
и
ту
ж
е
функцию
для
разных
т
аблиц.
Т
аблица
accounts
в
момент
инициализации
данных
хранит
значе-
ние
масштабного
коэффициент
а
равное
3,
зна
чения
столбца
aid
от
1
до
300000.
Функция
создана
таким
образом
что
данные
равномерно
распре-
деляютс
я
по
трем
узлам
базы
данных:
Листинг
7.25
У
становк
а
правил
распределения
данных
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
-
p
g
p
o
o
l
_
c
a
t
a
l
o
g
.
d
i
s
t
_
d
e
f
_
b
r
a
n
c
h
e
s
(
a
n
y
e
l
e
m
e
n
t
)
-
R
E
T
U
R
N
S
i
n
t
e
g
e
r
A
S
$
$
-
S
E
L
E
C
T C
A
S
E
W
H
E
N
$
1
>
0
A
N
D
$
1
<
=
1
T
H
E
N
0
5
W
H
E
N
$
1
>
1
A
N
D
$
1 <
=
2
T
H
E
N
1
-
E
LS
E
2
-
E
N
D
;
-
$
$
L
A
N
G
U
A
G
E
s
q
l
;
У
становк
а
правил
реплик
ации
Правило
реплик
ации
—
это
то
что
определяет
какие
таблицы
долж-
ны
быть
использованы
для выполнения
репликации.
Здесь
это с
делано
при
помощи
pgb
ench
с
зарегистрированными
т
аблицами
branches
и
tellers
.
Как
резу
ль
т
ат
,
стало
возмо
жно
создание
таблицы
accoun
ts
и
выполнение
запросов,
использующих
т
аблицы
branches
и
tellers
:
Листинг
7.26
У
становк
а
правил
репликации
Line
1
IN
SE
R
T
I
N
T
O
p
g
p
o
o
l
_
c
a
t
a
l
o
g
.
r
e
p
l
i
c
a
t
e
_
d
e
f
V
A
L
U
E
S
(
-
’
b
e
n
c
h
_
p
a
r
a
l
l
e
l
’
,
-
’
p
u
b
l
i
c
’
,
-
’
b
r
a
n
c
h
e
s
’
,
169
7.4.
Параллельное
выполнение
запросов
5
A
R
R
A
Y
[
’
b
i
d
’
,
’
b
b
a
l
a
n
c
e
’
,
’
f
i
l
l
e
r
’
]
,
-
A
R
R
A
Y
[
’
i
n
t
e
g
e
r
’
,
’
i
n
t
e
g
e
r
’
,
’
c
h
a
r
a
c
t
e
r
(
8
8
)
’
]
-
)
;
-
-
I
N
SE
RT I
NT
O
p
g
p
o
o
l
_
c
a
t
a
l
o
g
.
r
e
p
l
i
c
a
t
e
_
d
e
f
V
A
L
U
E
S
(
10
’
b
e
n
c
h
_
p
a
r
a
l
l
e
l
’
,
-
’
p
u
b
l
i
c
’
,
-
’
t
e
l
l
e
r
s
’
,
-
A
R
R
A
Y
[
’
t
i
d
’
,
’
b
i
d
’
,
’
t
b
a
l
a
n
c
e
’
,
’
f
i
l
l
e
r
’
]
,
-
A
R
R
A
Y
[
’
i
n
t
e
g
e
r
’
,
’
i
n
t
e
g
e
r
’
,
’
i
n
t
e
g
e
r
’
,
’
c
h
a
r
a
c
t
e
r
(
8
4
)
’
]
15
)
;
По
дготовленный
файл
replicate_def_pgb
ench.sql
нахо
дитс
я в
к
аталоге
sample:
Листинг
7.27
У
становк
а
правил
репликации
Line
1
$
p
s
q
l
-
f
s
a
m
p
l
e
/
r
e
p
l
i
c
a
t
e
_
d
e
f
_
p
g
b
e
n
c
h
.
s
q
l
-
p
5
4
3
2
p
g
p
o
o
l
Проверк
а
параллельного
запроса
После
настройки
pgp
o
ol.conf
и
перезапуск
а
pgp
o
ol-I
I
возможно
провести
проверку
работоспособности
параллельных
запросов.
Сна
чала
требу
ется
создать
базу
данных,
которая
бу
дет
распределена.
Эту
базу
данных
нужно
создать
на
всех
узлах:
Листинг
7.28
Проверка
параллельного
запроса
Line
1
$
c
r
e
a
t
e
d
b
-
p
9
9
9
9
b
e
n
c
h
_
p
a
r
a
l
l
e
l
Затем
запу
стим
pgb
enc
h
с
параметрами
-
i
-
s 3
:
Листинг
7.29
Проверка
параллельного
запроса
Line
1
$
p
g
b
e
n
c
h
-
i
-
s
3
-
p
9
9
9
9
b
e
n
c
h
_
p
a
r
a
l
l
e
l
Один из способов
проверить к
орректно ли были распределены
дан-
ные
—
выполнить
запрос
SELECT
посредством
pgp
o
ol-I
I
и
напр
ямую
на
бэк
ендах
и
сравнить
резу
льт
аты.
Если
все
настроено
правильно
база
дан-
ных
b
enc
h_parallel
должна
быть
распределена
к
ак
показано
ниже:
Имя
т
аблицы
Число
строк
branc
hes
3
tellers
30
accoun
ts
300000
history
0
Для
проверки
указанной
выше
информации
на
всех
узлах
и
посред-
ством
pgp
o
ol-I
I
использу
ем
простой
скрипт
на
shell.
Приведенный
ниже
170
7.5.
Master-slav
e
режим
скрипт
покаж
ет
минимальное
и
мак
симальное
зна
чение
в
таблице
accounts
использу
я
для
соединения
порты
5432,
5433,
5434
и
9999.
Листинг
7.30
Проверка
параллельного
запроса
Line
1
f
o
r
p
o
r
t
i
n
5
4
3
2
5
4
3
3
5
4
3
4
i
9
9
9
9
;
d
o
-
>
e
c
h
o
$
p
o
r
t
-
>
p
s
q
l
-
c
"S
E
L
E
C
T
m
i
n
(
a
i
d
)
,
ma
x
(
a
i
d
)
F
R
O
M
a
c
c
o
u
n
t
s
"
\
-
>
-
p
$
p
o
r
t
b
e
n
c
h
_
p
a
r
a
l
l
e
l
5
>
d
o
n
e
7.5
Master-sla
v
e
режим
Этот
режим
предназначен
для
использования
pgp
o
ol-I
I
с
другой
репли-
к
ацией
(например
streaming,
londiste).
Информация
про
БД
ук
азывается
к
ак
для
репликации.
master_sla
ve_mode
и
load_balance_mo
de
уст
анавлива-
етс
я
в
true
.
pgp
o
ol-I
I
бу
дет
посылать
запросы
INSER
T
/
UPD
A
TE
/
DELETE
на
master
базу
данных
(1
в
списке),
а
SELECT
—
использовать
балансиров-
ку
нагрузки,
если
это
возмо
жно.
При
этом,
DDL
и
DML
для
временной
т
аблицы
мож
ет
быть
выполнен
только
на
мастере.
Если
нужен
SELECT
тольк
о
на
мастере,
то
для
этого
нужно
использовать
коммент
арий
/*NO
LO
AD
BALANCE*/
перед
SELECT
.
В
Master/Slav
e
режиме
replication_mo
de
долж
ен
быть
уст
ановлен
false
,
а
master_sla
ve_mode
—
true
.
Streaming
Replication
(Поток
овая
репликация)
В
master-sla
ve
режиме
с
потоковой
реплик
ацией,
если
мастер
или
слейв
упал,
возможно
использовать
отк
азоу
стойчивый
функционал
внут-
ри
pgp
o
ol-I
I.
Автоматически
отключив
упавший
инстанс
P
ostgreSQL,
pgp
o
ol-I
I
переключится
на
следующий
слейв
как
на
новый
мастер
(при
па-
дении
мастера),
или
ост
анется
работ
ать
на
мастере
(при
падении
слейва).
В
поток
овой
реплик
ации,
к
ог
да
слейв
ст
ановитс
я
мастером,
требу
етс
я
со-
здать
триггер
файл
(который
указан
в
recov
ery
.
conf
,
параметр
trigger_file
),
чтобы
PostgreSQL
перешел
из
режима
восст
ановления
в
нормальный.
Для
этого
мо
жно
создать
небольшой
скрипт:
Листинг
7.31
Скрипт
выполняется
при
падении
нода
P
ostgreSQL
Line
1
#
!
/
b
i
n
/
s
h
-
#
F
a
i
l
o
v
e
r
command
f
o
r
s
t
r
e
m
i
n
g
r
e
p
l
i
c
a
t
i
o
n
.
-
#
T
h
i
s
s
c
r
i
p
t
a
s
s
u
m
e
s
t
h
a
t
D
B
n
o
d
e
0
i
s
p
r
i
m
a
r
y
,
a
n
d
1
i
s
s
t
a
n
d
b
y
.
-
#
171
7.6.
Онлайн
восстановление
5
#
I
f
s
t
a
n
d
b
y
g
o
e
s
d
ow
n
,
d
o
e
s
n
o
t
h
i
n
g
.
I
f
p
r
i
m
a
r
y
g
o
e
s
d
ow
n
,
c
r
e
a
t
e
a
-
#
t
r
i
g
g
e
r
f
i
l
e
s
o
t
h
a
t
s
t
a
n
d
b
y
t
a
k
e
o
v
e
r
p
r
i
m
a
r
y
n
o
d
e
.
-
#
-
#
A
r
g
u
m
e
n
t
s
:
$
1
:
f
a
i
l
e
d
n
o
d
e
i
d
.
$
2
:
ne
w
m
a
s
t
e
r
h
o
s
t
n
a
m
e
.
$
3
:
p
a
t
h
t
o
-
#
t
r
i
g
g
e
r
f
i
l
e
.
10
-
f
a
i
l
e
d
_
n
o
d
e
=$
1
-
n
e
w
_
m
a
s
t
e
r
=$
2
-
t
r
i
g
g
e
r
_
f
i
l
e
=
$
3
-
15
# D
o
n
o
t
h
i
n
g
i
f
s
t
a
n
d
b
y
g
o
e
s
do
wn
.
-
i
f
[
$
f
a
i
l
e
d
_
n
o
d
e
=
1
]
;
t
h
e
n
-
e
x
i
t
0
;
-
f
i
-
20
#
C
r
e
a
t
e
t
r
i
g
g
e
r
f
i
l
e
.
-
/
u
s
r
/
b
i
n
/
s
s
h
-
T
$
n
e
w
_
m
a
s
t
e
r
/
b
i
n
/
t
o
u
c
h
$
t
r
i
g
g
e
r
_
f
i
l
e
-
-
e
x
i
t
0
;
Р
аботает
скрипт просто:
если падает
слейв —
скрипт ничего
не вы-
полняет
,
при
падении
мастера
—
создает
триггер
файл
на
новом
мастере.
Со
храним
этот
файл
под
именем
failo
ver
\_stream.sh
и
добавим
в
pgp
o
ol.
conf
:
Листинг
7.32
Что
выполнять
при
падении
нода
Line
1
f
a
i
l
o
v
e
r
_
c
o
m
m
a
n
d
=
’
/
p
a
t
h
_
t
o
_
s
c
r
i
p
t
/
f
a
i
l
o
v
e
r
_
s
t
r
e
a
m
.
s
h
%
d %
H
/
tmp
/
t
r
i
g
g
e
r
_
f
i
l
e
’
г
де
/tmp/trigger_file
—
триггер
файл,
ук
азанный
в
к
онфиге
recov
ery
.
conf
.
Т
еперь,
если
мастер
СУБД
упадет
,
слейв
бу
дет
переключен
из
режима
восст
ановления
в
обычный
и
смож
ет
принимать
запросы
на
запись.
7.6
Онлайн
восстановление
Pgp
o
ol-I
I
в
режиме
реплик
ации
мо
жет
синхронизировать
базы
данных
и добавлять их
к
ак новые но
ды. Называетс
я это «онлайн восст
ановле-
ние»
.
Этот
мето
д
т
акже
мож
ет
быть
использован
ког
да
нужно
вернуть
в
реплик
ацию
упавший
нод
базы
данных.
Вс
я
процедура
выполняется
в
два
задания.
Нескольк
о
секунд
или
минут
клиент
мо
жет
ждать
по
дключения
к
pgp
o
ol,
в
то
время
к
ак
восст
анавливается
узел
базы
данных.
Онлайн
восст
ановление
состоит
из
следующих
шагов:
∙
CHECKPOINT;
172
7.6.
Онлайн
восстановление
∙
Первый
эт
ап
восст
ановления;
∙
Ждем,
пок
а
все
клиенты
не
отключатс
я;
∙
CHECKPOINT;
∙
Второй
эт
ап
восст
ановления;
∙
Запу
ск
p
ostmaster
(выполнить
pgp
o
ol_remote_start
);
∙
Восст
анавливаем
инст
анс
СУБД;
Для работы
онлайн восст
ановления потребу
ется
ук
азать следующие
параметры:
∙
bac
k
end_data_directory
-
кат
алог
данных
определенного
PostgreSQL
кластера;
∙
reco
v
ery_user
-
имя
пользователя
PostgreSQL;
∙
reco
v
ery_password
-
пароль
пользователя
PostgreSQL;
∙
reco
v
ery_1st_stage_command
-
параметр
указывает
к
оманду
для
пер-
вого
эт
апа
онлайн
восстановления.
Файл
с
командами
должен
быть
помещен
в
кат
алог
данных
СУБД
кластера
из
соображений
безопас-
ности.
Например,
если
reco
very_1st_stage_command
=
’some_script’
,
то
pgpo
ol-I
I
выполнит
$PGD
A
T
A/some_script
.
Обратите
внимание,
что
pgp
o
ol-I
I
принимает
подключения
и
запросы
в
то
время
как
вы-
полняетс
я
recov
ery_1st_stage
;
∙
reco
v
ery_2nd_stage_command
-
параметр
указывает
команду
для
вто-
рого
этапа
онлайн
восст
ановления.
Файл
с
командами
долж
ен
быть
помещен
в
кат
алог
данных
СУБД
кластера
из-за
проблем
безопасно-
сти. Например,
если
reco
very_2st_stage_command
=
’some_script’
, то
pgp
o
ol-I
I
выполнит
$PGDA
T
A/some_script
.
Обратите
внимание,
что
pgp
o
ol-I
I
НЕ
принимает
подключения
и
запросы
в
то
время
к
ак
вы-
полняетс
я
reco
very_2st_stage
.
Т
аким
образом,
pgp
o
ol-I
I
бу
дет
ждать
пок
а
все
клиенты
не
закроют
подключения;
Streaming
Replication
(Поток
овая
репликация)
В
master-sla
ve
режиме
с
потоковой
репликацией,
онлайн
восст
ановле-
ние
—
от
личное
средство
вернуть
назад
упавший
инст
анс
PostgreSQL.
Вернуть возмо
жно тольк
о слейв но
ды, т
аким методом
не восст
ановить
упавший
мастер.
Для
восстановления
мастера
потребу
ется
ост
ановить
все
P
ostgreSQL
инст
ансы
и
pgp
o
ol-I
I
(для
восст
ановления
из
резервной
к
опии
мастера).
Для
настройки
онлайн
восст
ановления
потребуетс
я:
∙
У
ст
ановить
reco
very_user
.
Обычно
это
«p
ostgres»;
∙
У
ст
ановить
reco
very_passw
ord
для
recov
ery_user
для
по
дключения к
СУБД;
173
7.6.
Онлайн
восстановление
∙
Настроить
recov
ery_1st_stage_command
.
Для
этого
можно
создать
скрипт
basebackup.sh
и
положим
его
в
папку
с
данными
мастера
(
$PGD
A
T
A
),
у
становив
ему
права
на
выполнение:
Листинг
7.33
basebackup.sh
Line
1
#
!
/
b
i
n
/
s
h
-
#
R
e
c
o
v
e
r
y
s
c
r
i
p
t
f
o
r
s
t
r
e
a
m
i
n
g
r
e
p
l
i
c
a
t
i
o
n
.
-
#
T
h
i
s
s
c
r
i
p
t
a
s
s
u
m
e
s
t
h
a
t
D
B
n
o
d
e
0
i
s
p
r
i
m
a
r
y
,
a
n
d
1
i
s
s
t
a
n
d
b
y
.
-
#
5
d
a
t
a
d
i
r
=$
1
-
d
e
s
t
h
o
s
t
=
$
2
-
d
e
s
t
d
i
r
=$
3
-
-
p
s
q
l
-
c
"S
E
L
E
C
T
p
g
_
s
t
a
r
t
_
b
a
c
k
u
p
(
’
S
t
r
e
a
m
i
n
g
R
e
p
l
i
c
a
t
i
o
n
’
,
t
r
u
e
)
"
p
o
s
t
g
r
e
s
10
-
r
s
y
n
c
-
C
-
a
-
-
d
e
l
e
t
e
-
e
s
s
h
-
-
e
x
c
l
u
d
e
p
o
s
t
g
r
e
s
q
l
.
c
o
n
f
-
-
e
x
c
l
u
d
e
p
o
s
t
m
a
s
t
e
r
.
p
i
d
\
-
-
-
e
x
c
l
u
d
e
p
o
s
t
m
a
s
t
e
r
.
o
p
t
s
-
-
e
x
c
l
u
d
e
p
g
_
l
o
g
-
-
e
x
c
l
u
d
e
p
g
_
x
l
o
g
\
-
-
-
e
x
c
l
u
d
e
r
e
c
o
v
e
r
y
.
c
o
n
f
$
d
a
t
a
d
i
r
/
$
d
e
s
t
h
o
s
t
:
$
d
e
s
t
d
i
r
/
-
15
s
s
h
-
T
l
o
c
a
l
h
o
s
t
m
v
$
d
e
s
t
d
i
r
/
r
e
c
o
v
e
r
y
.
d
o
n
e
$
d
e
s
t
d
i
r
/
r
e
c
o
v
e
r
y
.
c
o
n
f
-
-
p
s
q
l
-
c
"S
E
L
E
C
T
p
g
_
s
t
o
p
_
b
a
c
k
u
p
(
)
"
p
o
s
t
g
r
e
s
При
восст
ановления
слейва,
скрипт
запуск
ает
бэкап
мастера
и
через
rsync
утилиту
передает
данные
с
мастера
на
слейв.
Для
этого
необ
х
о-
димо
настроить
ssh
так,
чтобы
recov
ery_user
мог
захо
дить
с
мастера
на
слейв
без
пароля.
Далее
добавим
скрипт
на
выполнение
для
пер-
вого
эт
апа
онлайн
восстановления:
Листинг
7.34
recov
ery_1st_stage_command
Line
1
r
e
c
o
v
e
r
y
_
1
s
t
_
s
t
a
g
e
_
c
o
m
m
a
n
d
=
’
b
a
s
e
b
a
c
k
u
p
.
s
h
’
∙
Ост
авляем
recov
ery_2nd_stage_command
пу
стым.
После
успешного
выполнения
первого
этапа
онлайн
восст
ановления,
разницу
в
дан-
ных,
что
у
спели
записатьс
я
во
время
работы
скрипта
basebackup.sh
,
слейв
инст
анс
заберет
через
W
AL
файлы
с
мастера;
∙
У
ст
анавливаем
C
и
SQL
функции
для
работы
онлайн
восст
ановления
на
к
аждый
инстанс
СУБД:
174
7.7.
Заключение
Листинг
7.35
У
станавливаем
C
и
SQL
функции
Line
1
$
c
d
p
g
p
o
o
l
-
I
I
-
x
.
x
.
x
/
s
q
l
/
p
g
p
o
o
l
-
r
e
c
o
v
e
r
y
-
$
m
a
ke
-
$
m
a
ke
i
n
s
t
a
l
l
-
$
p
s
q
l
-
f
p
g
p
o
o
l
-
r
e
c
o
v
e
r
y
.
s
q
l
t
e
m
p
l
a
t
e
1
После
этого
возмо
жно
использовать
p
cp_recov
ery_no
de
для
онлайн
вос-
ст
ановления
упавших
слейвов.
7.7
Заключение
PgP
o
ol-I
I
—
прекрасное
средство,
функционал
к
оторого
мо
ж
ет
помочь
администраторам
баз
данных
при
масшт
абировании
PostgreSQL.
175
8
Му
ль
типлек
соры
соединений
Если
сразу
успех
а
не
добились,
пыт
айтесь
снова
и
снова.
Затем
оставь
те
эти
попытки.
Как
ой
смысл
глупо
упорствовать?
Уильям
Кло
д
Филдс
8.1
Введение
Му
ль
типлексоры
соединений
(программы
для
создания
пу
ла
соедине-
ний)
позволяют
уменьшить накладные
расх
о
ды на
базу
данных,
в
слу-
чае,
к
ог
да
огромное
количество
физических
соединений
ведет
к
падению
произво
дительности
PostgreSQL.
Это
особенно
важно
на
Windows,
ког
да
система
ограничивает
большое
количество
соединений.
Это
такж
е
важно
для
веб-прило
ж
ений,
где
количество
соединений
мож
ет
быть
очень
боль-
шим.
Для
PostgreSQL
существует
PgBouncer
и
Pgp
o
ol-I
I,
которые
работают
к
ак
му
льтиплек
соры
соединений.
8.2
PgBouncer
Это му
ль
типлексор соединений для P
ostgreSQL от к
омпании Skyp
e.
Существуют
три
режима
управления:
∙
Session
Pooling
—
наиболее
«вежливый»
режим.
При
на
чале
сессии
клиенту
выделяется
соединение
с
сервером;
оно
приписано
ему
в
те-
чение
всей
сессии
и
возвращается
в
пу
л
только
после
отсоединения
клиент
а;
176
8.2.
PgBouncer
∙
T
ransaction
Pooling
—
клиент
владеет
соединением
с
бэкендом
тольк
о
в
течение
транзакции.
Ког
да PgBouncer
замечает
,
что
транзакция
завершилась,
он
возвращает
соединение
назад
в
пу
л;
∙
Statemen
t
P
o
oling
—
наиболее
агрессивный
режим.
Соединение
с
бэ-
к
ендом
возвращаетс
я
назад
в
пу
л
сразу
после
завершения
запроса.
Транзакции
с неск
олькими
запросами в
этом
режиме
не
разреше-
ны,
т
ак
как
они
гарантировано
бу
дут
отменены.
Т
акж
е
не
работают
по
дготовленные
выражения
(prepared
statements)
в
этом
режиме;
К
достоинствам
PgBouncer
относитс
я:
∙
малое
потребление
памяти
(менее
2
КБ
на
соединение);
∙
отсутствие
привязки
к
одному
серверу
баз
данных;
∙
рек
онфигурация
настроек
без
рест
арта.
Базовая
утилит
а
запуск
ается
просто:
Листинг
8.1
PgBouncer
Line
1
$
p
g
b
o
u
n
c
e
r
[
-
d
]
[
-
R
]
[
-
v
]
[
-
u
u
s
e
r
]
<
p
g
b
o
u
n
c
e
r
.
i
n
i
>
Пример
к
онфига:
Листинг
8.2
PgBouncer
Line
1
[
d
a
t
a
b
a
s
e
s
]
-
t
e
m
p
l
a
t
e
1
=
h
o
s
t
=
1
2
7
.
0
.
0
.
1
p
o
r
t
=
5
4
3
2
d
b
n
a
m
e
=t
e
m
p
l
a
t
e
1
-
[
p
g
b
o
u
n
c
e
r
]
-
l
i
s
t
e
n
_
p
o
r
t
=
6
5
4
3
5
l
i
s
t
e
n
_
a
d
d
r
=
1
2
7
.
0
.
0
.
1
-
a
u
t
h
_
t
y
p
e
= m
d5
-
a
u
t
h
_
f
i
l
e
=
u
s
e
r
l
i
s
t
.
t
x
t
-
l
o
g
f
i
l
e
=
p
g
b
o
u
n
c
e
r
.
l
o
g
-
p
i
d
f
i
l
e
=
p
g
b
o
u
n
c
e
r
.
p
i
d
10
a
d
m
i
n
_
u
s
e
r
s
=
s
o
m
e
u
s
e
r
Нужно
создать
файл
пользователей
userlist
.
txt
примерно
так
ого
содер-
ж
ания:
"someuser"
"same_passw
ord_as_in_serv
er"
.
Административный
до-
ступ
из
консоли
к
базе
данных
pgb
ouncer
можно
получить
через
к
оманду
ниж
е:
Листинг
8.3
PgBouncer
Line
1
$
p
s
q
l
-
h
1
2
7
.
0
.
0
.
1
-
p
6
5
4
3
p
g
b
o
u
n
c
e
r
Здесь
мо
жно
получить
различную
статистическую
информацию
с
по-
мощью
к
оманды
SHOW
.
177
8.3.
PgPool-I
I
vs
PgBouncer
8.3
PgP
o
ol-I
I
vs
PgBouncer
Если
сравнивать
PgP
o
ol-I
I
и
PgBouncer,
то
PgBouncer
намного
лучше
работ
ает
с
пу
лами
соединений,
чем
PgPool-I
I.
Если
вам
не
нужны
осталь-
ные
возможности,
которыми
владеет
PgP
o
ol-I
I
(ведь
пу
лы
к
оннектов
это
мелочи
к
его
функционалу),
то
к
онечно
лучше
использовать
PgBouncer.
∙
PgBouncer
потребляет
меньше
памяти,
чем
PgPool-I
I;
∙
у
PgBouncer
возмо
жно
настроить
очередь
соединений;
∙
в
PgBouncer
можно
настраивать
псевдо
базы
данных
(на
сервере
они
могут
называтьс
я
по-другому);
Т
акж
е возмо
жен
вариант
использования
PgBouncer и
PgP
o
ol-I
I сов-
местно.
178
9
Кэширование
в
P
ostgreSQL
Чтобы
что-то
узнать,
нужно
уж
е
что-то
знать
Ст
анислав
Лем
9.1
Введение
Кэш
или
кеш
—
промежуточный
буфер
с
быстрым
доступом,
содер
жа-
щий
информацию,
которая
мож
ет
быть
запрошена
с
наибольшей
вероят-
ностью.
Кэширование
SELECT
запросов
позволяет
повысить
произво
ди-
тельность
прило
жений
и
снизить
нагрузку
на
PostgreSQL.
Преимущества
кэширования
особенно
заметны
в
случае
с
относительно
маленькими
т
аб-
лицами,
имеющими
статические
данные,
например,
справочными
т
абли-
цами.
Многие
СУБД
могут
кэшировать
SQL
запросы,
и
данная
возможность
идет
у
них,
в
основном,
«из
коробки»
.
P
ostgreSQL
не
обладает
по
добным
функционалом.
Почему?
Во-первых,
мы
теряем
транзакционную
чистоту
проис
хо
дящего
в
базе.
Что
это
значит?
Управление
конкурентным
досту-
пом
с
помощью
многоверсионности
(MVCC
—
MultiV
ersion Concurrency
Con
trol)
—
один
из
механизмов
обеспечения
одновременного
к
онкурентно-
го
доступа
к
БД,
заключающийс
я
в
предоставлении
каждому
пользова-
телю
«снимка»
БД,
обладающего
тем
свойством,
что
вносимые
данным
пользователем
изменения
в
БД
невидимы
другим
пользователям
до
мо-
мент
а
фик
сации
транзакции.
Этот
способ
управления
позволяет
добить-
с
я
того,
что
пишущие
транзакции
не
блокируют
читающих,
и
читающие
транзакции
не
блокируют
пишущих.
При
использовании
кэширования,
ко-
торому
нет
дела
к
транзакциям
СУБД,
«снимки»
БД
могут
быть
с
невер-
ными
данными.
Во-вторых,
к
еширование
резу
ль
татов
запросов,
в
основ-
ном,
должно
происх
о
дить
на
стороне
прило
жения,
а
не
СУБД.
В
так
ом
случае
управление
кэшированием
мож
ет
работать
более
гибк
о
(включать-
179
9.2.
Pgmemcache
cя
и
отключаться
где
потребуетс
я
для
прилож
ения),
а
СУБД
бу
дет
зани-
матьс
я
своей
непосредственной
целью
—
хранением
и
обеспечение
целост-
ности
данных.
Для
орг
анизации
кэширования
существу
ет
два
инструмент
а
для
P
ostgreSQL:
∙
Pgmemcac
he
(с
memcac
hed);
∙
Pgpo
ol-I
I
(query
cache);
9.2
Pgmemcac
he
Memcac
hed
—
программное
обеспечение,
реализующее
сервис
кэширо-
вания
данных
в
оперативной
памяти
на
основе
хеш-т
аблицы.
С
помощью
клиентск
ой
библиотеки
позволяет
кэшировать
данные
в
оперативной
па-
мяти
мно
ж
ества
доступных
серверов.
Р
аспределение
реализу
ется
путём
сегментирования
данных
по
зна
чению
хэша
ключа
по
аналогии
с
сокет
ами
хэш-т
аблицы.
Клиентск
ая
библиотека,
использу
я
ключ
данных,
вычисля-
ет
хэш
и
использу
ет
его
для
выбора
соответствующего
сервера.
Ситуация
сбо
я
сервера
трактуетс
я
как
промах
кэша,
что
позволяет
повышать
от-
к
азоустойчивость
к
омплекса
за
счет
наращивания
количества
memcached
серверов
и
возмо
жности
производить
их
горячую
замену
.
Pgmemcac
he
—
это
PostgreSQL
API
библиотека
на
основе
libmemcac
hed
для
взаимодействия
с
memcac
hed.
С
помощью
данной
библиотеки
P
ostgreSQL мо
ж
ет
записывать,
считывать,
иск
ать
и
у
далять
данные из
memcac
hed.
У
становк
а
Поск
ольку
Pgmemcache
идет
как
моду
ль,
то
потребуетс
я
P
ostgreSQL
с
PGXS
(если
уж
е
не
у
ст
ановлен,
поскольку
в
сборках
для
Linux
присут-
ству
ет
PGXS).
Т
акже
потребуетс
я
memcac
hed
и
libmemcached
библиотека
версии
не
ниже
0.38.
После
ска
чивания
и
распаковки
ис
хо
дник
ов
дост
а-
точно
выполнить
в
к
онсоли:
Листинг
9.1
У
становк
а
из
исх
одник
ов
Line
1
$
m
a
k
e
-
$
s
u
d
o
m
a
ke
i
n
s
t
a
l
l
Настройк
а
После
успешной
уст
ановки
Pgmemcache
потребуетс
я
добавить
во
все
базы
данных
(на
которых
вы
хотите
использовать
Pgmemcache)
функции
для
работы
с
этой
библиотек
ой:
180
9.2.
Pgmemcache
Листинг
9.2
Настройка
Line
1
%
p
s
q
l
[
mydbname
]
[
p
g
u
s
e
r
]
-
[
mydbname
]=
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
g
m
e
m
c
a
c
h
e
;
Т
еперь
можно
добавлять
сервера
memcac
hed
через
memcac
he_server_add
и
работ
ать
с
кэшем.
Но
есть
о
дно
но.
Все
сер-
вера memcached придетс
я
задавать
при каждом новом
по
дключении
к
P
ostgreSQL.
Это
ограничение
мо
жно
обойти,
если
настроить
параметры
в
postgresql
.
conf
файле:
∙
Добавить
pgmemcache
в
shared_preload_libraries
(автозагрузк
а
библио-
теки
pgmemcac
he
во
время
старт
а
PostgreSQL);
∙
Добавить
pgmemcac
he
в
custom_v
ariable_classes
(у
станавливаем
пере-
менную
для
pgmemcac
he);
∙
Создаем
pgmemcac
he.default_servers
,
ук
азав
в
формате
«host:p
ort»
(p
ort
-
опционально)
через
запятую.
Например:
Листинг
9.3
Настройка
default_servers
Line
1
p
g
m
e
m
c
a
c
h
e
.
d
e
f
a
u
l
t
_
s
e
r
v
e
r
s
=
’
1
2
7
.
0
.
0
.
1
,
1
9
2
.
1
6
8
.
0
.
2
0
:
1
1
2
1
1
’
# по
дключили
два
сервера
m
e
m
c
a
c
h
e
d
∙
Т
акж
е
мож
ем
настроить
работу
самой
библиотеки
pgmemcache
че-
рез
pgmemcache.default_behavior
.
Настройки
соответствуют
настрой-
к
ам
libmemcached.
Например:
Листинг
9.4
Настройка
pgmemcache
Line
1
p
g
m
e
m
c
a
c
h
e
.
d
e
f
a
u
l
t
_
b
e
h
a
v
i
o
r=
’B
I
N
A
R
Y
_
P
R
O
T
O
C
O
L
:
1
’
Т
еперь
не
требу
етс
я
при
по
дключении
к
P
ostgreSQL
указывать
сервера
memcac
hed.
Проверк
а
После
у
спешной
у
становки
и
настройки
pgmemcac
he
становитс
я
досту-
пен
список
к
оманд
для
работы
с
memcached
серверами.
Посмотрим работу в СУБД данных функций. Для на
чала получим
информацию
о
memcac
hed
серверах:
Листинг
9.5
Проверка
memcache_stats
Line
1
p
g
m
e
m
c
a
c
h
e
=
#
S
E
L
E
C
T
m
e
m
c
a
c
h
e
_
s
t
a
t
s
(
)
;
-
m
e
m
c
a
c
h
e
_
s
t
a
t
s
181
9.2.
Pgmemcache
Т
аблица
9.1:
Список
к
оманд
pgmemcache
Команда
Описание
memcac
he_server_add(’hostname:port’::TEXT)
memcac
he_server_add(’hostname’::TEXT)
Добавляет
memcached
сервер
в
список
доступ-
ных
серверов.
Если
порт
не
указан,
по
умолча-
нию
используетс
я
11211.
memcac
he_add(key::TEXT,
v
alue::TEXT,
expire::TIMEST
AMPTZ)
memcac
he_add(key::TEXT,
v
alue::TEXT,
expire::INTER
V
AL)
memcac
he_add(key::TEXT,
v
alue::TEXT)
Добавляет
ключ
в
кэш,
если
ключ
не
существу-
ет
.
newv
al
=
memcache_decr(k
ey::TEXT,
decremen
t::INT4)
newv
al
=
memcache_decr(k
ey::TEXT)
Если
ключ
существует
и
является
целым
чис-
лом,
происх
одит
уменьшение его
значения
на
ук
азанное
число
(по
умолчанию на
единицу).
Возвращает
целое
число
после
уменьшения.
memcac
he_delete(key::TEXT,
hold_timer::INTER
V
AL)
memcac
he_delete(key::TEXT)
У
даляет
указанный ключ. Если
указать тай-
мер,
то
ключ
с
таким
ж
е
названием
мож
ет
быть
добавлен
только
после
окончания
таймера.
memcac
he_flush_all()
Очищает
все
данные
на
всех
memcached
серве-
рах.
v
alue
=
memcache_get(k
ey::TEXT)
Выбирает ключ из
кэша. Возвращает
NULL,
если
ключ
не
существует
,
иначе
—
текстовую
строку
.
memcac
he_get_multi(k
eys::TEXT[])
memcac
he_get_multi(k
eys::BYTEA[])
Получает
массив
ключей
из
кэша.
Воз-
вращает
список
найденных
записей
в
виде
«ключ=зна
чение»
.
newv
al
=
memcache_incr(k
ey::TEXT,
incremen
t::INT4)
newv
al
=
memcache_incr(k
ey::TEXT)
Если
ключ
существует
и
является
целым
чис-
лом,
происх
одит увеличение
его
значения на
ук
азанное
число
(по
умолчанию на
единицу).
Возвращает
целое
число
после
увеличения.
memcac
he_replace(key::TEXT,
v
alue::TEXT,
expire::TIMEST
AMPTZ)
memcac
he_replace(key::TEXT,
v
alue::TEXT,
expire::INTER
V
AL)
memcac
he_replace(key::TEXT,
v
alue::TEXT)
Заменяет
значение
для
существующего
ключа.
memcac
he_set(key::TEXT,
v
alue::TEXT,
expire::TIMEST
AMPTZ)
memcac
he_set(key::TEXT,
v
alue::TEXT,
expire::INTER
V
AL)
memcac
he_set(key::TEXT,
v
alue::TEXT)
Создает
ключ
со
зна
чением.
Если
так
ой
ключ
существу
ет
—
заменяет
в
нем
значение
на
ука-
занное.
stats
=
memcache_stats()
Возвращает
статистику
по
всем
серверам
memcac
hed.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
5
S
e
r
v
e
r
:
1
2
7
.
0
.
0
.
1
(
1
1
2
1
1
)
-
p
i
d
:
1
1
1
6
-
u
p
t
i
m
e
:
7
0
-
t
i
m
e
:
1
2
8
9
5
9
8
0
9
8
-
v
e
r
s
i
o
n
:
1
.
4
.
5
10
p
o
i
n
t
e
r
_
s
i
z
e
:
3
2
182
9.2.
Pgmemcache
-
r
u
s
a
g
e
_
u
s
e
r
:
0
.
0
-
r
u
s
a
g
e
_
s
y
s
t
e
m
:
0
.
2
4
0
0
1
-
c
u
r
r
_
i
t
e
m
s
:
0
-
t
o
t
a
l
_
i
t
e
m
s
:
0
15
b
y
t
e
s
:
0
-
c
u
r
r
_
c
o
n
n
e
c
t
i
o
n
s
:
5
-
t
o
t
a
l
_
c
o
n
n
e
c
t
i
o
n
s
:
7
-
c
o
n
n
e
c
t
i
o
n
_
s
t
r
u
c
t
u
r
e
s
:
6
-
c
m
d
_
g
e
t
:
0
20
c
m
d
_
s
e
t
:
0
-
g
e
t
_
h
i
t
s
:
0
-
g
e
t
_
m
i
s
s
e
s
:
0
-
e
v
i
c
t
i
o
n
s
:
0
-
b
y
t
e
s
_
r
e
a
d
:
2
0
25
b
y
t
e
s
_
w
r
i
t
t
e
n
:
7
8
2
-
l
i
m
i
t
_
m
a
x
b
y
t
e
s
:
6
7
1
0
8
8
6
4
-
t
h
r
e
a
d
s
:
4
-
-
(
1
r
o
w
)
Т
еперь
со
храним
данные
в
memcached
и
попробуем
их
забрать:
Листинг
9.6
Проверка
Line
1
p
g
m
e
m
c
a
c
h
e
=
#
S
E
L
E
C
T
m
e
m
c
a
c
h
e
_
a
d
d
(
’
s
o
m
e
_
k
e
y
’
,
’
t
e
s
t
_
v
a
l
u
e
’
)
;
-
me
m
c
a
c
h
e
_
a
d
d
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
t
5
(
1
r
o
w
)
-
-
p
g
m
e
m
c
a
c
h
e
=
#
S
E
L
E
C
T
m
e
m
c
a
c
h
e
_
g
e
t
(
’
s
o
m
e
_
k
e
y
’
)
;
-
m
e
m
c
a
c
h
e
_
g
e
t
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
10
t
e
s
t
_
v
a
l
u
e
-
(
1
r
o
w
)
Мо
жно
т
акже
проверить
работу
счетчиков
в
memcac
hed
(данный
функ-
ционал
мо
жет
пригодитьс
я
для
создания
последовательностей):
Листинг
9.7
Проверка
Line
1
p
g
m
e
m
c
a
c
h
e
=
#
S
E
L
E
C
T
m
e
m
c
a
c
h
e
_
a
d
d
(
’
s
o
m
e
_
s
e
q
’
,
’
1
0
’
)
;
-
me
m
c
a
c
h
e
_
a
d
d
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
t
5
(
1
r
o
w
)
-
-
p
g
m
e
m
c
a
c
h
e
=
#
S
E
L
E
C
T
m
e
m
c
a
c
h
e
_
i
n
c
r
(
’
s
o
m
e
_
s
e
q
’
)
;
183
9.2.
Pgmemcache
-
m
e
m
c
a
c
h
e
_
i
n
c
r
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
10
1
1
-
(
1
r
o
w
)
-
-
p
g
m
e
m
c
a
c
h
e
=
#
S
E
L
E
C
T
m
e
m
c
a
c
h
e
_
i
n
c
r
(
’
s
o
m
e
_
s
e
q
’
)
;
-
m
e
m
c
a
c
h
e
_
i
n
c
r
15
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1
2
-
(
1
r
o
w
)
-
-
p
g
m
e
m
c
a
c
h
e
=
#
S
E
L
E
C
T
m
e
m
c
a
c
h
e
_
i
n
c
r
(
’
s
o
m
e
_
s
e
q
’
,
1
0
)
;
20
m
e
m
c
a
c
h
e
_
i
n
c
r
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2
2
-
(
1
r
o
w
)
-
25
p
g
m
e
m
c
a
c
h
e
=
#
S
E
L
E
C
T
m
e
m
c
a
c
h
e
_
d
e
c
r
(
’
s
o
m
e
_
s
e
q
’
)
;
-
m
e
m
c
a
c
h
e
_
d
e
c
r
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2
1
-
(
1
r
o
w
)
30
-
p
g
m
e
m
c
a
c
h
e
=
#
S
E
L
E
C
T
m
e
m
c
a
c
h
e
_
d
e
c
r
(
’
s
o
m
e
_
s
e
q
’
)
;
-
m
e
m
c
a
c
h
e
_
d
e
c
r
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2
0
35
(
1
r
o
w
)
-
-
p
g
m
e
m
c
a
c
h
e
=
#
S
E
L
E
C
T
m
e
m
c
a
c
h
e
_
d
e
c
r
(
’
s
o
m
e
_
s
e
q
’
,
6
)
;
-
m
e
m
c
a
c
h
e
_
d
e
c
r
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
40
1
4
-
(
1
r
o
w
)
Для
работы
с
pgmemcache
лучше
создать
функции
и,
если
требу
ется,
активировать
эти
функции
через
триггеры.
Например,
прило
ж
ение
кэширу
ет
зашифрованные
пароли
пользовате-
лей
в
memcached
(для
более
быстрого
доступа),
и
нам
требуетс
я
обновлять
информацию
в
кэше,
если
она
изменяетс
я
в
СУБД.
Создаем
функцию:
Листинг
9.8
Функция
для
обновления
данных
в
кэше
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
a
u
t
h
_
p
a
s
s
w
d
_
u
p
d
(
)
R
E
T
U
R
N
S
T
R
I
G
G
E
R
A
S
$
$
-
B
E
G
I
N
-
I
F
O
L
D
.
p
a
s
s
w
d
!
= N
E
W.
p
a
s
s
w
d
T
H
E
N
184
9.2.
Pgmemcache
-
P
E
R
F
O
R
M
m
e
m
c
a
c
h
e
_
s
e
t
(
’
u
s
e
r
_
i
d
_
’
|
|
N
E
W.
u
s
e
r
_
i
d
|
|
’
_
p
a
s
s
w
o
r
d
’
,
N
E
W.
p
a
s
s
w
d
)
;
5
E
N
D
I
F
;
-
R
E
T
U
R
N
N
E
W;
-
E
N
D
;
-
$
$
L
A
N
G
U
A
G
E
’
p
l
p
g
s
q
l
’
;
Активиру
ем
триггер
для
обновления
таблицы
пользователей:
Листинг
9.9
Триггер
Line
1
C
R
E
A
T
E
T
R
I
G
G
E
R
a
u
t
h
_
p
a
s
s
w
d
_
u
p
d
_
t
r
g
A
F
T
E
R
U
P
D
A
T
E
O
N
p
a
s
s
w
d
F
O
R
E
A
C
H
R
O
W
E
X
E
C
U
T
E
P
R
O
C
E
D
U
R
E
a
u
t
h
_
p
a
s
s
w
d
_
u
p
d
(
)
;
Но
данный
пример
транзакционно
небезопасен
—
при
отмене
транзак-
ции
кэш
не
вернетс
я
на
ст
арое
значение.
Поэтому
лучше
очищать
ст
арые
данные:
Листинг
9.10
Очистка
ключа
в
кэше
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
a
u
t
h
_
p
a
s
s
w
d
_
u
p
d
(
)
R
E
T
U
R
N
S
T
R
I
G
G
E
R
A
S
$
$
-
B
E
G
I
N
-
I
F
O
L
D
.
p
a
s
s
w
d
!
= N
E
W.
p
a
s
s
w
d
T
H
E
N
-
P
E
R
F
O
R
M
m
e
m
c
a
c
h
e
_
d
e
l
e
t
e
(
’
u
s
e
r
_
i
d
_
’
|
|
N
E
W.
u
s
e
r
_
i
d
|
|
’
_
p
a
s
s
w
o
r
d
’
)
;
5
E
N
D
I
F
;
-
R
E
T
U
R
N
N
E
W;
-
E
N
D
;
$
$
L
A
N
G
U
A
G
E
’
p
l
p
g
s
q
l
’
;
Т
акж
е
нужен
триггер
на
чистку
кэша
при
у
далении
записи
из
СУБД:
Листинг
9.11
Триггер
Line
1
C
R
E
A
T
E
T
R
I
G
G
E
R
a
u
t
h
_
p
a
s
s
w
d
_
d
e
l
_
t
r
g
A
F
T
E
R
D
E
L
E
T
E
O
N
p
a
s
s
w
d
F
O
R
E
A
C
H
R
O
W
E
X
E
C
U
T
E
P
R
O
C
E
D
U
R
E
a
u
t
h
_
p
a
s
s
w
d
_
u
p
d
(
)
;
Данный
пример
с
делан
для
наглядности,
а
создавать
кэш
в
memcached
на
к
ешированый
пароль
нового
пользователя
(или
обновленного)
лучше
через
прило
жение.
Заключение
P
ostgreSQL
с
помощью
Pgmemcache
библиотеки
позволяет
работ
ать
с
memcac
hed
серверами,
что
мож
ет
потребоваться
в
определенных
случаях
для
кэширования
данных
напрямую
с
СУБД.
У
добство
данной
библиоте-
ки
заключаетс
я
в
полном
доступе
к
функциям
memcached,
но
вот
готовой
реализации
кэширование
SQL
запросов
тут
нет
,
и
её
придется
дорабаты-
вать
вручную
через
функции
и
триггеры
P
ostgreSQL.
185
9.3.
Заключение
9.3
Заключение
TODO
186
10
Р
асширения
Гибк
ость
ума
мо
жет
заменить
красоту
Стендаль
10.1
Введение
Один
из
главных
плюсов
P
ostgreSQL
это
возмо
жность
расширения
его
функционала
с
помощью
расширений.
В
данной
статье
я
затрону
только
самые
интересные
и
попу
лярные
из
существующих
расширений.
10.2
P
ostGIS
P
ostGIS
добавляет
поддер
жку
для
географических
объектов
в
P
ostgreSQL. По
сути
PostGIS
позволяет использовать
P
ostgreSQL
в
к
а-
честве
бэкенда
пространственной
базы
данных
для
геоинформационных
систем
(ГИС),
так
ж
е,
к
ак
ESRI
SDE
или
пространственного
расширения
Oracle.
PostGIS
соответствует
Op
enGIS
«Простые
особенности.
Специфи-
к
ация
для
SQL»
и
был
сертифицирован.
У
становк
а
и
использование
Для
на
чала
инициализируем
расширение
в
базе
данных:
Листинг
10.1
Инициализация
p
ostgis
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
o
s
t
g
i
s
;
При
создании
пространственной
базы
данных
автоматически
создают-
с
я
таблица
метаданных
spatial_ref_sys
и
представления
geometry_columns
,
187
10.2.
PostGIS
geograph
y_columns
,
raster_columns
и
raster_o
verviews
.
Они
создаютс
я
в
соот-
ветствии
со
спецификацией
«Op
en
Geospatial
Consortium
Simple
F
eatures
for
SQL
sp
ecification»
,
выпущенной
OGC
и
описывающей
стандартные
ти-
пы
объектов ГИС,
функции для
манипу
ляции
ими
и
набор
т
аблиц ме-
т
аданных.
Т
аблица
spatial_ref_sys
содер
жит
числовые
идентификаторы
и
тек
стовые
описания
си
стем
к
оординат
,
используемых
в
пространственной
базе
данных.
Одним
из
полей
этой
т
аблицы
являетс
я
поле
SRID
—
уни-
к
альный
идентификатор,
однозна
чно
определяющий
систему
к
оординат
.
SRID
представляет
из себ
я
числовой
к
од,
которому
соответствует
нек
о-
торая
система
к
оординат
.
Например,
распространенный
к
о
д
EPSG
4326
соответству
ет
географическ
ой
системе
к
оординат
W
GS84.
Более
по
дроб-
ную
информацию
по
таблицами
мет
аданных
мо
жно
найти
в
рук
оводстве
по
P
ostGIS
.
Т
еперь,
имея
пространственную
базу
данных,
можно
создать
нескольк
о
пространственных
т
аблиц.
Для
начала
создадим
обычную
т
аблицу
базы
данных,
чтобы
хранить
данные
о
горо
де.
Эт
а
т
аблица
бу
дет
со
держ
ать
три
поля:
числовой
идентифик
атор,
название
города
и
колонк
а
геометрии,
со
держ
ащую
данные
о
местополож
ении
горо
дов:
Листинг
10.2
Создание
таблицы
cities
Line
1
#
C
R
E
A
T
E
T
A
B
L
E
c
i
t
i
e
s
(
i
d
i
n
t
4
p
r
i
m
a
r
y
k
e
y
,
nam
e
v
a
r
c
h
a
r
(
5
0
)
,
t
h
e
_
g
e
o
m
g
e
o
m
e
t
r
y
(
PO
I
N
T
,
4
3
2
6
)
)
;
the_geom
поле указывает
P
ostGIS, как
ой тип геометрии имеет к
аж-
дый
из
объектов
(точки,
линии,
полигоны
и
т
.
п.),
к
акая
размерность
(т
.к.
возмо
жны
и
3-4
измерения
—
POINTZ
,
POINTM
,
POINTZM
)
и
как
ая
си-
стема
к
оординат
.
Для
данных
по
горо
дам
мы
бу
дем
использовать
систему
к
оординат
EPSG:4326.
Чтобы
добавить
данные
геометрии
в
соответству-
ющую
колонку
,
используетс
я
функция
P
ostGIS
ST_GeomF
romT
ext
,
чтобы
ск
онвертировать
коор
динаты
и
идентифик
атор
референсной
системы
из
тек
стового
формата:
Листинг
10.3
Заполнение
таблицы
cities
Line
1
#
I
N
SE
RT I
N
T
O
c
i
t
i
e
s
(
i
d
,
t
h
e
_
g
e
o
m
,
nam
e
)
V
A
L
U
E
S
(
1
,
ST_Ge
omFrom
Text
(
’
P
O
I
N
T
(
-
0
.
1
2
5
7
5
1
.
5
0
8
)
’
,
4
3
2
6
)
,
’
L
o
n
d
o
n
,
E
n
g
l
a
n
d
’
)
;
-
#
IN
SE
R
T
I
NT
O
c
i
t
i
e
s
(
i
d
,
t
h
e
_
g
e
o
m
,
na
me
)
V
A
L
U
E
S
(
2
,
ST_Ge
omFrom
Text
(
’
P
O
I
N
T
(
-
8
1
.
2
3
3
4
2
.
9
8
3
)
’
,
4
3
2
6
)
,
’
L
o
n
d
o
n
,
O
n
t
a
r
i
o
’
)
;
-
#
IN
SE
R
T
I
NT
O
c
i
t
i
e
s
(
i
d
,
t
h
e
_
g
e
o
m
,
na
me
)
V
A
L
U
E
S
(
3
,
ST_Ge
omFrom
Text
(
’
P
O
I
N
T
(
2
7
.
9
1
1
6
2
4
9
1
-
3
3
.
0
1
5
2
9
)
’
,
4
3
2
6
)
,
’
E
a
s
t
L
o
n
d
o
n
,
SA
’
)
;
Все
самые
обычные
операторы
SQL
могут
быть
использованы
для
вы-
бора
данных
из
т
аблицы
PostGIS:
188
10.2.
PostGIS
Листинг
10.4
SELECT
cities
Line
1
#
S
E
L
E
C
T
*
F
R
O
M
c
i
t
i
e
s
;
-
i
d
|
nam
e
|
t
h
e
_
g
e
o
m
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1
|
L
o
n
d
o
n
,
E
n
g
l
a
n
d
|
0
1
0
1
0
0
0
0
2
0
E
6
1
0
0
0
0
0
B
B
B
8
8
D
0
6
F
0
1
6
C
0
B
F
1
B
2
F
D
D
2
4
0
6
C
1
4
9
4
0
5
2
|
L
o
n
d
o
n
,
O
n
t
a
r
i
o
|
0
1
0
1
0
0
0
0
2
0
E
61
0
0
0
0
0
F
4
F
D
D
4
7
8
E
9
4
E5
4
C
0
E
7
F
B
A
9
F
1
D
2
7
D
4
54
0
-
3
|
E
a
s
t
L
o
n
d
o
n
,
S
A
|
0
1
0
1
0
0
0
0
2
0
E
6
1
0
0
0
0
0
4
0
A
B
0
6
4
0
6
0
E
9
3
B
4
0
5
9
F
A
D
0
0
5
F
5
8
1
4
0
C
0
-
(
3
r
o
w
s
)
Это
возвращает
нам
бессмысленные
значения
коор
динат
в
шестна-
дцатеричной
системе.
Если
вы
хотите увидеть
вашу
геометрию
в
тек-
стовом
формате
WKT,
используйте
функцию
ST_AsT
ext(the_geom)
или
ST_AsEwkt(the_geom)
. Вы такж
е мож
ете использовать функции
ST_X(
the_geom)
,
ST_Y(the_geom)
,
чтобы
получить
числовые
зна
чения
к
оорди-
нат:
Листинг
10.5
SELECT
cities
Line
1
#
S
E
L
E
C
T
i
d
,
ST
_A
sT
ex
t
(
t
h
e
_
g
e
o
m
)
,
S
T_
As
Ew
kt
(
th
e
_
g
e
o
m
)
,
S
T
_
X
(
t
h
e
_
g
e
o
m
)
,
S
T
_
Y
(
t
h
e
_
g
e
o
m
)
F
R
O
M
c
i
t
i
e
s
;
-
i
d
|
s
t
_
a
s
t
e
x
t
|
s
t
_
a
s
e
w
k
t
|
s
t
_
x
|
s
t
_
y
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
1
|
P
O
I
N
T
(
-
0
.
1
2
5
7
5
1
.
5
0
8
)
|
SRID
=
4
3
2
6
;
P
O
I
N
T
(
-
0
.
1
2
5
7
5
1
.
5
0
8
)
|
-
0
.
1
2
5
7
|
5
1
.
5
0
8
5
2
|
P
O
I
N
T
(
-
8
1
.
2
3
3
4
2
.
9
8
3
)
|
SRID
=
4
3
2
6
;
P
O
I
N
T
(
-
8
1
.
2
3
3
4
2
.
9
8
3
)
|
-
8
1
.
2
3
3
|
4
2
.
9
8
3
-
3
|
P
O
I
N
T
(
2
7
.
9
1
1
6
2
4
9
1
-
3
3
.
0
1
5
2
9
)
|
SRID
=
4
3
2
6
;
P
O
I
N
T
(
2
7
.
9
1
1
6
2
4
9
1
-
3
3
.
0
1
5
2
9
)
|
2
7
.
9
1
1
6
2
4
9
1
|
-
3
3
.
0
1
5
2
9
-
(
3
r
o
w
s
)
Большинство
т
аких
функций
на
чинаются
с
ST
(пространственный
тип)
и
описаны
в
документ
ации
PostGIS.
Т
еперь
ответим
на
практический
во-
прос:
на
к
аком
расстоянии
в
метрах
друг
от
друга
нахо
дятся
три
города
с
названием
Лондон,
учитывая
сферичность
земли?
Листинг
10.6
Рассто
яние
до
Лондона
189
10.3.
pgSphere
Line
1
#
S
E
L
E
C
T
p
1
.
n
am
e
,
p
2
.
name
,
S
T
_
D
i
s
t
a
n
c
e
_
S
p
h
e
r
e
(
p
1
.
t
h
e
_
g
e
o
m
,
p
2
.
t
h
e
_
g
e
o
m
)
F
R
O
M
c
i
t
i
e
s
AS
p
1
,
c
i
t
i
e
s
AS
p
2
W
H
E
R
E
p
1
.
i
d
>
p
2
.
i
d
;
-
na
me
|
nam
e
|
s
t
_
d
i
s
t
a
n
c
e
_
s
p
h
e
r
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
L
o
n
d
o
n
,
O
n
t
a
r
i
o
|
L
o
n
d
o
n
,
E
n
g
l
a
n
d
|
5
8
7
5
7
8
7
.
0
3
7
7
7
3
5
6
5
E
a
s
t
L
o
n
d
o
n
,
SA
|
L
o
n
d
o
n
,
E
n
g
l
a
n
d
|
9
7
8
9
6
8
0
.
5
9
9
6
1
4
7
2
-
E
a
s
t
L
o
n
d
o
n
,
SA
|
L
o
n
d
o
n
,
O
n
t
a
r
i
o
|
1
3
8
9
2
2
0
8
.
6
7
8
2
9
2
8
-
(
3
r
o
w
s
)
Этот
запрос
возвращает
расстояние
в
метрах
между
к
аждой
парой
го-
ро
дов.
Обратите
внимание
как
часть
WHERE
предотвращает
нас
от
полу-
чения
рассто
яния
от
города
до
самого
себя
(рассто
яние
всегда
бу
дет
равно
ну
лю)
и
расстояния
в
обратном
порядк
е
(расстояние
от
Лондона,
Анг
лия
до
Лондона,
Онт
арио
бу
дет
т
аким
же
к
ак
от
Лондона,
Онтарио
до
Лон-
дона,
Англия).
Т
акже
мо
жем
рассчит
ать
расстояния
на
сфере,
используя
различные
функции
и
указывая
называния
сфероида,
параметры
г
лавных
полу
осей
и
коэффициент
а
обратного
сж
атия:
Листинг
10.7
Рассто
яние
до
Лондона
Line
1
#
S
E
L
E
C
T
p
1
.
n
am
e
,
p
2
.
name
,
S
T
_
D
i
s
t
a
n
c
e
_
S
p
h
e
r
o
i
d
(
-
#
p
1
.
t
h
e
_
g
e
o
m
,
p
2
.
t
h
e
_
g
e
o
m
,
’
S
P
H
E
R
O
I
D
[
"
GRS_198
0
"
,
6
3
7
8
1
3
7
,
2
9
8
.
2
5
7
2
2
2
]
’
-
#
)
-
#
F
R
O
M
c
i
t
i
e
s
AS
p
1
,
c
i
t
i
e
s
A
S
p
2
W
H
E
R
E
p
1
.
i
d
>
p
2
.
i
d
;
5
na
me
|
nam
e
|
s
t
_
d
i
s
t
a
n
c
e
_
s
p
h
e
r
o
i
d
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
L
o
n
d
o
n
,
O
n
t
a
r
i
o
|
L
o
n
d
o
n
,
E
n
g
l
a
n
d
|
5
8
9
2
4
1
3
.
6
3
9
9
9
1
5
3
-
E
a
s
t
L
o
n
d
o
n
,
SA
|
L
o
n
d
o
n
,
E
n
g
l
a
n
d
|
9
7
5
6
8
4
2
.
6
5
7
1
5
0
4
6
-
E
a
s
t
L
o
n
d
o
n
,
SA
|
L
o
n
d
o
n
,
O
n
t
a
r
i
o
|
1
3
8
8
4
1
4
9
.
4
1
4
3
7
9
5
10
(
3
r
o
w
s
)
Заключение
В
данной
главе
мы
рассмотрели
как
на
чать
работать
с
PostGIS.
Более
по
дробно
об
использовании
расширения
мо
жно
ознакомитьс
я
через
офи-
циальную
документ
ацию
.
10.3
pgSphere
pgSphere
обеспечивает
PostgreSQL сферическими
типами
данных,
а
т
акже
функциями
и
операторами
для
работы
с
ними.
Использу
ется
для
работы
с
географическими
(мо
жет
использоваться
вместо
P
ostGIS)
или
астрономическими
типами
данных.
190
10.3.
pgSphere
У
становк
а
и
использование
Для
на
чала
инициализируем
расширение
в
базе
данных:
Листинг
10.8
Инициализация
pgSphere
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
g
_
s
p
h
e
r
e
;
После
этого
мо
жем
проверить,
что
расширение
функционирует:
Листинг
10.9
Проверка
pgSphere
Line
1
#
S
E
L
E
C
T
s
p
o
l
y
’
{
(
2
7
0
d
,
-
1
0
d
)
,
(
2
7
0
d
,
3
0
d
)
,
(
2
9
0
d
,
1
0
d
)
}
’
;
-
s
p
o
l
y
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{
(
4
.
7
1
2
3
8
8
9
8
0
3
8
4
6
9
,
-
0
.
1
7
4
5
3
2
9
2
5
1
9
9
4
3
3
)
,
(
4
.
7
1
2
3
8
8
9
8
0
3
8
4
6
9
,
0
.
5
2
3
5
9
8
7
7
5
5
9
8
2
9
9
)
,
(
5
.
0
6
1
4
5
4
8
3
0
7
8
3
5
6
,
0
.
1
7
4
5
3
2
9
2
5
1
9
9
4
3
3
)
}
5
(
1
r
o
w
)
И
работу
индек
сов:
Листинг
10.10
Проверка
pgSphere
Line
1
#
C
R
E
A
T
E
T
A
B
L
E
t
e
s
t
(
-
#
p
o
s
s
p
o
i
n
t
N
O
T
N
U
L
L
-
#
)
;
-
C
R
E
A
T
E
T
A
B
L
E
5
#
C
R
E
A
T
E
I
N
D
E
X
t
e
s
t
_
p
o
s
_
i
d
x
O
N
t
e
s
t
US
I
NG
G
IST
(
p
o
s
)
;
-
C
R
E
A
T
E
I
N
D
E
X
-
#
IN
SE
R
T
I
NT
O
t
e
s
t
(
p
o
s
)
V
A
L
U
E
S
(
’
(
1
0
.
1
d
,
-
9
0
d
)
’
)
,
(
’
(
1
0
d
1
2
m
1
1
.
3
s
,
-
1
3
d
1
4
m)
’
)
;
-
I
N
SE
RT
0
2
-
#
V
A
C
U
U
M
A
N
A
L
Y
Z
E
t
e
s
t
;
10
V
A
C
U
U
M
-
#
S
E
L
E
C
T
s
e
t
_
s
p
h
e
r
e
_
o
u
t
p
u
t
(
’D
E
G
’
)
;
-
s
e
t
_
s
p
h
e
r
e
_
o
u
t
p
u
t
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
S
ET
D
E
G
15
(
1
r
o
w
)
-
-
#
S
E
L
E
C
T
*
F
R
O
M
t
e
s
t
;
-
p
o
s
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
20
(
1
0
.
1
d
,
-
9
0
d
)
191
10.4.
HStore
-
(
1
0
.
2
0
3
1
3
8
8
8
8
8
8
8
9
d
,
-
1
3
.
2
3
3
3
3
3
3
3
3
3
3
3
3
d
)
-
(
2
r
o
w
s
)
-
#
S
ET
e
n
a
b
l
e
_
s
e
q
s
c
a
n
=
O
F
F
;
-
SE
T
25
#
E
X
P
L
A
I
N
S
E
L
E
C
T
*
F
R
O
M
t
e
s
t
W
H
E
R
E
p
o
s
=
s
p
o
i
n
t
’
(
1
0
.
1
d
,
-
9
0
d
)
’
;
-
Q
U
E
R
Y
P
L
A
N
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
B
i
t
m
a
p
He
a
p
S
c
a
n
o
n
t
e
s
t
(
c
o
s
t
=
4
.
1
6
.
.
9
.
5
0
r
o
w
s
=
2
w
i
d
t
h
=
1
6
)
-
R
e
c
h
e
c
k
Con
d
:
(
p
o
s
=
’
(
1
0
.
1
d
,
-
9
0
d
)
’
:
:
s
p
o
i
n
t
)
30
-
>
B
i
t
m
a
p
I
n
d
e
x
S
c
a
n
o
n
t
e
s
t
_
p
o
s
_
i
d
x
(
c
o
s
t
=
0
.
0
0
.
.
4
.
1
6
r
o
w
s
=2
w
i
d
t
h
=
0
)
-
I
n
d
e
x
Co
nd
:
(
p
o
s
=
’
(
1
0
.
1
d
,
-
9
0
d
)
’
:
:
s
p
o
i
n
t
)
-
(
4
r
o
w
s
)
Заключение
Более
подробно
об
использовании
расширения
мо
жно
ознакомитьс
я
че-
рез
официальную
документ
ацию
.
10.4
HStore
HStore
–
расширение,
которое
реализу
ет
тип
данных
для
хранения
клю-
ч/зна
чение
в
пределах
одного
значения
в
PostgreSQL
(например,
в
одном
тек
стовом поле). Это мож
ет быть полезно в различных ситу
ациях, т
а-
ких
как
строки
со
многими
атрибутами,
которые
редко
выбираются,
или
полу-структурированные
данные.
Ключи
и
значения
являются
простыми
тек
стовыми
строками.
На
чиная
с
версии
9.4
PostgreSQL
был
добавлен
JSONB
тип
(бинарный
JSON).
Данный
тип
являетс
я
объединением
JSON
структуры
с
возмо
ж-
ностью использовать
индексы,
к
ак у
Hstore.
JSONB
лучше
Hstore
тем,
что
есть
возмо
жность
со
хранять
влож
енную
структуру
данных
(nested)
и
хранить
не
тольк
о
текстовые
строки
в
значениях.
Поэтому
лучше
исполь-
зовать
JSONB,
если
есть
т
акая
возможность.
У
становк
а
и
использование
Для
на
чала
активируем
расширение:
Листинг
10.11
Активация
hstore
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
h
s
t
o
r
e
;
192
10.4.
HStore
Проверим
его
работу:
Листинг
10.12
Проверка
hstore
Line
1
#
S
E
L
E
C
T
’
a
=
>1
,
a=
>
2
’
:
:
h
s
t
o
r
e
;
-
h
s
t
o
r
e
-
-
-
-
-
-
-
-
-
-
-
-
"
a
"=
>
"
1
"
5
(
1
r
o
w
)
Как
видно
в
примере
10.12
ключи
в
hstore
уникальны.
Создадим
т
аб-
лицу
и
заполним
её
данными:
Листинг
10.13
Проверка
hstore
Line
1
C
R
E
A
T
E
T
A
B
L
E
p
r
o
d
u
c
t
s
(
-
i
d
s
e
r
i
a
l
P
R
I
M
A
R
Y
K
E
Y
,
-
n
am
e
v
a
r
c
h
a
r
,
-
a
t
t
r
i
b
u
t
e
s
h
s
t
o
r
e
5
)
;
-
I
N
SE
RT I
NT
O
p
r
o
d
u
c
t
s
(
nam
e
,
a
t
t
r
i
b
u
t
e
s
)
-
V
A
L
U
E
S
(
-
’
G
e
e
k
L
o
v
e
:
A
N
o
v
e
l
’
,
-
’
a
u
t
h
o
r
=
>
"
K
a
t
h
e
r
i
n
e
Dunn
"
,
10
p
a
g
e
s
=
>
3
6
8
,
-
c
a
t
e
g
o
r
y
=
>
f
i
c
t
i
o
n
’
-
)
,
-
(
-
’
L
e
i
c
a
M
9
’
,
15
’
m
a
n
u
f
a
c
t
u
r
e
r
=
>
L
e
i
c
a
,
-
t
y
p
e
=
>
c
a
m
e
r
a
,
-
m
e
g
a
p
i
x
e
l
s
=
>
1
8
,
-
s
e
n
s
o
r
=
>
"
f
u
l
l
-
f
r
a
m
e
3
5
m
m
"
’
-
)
,
20
(
’
Ma
c
Bo
ok
A
i
r
1
1
’
,
-
’
m
a
n
u
f
a
c
t
u
r
e
r
=
>
A
p
p
l
e
,
-
t
y
p
e
=
>
c
o
m
p
u
t
e
r
,
-
ra
m
=
>
4G
B,
-
s
t
o
r
a
g
e
=
>
2
5
6G
B
,
25
p
r
o
c
e
s
s
o
r
=
>
"
1
.
8
g
h
z
I
n
t
e
l
i
7
d
u
e
l
c
o
r
e
"
,
-
w
e
i
g
h
t
=
>
2
.
3
8
l
b
s
’
-
)
;
Т
еперь
мо
жно
производить
поиск
по
ключу:
Листинг
10.14
Поиск
по
ключу
193
10.5.
PL
V8
Line
1
#
S
E
L
E
C
T
n
am
e
,
a
t
t
r
i
b
u
t
e
s
-
>
’
p
a
g
e
s
’
a
s
p
a
g
e
F
R
O
M
p
r
o
d
u
c
t
s
W
H
E
R
E
a
t
t
r
i
b
u
t
e
s
?
’
p
a
g
e
s
’
;
-
nam
e
|
p
a
g
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
G
e
e
k
L
o
v
e
:
A
N
o
v
e
l
|
3
6
8
5
(
1
r
o
w
)
Или
по
зна
чению
ключа:
Листинг
10.15
Поиск
по
значению
ключа
Line
1
#
S
E
L
E
C
T
n
am
e
,
a
t
t
r
i
b
u
t
e
s
-
>
’
m
a
n
u
f
a
c
t
u
r
e
r
’
a
s
m
a
n
u
f
a
c
t
u
r
e
r
F
R
O
M
p
r
o
d
u
c
t
s
W
H
E
R
E
a
t
t
r
i
b
u
t
e
s
-
>
’
t
y
p
e
’
=
’
c
o
m
p
u
t
e
r
’
;
-
na
me
|
m
a
n
u
f
a
c
t
u
r
e
r
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Mac
Bo
ok
A
i
r
1
1
|
A
p
p
l
e
5
(
1
r
o
w
)
Создание
индек
сов:
Листинг
10.16
Индексы
Line
1
#
C
R
E
A
T
E
I
N
D
E
X
p
r
o
d
u
c
t
s
_
h
s
t
o
r
e
_
i
n
d
e
x
O
N
p
r
o
d
u
c
t
s
U
S
I
NG
GI
ST
(
a
t
t
r
i
b
u
t
e
s
)
;
-
#
C
R
E
A
T
E
I
N
D
E
X
p
r
o
d
u
c
t
s
_
h
s
t
o
r
e
_
i
n
d
e
x
O
N
p
r
o
d
u
c
t
s
US
I
NG
GI
N
(
a
t
t
r
i
b
u
t
e
s
)
;
Мо
жно
такж
е
cоздавать
индекс
на
ключ:
Листинг
10.17
Индекс
на
ключ
Line
1
#
C
R
E
A
T
E
I
N
D
E
X
p
r
o
d
u
c
t
_
m
a
n
u
f
a
c
t
u
r
e
r
O
N
p
r
o
d
u
c
t
s
(
(
p
r
o
d
u
c
t
s
.
a
t
t
r
i
b
u
t
e
s
-
>
’
m
a
n
u
f
a
c
t
u
r
e
r
’
)
)
;
Заключение
HStore
—
расширение
для
у
добного
и
индек
сируемого
хранения
слабо-
структурированных
данных
в
PostgreSQL,
если
нет
возможности
исполь-
зовать
версию
базы
9.4
или
выше,
г
де
для
данной
задачи
есть
встроенный
JSONB
тип
данных.
10.5
PL
V8
PL
V8
являетс
я
расширением,
к
оторое
предоставляет
PostgreSQL
про-
цедурный
язык
с
движк
ом
V8
Jav
aScript.
С
помощью
этого
расширения
мо
жно
писать
в
PostgreSQL
Ja
v
aScript
функции,
к
оторые
можно
вызывать
из
SQL.
194
10.5.
PL
V8
У
становк
а
и
использование
Для
на
чала
инициализируем
расширение
в
базе
данных:
Листинг
10.18
Инициализация
plv8
Line
1
#
C
R
E
A
T
E
e
x
t
e
n
s
i
o
n
p
l
v
8
;
V8
компилиру
ет
Jav
aScript
к
од
непосредственно
в
машинный
к
од
и
с
помощью
этого
достиг
ается
высок
ая
ск
орость
работы.
Для
примера
рас-
смотрим
расчет
числа
Фибона
ччи.
Вот
функция
написана
на
plpgsql:
Листинг
10.19
Фибоначчи
на
plpgsql
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
-
p
s
q
l
f
i
b
(
n
i
n
t
)
R
E
T
U
R
N
S
i
n
t
AS
$
$
-
B
E
G
I
N
-
I
F
n <
2
T
H
E
N
5
R
E
T
U
R
N
n
;
-
E
N
D
I
F
;
-
R
E
T
U
R
N
p
s
q
l
f
i
b
(
n
-
1
)
+
p
s
q
l
f
i
b
(
n
-
2
)
;
-
E
N
D
;
-
$
$
L
A
N
G
U
A
G
E
p
l
p
g
s
q
l
I
M
M
U
T
A
B
L
E S
T
RI
C
T
;
Замерим
ск
орость
её
работы:
Листинг
10.20
Скорость
расчета
числа
Фибоначчи
на
plpgsql
Line
1
#
S
E
L
E
C
T
n
,
p
s
q
l
f
i
b
(
n
)
F
R
O
M
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
0
,
2
5
,
5
)
a
s
n
;
-
n
|
p
s
q
l
f
i
b
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
0
|
0
5
5
|
5
-
1
0
|
5
5
-
1
5
|
6
1
0
-
2
0
|
6
7
6
5
-
2
5
|
7
5
0
2
5
10
(
6
r
o
w
s
)
-
-
T
i
m
e
:
2
5
2
0
.
3
8
6
ms
Т
еперь
с
делаем
то
же
самое,
но
с
использованием
PL
V8:
Листинг
10.21
Фибоначчи
на
plv8
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
-
f
i
b
(
n
i
n
t
)
R
E
T
U
R
N
S
i
n
t
a
s
$
$
-
-
f
u
n
c
t
i
o
n
f
i
b
(
n
)
{
195
10.5.
PL
V8
5
r
e
t
u
r
n
n<2
?
n
:
f
i
b
(
n
-
1
)
+
f
i
b
(
n
-
2
)
-
}
-
r
e
t
u
r
n
f
i
b
(
n
)
-
-
$
$
L
A
N
G
U
A
G
E
p
l
v
8
I
M
M
U
T
A
B
L
E S
T
R
IC
T
;
Замерим
ск
орость
работы:
Листинг
10.22
Скорость
расчета
числа
Фибоначчи
на
plv8
Line
1
#
S
E
L
E
C
T
n
,
f
i
b
(
n
)
F
R
O
M
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
0
,
2
5
,
5
)
a
s
n
;
-
n
|
f
i
b
-
-
-
-
-
+
-
-
-
-
-
-
-
-
0
|
0
5
5
|
5
-
1
0
|
5
5
-
1
5
|
6
1
0
-
2
0
|
6
7
6
5
-
2
5
|
7
5
0
2
5
10
(
6
r
o
w
s
)
-
-
T
i
m
e
:
5
.
2
0
0
ms
Как
видим,
PL
V8
приблизительно
в
484
(2520.386/5.200)
раз
быстрее
plpgsql.
Можно
уск
орить
работу
расчет
а
чисел
Фибоначи
на
PL
V8
за
счет
к
еширования:
Листинг
10.23
Фибоначчи
на
plv8
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
-
f
i
b
c
a
c
h
e
(
n
i
n
t
)
R
E
T
U
R
N
S
i
n
t
a
s
$
$
-
v
a
r
m
e
m
o
=
{
0
:
0
,
1
:
1
}
;
-
f
u
n
c
t
i
o
n
f
i
b
(
n
)
{
5
i
f
(
!
(
n
i
n
m
e
m
o
)
)
-
m
e
m
o
[
n
]
=
f
i
b
(
n
-
1
)
+
f
i
b
(
n
-
2
)
-
r
e
t
u
r
n
m
e
m
o
[
n
]
-
}
-
r
e
t
u
r
n
f
i
b
(
n
)
;
10
$
$
L
A
N
G
U
A
G
E
p
l
v
8
I
M
M
U
T
A
B
L
E S
T
R
IC
T
;
Замерим
ск
орость
работы:
Листинг
10.24
Скорость
расчета
числа
Фибоначчи
на
plv8
Line
1
#
S
E
L
E
C
T
n
,
f
i
b
c
a
c
h
e
(
n
)
F
R
O
M
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
0
,
2
5
,
5
)
a
s
n
;
-
n
|
f
i
b
c
a
c
h
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
0
|
0
196
10.5.
PL
V8
5
5
|
5
-
1
0
|
5
5
-
1
5
|
6
1
0
-
2
0
|
6
7
6
5
-
2
5
|
7
5
0
2
5
10
(
6
r
o
w
s
)
-
-
T
i
m
e
:
1
.
2
0
2
ms
Естественно
эти
измерения
не
имеют
ничего
общего
с
реальным
ми-
ром
(не
нужно
каждый
день
считать
числа
Фибона
ччи
в
базе
данных),
но
позволяет
понять,
как
V8
мо
жет
помочь
у
скорить
функции,
к
оторые
занимаютс
я
вычислением
чего-либо
в
базе.
NoSQL
Одним из
полезных применений
PL
V8 мож
ет быть
создание на
ба-
зе
P
ostgreSQL
документоориентированного
хранилища.
Для
хранения
неструктурированных
данных
можно
использовать
hstore
(«
10.4
HStore
»),
но
у
него
есть
свои
недост
атки:
∙
нет
вло
ж
енности;
∙
все
данные
(ключ
и
значение
по
ключу)
это
строка;
Для
хранения
данных
многие
документно-ориентированные
базы
дан-
ных
используют
JSON
(MongoDB,
Couc
hDB,
Couch
base
и
т
.
д.).
Для
этого,
на
чиная
с
PostgreSQL
9.2,
добавлен
тип
данных
JSON,
а
с
версии
9.4
—
JSONB.
JSON
тип
можно
добавить
для
PostgreSQL
9.1
и
ниж
е
использу
я
PL
V8
и
DOMAIN
:
Листинг
10.25
Создание
типа
JSON
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
-
v
a
l
i
d
_
j
s
o
n
(
j
s
o
n
t
e
x
t
)
-
R
E
T
U
R
N
S
B
O
O
L
E
A
N
A
S
$
$
-
t
r
y
{
5
JS
O
N
.
p
a
r
s
e
(
j
s
o
n
)
;
r
e
t
u
r
n
t
r
u
e
;
-
}
c
a
t
c
h
(
e
)
{
-
r
e
t
u
r
n
f
a
l
s
e
;
-
}
-
$
$
L
A
N
G
U
A
G
E
p
l
v
8
I
M
M
U
T
A
B
L
E S
T
R
IC
T
;
10
-
C
R
E
A
T
E
D
O
M
A
I
N
j
s
o
n
A
S
T
E
X
T
-
C
H
E
C
K
(
v
a
l
i
d
_
j
s
o
n
(
V
A
L
U
E
)
)
;
Функция
v
alid_json
используетс
я
для
проверки
JSON
данных.
Пример
использования:
197
10.5.
PL
V8
Листинг
10.26
Проверка
JSON
Line
1
$
C
R
E
A
T
E
T
A
B
L
E
m
e
m
b
e
r
s
(
i
d
SER
IAL
,
p
r
o
f
i
l
e
j
s
o
n
)
;
-
$
I
N
SE
RT I
NT
O
m
e
m
b
e
r
s
-
V
A
L
U
E
S
(
’
n
o
t
g
o
o
d
j
s
o
n
’
)
;
-
E
R
R
O
R
:
v
a
l
u
e
f
o
r
d
o
m
a
i
n
j
s
o
n
5
v
i
o
l
a
t
e
s
c
h
e
c
k
c
o
n
s
t
r
a
i
n
t
"
j
s
o
n
_
c
h
e
c
k
"
-
$
I
N
SE
RT I
NT
O
m
e
m
b
e
r
s
-
V
A
L
U
E
S
(
’
{
"
g
o
o
d
"
:
"
j
s
o
n
"
,
"
i
s
"
:
t
r
u
e
}
’
)
;
-
I
N
SE
RT
0
1
-
$
S
E
L
E
C
T
*
F
R
O
M
m
e
m
b
e
r
s
;
10
p
r
o
f
i
l
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{
"
g
o
o
d
"
:
"
j
s
o
n
"
,
"
i
s
"
:
t
r
u
e
}
-
(
1
r
o
w
)
Р
ассмотрим
пример
использования
JSON
для
хранения
данных
и
PL
V8
для
их
поиск
а.
Для
начала
создадим
таблицу
и
заполним
её
данными:
Листинг
10.27
Т
аблица
с
JSON
полем
Line
1
$
C
R
E
A
T
E
T
A
B
L
E
m
e
m
b
e
r
s
(
i
d
SER
IAL
,
p
r
o
f
i
l
e
j
s
o
n
)
;
-
$
S
E
L
E
C
T
c
o
u
n
t
(
*
)
F
R
O
M
m
e
m
b
e
r
s
;
-
c
o
u
n
t
-
-
-
-
-
-
-
-
-
-
5
1
0
0
0
0
0
0
-
(
1
r
o
w
)
-
-
T
i
m
e
:
2
0
1
.
1
0
9
ms
В
profile
поле
мы
записали
приблизительно
т
акую
структуру
JSON:
Листинг
10.28
JSON
структура
Line
1
{
+
-
"
n
am
e
"
:
"
L
i
t
z
y
S
a
t
t
e
r
f
i
e
l
d
"
,
+
-
"
a
g
e
"
:
2
4
,
+
-
"
s
i
b
l
i
n
g
s
"
:
2
,
+
5
"
f
a
c
u
l
t
y
"
:
f
a
l
s
e
,
+
-
"
n
u
m
b
e
r
s
"
:
[
+
-
{
+
-
"
t
y
p
e
"
:
"
w
o
r
k
"
,
+
-
"
n
u
m
b
e
r
"
:
"
6
8
4
.
5
7
3
.
3
7
8
3
x
3
6
8
"+
10
}
,
+
-
{
+
-
"
t
y
p
e
"
:
"
hom
e
"
,
+
-
"
n
u
m
b
e
r
"
:
"
6
2
5
.
1
1
2
.
6
0
8
1
"
+
-
}
+
15
]
+
198
10.5.
PL
V8
-
}
Т
еперь
создадим
функцию
для
выво
да
значения
по
ключу
из
JSON
(в
данном
случае
о
жидаем
цифру):
Листинг
10.29
Функция
для
JSON
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
g
e
t
_
n
u
m
e
r
i
c
(
j
s
o
n
_
r
a
w
j
s
o
n
,
k
e
y
t
e
x
t
)
-
R
E
T
U
R
N
S
n
u
m
e
r
i
c
AS
$
$
-
v
a
r
o
= J
S
O
N
.
p
a
r
s
e
(
j
s
o
n
_
r
a
w
)
;
-
r
e
t
u
r
n
o
[
k
e
y
]
;
5
$
$
L
A
N
G
U
A
G
E
p
l
v
8
I
M
M
U
T
A
B
L
E S
T
R
IC
T
;
Т
еперь
мы
мож
ем
произвести
поиск
по
т
аблице,
филь
труя
по
зна
чени-
ям
ключей
age
,
siblings
или
другим
числовым
полям:
Листинг
10.30
Поиск
по
данным
JSON
Line
1
$
S
E
L
E
C
T
*
F
R
O
M
m
e
m
b
e
r
s
W
H
E
R
E
g
e
t
_
n
u
m
e
r
i
c
(
p
r
o
f
i
l
e
,
’
a
g
e
’
)
=
3
6
;
-
T
i
m
e
:
9
3
4
0
.
1
4
2
ms
-
$
S
E
L
E
C
T
*
F
R
O
M
m
e
m
b
e
r
s
W
H
E
R
E
g
e
t
_
n
u
m
e
r
i
c
(
p
r
o
f
i
l
e
,
’
s
i
b
l
i
n
g
s
’
)
=
1
;
-
T
i
m
e
:
1
4
3
2
0
.
0
3
2
ms
Поиск
работает
,
но
ск
орость
очень
маленьк
ая.
Чтобы
увеличить
ско-
рость,
нужно
создать
функциональные
индек
сы:
Листинг
10.31
Создание
индексов
Line
1
$
C
R
E
A
T
E
I
N
D
E
X
m
e
m
b
e
r
_
a
g
e
O
N
m
e
m
b
e
r
s
(
g
e
t
_
n
u
m
e
r
i
c
(
p
r
o
f
i
l
e
,
’
a
g
e
’
)
)
;
-
$
C
R
E
A
T
E
I
N
D
E
X
m
e
m
b
e
r
_
s
i
b
l
i
n
g
s
O
N
me
m
b
e
r
s
(
g
e
t
_
n
u
m
e
r
i
c
(
p
r
o
f
i
l
e ,
’
s
i
b
l
i
n
g
s
’
)
)
;
С
индек
сами
скорость
поиска
по
JSON
станет
достаточно
высокая:
Листинг
10.32
Поиск
по
данным
JSON
с
индексами
Line
1
$
S
E
L
E
C
T
*
F
R
O
M
m
e
m
b
e
r
s
W
H
E
R
E
g
e
t
_
n
u
m
e
r
i
c
(
p
r
o
f
i
l
e
,
’
a
g
e
’
)
=
3
6
;
-
T
i
m
e
:
5
7
.
4
2
9
ms
-
$
S
E
L
E
C
T
*
F
R
O
M
m
e
m
b
e
r
s
W
H
E
R
E
g
e
t
_
n
u
m
e
r
i
c
(
p
r
o
f
i
l
e
,
’
s
i
b
l
i
n
g
s
’
)
=
1
;
-
T
i
m
e
:
6
5
.
1
3
6
ms
5
$
S
E
L
E
C
T
c
o
u
n
t
(
*
)
f
r
o
m
m
e
m
b
e
r
s
w
h
e
r
e
g
e
t
_
n
u
m
e
r
i
c
(
p
r
o
f
i
l
e
,
’
a
g
e
’
)
=
2
6
a
n
d
g
e
t
_
n
u
m
e
r
i
c
(
p
r
o
f
i
l
e ,
’
s
i
b
l
i
n
g
s
’
)
=
1
;
-
T
i
m
e
:
1
0
6
.
4
9
2
ms
199
10.6.
Pg_repack
Получилось
отличное
документоориентированное
хранилище
из
P
ostgreSQL.
Если
используетс
я
P
ostgreSQL
9.4
или
новее,
то
можно
ис-
пользовать
JSONB
тип,
у
к
оторого
уже
есть
возможность
создавать
ин-
дек
сы
на
требуемые
ключи
в
JSON
структуре.
PL
V8
позволяет
использовать
некоторые
Jav
aScript
библиотеки
внутри
P
ostgreSQL.
Вот
пример
рендера
Mustache
темплейтов:
Листинг
10.33
Функция
для
рендера
Mustache
темплейтов
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
m
u
s
t
a
c
h
e
(
t
e
m
p
l
a
t
e
t
e
x
t
,
v
i
e
w
j
s
o
n
)
-
R
E
T
U
R
N
S
t
e
x
t
a
s
$
$
-
/
/
.
.
.
4
0
0
l
i
n
e
s
o
f
m
u
s
t
a
c
h
e
.
.
.
.
j
s
-
r
e
t
u
r
n
M
u
s
t
a
c
h
e
.
r
e
n
d
e
r
(
t
e
m
p
l
a
t
e
,
J
S
ON
.
p
a
r
s
e
(
v
i
e
w
)
)
5
$
$
L
A
N
G
U
A
G
E
p
l
v
8
I
M
M
U
T
A
B
L
E S
T
R
IC
T
;
Листинг
10.34
Рендер
темплейтов
Line
1
$
S
E
L
E
C
T
m
u
s
t
a
c
h
e
(
-
’
h
e
l
l
o
{{#
t
h
i
n
g
s
}
}
{
{
.
}
}
{
{
/
t
h
i
n
g
s
}
}
:
)
{{#
d
a
t
a
}
}
{
{
k
e
y
}
}
{
{
/
d
a
t
a
}
}
’
,
-
’
{
"
t
h
i
n
g
s
"
:
[
"
w
o
r
l
d
"
,
"
f
r
o
m
"
,
"
p
o
s
t
g
r
e
s
q
l
"
]
,
"
d
a
t
a
"
:
{
"
k
e
y
"
:
"
a
n
d
me
"
}
}
’
-
)
;
5
m
u
s
t
a
c
h
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
h
e
l
l
o
w
o
r
l
d
f
r
o
m
p
o
s
t
g
r
e
s
q
l
:
)
a
n
d
m
e
-
(
1
r
o
w
)
-
10
T
i
m
e
:
0
.
8
3
7
ms
Этот
пример
показывает
какие
возможности
предоставляет
PL
V8
в
PostgreSQL.
В
действительности
рендерить
Mustac
he
темплейты
в
P
ostgreSQL
не
лучшая
идея.
Заключение
PL
V8
расширение
предоставляет
P
ostgreSQL
процедурный
язык
с
движк
ом
V8
Jav
aScript,
с
помощью
которого
мо
жно
работ
ать
с
Jav
aScript
библиотек
ами,
индексировать
JSON
данные
и
использовать
его
к
ак
более
быстрый
язык
для
вычислений
внутри
базы.
10.6
Pg_repac
k
Т
аблицы
в
P
ostgreSQL
представлены
в
виде
страниц
размером
8
КБ,
в
к
оторых
размещены
записи.
Когда
одна
страница
полностью
заполняется
200
10.6.
Pg_repack
запис
ями,
к
таблице
добавляется
новая
страница.
При
у
далении
записей
с
помощью
DELETE
или
изменении
с
помощью
UPDA
TE
,
место
г
де
бы-
ли
старые
записи
не
мож
ет
быть
повторно
использовано
сразу
ж
е.
Для
этого
процесс
очистки
auto
v
acuum,
или
команда
V
A
CUUM
,
пробег
ает
по
изменённым
страницам
и
помечает
так
ое
место
к
ак
свободное,
после
чего
новые
записи
могут
спокойно
записыватьс
я
в
это
место.
Если
autov
acuum
не
справляется,
например
в
резу
ль
тате
активного
изменения
большего
ко-
личества
данных
или
просто
из-за
плохих
настроек,
то
к
т
аблице
бу
дут
из-
лишне
добавляться
новые
страницы
по
мере
поступления
новых
записей.
И
даже
после
того
как
очистк
а
дойдёт
до
наших
у
далённых
записей,
новые
страницы
останутс
я.
Получается,
что
таблица
становитс
я
более
разр
яжен-
ной
в
плане
плотности
записей.
Это
и
называется
эффектом
раздувания
т
аблиц
(table
bloat).
Процедура
очистки,
auto
v
acuum
или
V
ACUUM
,
мож
ет
уменьшить
раз-
мер
таблицы,
убрав
полностью
пустые
страницы,
но
тольк
о
при
условии,
что
они
нахо
дятс
я
в
самом
конце
таблицы.
Чтобы
максимально
уменьшить
т
аблицу
в
PostgreSQL
есть
V
ACUUM
FULL
или
CLUSTER
,
но
оба
эти
спо-
соба
требуют
«exclusively
lo
cks»
на
таблицу
(то
есть
в
это
время
с
таблицы
нельзя
ни
чит
ать,
ни
писать),
что
далек
о
н
е
всег
да
является
подх
одящим
решением.
Для
решения
подобных
проблем
существу
ет
утилита
pg_repac
k
.
Эта
утилит
а
позволяет
с
делать
V
ACUUM
FULL
или
CLUSTER
к
оманды
без
бло-
кировки
т
аблицы.
Для
чистки
таблицы
pg_repac
k
создает
точную
её
ко-
пию
в
repack
сх
еме
базы
данных
(ваша
база
по
умолчанию
работает
в
public
с
хеме)
и
сортиру
ет
строки
в
этой
таблице.
После
переноса
данных
и
чист-
ки
мусора
утилита
меняет
сх
ему
у
т
аблиц.
Для
чистки
индексов
утилит
а
создает
новые
индексы
с
другими
именами,
а
по
выполнению
работы
ме-
няет
их
на
первоначальные.
Для
выполнения
всех
этих
работ
потребуетс
я
дополнительное
место
на
диск
е
(например,
если
у
вас
100
ГБ
данных,
и
из
них
40
ГБ
-
распух
ание
т
аблиц
или
индексов,
то
вам
потребу
ется
100
ГБ
+
(100
ГБ
-
40
ГБ)
=
160
ГБ
на
диске
минимум).
Для
проверки
«рас-
пух
ания» т
аблиц
и
индексов
в вашей
базе
мо
жно воспользоватьс
я
SQL
запросом
из
раздела
«
14.2
Р
азмер
распух
ания
(bloat)
т
аблиц
и
индексов
в
базе
данных
»
.
Существу
ет
ряд
ограничений
в
работе
pg_repack:
∙
Не
мо
ж
ет
очистить
временные
таблицы;
∙
Не
мо
ж
ет
очистить
таблицы
с
использованием
GIST
индексов;
∙
Нельзя
выполнять DDL (Data Definition Language) на т
аблице во
время
работы;
Пример
использования
Выполнить
к
оманду
CLUSTER
всех
кластеризированных
т
аблиц
и
V
ACUUM
FULL
для
всех
не
кластеризированных
т
аблиц
в
test
базе
дан-
201
10.6.
Pg_repack
ных:
Ск
ачать
Листинг
Line
1
$
p
g
_
r
e
p
a
c
k
t
e
s
t
Выполните
к
оманду
V
ACUUM
FULL
на
fo
o
и
bar
таблицах
в
test
базе
данных
(кластеризация
т
аблиц
игнорируетс
я):
Ск
ачать
Листинг
Line
1
$
p
g
_
r
e
p
a
c
k
-
-
no
-
o
r
d
e
r
-
-
t
a
b
l
e
f
o
o
-
-
t
a
b
l
e
b
a
r
t
e
s
t
Переместить
все
индек
сы
таблицы
fo
o
в
неймспейс
tbs
:
Ск
ачать
Листинг
Line
1
$
p
g
_
r
e
p
a
c
k
-
d
t
e
s
t
-
-
t
a
b
l
e
f
o
o
-
-
o
n
l
y
-
i
n
d
e
x
e
s
-
-
t
a
b
l
e
s
p
a
c
e
t
b
s
Pgcompact
Существу
ет
еще
одно
решение
для
борьбы
с
раздуванием
т
аблиц.
При
обновлении
записи
с
помощью
UPDA
TE
,
если
в
т
аблице есть
свободное
место,
то
новая
версия
пойдет
именно
в
свободное
место,
без
выделения
новых
страниц.
Предпочтение
отдаетс
я
свобо
дному
месту
ближ
е
к
на
чалу
т
аблицы.
Если
обновлять
т
аблицу
с
помощью
«fake
up
dates»(
some_column
=
some_column
)
с
последней
страницы,
в
как
ой-то
момент
все
записи
с
последней
страницы
перейдут
в
свобо
дное
место
в
предшествующих
стра-
ницах
т
аблицы.
Т
аким
образом,
после
нескольких
т
аких
операций,
послед-
ние
страницы
ок
ажутся
пу
стыми
и
обычный
не
блокирующий
V
ACUUM
смо
жет
отрезать
их
от
таблицы,
тем
самым
уменьшив
размер.
В
итоге,
с
помощью
т
акой
техники
мо
жно
максимально
сж
ать
таблицу
,
при
этом
не
вызывая
критичных
блокировок,
а
значит
без
помех
для
других
сессий
и
нормальной
работы
базы.
Для
автоматизации
этой
процедуры
существует
утилит
а
pgcompactor
.
Основные
х
арактеристики
утилиты:
∙
не
требует
никаких
зависимостей
кроме
P
erl
>=5.8.8,
мо
жно
просто
ск
опировать
pgcompactor
на
сервер
и
работать
с
ним;
∙
работ
ает
через
адаптеры
DBD::Pg
,
DBD::PgPP
или
даж
е
через
ст
ан-
дартную
утилиту
psql,
если
первых
двух
на
сервере
нет;
∙
обработк
а
к
ак
отдельных
т
аблиц,
так
и
всех
т
аблиц
внутри
сх
емы,
базы
или
всего
кластера;
∙
возмо
жность
исключения
баз,
сх
ем
или
таблиц
из
обработки;
202
10.6.
Pg_repack
∙
анализ
эффекта
раздувания
и
обработк
а
тольк
о
тех
т
аблиц,
у
к
о-
торых
он
присутству
ет
,
для
более
точных
расчетов
рек
омендуетс
я
у
становить
расширение
pgstattuple
;
∙
анализ
и
перестроение
индек
сов
с
эффектом
раздувания;
∙
анализ
и
перестроение
уникальных
ограничений
(unique
constraints)
и
первичных
ключей
(primary
k
eys)
с
эффектом
раздувания;
∙
инкремент
альное
использование,
т
.
е.
мо
жно
ост
ановить
процесс
сж
а-
тия
без
ущерба
чему-либо;
∙
динамическ
ая
подстройк
а
по
д
текущую
нагрузку
базы
данных,
что-
бы
не
влиять
на
произво
дительность
пользовательских
запросов
(с
возмо
жностью
регу
лировки
при
запуск
е);
∙
рек
омендации
администраторам,
сопровождаемые
готовым
DDL,
для
перестроения
объектов
базы,
к
оторые
не
могут
быть
перестрое-
ны
в
автоматическ
ом
режиме;
Р
ассмотрим
пример
использования
данной
утилиты.
Для
на
чала
со-
здадим
т
аблицу:
Листинг
10.35
Создаем
test
таблицу
Line
1
#
c
r
e
a
t
e
t
a
b
l
e
t
e
s
t
(
-
i
d
i
n
t
4
,
-
i
n
t
_
1
i
n
t
4
,
-
i
n
t
_
2
i
n
t
4
,
5
i
n
t
_
3
i
n
t
4
,
-
t
s
_
1
t
i
m
e
s
t
a
m
p
t
z
,
-
t
s
_
2
t
i
m
e
s
t
a
m
p
t
z
,
-
t
s
_
3
t
i
m
e
s
t
a
m
p
t
z
,
-
t
e
x
t
_
1
t
e
x
t
,
10
t
e
x
t
_
2
t
e
x
t
,
-
t
e
x
t
_
3
t
e
x
t
-
)
;
После
этого
заполним
её
данными:
Листинг
10.36
Заполняем
данными
test
таблицу
Line
1
#
i
n
s
e
r
t
i
n
t
o
t
e
s
t
-
s
e
l
e
c
t
-
i
,
-
c
a
s
t
(
r
a
n
d
o
m
(
)
*
1
0
0
0
0
0
0
0
a
s
i
n
t
4
)
,
5
c
a
s
t
(
r
a
n
d
o
m
(
)
*
1
0
0
0
0
0
0
0
a
s
i
n
t
4
)
,
-
c
a
s
t
(
r
a
n
d
o
m
(
)
*
1
0
0
0
0
0
0
0
a
s
i
n
t
4
)
,
-
now
(
)
-
’
2
y
e
a
r
s
’
:
:
i
n
t
e
r
v
a
l
*
r
a
n
d
o
m
(
)
,
-
now
(
)
-
’
2
y
e
a
r
s
’
:
:
i
n
t
e
r
v
a
l
*
r
a
n
d
o
m
(
)
,
-
now
(
)
-
’
2
y
e
a
r
s
’
:
:
i
n
t
e
r
v
a
l
*
r
a
n
d
o
m
(
)
,
10
r
e
p
e
a
t
(
’
t
e
x
t
_
1
’
,
c
a
s
t
(
1
0
+
r
a
n
d
o
m
(
)
*
1
0
0
a
s
i
n
t
4
)
)
,
203
10.6.
Pg_repack
-
r
e
p
e
a
t
(
’
t
e
x
t
_
2
’
,
c
a
s
t
(
1
0
+
r
a
n
d
o
m
(
)
*
1
0
0
a
s
i
n
t
4
)
)
,
-
r
e
p
e
a
t
(
’
t
e
x
t
_
2
’
,
c
a
s
t
(
1
0
+
r
a
n
d
o
m
(
)
*
1
0
0
a
s
i
n
t
4
)
)
-
f
r
o
m
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
1
,
1
0
0
0
0
0
0
)
i
;
И
добавим
индек
сы:
Листинг
10.37
Индексы
для
test
Line
1
#
a
l
t
e
r
t
a
b
l
e
t
e
s
t
a
d
d
p
r
i
m
a
r
y
k
e
y
(
i
d
)
;
-
A
L
T
E
R
T
A
B
L
E
-
-
#
c
r
e
a
t
e
u
n
i
q
u
e
i
n
d
e
x
i
1
o
n
t
e
s
t
(
i
n
t
_
1
,
i
n
t
_
2
)
;
5
C
R
E
A
T
E
I
N
D
E
X
-
-
#
c
r
e
a
t
e
i
n
d
e
x
i
2
o
n
t
e
s
t
(
i
n
t
_
2
)
;
-
C
R
E
A
T
E
I
N
D
E
X
-
10
#
c
r
e
a
t
e
i
n
d
e
x
i
3
o
n
t
e
s
t
(
i
n
t
_
3
,
t
s
_
1
)
;
-
C
R
E
A
T
E
I
N
D
E
X
-
-
#
c
r
e
a
t
e
i
n
d
e
x
i
4
o
n
t
e
s
t
(
t
s
_
2
)
;
-
C
R
E
A
T
E
I
N
D
E
X
15
-
#
c
r
e
a
t
e
i
n
d
e
x
i
5
o
n
t
e
s
t
(
t
s
_
3
)
;
-
C
R
E
A
T
E
I
N
D
E
X
-
-
#
c
r
e
a
t
e
i
n
d
e
x
i
6
o
n
t
e
s
t
(
t
e
x
t
_
1
)
;
20
C
R
E
A
T
E
I
N
D
E
X
В
резу
ль
тате
получим
test
таблицу
,
как
показано
на
10.38
:
Листинг
10.38
Т
аблица
test
Line
1
#
\
d
t
e
s
t
-
T
a
b
l
e
"
p
u
b
l
i
c
.
t
e
s
t
"
-
Co
l
u
m
n
|
T
y
p
e
|
M
o
d
i
f
i
e
r
s
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
5
i
d
|
i
n
t
e
g
e
r
|
n
o
t
n
u
l
l
-
i
n
t
_
1
|
i
n
t
e
g
e
r
|
-
i
n
t
_
2
|
i
n
t
e
g
e
r
|
-
i
n
t
_
3
|
i
n
t
e
g
e
r
|
-
t
s
_
1
|
t
i
m
e
s
t
a
m
p
w
i
t
h
t
i
m
e
z
o
n
e
|
10
t
s
_
2
|
t
i
m
e
s
t
a
m
p
w
i
t
h
t
i
m
e
z
o
n
e
|
-
t
s
_
3
|
t
i
m
e
s
t
a
m
p
w
i
t
h
t
i
m
e
z
o
n
e
|
-
t
e
x
t
_
1
|
t
e
x
t
|
-
t
e
x
t
_
2
|
t
e
x
t
|
-
t
e
x
t
_
3
|
t
e
x
t
|
15
I
n
d
e
x
e
s
:
204
10.6.
Pg_repack
-
"
t
e
s
t
_
p
k
e
y
"
P
R
I
M
A
R
Y
K
E
Y
,
b
t
r
e
e
(
i
d
)
-
"
i
1
"
U
N
I
Q
U
E
,
b
t
r
e
e
(
i
n
t
_
1
,
i
n
t
_
2
)
-
"
i
2
"
b
t
r
e
e
(
i
n
t
_
2
)
-
"
i
3
"
b
t
r
e
e
(
i
n
t
_
3
,
t
s
_
1
)
20
"
i
4
"
b
t
r
e
e
(
t
s
_
2
)
-
"
i
5
"
b
t
r
e
e
(
t
s
_
3
)
-
"
i
6
"
b
t
r
e
e
(
t
e
x
t
_
1
)
Р
азмер
таблицы
и
индексов:
Листинг
10.39
Размер
таблицы
и
индексов
Line
1
#
S
E
L
E
C
T
n
s
p
n
a
m
e
|
|
’
.
’
|
|
r
e
l
n
a
m
e
A
S
"
r
e
l
a
t
i
o
n
"
,
-
p
g
_
s
i
z
e
_
p
r
e
t
t
y
(
p
g
_
t
o
t
a
l
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
C
.
o
i
d
)
)
A
S
"
t
o
t
a
l
_
s
i
z
e
"
-
F
R
O
M
p
g
_
c
l
a
s
s
C
-
L
E
F
T
JOIN
p
g
_
n
a
m
e
s
p
a
c
e
N
O
N
(
N
.
o
i
d
=
C
.
r
e
l
n
a
m
e
s
p
a
c
e
)
5
W
H
E
R
E
n
s
p
n
a
m
e
N
O
T I
N
(
’
p
g
_
c
a
t
a
l
o
g
’
,
’
i
n
f
o
r
m
a
t
i
o
n
_
s
c
h
e
m
a
’
)
-
A
N
D
n
s
p
n
a
m
e
!
~
’
^
p
g
_
t
o
a
s
t
’
-
O
R
D
E
R
B
Y
p
g
_
t
o
t
a
l
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
C
.
o
i
d
)
D
E
S
C
-
LIMIT
2
0
;
-
r
e
l
a
t
i
o
n
|
t
o
t
a
l
_
s
i
z
e
10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
p
u
b
l
i
c
.
t
e
s
t
|
1
7
0
5
M
B
-
p
u
b
l
i
c
.
i
6
|
2
4
2
M
B
-
p
u
b
l
i
c
.
i
3
|
3
0
M
B
-
p
u
b
l
i
c
.
i
1
|
2
1
M
B
15
p
u
b
l
i
c
.
i
2
|
2
1
M
B
-
p
u
b
l
i
c
.
i
4
|
2
1
M
B
-
p
u
b
l
i
c
.
i
5
|
2
1
M
B
-
p
u
b
l
i
c
.
t
e
s
t
_
p
k
e
y
|
2
1
M
B
-
(
8
r
o
w
s
)
Т
еперь
давайте
создадим
распухание
т
аблицы.
Для
этого
у
далим
95%
записей
в
ней:
Листинг
10.40
У
даляем
95%
записей
Line
1
#
D
E
L
E
T
E
F
R
O
M
t
e
s
t
W
H
E
R
E
r
a
n
d
o
m
(
)
<
0
.
9
5
;
-
D
E
L
E
T
E
9
5
0
1
5
0
Далее
с
делаем
V
A
CUUM
и
проверим
размер
заново:
Листинг
10.41
Размер
таблицы
и
индексов
Line
1
#
V
A
C
U
U
M;
-
V
A
C
U
U
M
-
#
S
E
L
E
C
T
n
s
p
n
a
m
e
|
|
’
.
’
|
|
r
e
l
n
a
m
e
A
S
"
r
e
l
a
t
i
o
n
"
,
205
10.6.
Pg_repack
-
p
g
_
s
i
z
e
_
p
r
e
t
t
y
(
p
g
_
t
o
t
a
l
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
C
.
o
i
d
)
)
A
S
"
t
o
t
a
l
_
s
i
z
e
"
5
F
R
O
M
p
g
_
c
l
a
s
s
C
-
L
E
F
T
JOIN
p
g
_
n
a
m
e
s
p
a
c
e
N
O
N
(
N
.
o
i
d
=
C
.
r
e
l
n
a
m
e
s
p
a
c
e
)
-
W
H
E
R
E
n
s
p
n
a
m
e
N
O
T I
N
(
’
p
g
_
c
a
t
a
l
o
g
’
,
’
i
n
f
o
r
m
a
t
i
o
n
_
s
c
h
e
m
a
’
)
-
A
N
D
n
s
p
n
a
m
e
!
~
’
^
p
g
_
t
o
a
s
t
’
-
O
R
D
E
R
B
Y
p
g
_
t
o
t
a
l
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
C
.
o
i
d
)
D
E
S
C
10
LIMIT
2
0
;
-
r
e
l
a
t
i
o
n
|
t
o
t
a
l
_
s
i
z
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
p
u
b
l
i
c
.
t
e
s
t
|
1
7
0
5
M
B
-
p
u
b
l
i
c
.
i
6
|
2
4
2
M
B
15
p
u
b
l
i
c
.
i
3
|
3
0
M
B
-
p
u
b
l
i
c
.
i
1
|
2
1
M
B
-
p
u
b
l
i
c
.
i
2
|
2
1
M
B
-
p
u
b
l
i
c
.
i
4
|
2
1
M
B
-
p
u
b
l
i
c
.
i
5
|
2
1
M
B
20
p
u
b
l
i
c
.
t
e
s
t
_
p
k
e
y
|
2
1
M
B
-
(
8
r
o
w
s
)
Как
видно
из
резу
льт
ат
а,
размер
не
изменилс
я.
Т
еперь
попробу
ем
убрать
через
pgcompact распух
ание
т
аблицы
и
индек
сов
(для
этого до-
полнительно
добавим
в
базу
данных
расширение
pgstattuple):
Листинг
10.42
Запуск
pgcompact
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
g
s
t
a
t
t
u
p
l
e
;
-
#
\
q
-
-
$
g
i
t
c
l
o
n
e
h
t
t
p
s
:
/
/
g
i
t
h
u
b
.
com
/
g
r
a
y
h
e
m
p
/
p
g
t
o
o
l
k
i
t
.
g
i
t
5
$
c
d
p
g
t
o
o
l
k
i
t
-
$
t
i
m
e
.
/
b
i
n
/
p
g
c
o
m
p
a
c
t
-
v
i
n
f
o
-
d
a
n
a
l
y
t
i
c
s
_
p
r
o
d
-
-
r
e
i
n
d
e
x
2
>
&1
|
t
e
e
p
g
c
o
m
p
a
c
t
.
o
u
t
p
u
t
-
S
u
n
O
c
t
3
0
1
1
:
0
1
:
1
8
2
0
1
6
IN
F
O
D
a
t
a
b
a
s
e
c
o
n
n
e
c
t
i
o
n
m
e
t
h
o
d
:
p
s
q
l
.
-
S
u
n
O
c
t
3
0
1
1
:
0
1
:
1
8
2
0
1
6
d
e
v
I
NF
O
C
r
e
a
t
e
d
e
n
v
i
r
o
n
m
e
n
t
.
-
S
u
n
O
c
t
3
0
1
1
:
0
1
:
1
8
2
0
1
6
d
e
v
I
NF
O
S
t
a
t
i
c
t
i
c
s
c
a
l
c
u
l
a
t
i
o
n
m
e
t
h
o
d
:
p
g
s
t
a
t
t
u
p
l
e
.
10
S
u
n
O
c
t
3
0
1
1
:
0
2
:
0
3
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
Vacuum
i
n
i
t
i
a
l
:
1
6
9
6
8
9
p
a
g
e
s
l
e
f
t
,
d
u
r
a
t
i
o
n
4
5
.
1
2
9
s
e
c
o
n
d
s
.
-
S
u
n
O
c
t
3
0
1
1
:
0
2
:
1
3
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
B
l
o
a
t
s
t
a
t
i
s
t
i
c
s
w
i
t
h
p
g
s
t
a
t
t
u
p
l
e
:
d
u
r
a
t
i
o
n
9
.
7
6
4
s
e
c
o
n
d
s
.
-
S
u
n
O
c
t
3
0
1
1
:
0
2
:
1
3
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
N
O
T
I
C
E
S
t
a
t
i
s
t
i
c
s
:
1
6
9
6
8
9
p
a
g
e
s
(
2
1
8
2
3
3
p
a
g
e
s
i
n
c
l
u
d
i
n
g
t
o
a
s
t
s
a
n
d
i
n
d
e
x
e
s
)
,
a
p
p
r
o
x
i
m
a
t
e
l
y
9
4
.
6
2
%
(
1
6
0
5
5
7
p
a
g
e
s
)
c
a
n
b
e
c
o
m
p
a
c
t
e
d
r
e
d
u
c
i
n
g
t
h
e
s
i
z
e
b
y
1
2
5
4
M
B.
-
S
u
n
O
c
t
3
0
1
1
:
0
2
:
1
3
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
U
p
d
a
t
e
by
c
o
l
u
m
n
:
i
d
.
206
10.6.
Pg_repack
-
S
u
n
O
c
t
3
0
1
1
:
0
2
:
1
3
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
S
e
t
p
a
g
e
s
/
r
o
u
n
d
:
1
0
.
15
S
u
n
O
c
t
3
0
1
1
:
0
2
:
1
3
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
S
e
t
p
a
g
e
s
/
v
a
c
u
u
m
:
3
3
9
4
.
-
S
u
n
O
c
t
3
0
1
1
:
0
4
:
5
6
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
P
r
o
g
r
e
s
s
:
0
%
,
2
6
0
p
a
g
e
s
c
o
m
p
l
e
t
e
d
.
-
S
u
n
O
c
t
3
0
1
1
:
0
5
:
4
5
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
C
l
e
a
n
i
n
g
i
n
a
v
e
r
a
g
e
:
8
5
.
8
p
a
g
e
s
/
s
e
c
o
n
d
(
0
.
1
1
7
s
e
c
o
n
d
s
p
e
r
1
0
p
a
g
e
s
)
.
-
S
u
n
O
c
t
3
0
1
1
:
0
5
:
4
8
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
Vacuum
r
o
u
t
i
n
e
:
1
6
6
2
8
5
p
a
g
e
s
l
e
f
t
,
d
u
r
a
t
i
o
n
2
.
7
0
5
s
e
c
o
n
d
s
.
-
S
u
n
O
c
t
3
0
1
1
:
0
5
:
4
8
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
S
e
t
p
a
g
e
s
/
v
a
c
u
u
m
:
3
3
2
6
.
20
S
u
n
O
c
t
3
0
1
1
:
0
5
:
5
7
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
P
r
o
g
r
e
s
s
:
2
%
,
4
3
0
4
p
a
g
e
s
c
o
m
p
l
e
t
e
d
.
-
S
u
n
O
c
t
3
0
1
1
:
0
6
:
1
9
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
C
l
e
a
n
i
n
g
i
n
a
v
e
r
a
g
e
:
8
4
1
.
6
p
a
g
e
s
/
s
e
c
o
n
d
(
0
.
0
1
2
s
e
c
o
n
d
s
p
e
r
1
0
p
a
g
e
s
)
.
-
S
u
n
O
c
t
3
0
1
1
:
0
6
:
2
3
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
Vacuum
r
o
u
t
i
n
e
:
1
6
2
9
4
2
p
a
g
e
s
l
e
f
t
,
d
u
r
a
t
i
o
n
4
.
2
6
4
s
e
c
o
n
d
s
.
-
S
u
n
O
c
t
3
0
1
1
:
0
6
:
2
3
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
S
e
t
p
a
g
e
s
/
v
a
c
u
u
m
:
3
2
6
0
.
-
S
u
n
O
c
t
3
0
1
1
:
0
6
:
4
9
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
C
l
e
a
n
i
n
g
i
n
a
v
e
r
a
g
e
:
8
1
8
.
1
p
a
g
e
s
/
s
e
c
o
n
d
(
0
.
0
1
2
s
e
c
o
n
d
s
p
e
r
1
0
p
a
g
e
s
)
.
25
S
u
n
O
c
t
3
0
1
1
:
0
6
:
4
9
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
Vacuum
r
o
u
t
i
n
e
:
1
5
9
6
8
1
p
a
g
e
s
l
e
f
t
,
d
u
r
a
t
i
o
n
0
.
3
2
5
s
e
c
o
n
d
s
.
-
S
u
n
O
c
t
3
0
1
1
:
0
6
:
4
9
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
S
e
t
p
a
g
e
s
/
v
a
c
u
u
m
:
3
1
9
4
.
-
S
u
n
O
c
t
3
0
1
1
:
0
6
:
5
7
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
P
r
o
g
r
e
s
s
:
6
%
,
1
0
9
5
8
p
a
g
e
s
c
o
m
p
l
e
t
e
d
.
-
S
u
n
O
c
t
3
0
1
1
:
0
7
:
2
3
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
C
l
e
a
n
i
n
g
i
n
a
v
e
r
a
g
e
:
6
9
4
.
8
p
a
g
e
s
/
s
e
c
o
n
d
(
0
.
0
1
4
s
e
c
o
n
d
s
p
e
r
1
0
p
a
g
e
s
)
.
-
S
u
n
O
c
t
3
0
1
1
:
0
7
:
2
4
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
Vacuum
r
o
u
t
i
n
e
:
1
5
6
4
7
8
p
a
g
e
s
l
e
f
t
,
d
u
r
a
t
i
o
n
1
.
3
6
2
s
e
c
o
n
d
s
.
30
S
u
n
O
c
t
3
0
1
1
:
0
7
:
2
4
2
0
1
6
d
e
v
,
p
u
b
l
i
c
.
t
e
s
t
IN
FO
S
e
t
p
a
g
e
s
/
v
a
c
u
u
m
:
3
1
3
0
.
-
.
.
.
-
S
u
n
O
c
t
3
0
1
1
:
4
9
:
0
2
2
0
1
6
d
e
v
N
O
T
I
C
E
P
r
o
c
e
s
s
i
n
g
c
o
m
p
l
e
t
e
.
-
S
u
n
O
c
t
3
0
1
1
:
4
9
:
0
2
2
0
1
6
d
e
v
N
O
T
I
C
E
P
r
o
c
e
s
s
i
n
g
r
e
s
u
l
t
s
:
s
i
z
e
r
e
d
u
c
e
d
b
y
1
2
5
6
M
B
(
1
2
5
6
M
B
i
n
c
l
u
d
i
n
g
t
o
a
s
t
s
a
n
d
i
n
d
e
x
e
s
)
i
n
t
o
t
a
l
.
-
S
u
n
O
c
t
3
0
1
1
:
4
9
:
0
2
2
0
1
6
N
O
T
I
C
E
P
r
o
c
e
s
s
i
n
g
c
o
m
p
l
e
t
e
:
0
r
e
t
r
i
e
s
f
r
o
m
1
0
.
35
S
u
n
O
c
t
3
0
1
1
:
4
9
:
0
2
2
0
1
6
N
O
T
I
C
E
P
r
o
c
e
s
s
i
n
g
r
e
s
u
l
t
s
:
s
i
z
e
r
e
d
u
c
e
d
b
y
1
2
5
6
M
B
(
1
2
5
6
M
B
i
n
c
l
u
d
i
n
g
t
o
a
s
t
s
a
n
d
i
n
d
e
x
e
s
)
i
n
t
o
t
a
l
,
1
2
5
6
M
B
(
1
2
5
6
M
B
)
d
e
v
.
-
S
u
n
O
c
t
3
0
1
1
:
4
9
:
0
2
2
0
1
6
d
e
v
I
NF
O
D
r
o
p
p
e
d
e
n
v
i
r
o
n
m
e
n
t
.
-
-
r
e
a
l
4
7
m4
4
.
8
3
1
s
207
10.6.
Pg_repack
-
u
s
e
r
0
m37
.
6
9
2
s
40
s
y
s
0
m16
.
3
3
6
s
После
данной
процедуры
проверим
размер
таблицы
и
индек
сов
в
базе:
Листинг
10.43
Размер
таблицы
и
индексов
Line
1
#
V
A
C
U
U
M;
-
V
A
C
U
U
M
-
#
S
E
L
E
C
T
n
s
p
n
a
m
e
|
|
’
.
’
|
|
r
e
l
n
a
m
e
A
S
"
r
e
l
a
t
i
o
n
"
,
-
p
g
_
s
i
z
e
_
p
r
e
t
t
y
(
p
g
_
t
o
t
a
l
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
C
.
o
i
d
)
)
A
S
"
t
o
t
a
l
_
s
i
z
e
"
5
F
R
O
M
p
g
_
c
l
a
s
s
C
-
L
E
F
T
JOIN
p
g
_
n
a
m
e
s
p
a
c
e
N
O
N
(
N
.
o
i
d
=
C
.
r
e
l
n
a
m
e
s
p
a
c
e
)
-
W
H
E
R
E
n
s
p
n
a
m
e
N
O
T I
N
(
’
p
g
_
c
a
t
a
l
o
g
’
,
’
i
n
f
o
r
m
a
t
i
o
n
_
s
c
h
e
m
a
’
)
-
A
N
D
n
s
p
n
a
m
e
!
~
’
^
p
g
_
t
o
a
s
t
’
-
O
R
D
E
R
B
Y
p
g
_
t
o
t
a
l
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
C
.
o
i
d
)
D
E
S
C
10
LIMIT
2
0
;
-
r
e
l
a
t
i
o
n
|
t
o
t
a
l
_
s
i
z
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
p
u
b
l
i
c
.
t
e
s
t
|
4
4
9
M
B
-
p
u
b
l
i
c
.
i
6
|
1
2
M
B
15
p
u
b
l
i
c
.
i
3
|
1
5
4
4
kB
-
p
u
b
l
i
c
.
i
1
|
1
1
1
2
kB
-
p
u
b
l
i
c
.
i
2
|
1
1
1
2
kB
-
p
u
b
l
i
c
.
t
e
s
t
_
p
k
e
y
|
1
1
1
2
kB
-
p
u
b
l
i
c
.
i
4
|
1
1
1
2
kB
20
p
u
b
l
i
c
.
i
5
|
1
1
1
2
kB
-
(
8
r
o
w
s
)
Как
видно,
в
резу
ль
тате
размер
т
аблицы
сократился
до
449
МБ
(было
1705
МБ).
Индексы
то
же
ст
али
меньше
(например,
i6
был
242
МБ,
а
ст
ал
12
МБ).
Операция
заняла
47
минут
и
обрабатывала
в
среднем
600
страниц
в
секунду
(4.69
МБ
в
секунду).
Мо
жно
уск
орить
выполнение
этой
опера-
ции
через
--
delay
-
ratio
параметр
(задержк
а
между
раундами
выполнения,
по
умолчанию
2
секунды) и
--
max-pages-p
er-round
параметр (к
оличество
страниц,
что
бу
дет
обработ
ано
за
один
ра
унд,
по
умолчанию
10).
Более
по
дробно
по
параметрам
pgcompact
мо
жно
ознакомитьс
я
через
команду
pgcompact
--man
.
Заключение
Pg_repac
k
и
pgcompact
—
утилиты,
кото
рые
могут
помочь
в
борьбе
с
распух
анием
таблиц
в
PostgreSQL
«на
лету»
.
208
10.7.
Pg_prewarm
10.7
Pg_prew
arm
Мо
ду
ль
pg_prew
arm
обеспечивает
у
добный способ
загрузки
данных
обьектов (т
аблиц, индексов,
прочего) в буферный кэш
P
ostgreSQL или
операционной
системы.
Данный
мо
ду
ль
добавлен
в
contrib
на
чиная
с
P
ostgreSQL
9.4.
У
становк
а
и
использование
Для
на
чала
нужно
уст
ановить
моду
ль:
Ск
ачать
Листинг
Line
1
$
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
g
_
p
r
e
w
a
r
m
;
После
у
становки
доступна
функция
pg_prewarm
:
Ск
ачать
Листинг
Line
1
$
S
E
L
E
C
T
p
g
_
p
r
e
w
a
r
m
(
’
p
g
b
e
n
c
h
_
a
c
c
o
u
n
t
s
’
)
;
-
p
g
_
p
r
e
w
a
r
m
-
-
-
-
-
-
-
-
-
-
-
-
-
-
4
0
8
2
5
(
1
r
o
w
)
Первый
аргумент
—
объект
,
ко
торый
требуетс
я
предварительно
загру-
ж
ать
в
память.
Второй
аргумент
—
«режим»
загрузки
в
память,
который
мо
жет
содер
жать
т
акие
варианты:
∙
prefetc
h
—
чтение
файла
ядром
системы
в
асинхронном
режиме
(в
фоновом
режиме).
Это
позволяет
поло
жить
содер
жимое
файла
в
кэ-
ше
ядра
системы.
Но
этот
режим
работ
ает
не
на
всех
п
латформах;
∙
read
—
резу
ль
тат
по
хо
ж
на
prefetc
h
,
но
делается
синхронно
(а
зна
чит
медленнее).
Р
аботает
на
всех
платформах;
∙
buffer
—
в
этом
режиме
данные
бу
дут
грузиться
в
P
ostgreSQL
shared_buffers
.
Этот
режим
использу
ется
по
умолчанию;
Третий
аргумент
называется
«fork»
.
О
нем
не
нужно
беспок
оиться.
Воз-
мо
жные
значения:
«main»
(используетс
я
по
умолчанию),
«fsm»
,
«vm»
.
Четвертый
и
пятый
аргументы
ук
азывают
диапазон
страниц
для
за-
грузки
данных.
По
умолчанию
загруж
ается
весь
обьект
в
память,
но
мож-
но
решить,
например,
загрузить
тольк
о
последние
1000
страниц:
Ск
ачать
Листинг
Line
1
$
S
E
L
E
C
T
p
g
_
p
r
e
w
a
r
m
(
-
’
p
g
b
e
n
c
h
_
a
c
c
o
u
n
t
s
’
,
209
10.8.
Smlar
-
f
i
r
s
t
_
b
l
o
c
k
:
=
(
-
S
E
L
E
C
T
p
g
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
’
p
g
b
e
n
c
h
_
a
c
c
o
u
n
t
s
’
)
/
c
u
r
r
e
n
t
_
s
e
t
t
i
n
g
(
’
b
l
o
c
k
_
s
i
z
e
’
)
:
:
i
n
t
4
-
1
0
0
0
5
)
-
)
;
Заключение
Pg_prew
arm
—
расширение,
которое
позволяет
предварительно
загру-
зить
(«по
догреть»)
данные
в
буферной
кэш
PostgreSQL
или
операционной
системы.
10.8
Smlar
Поиск
по
хо
жести
в
больших
базах
данных
является
важным
вопросом
в
настоящее
время
для
таких
систем
как
блоги
(пох
о
жие
статьи),
интернет-
маг
азины
(по
хо
жие
продукты),
х
остинг
изображений
(по
хо
жие
изображе-
ния,
поиск
дубликатов
изображений)
и
т
.
д.
P
ostgreSQL
позволяет
сделать
т
акой
поиск
более
легким.
Прежде
всего
необ
хо
димо
понять,
как
мы
бу
дем
вычислять
с
хо
дство
двух
объектов.
По
хо
ж
есть
Любой
объект
мо
жет
быть
описан
к
ак
список
характеристик.
Напри-
мер,
статья в
блоге
мож
ет
быть
описана
тег
ами,
продукт в
интернет-
маг
азине
мож
ет
быть
описан
размером,
весом,
цветом
и
т
.
д.
Это
означает
,
что
для
к
аждого
объекта
можно
создать
цифровую
подпись
—
массив
чи-
сел,
описывающих
объект
(
отпечатки
пальцев
,
n-grams
).
Т
о
есть
нужно
создать
массив
из
цифр
для
описания
к
аждого
объекта.
Р
асчет
пох
о
ж
ести
Есть
неск
олько
методов
вычисления
пох
о
жести
сигнатур
объектов.
Прежде
всего,
легенда
для
расчетов:
∙
𝑁
𝑎
,
𝑁
𝑏
—
к
оличество
уникальных
элементов
в
массивах;
∙
𝑁
𝑢
—
количество
уник
альных
элементов
при
объединении
массивов;
∙
𝑁
𝑖
—
к
оличество
уникальных
элементов
при
пересечении
массивов.
Один
из
простейших
расчетов
пох
о
жести
двух
объектов
-
к
оличество
уник
альных
элементов
при
пересечении
массивов
делить
на
количество
уник
альных
элементов
в
двух
массивах:
𝑆
(
𝐴,
𝐵
)
=
𝑁
𝑖
(
𝑁
𝑎
+
𝑁
𝑏
)
(10.1)
210
10.8.
Smlar
или
проще
𝑆
(
𝐴,
𝐵
)
=
𝑁
𝑖
𝑁
𝑢
(10.2)
Преимущества:
∙
Легк
о
понять;
∙
Ск
орость
расчета:
𝑁
*
log
𝑁
;
∙
Хорошо
работ
ает
на
пох
ожих
и
больших
𝑁
𝑎
и
𝑁
𝑏
;
Т
акж
е
пох
ож
есть
мо
жно
рассчитать
по
форму
ле
косину
сов
:
𝑆
(
𝐴,
𝐵
)
=
𝑁
𝑖
√
𝑁
𝑎
*
𝑁
𝑏
(10.3)
Преимущества:
∙
Ск
орость
расчета:
𝑁
*
log
𝑁
;
∙
От
лично
работает
на
больших
𝑁
;
Но
у
обоих
этих
мето
дов
есть
общие
проблемы:
∙
Если
элементов
мало,
то
разброс
по
хо
жести
невелик;
∙
Г
лобальная
ст
атистик
а:
частые
элементы
ведут
к
тому
,
что
вес
ниже;
∙
Спамеры
и
недобросовестные
пользователи
могут
разрушить
работу
алгоритма
и
он
перест
анет
работать
на
Вас;
Для
избежания
этих
проблем
мо
жно
воспользоватьс
я
TF/IDF
метри-
к
ой
:
𝑆
(
𝐴,
𝐵
)
=
𝑖<𝑁
𝑎
,𝑗
<𝑁
𝑏
,𝐴
𝑖
=
𝐵
𝑗
𝑇
𝐹
𝑖
*
𝑇
𝐹
𝑗
𝑖<𝑁
𝑎
𝑇
𝐹
2
𝑖
*
𝑗
<𝑁
𝑏
𝑇
𝐹
2
𝑗
(10.4)
г
де
инвертированный
вес
элемента
в
коллекции:
𝐼
𝐷
𝐹
𝑒𝑙𝑒𝑚𝑒𝑛𝑡
=
log
(
𝑁
𝑜𝑏𝑗
𝑒𝑐𝑡𝑠
𝑁
𝑜𝑏𝑗
𝑒𝑐𝑡𝑠
𝑤
𝑖𝑡ℎ
𝑒𝑙𝑒𝑚𝑒𝑛𝑡
+
1)
(10.5)
и
вес
элемент
а
в
массиве:
𝑇
𝐹
𝑒𝑙𝑒𝑚𝑒𝑛𝑡
=
𝐼
𝐷
𝐹
𝑒𝑙𝑒𝑚𝑒𝑛𝑡
*
𝑁
𝑜𝑐𝑐𝑢𝑟𝑟
𝑒𝑛𝑐𝑒𝑠
(10.6)
Все
эти
алгоритмы
встроены
в
smlar
расширение.
Г
лавное
понимать,
что
для
TF/IDF
метрики
требу
ется
вспомогательная
т
аблица
для
хране-
ния
данных,
по
сравнению
с
другими
простыми
метрик
ами.
211
10.8.
Smlar
Smlar
Олег
Бартунов
и
Т
еодор
Сигаев
разработали
P
ostgreSQL
расширение
smlar
,
к
оторое
предоставляет
нескольк
о
мето
дов
для
расчета
по
х
ож
ести
массивов
(все
встроенные
типы
данных
по
ддер
живаются)
и
оператор
для
расчет
а
пох
о
ж
ести
с
поддер
жк
ой
индек
са
на
базе
GIST
и
GIN.
Для
на
чала
у
становим
это
расширение:
Листинг
10.44
У
становк
а
smlar
Line
1
$
g
i
t
c
l
o
n
e
g
i
t
:
/
/
s
i
g
a
e
v
.
r
u
/
s
m
l
a
r
-
$
c
d
s
m
l
a
r
-
$
U
S
E
_
P
G
X
S
=1
m
ak
e &
& m
a
k
e
i
n
s
t
a
l
l
Т
еперь
проверим
расширение:
Листинг
10.45
Проверка
smlar
Line
1
$
p
s
q
l
-
p
s
q
l
(
9
.
5
.
1
)
-
T
y
p
e
"
h
e
l
p
"
f
o
r
h
e
l
p
.
-
5
t
e
s
t
=
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
s
m
l
a
r
;
-
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
-
-
t
e
s
t
=
#
S
E
L
E
C
T
s
m
l
a
r
(
’
{
1
,
4
,
6
}
’
:
:
i
n
t
[
]
,
’
{
5
,
4
,
6
}
’
:
:
i
n
t
[
]
)
;
-
s
m
l
a
r
10
-
-
-
-
-
-
-
-
-
-
-
0
.
6
6
6
6
6
7
-
(
1
r
o
w
)
-
-
t
e
s
t
=
#
S
E
L
E
C
T
s
m
l
a
r
(
’
{
1
,
4
,
6
}
’
:
:
i
n
t
[
]
,
’
{
5
,
4
,
6
}
’
:
:
i
n
t
[
]
,
’
N
.
i
/
s
q
r
t
(
N
.
a
*
N
.
b
)
’
)
;
15
s
m
l
a
r
-
-
-
-
-
-
-
-
-
-
-
-
0
.
6
6
6
6
6
7
-
(
1
r
o
w
)
Мето
ды,
которые
предоставляет
это
расширение:
∙
float4
smlar(any
array,
any
array)
—
вычисляет пох
ож
есть двух
масси-
вов.
Массивы
должны
быть
о
дного
типа;
∙
float4
smlar(any
array,
any
array,
b
o
ol
useIn
tersect
)
—
вычисляет
по
хо-
ж
есть
двух
массивов
составных
типов.
Составной
тип
выглядит
сле-
дующим
образом:
Листинг
10.46
Составной
тип
212
10.8.
Smlar
Line
1
C
R
E
A
T
E
T
Y
P
E
t
y
p
e
_
n
a
m
e
AS
(
e
l
e
m
e
n
t
_
n
a
m
e
a
n
y
t
y
p
e
,
w
e
i
g
h
t
_
n
a
m
e
f
l
o
a
t
4
)
;
useIn
tersect
параметр
для
использования
пересек
ающихс
я
элементов
в
знаменателе;
∙
float4
smlar(
an
y
array
a, an
y
arra
y
b,
text
formula
)
—
вычисляет
по
хо-
ж
есть
двух
массивов
по
данной
форму
ле,
массивы
должны
быть
того
ж
е
типа.
Доступные
переменные
в
форму
ле:
– N.i
—
к
оличество
общих
элементов
обоих
массивов
(пересече-
ние);
– N.a
—
к
оличество
уникальных
элементов
первого
массива;
– N.b
—
к
оличество
уникальных
элементов
второго
массива;
∙
an
yarra
y
%
any
array
—
возвращает
истину
,
если
по
х
ож
есть
масси-
вов
больше,
чем
ук
азанный
предел.
Предел
ук
азывается
в
к
онфиге
P
ostgreSQL:
Листинг
10.47
Smlar
предел
Line
1
c
u
s
t
o
m
_
v
a
r
i
a
b
l
e
_
c
l
a
s
s
e
s
=
’
s
m
l
a
r
’
-
s
m
l
a
r
.
t
h
r
e
s
h
o
l
d
=
0
.
8
# предел
от
0
до
1
Т
акж
е
в
к
онфиге
можно указать
дополнительные
настройки
для
smlar:
Листинг
10.48
Smlar
настройки
Line
1
c
u
s
t
o
m
_
v
a
r
i
a
b
l
e
_
c
l
a
s
s
e
s
=
’
s
m
l
a
r
’
-
s
m
l
a
r
.
t
h
r
e
s
h
o
l
d
=
0
.
8
# предел
от
0
до
1
-
s
m
l
a
r
.
t
y
p
e
=
’
c
o
s
i
n
e
’
# по
к
ак
ой
форму
ле
производить
расчет
по
хо
жести
:
c
o
s
i
n
e
,
t
f
i
d
f ,
o
v
e
r
l
a
p
-
s
m
l
a
r
.
s
t
a
t
t
a
b
l
e
=
’
s
t
a
t
’
# Имя
таблицы
для
хранения
ст
атистики
при
работе
по
форму
ле
t
f
i
d
f
Более
по
дробно
можно
прочитать
в
README
этого
расширения.
GiST
и
GIN
индек
сы
поддер
живаются
для
оператора
%
.
Пример:
поиск
дублик
атов
картинок
Р
ассмотрим
простой
пример
поиск
а
дубликатов
картинок.
Алгоритм
помог
ает
найти
пох
о
жие
изображения,
которые,
например,
незна
читель-
но
отличаютс
я
(изображение
обесцветили,
добавили
во
дяные
знаки,
про-
пу
стили
через
филь
тры).
Но,
поскольку
точность
мала,
то
у
алгоритма
есть
и
позитивная
сторона
—
ск
орость
работы.
Как
мо
жно
определить,
что
к
артинки
пох
о
жи?
Самый
простой
метод
—
сравнивать
попик
сельно
213
10.8.
Smlar
два
изображ
ения.
Но
скорость
так
ой
работы
бу
дет
невелик
а
на
больших
разрешениях.
Т
ем
более,
т
акой
мето
д
не
учитывает
,
что
мог
ли
изменять
уровень
свет
а,
насыщенность
и
прочие
х
арактеристики
изображения.
Нам
нужно
создать
сигнатуру
для
к
артинок
в
виде
массива
цифр:
Рис.
10.1:
Пик
сельная
матрица
∙
Создаем
пиксельную
матрицу
к
изображению
(изменения
размера
изображ
ения
к
требу
емому
размеру
пик
сельной
матрице),
например
15X15
пик
селей(Рис.
10.1
);
∙
Р
ассчитаем
интенсивность
к
аждого
пик
селя
(интенсивность
вычис-
ляетс
я
по
форму
ле
0
.
299
*
красный
+
0
.
587
*
зеленый
+
0
.
114
*
синий).
Интенсивность
помо
ж
ет
нам
нахо
дить
по
хо
жие
изображения,
не
об-
ращая
внимание
на
использу
емые
цвета
в
них;
∙
Узнаем
отношение
интенсивности
каждого
пик
селя
к
среднему
зна-
чению
интенсивности
по
всей
матрице(Рис.
10.2
);
∙
Г
енериру
ем
уникальное
число
для
каждой
ячейки
(отношение
интен-
сивности
+
к
оординаты
ячейки);
∙
Сигнатура
для
к
артинки
готова;
Создаем
таблицу
,
г
де
бу
дем
хранить
имя
к
артинки,
путь
к
ней
и
её
сигнатуру:
214
10.8.
Smlar
Рис.
10.2:
Пик
сельная
матрица
Листинг
10.49
Т
аблица
для
изображений
Line
1
C
R
E
A
T
E
T
A
B
L
E
i
m
a
g
e
s
(
-
i
d
s
e
r
i
a
l
P
R
I
M
A
R
Y
K
E
Y
,
-
nam
e
v
a
r
c
h
a
r
(
5
0
)
,
-
i
m
g
_
p
a
t
h
v
a
r
c
h
a
r
(
2
5
0
)
,
5
i
m
a
g
e
_
a
r
r
a
y
i
n
t
e
g
e
r
[
]
-
)
;
Создадим
GIN
или
GIST
индек
с:
Листинг
10.50
Создание
GIN
или
GIST
индекса
Line
1
C
R
E
A
T
E
I
N
D
E
X
i
m
a
g
e
_
a
r
r
a
y
_
g
i
n
O
N
i
m
a
g
e
s
U
SI
N
G
GI
N
(
i
m
a
g
e
_
a
r
r
a
y
_
i
n
t
4
_
s
m
l
_
o
p
s
)
;
-
C
R
E
A
T
E
I
N
D
E
X
i
m
a
g
e
_
a
r
r
a
y
_
g
i
s
t
O
N
i
m
a
g
e
s
US
I
NG
GIST
(
i
m
a
g
e
_
a
r
r
a
y
_
i
n
t
4
_
s
m
l
_
o
p
s
)
;
Т
еперь
мо
жно
произвести
поиск
дубликатов:
Листинг
10.51
Поиск
дубликатов
Line
1
t
e
s
t=
#
S
E
L
E
C
T
c
o
u
n
t
(
*
)
f
r
o
m
i
m
a
g
e
s
;
-
c
o
u
n
t
-
-
-
-
-
-
-
-
-
-
-
1
0
0
0
0
0
0
5
(
1
r
o
w
)
-
-
t
e
s
t
=
#
E
X
P
L
A
I
N
A
N
A
L
Y
Z
E
S
E
L
E
C
T
c
o
u
n
t
(
*
)
F
R
O
M
i
m
a
g
e
s
W
H
E
R
E
i
m
a
g
e
s
.
i
m
a
g
e
_
a
r
r
a
y
%
’
{
1
0
1
0
2
5
9
,
1
0
1
1
2
5
3
,
.
.
.
,
2
4
2
3
2
5
3
,
2
4
2
4
2
5
2
}
’
:
:
i
n
t
[
]
;
-
215
10.8.
Smlar
-
B
i
t
m
a
p
He
a
p
S
c
a
n
o
n
i
m
a
g
e
s
(
c
o
s
t
=
2
8
6
.
6
4
.
.
3
9
6
9
.
4
5
r
o
w
s
=
9
8
6
w
i
d
t
h
=
4
)
(
a
c
t
u
a
l
t
i
m
e
=
5
0
4
.
3
1
2
.
.
2
0
4
7
.
5
3
3
r
o
w
s
=
2
0
0
0
0
0
l
o
o
p
s
=
1
)
10
R
e
c
h
e
c
k
Con
d
:
(
i
m
a
g
e
_
a
r
r
a
y
%
’
{
1
0
1
0
2
5
9
,
1
0
1
1
2
5
3
,
.
.
.
,
2
4
2
3
2
5
3
,
2
4
2
4
2
5
2
}
’
:
:
i
n
t
e
g
e
r
[
]
)
-
-
>
B
i
t
m
a
p
I
n
d
e
x
S
c
a
n
o
n
i
m
a
g
e
_
a
r
r
a
y
_
g
i
s
t
(
c
o
s
t
=
0
.
0
0
.
.
2
8
6
.
3
9
r
o
w
s
=
9
8
6
w
i
d
t
h
=
0
)
(
a
c
t
u
a
l
t
i
m
e
=
4
4
6
.
1
0
9
.
.
4
4
6
.
1
0
9
r
o
w
s
=
2
0
0
0
0
0
l
o
o
p
s
=
1
)
-
I
n
d
e
x
Co
nd
:
(
i
m
a
g
e
_
a
r
r
a
y
%
’
{
1
0
1
0
2
5
9
,
1
0
1
1
2
5
3
,
.
.
.
,
2
4
2
3
2
5
3
,
2
4
2
4
2
5
2
}
’
:
:
i
n
t
e
g
e
r
[
]
)
-
T
o
t
a
l
r
u
n
t
i
m
e
:
2
1
5
2
.
4
1
1
ms
-
(
5
r
o
w
s
)
г
де
’
{1010259,...,2424252}
’
::
int
[]
—
сигнатура
изображ
ения,
для
которой
пыт
аемся
найти
по
хо
жие
изображения.
С
помощью
smlar
.threshold
управ-
ляем
%
пох
о
жести
картинок
(при
к
аком
проценте
они
бу
дут
попадать
в
выборку).
Дополнительно
мож
ем
добавить
сортировку
по
самым
пох
о
жим
изоб-
раж
ениям:
Листинг
10.52
Добавляем
сортировку
по
сх
одству
картинок
Line
1
t
e
s
t=
#
E
X
P
L
A
I
N
A
N
A
L
Y
Z
E
S
E
L
E
C
T
s
m
l
a
r
(
i
m
a
g
e
s
.
i
m
a
g
e
_
a
r
r
a
y
,
’
{
1
0
1
0
2
5
9
,
.
.
.
,
2
4
2
4
2
5
2
}
’
:
:
i
n
t
[
]
)
a
s
s
i
m
i
l
a
r
i
t
y
F
R
O
M
i
m
a
g
e
s
W
H
E
R
E
i
m
a
g
e
s
.
i
m
a
g
e
_
a
r
r
a
y
%
’
{
1
0
1
0
2
5
9
,
1
0
1
1
2
5
3
,
.
.
.
,
2
4
2
3
2
5
3
,
2
4
2
4
2
5
2
}
’
:
:
i
n
t
[
]
O
R
D
E
R
B
Y
s
i
m
i
l
a
r
i
t
y
D
E
S
C
;
-
-
-
S
o
r
t
(
c
o
s
t
=
4
0
2
0
.
9
4
.
.
4
0
2
3
.
4
1
r
o
w
s
=
9
8
6
w
i
d
t
h
=
9
2
4
)
(
a
c
t
u
a
l
t
i
m
e
=
2
8
8
8
.
4
7
2
.
.
2
9
0
1
.
9
7
7
r
o
w
s
=
2
0
0
0
0
0
l
o
o
p
s
=
1
)
5
S
o
r
t
K
ey
:
(
s
m
l
a
r
(
i
m
a
g
e
_
a
r
r
a
y
,
’
{
.
.
.
,
2
4
2
4
2
5
2
}
’
:
:
i
n
t
e
g
e
r
[
]
)
)
-
S
o
r
t
M
e
t
h
o
d
:
q
u
i
c
k
s
o
r
t
Memory
:
1
5
5
2
0
kB
-
-
>
B
i
t
m
a
p
He
a
p
S
c
a
n
o
n
i
m
a
g
e
s
(
c
o
s
t
=
2
8
6
.
6
4
.
.
3
9
7
1
.
9
1
r
o
w
s
=
9
8
6
w
i
d
t
h
=
9
2
4
)
(
a
c
t
u
a
l
t
i
m
e
=
4
7
4
.
4
3
6
.
.
2
7
2
9
.
6
3
8
r
o
w
s
=
2
0
0
0
0
0
l
o
o
p
s
=1
)
-
R
e
c
h
e
c
k
C
on
d
:
(
i
m
a
g
e
_
a
r
r
a
y
%
’
{
.
.
.
,
2
4
2
4
2
5
2
}
’
:
:
i
n
t
e
g
e
r
[
]
)
-
-
>
B
i
t
m
a
p
I
n
d
e
x
S
c
a
n
o
n
i
m
a
g
e
_
a
r
r
a
y
_
g
i
s
t
(
c
o
s
t
=
0
.
0
0
.
.
2
8
6
.
3
9
r
o
w
s
=
9
8
6
w
i
d
t
h
=
0
)
(
a
c
t
u
a
l
t
i
m
e
=
4
2
1
.
1
4
0
.
.
4
2
1
.
1
4
0
r
o
w
s
=
2
0
0
0
0
0
l
o
o
p
s
=
1
)
10
I
n
d
e
x
C
on
d
:
(
i
m
a
g
e
_
a
r
r
a
y
%
’
{
.
.
.
,
2
4
2
4
2
5
2
}
’
:
:
i
n
t
e
g
e
r
[
]
)
-
T
o
t
a
l
r
u
n
t
i
m
e
:
2
9
1
2
.
2
0
7
ms
-
(
8
r
o
w
s
)
216
10.9.
Multicorn
Заключение
Smlar
расширение
мож
ет
быть
использовано
в
системах,
г
де
нам
нужно
иск
ать
пох
о
жие
объекты,
т
акие
как:
тексты,
темы,
блоги,
товары,
изобра-
ж
ения,
видео,
отпечатки
пальцев
и
прочее.
10.9
Multicorn
Multicorn
—
расширение
для
PostgreSQL
версии
9.1
или
выше,
к
оторое
позволяет
создавать
собственные
FDW
(F
oreign
Data
W
rapp
er),
использу
я
язык программирования
Python
. F
oreign Data W
rapp
er позволяют по
д-
ключитьс
я
к
другим
источникам
данных
(друг
ая
база,
файловая
система,
REST
API,
прочее)
в
P
ostgreSQL
и
были
представлены
с
версии
9.1.
Пример
У
ст
ановка
бу
дет
проводитьс
я
на
Ubun
tu
Linux.
Для
начала
нужно
уст
а-
новить
требу
емые
зависимости:
Листинг
10.53
Multicorn
Line
1
$
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
b
u
i
l
d
-
e
s
s
e
n
t
i
a
l
p
o
s
t
g
r
e
s
q
l
-
s
e
r
v
e
r
-
d
e
v
-
9
.
3
p
y
t
h
o
n
-
d
e
v
p
y
t
h
o
n
-
s
e
t
u
p
t
o
o
l
s
Следующим
шагом
у
становим
расширение:
Листинг
10.54
Multicorn
Line
1
$
g
i
t
c
l
o
n
e
g
i
t
@
g
i
t
h
u
b
.
co
m
:
K
o
z
e
a
/
M
u
l
t
i
c
o
r
n
.
g
i
t
-
$
c
d
M
u
l
t
i
c
o
r
n
-
$
m
a
ke &
&
s
u
d
o
ma
ke
i
n
s
t
a
l
l
Для
завершения
у
становки
активируем
расширение
для
базы
данных:
Листинг
10.55
Multicorn
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
m
u
l
t
i
c
o
r
n
;
-
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
Р
ассмотрим
какие
FDW
мож
ет
предоставить
Multicorn.
Р
еляционная
СУБД
Для
подключения
к
другой
реляционной
СУБД
Multicorn
использу-
ет
SQLAlc
hem
y
библиотеку
.
Данная
библиотек
а
поддер
живает
SQLite,
P
ostgreSQL,
MySQL,
Oracle,
MS-SQL,
Firebird,
Sybase,
и
другие
базы
дан-
ных.
Для
примера
настроим
подключение
к
MySQL.
Для
на
чала
нам
по-
требу
ется
уст
ановить
зависимости:
217
10.9.
Multicorn
Листинг
10.56
Multicorn
Line
1
$
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
p
y
t
h
o
n
-
s
q
l
a
l
c
h
e
m
y
p
y
t
h
o
n
-
m
y
s
q
l
d
b
В
MySQL
базе
данных
«testing»
у
нас
есть
т
аблица
«companies»
:
Листинг
10.57
Multicorn
Line
1
$
m
y
s
q
l
-
u
r
o
o
t
-
p
t
e
s
t
i
n
g
-
-
m
y
s
q
l
>
S
E
L
E
C
T
*
F
R
O
M
c
o
m
p
a
n
i
e
s
;
-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
5
|
i
d
|
c
r
e
a
t
e
d
_
a
t
|
u
p
d
a
t
e
d
_
a
t
|
-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
|
1
|
2
0
1
3
-
0
7
-
1
6
1
4
:
0
6
:
0
9
|
2
0
1
3
-
0
7
-
1
6
1
4
:
0
6
:
0
9
|
-
|
2
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
0
:
0
0
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
0
:
0
0
|
-
|
3
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
3
:
4
1
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
3
:
4
1
|
10
|
4
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
8
:
4
2
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
8
:
4
2
|
-
|
5
|
2
0
1
3
-
0
7
-
1
9
1
4
:
3
8
:
2
9
|
2
0
1
3
-
0
7
-
1
9
1
4
:
3
8
:
2
9
|
-
+
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
5
r
o
w
s
i
n
s
e
t
(
0
.
0
0
s
e
c
)
В
P
ostgreSQL
мы
должны
создать
сервер
для
Multicorn:
Листинг
10.58
Multicorn
Line
1
#
C
R
E
A
T
E
S
E
R
V
E
R
a
l
c
h
e
m
y
_
s
r
v
f
o
r
e
i
g
n
d
a
t
a
w
r
a
p
p
e
r
m
u
l
t
i
c
o
r
n
o
p
t
i
o
n
s
(
-
w
r
a
p
p
e
r
’
m
u
l
t
i
c
o
r
n
.
s
q
l
a
l
c
h
e
m
y
f
d
w
.
S
q
l
A
l
c
h
e
m
y
F
d
w
’
-
)
;
-
C
R
E
A
T
E
S
E
R
V
E
R
Т
еперь
мы
мо
жем
создать
таблицу
,
которая
бу
дет
содер
ж
ать
данные
из
MySQL
т
аблицы
«companies»:
Листинг
10.59
Multicorn
Line
1
#
C
R
E
A
T
E
F
O
R
E
I
G
N
T
A
B
L
E
m
y
s
q
l
_
c
o
m
p
a
n
i
e
s
(
-
i
d
i
n
t
e
g
e
r
,
-
c
r
e
a
t
e
d
_
a
t
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
,
-
u
p
d
a
t
e
d
_
a
t
t
i
m
e
s
t
a
m
p
w
i
t
h
o
u
t
t
i
m
e
z
o
n
e
5
)
s
e
r
v
e
r
a
l
c
h
e
m
y
_
s
r
v
o
p
t
i
o
n
s
(
-
t
a
b
l
e
n
a
m
e
’
c
o
m
p
a
n
i
e
s
’
,
-
d
b
_
u
r
l
’
m
y
s
q
l
:
/
/
r
o
o
t
:
p
a
s
s
w
o
r
d
@
1
2
7
.
0
.
0
.
1
/
t
e
s
t
i
n
g
’
-
)
;
-
C
R
E
A
T
E
F
O
R
E
I
G
N
T
A
B
L
E
Основные
опции:
218
10.9.
Multicorn
∙
db_url
(string)
— SQLAlc
hemy
настройки по
дключения к
базе
дан-
ных
(примеры:
m
ysql://<user>:<password>@<host>/<dbname>
,
mssql:
mssql://<user>:<passw
ord>@<dsname>
).
По
дробнее
мо
жно
узнать
из
SQLAlc
hemy
документации
;
∙
tablename
(string)
—
имя
т
аблицы
в
по
дключенной
базе
данных.
Т
еперь
мо
жем
проверить,
что
все
работает:
Листинг
10.60
Multicorn
Line
1
#
S
E
L
E
C
T
*
F
R
O
M
m
y
s
q
l
_
c
o
m
p
a
n
i
e
s
;
-
i
d
|
c
r
e
a
t
e
d
_
a
t
|
u
p
d
a
t
e
d
_
a
t
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1
|
2
0
1
3
-
0
7
-
1
6
1
4
:
0
6
:
0
9
|
2
0
1
3
-
0
7
-
1
6
1
4
:
0
6
:
0
9
5
2
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
0
:
0
0
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
0
:
0
0
-
3
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
3
:
4
1
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
3
:
4
1
-
4
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
8
:
4
2
|
2
0
1
3
-
0
7
-
1
6
1
4
:
3
8
:
4
2
-
5
|
2
0
1
3
-
0
7
-
1
9
1
4
:
3
8
:
2
9
|
2
0
1
3
-
0
7
-
1
9
1
4
:
3
8
:
2
9
-
(
5
r
o
w
s
)
IMAP
сервер
Multicorn
мо
жет
использоватьс
я
для
получения
писем
по
IMAP
прото-
к
олу
.
Для
начала
уст
ановим
зависимости:
Листинг
10.61
Multicorn
Line
1
$
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
p
y
t
h
o
n
-
p
i
p
-
$
s
u
d
o
p
i
p
i
n
s
t
a
l
l
i
m
a
p
c
l
i
e
n
t
Следующим
шагом
мы
должны
создать
сервер
и
таблицу
,
которая
бу-
дет
по
дключена
к
IMAP
серверу:
Листинг
10.62
Multicorn
Line
1
#
C
R
E
A
T
E
S
E
R
V
E
R
m
u
l
t
i
c
o
r
n
_
i
m
a
p
F
O
R
E
I
G
N
D
A
T
A
W
R
A
P
P
E
R
m
u
l
t
i
c
o
r
n
o
p
t
i
o
n
s
(
w
r
a
p
p
e
r
’
m
u
l
t
i
c
o
r
n
.
i
m
a
p
f
d
w
.
Ima
pFdw
’
)
;
-
C
R
E
A
T
E
S
E
R
V
E
R
-
#
C
R
E
A
T
E
F
O
R
E
I
G
N
T
A
B
L
E
m
y
_
i
n
b
o
x
(
-
"
M
e
s
s
a
g
e
-
I
D
"
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
,
5
"
From
"
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
,
-
"
S
u
b
j
e
c
t
"
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
,
-
"
p
a
y
l
o
a
d
"
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
,
-
"
f
l
a
g
s
"
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
[
]
,
-
"
To
"
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
)
s
e
r
v
e
r
m
u
l
t
i
c
o
r
n
_
i
m
a
p
o
p
t
i
o
n
s
(
10
h
o
s
t
’
i
m
a
p
.
g
m
a
i
l
.
com
’
,
219
10.9.
Multicorn
-
p
o
r
t
’
9
9
3
’
,
-
p
a
y
l
o
a
d
_
c
o
l
u
m
n
’
p
a
y
l
o
a
d
’
,
-
f
l
a
g
s
_
c
o
l
u
m
n
’
f
l
a
g
s
’
,
-
s
s
l
’
T
r
u
e
’
,
15
l
o
g
i
n
’
e
x
a
m
p
l
e
@
g
m
a
i
l
.
c
om
’
,
-
p
a
s
s
w
o
r
d
’
s
u
p
e
r
s
e
c
r
e
t
p
a
s
s
w
o
r
d
’
-
)
;
-
C
R
E
A
T
E
F
O
R
E
I
G
N
T
A
B
L
E
Основные
опции:
∙
host
(
string
)
—
IMAP
хост;
∙
p
ort
(
string
)
—
IMAP
порт;
∙
login
(
string
)
—
IMAP
логин;
∙
passw
ord
(string)
—
IMAP
пароль;
∙
pa
yload_column
(string)
—
имя
поля,
которое
бу
дет
со
держ
ать
текст
письма;
∙
flags_column
(string)
—
имя
поля,
которое
бу
дет
содер
ж
ать
IMAP
фла-
ги
письма
(массив);
∙
ssl
(
b
o
olean)
—
использовать
SSL
для
подключения;
∙
imap_serv
er_charset
(string)
—
к
о
дировка
для
IMAP
команд.
По
умол-
чанию
UTF8.
Т
еперь
мо
жно
получить
письма
через
таблицу
«my_in
b
ox»:
Листинг
10.63
Multicorn
Line
1
#
S
E
L
E
C
T
f
l
a
g
s
,
"
S
u
b
j
e
c
t
"
,
p
a
y
l
o
a
d
F
R
O
M
m
y
_
i
n
b
o
x
LIM
IT
1
0
;
-
f
l
a
g
s
|
S
u
b
j
e
c
t
|
p
a
y
l
o
a
d
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{
$
M
a
i
l
F
l
a
g
B
i
t
1
,
"
\
\
F
l
a
g
g
e
d
"
,
"
\
\
S
e
e
n
"
}
|
T
e
s
t
e
m
a
i
l
|
T
e
s
t
e
m
a
i
l
\
r
+
5
|
|
-
{
"
\
\
S
e
e
n
"
}
|
T
e
s
t
s
e
c
o
n
d
e
m
a
i
l
|
T
e
s
t
s
e
c
o
n
d
e
m
a
i
l
\
r+
-
|
|
-
(
2
r
o
w
s
)
RSS
Multicorn
мож
ет
использовать
RSS
как
источник
данных.
Для
начала
у
становим
зависимости:
220
10.9.
Multicorn
Листинг
10.64
Multicorn
Line
1
$
s
u
d
o
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
p
y
t
h
o
n
-
l
x
m
l
Как
и
в
прошлые
разы,
создаем
сервер
и
т
аблицу
для
RSS
ресурса:
Листинг
10.65
Multicorn
Line
1
#
C
R
E
A
T
E
S
E
R
V
E
R
r
s
s
_
s
r
v
f
o
r
e
i
g
n
d
a
t
a
w
r
a
p
p
e
r
m
u
l
t
i
c
o
r
n
o
p
t
i
o
n
s
(
-
w
r
a
p
p
e
r
’
m
u
l
t
i
c
o
r
n
.
r
s
s
f
d
w
.
R
s
s
F
d
w
’
-
)
;
-
C
R
E
A
T
E
S
E
R
V
E
R
5
#
C
R
E
A
T
E
F
O
R
E
I
G
N
T
A
B
L
E
m
y
_
r
s
s
(
-
"
p
u
b
D
a
t
e
"
t
i
m
e
s
t
a
m
p
,
-
d
e
s
c
r
i
p
t
i
o
n
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
,
-
t
i
t
l
e
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
,
-
l
i
n
k
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
10
)
s
e
r
v
e
r
r
s
s
_
s
r
v
o
p
t
i
o
n
s
(
-
u
r
l
’
h
t
t
p
:
/
/
n
e
w
s
.
y
a
h
o
o
.
c
om
/
r
s
s
/
e
n
t
e
r
t
a
i
n
m
e
n
t
’
-
)
;
-
C
R
E
A
T
E
F
O
R
E
I
G
N
T
A
B
L
E
Основные
опции:
∙
url
(
string
)
—
URL
RSS
ленты.
Кроме
того,
вы
должны
быть
уверены,
что
P
ostgreSQL
база
данных
использу
ет UTF-8
ко
дировку
(в
другой к
о
дировке
вы мо
ж
ете получить
ошибки).
Р
езу
льт
ат
т
аблицы
«my_rss»:
Листинг
10.66
Multicorn
Line
1
#
S
E
L
E
C
T
"
p
u
b
D
a
t
e
"
,
t
i
t
l
e ,
l
i
n
k
f
r
o
m
m
y
_
r
s
s
O
R
D
E
R
B
Y
"
p
u
b
D
a
t
e
"
D
E
S
C
L
IMIT
1
0
;
-
p
u
b
D
a
t
e
|
t
i
t
l
e
|
l
i
n
k
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2
0
1
3
-
0
9
-
2
8
1
4
:
1
1
:
5
8
|
R
o
y
a
l
M
i
n
t
c
o
i
n
s
t
o
m
a
r
k
P
r
i
n
c
e
G
e
o
r
g
e
c
h
r
i
s
t
e
n
i
n
g
|
h
t
t
p
:
/
/
n
e
w
s
.
y
a
h
o
o
.
com
/
r
o
y
a
l
-
m
i
n
t
-
c
o
i
n
s
-
m
a
r
k
-
p
r
i
n
c
e
-
g
e
o
r
g
e
-
c
h
r
i
s
t
e
n
i
n
g
-
1
1
5
9
0
6
2
4
2
.
h
t
m
l
5
2
0
1
3
-
0
9
-
2
8
1
1
:
4
7
:
0
3
|
M
i
s
s
P
h
i
l
i
p
p
i
n
e
s
w
i
n
s
M
i
s
s
W
o
r
l
d
i
n
I
n
d
o
n
e
s
i
a
|
h
t
t
p
:
/
/
n
e
w
s
.
y
a
h
o
o
.
com
/
m
i
s
s
-
p
h
i
l
i
p
p
i
n
e
s
-
w
i
n
s
-
m
i
s
s
-
w
o
r
l
d
-
i
n
d
o
n
e
s
i
a
-
1
4
4
5
4
4
3
8
1
.
h
t
m
l
-
2
0
1
3
-
0
9
-
2
8
1
0
:
5
9
:
1
5
|
B
i
l
l
i
o
n
a
i
r
e
’
s
d
a
u
g
h
t
e
r
i
n
NJ
c
o
u
r
t
i
n
w
i
l
l
d
i
s
p
u
t
e
|
h
t
t
p
:
/
/
n
e
w
s
.
y
a
h
o
o
.
com
/
b
i
l
l
i
o
n
a
i
r
e
s
-
d
a
u
g
h
t
e
r
-
n
j
-
c
o
u
r
t
-
d
i
s
p
u
t
e
-
1
4
4
4
3
2
3
3
1
.
h
t
m
l
221
10.9.
Multicorn
-
2
0
1
3
-
0
9
-
2
8
0
8
:
4
0
:
4
2
|
S
e
c
u
r
i
t
y
t
i
g
h
t
a
t
M
i
s
s
W
o
r
l
d
f
i
n
a
l
i
n
I
n
d
o
n
e
s
i
a
|
h
t
t
p
:
/
/
n
e
w
s
.
y
a
h
o
o
.
c
om
/
s
e
c
u
r
i
t
y
-
t
i
g
h
t
-
m
i
s
s
-
w
o
r
l
d
-
f
i
n
a
l
-
i
n
d
o
n
e
s
i
a
-
1
2
3
7
1
4
0
4
1
.
h
t
m
l
-
2
0
1
3
-
0
9
-
2
8
0
8
:
1
7
:
5
2
|
G
u
e
s
t
l
i
n
e
u
p
s
f
o
r
t
h
e
S
u
n
d
a
y
n
e
w
s
s
h
o
w
s
|
h
t
t
p
:
/
/
n
e
w
s
.
y
a
h
o
o
.
c
om
/
g
u
e
s
t
-
l
i
n
e
u
p
s
-
s
u
n
d
a
y
-
n
e
w
s
-
s
h
o
w
s
-
1
8
3
8
1
5
6
4
3
.
h
t
m
l
-
2
0
1
3
-
0
9
-
2
8
0
7
:
3
7
:
0
2
|
S
e
c
u
r
i
t
y
t
i
g
h
t
a
t
M
i
s
s
W
o
r
l
d
c
r
o
w
n
i
n
g
i
n
I
n
d
o
n
e
s
i
a
|
h
t
t
p
:
/
/
n
e
w
s
.
y
a
h
o
o
.
com
/
s
e
c
u
r
i
t
y
-
t
i
g
h
t
-
m
i
s
s
-
w
o
r
l
d
-
c
r
o
w
n
i
n
g
-
i
n
d
o
n
e
s
i
a
-
1
1
3
6
3
4
3
1
0
.
h
t
m
l
10
2
0
1
3
-
0
9
-
2
7
2
0
:
4
9
:
3
2
|
S
i
m
o
n
s
s
t
a
m
p
s
h
i
s
n
a
t
u
r
a
l
m
a
r
k
o
n
D
i
o
r
|
h
t
t
p
:
/
/
n
e
w
s
.
y
a
h
o
o
.
com
/
s
i
m
o
n
s
-
s
t
a
m
p
s
-
n
a
t
u
r
a
l
-
m
a
r
k
-
d
i
o
r
-
2
2
3
8
4
8
5
2
8
.
h
t
m
l
-
2
0
1
3
-
0
9
-
2
7
1
9
:
5
0
:
3
0
|
J
a
c
k
s
o
n
j
u
r
y
e
n
d
s
d
e
l
i
b
e
r
a
t
i
o
n
s
u
n
t
i
l
T
u
e
s
d
a
y
|
h
t
t
p
:
/
/
n
e
w
s
.
y
a
h
o
o
.
com
/
j
a
c
k
s
o
n
-
j
u
r
y
-
e
n
d
s
-
d
e
l
i
b
e
r
a
t
i
o
n
s
-
u
n
t
i
l
-
t
u
e
s
d
a
y
-
2
3
5
0
3
0
9
6
9
.
h
t
m
l
-
2
0
1
3
-
0
9
-
2
7
1
9
:
2
3
:
4
0
|
E
r
i
c
C
l
a
p
t
o
n
-
o
w
n
e
d
R
i
c
h
t
e
r
p
a
i
n
t
i
n
g
t
o
s
e
l
l
i
n
N
Y
C
|
h
t
t
p
:
/
/
n
e
w
s
.
y
a
h
o
o
.
c
om
/
e
r
i
c
-
c
l
a
p
t
o
n
-
o
w
n
e
d
-
r
i
c
h
t
e
r
-
p
a
i
n
t
i
n
g
-
s
e
l
l
-
n
y
c
-
2
0
1
4
4
7
2
5
2
.
h
t
m
l
-
2
0
1
3
-
0
9
-
2
7
1
9
:
1
4
:
1
5
|
R
e
p
o
r
t
:
H
o
l
l
y
w
o
o
d
i
s
l
e
s
s
g
a
y
-
f
r
i
e
n
d
l
y
o
f
f
-
s
c
r
e
e
n
|
h
t
t
p
:
/
/
n
e
w
s
.
y
a
h
o
o
.
com
/
r
e
p
o
r
t
-
h
o
l
l
y
w
o
o
d
-
l
e
s
s
-
g
a
y
-
f
r
i
e
n
d
l
y
-
o
f
f
-
s
c
r
e
e
n
-
2
3
1
4
1
5
2
3
5
.
h
t
m
l
-
(
1
0
r
o
w
s
)
CSV
Multicorn
мож
ет
использовать
CSV
файл
как
источник
данных.
Как
и
в
прошлые
разы,
создаем
сервер
и
т
аблицу
для
CSV
ресурса:
Листинг
10.67
Multicorn
Line
1
#
C
R
E
A
T
E
S
E
R
V
E
R
c
s
v
_
s
r
v
f
o
r
e
i
g
n
d
a
t
a
w
r
a
p
p
e
r
m
u
l
t
i
c
o
r
n
o
p
t
i
o
n
s
(
-
w
r
a
p
p
e
r
’
m
u
l
t
i
c
o
r
n
.
c
s
v
f
d
w
.
C
svFdw
’
-
)
;
-
C
R
E
A
T
E
S
E
R
V
E
R
5
#
C
R
E
A
T
E
F
O
R
E
I
G
N
T
A
B
L
E
c
s
v
t
e
s
t
(
-
s
o
r
t
_
o
r
d
e
r
n
u
m
e
r
i
c
,
-
com
mo
n_n
am
e
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
,
-
f
o
r
m
a
l
_
n
a
m
e
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
,
-
m
a
i
n
_
t
y
p
e
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
,
10
s
u
b
_
t
y
p
e
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
,
-
s
o
v
e
r
e
i
g
n
t
y
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
,
-
c
a
p
i
t
a
l
c
h
a
r
a
c
t
e
r
v
a
r
y
i
n
g
-
)
s
e
r
v
e
r
c
s
v
_
s
r
v
o
p
t
i
o
n
s
(
-
f
i
l
e
n
a
m
e
’
/
v
a
r
/
d
a
t
a
/
c
o
u
n
t
r
y
l
i
s
t
.
c
s
v
’
,
15
s
k
i
p
_
h
e
a
d
e
r
’
1
’
,
-
d
e
l
i
m
i
t
e
r
’
,
’
)
;
222
10.9.
Multicorn
-
C
R
E
A
T
E
F
O
R
E
I
G
N
T
A
B
L
E
Основные
опции:
∙
filename
(
string
)
—
полный
путь
к
CSV
файлу;
∙
delimiter
(
character
)
—
разделитель
в
CSV
файле
(по
умолчанию
«,»);
∙
quotec
har
(
c
haracter
)
—
к
авычки
в
CSV
файле;
∙
skip_header
(
in
teger
)
—
число
строк,
которые
необ
х
одимо
пропу
стить
(по
умолчанию
0).
Р
езу
льт
ат
т
аблицы
«csvtest»:
Листинг
10.68
Multicorn
Line
1
#
S
E
L
E
C
T
*
F
R
O
M
c
s
v
t
e
s
t
L
IMIT
1
0
;
-
s
o
r
t
_
o
r
d
e
r
|
c
om
mon
_n
ame
|
f
o
r
m
a
l
_
n
a
m
e
|
m
a
i
n
_
t
y
p
e
|
s
u
b
_
t
y
p
e
|
s
o
v
e
r
e
i
g
n
t
y
|
c
a
p
i
t
a
l
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1
|
A
f
g
h
a
n
i
s
t
a
n
|
I
s
l
a
m
i
c
S
t
a
t
e
o
f
A
f
g
h
a
n
i
s
t
a
n
|
I
n
d
e
p
e
n
d
e
n
t
S
t
a
t
e
|
|
|
K
a
b
u
l
5
2
|
A
l
b
a
n
i
a
|
R
e
p
u
b
l
i
c
o
f
A
l
b
a
n
i
a
|
I
n
d
e
p
e
n
d
e
n
t
S
t
a
t
e
|
|
|
T
i
r
a
n
a
-
3
|
A
l
g
e
r
i
a
|
P
e
o
p
l
e
’
s
D
e
m
o
c
r
a
t
i
c
R
e
p
u
b
l
i
c
o
f
A
l
g
e
r
i
a
|
I
n
d
e
p
e
n
d
e
n
t
S
t
a
t
e
|
|
|
A
l
g
i
e
r
s
-
4
|
A
n
d
o
r
r
a
|
P
r
i
n
c
i
p
a
l
i
t
y
o
f
A
n
d
o
r
r
a
|
I
n
d
e
p
e
n
d
e
n
t
S
t
a
t
e
|
|
|
A
n
d
o
r
r
a
l
a
V
e
l
l
a
-
5
|
A
n
g
o
l
a
|
R
e
p
u
b
l
i
c
o
f
A
n
g
o
l
a
|
I
n
d
e
p
e
n
d
e
n
t
S
t
a
t
e
|
|
|
L
u
a
n
d
a
-
6
|
A
n
t
i
g
u
a
a
n
d
B
a
r
b
u
d
a
|
|
I
n
d
e
p
e
n
d
e
n
t
S
t
a
t
e
|
|
|
S
a
i
n
t
J
o
h
n
’
s
10
7
|
A
r
g
e
n
t
i
n
a
|
A
r
g
e
n
t
i
n
e
R
e
p
u
b
l
i
c
|
I
n
d
e
p
e
n
d
e
n
t
S
t
a
t
e
|
|
|
B
u
e
n
o
s
A
i
r
e
s
-
8
|
A
r
m
e
n
i
a
|
R
e
p
u
b
l
i
c
o
f
A
r
m
e
n
i
a
|
I
n
d
e
p
e
n
d
e
n
t
S
t
a
t
e
|
|
|
Y
e
r
e
v
a
n
-
9
|
A
u
s
t
r
a
l
i
a
|
C
o
m
m
o
n
w
e
a
l
t
h
o
f
A
u
s
t
r
a
l
i
a
|
I
n
d
e
p
e
n
d
e
n
t
S
t
a
t
e
|
|
|
C
a
n
b
e
r
r
a
223
10.10.
Pgaudit
-
1
0
|
A
u
s
t
r
i
a
|
R
e
p
u
b
l
i
c
o
f
A
u
s
t
r
i
a
|
I
n
d
e
p
e
n
d
e
n
t
S
t
a
t
e
|
|
|
V
i
e
n
n
a
-
(
1
0
r
o
w
s
)
Другие
FD
W
Multicorn
т
акже
содер
жит
FD
W
для
LD
AP
и
файловой
системы.
LDAP
FD
W
мо
жет
использоватьс
я
для
доступа
к
серверам
по
LD
AP
проток
олу
.
FD
W
для
файловой
системы
мо
ж
ет
быть
использован
для
доступа
к
дан-
ным,
хранящимс
я
в
различных
файлах
в
файловой
системе.
Собственный
FD
W
Multicorn
предоставляет
простой
интерфейс
для
написания
собствен-
ных
FD
W.
Более
подробную
информацию
вы
мо
жете
найти
по
этой
ссыл-
к
е
.
P
ostgreSQL
9.3+
В
PostgreSQL
9.1
и
9.2
была
предст
авлена
реализация
FD
W
тольк
о
на
чтение.
На
чиная
с
версии
9.3,
FDW
мож
ет
писать
во
внешние
источники
данных.
Сейчас
Multicorn
поддер
живает
запись
данных
в
другие
источни-
ки,
на
чиная
с
версии
1.0.0.
Заключение
Multicorn
—
расширение
для
PostgreSQL,
к
оторое
позволяет
использо-
вать
встроенные
FD
W
или
создавать
собственные
на
Python.
10.10
Pgaudit
Pgaudit
— расширение
для P
ostgreSQL, к
оторое позволяет собирать
события
из
различных
источников
внутри
P
ostgreSQL
и
записывает
их
в
формате
CSV
c
временной
меткой,
информацией
о
пользователе,
объекте,
к
оторый
был
затронут
к
омандой
(если
т
акое
произошло)
и
полным
тек-
стом
к
оманды.
Поддер
живает
все
DDL,
DML
(включая
SELECT
)
и
прочие
к
оманды.
Данное
расширение
работает
в
PostgreSQL
9.3
и
выше.
После
уст
ановки
расширения
нужно
добавит
в
к
онфиг
P
ostgreSQL
на-
стройки
расширения:
Листинг
10.69
Pgaudit
Line
1
s
h
a
r
e
d
_
p
r
e
l
o
a
d
_
l
i
b
r
a
r
i
e
s
=
’
p
g
a
u
d
i
t
’
224
10.11.
Ltree
-
-
p
g
a
u
d
i
t
.
l
o
g
=
’
r
e
a
d
,
w
r
i
t
e
,
u
s
e
r
’
Далее
перегрузить
базу
данных
и
у
становить
расширение
для
базы:
Листинг
10.70
Pgaudit
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
g
a
u
d
i
t
;
После
этого
в
лог
ах
можно
увидеть
подобный
резу
льт
ат
от
pgaudit:
Листинг
10.71
Pgaudit
Line
1
L
O
G
:
[
A
U
D
I
T
]
,
2
0
1
4
-
0
4
-
3
0
1
7
:
1
3
:
5
5
.
2
0
2
8
5
4
+
0
9
,
a
u
d
i
t
d
b
,
i
a
n
b
,
i
a
n
b
,
D
EFI
NITI
ON
,
C
R
E
A
T
E
T
A
B
L
E
,
T
A
B
L
E,
p
u
b
l
i
c
.
x
,
C
R
E
A
T
E
T
A
B
L
E
p
u
b
l
i
c
.
x
(
a
p
g
_
c
a
t
a
l
o
g
.
i
n
t
4
,
b
p
g
_
c
a
t
a
l
o
g
.
i
n
t
4
)
W
I
T
H
(
o
i
d
s
=
O
F
F
)
-
L
O
G
:
[
A
U
D
I
T
]
,
2
0
1
4
-
0
4
-
3
0
1
7
:
1
4
:
0
6
.
5
4
8
9
2
3
+
0
9
,
a
u
d
i
t
d
b
,
i
a
n
b
,
i
a
n
b
,
W
R
I
T
E
,
IN
SE
RT
,
T
A
B
L
E
,
p
u
b
l
i
c
.
x
,
I
N
S
ER
T
I
N
T
O
x
V
A
L
U
E
S
(
1
,
1
)
;
-
L
O
G
:
[
A
U
D
I
T
]
,
2
0
1
4
-
0
4
-
3
0
1
7
:
1
4
:
2
1
.
2
2
1
8
7
9
+
0
9
,
a
u
d
i
t
d
b
,
i
a
n
b
,
i
a
n
b
,
R
E
A
D,
S
E
L
E
C
T
,
T
A
B
L
E,
p
u
b
l
i
c
.
x
,
S
E
L
E
C
T
* F
R
O
M x
;
-
L
O
G
:
[
A
U
D
I
T
]
,
2
0
1
4
-
0
4
-
3
0
1
7
:
1
5
:
2
5
.
6
2
0
2
1
3
+
0
9
,
a
u
d
i
t
d
b
,
i
a
n
b
,
i
a
n
b
,
R
E
A
D,
S
E
L
E
C
T
,
V
I
E
W,
p
u
b
l
i
c
.
v_x
,
S
E
L
E
C
T
*
f
r
o
m
v_x
;
5
L
O
G
:
[
A
U
D
I
T
]
,
2
0
1
4
-
0
4
-
3
0
1
7
:
1
5
:
2
5
.
6
2
0
2
6
2
+
0
9
,
a
u
d
i
t
d
b
,
i
a
n
b
,
i
a
n
b
,
R
E
A
D,
S
E
L
E
C
T
,
T
A
B
L
E,
p
u
b
l
i
c
.
x
,
S
E
L
E
C
T
*
f
r
o
m
v_x
;
-
L
O
G
:
[
A
U
D
I
T
]
,
2
0
1
4
-
0
4
-
3
0
1
7
:
1
6
:
0
0
.
8
4
9
8
6
8
+
0
9
,
a
u
d
i
t
d
b
,
i
a
n
b
,
i
a
n
b
,
W
R
I
T
E
,
U
P
D
A
T
E,
T
A
B
L
E,
p
u
b
l
i
c
.
x
,
U
P
D
A
T
E
x
SE
T
a
=a
+
1
;
-
L
O
G
:
[
A
U
D
I
T
]
,
2
0
1
4
-
0
4
-
3
0
1
7
:
1
6
:
1
8
.
2
9
1
4
5
2
+
0
9
,
a
u
d
i
t
d
b
,
i
a
n
b
,
i
a
n
b
,
A
D
M
I
N,
V
A
C
U
U
M
,
,
,V
A
C
U
U
M x
;
-
L
O
G
:
[
A
U
D
I
T
]
,
2
0
1
4
-
0
4
-
3
0
1
7
:
1
8
:
0
1
.
0
8
2
9
1
+
0
9
,
a
u
d
i
t
d
b
,
i
a
n
b
,
i
a
n
b
,
D
EFIN
ITI
ON
,
C
R
E
A
T
E
F
U
N
C
T
I
O
N
,
F
U
N
C
T
I
O
N
,
p
u
b
l
i
c
.
f
u
n
c
_
x
(
)
,
C
R
E
A
T
E
F
U
N
C
T
I
O
N
p
u
b
l
i
c
.
f
u
n
c
_
x
(
)
R
E
T
U
R
N
S
p
g
_
c
a
t
a
l
o
g
.
i
n
t
4
L
A
N
G
U
A
G
E
s
q
l
V
O
L
A
T
I
L
E
C
A
L
L
E
D
O
N
N
U
L
L I
N
P
U
T S
E
C
U
R
I
T
Y
I
N
V
O
K
E
R
C
O
S
T
1
0
0
.
0
0
0
0
0
0
AS
$
dpr
s_
$S
ELE
CT
a
F
R
O
M x
LIMI
T
1
;
$
d
p
r
s
_
$
Более
подробную
информацию
про
настройку
расширения
можно
най-
ти
в
официальном
README
.
10.11
Ltree
Ltree
—
расширение,
ко
торое
позволяет
хранить
древовидные
структу-
ры
в
виде
меток,
а
такж
е
предоставляет
широкие
возможности
поиск
а
по
ним.
225
10.11.
Ltree
Почему
Ltree?
∙
Р
еализация
алгоритма
Materialized
Path
(довольно
быстра,
как
на
запись,
т
ак
и
на
чтение);
∙
Как
правило
данное
решение
бу
дет
быстрее,
чем
использование
CTE
(Common
T
able
Expressions)
или
рекурсивной
функции
(посто
янно
бу
дут
пересчитываться
ветвления);
∙
Встроены
мех
анизмы
поиска
по
дереву;
∙
Индек
сы;
У
становк
а
и
использование
Для
на
чала
активируем
расширение
для
базы
данных:
Листинг
10.72
Ltree
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
l
t
r
e
e
;
Далее
создадим
т
аблицу
к
омментариев,
к
оторые
бу
дут
храниться
как
дерево:
Листинг
10.73
Ltree
Line
1
C
R
E
A
T
E
T
A
B
L
E
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
i
n
t
e
g
e
r
,
d
e
s
c
r
i
p
t
i
o
n
t
e
x
t
,
p
a
t
h
l
t
r
e
e
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
1
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
2
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
1
.
0
0
0
1
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
2
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
1
.
0
0
0
1
.
0
0
0
1
’
)
;
5
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
1
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
1
.
0
0
0
1
.
0
0
0
2
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
5
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
1
.
0
0
0
1
.
0
0
0
3
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
6
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
2
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
6
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
2
.
0
0
0
1
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
6
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
’
)
;
10
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
8
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
1
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
9
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
2
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
1
1
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
1
’
)
;
226
10.11.
Ltree
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
2
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
5
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
3
’
)
;
15
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
7
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
1
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
2
0
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
2
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
3
1
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
3
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
2
2
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
4
’
)
;
-
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
3
4
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
5
’
)
;
20
I
N
SE
RT I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
2
2
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
6
’
)
;
Не
забываем
добавить
индек
сы:
Листинг
10.74
Ltree
Line
1
#
C
R
E
A
T
E
I
N
D
E
X
p
a
t
h
_
g
i
s
t
_
c
o
m
m
e
n
t
s
_
i
d
x
O
N
c
o
m
m
e
n
t
s
U
SI
N
G
GIST
(
p
a
t
h
)
;
-
#
C
R
E
A
T
E
I
N
D
E
X
p
a
t
h
_
c
o
m
m
e
n
t
s
_
i
d
x
O
N
c
o
m
m
e
n
t
s
U
SI
N
G
b
t
r
e
e
(
p
a
t
h
)
;
В
данном
примере
я
создаю
т
аблицу
commen
ts
с
полем
path
,
которое
и
бу
дет
содер
ж
ать
полный
путь
к
этому
коммент
арию
в
дереве
(я
использую
4 цифры
и точку
для делителя
узлов дерева).
Для на
чала найдем
все
к
омментарии,
у
которых
путь
начинаетс
я
с
0001.0003
:
Листинг
10.75
Ltree
Line
1
#
S
E
L
E
C
T
u
s
e
r
_
i
d
,
p
a
t
h
F
R
O
M
c
o
m
m
e
n
t
s
W
H
E
R
E
p
a
t
h
<
@
’
0
0
0
1
.
0
0
0
3
’
;
-
u
s
e
r
_
i
d
|
p
a
t
h
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
6
|
0
0
0
1
.
0
0
0
3
5
8
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
-
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
-
1
1
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
1
-
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
-
5
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
3
10
7
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
1
-
2
0
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
2
-
3
1
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
3
-
2
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
4
-
3
4
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
5
227
10.11.
Ltree
15
2
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
6
-
(
1
2
r
o
w
s
)
И
проверим
к
ак
работают
индексы:
Листинг
10.76
Ltree
Line
1
#
S
E
T
e
n
a
b
l
e
_
s
e
q
s
c
a
n
=
f
a
l
s
e
;
-
SE
T
-
#
E
X
P
L
A
I
N
A
N
A
L
Y
Z
E
S
E
L
E
C
T
u
s
e
r
_
i
d
,
p
a
t
h
F
R
O
M
c
o
m
m
e
n
t
s
W
H
E
R
E
p
a
t
h
<
@
’
0
0
0
1
.
0
0
0
3
’
;
-
Q
U
E
R
Y
P
L
A
N
5
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
I
n
d
e
x
S
c
a
n
u
s
i
n
g
p
a
t
h
_
g
i
s
t
_
c
o
m
m
e
n
t
s
_
i
d
x
o
n
c
o
m
m
e
n
t
s
(
c
o
s
t
=
0
.
0
0
.
.
8
.
2
9
r
o
w
s
=2
w
i
d
t
h
=
3
8
)
(
a
c
t
u
a
l
t
i
m
e
=
0
.
0
2
3
.
.
0
.
0
3
4
r
o
w
s
=12
l
o
o
p
s
=
1
)
-
I
n
d
e
x
C
on
d
:
(
p
a
t
h
<
@
’
0
0
0
1
.
0
0
0
3
’
:
:
l
t
r
e
e
)
-
T
o
t
a
l
r
u
n
t
i
m
e
:
0
.
0
7
6
ms
-
(
3
r
o
w
s
)
Данную
выборку
мо
жно
сделать
другим
запросом:
Листинг
10.77
Ltree
Line
1
#
S
E
L
E
C
T
u
s
e
r
_
i
d
,
p
a
t
h
F
R
O
M
c
o
m
m
e
n
t
s
W
H
E
R
E
p
a
t
h
~
’
0
0
0
1
.
0
0
0
3
.
*
’
;
-
u
s
e
r
_
i
d
|
p
a
t
h
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
6
|
0
0
0
1
.
0
0
0
3
5
8
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
-
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
-
1
1
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
1
-
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
-
5
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
3
10
7
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
1
-
2
0
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
2
-
3
1
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
3
-
2
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
4
-
3
4
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
5
15
2
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
6
-
(
1
2
r
o
w
s
)
Не
забываем
про
сортировку
дерева:
Листинг
10.78
Ltree
228
10.11.
Ltree
Line
1
#
I
N
SE
RT I
N
T
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
9
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
1
’
)
;
-
#
IN
SE
R
T
I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
9
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
2
’
)
;
-
#
IN
SE
R
T
I
NT
O
c
o
m
m
e
n
t
s
(
u
s
e
r
_
i
d
,
d
e
s
c
r
i
p
t
i
o
n
,
p
a
t
h
)
V
A
L
U
E
S
(
9
,
m
d5
(
r
a
n
d
o
m
(
)
:
:
t
e
x
t
)
,
’
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
3
’
)
;
-
#
S
E
L
E
C
T
u
s
e
r
_
i
d
,
p
a
t
h
F
R
O
M
c
o
m
m
e
n
t
s
W
H
E
R
E
p
a
t
h
~
’
0
0
0
1
.
0
0
0
3
.
*
’
;
5
u
s
e
r
_
i
d
|
p
a
t
h
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
6
|
0
0
0
1
.
0
0
0
3
-
8
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
-
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
10
1
1
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
1
-
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
-
5
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
3
-
7
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
1
-
2
0
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
2
15
3
1
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
3
-
2
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
4
-
3
4
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
5
-
2
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
6
-
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
1
20
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
2
-
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
3
-
(
1
5
r
o
w
s
)
-
#
S
E
L
E
C
T
u
s
e
r
_
i
d
,
p
a
t
h
F
R
O
M
c
o
m
m
e
n
t
s
W
H
E
R
E
p
a
t
h
~
’
0
0
0
1
.
0
0
0
3
.
*
’
O
R
D
E
R
b
y
p
a
t
h
;
-
u
s
e
r
_
i
d
|
p
a
t
h
25
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
6
|
0
0
0
1
.
0
0
0
3
-
8
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
-
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
1
-
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
2
30
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
3
-
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
-
1
1
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
1
-
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
-
7
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
1
35
2
0
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
2
-
3
1
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
3
-
2
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
4
-
3
4
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
5
-
2
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
6
40
5
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
3
-
(
1
5
r
o
w
s
)
Для
поиск
а
можно
использовать
разные
модифик
аторы.
Пример
ис-
229
10.11.
Ltree
пользования
«или»
(
|
):
Листинг
10.79
Ltree
Line
1
#
S
E
L
E
C
T
u
s
e
r
_
i
d
,
p
a
t
h
F
R
O
M
c
o
m
m
e
n
t
s
W
H
E
R
E
p
a
t
h
~
’
0
0
0
1
.
*
{
1
,
2
}
.
0
0
0
1
|
0
0
0
2
.
*
’
O
R
D
E
R
b
y
p
a
t
h
;
-
u
s
e
r
_
i
d
|
p
a
t
h
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2
|
0
0
0
1
.
0
0
0
1
.
0
0
0
1
5
2
|
0
0
0
1
.
0
0
0
1
.
0
0
0
1
.
0
0
0
1
-
1
|
0
0
0
1
.
0
0
0
1
.
0
0
0
1
.
0
0
0
2
-
5
|
0
0
0
1
.
0
0
0
1
.
0
0
0
1
.
0
0
0
3
-
6
|
0
0
0
1
.
0
0
0
2
.
0
0
0
1
-
8
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
10
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
1
-
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
2
-
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
.
0
0
0
3
-
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
-
1
1
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
1
15
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
-
7
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
1
-
2
0
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
2
-
3
1
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
3
-
2
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
4
20
3
4
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
5
-
2
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
6
-
5
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
3
-
(
1
9
r
o
w
s
)
Например,
найдем
пр
ямых
потомков
от
0001.0003
:
Листинг
10.80
Ltree
Line
1
#
S
E
L
E
C
T
u
s
e
r
_
i
d
,
p
a
t
h
F
R
O
M
c
o
m
m
e
n
t
s
W
H
E
R
E
p
a
t
h
~
’
0
0
0
1
.
0
0
0
3
.
*
{
1
}
’
O
R
D
E
R
b
y
p
a
t
h
;
-
u
s
e
r
_
i
d
|
p
a
t
h
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
8
|
0
0
0
1
.
0
0
0
3
.
0
0
0
1
5
9
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
-
(
2
r
o
w
s
)
Мо
жно
такж
е
найти
ро
дителя
для
потомк
а
«0001.0003.0002.0002.0005»:
Листинг
10.81
Ltree
Line
1
#
S
E
L
E
C
T
u
s
e
r
_
i
d
,
p
a
t
h
F
R
O
M
c
o
m
m
e
n
t
s
W
H
E
R
E
p
a
t
h
=
s
u
b
p
a
t
h
(
’
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
.
0
0
0
5
’
,
0
,
-
1
)
O
R
D
E
R
b
y
p
a
t
h
;
-
u
s
e
r
_
i
d
|
p
a
t
h
230
10.12.
PostPic
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2
|
0
0
0
1
.
0
0
0
3
.
0
0
0
2
.
0
0
0
2
5
(
1
r
o
w
)
Заключение
Ltree
—
расширение,
которое
позволяет
хранить
и
у
добно
управлять
Materialized
P
ath
в
PostgreSQL.
10.12
P
ostPic
P
ostPic
-
расширение
для
PostgreSQL,
которое
позволяет
обрабатывать
изображ
ения
в
базе
данных,
к
ак
P
ostGIS
делает
это
с
пространственными
данными.
Он
добавляет
новый
типа
поля
image
,
а
т
акже
нескольк
о
функ-
ций
для
обработки
изображений
(обрезка
краев,
создание
миниатюр,
по-
ворот
и
т
.
д.)
и
извлечений
его
атрибутов
(размер,
тип,
разрешение).
Более
по
дробно
о
возможност
ях
расширения
мо
жно
ознакомитьс
я
на
официаль-
ной
странице
.
10.13
F
uzzystrmatc
h
F
uzzystrmatc
h
расширение
предост
авляет
нескольк
о
функций
для
опре-
деления
сх
о
дства
и
расстояния
между
строк
ами.
Функция
soundex
исполь-
зу
ется
для
согласования
с
хо
дно
звучащих
имен
путем
преобразования
их
в
одинак
овый
к
о
д.
Функция
difference
преобразует
две
строки
в
soundex
к
од,
а
затем
сообщает
к
оличество
совпадающих
позиций
ко
да.
В
soundex
к
од
состоит
из
четырех
символов,
поэтому
резу
ль
т
ат
бу
дет
от
ну
ля
до
че-
тырех:
0
—
не
совпадают
,
4
—
точное
совпадение
(таким
образом,
функция
названа
неверно
—
к
ак
название
лучше
подх
одит
similarity):
Листинг
10.82
soundex
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
f
u
z
z
y
s
t
r
m
a
t
c
h
;
-
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
-
#
S
E
L
E
C
T
s
o
u
n
d
e
x
(
’
h
e
l
l
o
w
o
r
l
d
!
’
)
;
-
s
o
u
n
d
e
x
5
-
-
-
-
-
-
-
-
-
-
H
4
6
4
-
(
1
r
o
w
)
-
-
#
S
E
L
E
C
T
s
o
u
n
d
e
x
(
’
A
n
n
e
’
)
,
s
o
u
n
d
e
x
(
’
An
n
’
)
,
d
i
f
f
e
r
e
n
c
e
(
’
A
n
ne
’
,
’
An
n
’
)
;
10
s
o
u
n
d
e
x
|
s
o
u
n
d
e
x
|
d
i
f
f
e
r
e
n
c
e
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
231
10.13.
F
uzzystrmatch
-
A
5
0
0
|
A
5
0
0
|
4
-
(
1
r
o
w
)
-
15
#
S
E
L
E
C
T
s
o
u
n
d
e
x
(
’
A
n
n
e
’
)
,
s
o
u
n
d
e
x
(
’
A
n
d
r
e
w
’
)
,
d
i
f
f
e
r
e
n
c
e
(
’
An
n
e
’
,
’
An
d
r
e
w
’
)
;
-
s
o
u
n
d
e
x
|
s
o
u
n
d
e
x
|
d
i
f
f
e
r
e
n
c
e
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
A
5
0
0
|
A
5
3
6
|
2
-
(
1
r
o
w
)
20
-
#
S
E
L
E
C
T
s
o
u
n
d
e
x
(
’
A
n
n
e
’
)
,
s
o
u
n
d
e
x
(
’
M
a
r
g
a
r
e
t
’
)
,
d
i
f
f
e
r
e
n
c
e
(
’
An
n
e
’
,
’
M
a
r
g
a
r
e
t
’
)
;
-
s
o
u
n
d
e
x
|
s
o
u
n
d
e
x
|
d
i
f
f
e
r
e
n
c
e
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
A
5
0
0
|
M626
|
0
25
(
1
r
o
w
)
-
-
#
C
R
E
A
T
E
T
A
B
L
E
s
(
n
m
t
e
x
t
)
;
-
C
R
E
A
T
E
T
A
B
L
E
-
#
IN
SE
R
T
I
NT
O
s
V
A
L
U
E
S
(
’
j
o
h
n
’
)
,
(
’
j
o
a
n
’
)
,
(
’
w
o
b
b
l
y
’
)
,
(
’
j
a
c
k
’
)
;
30
I
N
SE
RT
0
4
-
#
S
E
L
E
C
T
*
F
R
O
M
s
W
H
E
R
E
s
o
u
n
d
e
x
(
n
m
)
=
s
o
u
n
d
e
x
(
’
j
o
h
n
’
)
;
-
n
m
-
-
-
-
-
-
-
-
j
o
h
n
35
j
o
a
n
-
(
2
r
o
w
s
)
-
-
#
S
E
L
E
C
T
*
F
R
O
M
s
W
H
E
R
E
d
i
f
f
e
r
e
n
c
e
(
s
.
n
m
,
’
j
o
h
n
’
)
>
2
;
-
n
m
40
-
-
-
-
-
-
-
j
o
h
n
-
j
o
a
n
-
j
a
c
k
-
(
3
r
o
w
s
)
Функция
lev
ensh
tein
вычисляет
расстояние
Левенштейна
между
двумя
строк
ами.
lev
enshtein_less_equal
у
скор
яетс
я
функцию
levensh
tein
для
ма-
леньких
зна
чений
расстояния:
Листинг
10.83
levensh
tein
Line
1
#
S
E
L
E
C
T
l
e
v
e
n
s
h
t
e
i
n
(
’
G
U
M
B
O
’
,
’
G
A
M
B
O
L
’
)
;
-
l
e
v
e
n
s
h
t
e
i
n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2
5
(
1
r
o
w
)
232
10.13.
F
uzzystrmatch
-
-
#
S
E
L
E
C
T
l
e
v
e
n
s
h
t
e
i
n
(
’
G
U
M
B
O
’
,
’
G
A
M
B
O
L
’
,
2
,
1
,
1
)
;
-
l
e
v
e
n
s
h
t
e
i
n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
10
3
-
(
1
r
o
w
)
-
-
#
S
E
L
E
C
T
l
e
v
e
n
s
h
t
e
i
n
_
l
e
s
s
_
e
q
u
a
l
(
’
e
x
t
e
n
s
i
v
e
’
,
’
e
x
h
a
u
s
t
i
v
e
’
,
2
)
;
-
l
e
v
e
n
s
h
t
e
i
n
_
l
e
s
s
_
e
q
u
a
l
15
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
3
-
(
1
r
o
w
)
-
-
t
e
s
t
=
#
S
E
L
E
C
T
l
e
v
e
n
s
h
t
e
i
n
_
l
e
s
s
_
e
q
u
a
l
(
’
e
x
t
e
n
s
i
v
e
’
,
’
e
x
h
a
u
s
t
i
v
e
’
,
4
)
;
20
l
e
v
e
n
s
h
t
e
i
n
_
l
e
s
s
_
e
q
u
a
l
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
4
-
(
1
r
o
w
)
Функция
metaphone
,
к
ак
и
soundex,
построена
на
идее
создания
ко
да
для
строки:
две
строки,
которые
бу
дут
считатьс
я
пох
ожими,
бу
дут
иметь
о
динаковые
ко
ды.
Последним
параметром
ук
азывается
максимальная
дли-
на
metaphone
ко
да.
Функция
dmetaphone
вычисляет
два
«как
звучит»
к
ода
для
строки
—
«первичный»
и
«аль
тернативный»:
Листинг
10.84
metaphone
Line
1
#
S
E
L
E
C
T
m
e
t
a
p
h
o
n
e
(
’
G
U
M
B
O
’
,
4
)
;
-
m
e
t
a
p
h
o
n
e
-
-
-
-
-
-
-
-
-
-
-
-
-
K
M
5
(
1
r
o
w
)
-
#
S
E
L
E
C
T
d
m
e
t
a
p
h
o
n
e
(
’
p
o
s
t
g
r
e
s
q
l
’
)
;
-
d
m
e
t
a
p
h
o
n
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
P
S
T
K
10
(
1
r
o
w
)
-
-
#
S
E
L
E
C
T
d
m
e
t
a
p
h
o
n
e
_
a
l
t
(
’
p
o
s
t
g
r
e
s
q
l
’
)
;
-
d
m
e
t
a
p
h
o
n
e
_
a
l
t
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
15
P
S
T
K
-
(
1
r
o
w
)
233
10.14.
Pg_trgm
10.14
Pg_trgm
Авто
дополнение
— функция в
программах,
преду
сматривающих ин-
терактивный
ввод
текст
а
по
дополнению
текст
а
по
введённой
его
части.
Р
еализуетс
я
это
простым
LIKE
’some%’
запросом
в
базу
,
г
де
«some»
—
то,
что
пользователь
у
спел
ввести
в
поле
ввода.
Проблема
в
том,
что
в
огром-
ной
т
аблице
так
ой
запрос
бу
дет
работ
ать
очень
медленно.
Для
у
скорения
запроса типа
LIKE
’bla%’
можно
использовать
text_pattern_ops
для
text
поля
или
v
arc
har_pattern_ops
для
v
arc
har
поля
класс
операторов
в
опреде-
лении
индекса
(данные
типы
индек
сов
не
бу
дут
работ
ать
для
стандартных
операторов
<
,
<=
,
=>
,
>
и
для
работы
с
ними
придется
создать
обычный
btree
индек
с).
Листинг
10.85
text_pattern_ops
Line
1
#
c
r
e
a
t
e
t
a
b
l
e
t
a
g
s
(
-
#
t
a
g
t
e
x
t
p
r
i
m
a
r
y
k
e
y
,
-
#
n
am
e
t
e
x
t
n
o
t
n
u
l
l
,
-
#
s
h
o
r
t
n
a
m
e
t
e
x
t
,
5
#
s
t
a
t
u
s
c
h
a
r
d
e
f
a
u
l
t
’
S
’
,
-
#
-
#
c
h
e
c
k
(
s
t
a
t
u
s
i
n
(
’
S
’
,
’
R
’
)
)
-
#
)
;
-
N
O
T
I
C
E
:
C
R
E
A
T
E
T
A
B
L
E
/
P
R
I
M
A
R
Y
K
E
Y
w
i
l
l
c
r
e
a
t
e
i
m
p
l
i
c
i
t
i
n
d
e
x
"
t
a
g
s
_
p
k
e
y
"
f
o
r
t
a
b
l
e
"
t
a
g
s
"
10
C
R
E
A
T
E
T
A
B
L
E
-
-
#
C
R
E
A
T
E
I
N
D
E
X
i
_
t
a
g
O
N
t
a
g
s
U
S
IN
G
b
t
r
e
e
(
l
o
w
e
r
(
t
a
g
)
t
e
x
t
_
p
a
t
t
e
r
n
_
o
p
s
)
;
-
C
R
E
A
T
E
I
N
D
E
X
-
15
#
E
X
P
L
A
I
N
A
N
A
L
Y
Z
E
s
e
l
e
c
t
*
f
r
o
m
t
a
g
s
w
h
e
r
e
l
o
w
e
r
(
t
a
g
)
LIKE
l
o
w
e
r
(
’
0
1
4
6
%
’
)
;
-
Q
U
E
R
Y
P
L
A
N
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
B
i
t
m
a
p
He
a
p
S
c
a
n
o
n
t
a
g
s
(
c
o
s
t
=
5
.
4
9
.
.
9
7
.
7
5
r
o
w
s
=
1
2
1
w
i
d
t
h
=
2
6
)
(
a
c
t
u
a
l
t
i
m
e
=
0
.
0
2
5
.
.
0
.
0
2
5
r
o
w
s
=1
l
o
o
p
s
=
1
)
-
F
i
l
t
e
r
:
(
l
o
w
e
r
(
t
a
g
)
~~
’
01
4
6
%
’
:
:
t
e
x
t
)
20
-
>
B
i
t
m
a
p
I
n
d
e
x
S
c
a
n
o
n
i
_
t
a
g
(
c
o
s
t
=
0
.
0
0
.
.
5
.
4
6
r
o
w
s
=
1
2
0
w
i
d
t
h
=
0
)
(
a
c
t
u
a
l
t
i
m
e
=
0
.
0
1
6
.
.
0
.
0
1
6
r
o
w
s
=1
l
o
o
p
s
=
1
)
-
I
n
d
e
x
Co
nd
:
(
(
l
o
w
e
r
(
t
a
g
)
~
>
=
~
’
0
1
4
6
’
:
:
t
e
x
t
)
A
N
D
(
l
o
w
e
r
(
t
a
g
)
~
<
~
’
0
1
4
7
’
:
:
t
e
x
t
)
)
-
T
o
t
a
l
r
u
n
t
i
m
e
:
0
.
0
5
0
ms
-
(
5
r
o
w
s
)
234
10.14.
Pg_trgm
Для
более
сло
жных
вариантов
поиск
а,
таких
к
ак
LIKE
’%some%’
или
LIKE
’so%me%’
т
ак
ой
индекс
не
бу
дет
работать,
но
эту
проблему
можно
решить
через
расширение.
Pg_trgm
—
P
ostgreSQL
расширение,
которое
предоставляет
функции
и
операторы
для
определения
с
хо
ж
ести
алфавитно-цифровых
строк
на
ос-
нове
триграмм,
а
такж
е
классы
операторов
индек
сов,
поддер
живающие
быстрый поиск
сх
ожих строк.
Триграмма
—
это
группа
трёх последо-
вательных
символов,
взятых
из
строки.
Мо
жно
измерить
с
хо
жесть
двух
строк,
по
дсчит
ав
число
триграмм,
которые
есть
в
обеих.
Эт
а
простая
идея
ок
азывается
очень
эффективной
для
измерения
сх
о
жести
слов
на
многих
естественных
языках.
Моду
ль
pg_trgm
предост
авляет
классы
операторов
индек
сов
GiST
и
GIN,
позволяющие
создавать
индекс
по
тек
стовым
колон-
к
ам
для
очень
быстрого
поиск
а
по
критерию
с
хо
жести.
Эти
типы
индекс
ов
по
ддерживают
%
и
<->
операторы
сх
ож
ести
и
дополнительно
поддер
жи-
вают
поиск
на
основе
триграмм
для
запросов
с
LIKE
,
ILIKE
,
~
и
~*
(эти
индек
сы
не
по
ддер
живают
простые
операторы
сравнения
и
равенства,
так
что
мо
жет
понадобиться
и
обычный
btree
индекс).
Листинг
10.86
pg_trgm
Line
1
#
C
R
E
A
T
E
T
A
B
L
E
t
e
s
t
_
t
r
g
m
(
t
t
e
x
t
)
;
-
#
C
R
E
A
T
E
I
N
D
E
X
t
r
g
m
_
i
d
x
O
N
t
e
s
t
_
t
r
g
m
U
SI
N
G
g
i
s
t
(
t
g
i
s
t
_
t
r
g
m
_
o
p
s
)
;
-
-
-
o
r
-
#
C
R
E
A
T
E
I
N
D
E
X
t
r
g
m
_
i
d
x
O
N
t
e
s
t
_
t
r
g
m
U
SI
N
G
g
i
n
(
t
g
i
n
_
t
r
g
m
_
o
p
s
)
;
После
создания
GIST
или
GIN
индекса
по
колонк
е
t
мо
жно
осуществ-
лять
поиск
по
с
хо
жести.
Пример
запроса:
Листинг
10.87
pg_trgm
Line
1
S
E
L
E
C
T
t
,
s
i
m
i
l
a
r
i
t
y
(
t
,
’
w
o
r
d
’
)
A
S
s
m
l
-
F
R
O
M
t
e
s
t
_
t
r
g
m
-
W
H
E
R
E
t
%
’
w
o
r
d
’
-
O
R
D
E
R
B
Y
s
m
l
D
E
S
C
,
t
;
Он
выдаст
все
значения
в
тек
стовой
к
олонке,
которые
дост
аточно
с
хо-
жи
со
словом
w
ord
,
в
порядк
е
сортировки
от
наиболее
к
наименее
сх
о
жим.
Другой
вариант
предыдущего
запроса
(мо
жет
быть
довольно
эффективно
выполнен
с
применением
индек
сов
GiST,
а
не
GIN):
Листинг
10.88
pg_trgm
Line
1
S
E
L
E
C
T
t
,
t
<
->
’
w
o
r
d
’
AS
d
i
s
t
-
F
R
O
M
t
e
s
t
_
t
r
g
m
-
O
R
D
E
R
B
Y
d
i
s
t
LI
MIT
1
0
;
235
10.15.
Cstore_fdw
На
чиная с
P
ostgreSQL
9.1,
эти
типы
индексов
т
акж
е по
ддерживают
поиск
с
операторами
LIKE
и
ILIKE
,
например:
Листинг
10.89
pg_trgm
Line
1
S
E
L
E
C
T
*
F
R
O
M
t
e
s
t
_
t
r
g
m
W
H
E
R
E
t
LIKE
’%f
o
o
%
b
a
r
’
;
На
чиная
с
P
ostgreSQL
9.3,
индек
сы
этих
типов
такж
е
поддер
живают
поиск
по
регу
лярным
выражениям
(операторы
~
и
~*
),
например:
Листинг
10.90
pg_trgm
Line
1
S
E
L
E
C
T
*
F
R
O
M
t
e
s
t
_
t
r
g
m
W
H
E
R
E
t
~
’
(
f
o
o
|
b
a
r
)
’
;
Относительно
поиск
а
по
регу
лярному
выражению
или
с
LIKE
,
нужно
принимать
в
расчет
,
что
при
отсутствии
триграмм
в
искомом
шаблоне
по-
иск
сводитс
я
к
полному
ск
анирования
индек
са.
Выбор
между
индек
сами
GiST
и
GIN
зависит
от
относительных
характеристик
произво
дительности
GiST
и
GIN,
к
оторые
здесь
не
рассматриваются.
Как
правило,
индекс
GIN
быстрее
индекса
GiST
при
поиске,
но
строится
или
обновляетс
я
он
мед-
леннее;
поэтому
GIN
лучше
по
дх
одит
для
ст
атических,
а
GiST
для
часто
изменяемых
данных.
10.15
Cstore_fdw
Cstore_fdw
расширение
реализует
модель
хранения
данных
на
базе
се-
мейства
столбцов
(column-oriented
systems)
для
P
ostgreSQL
(колоночное
хранение данных).
Т
ак
ое хранение данных
обеспечивает заметные
пре-
имущества
для
аналитических
зада
ч
(
OLAP
,
data
w
arehouse
),
поскольку
требу
ется считывать
меньше данных с
диск
а (благо
дар
я формату хра-
нения и к
омпрессии). Р
асширение использует
Optimized Ro
w Columnar
(OR
C)
формат
для
размещения
данных
на
диск
е,
который
имеет
следую-
щие
преимущества:
∙
Уменьшение
(с
жатие)
размера
данных
в
памяти
и
на
диск
е
в
2-4
раза.
Мо
жно
добавить
в
расширение
другой
ко
дек
для
сж
атия
(алгоритм
Лемпеля-Зива,
LZ
присутству
ет
в
расширении);
∙
Считывание
с
диска
тольк
о
тех
данных,
к
оторые
требуютс
я.
Повы-
шаетс
я
производительность
по
I/O
диска
для
других
запросов;
∙
Хранение
минимального/максимального
значений
для
групп
полей
(skip
index,
индекс
с
пропуск
ами),
что
помогает
пропустить
не
тре-
бу
емые
данные
на
диске
при
выборке;
236
10.15.
Cstore_fdw
У
становк
а
и
использование
Для
работы
cstore_fdw
требуетс
я
protobuf-c
для
сериализации
и
десери-
ализации
данных.
Далее
требуетс
я
добавить
в
p
ostgresql
.
conf
расширение:
Листинг
10.91
Cstore_fdw
Line
1
s
h
a
r
e
d
_
p
r
e
l
o
a
d
_
l
i
b
r
a
r
i
e
s
=
’
c
s
t
o
r
e
_
f
d
w
’
И
активировать
его
для
базы:
Листинг
10.92
Cstore_fdw
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
c
s
t
o
r
e
_
f
d
w
;
Для
загрузки
данных
в
cstore
т
аблицы
существует
два
варианта:
∙
Использование
команды
COPY
для
загрузки
или
добавления
данных
из
файлов
или
STDIN;
∙
Использование
конструкции
INSER
T
INTO
cstore_table
SELECT
...
для
загрузки
или
добавления
данных
из
другой
т
аблицы;
Cstore
т
аблицы
не
по
ддер
живают
INSER
T
(кроме
выше
упомянутого
INSER
T
INTO
...
SELECT
),
UPDA
TE
или
DELETE
к
оманды.
Для
примера
загрузим
тестовые
данные:
Листинг
10.93
Cstore_fdw
Line
1
$
w
g
e
t
h
t
t
p
:
/
/
e
x
a
m
p
l
e
s
.
c
i
t
u
s
d
a
t
a
.
com
/
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
_
1
9
9
8
.
c
s
v
.
g
z
-
$
w
g
e
t
h
t
t
p
:
/
/
e
x
a
m
p
l
e
s
.
c
i
t
u
s
d
a
t
a
.
com
/
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
_
1
9
9
9
.
c
s
v
.
g
z
-
-
$
g
z
i
p
-
d
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
_
1
9
9
8
.
c
s
v
.
g
z
5
$
g
z
i
p
-
d
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
_
1
9
9
9
.
c
s
v
.
g
z
Далее
загрузим
эти
данные
в
cstore
таблицу
(расширение
уж
е
активи-
ровано
для
P
ostgreSQL):
Листинг
10.94
Cstore
таблицы
Line
1
-
-
c
r
e
a
t
e
s
e
r
v
e
r
o
b
j
e
c
t
-
C
R
E
A
T
E
S
E
R
V
E
R
c
s
t
o
r
e
_
s
e
r
v
e
r
F
O
R
E
I
G
N
D
A
T
A
W
R
A
P
P
E
R
c
s
t
o
r
e
_
f
d
w
;
-
-
-
-
c
r
e
a
t
e
f
o
r
e
i
g
n
t
a
b
l
e
5
C
R
E
A
T
E
F
O
R
E
I
G
N
T
A
B
L
E
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
-
(
-
c
u
s
t
o
m
e
r
_
i
d
T
E
X
T,
237
10.15.
Cstore_fdw
-
r
e
v
i
e
w
_
d
a
t
e
D
A
T
E
,
-
r
e
v
i
e
w
_
r
a
t
i
n
g
I
N
T
E
G
E
R
,
10
r
e
v
i
e
w
_
v
o
t
e
s
I
N
T
E
G
E
R
,
-
r
e
v
i
e
w
_
h
e
l
p
f
u
l
_
v
o
t
e
s
I
N
T
E
G
E
R
,
-
p
r
o
d
u
c
t
_
i
d
C
H
A
R
(
1
0
)
,
-
p
r
o
d
u
c
t
_
t
i
t
l
e
T
E
X
T,
-
p
r
o
d
u
c
t
_
s
a
l
e
s
_
r
a
n
k
BIG
INT
,
15
p
r
o
d
u
c
t
_
g
r
o
u
p
T
E
X
T,
-
p
r
o
d
u
c
t
_
c
a
t
e
g
o
r
y
T
E
X
T,
-
p
r
o
d
u
c
t
_
s
u
b
c
a
t
e
g
o
r
y
T
E
X
T,
-
s
i
m
i
l
a
r
_
p
r
o
d
u
c
t
_
i
d
s
C
H
A
R
(
1
0
)
[
]
-
)
20
S
E
R
V
E
R
c
s
t
o
r
e
_
s
e
r
v
e
r
-
O
P
T
I
O
N
S
(
c
o
m
p
r
e
s
s
i
o
n
’
p
g
l
z
’
)
;
-
-
C
O
P
Y
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
F
R
O
M
’
/
tmp
/
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
_
1
9
9
8
.
c
s
v
’
W
I
T
H
C
S
V
;
-
C
O
P
Y
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
F
R
O
M
’
/
tmp
/
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
_
1
9
9
9
.
c
s
v
’
W
I
T
H
C
S
V
;
25
-
A
N
A
L
Y
Z
E
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
;
После
этого
мо
жно
проверить
как
работает
расширение:
Листинг
10.95
Cstore
запросы
Line
1
-
-
F
i
n
d
a
l
l
r
e
v
i
e
w
s
a
p
a
r
t
i
c
u
l
a
r
c
u
s
t
o
m
e
r
ma
de
o
n
t
h
e
Du
n
e
s
e
r
i
e
s
i
n
1
9
9
8
.
-
#
S
E
L
E
C
T
-
c
u
s
t
o
m
e
r
_
i
d
,
r
e
v
i
e
w
_
d
a
t
e
,
r
e
v
i
e
w
_
r
a
t
i
n
g
,
p
r
o
d
u
c
t
_
i
d
,
p
r
o
d
u
c
t
_
t
i
t
l
e
-
F
R
O
M
5
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
-
W
H
E
R
E
-
c
u
s
t
o
m
e
r
_
i
d
=
’
A
2
7
T
7
H
V
D
X
A
3
K
2
A
’
A
N
D
-
p
r
o
d
u
c
t
_
t
i
t
l
e
LIKE
’%
D
un
e
%
’
A
N
D
-
r
e
v
i
e
w
_
d
a
t
e
>
=
’
1
9
9
8
-
0
1
-
0
1
’
A
N
D
10
r
e
v
i
e
w
_
d
a
t
e
<
=
’
1
9
9
8
-
1
2
-
3
1
’
;
-
c
u
s
t
o
m
e
r
_
i
d
|
r
e
v
i
e
w
_
d
a
t
e
|
r
e
v
i
e
w
_
r
a
t
i
n
g
|
p
r
o
d
u
c
t
_
i
d
|
p
r
o
d
u
c
t
_
t
i
t
l
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
A
2
7
T
7
H
V
D
X
A
3
K
2
A
|
1
9
9
8
-
0
4
-
1
0
|
5
|
0
3
9
9
1
2
8
9
6
4
|
Du
n
e
(
D
u
ne
C
h
r
o
n
i
c
l
e
s
(
E
c
o
n
o
-
C
l
a
d
H
a
r
d
c
o
v
e
r
)
)
-
A
2
7
T
7
H
V
D
X
A
3
K
2
A
|
1
9
9
8
-
0
4
-
1
0
|
5
|
0
4
4
1
0
0
5
9
0X
|
Du
n
e
238
10.16.
Postgresql-hll
15
A
2
7
T
7
H
V
D
X
A
3
K
2
A
|
1
9
9
8
-
0
4
-
1
0
|
5
|
0
4
4
1
1
7
2
7
1
7
|
Du
n
e
(
D
u
ne
C
h
r
o
n
i
c
l
e
s
,
B
o
o
k
1
)
-
A
2
7
T
7
H
V
D
X
A
3
K
2
A
|
1
9
9
8
-
0
4
-
1
0
|
5
|
0
8
8
1
0
3
6
3
6
6
|
Du
n
e
(
D
u
ne
C
h
r
o
n
i
c
l
e
s
(
E
c
o
n
o
-
C
l
a
d
H
a
r
d
c
o
v
e
r
)
)
-
A
2
7
T
7
H
V
D
X
A
3
K
2
A
|
1
9
9
8
-
0
4
-
1
0
|
5
|
1
5
5
9
9
4
9
5
7
0
|
Du
n
e
A
u
d
i
o
C
o
l
l
e
c
t
i
o
n
-
(
5
r
o
w
s
)
-
20
T
i
m
e
:
2
3
8
.
6
2
6
ms
-
-
-
-
D
o
we
h
a
v
e
a
c
o
r
r
e
l
a
t
i
o
n
b
e
t
w
e
e
n
a
b
o
o
k
’
s
t
i
t
l
e ’
s
l
e
n
g
t
h
a
n
d
i
t
s
r
e
v
i
e
w
r
a
t
i
n
g
s
?
-
#
S
E
L
E
C
T
-
w
i
d
t
h
_
b
u
c
k
e
t
(
l
e
n
g
t
h
(
p
r
o
d
u
c
t
_
t
i
t
l
e
)
,
1
,
5
0
,
5
)
t
i
t
l
e
_
l
e
n
g
t
h
_
b
u
c
k
e
t
,
25
r
o
u
n
d
(
a
v
g
(
r
e
v
i
e
w
_
r
a
t
i
n
g
)
,
2
)
A
S
r
e
v
i
e
w
_
a
v
e
r
a
g
e
,
-
c
o
u
n
t
(
*
)
-
F
R
O
M
-
c
u
s
t
o
m
e
r
_
r
e
v
i
e
w
s
-
W
H
E
R
E
30
p
r
o
d
u
c
t
_
g
r
o
u
p
=
’
B
o
o
k
’
-
G
R
O
U
P
B
Y
-
t
i
t
l
e
_
l
e
n
g
t
h
_
b
u
c
k
e
t
-
O
R
D
E
R
B
Y
-
t
i
t
l
e
_
l
e
n
g
t
h
_
b
u
c
k
e
t
;
35
t
i
t
l
e
_
l
e
n
g
t
h
_
b
u
c
k
e
t
|
r
e
v
i
e
w
_
a
v
e
r
a
g
e
|
c
o
u
n
t
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
1
|
4
.
2
6
|
1
3
9
0
3
4
-
2
|
4
.
2
4
|
4
1
1
3
1
8
-
3
|
4
.
3
4
|
2
4
5
6
7
1
40
4
|
4
.
3
2
|
1
6
7
3
6
1
-
5
|
4
.
3
0
|
1
1
8
4
2
2
-
6
|
4
.
4
0
|
1
1
6
4
1
2
-
(
6
r
o
w
s
)
-
45
T
i
m
e
:
1
2
8
5
.
0
5
9
ms
Заключение
Более
подробно
об
использовании
расширения
мо
жно
ознакомитьс
я
че-
рез
официальную
документ
ацию
.
10.16
P
ostgresql-hll
На
сегодняшний
день
широко
распространена
задача
по
дсчета
к
оличе-
ства
уник
альных
элементов
(coun
t-distinct
problem)
в
потоке
данных,
кото-
239
10.16.
Postgresql-hll
рые
могут
содер
ж
ать
повтор
яющиес
я
элементы.
Например,
скольк
о
уни-
к
альных
IP-адресов
по
дключалось
к
серверу
за
последний
час?
Скольк
о
различных
слов
в
большом
куск
е
тек
стов?
Как
ое
к
оличество
уник
альных
посетителей
побывало
на попу
лярном сайте
за день?
Скольк
о
уник
аль-
ных
URL
было
запрошено через
прокси-сервер?
Данную
задачу
можно
решить
«в
лоб»:
пройтись
по
всем
элемент
ам
и
убрать
дублик
аты,
после
этого
посчит
ать
их
к
оличество
(например
использовать
мно
жество,
set).
Тру
дности
в
так
ом
подх
о
де
возник
ают
при
увеличении
масшт
аба.
С
мини-
мальными
затратами
мо
жно
по
дсчитать
тыс
ячу
или
даже
миллион
уни-
к
альных
посетителей,
IP-адресов,
URL
или
слов.
А
что
если
речь
идет
о
100
миллионах
уникальных
элементов
на
один
сервер
при
наличии
тыс
яч
серверов?
Т
еперь
это
уж
е
становитс
я
интересным.
Т
екущее
решение
проблемы
бу
дет
выглядеть
так:
необх
одимо
сформи-
ровать
множ
ества
(set)
уник
альных
элементов
для
каждого
из
1000
серве-
ров,
каждое
из
к
оторых
мож
ет
со
дер
жать
около
100
миллионов
уникаль-
ных
элементов,
а
затем
по
дсчитать
количество
уникальных
элементов
в
объединении
этих
множ
еств.
Другими
словами,
мы
имеем
дело
с
распре-
деленным вариантом
зада
чи по
дсчета
уник
альных элементов.
Хоть
это
решение
являетс
я
вполне
логичным,
на
практик
е
этот
по
дх
од
обойдется
высок
ой
ценой.
Для
примера
возьмем
URL,
средняя
длина
к
оторого
со-
ст
авляет 76
символов. В
нашем случае
один
сервер
обслуживает
ок
оло
100
миллионов
уникальных
URL,
следовательно,
размер
файла
с
их
пе-
речнем
сост
авит
ок
оло
7.6
ГБ.
Даже
если
к
аждый
URL
преобразовать
в
64-битный
х
еш,
размер
файла
сост
авит
800
МБ.
Это
намного
лучше,
но
не
забывайте,
что
речь
идет
о
1000
серверов.
Каждый
сервер
отправляет
файл
с
перечнем
уник
альных
URL
на
центральный
сервер,
следовательно,
при
наличии
1000
серверов
функция
объединения
мно
ж
еств
должна
обра-
бот
ать
800
ГБ
данных.
Если
так
ая
операция
должна
выполняться
часто,
тог
да
необх
о
димо
бу
дет
либо
уст
ановить
систему
для
обработки
больших
данных
(и
нанять
к
оманду
для
ее
обслуживания),
либо
найти
другое
ре-
шение.
И
вот
на
сцену
вых
одит
Hyp
erLogLog
алгоритм.
Этот
алгоритм
реа-
лизу
ет
веро
ятностный
подх
о
д
к
задаче
подсчет
а
уникальных
элементов
и
базиру
ется
на
двух
следующих
полож
ениях:
∙
веро
ятность
того,
что
любой
данный
бит
двоичного
представления
случайного
числа
равен
единице,
сост
авляет
50%;
∙
веро
ятность
того,
что
совместно
произойдут
два
независимых
слу-
чайных
события
𝐴
и
𝐵
,
вычисляетс
я
по
форму
ле
𝑃
(
𝐴
)
*
𝑃
(
𝐵
)
.
Т
а-
ким
образом,
если
вероятность
равенства
единице
одного
любого
би-
т
а
случайного
числа
сост
авляет
50%,
тог
да
веро
ятность
равенства
единице
двух
любых
битов
сост
авляет
25%,
трех
—
12,5%
и
т
.д;
Вспомним
еще
одно
базовое
поло
ж
ение
теории
вероятностей,
согласно
к
оторому
ожидаемое
количество
испытаний,
необх
о
димое
для
наступле-
240
10.16.
Postgresql-hll
ния
события,
вычисляется
по
форму
ле
1
/𝑃
(
𝑒𝑣
𝑒𝑛𝑡
)
.
Следовательно,
если
𝑃
(
𝑜𝑛𝑒
𝑠𝑝𝑒𝑐𝑖𝑓
𝑖𝑐
𝑏𝑖𝑡
𝑠𝑒𝑡
)
=
50%
,
то
ожидаемое
к
оличество
испыт
аний
равно
2.
Для
двух
битов
—
4,
для
трех
битов
—
8
и
т
.
д.
В
общем
случае
вхо
дные
значения
не
являются
равномерно
распреде-
ленными
случайными
числами,
поэтому
необх
о
дим
способ
преобразования
вх
одных
зна
чений
к
равномерному
распределению,
т
.
е.
необ
хо
дима
хеш-
функция.
Обратите
внимание,
в
некоторых
случаях
распределение,
полу-
чаемое
на
вых
о
де
хеш-функции,
не
оказывает
существенное
влияние
на
точность
системы.
Однако
Hyp
erLogLog
очень
чувствителен
в
этом
отно-
шении.
Если
выхо
д
х
еш-функции
не
соответствует
равномерному
распре-
делению,
алгоритм
теряет
точность,
поскольку
не
выполняютс
я
базовые
допущения,
леж
ащие
в
его
основе.
Р
ассмотрим
алгоритм
подробно.
Вна
чале
необ
х
одимо
х
ешировать
все
элементы
исследуемого
набора.
Затем
нужно
подсчит
ать
количество
по-
следовательных
начальных
битов,
равных
единице,
в
двоичном
представ-
лении
к
аждого
хеша
и
определить
максимальное
зна
чение
этого
количе-
ства
среди
всех
хешей.
Если
максимальное
количество
единиц
обозначить
𝑛
,
тогда
количество
уникальных
элементов
в
наборе
мо
жно
оценить,
к
ак
2
𝑛
.
Т
о
есть,
если
мак
симум
один
начальный
бит
равен
единице,
тогда
к
о-
личество
уник
альных
элементов,
в
среднем,
равно
2;
если
мак
симум
три
на
чальных
бит
а
равны
единице,
в
среднем,
мы
мо
жем
ожидать
8
уникаль-
ных
элементов
и
т
.
д.
По
дхо
д,
направленный
на
повышение
точности
оценки
и
являющийся
о
дной из
ключевых идей
Hyp
erLogLog,
заключаетс
я
в
следующем:
раз-
деляем
хеши
на
подгруппы
на
основании
их
к
онечных
битов,
определя-
ем
мак
симальное
к
оличество
на
чальных
единиц
в
каждой
по
дгруппе,
а
затем
нах
одим
среднее.
Этот
подх
од
позволяет
получить
намного
более
точную
оценку
общего
количества
уникальных
элементов.
Если
мы
име-
ем
𝑚
по
дгрупп
и
𝑛
уник
альных
элементов,
тог
да,
в
среднем,
в
к
аждой
по
дгруппе
бу
дет
𝑛/𝑚
уникальных
элементов.
Т
аким
образом,
нах
ождение
среднего
по
всем
по
дгруппам
дает
достаточно
точную
оценку
величины
𝑙
𝑜𝑔
2
(
𝑛/𝑚
)
,
а
отсю
да
легко
можно
получить
необх
о
димое
нам
значение.
Бо-
лее
того,
Hyp
erLogLog
позволяет
обрабатывать
по
отдельности
различные
варианты
группировок,
а
затем
на
основе
этих
данных
нахо
дить
итоговую
оценку
.
Следу
ет
отметить,
что
для
нах
ождения
среднего
Hyp
erLogLog
ис-
пользу
ет
среднее
г
армоническое,
к
оторое
обеспечивает
лучшие
резу
ль
т
аты
по
сравнению
со
средним
арифметическим (более
по
дробную информа-
цию
можно
найти
в
оригинальных
публик
ациях,
посвященных
LogLog
и
Hyp
erLogLog
).
Вернемс
я
к
зада
че.
По
условию
существуе
т
1000
серверов
и
100
миллио-
нов
уникальных
URL
на
к
аждый
сервер,
следовательно,
центральный
сер-
вер
долж
ен
обрабатывать
800
ГБ
данных
при
каждом
выполнении
просто-
го
вариант
а
алгоритма.
Это
такж
е
означает
,
что
800
ГБ
данных
каждый
раз
необ
хо
димо
передавать
по
сети.
Hyp
erLogLog
меняет
ситу
ацию
кар
ди-
241
10.16.
Postgresql-hll
нально.
Согласно
анализу
,
проведенному
авторами
оригинальной
публи-
к
ации,
Hyp
erLogLog
обеспечивает
точность
ок
оло
98%
при
использовании
всего
1.5
КБ
памяти.
Каждый
сервер
формирует
соответствующий
файл
размером
1.5
КБ,
а
затем
отправляет
его
на
центральный
сервер.
При
наличии
1000
серверов,
центральный
сервер
обрабатывает
всего
1.5
МБ
данных
при
каждом
выполнении
алгоритма.
Другими
словами,
обрабаты-
ваетс
я
ли
шь
0.0002%
данных
по
сравнению
с
предыдущим
решением.
Это
полностью
меняет
экономический
аспект
задачи.
Благо
дар
я
Hyp
erLogLog,
возмо
жно
выполнять
т
акие
операции
чаще
и
в
большем
к
оличестве.
И
все
это
ценой
всего
лишь
2%
погрешности.
Для
работы
с
этим
алгоритмом
внутри
P
ostgreSQL
было
создано
рас-
ширение
p
ostgresql-hll
.
Оно
добавляет
новый
тип
поля
hll
,
который
пред-
ст
авляет
собой
Hyp
erLogLog
структуру
данных.
Р
ассмотрим
пример
его
использования.
У
становк
а
и
использование
Для
на
чала
инициализируем
расширение
в
базе
данных:
Листинг
10.96
Инициализация
hll
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
h
l
l
;
Давайте
предположим,
что
есть
т
аблица
users_visits
,
к
оторая
записы-
вает
визиты
пользователей
на
сайт
,
что
они
сделали
и
отку
да
они
пришли.
В
т
аблице
сотни
миллионов
строк.
Листинг
10.97
users_visits
Line
1
C
R
E
A
T
E
T
A
B
L
E
u
s
e
r
s
_
v
i
s
i
t
s
(
-
d
a
t
e
d
a
t
e
,
-
u
s
e
r
_
i
d
i
n
t
e
g
e
r
,
-
a
c
t
i
v
i
t
y
_
t
y
p
e
s
m
a
l
l
i
n
t
,
5
r
e
f
e
r
r
e
r
v
a
r
c
h
a
r
(
2
5
5
)
-
)
;
Требу
ется
получать
очень
быстро
представление
о
том,
скольк
о
уни-
к
альных
пользователей
посещают
сайт
в
день
на
админ
панели.
Для
этого
создадим
агрег
атную
таблицу:
Листинг
10.98
daily_uniques
Line
1
C
R
E
A
T
E
T
A
B
L
E
d
a
i
l
y
_
u
n
i
q
u
e
s
(
-
d
a
t
e
d
a
t
e
U
N
I
Q
U
E
,
-
u
s
e
r
s
h
l
l
-
)
;
5
242
10.16.
Postgresql-hll
-
-
-
F
i
l
l
i
t
w
i
t
h
t
h
e
a
g
g
r
e
g
a
t
e
d
u
n
i
q
u
e
s
t
a
t
i
s
t
i
c
s
-
I
N
SE
RT I
NT
O
d
a
i
l
y
_
u
n
i
q
u
e
s
(
d
a
t
e
,
u
s
e
r
s
)
-
S
E
L
E
C
T
d
a
t
e
,
h
l
l
_
a
d
d
_
a
g
g
(
h
l
l
_
h
a
s
h
_
i
n
t
e
g
e
r
(
u
s
e
r
_
i
d
)
)
-
F
R
O
M
u
s
e
r
s
_
v
i
s
i
t
s
10
G
R
O
U
P
B
Y
1
;
Далее
хэшируетс
я
user_id
и
собираютс
я
эти
хэш-зна
чения
в
один
hll
за
день.
Т
еперь
мо
жно
запросить
информацию
по
уник
альным
пользовате-
лям
за
к
аждый
день:
Листинг
10.99
daily_uniques
по
дням
Line
1
#
S
E
L
E
C
T
d
a
t
e
,
h
l
l
_
c
a
r
d
i
n
a
l
i
t
y
(
u
s
e
r
s
)
F
R
O
M
d
a
i
l
y
_
u
n
i
q
u
e
s
;
-
d
a
t
e
|
h
l
l
_
c
a
r
d
i
n
a
l
i
t
y
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2
0
1
7
-
0
2
-
2
1
|
2
3
1
2
3
5
2
0
1
7
-
0
2
-
2
2
|
5
9
4
3
3
-
2
0
1
7
-
0
2
-
2
3
|
2
1
3
4
8
9
0
-
2
0
1
7
-
0
2
-
2
4
|
3
2
7
6
2
4
7
-
(
4
r
o
w
s
)
Мо
жно
возразить,
что
такую
задачу
можно
решить
и
через
COUNT
DISTINCT
и
это
бу
дет
верно.
Но
в
примере
только
ответили
на
вопрос:
«Ск
олько уник
альных пользователей посещает сайт
к
аждый
день?»
. А
что, если
требу
ется знать
ск
олько
уник
альных пользователей посетили
сайт
за
неделю?
Листинг
10.100
daily_uniques
за
неделю
Line
1
S
E
L
E
C
T
h
l
l
_
c
a
r
d
i
n
a
l
i
t
y
(
h
l
l
_
u
n
i
o
n
_
a
g
g
(
u
s
e
r
s
)
)
F
R
O
M
d
a
i
l
y
_
u
n
i
q
u
e
s
W
H
E
R
E
d
a
t
e
>
=
’
2
0
1
7
-
0
2
-
2
0
’
:
:
d
a
t
e
A
N
D
d
a
t
e
<
=
’
2
0
1
7
-
0
2
-
2
6
’
:
:
d
a
t
e
;
Или
выбрать
уникальных
пользователей
за
каждый
месяц
в
течение
го
да?
Листинг
10.101
daily_uniques
за
каждый
месяц
Line
1
S
E
L
E
C
T
E
X
T
R
A
C
T
(
M
O
N
T
H
F
R
O
M
d
a
t
e
)
AS
m
o
n
t
h
,
h
l
l
_
c
a
r
d
i
n
a
l
i
t
y
(
h
l
l
_
u
n
i
o
n
_
a
g
g
(
u
s
e
r
s
)
)
-
F
R
O
M
d
a
i
l
y
_
u
n
i
q
u
e
s
-
W
H
E
R
E
d
a
t
e
>
=
’
2
0
1
6
-
0
1
-
0
1
’
A
N
D
-
d
a
t
e
<
’
2
0
1
7
-
0
1
-
0
1
’
5
G
R
O
U
P
B
Y
1
;
Или
узнать
к
оличество
пользователей,
что
посетили
сайт
вчера,
но
не
сего
дня?
243
10.17.
T
search2
Листинг
10.102
daily_uniques
за
вчера
но
не
сегодня
Line
1
S
E
L
E
C
T
d
a
t
e
,
(#
h
l
l
_
u
n
i
o
n
_
a
g
g
(
u
s
e
r
s
)
O
V
E
R
t
w
o
_
d
a
y
s
)
-
#u
s
e
r
s
A
S
l
o
s
t
_
u
n
i
q
u
e
s
-
F
R
O
M
d
a
i
l
y
_
u
n
i
q
u
e
s
-
W
I
N
D
O
W t
w
o
_
d
a
y
s
A
S
(
O
R
D
E
R
B
Y
d
a
t
e
A
S
C
R
O
W
S
1
P
R
E
C
E
D
I
N
G
)
;
Это
всего
пара
примеров
типов
запросов,
которые
бу
дут
возвращать
резу
ль
тат
в
течение
миллисекунд
благо
даря
hll
,
но
потребует
либо
пол-
ностью
от
дельные
предварительно
созданные
агрегирующие
таблицы
или
self
join
/generate_series
фокусы
в
COUNT
DISTINCT
мире.
Заключение
Более
подробно
об
использовании
расширения
мо
жно
ознакомитьс
я
че-
рез
официальную
документ
ацию
.
10.17
T
searc
h2
Как
и
многие
современные
СУБД,
PostgreSQL
имеет
встроенный
ме-
х
анизм
полнотекстового
поиска.
Отметим,
что
операторы
поиска
по
тек-
стовым
данных
существовали
очень
давно,
это
операторы
LIKE
,
ILIKE
,
~
,
~*
.
Однак
о,
они
не
го
дились
для
эффективного
полнотекстового
поиск
а,
т
ак
как:
∙
У
них
не
было
лингвистической
поддер
жки,
например,
при
поиске
слова
satisfies
бу
дут
не
найдены
документы
со
словом
satisfy
и
ни-
к
акими
регу
лярными
выраж
ениями
этому
не
помочь.
В
принципе,
использу
я
OR
и
все
формы
слова,
можно
найти
все
необ
хо
димые
до-
кументы,
но
это
очень
неэффективно,
т
ак
к
ак
в
некоторых
язык
ах
могут
быть
слова
со
многими
тыс
ячами
форм!;
∙
Они
не
предоставляют
никак
ой
информации
для
ранжирования
(сор-
тировки)
документов,
что
делает
т
акой
поиск
практически
бесполез-
ным, если тольк
о не существу
ет другой сортировки или в
случае
малого
к
оличества
найденных
документов;
∙
Они,
в
целом,
очень
медленные
из-за
того,
что
они
к
аждый
раз
про-
сматривают
весь
документ
и
не
имеют
индек
сной
поддер
жки;
Для
у
лучшения
ситуации
Олег
Бартунов
и
Федор
Сигаев
предло
жили
и
реализовали
новый
полнотек
стовый
поиск,
существовавший
к
ак
мо
ду
ль
расширения и интегрированный в P
ostgreSQL, на
чиная с версии 8.3 —
T
searc
h2
.
Идея
нового
поиска
состояла
в
том,
чтобы
затратить
время
на
обработ-
ку
документа
один
раз
и
сохранить
время
при
поиск
е,
использовать
специ-
альные
программы-словари
для
нормализации
слов,
чтобы
не
заботиться,
например,
о
формах
слов,
учитывать
информацию
о
важности
различных
244
10.17.
T
search2
атрибутов
документ
а
и
полож
ения
слова
из
запроса
в
документе
для
ран-
жирования
найденных
документов.
Для
этого,
требовалось
создать
новые
типы
данных,
соответствующие
документу
и
запросу
,
и
полнотекстовый
оператор
для
сравнения
документа
и
запроса,
который
возвращает
TRUE
,
если
запрос
у
довлетвор
яет
запросу
,
и
в
противном
случае
-
F
ALSE
.
P
ostgreSQL
предоставляет
возможность
как
для
создания
новых
типов
данных,
операторов,
т
ак
и
создания
индексной
по
ддержки
для
доступа
к
ним,
причем
с
поддер
жк
ой
к
онкурентности
и
восст
ановления
после
сбоев.
Однак
о,
надо
понимать,
что
индексы
нужны
только
для
уск
орения
поиска,
сам
поиск
обязан
работ
ать
и
без
них.
Т
аким
образом,
были
созданы
но-
вые
типы
данных
-
tsvector
,
который
являетс
я
хранилищем
для
лек
сем
из
документ
а,
оптимизированного
для
поиск
а,
и
tsquery
-
для
запроса
с
под-
дер
жкой
логических
операций,
полнотек
стовый
оператор
«две
собаки»
@@
и
индексная
по
ддержк
а
для
него
с
использованием
GiST
и
GIN.
tsv
ector
помимо
самих
лексем
мож
ет
хранить
информацию
о
полож
ении
лек
семы
в
документе
и
ее
весе
(важности),
которая
потом
мо
жет
использоваться
для
вычисления
ранжирующей
информации.
У
становк
а
и
использование
Для
на
чала
активируем
расширение:
Листинг
10.103
Активация
tsearch2
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
t
s
e
a
r
c
h
2
;
Проверим
его
работу:
Листинг
10.104
Проверка
tsearch2
Line
1
#
S
E
L
E
C
T
’
T
h
i
s
i
s
t
e
s
t
s
t
r
i
n
g
’
:
:
t
s
v
e
c
t
o
r
;
-
t
s
v
e
c
t
o
r
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
’
T
h
i
s
’
’
i
s
’
’
s
t
r
i
n
g
’
’
t
e
s
t
’
5
(
1
r
o
w
)
-
-
#
S
E
L
E
C
T
s
t
r
i
p
(
t
o
_
t
s
v
e
c
t
o
r
(
’
T
h
e
a
i
r
s
m
e
l
l
s
o
f
s
e
a
w
a
t
e
r
.
’
)
)
;
-
s
t
r
i
p
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
10
’
a
i
r
’
’
s
e
a
’
’
s
m
e
l
l
’
’
w
a
t
e
r
’
-
(
1
r
o
w
)
Заключение
Данное
расширение
заслуживает
от
дельной
книги,
поэтому
лучше
ознак
омиться с
ним
по
дробнее
в
«
Введение
в
полнотек
стовый поиск
в
245
10.18.
PL/Proxy
P
ostgreSQL
»
документе.
10.18
PL/Pro
xy
PL/Pro
xy
предст
авляет
собой
прок
си-язык
для
у
даленного
вызова
про-
цедур
и
партицирования
данных
между
разными
базами
(шардинг).
По-
дробнее
мо
жно
почитать
в
«
6.2
PL/Proxy
»
главе.
10.19
T
excaller
T
excaller
—
это
у
добный
интерфейс
для
командной
строки
T
eX
,
кото-
рый
обрабатывает
все
виды
ошибок.
Он
написан
в
простом
C,
довольно
порт
ативный
и
не
имеет
внешних
зависимостей,
кроме
T
eX.
Неверный
T
eX
документ
обрабатывается
путем
простого
возвращения
NULL,
а
не
преры-
ваетс
я
с
ошибкой.
В
случае
неу
да
чи,
а
т
акже
в
случае
успех
а,
дополни-
тельная
обработк
а
информации
осуществляется
через
NOTICEs.
10.20
Pgmemcac
he
Pgmemcac
he
—
это
PostgreSQL
API
библиотека
на
основе
libmemcac
hed
для
взаимодействия
с
memcac
hed.
С
помощью
данной
библиотеки
P
ostgreSQL мо
ж
ет
записывать,
считывать,
иск
ать
и
у
далять
данные из
memcac
hed.
Подробнее
можно
почитать
в
«
9.2
Pgmemcache
»
главе.
10.21
Prefix
Prefix
реализу
ет
поиск
текст
а
по
префик
су
(
prefix
@>
text
).
Prefix
ис-
пользу
ется
в
прилож
ениях
телефонии,
г
де
маршрутизация
вызовов
и
рас-
х
оды
зависят
от
вызывающего/вызываемого
префикса
телефонного
номе-
ра
оператора.
У
становк
а
и
использование
Для
на
чала
инициализируем
расширение
в
базе
данных:
Листинг
10.105
Инициализация
prefix
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
r
e
f
i
x
;
После
этого
мо
жем
проверить,
что
расширение
функционирует:
246
10.21.
Prefix
Листинг
10.106
Проверка
prefix
Line
1
#
s
e
l
e
c
t
’
1
2
3
’
:
:
p
r
e
f
i
x
_
r
a
n
g
e
@
>
’
1
2
3
4
5
6
’
;
-
?
c
o
l
u
m
n
?
-
-
-
-
-
-
-
-
-
-
-
-
t
5
(
1
r
o
w
)
-
-
#
s
e
l
e
c
t
a
,
b
,
a
|
b
a
s
u
n
i
o
n
,
a
&
b
a
s
i
n
t
e
r
s
e
c
t
-
f
r
o
m
(
s
e
l
e
c
t
a
:
:
p
r
e
f
i
x
_
r
a
n
g
e
,
b
:
:
p
r
e
f
i
x
_
r
a
n
g
e
-
f
r
o
m
(
v
a
l
u
e
s
(
’
1
2
3
’
,
’
1
2
3
’
)
,
10
(
’
1
2
3
’
,
’
1
2
4
’
)
,
-
(
’
1
2
3
’
,
’
1
2
3
[
4
-
5
]
’
)
,
-
(
’
1
2
3
[
4
-
5
]
’
,
’
1
2
3
[
2
-
7
]
’
)
,
-
(
’
1
2
3
’
,
’
[
2
-
3
]
’
)
)
a
s
t
(
a
,
b
)
-
)
a
s
x
;
15
-
a
|
b
|
u
n
i
o
n
|
i
n
t
e
r
s
e
c
t
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
1
2
3
|
1
2
3
|
1
2
3
|
1
2
3
-
1
2
3
|
1
2
4
|
1
2
[
3
-
4
]
|
20
1
2
3
|
1
2
3
[
4
-
5
]
|
1
2
3
|
1
2
3
[
4
-
5
]
-
1
2
3
[
4
-
5
]
|
1
2
3
[
2
-
7
]
|
1
2
3
[
2
-
7
]
|
1
2
3
[
4
-
5
]
-
1
2
3
|
[
2
-
3
]
|
[
1
-
3
]
|
-
(
5
r
o
w
s
)
В
примере
10.107
производитс
я
поиск
мобильного
оператора
по
номеру
телефона:
Листинг
10.107
Проверка
prefix
Line
1
$
w
g
e
t
h
t
t
p
s
:
/
/
g
i
t
h
u
b
.
c
om
/
d
i
m
i
t
r
i
/
p
r
e
f
i
x
/
r
a
w
/
m
a
s
t
e
r
/
p
r
e
f
i
x
e
s
.
f
r
.
c
s
v
-
$
p
s
q
l
-
-
#
c
r
e
a
t
e
t
a
b
l
e
p
r
e
f
i
x
e
s
(
5
p
r
e
f
i
x
p
r
e
f
i
x
_
r
a
n
g
e
p
r
i
m
a
r
y
k
e
y
,
-
na
me
t
e
x
t
n
o
t
n
u
l
l
,
-
s
h
o
r
t
n
a
m
e
t
e
x
t
,
-
s
t
a
t
u
s
c
h
a
r
d
e
f
a
u
l
t
’
S
’
,
-
10
c
h
e
c
k
(
s
t
a
t
u
s
i
n
(
’
S
’
,
’
R
’
)
)
-
)
;
-
C
R
E
A
T
E
T
A
B
L
E
-
#
c
o
m
m
e
n
t
o
n
c
o
l
u
m
n
p
r
e
f
i
x
e
s
.
s
t
a
t
u
s
i
s
’
S
:
-
R
:
r
e
s
e
r
v
e
d
’
;
-
C
O
M
M
E
N
T
15
#
\
c
o
p
y
p
r
e
f
i
x
e
s
f
r
o
m
’
p
r
e
f
i
x
e
s
.
f
r
.
c
s
v
’
w
i
t
h
d
e
l
i
m
i
t
e
r
’
;
’
c
s
v
q
u
o
t
e
’
"
’
247
10.21.
Prefix
-
C
O
P
Y
1
1
9
6
6
-
#
c
r
e
a
t
e
i
n
d
e
x
i
d
x
_
p
r
e
f
i
x
o
n
p
r
e
f
i
x
e
s
u
s
i
n
g
g
i
s
t
(
p
r
e
f
i
x
)
;
-
C
R
E
A
T
E
I
N
D
E
X
-
#
s
e
l
e
c
t
*
f
r
o
m
p
r
e
f
i
x
e
s
l
i
m
i
t
1
0
;
20
p
r
e
f
i
x
|
na
me
|
s
h
o
r
t
n
a
m
e
|
s
t
a
t
u
s
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
0
1
0
0
0
1
|
C
O
L
T
T
E
L
E
C
O
M
M
U
N
I
C
A
T
I
O
N
S
F
R
A
N
C
E
|
C
O
L
T
|
S
-
0
1
0
0
0
2
|
E
Q
U
A
N
T
F
r
a
n
c
e
|
E
Q
F
R
|
S
-
0
1
0
0
0
3
|
N
U
M
E
R
I
C
A
B
L
E
|
N
U
R
C
|
S
25
0
1
0
0
0
4
|
P
R
O
S
O
D
I
E
|
P
R
O
S
|
S
-
0
1
0
0
0
5
|
I
N
T
E
R
N
A
T
I
O
N
A
L
T
E
L
E
C
O
M
M
U
N
I
C
A
T
I
O
N
N
E
T
W
O
R
K
F
r
a
n
c
e
(
V
i
v
a
c
t
i
o
n
)
|
IT
NF
|
S
-
0
1
0
0
0
6
|
S
O
CI
E
T
E
F
R
A
N
C
A
I
S
E
D
U
R
A
D
I
O
T
E
L
E
P
H
O
N
E
|
SF
R
|
S
-
0
1
0
0
0
7
|
S
O
CI
E
T
E
F
R
A
N
C
A
I
S
E
D
U
R
A
D
I
O
T
E
L
E
P
H
O
N
E
|
SF
R
|
S
-
0
1
0
0
0
8
|
B
JT
P
A
R
T
N
E
R
S
|
B
J
T
P
|
S
30
0
1
0
0
0
9
|
L
O
N
G
P
H
O
N
E
|
L
G
P
H
|
S
-
0
1
0
0
1
0
|
IP
NOT
IC
T
E
L
E
C
O
M
|
T
L
N
W
|
S
-
(
1
0
r
o
w
s
)
-
-
#
s
e
l
e
c
t
*
f
r
o
m
p
r
e
f
i
x
e
s
w
h
e
r
e
p
r
e
f
i
x
@
>
’
0
1
4
6
6
4
0
1
2
3
’
;
35
p
r
e
f
i
x
|
nam
e
|
s
h
o
r
t
n
a
m
e
|
s
t
a
t
u
s
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
0
1
4
6
|
F
R
A
N
C
E
T
E
L
E
C
O
M
|
F
R
T
E
|
S
-
(
1
r
o
w
)
-
40
#
s
e
l
e
c
t
*
f
r
o
m
p
r
e
f
i
x
e
s
w
h
e
r
e
p
r
e
f
i
x
@
>
’
0
1
0
0
0
9
1
2
3
4
’
;
-
p
r
e
f
i
x
|
na
me
|
s
h
o
r
t
n
a
m
e
|
s
t
a
t
u
s
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
0
1
0
0
0
9
|
L
O
N
G
P
H
O
N
E
|
L
G
P
H
|
S
-
(
1
r
o
w
)
Заключение
Более
подробно
об
использовании
расширения
мо
жно
ознакомитьс
я
че-
рез
официальную
документ
ацию
.
248
10.22.
Dblink
10.22
Dblink
Dblink
–
расширение,
которое
позволяет
выполнять
запросы
к
у
дален-
ным
базам
данных
непосредственно
из
SQL,
не
прибег
ая
к
помощи
внеш-
них
скриптов.
У
становк
а
и
использование
Для
на
чала
инициализируем
расширение
в
базе
данных:
Листинг
10.108
Инициализация
dblink
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
d
b
l
i
n
k
;
Для
создания
по
дключения
к
другой
базе
данных
нужно
использовать
dblink_connect
функцию, г
де первым параметром
ук
азывается
имя
по
д-
ключения,
а
вторым
-
опции
по
дключения
к
базе:
Листинг
10.109
Подключение
через
dblink
Line
1
#
S
E
L
E
C
T
d
b
l
i
n
k
_
c
o
n
n
e
c
t
(
’
s
l
a
v
e
_
d
b
’
,
’
h
o
s
t=
s
l
a
v
e
.
e
x
a
m
p
l
e
.
co
m
p
o
r
t
=
5
4
3
2
d
b
n
a
m
e
=
e
x
a
m
p
l
e
d
b
u
s
e
r
=
a
d
m
i
n
p
a
s
s
w
o
r
d=p
a
s
s
w
o
r
d
’
)
;
-
d
b
l
i
n
k
_
c
o
n
n
e
c
t
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
O
K
5
(
1
r
o
w
)
При
у
спешном
выполнении
к
оманды
бу
дет
выведен
ответ
«OK»
.
Т
еперь
мо
жно
попробовать
считать
данные
из
таблиц
через
dblink
функцию:
Листинг
10.110
SELECT
Line
1
#
S
E
L
E
C
T
*
-
F
R
O
M
d
b
l
i
n
k
(
’
s
l
a
v
e
_
d
b
’
,
’
S
E
L
E
C
T
i
d
,
u
s
e
r
n
a
m
e
F
R
O
M
u
s
e
r
s
LIMIT
3
’
)
-
AS
d
b
l
i
n
k
_
u
s
e
r
s
(
i
d
i
n
t
e
g
e
r
,
u
s
e
r
n
a
m
e
t
e
x
t
)
;
-
5
i
d
|
u
s
e
r
n
a
m
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
1
|
6
4
e
c
7
0
8
3
d
7
f
a
c
b
7
c
5
d
9
7
6
8
4
e
7
f
4
1
5
b
6
5
-
2
|
4
0
4
c
3
b
6
3
9
a
9
2
0
b
5
b
a
8
1
4
f
c
0
1
3
5
3
3
6
8
f
2
-
3
|
1
5
3
0
4
1
f
9
9
2
e
3
e
a
b
6
8
9
1
f
0
e
8
d
a
9
d
1
1
f
2
3
10
(
3
r
o
w
s
)
По
завершению
работы с
сервером, по
дключение
требу
ется
закрыть
через
функцию
dblink_disconnect
:
249
10.22.
Dblink
Листинг
10.111
dblink_disconnect
Line
1
#
S
E
L
E
C
T
d
b
l
i
n
k
_
d
i
s
c
o
n
n
e
c
t
(
’
s
l
a
v
e
_
d
b
’
)
;
-
d
b
l
i
n
k
_
d
i
s
c
o
n
n
e
c
t
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
O
K
5
(
1
r
o
w
)
Курсоры
Dblink
поддер
живает
курсоры
—
инк
апсу
лирующие
запросы,
к
оторые
позволяют
получать
резу
льт
ат
запроса
по
неск
ольку
строк
за
раз.
Одна
из
причин
использования
курсоров
заключается
в
том,
чтобы
избежать
пе-
реполнения
памяти,
ког
да
резу
льт
ат
содер
жит
большое
количество
строк.
Для
открытия
курсора
использу
ется
функция
dblink_op
en
,
г
де
первый
параметр
-
название
подключения,
второй
-
название
для
курсора,
а
тре-
тий
-
сам
запрос:
Листинг
10.112
dblink_op
en
Line
1
#
S
E
L
E
C
T
d
b
l
i
n
k
_
o
p
e
n
(
’
s
l
a
v
e
_
d
b
’
,
’
u
s
e
r
s
’
,
’
S
E
L
E
C
T
i
d
,
u
s
e
r
n
a
m
e
F
R
O
M
u
s
e
r
s
’
)
;
-
d
b
l
i
n
k
_
o
p
e
n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
O
K
5
(
1
r
o
w
)
Для
получения
данных
из
курсора
требуетс
я
использовать
dblink_fetc
h
,
г
де
первый
параметр
- название
подключения,
второй -
название для
курсора,
а
третий
-
требу
емое
количество
записей
из
курсора:
Листинг
10.113
dblink_fetch
Line
1
#
S
E
L
E
C
T
i
d
,
u
s
e
r
n
a
m
e
F
R
O
M
d
b
l
i
n
k
_
f
e
t
c
h
(
’
s
l
a
v
e
_
d
b
’
,
’
u
s
e
r
s
’
,
2
)
-
AS
(
i
d
i
n
t
e
g
e
r
,
u
s
e
r
n
a
m
e
t
e
x
t
)
;
-
i
d
|
u
s
e
r
n
a
m
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
5
1
|
6
4
e
c
7
0
8
3
d
7
f
a
c
b
7
c
5
d
9
7
6
8
4
e
7
f
4
1
5
b
6
5
-
2
|
4
0
4
c
3
b
6
3
9
a
9
2
0
b
5
b
a
8
1
4
f
c
0
1
3
5
3
3
6
8
f
2
-
(
2
r
o
w
s
)
-
-
#
S
E
L
E
C
T
i
d
,
u
s
e
r
n
a
m
e
F
R
O
M
d
b
l
i
n
k
_
f
e
t
c
h
(
’
s
l
a
v
e
_
d
b
’
,
’
u
s
e
r
s
’
,
2
)
10
AS
(
i
d
i
n
t
e
g
e
r
,
u
s
e
r
n
a
m
e
t
e
x
t
)
;
-
i
d
|
u
s
e
r
n
a
m
e
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
250
10.22.
Dblink
-
3
|
1
5
3
0
4
1
f
9
9
2
e
3
e
a
b
6
8
9
1
f
0
e
8
d
a
9
d
1
1
f
2
3
-
4
|
3
1
8
c
3
3
4
5
8
b
4
8
4
0
f
9
0
d
8
7
e
e
4
e
a
8
7
3
7
5
1
5
15
(
2
r
o
w
s
)
-
-
#
S
E
L
E
C
T
i
d
,
u
s
e
r
n
a
m
e
F
R
O
M
d
b
l
i
n
k
_
f
e
t
c
h
(
’
s
l
a
v
e
_
d
b
’
,
’
u
s
e
r
s
’
,
2
)
-
AS
(
i
d
i
n
t
e
g
e
r
,
u
s
e
r
n
a
m
e
t
e
x
t
)
;
-
i
d
|
u
s
e
r
n
a
m
e
20
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
6
|
5
b
7
9
5
b
0
e
7
3
b
0
0
2
2
0
8
4
3
f
8
2
c
4
d
0
f
8
1
f
3
7
-
8
|
c
2
6
7
3
e
e
9
8
6
c
2
3
f
6
2
a
a
e
b
6
6
9
c
3
2
2
6
1
4
0
2
-
(
2
r
o
w
s
)
После
работы
с
курсором
его
нужно
обязательно
закрыть
через
dblink_close
функцию:
Листинг
10.114
dblink_close
Line
1
#
S
E
L
E
C
T
d
b
l
i
n
k
_
c
l
o
s
e
(
’
s
l
a
v
e
_
d
b
’
,
’
u
s
e
r
s
’
)
;
-
d
b
l
i
n
k
_
c
l
o
s
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
O
K
5
(
1
r
o
w
)
Асинхронные
запросы
Последним
вариантом
для
выполнения
запросов
в
dblink
являетс
я
асинхронный
запрос.
При
его
использовании
резу
ль
таты
не
бу
дут
возвра-
щены
до
полного
выполнения
резу
льт
ат
а
запроса.
Для
создания
асинхрон-
ного
запроса
использу
ется
dblink_send_query
функция:
Листинг
10.115
dblink_send_query
Line
1
#
S
E
L
E
C
T
*
F
R
O
M
d
b
l
i
n
k
_
s
e
n
d
_
q
u
e
r
y
(
’
s
l
a
v
e
_
d
b
’
,
’
S
E
L
E
C
T
i
d
,
u
s
e
r
n
a
m
e
F
R
O
M
u
s
e
r
s
’
)
A
S
u
s
e
r
s
;
-
u
s
e
r
s
-
-
-
-
-
-
-
-
-
1
5
(
1
r
o
w
)
Р
езу
льт
ат
получаетс
я
через
dblink_get_result
функцию:
Листинг
10.116
dblink_get_result
Line
1
#
S
E
L
E
C
T
i
d
,
u
s
e
r
n
a
m
e
F
R
O
M
d
b
l
i
n
k
_
g
e
t
_
r
e
s
u
l
t
(
’
s
l
a
v
e
_
d
b
’
)
-
AS
(
i
d
i
n
t
e
g
e
r
,
u
s
e
r
n
a
m
e
t
e
x
t
)
;
-
i
d
|
u
s
e
r
n
a
m
e
251
10.23.
Postgres_fdw
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
5
1
|
6
4
e
c
7
0
8
3
d
7
f
a
c
b
7
c
5
d
9
7
6
8
4
e
7
f
4
1
5
b
6
5
-
2
|
4
0
4
c
3
b
6
3
9
a
9
2
0
b
5
b
a
8
1
4
f
c
0
1
3
5
3
3
6
8
f
2
-
3
|
1
5
3
0
4
1
f
9
9
2
e
3
e
a
b
6
8
9
1
f
0
e
8
d
a
9
d
1
1
f
2
3
-
4
|
3
1
8
c
3
3
4
5
8
b
4
8
4
0
f
9
0
d
8
7
e
e
4
e
a
8
7
3
7
5
1
5
-
6
|
5
b
7
9
5
b
0
e
7
3
b
0
0
2
2
0
8
4
3
f
8
2
c
4
d
0
f
8
1
f
3
7
10
8
|
c
2
6
7
3
e
e
9
8
6
c
2
3
f
6
2
a
a
e
b
6
6
9
c
3
2
2
6
1
4
0
2
-
9
|
c
5
3
f
1
4
0
4
0
f
e
f
9
5
4
c
d
6
e
7
3
b
9
a
a
2
e
3
1
d
0
e
-
1
0
|
2
d
b
e
2
7
f
d
9
6
c
d
b
3
9
f
0
1
c
e
1
1
5
c
f
3
c
2
a
5
1
7
10.23
P
ostgres_fdw
P
ostgres_fdw
—
расширение,
которое
позволяет
по
дключить
P
ostgreSQL
к
P
ostgreSQL,
к
оторые
могут
нахо
дитьс
я
на
разных
х
о-
ст
ах.
У
становк
а
и
использование
Для
на
чала
инициализируем
расширение
в
базе
данных:
Листинг
10.117
Инициализация
p
ostgres_fdw
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
o
s
t
g
r
e
s
_
f
d
w
;
Далее
создадим
сервер
подключений,
к
оторый
бу
дет
содер
ж
ать
данные
для
по
дключения
к
другой
PostgreSQL
базе:
Листинг
10.118
Создание
сервера
Line
1
#
C
R
E
A
T
E
S
E
R
V
E
R
s
l
a
v
e
_
d
b
-
F
O
R
E
I
G
N
D
A
T
A
W
R
A
P
P
E
R
p
o
s
t
g
r
e
s
_
f
d
w
-
O
P
T
I
O
N
S
(
h
o
s
t
’
s
l
a
v
e
.
e
x
a
m
p
l
e
.
co
m
’
,
d
b
n
a
m
e
’
e
x
a
m
p
l
e
d
b
’
,
p
o
r
t
’
5
4
3
2
’
)
;
После
этого
нужно
создать
USER
MAPPING
,
которое
создаёт
сопост
ав-
ление
пользователя
на
внешнем
сервере:
Листинг
10.119
USER
MAPPING
Line
1
#
C
R
E
A
T
E
U
S
E
R
M
A
P
P
I
N
G
F
O
R
a
d
m
i
n
-
S
E
R
V
E
R
s
l
a
v
e
_
d
b
-
O
P
T
I
O
N
S
(
u
s
e
r
’
a
d
m
i
n
’
,
p
a
s
s
w
o
r
d
’
p
a
s
s
w
o
r
d
’
)
;
Т
еперь
мо
жно
импортировать
таблицы:
252
10.23.
Postgres_fdw
Листинг
10.120
Импорт
таблицы
Line
1
#
C
R
E
A
T
E
F
O
R
E
I
G
N
T
A
B
L
E
f
d
w
_
u
s
e
r
s
(
-
i
d
s
e
r
i
a
l ,
-
u
s
e
r
n
a
m
e
t
e
x
t
n
o
t
n
u
l
l
,
-
p
a
s
s
w
o
r
d
t
e
x
t
,
5
c
r
e
a
t
e
d
_
o
n
t
i
m
e
s
t
a
m
p
t
z
n
o
t
n
u
l
l
,
-
l
a
s
t
_
l
o
g
g
e
d
_
o
n
t
i
m
e
s
t
a
m
p
t
z
n
o
t
n
u
l
l
-
)
-
S
E
R
V
E
R
s
l
a
v
e
_
d
b
-
O
P
T
I
O
N
S
(
sc
h
e
m
a
_
n
a
m
e
’
p
u
b
l
i
c
’
,
t
a
b
l
e
_
n
a
m
e
’
u
s
e
r
s
’
)
;
Для
того,
чтобы
не
импортировать
к
аждую
таблицу
отдельно,
можно
воспользоватьс
я
IMPOR
T
FOREIGN
SCHEMA
к
омандой:
Листинг
10.121
Импортируем
таблицы
Line
1
#
I
M
P
O
R
T
F
O
R
E
I
G
N
S
C
H
E
M
A
p
u
b
l
i
c
-
LIMIT
T
O
(
u
s
e
r
s
,
p
a
g
e
s
)
-
F
R
O
M
S
E
R
V
E
R
s
l
a
v
e
_
d
b
I
N
T
O
f
d
w
;
Т
еперь
мо
жно
проверить
таблицы:
Листинг
10.122
SELECT
Line
1
#
S
E
L
E
C
T
*
F
R
O
M
f
d
w
_
u
s
e
r
s
L
IMIT
1
;
-
-
[
R
E
C
O
R
D
1
]
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
i
d
|
1
-
u
s
e
r
n
a
m
e
|
6
4
e
c
7
0
8
3
d
7
f
a
c
b
7
c
5
d
9
7
6
8
4
e
7
f
4
1
5
b
6
5
5
p
a
s
s
w
o
r
d
|
b
8
2
a
f
3
9
6
6
b
4
9
c
9
e
f
0
f
7
8
2
9
1
0
7
d
b
6
4
2
b
c
-
c
r
e
a
t
e
d
_
o
n
|
2
0
1
7
-
0
2
-
2
1
0
5
:
0
7
:
2
5
.
6
1
9
5
6
1
+
0
0
-
l
a
s
t
_
l
o
g
g
e
d
_
o
n
|
2
0
1
7
-
0
2
-
1
9
2
1
:
0
3
:
3
5
.
6
5
1
5
6
1
+
0
0
По
умолчанию
из
таблиц
можно
не
тольк
о
чит
ать,
но
и
изменять
в
них
данные
(
INSER
T
/
UPDA
TE
/
DELETE
).
up
datable
опция
мо
ж
ет
использовать
для
по
дключения
к
серверу
в
режиме
«только
на
чтение»:
Листинг
10.123
Read-only
mo
de
Line
1
#
A
L
T
E
R
S
E
R
V
E
R
s
l
a
v
e
_
d
b
-
O
P
T
I
O
N
S
(
A
D
D
u
p
d
a
t
a
b
l
e
’
f
a
l
s
e
’
)
;
-
A
L
T
E
R
S
E
R
V
E
R
-
#
D
E
L
E
T
E
F
R
O
M
f
d
w
_
u
s
e
r
s
W
H
E
R
E
i
d
<
1
0
;
5
E
R
R
O
R
:
f
o
r
e
i
g
n
t
a
b
l
e
"
f
d
w
_
u
s
e
r
s
"
d
o
e
s
n
o
t
a
l
l
o
w
d
e
l
e
t
e
s
Данную
опцию
можно
у
ст
ановить
не
только
на
уровне
сервера,
но
и
на
уровне
от
дельных
таблиц:
253
10.24.
Pg_cron
Листинг
10.124
Read-only
mo
de
для
таблицы
Line
1
#
A
L
T
E
R
F
O
R
E
I
G
N
T
A
B
L
E
f
d
w
_
u
s
e
r
s
-
O
P
T
I
O
N
S
(
A
D
D
u
p
d
a
t
a
b
l
e
’
f
a
l
s
e
’
)
;
P
ostgres_fdw
и
DBLink
Как
мо
жно
было
заметить,
p
ostgres_fdw
и
dblink
выполняют
одну
и
ту
ж
е
работу
—
по
дключение
одной
PostgreSQL
базы
к
другой.
Что
лучше
использовать
в
т
аком
случае?
P
ostgreSQL
FDW
(F
oreign
Data
W
rapper)
более
новый
и
рекоменду
е-
мый
метод
подключения
к
другим
источникам
данных.
Хот
я
функцио-
нальность
dblink
пох
ож
а
на
FD
W,
последний
являетс
я
более
SQL
совме-
стимым
и
мож
ет
обеспечивать
у
лучшеную
производительность
по
срав-
нению
с
dblink
подключениями.
Кроме
того,
в
от
личии
от
p
ostgres_fdw,
dblink
не
способен
с
делать
данные
«тольк
о
на
чтение»
.
Это
мож
ет
быть
дост
аточно
важно,
если
требуетс
я
обеспечить,
чтобы
данные
в
другой
базе
нельзя
было
изменять.
В
dblink
подключения работают
тольк
о
в
течение
работы
сессии
и
их
требуетс
я
п
ересоздавать
каждый
раз.
Postgres_fdw
создает
постоян-
ное
подключение
к
другой
базе
данных.
Это
мо
ж
ет
быть
к
ак
х
орошо,
так
пло
хо,
в
зависимости
от
потребностей.
Из
положительных
сторон
dblink
мо
жно
отнести
множ
ество
полезных
к
оманд,
к
оторые
позволяют
использовать
его
для
программирования
по-
лезного
функционала.
Т
акже
dblink
работает
в
версиях
P
ostgreSQL
8.3
и
выше,
в
то
время
как
p
ostgres_fdw
работает
только
в
P
ostgreSQL
9.3
и
вы-
ше
(т
акое
мож
ет
возникнуть,
если
нет
возмо
жности
обновить
PostgreSQL
базу).
10.24
Pg_cron
Pg_cron
—
cron-по
добный
планировщик
зада
ч
для
P
ostgreSQL
9.5
или
выше, к
оторый работает
к
ак расширение к базе. Он мо
ж
ет выполнять
неск
олько
задач
параллельно,
но
о
дновременно
мож
ет
работ
ать
не
более
о
дного
экземпляра
задания
(если
при
запуск
е
зада
чи
предыдущий
запуск
бу
дет
еще
выполнятьс
я,
то
запу
ск
бу
дет
отло
жен
до
выполнения
текущей
зада
чи).
У
становк
а
и
использование
После
уст
ановки
расширения
требуетс
я
добавить
его
в
p
ostgresql
.
conf
и
перезапу
стить
PostgreSQL:
Листинг
10.125
pg_cron
254
10.24.
Pg_cron
Line
1
s
h
a
r
e
d
_
p
r
e
l
o
a
d
_
l
i
b
r
a
r
i
e
s
=
’
p
g
_
c
r
o
n
’
Далее
требу
ется
активировать
расширение
для
p
ostgres
базы:
Листинг
10.126
pg_cron
Line
1
#
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
p
g
_
c
r
o
n
;
По
умолчанию
pg_cron
ожидает
,
что
все
т
аблицы
с
метаданными
бу
дут
нах
одитьс
я
в
p
ostgres
базе
данных.
Данное
поведение
мо
жно
изменить
и
ук
азать
через
параметр
cron
.
database_name
в
p
ostgresql
.
conf
другую
базу
данных,
г
де
pg_cron
бу
дет
хранить
свои
данные.
Внутри
pg_cron
использу
ет
libp
q
библиотеку
,
поэтому
потребуетс
я
раз-
решить
подключения
с
lo
calhost
без
пароля
(
trust
в
pg_hba.conf
)
или
же
создать
.pgpass
файл
для
настройки
по
дключения
к
базе.
Для
создания
cron
зада
ч
используетс
я
функция
cron
.
schedule
:
Листинг
10.127
Cron.schedule
Line
1
-
-
D
e
l
e
t
e
o
l
d
d
a
t
a
o
n
S
a
t
u
r
d
a
y
a
t
3
:
3
0
a
m
(
G
M
T
)
-
S
E
L
E
C
T
c
r
o
n
.
s
c
h
e
d
u
l
e
(
’
3
0
3
*
*
6
’
,
$
$
D
E
LE
T
E
F
R
O
M
e
v
e
n
t
s
W
H
E
R
E
e
v
e
n
t
_
t
i
m
e
<
now
(
)
-
i
n
t
e
r
v
a
l
’
1
w
e
e
k
’
$
$
)
;
-
s
c
h
e
d
u
l
e
-
-
-
-
-
-
-
-
-
-
-
5
4
2
Для
у
даления
созданых
задач
используетс
я
cron
.
unschedule
:
Листинг
10.128
Cron.unschedule
Line
1
-
-
Vacu
um
e
v
e
r
y
d
a
y
a
t
1
0
:
0
0
a
m
(
G
M
T
)
-
S
E
L
E
C
T
c
r
o
n
.
s
c
h
e
d
u
l
e
(
’
0
1
0
*
*
*
’
,
’
V
A
C
U
U
M
’
)
;
-
s
c
h
e
d
u
l
e
-
-
-
-
-
-
-
-
-
-
-
5
4
3
-
-
-
-
S
t
o
p
s
c
h
e
d
u
l
i
n
g
a
j
o
b
-
S
E
L
E
C
T
c
r
o
n
.
u
n
s
c
h
e
d
u
l
e
(
4
3
)
;
-
u
n
s
c
h
e
d
u
l
e
10
-
-
-
-
-
-
-
-
-
-
-
-
-
t
В
целях
безопасности
cron
задачи
выполняются
в
базе
данных,
в
ко-
торой
cron
.
schedule
функция
была вызвана
с
правами доступа
текущего
пользователя.
Поск
ольку
pg_cron
использует
libp
q
библиотеку
,
это
позволяет
запу
с-
к
ать
cron
зада
чи
на
других
базах
данных
(даж
е
на
других
серверах).
С
помощью
суперпользователя
возможно
модифицировать
cron
.
job
таблицу
255
10.25.
PGStrom
и
добавить
в
нее
параметры
подключения
к
другой
базе
через
no
dename
и
no
dep
ort
поля:
Листинг
10.129
Cron.job
Line
1
IN
SE
R
T
I
N
TO
c
r
o
n
.
j
o
b
(
s
c
h
e
d
u
l
e
,
command
,
n
o
d
e
n
a
m
e
,
n
o
d
e
p
o
r
t
,
d
a
t
a
b
a
s
e
,
u
s
e
r
n
a
m
e
)
-
V
A
L
U
E
S
(
’
0
4
*
*
*
’
,
’
V
A
C
U
U
M
’
,
’
w
o
r
k
e
r
-
n
o
d
e
-
1
’
,
5
4
3
2
,
’
p
o
s
t
g
r
e
s
’
,
’
m
a
r
c
o
’
)
;
В
так
ом
случае
нужно
бу
дет
создать
.pgpass
файл
для
настройки
под-
ключения
к
базе
на
другом
сервере.
10.25
PGStrom
PGStrom
—
P
ostgreSQL
расширение,
к
оторое
позволяет
использовать
GPU
для
выполнения
некоторых
SQL
операций.
В
частности,
за
счёт
при-
влечения
GPU
могут
быть
у
скорены
т
акие
операции
как
сравнительный
перебор
элементов
т
аблиц,
агрегирование
записей
и
слияние
хэшей.
Ко
д
для выполнения
на
стороне GPU
генериру
ется
в
момент
разбора SQL-
запроса
при
помощи
специального
JIT-к
омпилятора
и
в
дальнейшем
вы-
полняетс
я
параллельно
с
другими
связанными
с
текущим
запросом
опе-
рациями,
выполняемыми
на
CPU.
Для
выполнения
заданий
на
GPU
за-
действован
Op
enCL.
Увеличение
произво
дительности
операций
слияния
т
аблиц
(
JOIN
)
при
использовании
GPU
увеличивается
в
десятки
раз.
Областью
применения
PG-Strom
являютс
я
огромные
отчеты
с
исполь-
зованием
агрегации
и
объеди
нения
таблиц.
Эти
рабочие
нагрузки
чаще
используютс
я
в
пакетной
обработке
данных
для
OLAP
систем.
10.26
Zom
b
oDB
Zom
b
oDB
—
PostgreSQL
расширение,
которое
позволяет
использовать
Elasticsearc
h
индек
сы
внутри
базы
(использу
етс
я
интерфейс
для
мето
дов
доступа
индекса
).
ZomboDB
индекс
для
PostgreSQL
ничем
не
отличаетс
я
от
стандартного
btree
индекса.
Т
аким
образом,
стандартные
команды
SQL
полностью
по
ддерживаютс
я,
включая
SELECT
,
BEGIN
,
COMMIT
,
ABOR
T
,
INSER
T
,
UPDA
TE
,
DELETE
,
COPY
и
V
A
CUUM
и
данные
индек
сы
являются
MV
CC-безопасными.
На
низк
ом
уровне
ZomboDB
индексы
взаимодействуют
с
Elasticsearch
сервером
через
HTTP
запросы
и
автоматически
синхронизируются
в
про-
цессе
изменения
данных
в
P
ostgreSQL
базе.
256
10.26.
ZomboDB
Рис.
10.3:
PGStrom
У
становк
а
и
использование
Zom
b
oDB
состоит
из
двух
частей:
P
ostgreSQL
расширения
(написан
на
C
и
SQL/PLPGSQL)
и
Elasticsearc
h
плагина
(написан
на
Ja
v
a).
После
у
ст
ановки
требуетс
я
добавить
в
p
ostgresql
.
conf
zom
b
o
db
библио-
теку:
Листинг
10.130
Zombo
db
Line
1
l
o
c
a
l
_
p
r
e
l
o
a
d
_
l
i
b
r
a
r
i
e
s
=
’
z
o
m
b
o
d
b
.
s
o
’
И
после
перегрузки
P
ostgreSQL
активировать
его
для
базы
данных:
Листинг
10.131
Zombo
db
Line
1
C
R
E
A
T
E
E
X
T
E
N
S
I
O
N
z
o
m
b
o
d
b
;
После
этого
требу
етс
я
уст
ановить
Elasticsearch
плагин
на
все
ноды
сер-
вера
и
изменить
к
онфигурацию
в
elasticsearc
h
.
yml
:
257
10.26.
ZomboDB
Листинг
10.132
Elasticsearch
Line
1
t
h
r
e
a
d
p
o
o
l
.
b
u
l
k
.
q
u
e
u
e
_
s
i
z
e
:
1
0
2
4
-
t
h
r
e
a
d
p
o
o
l
.
b
u
l
k
.
s
i
z
e
:
1
2
-
-
h
t
t
p
.
c
o
m
p
r
e
s
s
i
o
n
:
t
r
u
e
5
-
h
t
t
p
.
m
a
x
_
c
o
n
t
e
n
t
_
l
e
n
g
t
h
:
1
0
2
4m
b
-
i
n
d
e
x
.
q
u
e
r
y
.
b
o
o
l
.
m
a
x
_
c
l
a
u
s
e
_
c
o
u
n
t
:
1
0
0
0
0
0
0
Для
примера
создадим
таблицу
с
продукт
ами
и
заполним
её
данными:
Листинг
10.133
Pro
ducts
table
Line
1
#
C
R
E
A
T
E
T
A
B
L
E
p
r
o
d
u
c
t
s
(
-
i
d
SERIAL8
N
O
T
N
U
L
L
P
R
I
M
A
R
Y
K
E
Y
,
-
n
am
e
t
e
x
t
N
O
T
N
U
L
L
,
-
k
e
y
w
o
r
d
s
v
a
r
c
h
a
r
(
6
4
)
[
]
,
5
s
h
o
r
t
_
s
u
m
m
a
r
y
p
h
r
a
s
e
,
-
l
o
n
g
_
d
e
s
c
r
i
p
t
i
o
n
f
u
l
l
t
e
x
t ,
-
p
r
i
c
e
b
i
g
i
n
t
,
-
i
n
v
e
n
t
o
r
y
_
c
o
u
n
t
i
n
t
e
g
e
r
,
-
d
i
s
c
o
n
t
i
n
u
e
d
b
o
o
l
e
a
n
d
e
f
a
u
l
t
f
a
l
s
e
,
10
a
v
a
i
l
a
b
i
l
i
t
y
_
d
a
t
e
d
a
t
e
-
)
;
-
-
#
C
O
P
Y
p
r
o
d
u
c
t
s
F
R
O
M
P
R
O
G
R
A
M
’
c
u
r
l
h
t
t
p
s
:
/
/
r
a
w
.
g
i
t
h
u
b
u
s
e
r
c
o
n
t
e
n
t
.
com
/
z
o
m
b
o
d
b
/
z
o
m
b
o
d
b
/
m
a
s
t
e
r
/T
U
T
O
R
I
A
L-
d
a
t
a
.
dm
p
’
;
zdb(record)
zombo
db
функция
конвертиру
ет
запись
в
JSON
формат
(обертк
а
поверх
row_to_json(record)
):
Листинг
10.134
Zdb
Line
1
#
S
E
L
E
C
T
z
d
b
(
p
r
o
d
u
c
t
s
)
F
R
O
M
p
r
o
d
u
c
t
s
W
H
E
R
E
i
d
=
1
;
-
z
d
b
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{
"
i
d
"
:
1
,
"
n
am
e
"
:
"
M
a
g
i
c
a
l
W
i
d
g
e
t
"
,
"
k
e
y
w
o
r
d
s
"
:
[
"
m
a
g
i
c
a
l
"
,
"
w
i
d
g
e
t
"
,
"
r
o
u
n
d
"
]
,
"
s
h
o
r
t
_
s
u
m
m
a
r
y
"
:
"A
w
i
d
g
e
t
t
h
a
t
i
s
q
u
i
t
e
m
a
g
i
c
a
l
"
,
"
l
o
n
g
_
d
e
s
c
r
i
p
t
i
o
n
"
:
"
M
a
g
i
c
a
l
W
i
d
g
e
t
s
c
o
m
e
f
r
o
m
t
h
e
l
a
n
d
o
f
M
a
g
i
c
v
i
l
l
e
a
n
d
a
r
e
c
a
p
a
b
l
e
o
f
t
h
i
n
g
s
y
o
u
c
a
n
’
t
i
m
a
g
i
n
e
"
,
"
p
r
i
c
e
"
:
9
9
0
0
,
"
i
n
v
e
n
t
o
r
y
_
c
o
u
n
t
"
:
4
2
,
"
d
i
s
c
o
n
t
i
n
u
e
d
"
:
f
a
l
s
e
,
"
a
v
a
i
l
a
b
i
l
i
t
y
_
d
a
t
e
"
:
"
2
0
1
5
-
0
8
-
3
1
"
}
zdb(
regclass
,
tid
)
zom
b
o
db
функция,
которая
используетс
я
для
ст
ати-
ческ
ого определения ссылок на
т
аблицу/индекс
в к
онтек
сте последова-
тельного
ск
анирования.
Благодар
я
этим
двум
функциям
мо
жно
создать
zom
b
o
db
индек
с
для
pro
ducts
т
аблицы:
258
10.26.
ZomboDB
Листинг
10.135
Zdb
Line
1
#
C
R
E
A
T
E
I
N
D
E
X
i
d
x
_
z
d
b
_
p
r
o
d
u
c
t
s
-
O
N
p
r
o
d
u
c
t
s
-
U
SI
N
G
z
o
m
b
o
d
b
(
z
d
b
(
’
p
r
o
d
u
c
t
s
’
,
p
r
o
d
u
c
t
s
.
c
t
i
d
)
,
z
d
b
(
p
r
o
d
u
c
t
s
)
)
-
W
I
T
H
(
u
r
l
=
’
h
t
t
p
:
/
/
l
o
c
a
l
h
o
s
t
:
9
2
0
0
/
’
)
;
Т
еперь
мо
жно
проверить
работу
индекса:
Листинг
10.136
Index
usage
Line
1
#
S
E
L
E
C
T
i
d
,
na
me
,
s
h
o
r
t
_
s
u
m
m
a
r
y
F
R
O
M
p
r
o
d
u
c
t
s
W
H
E
R
E
z
d
b
(
’
p
r
o
d
u
c
t
s
’
,
p
r
o
d
u
c
t
s
.
c
t
i
d
)
=
=
>
’
s
p
o
r
t
s
o
r
b
o
x
’
;
-
i
d
|
na
me
|
s
h
o
r
t
_
s
u
m
m
a
r
y
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
2
|
B
a
s
e
b
a
l
l
|
I
t
’
s
a
b
a
s
e
b
a
l
l
5
4
|
B
o
x
|
J
u
s
t
a
n
e
m
p
t
y
b
o
x
m
ad
e
o
f
w
o
o
d
-
(
2
r
o
w
s
)
-
#
E
X
P
L
A
I
N S
E
L
E
C
T
*
F
R
O
M
p
r
o
d
u
c
t
s
W
H
E
R
E
z
d
b
(
’
p
r
o
d
u
c
t
s
’
,
c
t
i
d
)
=
=
>
’
s
p
o
r
t
s
o
r
b
o
x
’
;
-
Q
U
E
R
Y
P
L
A
N
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
10
I
n
d
e
x
S
c
a
n
u
s
i
n
g
i
d
x
_
z
d
b
_
p
r
o
d
u
c
t
s
o
n
p
r
o
d
u
c
t
s
(
c
o
s
t
=
0
.
0
0
.
.
4
.
0
2
r
o
w
s
=2
w
i
d
t
h
=
1
5
3
)
-
I
n
d
e
x
C
on
d
:
(
z
d
b
(
’
p
r
o
d
u
c
t
s
’
:
:
r
e
g
c
l
a
s
s
,
c
t
i
d
)
=
=
>
’
s
p
o
r
t
s
o
r
b
o
x
’
:
:
t
e
x
t
)
-
(
2
r
o
w
s
)
Zom
b
oDB
содер
жит
набор
функций
для
агрег
ационных
запросов.
На-
пример,
если
нужно
выбрать
уник
альный
набор
ключевых
слов
для
всех
про
дуктов
в
keyw
ords
поле
вместе
с
их
к
оличеством,
то
можно
воспользо-
ватьс
я
zdb_tally
функцией:
Листинг
10.137
Zdb_tally
Line
1
#
S
E
L
E
C
T
*
F
R
O
M
z
d
b
_
t
a
l
l
y
(
’
p
r
o
d
u
c
t
s
’
,
’
k
e
y
w
o
r
d
s
’
,
’
^
.
*
’
,
’
’
,
5
0
0
0
,
’
t
e
r
m
’
)
;
-
t
e
r
m
|
c
o
u
n
t
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
a
l
e
x
a
n
d
e
r
g
r
a
h
a
m
b
e
l
l
|
1
5
b
a
s
e
b
a
l
l
|
1
-
b
o
x
|
1
-
c
o
m
m
u
n
i
c
a
t
i
o
n
|
1
-
m
a
g
i
c
a
l
|
1
-
n
e
g
a
t
i
v
e
s
p
a
c
e
|
1
10
p
r
i
m
i
t
i
v
e
|
1
-
r
o
u
n
d
|
2
259
10.27.
Заключение
-
s
p
o
r
t
s
|
1
-
s
q
u
a
r
e
|
1
-
w
i
d
g
e
t
|
1
15
w
o
o
d
e
n
|
1
-
(
1
2
r
o
w
s
)
Более подробно с
использованием
Zom
b
oDB
мо
жно
ознакомитьс
я
в
официальной
документ
ации
.
10.27
Заключение
Р
асширения
помогают
у
лучшить
работу
P
ostgreSQL
в
решении
специ-
фических
проблем.
Расшир
яемость
P
ostgreSQL
позволяет
создавать
соб-
ственные
расширения,
или
ж
е
наоборот
,
не
нагружать
СУБД
лишним,
не
требу
емым
функционалом.
260
11
Бэк
ап
и
восст
ановление
P
ostgreSQL
Есть
два
типа
администраторов
—
те,
кто
не
делает
бэк
апы,
и
те,
кто
уже
делает
Наро
дная
му
дрость
Если
к
ак
ая-нибу
дь
неприятность
мо
ж
ет
произойти,
она
случается
Зак
он
Мэрфи
11.1
Введение
Любой
хороший
сисадмин
знает
—
бэк
апы
нужны
всегда.
Наск
олько
бы
надежной
ни
казалась
Ваша
система,
всегда
мо
ж
ет
произойти
случай,
к
оторый
был
не
учтен,
и
из-за
которого
могут
быть
потеряны
данные.
Т
о
же
самое
к
асаетс
я
и
PostgreSQL
баз
данных.
Посыпавшийся
винче-
стер
на
сервере,
ошибк
а
в
файловой
системе,
ошибка
в
другой
програм-
ме,
которая
перетерла
весь
кат
алог
P
ostgreSQL
и
многое
другое
приведет
тольк
о
к
плачевному
резу
льт
ату
.
И
даже
если
у
Вас
реплик
ация
с
множ
е-
ством
слейвов,
это
не
означает
,
что
система
в
безопасности
—
неверный
запрос
на
мастер
(
DELETE
/
DR
OP
/TRUNCA
TE
),
и
у
слейвов
так
ая
же
пор-
ция
данных
(точнее
их
отсутствие).
Существуют
три
принципиально
различных
по
дхо
да
к
резервному
к
о-
пированию
данных
P
ostgreSQL:
∙
SQL
бэк
ап;
∙
Бэк
ап
уровня
файловой
системы;
∙
Непрерывное
резервное
к
опирование;
Каждый
из
этих
по
дхо
дов
имеет
свои
сильные
и
слабые
стороны.
261
11.2.
SQL
бэкап
11.2
SQL
бэкап
Идея
этого
подх
о
да
в
создании
тек
стового
файла
с
к
омандами
SQL.
Т
ак
ой
файл
мо
жно
передать
обратно
на
сервер
и
воссоздать
базу
данных
в
том
же
состоянии,
в
котором
она
была
во
время
бэкапа.
У
P
ostgreSQL
для
этого
есть
специ
альная
утилита
—
pg_dump
.
Пример
использования
pg_dump
:
Листинг
11.1
Создаем
бэкап
с
помощью
pg_dump
Line
1
$
p
g_d
ump
d
b
na
m
e >
o
u
t
f
i
l
e
Для
восст
ановления
так
ого
бэкапа
достаточно
выполнить:
Листинг
11.2
Восстанавливаем
бэкап
Line
1
$
p
s
q
l
db
n
a
m
e <
i
n
f
i
l
e
При
этом
базу
данных
dbname
потребу
ется
создать
перед
восст
ановле-
нием.
Т
акж
е
потребуетс
я
создать
пользователей,
которые
имеют
доступ
к
данным,
к
оторые
восст
анавливаютс
я
(это
можно
и
не
делать,
но
тогда
про-
сто
в
выводе
восст
ановления
бу
дут
ошибки).
Если
нам
требуетс
я,
чтобы
восст
ановление
прекратилось
при
возникновении
ошибки,
тогда
потребу-
етс
я
восстанавливать
бэкап
таким
способом:
Листинг
11.3
Восстанавливаем
бэкап
Line
1
$
p
s
q
l
-
-
s
e
t
O
N
_
E
R
R
O
R
_
S
T
O
P
=
o
n
db
n
a
m
e <
i
n
f
i
l
e
Т
акж
е,
можно
делать
бэкап
и
сразу
восстанавливать
его
в
другую
базу:
Листинг
11.4
Бэкап
в
другую
БД
Line
1
$
p
g_d
ump
-
h
h
o
s
t
1
d
b
n
a
m
e
|
p
s
q
l
-
h
h
o
s
t
2
d
b
n
am
e
После
восстановления
бэкапа
желательно
запу
стить
ANAL
YZE
,
чтобы
оптимизатор
запросов
обновил
ст
атистику
.
А
что,
если
нужно
с
делать
бэкап
не
о
дной
базы
данных,
а
всех,
да
и
еще
получить
в
бэкапе
информацию
про
роли
и
т
аблицы?
В
т
аком
слу-
чае
у
P
ostgreSQL
есть
утилита
pg_dumpall
.
pg_dumpall
использу
етс
я
для
создания
бэк
апа
данных
всего
кластера
PostgreSQL:
Листинг
11.5
Бэкап
кластера
PostgreSQL
Line
1
$
p
g
_
d
u
m
p
a
l
l
>
o
u
t
f
i
l
e
Для восстановления т
акого бэкапа дост
аточно
выполнить от
супер-
пользователя:
262
11.2.
SQL
бэкап
Листинг
11.6
Восстановления
бэкапа
PostgreSQL
Line
1
$
p
s
q
l
-
f
i
n
f
i
l
e
p
o
s
t
g
r
e
s
SQL
бэк
ап
больших
баз
данных
Нек
оторые
операционные
системы
имеют
ограничения
на
максималь-
ный
размер
файла,
что
мо
жет
вызывать
проблемы
при
создании
больших
бэк
апов
через
pg_dump
.
К
счастью,
pg_dump
мо
жете
бэкапить
в
ст
андарт-
ный
выво
д.
Т
ак
что
можно
использовать
ст
андартные
инструменты
Unix,
чтобы
обойти
эту
проблему
.
Есть
неск
олько
возможных
способов:
∙
Использовать
с
жатие
для
бэкапа
Мо
жно
использовать
программу
сж
атия
данных,
например
GZIP:
Листинг
11.7
Сжатие
бэкапа
PostgreSQL
Line
1
$
p
g_d
ump
d
b
na
m
e
|
g
z
i
p
>
f
i
l
e
n
a
m
e
.
g
z
Восст
ановление:
Листинг
11.8
Восстановление
бэкапа
PostgreSQL
Line
1
$
g
u
n
z
i
p
-
c
f
i
l
e
n
a
m
e
.
g
z
|
p
s
q
l
d
b
n
a
m
e
или
Листинг
11.9
Восстановление
бэкапа
PostgreSQL
Line
1
c
a
t
f
i
l
e
n
a
m
e
.
g
z
|
g
u
n
z
i
p
|
p
s
q
l
d
b
n
a
m
e
∙
Использовать
к
оманду
split
Команда
split
позволяет
разделить
вывод
в
файлы
меньшего
разме-
ра,
которые
являются
подх
одящими
по
размеру
для
файловой
систе-
мы.
Например,
бэк
ап
делится
на
куски
по
1
мегабайту:
Листинг
11.10
Создание
бэкапа
PostgreSQL
Line
1
$
p
g_d
ump
d
b
na
m
e
|
s
p
l
i
t
-
b
1
m
-
f
i
l
e
n
a
m
e
Восст
ановление:
Листинг
11.11
Восстановление
бэкапа
PostgreSQL
Line
1
$
c
a
t
f
i
l
e
n
a
m
e
*
|
p
s
q
l
d
b
n
a
m
e
263
11.3.
Бэкап
уровня
файловой
системы
∙
Использовать
пользовательский
формат
дампа
pg_dump
P
ostgreSQL
построен
на
системе
с
библиотек
ой
сж
атия
Zlib,
поэтому
пользовательский
формат
бэкапа
бу
дет
в
с
жатом
виде.
Это
по
хо
ж
е
на
мето
д
с
использованием
GZIP
,
но
он
имеет
дополнительное
пре-
имущество
—
таблицы
могут
быть
восст
ановлены
выборочно.
Минус
т
акого
бэк
апа
—
восстановить
возможно
только
в
такую
же
версию
P
ostgreSQL
(отличатьс
я
мо
жет
только
патч
релиз,
третья
цифра
по-
сле
точки
в
версии):
Листинг
11.12
Создание
бэкапа
PostgreSQL
Line
1
$
p
g_d
ump
-
Fc
d
b
n
a
m
e >
f
i
l
e
n
a
m
e
Через
psql
т
акой
бэк
ап
не
восстановить,
но
для
этого
есть
утилита
pg_restore
:
Листинг
11.13
Восстановление
бэкапа
PostgreSQL
Line
1
$
p
g
_
r
e
s
t
o
r
e
-
d
db
n
a
m
e
f
i
l
e
n
a
m
e
При
слишком
большой
базе
данных,
вариант
с
командой
split
нужно
к
омбинировать
со
сж
атием
данных.
11.3
Бэк
ап
уровня
файловой
системы
Аль
тернативный
метод
резервного
копирования
заключается
в
непо-
средственном
копировании
файлов,
которые
P
ostgreSQL
использует
для
хранения
данных
в
базе
данных.
Например:
Листинг
11.14
Бэкап
PostgreSQL
файлов
Line
1
$
t
a
r
-
c
f
b
a
c
k
u
p
.
t
a
r
/
u
s
r
/
l
o
c
a
l
/
p
g
s
q
l
/
d
a
t
a
Но
есть
два
ограничения,
к
оторые
делает
этот
мето
д
нецелесообраз-
ным,
или,
по
крайней
мере,
у
ступающим
SQL
бэкапу:
∙
P
ostgreSQL
база
данных
должна
быть
ост
ановлена,
для
того,
чтобы
получить
акту
альный
бэкап
(PostgreSQL
дер
жит
мно
ж
ество
объек-
тов
в
памяти,
буферизация
файловой
системы).
Излишне
говорить,
что
во
время
восстановления
т
акого
бэкапа
потребу
етс
я
такж
е
ост
а-
новить
P
ostgreSQL;
∙
Не получитс
я восст
ановить тольк
о определенные
данные с т
ак
ого
бэк
апа;
264
11.4.
Непрерывное
резервное
копирование
Как
аль
тернатива,
мо
жно
делать
снимки
(snapshot)
файлов
системы
(папки
с
файлами
PostgreSQL).
В
так
ом
случае
останавливать
PostgreSQL
не
требуетс
я.
Однако,
резервная
копия,
созданная
таким
образом,
сохра-
няет
файлы
базы
данных
в
состоянии,
ка
к
если
бы
сервер
базы
данных
был
неправильно
ост
ановлен.
Поэтому
при
запу
ске
P
ostgreSQL
из
резерв-
ной
копии,
он
бу
дет
думать,
что
предыдущий
экземпляр
сервера
вышел
из
строя
и
восстановит
данные
в
соответствии
с
данными
журнала
W
AL.
Это
не
проблема,
просто
надо
знать
про
это
(и
не
забыть
включить
W
AL
файлы
в
резервную
к
опию).
Т
акже,
если
файловая
система
PostgreSQL
распределена
по
разным
файловым
системам,
то
т
акой
метод
бэкапа
бу-
дет
очень
ненадежным
—
снимки
файлов
системы
должны
быть
с
деланы
о
дновременно.
Почитайте
документ
ацию
файловой
системы
очень
внима-
тельно,
прежде
чем
довер
ять
снимк
ам
файлов
системы
в
т
аких
ситу
ациях.
Т
акж
е
возмо
жен вариант
с
использованием
rsync
утилиты.
Первым
запу
ском
rsync
мы
к
опируем
основные
файлы
с
директории
P
ostgreSQL
(P
ostgreSQL
при
этом
продолж
ает
работу).
После
этого
мы
ост
анавлива-
ем
P
ostgreSQL
и
запуск
аем
повторно
rsync
.
Второй
запуск
rsync
пройдет
гораздо
быстрее,
чем
первый,
потому
что
бу
дет
передавать
относительно
небольшой
размер
данных,
и
конечный
резу
ль
т
ат
бу
дет
соответствовать
ост
ановленной
СУБД.
Этот
метод
позволяет
делать
бэк
ап
уровня
файло-
вой
системы
с
минимальным
временем
просто
я.
11.4
Непрерывное
ре
зервное
копирование
P
ostgreSQL по
ддер
живает упреждающую
запись
логов
(W
rite
Ahead
Log,
W
AL)
в
pg_xlog
директорию,
к
оторая
нах
о
дится
в
директории
дан-
ных
СУБД.
В
логи
пишутс
я
все
изменения,
с
деланные
с
данными
в
СУБД.
Этот
журнал
существу
ет
прежде
всего
для
безопасности
во
время
кра-
х
а
PostgreSQL:
если
проис
х
одят
сбои
в
системе,
базы
данных
могут
быть
восст
ановлены
с
помощью
«перезапуск
а»
этого
журнала.
Т
ем
не
менее,
су-
ществование
журнала
делает
возмо
жным
использование
третьей
страте-
гии
для
резервного
копирования
баз
данных:
мы
мож
ем
объединить
бэкап
уровня
файловой
системы
с
резервной
к
опией
W
AL
файлов.
Если
требу-
етс
я
восст
ановить
т
ак
ой
бэк
ап,
то
мы
восст
анавливаем
файлы
резервной
к
опии
файловой
системы,
а
затем
«перезапуск
аем»
с
резервной
к
опии
фай-
лов
W
AL
для
приведения
системы
к
акту
альному
состо
янию.
Этот
по
дхо
д
являетс
я
более
сложным
для
администрирования,
чем
любой
из
предыду-
щих
по
дхо
дов,
но
он
имеет
некоторые
преимущества:
∙
Не
нужно
согласовывать
файлы
резервной
копии
системы.
Любая
внутренняя
противоречивость
в
резервной
копии
бу
дет
исправлена
путем
преобразования
журнала
(не
отличаетс
я
от
того,
что
происх
о-
дит
во
время
восст
ановления
после
сбоя);
265
11.4.
Непрерывное
резервное
копирование
∙
Восст
ановление
состояния
сервера
для
определенного
момента
вре-
мени;
∙
Если
мы
посто
янно бу
дем «ск
армливать»
файлы
W
AL
на
другую
машину
,
к
оторая
была
загружена
с
тех
ж
е
файлов
резервной
базы,
то
у
нас
бу
дет
нах
одящийс
я
всегда
в
актуальном
состоянии
резервный
сервер
P
ostgreSQL
(создание
сервера
горячего
резерва);
Как
и
бэк
ап
файловой
системы,
этот
мето
д
мо
жет
по
ддер
живать
толь-
к
о восст
ановление всей
базы данных
кластера.
Кроме того,
он требу
ет
много
мест
а
для
хранения
W
AL
файлов.
Настройк
а
Первый
шаг
—
активировать
ар
хивирование.
Эта
процедура
бу
дет
к
опировать W
AL
файлы
в
ар
хивный к
ат
алог из
ст
андартного к
аталог
а
pg_xlog
.
Это
делаетс
я
в
файле
p
ostgresql
.
conf
:
Листинг
11.15
Настройка
архивирования
Line
1
a
r
c
h
i
v
e
_
m
o
d
e
=
o
n
#
e
n
a
b
l
e
a
r
c
h
i
v
i
n
g
-
a
r
c
h
i
v
e
_
c
o
m
m
a
n
d
=
’
c
p
-
v %
p
/
d
a
t
a
/
p
g
s
q
l
/
a
r
c
h
i
v
e
s
/
%
f
’
-
a
r
c
h
i
v
e
_
t
i
m
e
o
u
t
=
3
0
0
#
t
i
m
e
o
u
t
t
o
c
l
o
s
e
b
u
f
f
e
r
s
После
этого
необх
о
димо
перенести
файлы
(в
порядк
е
их
появления)
в
ар
хивный
кат
алог
.
Для
этого
можно
использовать
функцию
rsync
.
Можно
пост
авить
функцию
в
cron
и,
таким
образом,
файлы
могут
автоматически
перемещатьс
я
между
хост
ами
каждые
нескольк
о
минут:
Листинг
11.16
Копирование
W
AL
файлов
на
другой
х
ост
Line
1
$
r
s
y
n
c
-
a
v
z
-
-
d
e
l
e
t
e
p
r
o
d
1
:
/
d
a
t
a
/
p
g
s
q
l
/
a
r
c
h
i
v
e
s
/
\
-
/
d
a
t
a
/
p
g
s
q
l
/
a
r
c
h
i
v
e
s
/ >
/
d
e
v
/
n
u
l
l
В
конце
необ
хо
димо
ск
опировать
файлы
в
кат
алог
pg_xlog
на
сервере
P
ostgreSQL
(он
долж
ен
быть
в
режиме
восст
ановления).
Для
этого
необх
о-
димо
в
кат
алоге
данных
PostgreSQL
создать
файл
recov
ery
.
conf
с
заданной
к
омандой
копирования
файлов
из
архива
в
нужную
директорию:
Листинг
11.17
recov
ery
.conf
Line
1
r
e
s
t
o
r
e
_
c
o
m
m
a
n
d
=
’
c
p
/
d
a
t
a
/
p
g
s
q
l
/
a
r
c
h
i
v
e
s
/
%
f
"
%p
"
’
Документ
ация
P
ostgreSQL
предлагает
х
орошее
описание
настройки
непрерывного
копирования,
поэтому
данная
глава
не
бу
дет
углублятьс
я
в
дет
али
(например,
как
перенести
директорию
СУБД
с
о
дного
сервера
на
другой,
к
акие
могут
быть
проблемы).
Более
подробно
вы
мо
ж
ете
почи-
т
ать
по
этой
ссылке
.
266
11.5.
Утилиты
для
непрерывного
резервного
копирования
11.5
Утилиты
для
непрерывного
резервного
к
опирования
Непрерывное
резервное
к
опирования
-
один
из
лучших
способов
для
со-
здания
бэк
апов
и
их
восст
ановления.
Нередко
бэкапы
со
храняются
на
той
ж
е
файловой
системе,
на
к
оторой
располо
жена
база
данных.
Это
не
очень
безопасно,
т
.к.
при
выхо
де
диск
овой
системы
сервера
из
строя
вы
мо
жете
потер
ять
все
данные
(и
базу
,
и
бэк
апы),
или
попросту
столкнуться
с
тем,
что
на
ж
естк
ом
диск
е
закончитс
я
свобо
дное
место.
Поэтому
лучше,
к
огда
бэк
апы
складываются
на
отдельный
сервер
или
в
«облачное
хранилище»
(например
A
WS
S3
).
Чтобы
не писать
свой
«велосипед» для
автомати-
зации
этого
процесса
на
сего
дняшний
день
существует
набор
программ,
к
оторые облегчают процесс настройки и по
ддержки процесса создания
бэк
апов
на
основе
непрерывного
резервного
копирования.
W
AL-E
W
AL-E
предназначена
для
непрерывной
ар
хивации
P
ostgreSQL
W
AL-
logs
в
Amazon
S3
или
Windows
Azure
(начиная
с
версии
0.7)
и
управления
использованием
pg_start_bac
kup
и
pg_stop_bac
kup
.
Утилит
а
написана
на
Python
и
разработ
ана
в
компании
Heroku
,
где
её
активно
используют
.
У
ст
ановка
У
W
AL-E
есть
пара
зависимостей:
lzop
,
psql
,
pv
(в
ст
арых
версиях
ис-
пользу
ется
m
buffer
),
p
ython
3.4+
и
неск
олько
p
ython
библиотек
(
geven
t
,
b
oto
,
azure
).
Т
акже
для
у
добства
настроек
переменных
среды
уст
анавливаетс
я
daemon
to
ols
.
На
Ubun
tu
это
можно
все
поставить
одной
командой:
Листинг
11.18
У
становк
а
зависимостей
для
W
AL-E
Line
1
$
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
g
i
t
-
c
o
r
e
p
y
t
h
o
n
-
d
e
v
p
y
t
h
o
n
-
s
e
t
u
p
t
o
o
l
s
p
y
t
h
o
n
-
p
i
p
b
u
i
l
d
-
e
s
s
e
n
t
i
a
l
l
i
b
e
v
e
n
t
-
d
e
v
l
z
o
p
p
v
d
a
e
m
o
n
t
o
o
l
s
d
a
e
m
o
n
t
o
o
l
s
-
r
u
n
Т
еперь
у
становим
W
AL-E:
Листинг
11.19
У
становк
а
W
AL-E
Line
1
$
p
i
p
i
n
s
t
a
l
l
h
t
t
p
s
:
/
/
g
i
t
h
u
b
.
c
om
/
w
a
l
-
e
/
w
a
l
-
e
/
a
r
c
h
i
v
e
/
v
1
.
0
.
3
.
t
a
r
.
g
z
После
у
спешной
уст
ановки
можно
начать
работать
с
W
AL-E.
267
11.5.
Утилиты
для
непрерывного
резервного
копирования
Настройк
а
и
работа
Как
уже
писалось,
W
AL-E
сливает
все
данные
в
A
WS
S3,
поэтому
нам
потребуютс
я
«A
ccess
Key
ID»
,
«Secret
A
ccess
Key»
и
«A
WS
Region»
(эти
данные
можно
найти
в
акк
аунте
Amazon
A
WS).
Команда
для
загрузки
бэк
апа
всей
базы
данных
в
S3:
Листинг
11.20
Загрузка
бэкапа
всей
базы
данных
в
S3
Line
1
A
W
S
_
R
E
G
I
O
N
=
.
.
.
A
W
S
_
S
E
C
R
E
T
_
A
C
C
E
S
S
_
K
E
Y
=
.
.
.
w
a
l
-
e
\
-
-
k
A
W
S
_
A
C
C
E
S
S
_
K
E
Y
_
I
D
\
-
-
-
s
3
-
p
r
e
f
i
x
=s
3
:
/
/
s
o
m
e
-
b
u
c
k
e
t
/
d
i
r
e
c
t
o
r
y
/
o
r
/
w
h
a
t
e
v
e
r
\
-
b
a
c
k
u
p
-
p
u
s
h
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
9
.
2
/
m
a
i
n
Г
де
s3
-
prefix
—
URL,
к
оторый
со
держит
имя
S3
бакет
а
(buck
et)
и
путь
к
папк
е,
ку
да
следу
ет
складывать
резервные
копии.
Команда
для
загрузки
W
AL-логов
на
S3:
Листинг
11.21
Загрузка
W
AL-логов
на
S3
Line
1
A
W
S
_
R
E
G
I
O
N
=
.
.
.
A
W
S
_
S
E
C
R
E
T
_
A
C
C
E
S
S
_
K
E
Y
=
.
.
.
w
a
l
-
e
\
-
-
k
A
W
S
_
A
C
C
E
S
S
_
K
E
Y
_
I
D
\
-
-
-
s
3
-
p
r
e
f
i
x
=s
3
:
/
/
s
o
m
e
-
b
u
c
k
e
t
/
d
i
r
e
c
t
o
r
y
/
o
r
/
w
h
a
t
e
v
e
r
\
-
w
a
l
-
p
u
s
h
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
9
.
2
/
m
a
i
n
/
p
g
_
x
l
o
g
/
W
A
L
_
S
E
G
M
E
N
T
_
L
O
N
G
_
H
E
X
Для
управления
этими
переменными
окруж
ения
мо
жно
использовать
к
оманду
envdir
(идет
в
поставк
е
с
daemontools
).
Для
этого
создадим
envdir
к
аталог:
Листинг
11.22
W
AL-E
с
envdir
Line
1
$
m
k
d
i
r
-
p
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
-
$
e
c
h
o
"
a
w
s
_
r
e
g
i
o
n
" >
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
/
A
W
S
_
R
E
G
I
O
N
-
$
e
c
h
o
"
s
e
c
r
e
t
-
k
e
y
"
>
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
/
A
W
S
_
S
E
C
R
E
T
_
A
C
C
E
S
S
_
K
E
Y
-
$
e
c
h
o
"
a
c
c
e
s
s
-
k
e
y
"
>
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
/
A
W
S
_
A
C
C
E
S
S
_
K
E
Y
_
I
D
5
$
e
c
h
o
’
s
3
:
/
/
s
o
m
e
-
b
u
c
k
e
t
/
d
i
r
e
c
t
o
r
y
/
o
r
/
w
h
a
t
e
v
e
r
’
>
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
/W
A
L
E
_
S
3
_
P
R
E
F
I
X
-
$
c
h
o
w
n
-
R
r
o
o
t
:
p
o
s
t
g
r
e
s
/
e
t
c
/
w
a
l
-
e
.
d
После
создания
данного
к
аталог
а
появляетс
я
возможность
запу
скать
W
AL-E
команды
гораздо
проще
и
с
меньшим
риском
случайного
исполь-
зования
нек
орректных
значений:
Листинг
11.23
W
AL-E
с
envdir
268
11.5.
Утилиты
для
непрерывного
резервного
копирования
Line
1
$
e
n
v
d
i
r
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
w
a
l
-
e
b
a
c
k
u
p
-
p
u
s
h
.
.
.
-
$
e
n
v
d
i
r
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
w
a
l
-
e
w
a
l
-
p
u
s
h
.
.
.
Т
еперь
настроим
P
ostgreSQL
для
сбрасывания
W
AL-логов
в
S3
c
помо-
щью
W
AL-E.
Отредактиру
ем
p
ostgresql
.
conf
:
Листинг
11.24
Настройка
PostgreSQL
Line
1
w
a
l
_
l
e
v
e
l
=
h
o
t
_
s
t
a
n
d
b
y
# или
a
r
c
h
i
v
e
,
если
P
o
s
t
g
r
e
S
Q
L
<
9
.
0
-
a
r
c
h
i
v
e
_
m
o
d
e
=
o
n
-
a
r
c
h
i
v
e
_
c
o
m
m
a
n
d
=
’
e
n
v
d
i
r
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
/
u
s
r
/
l
o
c
a
l
/
b
i
n
/
w
a
l
-
e
w
a
l
-
p
u
s
h
%
p
’
-
a
r
c
h
i
v
e
_
t
i
m
e
o
u
t
=
6
0
Лучше
ук
азать
полный
путь
к
W
AL-E
(можно
узнать
к
омандой
which
w
al-e
),
поск
ольку
PostgreSQL
мож
ет
его
не
найти.
После
этого
нужно
пе-
регрузить
P
ostgreSQL.
В
логах
базы
вы
должны
увидеть
что-то
подобное:
Листинг
11.25
Логи
PostgreSQL
Line
1
2
0
1
6
-
1
1
-
0
7
1
4
:
5
2
:
1
9
U
T
C
L
O
G
:
d
a
t
a
b
a
s
e
s
y
s
t
e
m
w
a
s
s
h
u
t
do
wn
a
t
2
0
1
6
-
1
1
-
0
7
1
4
:
5
1
:
4
0
U
T
C
-
2
0
1
6
-
1
1
-
0
7
1
4
:
5
2
:
1
9
U
T
C
L
O
G
:
d
a
t
a
b
a
s
e
s
y
s
t
e
m
i
s
r
e
a
d
y
t
o
a
c
c
e
p
t
c
o
n
n
e
c
t
i
o
n
s
-
2
0
1
6
-
1
1
-
0
7
1
4
:
5
2
:
1
9
U
T
C
L
O
G
:
a
u
t
o
v
a
c
u
u
m
l
a
u
n
c
h
e
r
s
t
a
r
t
e
d
-
2
0
1
6
-
1
1
-
0
7
T
1
4
:
5
2
:
1
9
.
7
8
4
+
0
0
p
i
d
=
7
6
5
3
w
a
l
_
e
.
w
o
r
k
e
r
.
s
3
_
w
o
r
k
e
r
I
NF
O
M
S
G
:
b
e
g
i
n
a
r
c
h
i
v
i
n
g
a
f
i
l
e
5
DE
T
A
I
L
:
U
p
l
o
a
d
i
n
g
"
p
g
_
x
l
o
g
/
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
"
t
o
"
s
3
:
/
/
c
l
e
v
e
r
d
b
-
p
g
-
b
a
c
k
u
p
s
/
p
g
/
w
a
l
_
0
0
5
/
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
.
l
z
o
"
.
-
2
0
1
6
-
1
1
-
0
7
1
4
:
5
2
:
1
9
U
T
C
L
O
G
:
i
n
c
o
m
p
l
e
t
e
s
t
a
r
t
u
p
p
a
c
k
e
t
-
2
0
1
6
-
1
1
-
0
7
T
1
4
:
5
2
:
2
8
.
2
3
4
+
0
0
p
i
d
=
7
6
5
3
w
a
l
_
e
.
w
o
r
k
e
r
.
s
3
_
w
o
r
k
e
r
I
NF
O
M
S
G
:
c
o
m
p
l
e
t
e
d
a
r
c
h
i
v
i
n
g
t
o
a
f
i
l
e
-
DE
T
A
I
L
:
A
r
c
h
i
v
i
n
g
t
o
"
s
3
:
/
/
c
l
e
v
e
r
d
b
-
p
g
-
b
a
c
k
u
p
s
/
p
g
/
w
a
l
_
0
0
5
/
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
.
l
z
o
"
c
o
m
p
l
e
t
e
a
t
2
1
5
8
3
.
3
KiB
/
s
.
-
2
0
1
6
-
1
1
-
0
7
T
1
4
:
5
2
:
2
8
.
3
4
1
+
0
0
p
i
d
=
7
6
9
7
w
a
l
_
e
.
w
o
r
k
e
r
.
s
3
_
w
o
r
k
e
r
I
NF
O
M
S
G
:
b
e
g
i
n
a
r
c
h
i
v
i
n
g
a
f
i
l
e
10
DE
T
A
I
L
:
U
p
l
o
a
d
i
n
g
"
p
g
_
x
l
o
g
/
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
2
.
0
0
0
0
0
0
2
0
.
b
a
c
k
u
p
"
t
o
"
s
3
:
/
/
c
l
e
v
e
r
d
b
-
p
g
-
b
a
c
k
u
p
s
/
p
g
/
w
a
l
_
0
0
5
/
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
2
.
0
0
0
0
0
0
2
0
.
b
a
c
k
u
p
.
l
z
o
"
.
-
2
0
1
6
-
1
1
-
0
7
T
1
4
:
5
2
:
3
4
.
0
2
7
+
0
0
p
i
d
=
7
6
9
7
w
a
l
_
e
.
w
o
r
k
e
r
.
s
3
_
w
o
r
k
e
r
I
NF
O
M
S
G
:
c
o
m
p
l
e
t
e
d
a
r
c
h
i
v
i
n
g
t
o
a
f
i
l
e
-
DE
T
A
I
L
:
A
r
c
h
i
v
i
n
g
t
o
"
s
3
:
/
/
c
l
e
v
e
r
d
b
-
p
g
-
b
a
c
k
u
p
s
/
p
g
/
w
a
l
_
0
0
5
/
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
2
.
0
0
0
0
0
0
2
0
.
b
a
c
k
u
p
.
l
z
o
"
c
o
m
p
l
e
t
e
a
t
0
0
Ki
B
/
s
.
269
11.5.
Утилиты
для
непрерывного
резервного
копирования
-
2
0
1
6
-
1
1
-
0
7
T
1
4
:
5
2
:
3
4
.
1
8
7
+
0
0
p
i
d
=
7
7
1
1
w
a
l
_
e
.
w
o
r
k
e
r
.
s
3
_
w
o
r
k
e
r
I
NF
O
M
S
G
:
b
e
g
i
n
a
r
c
h
i
v
i
n
g
a
f
i
l
e
-
DE
T
A
I
L
:
U
p
l
o
a
d
i
n
g
"
p
g
_
x
l
o
g
/
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
2
"
t
o
"
s
3
:
/
/
c
l
e
v
e
r
d
b
-
p
g
-
b
a
c
k
u
p
s
/
p
g
/
w
a
l
_
0
0
5
/
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
2
.
l
z
o
"
.
15
2
0
1
6
-
1
1
-
0
7
T
1
4
:
5
2
:
4
0
.
2
3
2
+
0
0
p
i
d
=
7
7
1
1
w
a
l
_
e
.
w
o
r
k
e
r
.
s
3
_
w
o
r
k
e
r
I
NF
O
M
S
G
:
c
o
m
p
l
e
t
e
d
a
r
c
h
i
v
i
n
g
t
o
a
f
i
l
e
-
DE
T
A
I
L
:
A
r
c
h
i
v
i
n
g
t
o
"
s
3
:
/
/
c
l
e
v
e
r
d
b
-
p
g
-
b
a
c
k
u
p
s
/
p
g
/
w
a
l
_
0
0
5
/
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
2
.
l
z
o
"
c
o
m
p
l
e
t
e
a
t
2
4
6
6
.
6
7
KiB
/
s
.
Если
ничего
по
х
ож
его
в
логах
не
видно,
тогда
нужно
смотреть
что
за
ошибк
а
по
является
и
исправлять
её.
Для
того,
чтобы
бэк
апить
всю
базу
,
дост
аточно
выполнить
данную
команду:
Листинг
11.26
Загрузка
бэкапа
всей
базы
данных
в
S3
Line
1
$
e
n
v
d
i
r
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
w
a
l
-
e
b
a
c
k
u
p
-
p
u
s
h
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
9
.
2
/
m
a
i
n
-
2
0
1
6
-
1
1
-
0
7
T
1
4
:
4
9
:
2
6
.
1
7
4
+
0
0
p
i
d
=
7
4
9
3
w
a
l
_
e
.
o
p
e
r
a
t
o
r
.
s
3
_
o
p
e
r
a
t
o
r
IN
FO
M
S
G
:
s
t
a
r
t
u
p
l
o
a
d
p
o
s
t
g
r
e
s
v
e
r
s
i
o
n
m
e
t
a
d
a
t
a
-
DE
T
A
I
L
:
U
p
l
o
a
d
i
n
g
t
o
s
3
:
/
/
c
l
e
v
e
r
d
b
-
p
g
-
b
a
c
k
u
p
s
/
p
g
/
b
a
s
e
b
a
c
k
u
p
s
_
0
0
5
/
b
a
s
e
_
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
6
_
0
0
0
0
0
0
3
2
/
e
x
t
e
n
d
e
d
_
v
e
r
s
i
o
n
.
t
x
t
.
-
2
0
1
6
-
1
1
-
0
7
T
1
4
:
4
9
:
3
2
.
7
8
3
+
0
0
p
i
d
=
7
4
9
3
w
a
l
_
e
.
o
p
e
r
a
t
o
r
.
s
3
_
o
p
e
r
a
t
o
r
IN
FO
M
S
G
:
p
o
s
t
g
r
e
s
v
e
r
s
i
o
n
m
e
t
a
d
a
t
a
u
p
l
o
a
d
c
o
m
p
l
e
t
e
5
2
0
1
6
-
1
1
-
0
7
T
1
4
:
4
9
:
3
2
.
8
5
9
+
0
0
p
i
d
=
7
4
9
3
w
a
l
_
e
.
w
o
r
k
e
r
.
s
3
_
w
o
r
k
e
r
I
NF
O
M
S
G
:
b
e
g
i
n
n
i
n
g
v
o
l
u
m
e
c
o
m
p
r
e
s
s
i
o
n
-
DE
T
A
I
L
:
B
u
i
l
d
i
n
g
v
o
l
u
m
e
0
.
-
.
.
.
-
HI
N
T
:
C
h
e
c
k
t
h
a
t
y
o
u
r
a
r
c
h
i
v
e
_
c
o
m
m
a
n
d
i
s
e
x
e
c
u
t
i
n
g
p
r
o
p
e
r
l
y
.
p
g
_
s
t
o
p
_
b
a
c
k
u
p
c
a
n
b
e
c
a
n
c
e
l
e
d
s
a
f
e
l
y
,
b
u
t
t
h
e
d
a
t
a
b
a
s
e
b
a
c
k
u
p
w
i
l
l
n
o
t
b
e
u
s
a
b
l
e
w
i
t
h
o
u
t
a
l
l
t
h
e
W
A
L
s
e
g
m
e
n
t
s
.
-
N
O
T
I
C
E
:
p
g
_
s
t
o
p
_
b
a
c
k
u
p
c
o
m
p
l
e
t
e
,
a
l
l
r
e
q
u
i
r
e
d
W
A
L
s
e
g
m
e
n
t
s
h
a
v
e
b
e
e
n
a
r
c
h
i
v
e
d
Данный
бэкап
лучше
делать
раз
в
сутки
(например,
добавить
в
crontab
).
На
рис
11.1
-
11.3
видно
как
хранятс
я
бэкапы
на
S3.
Все
бэк
апы
сж
аты
через
lzop
.
Данный
алгоритм
сжимает
хуж
е
чем
gzip,
но
скорость
с
жатия
намного
быстрее
(приблизительно
25
Мб/сек
используя
5%
ЦПУ).
Чтобы
уменьшить
нагрузку
на
чтение
с
жестк
ого
диск
а
бэкапы
отправляютс
я
че-
рез
pv
утилиту
(опцией
cluster
-
read
-
rate
-
limit
можно
ограничить
ск
орость
чтения,
если
это
требу
ется).
Т
еперь
перейдем
к
восстановлению
данных.
Для
восстановления
базы
из
резервной
к
опии
используетс
я
backup-fetc
h
к
оманда:
270
11.5.
Утилиты
для
непрерывного
резервного
копирования
Рис.
11.1:
Папк
а
бэкапов
на
S3
Рис.
11.2:
Папк
а
бэкапов
базы
на
S3
Рис.
11.3:
Папк
а
W
AL-логов
на
S3
Листинг
11.27
Восстановление
бэкапа
базы
из
S3
Line
1
$
s
u
d
o
-
u
p
o
s
t
g
r
e
s
b
a
s
h
-
c
"
e
n
v
d
i
r
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
w
a
l
-
e
271
11.5.
Утилиты
для
непрерывного
резервного
копирования
-
-
s
3
-
p
r
e
f
i
x
=s
3
:
/
/
s
o
m
e
-
b
u
c
k
e
t
/
d
i
r
e
c
t
o
r
y
/
o
r
/
w
h
a
t
e
v
e
r
b
a
c
k
u
p
-
f
e
t
c
h
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
9
.
2
/
m
a
i
n
L
A
T
E
S
T
"
Г
де
LA
TEST
означает
,
что
база
восст
ановится
из
последнего
акту
аль-
ного
бэкапа
(PostgreSQL
в
это
время
долж
ен
быть
ост
ановлен).
Для
вос-
ст
ановления
из
более
поздней
резервной
копии:
Листинг
11.28
Восстановление
из
поздней
резервной
копии
Line
1
$
s
u
d
o
-
u
p
o
s
t
g
r
e
s
b
a
s
h
-
c
"
e
n
v
d
i
r
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
w
a
l
-
e
-
-
s
3
-
p
r
e
f
i
x
=s
3
:
/
/
s
o
m
e
-
b
u
c
k
e
t
/
d
i
r
e
c
t
o
r
y
/
o
r
/
w
h
a
t
e
v
e
r
b
a
c
k
u
p
-
f
e
t
c
h
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
9
.
2
/
m
a
i
n
b
a
s
e
_
L
O
N
G
W
A
L
N
U
M
B
E
R
_
P
O
S
I
T
I
O
N
_
N
U
M
B
E
R
"
Для
получения
списка
доступных
резервных
копий
есть
к
оманда
backup
-
list
:
Листинг
11.29
Список
резервных
копий
Line
1
$
e
n
v
d
i
r
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
w
a
l
-
e
b
a
c
k
u
p
-
l
i
s
t
-
n
am
e
l
a
s
t
_
m
o
d
i
f
i
e
d
e
x
p
a
n
d
e
d
_
s
i
z
e
_
b
y
t
e
s
w
a
l
_
s
e
g
m
e
n
t
_
b
a
c
k
u
p
_
s
t
a
r
t
w
a
l
_
s
e
g
m
e
n
t
_
o
f
f
s
e
t
_
b
a
c
k
u
p
_
s
t
a
r
t
w
a
l
_
s
e
g
m
e
n
t
_
b
a
c
k
u
p
_
s
t
o
p
w
a
l
_
s
e
g
m
e
n
t
_
o
f
f
s
e
t
_
b
a
c
k
u
p
_
s
t
o
p
-
b
a
s
e
_
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
8
_
0
0
0
0
0
0
3
2
2
0
1
6
-
1
1
-
0
7
T1
4
:
0
0
:
0
7
.
0
0
0
Z
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
8
0
0
0
0
0
0
3
2
-
b
a
s
e
_
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
C
_
0
0
0
0
0
0
3
2
2
0
1
6
-
1
1
-
0
8
T1
5
:
0
0
:
0
8
.
0
0
0
Z
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
C
0
0
0
0
0
0
3
2
После
завершения
работы
с
основной
резервной
копией
для
полного
восст
ановления
нужно
счит
ать
W
AL-логи
(чтобы
данные
обновились
до
последнего
состо
яния).
Для
этого
используетс
я
recov
ery
.
conf
:
Листинг
11.30
recov
ery
.conf
Line
1
r
e
s
t
o
r
e
_
c
o
m
m
a
n
d
=
’
e
n
v
d
i
r
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
/
u
s
r
/
l
o
c
a
l
/
b
i
n
/
w
a
l
-
e
w
a
l
-
f
e
t
c
h
"
%
f
"
"
%p
"
’
После
создания
этого
файла
нужно
запу
стить
PostgreSQL.
Через
небольшой
интервал
времени
база
ст
анет
полностью
восстановленной.
Для
у
даления
старых
резервных
копий
(или
вообще
всех)
использу
ется
к
оманда
delete
:
Листинг
11.31
У
даление
резервных
копий
Line
1
# у
даление
ст
арых
бэк
апов
ст
арше
b
a
s
e
_
0
0
0
0
0
0
0
4
0
0
0
0
0
2
D
F
0
0
0
0
0
0
A
6
_
0
3
6
2
6
1
4
4
272
11.5.
Утилиты
для
непрерывного
резервного
копирования
-
$
e
n
v
d
i
r
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
w
a
l
-
e
d
e
l
e
t
e
-
-
c
o
n
f
i
r
m
b
e
f
o
r
e
b
a
s
e
_
0
0
0
0
0
0
0
4
0
0
0
0
0
2
D
F
0
0
0
0
0
0
A
6
_
0
3
6
2
6
1
4
4
-
# у
даление
всех
бэкапов
-
$
e
n
v
d
i
r
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
w
a
l
-
e
d
e
l
e
t
e
-
-
c
o
n
f
i
r
m
e
v
e
r
y
t
h
i
n
g
5
# у
далить
все
старше
последних
2
0
бэк
апов
-
$
e
n
v
d
i
r
/
e
t
c
/
w
a
l
-
e
.
d
/
e
n
v
w
a
l
-
e
d
e
l
e
t
e
-
-
c
o
n
f
i
r
m
r
e
t
a
i
n
2
0
Без
опции
--
confirm
команды
бу
дут
запуск
аться
и
показывать,
что
бу
дет
у
далятьс
я,
но
фактического
у
даления
не
бу
дет
производитьс
я
(dry
run).
Заключение
W
AL-E
помог
ает
автоматизировать
сбор
резервных
копий
с
PostgreSQL
и
хранить
их
в
достаточно
дешевом
и
надежном
хранилище
—
Amazon
S3
или
Windo
ws
Azure.
Barman
Barman
,
как
и
W
AL-E,
позволяет
создать
систему
для
бэкапа
и
вос-
ст
ановления
PostgreSQL
на
основе
непрерывного
резервного
копирования.
Barman
использует
для
хранения
бэк
апов
отдельный
сервер,
который
мо-
ж
ет собирать
бэкапы
как
с о
дного,
т
ак и
с
неск
ольких P
ostgreSQL
баз
данных.
У
ст
ановка
и
настройка
Р
ассмотрим простой
случай
с
одним
экземпляром
P
ostgreSQL
(о
дин
сервер)
и
пусть
его
хост
бу
дет
pghost
.
Наша
задача
—
автоматизировать
сбор
и
хранение
бэк
апов
этой
базы
на
другом
сервере
(его
х
ост
бу
дет
brhost
).
Для
взаимо
действия
эти
два
сервера
должны
быть
полностью
открыты
по
SSH
(доступ
без
пароля,
по
ключам).
Для
этого
можно
использовать
authorized_k
eys
файл.
Листинг
11.32
Проверка
подключения
по
SSH
Line
1
# Проверк
а
подключения
с
сервера
P
o
s
t
g
r
e
S
Q
L
(
p
g
h
o
s
t
)
-
$
s
s
h
b
a
r
m
a
n
@
b
r
h
o
s
t
-
# Проверк
а
по
дключения
с
сервера
бэк
апов
(
b
r
h
o
s
t
)
-
$
s
s
h
p
o
s
t
g
r
e
s
@
p
g
h
o
s
t
Далее
нужно
уст
ановить
на
сервере
для
бэкапов
barman.
Сам
barman
написан
на
python
и
имеет
пару
зависимостей:
python
2.6+,
rsync
и
python
библиотеки
(
argh
,
psycopg2
,
p
ython-dateutil
,
distribute
).
На
Ubuntu
все
зави-
симости
мо
жно
поставить
одной
командой:
Листинг
11.33
У
становк
а
зависимостей
barman
273
11.5.
Утилиты
для
непрерывного
резервного
копирования
Line
1
$
a
p
t
i
t
u
d
e
i
n
s
t
a
l
l
p
y
t
h
o
n
-
d
e
v
p
y
t
h
o
n
-
a
r
g
h
p
y
t
h
o
n
-
p
s
y
c
o
p
g
2
p
y
t
h
o
n
-
d
a
t
e
u
t
i
l
r
s
y
n
c
p
y
t
h
o
n
-
s
e
t
u
p
t
o
o
l
s
Далее
нужно
у
становить
barman:
Листинг
11.34
У
становк
а
barman
Line
1
$
t
a
r
-
x
z
f
b
a
r
m
a
n
-
2
.
1
.
t
a
r
.
g
z
-
$
c
d
b
a
r
m
a
n
-
2
.
1
/
-
$
.
/
s
e
t
u
p
.
p
y
b
u
i
l
d
-
$
s
u
d
o
.
/
s
e
t
u
p
.
p
y
i
n
s
t
a
l
l
Или
использу
я
PostgreSQL
Communit
y
APT
репозиторий
:
Листинг
11.35
У
становк
а
barman
Line
1
$
a
p
t
-
g
e
t
i
n
s
t
a
l
l
b
a
r
m
a
n
Т
еперь
перейдем
к
серверу
с
PostgreSQL.
Для
того,
чтобы
barman
мог
по
дключаться
к
базе
данных
без
проблем,
нам
нужно
выставить
настройки
доступа
в
к
онфигах
PostgreSQL:
Листинг
11.36
Отредактировать
в
p
ostgresql.conf
Line
1
l
i
s
t
e
n
_
a
d
r
e
s
s
=
’
*
’
Листинг
11.37
Добавить
в
pg_hba.conf
Line
1
h
o
s
t
a
l
l
a
l
l
b
r
h
o
s
t
/
3
2
t
r
u
s
t
После
этих
изменений
нужно
перегрузить
P
ostgreSQL.
Т
еперь
мо
жем
проверить
с
сервера
бэк
апов
подключение
к
PostgreSQL:
Листинг
11.38
Проверка
подключения
к
базе
Line
1
$
p
s
q
l
-
c
’
S
E
L
E
C
T
v
e
r
s
i
o
n
(
)
’
-
U
p
o
s
t
g
r
e
s
-
h
p
g
h
o
s
t
-
v
e
r
s
i
o
n
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
P
o
s
t
g
r
e
S
Q
L
9
.
3
.
1
o
n
x
8
6
_
6
4
-
u
n
k
n
o
w
n
-
l
i
n
u
x
-
g
n
u
,
c
o
m
p
i
l
e
d
b
y
g
c
c
(
U
b
u
n
t
u
/
L
i
n
a
r
o
4
.
7
.
2
-
2
u
b
u
n
t
u
1
)
4
.
7
.
2
,
6
4
-
b
i
t
5
(
1
r
o
w
)
Далее
создадим
папку
на
сервере
с
бэк
апами
для
хранения
этих
самых
бэк
апов:
Листинг
11.39
Папка
для
хранения
бэкапов
Line
1
$
s
u
d
o
m
k
d
i
r
-
p
/
s
r
v
/
b
a
r
m
a
n
-
$
s
u
d
o
c
h
o
w
n
b
a
r
m
a
n
:
b
a
r
m
a
n
/
s
r
v
/
b
a
r
m
a
n
274
11.5.
Утилиты
для
непрерывного
резервного
копирования
Для
настройки
barman
создадим
/etc
/barman.conf
:
Листинг
11.40
barman.conf
Line
1
[
b
a
r
m
a
n
]
-
;
M
a
i
n
d
i
r
e
c
t
o
r
y
-
b
ar
ma
n_
ho
m
e
=
/
s
r
v
/
b
a
r
m
a
n
-
5
;
L
o
g
l
o
c
a
t
i
o
n
-
l
o
g
_
f
i
l
e
=
/
v
a
r
/
l
o
g
/
b
a
r
m
a
n
/
b
a
r
m
a
n
.
l
o
g
-
-
;
D
e
f
a
u
l
t
c
o
m
p
r
e
s
s
i
o
n
l
e
v
e
l
:
p
o
s
s
i
b
l
e
v
a
l
u
e
s
a
r
e
N
o
n
e
(
d
e
f
a
u
l
t
)
,
b
z
i
p
2
,
g
z
i
p
o
r
c
u
s
t
o
m
-
c
o
m
p
r
e
s
s
i
o
n
=
g
z
i
p
10
-
;
’
m
a
i
n
’
P
o
s
t
g
r
e
S
Q
L
S
e
r
v
e
r
c
o
n
f
i
g
u
r
a
t
i
o
n
-
[
m
a
i
n
]
-
;
H
um
a
n
r
e
a
d
a
b
l
e
d
e
s
c
r
i
p
t
i
o
n
-
d
e
s
c
r
i
p
t
i
o
n
=
"
M
a
i
n
P
o
s
t
g
r
e
S
Q
L
D
a
t
a
b
a
s
e
"
15
-
;
SSH
o
p
t
i
o
n
s
-
s
s
h
_
c
o
m
m
an
d
=
s
s
h
p
o
s
t
g
r
e
s
@
p
g
h
o
s
t
-
-
;
P
o
s
t
g
r
e
S
Q
L
c
o
n
n
e
c
t
i
o
n
s
t
r
i
n
g
20
c
o
n
n
i
n
f
o
=
h
o
s
t
=
p
g
h
o
s
t
u
s
e
r
=
p
o
s
t
g
r
e
s
Секция
«main»
(так
мы
назвали
для
barman
наш
PostgreSQL
сервер)
со
держит
настройки
для
по
дключения
к
PostgreSQL
серверу
и
базе.
Про-
верим
настройки:
Листинг
11.41
Проверка
barman
настроек
Line
1
$
b
a
r
m
a
n
s
h
o
w
-
s
e
r
v
e
r
m
a
i
n
-
S
e
r
v
e
r
m
a
i
n
:
-
a
c
t
i
v
e
:
t
r
u
e
-
d
e
s
c
r
i
p
t
i
o
n
:
M
a
i
n
P
o
s
t
g
r
e
S
Q
L
D
a
t
a
b
a
s
e
5
ss
h
_
c
o
m
m
a
nd
:
s
s
h
p
o
s
t
g
r
e
s
@
p
g
h
o
s
t
-
c
o
n
n
i
n
f
o
:
h
o
s
t=
p
g
h
o
s
t
u
s
e
r
=
p
o
s
t
g
r
e
s
-
b
a
c
k
u
p
_
d
i
r
e
c
t
o
r
y
:
/
s
r
v
/
b
a
r
m
a
n
/
m
a
i
n
-
b
a
s
e
b
a
c
k
u
p
s
_
d
i
r
e
c
t
o
r
y
:
/
s
r
v
/
b
a
r
m
a
n
/
m
a
i
n
/
b
a
s
e
-
w
a
l
s
_
d
i
r
e
c
t
o
r
y
:
/
s
r
v
/
b
a
r
m
a
n
/
m
a
i
n
/
w
a
l
s
10
i
n
c
o
m
i
n
g
_
w
a
l
s
_
d
i
r
e
c
t
o
r
y
:
/
s
r
v
/
b
a
r
m
a
n
/
m
a
i
n
/
i
n
c
o
m
i
n
g
-
l
o
c
k
_
f
i
l
e
:
/
s
r
v
/
b
a
r
m
a
n
/
m
a
i
n
/
m
a
i
n
.
l
o
c
k
-
c
o
m
p
r
e
s
s
i
o
n
:
g
z
i
p
-
c
u
s
t
o
m
_
c
o
m
p
r
e
s
s
i
o
n
_
f
i
l
t
e
r
:
N
o
n
e
-
c
u
s
t
o
m
_
d
e
c
o
m
p
r
e
s
s
i
o
n
_
f
i
l
t
e
r
:
N
o
n
e
15
r
e
t
e
n
t
i
o
n
_
p
o
l
i
c
y
:
N
o
n
e
-
w
a
l
_
r
e
t
e
n
t
i
o
n
_
p
o
l
i
c
y
:
N
o
n
e
275
11.5.
Утилиты
для
непрерывного
резервного
копирования
-
p
r
e
_
b
a
c
k
u
p
_
s
c
r
i
p
t
:
N
o
n
e
-
p
o
s
t
_
b
a
c
k
u
p
_
s
c
r
i
p
t
:
N
o
n
e
-
c
u
r
r
e
n
t
_
x
l
o
g
:
N
o
n
e
20
l
a
s
t
_
s
h
i
p
p
e
d
_
w
a
l
:
N
o
n
e
-
a
r
c
h
i
v
e
_
c
o
m
m
a
n
d
:
N
o
n
e
-
s
e
r
v
e
r
_
t
x
t
_
v
e
r
s
i
o
n
:
9
.
3
.
1
-
d
a
t
a
_
d
i
r
e
c
t
o
r
y
:
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
9
.
3
/
m
a
i
n
-
a
r
c
h
i
v
e
_
m
o
d
e
:
o
f
f
25
c
o
n
f
i
g
_
f
i
l
e
:
/
e
t
c
/
p
o
s
t
g
r
e
s
q
l
/
9
.
3
/
m
a
i
n
/
p
o
s
t
g
r
e
s
q
l
.
c
o
n
f
-
h
b
a
_
f
i
l
e
:
/
e
t
c
/
p
o
s
t
g
r
e
s
q
l
/
9
.
3
/
m
a
i
n
/
p
g_
h
b
a
.
c
o
n
f
-
i
d
e
n
t
_
f
i
l
e
:
/
e
t
c
/
p
o
s
t
g
r
e
s
q
l
/
9
.
3
/
m
a
i
n
/
p
g
_
i
d
e
n
t
.
c
o
n
f
-
-
#
b
a
r
m
a
n
c
h
e
c
k
m
a
i
n
30
S
e
r
v
e
r
m
a
i
n
:
-
s
s
h
:
O
K
-
P
o
s
t
g
r
e
S
Q
L
:
O
K
-
a
r
c
h
i
v
e
_
m
o
d
e
:
FA
I
LE
D
(
p
l
e
a
s
e
s
e
t
i
t
t
o
’
o
n
’
)
-
a
r
c
h
i
v
e
_
c
o
m
m
a
n
d
:
F
A
IL
E
D
(
p
l
e
a
s
e
s
e
t
i
t
a
c
c
o
r
d
i
n
g
l
y
t
o
d
o
c
u
m
e
n
t
a
t
i
o
n
)
35
d
i
r
e
c
t
o
r
i
e
s
:
O
K
-
c
o
m
p
r
e
s
s
i
o
n
s
e
t
t
i
n
g
s
:
O
K
Все
х
орошо,
вот
только
PostgreSQL
не
настроен.
Для
этого
на
сервере
с
P
ostgreSQL
отредактируем
конфиг
базы:
Листинг
11.42
Настройка
PostgreSQL
Line
1
w
a
l
_
l
e
v
e
l
=
h
o
t
_
s
t
a
n
d
b
y
#
a
r
c
h
i
v
e
для
P
o
s
t
g
r
e
S
Q
L
<
9
.
0
-
a
r
c
h
i
v
e
_
m
o
d
e
=
o
n
-
a
r
c
h
i
v
e
_
c
o
m
m
a
n
d
=
’
r
s
y
n
c
-
a
%
p
b
a
r
m
a
n
@
b
r
h
o
s
t
:
I
N
C
O
M
I
N
G
_
W
A
L
S
_
D
I
R
E
C
T
O
R
Y
/
%
f
’
г
де
INCOMING_W
ALS_DIRECTOR
Y
— директория для
складывания
W
AL-логов.
Её
можно
узнать
из
выво
да
команды
barman
show-serv
er
main
(листинг
11.41
,
ук
азано
/srv/barman/main/incoming
).
После
изменения
на-
строек
нужно
перегрузить
PostgreSQL.
Т
еперь
проверим
ст
атус
на
сервере
бэк
апов:
Листинг
11.43
Проверка
Line
1
$
b
a
r
m
a
n
c
h
e
c
k
m
a
i
n
-
S
e
r
v
e
r
m
a
i
n
:
-
s
s
h
:
O
K
-
P
o
s
t
g
r
e
S
Q
L
:
O
K
5
a
r
c
h
i
v
e
_
m
o
d
e
:
O
K
-
a
r
c
h
i
v
e
_
c
o
m
m
a
n
d
:
O
K
-
d
i
r
e
c
t
o
r
i
e
s
:
O
K
276
11.5.
Утилиты
для
непрерывного
резервного
копирования
-
c
o
m
p
r
e
s
s
i
o
n
s
e
t
t
i
n
g
s
:
O
K
Все
готово.
Для
добавления
нового
сервера
процедуру
потребуетс
я
по-
вторить,
а
в
barman.conf
добавить
новый
сервер.
Создание
бэк
апов
Получение
списк
а
серверов:
Листинг
11.44
Список
серверов
Line
1
$
b
a
r
m
a
n
l
i
s
t -
s
e
r
v
e
r
-
m
a
i
n
-
M
a
i
n
P
o
s
t
g
r
e
S
Q
L
D
a
t
a
b
a
s
e
Запу
ск
создания
резервной
копии
PostgreSQL
(сервер
ук
азываетс
я
по-
следним
параметром):
Листинг
11.45
Создание
бэкапа
Line
1
$
b
a
r
m
a
n
b
a
c
k
u
p
m
a
i
n
-
S
t
a
r
t
i
n
g
b
a
c
k
u
p
f
o
r
s
e
r
v
e
r
m
a
i
n
i
n
/
s
r
v
/
b
a
r
m
a
n
/
m
a
i
n
/
b
a
s
e
/
2
0
1
2
1
1
0
9
T
0
9
0
8
0
6
-
B
a
c
k
u
p
s
t
a
r
t
a
t
x
l
o
g
l
o
c
a
t
i
o
n
:
0
/
3
0
0
0
0
2
0
(
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
3
,
0
0
0
0
0
0
2
0
)
-
C
o
p
y
i
n
g
f
i
l
e
s
.
5
C
o
p
y
d
o
n
e
.
-
A
s
k
i
n
g
P
o
s
t
g
r
e
S
Q
L
s
e
r
v
e
r
t
o
f
i
n
a
l
i
z
e
t
h
e
b
a
c
k
u
p
.
-
B
a
c
k
u
p
e
n
d
a
t
x
l
o
g
l
o
c
a
t
i
o
n
:
0
/
3
0
0
0
0
D8
(
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
3
,
0
0
0
0
0
0
D
8
)
-
B
a
c
k
u
p
c
o
m
p
l
e
t
e
d
Т
акую
задачу
лучше
выполнять
раз
в
сутки
(добавить
в
cron).
Посмот-
реть
список
бэк
апов
для
указаной
базы:
Листинг
11.46
Список
бэкапов
Line
1
$
b
a
r
m
a
n
l
i
s
t -
b
a
c
k
u
p
m
a
i
n
-
m
a
i
n
2
0
1
2
1
1
1
0
T
0
9
1
6
0
8
-
F
r
i
No
v
1
0
0
9
:
2
0
:
5
8
2
0
1
2
-
S
i
z
e
:
1
.
0
GiB
-
W
A
L
S
i
z
e
:
4
4
6
.
0
K
iB
-
m
a
i
n
2
0
1
2
1
1
0
9
T
0
9
0
8
0
6
-
F
r
i
No
v
9
0
9
:
0
8
:
1
0
2
0
1
2
-
S
i
z
e
:
2
3
.
0
M
i
B
-
W
A
L
S
i
z
e
:
4
7
7
.
0
Mi
B
Более
по
дробная
информация
о
выбраной
резервной
копии:
Листинг
11.47
Информация
о
выбраной
резервной
копии
Line
1
$
b
a
r
m
a
n
s
h
o
w
-
b
a
c
k
u
p
m
a
i
n
2
0
1
2
1
1
1
0
T
0
9
1
6
0
8
-
B
a
c
k
u
p
2
0
1
2
1
1
0
9
T
0
9
1
6
0
8
:
-
S
e
r
v
e
r
Na
me
:
m
a
i
n
277
11.5.
Утилиты
для
непрерывного
резервного
копирования
-
S
t
a
t
u
s
:
:
D
O
N
E
5
P
o
s
t
g
r
e
S
Q
L
V
e
r
s
i
o
n
:
9
0
2
0
1
-
P
G
D
A
T
A
d
i
r
e
c
t
o
r
y
:
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
9
.
3
/
m
a
i
n
-
-
B
a
s
e
b
a
c
k
u
p
i
n
f
o
r
m
a
t
i
o
n
:
-
D
i
s
k
u
s
a
g
e
:
1
.
0
GiB
10
T
i
m
e
l
i
n
e
:
1
-
B
e
g
i
n
W
A
L
:
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
8
C
-
End
W
A
L
:
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
9
2
-
W
A
L n
u
m
b
e
r
:
7
-
B
e
g
i
n
t
i
m
e
:
2
0
1
2
-
1
1
-
1
0
0
9
:
1
6
:
0
8
.
8
5
6
8
8
4
15
End
t
i
m
e
:
2
0
1
2
-
1
1
-
1
0
0
9
:
2
0
:
5
8
.
4
7
8
5
3
1
-
B
e
g
i
n
O
f
f
s
e
t
:
3
2
-
End
O
f
f
s
e
t
:
3
5
7
6
0
9
6
-
B
e
g
i
n
X
L
O
G
:
0
/
8
C
0
0
0
0
2
0
-
End X
L
O
G
:
0
/
9
2
3
6
9
1
2
0
20
-
W
A
L
i
n
f
o
r
m
a
t
i
o
n
:
-
No
o
f
f
i
l
e
s
:
1
-
D
i
s
k
u
s
a
g
e
:
4
4
6
.
0
Ki
B
-
L
a
s
t
a
v
a
i
l
a
b
l
e
:
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
9
3
25
-
C
a
t
a
l
o
g
i
n
f
o
r
m
a
t
i
o
n
:
-
P
r
e
v
i
o
u
s
B
a
c
k
u
p
:
2
0
1
2
1
1
0
9
T
0
9
0
8
0
6
-
N
e
x
t
B
a
c
k
u
p
:
-
(
t
h
i
s
i
s
t
h
e
l
a
t
e
s
t
b
a
s
e
b
a
c
k
u
p
)
Т
акж
е
мо
жно
сжимать
W
AL-логи,
которые
накапливаютс
я
в
кат
алог
ах
к
омандой
«cron»:
Листинг
11.48
Архивирование
W
AL-логов
Line
1
$
b
a
r
m
a
n
c
r
o
n
-
P
r
o
c
e
s
s
i
n
g
x
l
o
g
s
e
g
m
e
n
t
s
f
o
r
m
a
i
n
-
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
-
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
2
5
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
3
-
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
3
.
0
0
0
0
0
0
2
0
.
b
a
c
k
u
p
-
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
4
-
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
5
-
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
6
Эту
команду
требуетс
я
добавлять
в
crontab
.
Частот
а
выполнения
дан-
ной
к
оманды
зависит
от
того,
к
ак
много
W
AL-логов
накапливаетс
я
(чем
больше
файлов
-
тем
дольше
она
выполняетс
я).
Barman
мож
ет
с
жи-
мать
W
AL-логи
через
gzip,
bzip2
или
другой
компрессор
данных
(коман-
ды
для
сж
атия
и
распаковки
задаются
через
custom_compression_filter
и
custom_decompression_filter
соответственно).
Т
акж
е
мо
жно
активировать
к
омпрессию
данных
при
переда
чи
по
сети
через
опцию
net
w
ork_compression
278
11.5.
Утилиты
для
непрерывного
резервного
копирования
(по
умолчанию
отключена).
Через
опции
bandwidth_limit
(по
умолчанию
0,
ограничений
нет)
и
tablespace_bandwidth_limit
возможно
ограничить
ис-
пользования
сетевого
к
анала.
Для
восст
ановления
базы
из
бэкапа
используетс
я
команда
recov
er
:
Листинг
11.49
Восстановление
базы
Line
1
$
b
a
r
m
a
n
r
e
c
o
v
e
r
-
-
r
e
m
o
t
e
-
s
s
h
-
com
mand
"
s
s
h
p
o
s
t
g
r
e
s
@
p
g
h
o
s
t
"
m
a
i
n
2
0
1
2
1
1
0
9
T
0
9
0
8
0
6
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
9
.
3
/
m
a
i
n
-
S
t
a
r
t
i
n
g
r
e
m
o
t
e
r
e
s
t
o
r
e
f
o
r
s
e
r
v
e
r
m
a
i
n
u
s
i
n
g
b
a
c
k
u
p
2
0
1
2
1
1
0
9
T
0
9
0
8
0
6
-
D
e
s
t
i
n
a
t
i
o
n
d
i
r
e
c
t
o
r
y
:
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
9
.
3
/
m
a
i
n
-
C
o
p
y
i
n
g
t
h
e
b
a
s
e
b
a
c
k
u
p
.
5
C
o
p
y
i
n
g
r
e
q
u
i
r
e
d
w
a
l
s
e
g
m
e
n
t
s
.
-
T
h
e
a
r
c
h
i
v
e
_
c
o
m
m
a
n
d
w
a
s
s
e
t
t
o
’
f
a
l
s
e
’
t
o
p
r
e
v
e
n
t
d
a
t
a
l
o
s
s
e
s
.
-
-
Y
o
u
r
P
o
s
t
g
r
e
S
Q
L
s
e
r
v
e
r
h
a
s
b
e
e
n
s
u
c
c
e
s
s
f
u
l
l
y
p
r
e
p
a
r
e
d
f
o
r
r
e
c
o
v
e
r
y
!
-
10
P
l
e
a
s
e
r
e
v
i
e
w
n
e
t
w
o
r
k
a
n
d
a
r
c
h
i
v
e
r
e
l
a
t
e
d
s
e
t
t
i
n
g
s
i
n
t
h
e
P
o
s
t
g
r
e
S
Q
L
-
c
o
n
f
i
g
u
r
a
t
i
o
n
f
i
l
e
b
e
f
o
r
e
s
t
a
r
t
i
n
g
t
h
e
j
u
s
t
r
e
c
o
v
e
r
e
d
i
n
s
t
a
n
c
e
.
-
-
W
A
R
N
I
N
G
:
B
e
f
o
r
e
s
t
a
r
t
i
n
g
u
p
t
h
e
r
e
c
o
v
e
r
e
d
P
o
s
t
g
r
e
S
Q
L
s
e
r
v
e
r
,
-
p
l
e
a
s
e
r
e
v
i
e
w
a
l
s
o
t
h
e
s
e
t
t
i
n
g
s
o
f
t
h
e
f
o
l
l
o
w
i
n
g
c
o
n
f
i
g
u
r
a
t
i
o
n
15
o
p
t
i
o
n
s
a
s
t
h
e
y
m
i
g
h
t
i
n
t
e
r
f
e
r
e
w
i
t
h
y
o
u
r
c
u
r
r
e
n
t
r
e
c
o
v
e
r
y
a
t
t
e
m
p
t
:
-
-
d
a
t
a
_
d
i
r
e
c
t
o
r
y
=
’
/
v
a
r
/
l
i
b
/
p
o
s
t
g
r
e
s
q
l
/
9
.
3
/
m
a
i
n
’
#
u
s
e
d
a
t
a
i
n
a
n
o
t
h
e
r
d
i
r
e
c
t
o
r
y
-
e
x
t
e
r
n
a
l
_
p
i
d
_
f
i
l
e
=
’
/
v
a
r
/
r
u
n
/
p
o
s
t
g
r
e
s
q
l
/
9
.
3
-
m
a
i
n
.
p
i
d
’
#
w
r
i
t
e
a
n
e
x
t
r
a
PID
f
i
l
e
-
h
b
a
_
f
i
l
e
=
’
/
e
t
c
/
p
o
s
t
g
r
e
s
q
l
/
9
.
3
/
m
a
i
n
/
p
g
_h
b
a
.
c
o
n
f
’
#
h
o
s
t
-
b
a
s
e
d
a
u
t
h
e
n
t
i
c
a
t
i
o
n
f
i
l
e
20
i
d
e
n
t
_
f
i
l
e
=
’
/
e
t
c
/
p
o
s
t
g
r
e
s
q
l
/
9
.
3
/
m
a
i
n
/
p
g
_
i
d
e
n
t
.
c
o
n
f
’
#
i
d
e
n
t
c
o
n
f
i
g
u
r
a
t
i
o
n
f
i
l
e
Barman
мож
ет
восстановить
базу
из
резервной
копии
на
у
даленном
сер-
вере
через
SSH
(для
этого
есть
опция
remote-ssh-command
).
Т
акже
barman
мо
жет
восстановить
базу
,
используя
PITR
:
для
этого
используются
опции
target
-
time
(указываетс
я
время)
или
target
-
xid
(id
транзакции).
279
11.5.
Утилиты
для
непрерывного
резервного
копирования
Заключение
Barman
помогает
автоматизировать
сбор
и
хранение
резервных
копий
P
ostgreSQL
данных
на
отдельном
сервере.
Утилита
прост
а,
позволяет
хра-
нить
и
у
добно
управлять
бэкапами
нескольких
PostgreSQL
серверов.
Pg_arman
Pg_arman
—
менедж
ер
резервного
копирования
и
восстановления
для
P
ostgreSQL
9.5
или
выше.
Это
ответвление
проект
а
pg_arman
,
изна
чаль-
но
разрабатываемого
в
NTT.
Т
еперь
его
разрабатывает
и
поддер
живает
Мишель
Пакье.
Утилит
а
предоставляет
следующие
возможности:
∙
Р
езервное
к
опирование
во
время
работы
базы
данных,
включая
таб-
личные
пространства,
с
помощью
всего
о
дной
команды;
∙
Восст
ановление
из
резервной
к
опии
всего
одной
к
омандой,
с
нестан-
дартными
вариант
ами,
включая
использование
PITR
;
∙
По
ддержк
а
полного
и
дифференциального
копирования;
∙
Управление
резервными
к
опиями
со
встроенными
кат
алогами;
Использование
Сна
чала требу
етс
я создать
«к
аталог
резервного к
опирования»
,
в
ко-
тором
бу
дут
хранитьс
я
файлы
к
опий
и
их
метаданные.
До
инициали-
зации этого
к
аталог
а рек
оменду
ется
настроить параметры
arc
hive_mode
и
arc
hive_command
в
p
ostgresql
.
conf
. Если переменные инициализирова-
ны,
pg_arman
мож
ет
скорректировать
файл
к
онфигурации.
В
этом
случае
потребу
ется
задать
путь
к
кластеру
баз
данных:
переменной
окружения
PGD
A
T
A
или
через
параметр
-
D/--pgdata
.
Листинг
11.50
init
Line
1
$
pg
_a
r
m
a
n
i
n
i
t
-
B
/
p
a
t
h
/
t
o
/
b
a
c
k
u
p
/
После
этого
возмож
ен
один
из
следующих
вариантов
резервного
к
опи-
рования:
∙
Полное резервное копирование (к
опируетс
я весь
кластер баз дан-
ных);
Листинг
11.51
backup
Line
1
$
p
g
_
a
r
m
an
b
a
c
k
u
p
-
-
b
a
c
k
u
p
-
mo
de
=
f
u
l
l
-
$
p
g
_
ar
m
a
n
v
a
l
i
d
a
t
e
-
280
11.5.
Утилиты
для
непрерывного
резервного
копирования
∙
Дифференциальное
резервное
копирование:
к
опируются
только
фай-
лы
или
страницы,
изменённые
после
последней
проверенной
копии.
Для
этого
выполняетс
я
ск
анирование
записей
W
AL
от
позиции
по-
следнего
к
опирования
до
LSN
выполнения
pg_start_backup
и
все
из-
менённые
блоки
записываются
и
отслеживаются
как
часть
резервной
к
опии.
Т
ак
как
просканированные
сегменты
W
AL
д
олжны
нахо
дить-
с
я
в
архиве
W
AL,
последний
сегмент
,
задействованный
после
запуск
а
pg_start_bac
kup
,
должен
быть
переключен
прину
дительно;
Листинг
11.52
backup
Line
1
$
p
g
_
a
r
m
an
b
a
c
k
u
p
-
-
b
a
c
k
u
p
-
mo
de
=p
a
g
e
-
$
p
g
_
ar
m
a
n
v
a
l
i
d
a
t
e
-
После
резервного
копирования
рекоменду
ется
проверять
файлы
к
опий
к
ак
тольк
о
это
бу
дет
возможно.
Непроверенные
к
опии
нельзя
использо-
вать
в
операциях
восст
ановления
и
резервного
копирования.
До
начала
восстановления
через
pg_arman
PostgreSQL
кластер
долж
ен
быть
ост
ановлен. Если
кластер баз
данных
всё ещё
существу
ет
,
к
оман-
да
восстановления
сохранит
незаар
хивированный журнал
транзакций
и
у
далит
все
файлы
баз
данных.
После
восст
ановления
файлов
pg_arman
создаёт
recov
ery
.
conf
в
$PGDA
T
A
кат
алоге.
Этот
к
онфигурационный
файл
со
держит
параметры
для
восст
ановления.
После
у
спешного
восстановле-
ния
рекоменду
етс
я
при
первой
ж
е
возмо
жности
сделать
полную
резерв-
ную
к
опию.
Если
ключ
--
recov
ery
-
target
-
timeline
не
задан,
целевой
точкой
восст
ановления
бу
дет
TimeLineID
последней
к
онтрольной
точки
в
файле
(
$PGD
A
T
A/
global
/pg_con
trol
). Если
файл
pg_con
trol
отсутствует
, целевой
точк
ой
бу
дет
TimeLineID
в
полной
резервной
копии,
используемой
пр
и
вос-
ст
ановлении.
Листинг
11.53
restore
Line
1
$
p
g
_
c
t
l
s
t
o
p
-
m
i
m
m
e
d
i
a
t
e
-
$
p
g
_
a
r
ma
n
r
e
s
t
o
r
e
-
$
p
g
_
c
t
l
s
t
a
r
t
Pg_arman
имеет
р
яд
ограничений:
∙
Требуютс
я
права
чтения
к
аталог
а
баз
данных
и
записи
в
к
ат
алог
ре-
зервного
к
опирования.
Обычно
для
этого
на
сервере
БД
требуетс
я
смонтировать
диск,
г
де
размещён
кат
алог
резервных
копий,
исполь-
зу
я
NFS
или
другую
технологию;
∙
Основные
версии
pg_arman
и
сервера
должны
совпадать;
∙
Р
азмеры
блоков
pg_arman
и
сервера
должны
совпадать;
281
11.6.
Заключение
∙
Если
в
к
ат
алоге
с
журналами
сервера
или
кат
алоге
с
архивом
W
AL
ок
азываются нечит
аемые файлы/кат
алоги, резервное к
опирование
или
восст
ановление
завершитс
я
сбоем
вне
зависимости
от
выбран-
ного
режима
к
опирования;
11.6
Заключение
В
любом
случае,
усилия
и
время,
затраченные
на
создание
оптималь-
ной
системы
создания
бэк
апов, бу
дут
оправданы.
Невозмо
жно
предуг
а-
дать
к
огда
произойдут
проблемы
с
базой
данных,
поэтому
бэк
апы
должны
быть
настроены
для
P
ostgreSQL
(особенно,
если
это
продакшн
система).
282
12
Стратегии
масшт
абирования
для
P
ostgreSQL
В
к
онце
к
онцов,
все
решают
лю
ди,
не
стратегии
Ларри
Боссиди
12.1
Введение
Многие
разработчики крупных
п
роектов
сталкиваютс
я
с
проблемой,
к
огда
один-единственный
сервер
базы
данных
ник
ак
не
мо
жет
справиться
с
нагрузками.
Очень
часто
т
акие
проблемы
проис
х
о
дят
из-за
неверного
проектирования
прилож
ения
(плох
ая
структура
БД
для
прило
ж
ения,
от-
сутствие
к
еширования).
Но
в
данном
случае
пусть
у
нас
есть
«идеальное»
прило
жение,
для
которого
оптимизированы
все
SQL
запросы,
использу-
етс
я к
еширование,
P
ostgreSQL
настроен,
но
все
равно не
справляетс
я
с
нагрузк
ой.
Т
акая
проблема
мож
ет
возникнуть
к
ак
на
этапе
проектирова-
ния,
так
и
на
этапе
рост
а
прило
жения.
И
тут
возникает
вопрос:
какую
стратегию
выбрать
при
возникновении
по
добной
ситуации?
Если
Ваш
зак
азчик
готов
купить
супер
сервер
за
нескольк
о
тыс
яч
дол-
ларов
(а
по
мере
роста
—
дес
ятк
ов
тыс
яч
и
т
.
д.),
чтобы
сэк
ономить
время
разработчик
ов,
но
сделать
все
быстро,
мож
ете
дальше
эту
главу
не
читать.
Но
так
ой
заказчик
—
мифическое
существо
и,
в
основном,
так
ая
проблема
ло
жится
на
плечи
разработчиков.
Суть
проблемы
Для
того,
чтобы
сделать
как
ой-то
выбор,
необх
о
димо
знать
суть
про-
блемы.
Существуют
два
предела,
в
которые
могут
уткнутьс
я
сервера
баз
данных:
283
12.2.
Проблема
чтения
данных
∙
Ограничение
пропу
скной
способности
чтения
данных;
∙
Ограничение
пропу
скной
способности
записи
данных;
Практически никог
да
не
возник
ает одновременно две
проблемы,
по
крайне
мере,
это
маловероятно
(если
вы,
конечно,
не
T
witter
или
F
aceb
o
ok
пишете).
Если
вдруг
так
ое
происх
одит
—
возможно,
система
неверно
спро-
ектирована,
и
её
реализацию
следу
ет
пересмотреть.
12.2
Проблема
чтения
данных
Проблема
с
чтением
данных
обычно
на
чинаетс
я,
к
огда
СУБД
не
в
со-
сто
янии
обеспечить
то
количество
выборок,
которое
требуетс
я.
В
основном
т
акое
происх
о
дит
в
блог
ах,
новостных
лент
ах
и
т
.
д.
Хочу
сразу
отметить,
что
подобную
проблему
лучше
решать
внедрением
кеширования,
а
потом
уж
е
думать
как
масштабировать
СУБД.
Мето
ды
решения
∙
PgP
o
ol-I
I
v.3
+
P
ostgreSQL
v.9
с
Streaming
Replication
—
отличное
ре-
шение
для
масштабирования
на
чтение,
более
по
дробно
можно
озна-
к
омиться
по
ссылке
.
Основные
преимущества:
– Низк
ая
задержк
а
репликации
между
мастером
и
слейвом;
– Произво
дительность
записи
падает
незначительно;
– Отк
азоустойчивость
(failov
er);
– Пу
лы
соединений;
– Интеллекту
альная
балансировка
нагрузки
–
проверк
а
задерж-
ки
репликации
между
мастером
и
слейвом
(сам
проверяет
pg_curren
t_xlog_lo
cation
и
pg_last_xlog_receiv
e_lo
cation
);
– Добавление
слейвов
СУБД
без
ост
ановки
pgp
o
ol-I
I;
– Простот
а
в
настройке
и
обслуживании;
∙
PgP
o
ol-I
I
v.3
+
PostgreSQL
с
Slony/Londiste/Bucardo
—
аналогично
предыдущему
решению,
но
с
использованием
Slon
y/Londiste/Bucardo.
Основные
преимущества:
– Отк
азоустойчивость
(failov
er);
– Пу
лы
соединений;
– Интеллекту
альная
балансировка
нагрузки
–
проверка
задержки
реплик
ации
между
мастером
и
слейвом;
– Добавление
слейв
СУБД
без
ост
ановки
pgp
o
ol-I
I;
– Мо
жно
использовать
Postgresql
ниже
9
версии;
∙
Citus
—
по
дробнее
можно
прочитать
в
«
6.5
Citus
»
главе;
∙
P
ostgres-X2
—
подробнее
можно
прочитать
в
«
6.3
Postgres-X2
»
главе;
∙
P
ostgres-XL
—
по
дробнее
можно
прочит
ать
в
«
6.4
Postgres-XL
»
главе;
284
12.3.
Проблема
записи
данных
12.3
Проблема
записи
данных
Обычно
т
акая проблема
возникает в
системах,
которые производят
анализ
больших
объемов
данных
(н
апример
аналог
Go
ogle
Analytics).
Дан-
ные
активно
пишутся
и
мало
читаютс
я
(или
читаетс
я
тольк
о
суммарный
вариант
собранных
данных).
Мето
ды
решения
Один
из
самых
попу
лярных
мето
дов
решения
проблемы
—
размазать
нагрузку
по
времени
с
помощью
систем
очередей.
∙
PgQ
—
это
система
очередей,
разработ
анная
на
базе
PostgreSQL.
Р
аз-
работчики
—
компания
Skyp
e.
Используетс
я
в
Londiste
(по
дробнее
«
5.6
Londiste
»).
Особенности:
– Высок
ая
произво
дительность
благо
даря
особенност
ям
P
ostgreSQL;
– Общая
очередь,
с
по
ддержк
ой
неск
ольких
обработчиков
и
неск
ольких
генераторов
событий;
– PgQ
г
арантирует
,
что
каждый
обработчик
увидит
каждое
собы-
тие
к
ак
минимум
один
раз;
– События
дост
аются
из
очереди
«пачк
ами»
(batches);
– Чистое
API
на
SQL
функциях;
– У
добный
мониторинг;
∙
Citus
—
по
дробнее
можно
прочитать
в
«
6.5
Citus
»
главе;
∙
P
ostgres-X2
—
подробнее
можно
прочитать
в
«
6.3
Postgres-X2
»
главе;
∙
P
ostgres-XL
—
по
дробнее
можно
прочит
ать
в
«
6.4
Postgres-XL
»
главе;
12.4
Заключение
В
данной
главе
показаны
только
нескольк
о
возможных
вариантов
ре-
шения
задач
масшт
абирования
PostgreSQL.
Т
аких
стратегий
существует
огромное
количество
и
каждая
из
них
имеет
как
сильные,
т
ак
и
слабые
стороны.
Самое
важное
то,
что
выбор
оптимальной
стратегии
масштабиро-
вания
для
решения
поставленных
зада
ч
остаетс
я
на
плечах
разработчиков
и/или
администраторов
СУБД.
285
13
Утилиты
для
P
ostgreSQL
Ум
всег
да
занят
исследованием
чего-либо
Цицерон
13.1
Введение
В
данной
г
лаве
собраны
полезные
утилиты
для
P
ostgreSQL,
к
оторые
не
упоминались
в
других
разделах
книги.
13.2
Pgcli
Pgcli
—
интерфейс
командной
строки
для
PostgreSQL
с
автозаполнени-
ем
и
по
дсветкой
синтак
сиса.
Написан
на
Python.
Рис.
13.1:
Pgcli
автозаполнение
286
13.3.
Pgloader
13.3
Pgloader
Pgloader
—
консольная
утилита
для
переноса
данных
с
CSV
файлов,
HTTP
ресурсов,
SQLite,
dBase
или
MySQL
баз
данных
в
P
ostgreSQL.
Для
быстрой
загрузки
данных
используетс
я
COPY
проток
ол.
Pgloader
содер-
жит
моду
ли
для
преобразование
данных,
к
оторые
позволяют
преобразо-
вывать
данные
во
время
переноса
(н
апример,
преобразование
набора
цифр
в
IP
адрес
или
разбить
строку
на
два
тек
стовых
поля).
13.4
P
ostgres.app
P
ostgres.app
—
полнофункциональный
PostgreSQL,
который
упак
ован
в
к
ачестве
ст
андартного
Mac
прилож
ения,
поэтому
работ
ает
тольк
о
на
Mac
OS
системах.
Прило
жение
имеет
красивый
пользовательский
интерфейс
и
работ
ает
в
системной
строке
меню.
13.5
pgA
dmin
pgA
dmin
—
инструмент
c
графическим
интерфейсом
для
управления
P
ostgreSQL
и
производных от
него
баз
данных.
Он
мо
жет
быть
запу-
щен
в
к
а
честве
десктоп
или
веб-прилож
ения.
Написан
на
Python
(с
ис-
пользованием
Flask
фреймворка)
и
Ja
v
aScript
(с
использованием
jQuery
и
Bo
otstrap).
Существуют
альтернативные
программные
про
дукты
для
P
ostgreSQL
(к
ак
платные,
так
и
бесплатные).
Вот
примеры
бесплатных
альтернатив:
∙
DBea
ver
;
∙
DBGlass
;
∙
Metabase
;
∙
pgMo
deler
;
∙
Pgw
eb
;
∙
P
ostbird
;
∙
SQL
T
abs
;
13.6
P
ostgREST
P
ostgREST
—
инструмент
создания
HTTP
REST
API
для
PostgreSQL
базы.
Написан
на
Hask
ell.
13.7
Ngx_p
ostgres
Ngx_p
ostgres
—
моду
ль
для
Nginx
,
который
позволяет
напр
ямую
рабо-
т
ать
с
PostgreSQL
базой.
Ответы
генерируетс
я
в
формате
RDS
(Resty
DBD
287
13.8.
Заключение
Stream),
поэтому
он
совместим
с
ngx_rds_json
,
ngx_rds_csv
и
ngx_drizzle
мо
ду
лями.
13.8
Заключение
В
данной
г
лаве
рассмотрено
лишь
нескольк
о
полезных
утилит
для
P
ostgreSQL.
Каждый
день
для
это
базы
данных
появляетс
я
все
больше
интересных
инструментов,
к
оторые
у
лучшают
,
упрощают
или
автомати-
зируют
работу
с
данной
базой
данных.
288
14
Полезные
мелочи
Быстро
найти
правильный
ответ
на
тру
дный
вопрос
—
ни
с
чем
не
сравнимое
у
довольствие
Мак
с
Фрай.
Об
жора-Хо
хотун
14.1
Введение
Иног
да
возникают
очень
интересные
проблемы
по
работе
с
PostgreSQL,
к
оторые
при
нах
о
ждении
ответ
а
пораж
ают
своей
лак
оничностью,
красо-
той
и
простым
исполнением.
В
данной
главе
я
решил
собрать
интересные
мето
ды
решения
разных
проблем,
с
которыми
сталкиваютс
я
люди
при
ра-
боте
с
P
ostgreSQL.
14.2
Мелочи
Р
азмер
объектов
в
базе
данных
Данный
запрос
показывает
размер
объектов
в
базе
данных
(например,
т
аблиц
и
индексов).
Ск
ачать
snipp
ets/biggest_relations.sql
Line
1
S
E
L
E
C
T
n
s
p
n
a
m
e
|
|
’
.
’
|
|
r
e
l
n
a
m
e
A
S
"
r
e
l
a
t
i
o
n
"
,
-
p
g
_
s
i
z
e
_
p
r
e
t
t
y
(
p
g
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
C
.
o
i
d
)
)
A
S
"
s
i
z
e
"
-
F
R
O
M
p
g
_
c
l
a
s
s
C
-
L
E
F
T
JOIN
p
g
_
n
a
m
e
s
p
a
c
e
N
O
N
(
N
.
o
i
d
=
C
.
r
e
l
n
a
m
e
s
p
a
c
e
)
5
W
H
E
R
E
n
s
p
n
a
m
e
N
O
T I
N
(
’
p
g
_
c
a
t
a
l
o
g
’
,
’
i
n
f
o
r
m
a
t
i
o
n
_
s
c
h
e
m
a
’
)
-
O
R
D
E
R
B
Y
p
g
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
C
.
o
i
d
)
D
E
S
C
-
LIMIT
2
0
;
289
14.2.
Мелочи
Пример
выво
да:
Листинг
14.1
Поиск
самых
больших
объектов
в
БД.
Пример
выво
да
Line
1
r
e
l
a
t
i
o
n
|
s
i
z
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
p
u
b
l
i
c
.
a
c
c
o
u
n
t
s
|
3
2
6
M
B
-
p
u
b
l
i
c
.
a
c
c
o
u
n
t
s
_
p
k
e
y
|
4
4 M
B
5
p
u
b
l
i
c
.
h
i
s
t
o
r
y
|
5
9
2
kB
-
p
u
b
l
i
c
.
t
e
l
l
e
r
s
_
p
k
e
y
|
1
6
kB
-
p
u
b
l
i
c
.
b
r
a
n
c
h
e
s
_
p
k
e
y
|
1
6
kB
-
p
u
b
l
i
c
.
t
e
l
l
e
r
s
|
1
6
k
B
-
p
u
b
l
i
c
.
b
r
a
n
c
h
e
s
|
8
1
9
2
b
y
t
e
s
Р
азмер
самых
больших
таблиц
Данный
запрос
пок
азывает
размер
самых
больших
т
аблиц
в
базе
дан-
ных.
Ск
ачать
snipp
ets/biggest_tables.sql
Line
1
S
E
L
E
C
T
n
s
p
n
a
m
e
|
|
’
.
’
|
|
r
e
l
n
a
m
e
A
S
"
r
e
l
a
t
i
o
n
"
,
-
p
g
_
s
i
z
e
_
p
r
e
t
t
y
(
p
g
_
t
o
t
a
l
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
C
.
o
i
d
)
)
A
S
"
t
o
t
a
l
_
s
i
z
e
"
-
F
R
O
M
p
g
_
c
l
a
s
s
C
-
L
E
F
T
JOIN
p
g
_
n
a
m
e
s
p
a
c
e
N
O
N
(
N
.
o
i
d
=
C
.
r
e
l
n
a
m
e
s
p
a
c
e
)
5
W
H
E
R
E
n
s
p
n
a
m
e
N
O
T I
N
(
’
p
g
_
c
a
t
a
l
o
g
’
,
’
i
n
f
o
r
m
a
t
i
o
n
_
s
c
h
e
m
a
’
)
-
A
N
D
C
.
r
e
l
k
i
n
d
<
>
’
i
’
-
A
N
D
n
s
p
n
a
m
e
!
~
’
^
p
g
_
t
o
a
s
t
’
-
O
R
D
E
R
B
Y
p
g
_
t
o
t
a
l
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
C
.
o
i
d
)
D
E
S
C
-
LIMIT
2
0
;
Пример
выво
да:
Листинг
14.2
Размер
самых
больших
таблиц.
Пример
выво
да
Line
1
r
e
l
a
t
i
o
n
|
t
o
t
a
l
_
s
i
z
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
p
u
b
l
i
c
.
a
c
t
i
o
n
s
|
4
2
4
9
M
B
-
p
u
b
l
i
c
.
p
r
o
d
u
c
t
_
h
i
s
t
o
r
y
_
r
e
c
o
r
d
s
|
1
9
7 M
B
5
p
u
b
l
i
c
.
p
r
o
d
u
c
t
_
u
p
d
a
t
e
s
|
5
2 M
B
-
p
u
b
l
i
c
.
i
m
p
o
r
t
_
p
r
o
d
u
c
t
s
|
3
4
M
B
-
p
u
b
l
i
c
.
p
r
o
d
u
c
t
s
|
2
9
M
B
-
p
u
b
l
i
c
.
v
i
s
i
t
s
|
2
5 M
B
290
14.2.
Мелочи
«Средний»
coun
t
Данный
метод
позволяет
узнать
приблизительное
количество
записей
в
т
аблице.
Для
огромных
т
аблиц
этот
метод
работает
быстрее,
чем
обык-
новенный
coun
t.
Ск
ачать
snipp
ets/coun
t_estimate.sql
Line
1
C
R
E
A
T
E
F
U
N
C
T
I
O
N
c
o
u
n
t
_
e
s
t
i
m
a
t
e
(
q
u
e
r
y
t
e
x
t
)
R
E
T
U
R
N
S
i
n
t
e
g
e
r
A
S
$
$
-
D
E
C
L
A
R
E
-
r
e
c
r
e
c
o
r
d
;
-
r
o
w
s
i
n
t
e
g
e
r
;
5
B
E
G
I
N
-
F
O
R
r
e
c
I
N
E
X
E
C
U
T
E
’
E
X
P
L
A
I
N
’
|
|
q
u
e
r
y
L
O
O
P
-
r
o
w
s
:
=
s
u
b
s
t
r
i
n
g
(
r
e
c
.
"
Q
U
E
R
Y
P
L
A
N"
F
R
O
M
’
r
o
w
s
=
(
[
[
:
d
i
g
i
t
:
]
]
+
)
’
)
;
-
EX
IT
W
H
E
N r
o
w
s
I
S
N
O
T
N
U
L
L
;
-
E
N
D
L
O
O
P
;
10
-
R
E
T
U
R
N
r
o
w
s
;
-
E
N
D
;
-
$
$
L
A
N
G
U
A
G
E
p
l
p
g
s
q
l
V
O
L
A
T
I
L
E ST
R
IC
T
;
Пример:
Листинг
14.3
«Средний»
count.
Пример
Line
1
C
R
E
A
T
E
T
A
B
L
E
f
o
o
(
r
d
o
u
b
l
e
p
r
e
c
i
s
i
o
n
)
;
-
I
N
SE
RT I
NT
O
f
o
o
S
E
L
E
C
T
r
a
n
d
o
m
(
)
F
R
O
M
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
1
,
1
0
0
0
)
;
-
A
N
A
L
Y
Z
E
f
o
o
;
-
5
#
S
E
L
E
C
T
c
o
u
n
t
(
*
)
F
R
O
M
f
o
o
W
H
E
R
E
r
<
0
.
1
;
-
c
o
u
n
t
-
-
-
-
-
-
-
-
-
9
2
-
(
1
r
o
w
)
10
-
#
S
E
L
E
C
T
c
o
u
n
t
_
e
s
t
i
m
a
t
e
(
’
S
E
L
E
C
T
* F
R
O
M
f
o
o
W
H
E
R
E
r
<
0
.
1
’
)
;
-
c
o
u
n
t
_
e
s
t
i
m
a
t
e
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
9
4
15
(
1
r
o
w
)
Случайное
число
из
диапазона
Данный
мето
д
позволяет
взять
случайное
число
из
указаного
диапазо-
на
(целое
или
с
плавающей
запятой).
291
14.2.
Мелочи
Ск
ачать
snipp
ets/random_from_range.sql
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
r
a
n
d
o
m
(
n
u
m
e
r
i
c
,
n
u
m
e
r
i
c
)
-
R
E
T
U
R
N
S
n
u
m
e
r
i
c
AS
-
$
$
-
S
E
L
E
C
T
(
$
1
+
(
$
2
-
$
1
)
*
r
a
n
d
o
m
(
)
)
:
:
n
u
m
e
r
i
c
;
5
$
$
L
A
N
G
U
A
G
E
’
s
q
l
’
V
O
L
A
T
I
L
E
;
Пример:
Листинг
14.4
Случайное
число
из
диапазона.
Пример
Line
1
S
E
L
E
C
T
r
a
n
d
o
m
(
1
,
1
0
)
:
:
i
n
t
,
r
a
n
d
o
m
(
1
,
1
0
)
;
-
r
a
n
d
o
m
|
r
a
n
d
o
m
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
6
|
5
.
1
1
6
7
5
1
8
4
8
2
5
4
3
5
5
(
1
r
o
w
)
-
-
S
E
L
E
C
T
r
a
n
d
o
m
(
1
,
1
0
)
:
:
i
n
t
,
r
a
n
d
o
m
(
1
,
1
0
)
;
-
r
a
n
d
o
m
|
r
a
n
d
o
m
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
10
7
|
1
.
3
7
0
6
0
0
7
0
6
4
3
2
0
1
-
(
1
r
o
w
)
Алгоритм
Луна
Алгоритм
Луна
или
форму
ла
Луна
—
алгоритм
вычисления
к
онтроль-
ной
цифры,
получивший
широкую
попу
лярность.
Он
используетс
я,
в
част-
ности,
при
первичной
проверк
е
номеров
банковских
пластик
овых
карт
,
но-
меров
социального
страхования
в
США
и
Канаде.
Алгоритм
был
разрабо-
т
ан
сотру
дник
ом
компании
«IBM»
Хансом
Петером
Луном
и
запатентован
в
1960
го
ду
.
Контрольные
цифры
вообще
и
алгоритм
Луна
в
частности
предназна-
чены
для
защиты
от
случайных
ошибок,
а
не
преднамеренных
иск
ажений
данных.
Алгоритм
Луна
реализован
на
чистом
SQL.
Обратите
внимание,
что
эт
а
реализация
является
чисто
арифметической.
Ск
ачать
snipp
ets/luhn_algorithm.sql
Line
1
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
l
u
h
n
_
v
e
r
i
f
y
(
i
n
t
8
)
R
E
T
U
R
N
S
B
O
O
L
E
A
N
A
S
$
$
-
-
-
T
a
k
e
t
h
e
sum
o
f
t
h
e
-
-
-
d
o
u
b
l
e
d
d
i
g
i
t
s
a
n
d
t
h
e
e
v
e
n
-
n
u
m
b
e
r
e
d
u
n
d
o
u
b
l
e
d
d
i
g
i
t
s ,
a
n
d
s
e
e
i
f
-
-
-
t
h
e
su
m
i
s
e
v
e
n
l
y
d
i
v
i
s
i
b
l
e
b
y
z
e
r
o
.
5
S
E
L
E
C
T
292
14.2.
Мелочи
-
-
-
D
o
u
b
l
e
d
d
i
g
i
t
s
m
i
g
h
t
i
n
t
u
r
n
b
e
t
w
o
d
i
g
i
t
s
.
I
n
t
h
a
t
c
a
s
e
,
-
-
-
w
e
m
u
s
t
a
d
d
e
a
c
h
d
i
g
i
t
i
n
d
i
v
i
d
u
a
l
l
y
r
a
t
h
e
r
t
h
a
n
a
d
d
i
n
g
t
h
e
-
-
-
d
o
u
b
l
e
d
d
i
g
i
t
v
a
l
u
e
t
o
t
h
e
sum
.
I
e
i
f
t
h
e
o
r
i
g
i
n
a
l
d
i
g
i
t
w
a
s
-
-
-
‘
6
’
t
h
e
d
o
u
b
l
e
d
r
e
s
u
l
t
w
a
s
‘
1
2
’
a
n
d
we
m
u
s
t
a
d
d
‘
1
+
2
’
t
o
t
h
e
10
-
-
sum
r
a
t
h
e
r
t
h
a
n
‘
1
2
’
.
-
M
O
D
(
S
U
M
(
d
o
u
b
l
e
d
_
d
i
g
i
t
/
I
NT
8
’
1
0
’
+
d
o
u
b
l
e
d
_
d
i
g
i
t
%
IN
T8
’
1
0
’
)
,
1
0
)
=
0
-
F
R
O
M
-
-
-
D
o
u
b
l
e
o
d
d
-
n
u
m
b
e
r
e
d
d
i
g
i
t
s
(
c
o
u
n
t
i
n
g
l
e
f
t
w
i
t
h
-
-
-
l
e
a
s
t
s
i
g
n
i
f
i
c
a
n
t
a
s
z
e
r
o
)
.
I
f
t
h
e
d
o
u
b
l
e
d
d
i
g
i
t
s
e
n
d
up
15
-
-
h
a
v
i
n
g
v
a
l
u
e
s
-
-
-
>
1
0
(
i
e
t
h
e
y
’
r
e
t
w
o
d
i
g
i
t
s
)
,
a
d
d
t
h
e
i
r
d
i
g
i
t
s
t
o
g
e
t
h
e
r
.
-
(
S
E
L
E
C
T
-
-
-
E
x
t
r
a
c
t
d
i
g
i
t
‘
n
’
c
o
u
n
t
i
n
g
l
e
f
t
f
r
o
m
l
e
a
s
t
s
i
g
n
i
f
i
c
a
n
t
-
-
-
a
s
z
e
r
o
20
M
O
D
(
(
$
1
:
:
i
n
t
8
/
(
1
0
^
n
)
:
:
i
n
t
8
)
,
1
0
:
:
i
n
t
8
)
-
-
-
D
o
u
b
l
e
o
d
d
-
n
u
m
b
e
r
e
d
d
i
g
i
t
s
-
*
(
M
O
D
(
n
,
2
)
+
1
)
-
A
S
d
o
u
b
l
e
d
_
d
i
g
i
t
-
F
R
O
M
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
0
,
CEIL
(L
O
G(
$
1
)
)
:
:
I
N
T
E
G
E
R
-
1
)
A
S
n
25
)
AS
d
o
u
b
l
e
d
_
d
i
g
i
t
s
;
-
-
$
$
L
A
N
G
U
A
G
E
’
SQ
L
’
-
I
M
M
U
T
A
B
L
E
-
S
TR
IC
T
;
30
-
C
O
M
M
E
N
T
O
N
F
U
N
C
T
I
O
N
l
u
h
n
_
v
e
r
i
f
y
(
i
n
t
8
)
I
S
’
R
e
t
u
r
n
t
r
u
e
i
f
f
t
h
e
l
a
s
t
d
i
g
i
t
o
f
t
h
e
-
i
n
p
u
t
i
s
a
c
o
r
r
e
c
t
c
h
e
c
k
d
i
g
i
t
f
o
r
t
h
e
r
e
s
t
o
f
t
h
e
i
n
p
u
t
a
c
c
o
r
d
i
n
g
t
o
L
u
h
n
’
’
s
-
a
l
g
o
r
i
t
h
m
.
’
;
-
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
l
u
h
n
_
g
e
n
e
r
a
t
e
_
c
h
e
c
k
d
i
g
i
t
(
i
n
t
8
)
R
E
T
U
R
N
S
i
n
t
8
A
S
$
$
35
S
E
L
E
C
T
-
-
-
Add
t
h
e
d
i
g
i
t
s
,
d
o
u
b
l
i
n
g
e
v
e
n
-
n
u
m
b
e
r
e
d
d
i
g
i
t
s
(
c
o
u
n
t
i
n
g
l
e
f
t
-
-
-
w
i
t
h
l
e
a
s
t
-
s
i
g
n
i
f
i
c
a
n
t
a
s
z
e
r
o
)
.
S
u
b
t
r
a
c
t
t
h
e
r
e
m
a
i
n
d
e
r
o
f
-
-
-
d
i
v
i
d
i
n
g
t
h
e
sum
b
y
1
0
f
r
o
m
1
0
,
a
n
d
t
a
k
e
t
h
e
r
e
m
a
i
n
d
e
r
-
-
-
o
f
d
i
v
i
d
i
n
g
t
h
a
t
b
y
1
0
i
n
t
u
r
n
.
293
14.2.
Мелочи
40
(
(
IN
T8
’
1
0
’
-
S
U
M
(
d
o
u
b
l
e
d
_
d
i
g
i
t
/
I
NT
8
’
1
0
’
+
d
o
u
b
l
e
d
_
d
i
g
i
t
% I
NT
8
’
1
0
’
)
%
-
IN
T8
’
1
0
’
)
% IN
T8
’
1
0
’
)
:
:
IN
T
8
-
F
R
O
M
(
S
E
L
E
C
T
-
-
-
E
x
t
r
a
c
t
d
i
g
i
t
‘
n
’
c
o
u
n
t
i
n
g
l
e
f
t
f
r
o
m
l
e
a
s
t
s
i
g
n
i
f
i
c
a
n
t
\
-
-
-
a
s
z
e
r
o
45
M
O
D
(
(
$
1
:
:
i
n
t
8
/
(
1
0
^
n
)
:
:
i
n
t
8
)
,
1
0
:
:
i
n
t
8
)
-
-
-
d
o
u
b
l
e
e
v
e
n
-
n
u
m
b
e
r
e
d
d
i
g
i
t
s
-
*
(
2
-
M
O
D
(
n
,
2
)
)
-
A
S
d
o
u
b
l
e
d
_
d
i
g
i
t
-
F
R
O
M
g
e
n
e
r
a
t
e
_
s
e
r
i
e
s
(
0
,
CEIL
(L
O
G(
$
1
)
)
:
:
I
N
T
E
G
E
R
-
1
)
A
S
n
50
)
AS
d
o
u
b
l
e
d
_
d
i
g
i
t
s
;
-
-
$
$
L
A
N
G
U
A
G
E
’
SQ
L
’
-
I
M
M
U
T
A
B
L
E
-
S
TR
IC
T
;
55
-
C
O
M
M
E
N
T
O
N
F
U
N
C
T
I
O
N
l
u
h
n
_
g
e
n
e
r
a
t
e
_
c
h
e
c
k
d
i
g
i
t
(
i
n
t
8
)
I
S
’
F
o
r
t
h
e
i
n
p
u
t
-
v
a
l
u
e
,
g
e
n
e
r
a
t
e
a
c
h
e
c
k
d
i
g
i
t
a
c
c
o
r
d
i
n
g
t
o
L
u
h
n
’
’
s
a
l
g
o
r
i
t
h
m
’
;
-
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
l
u
h
n
_
g
e
n
e
r
a
t
e
(
i
n
t
8
)
R
E
T
U
R
N
S
i
n
t
8
A
S
$
$
-
S
E
L
E
C
T
1
0
*
$
1
+
l
u
h
n
_
g
e
n
e
r
a
t
e
_
c
h
e
c
k
d
i
g
i
t
(
$
1
)
;
60
$
$
L
A
N
G
U
A
G
E
’
SQ
L
’
-
I
M
M
U
T
A
B
L
E
-
S
TR
IC
T
;
-
-
C
O
M
M
E
N
T
O
N
F
U
N
C
T
I
O
N
l
u
h
n
_
g
e
n
e
r
a
t
e
(
i
n
t
8
)
I
S
’
Ap
p
e
n
d
a
c
h
e
c
k
d
i
g
i
t
g
e
n
e
r
a
t
e
d
65
a
c
c
o
r
d
i
n
g
t
o
L
u
h
n
’
’
s
a
l
g
o
r
i
t
h
m
t
o
t
h
e
i
n
p
u
t
v
a
l
u
e
.
T
h
e
i
n
p
u
t
v
a
l
u
e
m
u
s
t
b
e
n
o
-
g
r
e
a
t
e
r
t
h
a
n
(
m
a
x
b
i
g
i
n
t
/
1
0
)
.
’
;
-
C
R
E
A
T
E
O
R
R
E
P
L
A
C
E
F
U
N
C
T
I
O
N
l
u
h
n
_
s
t
r
i
p
(
i
n
t
8
)
R
E
T
U
R
N
S
i
n
t
8
A
S
$
$
-
S
E
L
E
C
T
$
1
/
1
0
;
-
$
$
L
A
N
G
U
A
G
E
’
SQ
L
’
70
I
M
M
U
T
A
B
L
E
-
S
TR
IC
T
;
-
-
C
O
M
M
E
N
T
O
N
F
U
N
C
T
I
O
N
l
u
h
n
_
s
t
r
i
p
(
i
n
t
8
)
I
S
’
S
t
r
i
p
t
h
e
l
e
a
s
t
s
i
g
n
i
f
i
c
a
n
t
d
i
g
i
t
f
r
o
m
-
t
h
e
i
n
p
u
t
v
a
l
u
e
.
I
n
t
e
n
d
e
d
f
o
r
u
s
e
w
h
e
n
s
t
r
i
p
p
i
n
g
t
h
e
c
h
e
c
k
d
i
g
i
t
f
r
o
m
a
n
u
m
b
e
r
75
i
n
c
l
u
d
i
n
g
a
L
u
h
n
’
’
s
a
l
g
o
r
i
t
h
m
c
h
e
c
k
d
i
g
i
t
.
’
;
294
14.2.
Мелочи
Пример:
Листинг
14.5
Алгоритм
Луна.
Пример
Line
1
S
e
l
e
c
t
l
u
h
n
_
v
e
r
i
f
y
(
4
9
9
2
7
3
9
8
7
1
6
)
;
-
l
u
h
n
_
v
e
r
i
f
y
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
t
5
(
1
r
o
w
)
-
-
S
e
l
e
c
t
l
u
h
n
_
v
e
r
i
f
y
(
4
9
9
2
7
3
9
8
7
1
4
)
;
-
l
u
h
n
_
v
e
r
i
f
y
-
-
-
-
-
-
-
-
-
-
-
-
-
-
10
f
-
(
1
r
o
w
)
Выборк
а
и
сортировка
по
данному
набору
данных
Выбор
данных
по
определенному
набору
данных
мо
жно
с
делать
с
по-
мощью
обыкновенного
IN
.
Но
к
ак
сделать
подобную
выборку
и
отсорти-
ровать
данные
в
том
же
пор
ядк
е,
в
к
отором
передан
набор
данных?
На-
пример:
Дан
набор:
(2,6,4,10,25,7,9).
Нужно
получить
найденные
данные
в
та-
к
ом
же
порядк
е
т
.
е.
2
2
2
6
6
4
4
Ск
ачать
snipp
ets/order_lik
e_in.sql
Line
1
S
E
L
E
C
T
f
o
o
.
*
F
R
O
M
f
o
o
-
JOIN
(
S
E
L
E
C
T
i
d
.
v
a
l
,
r
o
w
_
n
u
m
b
e
r
(
)
o
v
e
r
(
)
F
R
O
M
(
V
A
L
U
E
S
(
3
)
,
(
2
)
,
(
6
)
,
(
1
)
,
(
4
)
)
AS
-
i
d
(
v
a
l
)
)
A
S
i
d
-
O
N
(
f
o
o
.
c
a
t
a
l
o
g
_
i
d
=
i
d
.
v
a
l
)
O
R
D
E
R
B
Y
r
ow
_
n
u
m
b
e
r
;
г
де
V
ALUES
(3),(2),(6),(1),(4)
—
наш
набор
данных
fo
o
–
таблица,
из
которой
идет
выборка
fo
o
.
catalog_id
— поле,
по к
оторому
ищем
набор данных
(замена
foo
.
catalog_id
IN
(3,2,6,1,4)
)
Quine
—
запрос
к
оторый
выводит
сам
себя
Ку
айн,
квайн
(анг
л.
quine)
—
компьютерная
программа
(частный
слу-
чай мет
апрограммирования), которая
выдаёт на вых
о
де точную к
опию
своего
ис
хо
дного
текст
а.
Ск
ачать
snipp
ets/quine.sql
295
14.2.
Мелочи
Line
1
s
e
l
e
c
t
a
|
|
’
f
r
o
m
(
s
e
l
e
c
t
’
|
|
q
u
o
t
e
_
l
i
t
e
r
a
l
(
a
)
|
|
b
|
|
’
,
’
|
|
q
u
o
t
e
_
l
i
t
e
r
a
l
(
b
)
|
|
’
:
:
t
e
x
t
a
s
b
)
a
s
q
u
i
n
e
’
f
r
o
m
-
(
s
e
l
e
c
t
’
s
e
l
e
c
t
a
|
|
’
’
f
r
o
m
(
s
e
l
e
c
t
’
’
|
|
q
u
o
t
e
_
l
i
t
e
r
a
l
(
a
)
|
|
b
|
|
’
’
,
’
’
|
|
q
u
o
t
e
_
l
i
t
e
r
a
l
(
b
)
|
|
’
’
:
:
t
e
x
t
a
s
b
)
a
s
-
q
u
i
n
e
’
’
’
:
:
t
e
x
t
a
s
a
,
’
:
:
t
e
x
t
a
s
a
’
:
:
t
e
x
t
a
s
b
)
a
s
q
u
i
n
e
;
Поиск
дублик
атов
индексов
Запрос
нахо
дит
индексы,
созданные
на
одинак
овый
набор
столбцов
(та-
кие
индек
сы
эквивалентны,
а
значит
бесполезны).
Ск
ачать
snipp
ets/duplicate_indexes.sql
Line
1
S
E
L
E
C
T
p
g
_
s
i
z
e
_
p
r
e
t
t
y
(
sum
(
p
g
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
i
d
x
)
)
:
:
b
i
g
i
n
t
)
A
S
s
i
z
e
,
-
(
a
r
r
a
y
_
a
g
g
(
i
d
x
)
)
[
1
]
AS
i
d
x
1
,
(
a
r
r
a
y
_
a
g
g
(
i
d
x
)
)
[
2
]
AS
i
d
x
2
,
-
(
a
r
r
a
y
_
a
g
g
(
i
d
x
)
)
[
3
]
AS
i
d
x
3
,
(
a
r
r
a
y
_
a
g
g
(
i
d
x
)
)
[
4
]
AS
i
d
x
4
-
F
R
O
M
(
5
S
E
L
E
C
T
i
n
d
e
x
r
e
l
i
d
:
:
r
e
g
c
l
a
s
s
A
S
i
d
x
,
(
i
n
d
r
e
l
i
d
:
:
t
e
x
t
|
|
E
’
\
n
’
|
|
i
n
d
c
l
a
s
s
:
:
t
e
x
t
|
|
E
’
\
n
’
|
|
i
n
d
k
e
y
:
:
t
e
x
t
|
|
E
’
\
n
’
|
|
-
c
o
a
l
e
s
c
e
(
i
n
d
e
x
p
r
s
:
:
t
e
x
t
,
’
’
)
|
|
E
’
\
n
’
|
|
c
o
a
l
e
s
c
e
(
i
n
d
p
r
e
d
:
:
t
e
x
t
,
’
’
)
)
A
S
K
E
Y
-
F
R
O
M
p
g
_
i
n
d
e
x
)
s
u
b
-
G
R
O
U
P
B
Y
K
E
Y
H
A
V
I
N
G
c
o
u
n
t
(
*
)
>1
-
O
R
D
E
R
B
Y sum
(
p
g
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
i
d
x
)
)
D
E
S
C
;
Р
азмер
и
статистик
а
использования
индек
сов
Ск
ачать
snipp
ets/indexes_statustic.sql
Line
1
S
E
L
E
C
T
-
t
.
t
a
b
l
e
n
a
m
e
,
-
i
n
d
e
x
n
a
m
e
,
-
c
.
r
e
l
t
u
p
l
e
s
AS
n
um_
row
s
,
5
p
g
_
s
i
z
e
_
p
r
e
t
t
y
(
p
g
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
q
u
o
t
e
_
i
d
e
n
t
(
t
.
t
a
b
l
e
n
a
m
e
)
:
:
t
e
x
t
)
)
A
S
t
a
b
l
e
_
s
i
z
e
,
-
p
g
_
s
i
z
e
_
p
r
e
t
t
y
(
p
g
_
r
e
l
a
t
i
o
n
_
s
i
z
e
(
q
u
o
t
e
_
i
d
e
n
t
(
i
n
d
e
x
r
e
l
n
a
m
e
)
:
:
t
e
x
t
)
)
A
S
i
n
d
e
x
_
s
i
z
e
,
-
C
A
S
E
W
H
E
N
x
.
i
s
_
u
n
i
q
u
e
=
1
T
H
E
N
’
Y
’
-
E
L
SE
’
N
’
-
E
N
D A
S U
N
I
Q
U
E
,
10
i
d
x
_
s
c
a
n
A
S
n
u
m
b
e
r
_
o
f
_
s
c
a
n
s
,
-
i
d
x
_
t
u
p
_
r
e
a
d
A
S
t
u
p
l
e
s
_
r
e
a
d
,
-
i
d
x
_
t
u
p
_
f
e
t
c
h
AS
t
u
p
l
e
s
_
f
e
t
c
h
e
d
-
F
R
O
M
p
g
_
t
a
b
l
e
s
t
296
14.2.
Мелочи
-
L
E
F
T
O
U
T
E
R JOIN
p
g
_
c
l
a
s
s
c
O
N
t
.
t
a
b
l
e
n
a
m
e=c
.
r
e
l
n
a
m
e
15
L
E
F
T
O
U
T
E
R JOIN
-
(
S
E
L
E
C
T
i
n
d
r
e
l
i
d
,
-
ma
x
(
C
A
S
T
(
i
n
d
i
s
u
n
i
q
u
e
A
S
i
n
t
e
g
e
r
)
)
A
S
i
s
_
u
n
i
q
u
e
-
F
R
O
M
p
g
_
i
n
d
e
x
-
G
R
O
U
P
B
Y
i
n
d
r
e
l
i
d
)
x
20
O
N
c
.
o
i
d
=
x
.
i
n
d
r
e
l
i
d
-
L
E
F
T
O
U
T
E
R JOIN
-
(
S
E
L
E
C
T
c
.
r
e
l
n
a
m
e
A
S
c
t
a
b
l
e
n
a
m
e
,
i
p
g
.
r
e
l
n
a
m
e
A
S
i
n
d
e
x
n
a
m
e
,
x
.
i
n
d
n
a
t
t
s
A
S
n
u
m
b
e
r
_
o
f
_
c
o
l
u
m
n
s
,
i
d
x
_
s
c
a
n
,
i
d
x
_
t
u
p
_
r
e
a
d
,
i
d
x
_
t
u
p
_
f
e
t
c
h
,
i
n
d
e
x
r
e
l
n
a
m
e
F
R
O
M
p
g
_
i
n
d
e
x
x
-
JOIN
p
g
_
c
l
a
s
s
c
O
N
c
.
o
i
d
=
x
.
i
n
d
r
e
l
i
d
-
JOIN
p
g
_
c
l
a
s
s
i
p
g
O
N
i
p
g
.
o
i
d
=
x
.
i
n
d
e
x
r
e
l
i
d
25
JOIN
p
g
_
s
t
a
t
_
a
l
l
_
i
n
d
e
x
e
s
p
s
a
i
O
N
x
.
i
n
d
e
x
r
e
l
i
d
=
p
s
a
i
.
i
n
d
e
x
r
e
l
i
d
)
-
AS
f
o
o
-
O
N
t
.
t
a
b
l
e
n
a
m
e
=
f
o
o
.
c
t
a
b
l
e
n
a
m
e
-
W
H
E
R
E
t
.
s
c
h
e
m
a
n
a
m
e
=
’
p
u
b
l
i
c
’
-
O
R
D
E
R
B
Y
1
,
2
;
Р
азмер
распухания
(bloat)
таблиц
и
индексов
в
базе
данных
Запрос,
к
оторый
пок
азывает
«приблизительный»
bloat
(раздутие)
т
аб-
лиц
и
индек
сов
в
базе:
Ск
ачать
snipp
ets/bloating.sql
Line
1
W
I
T
H
c
o
n
s
t
a
n
t
s
A
S
(
-
S
E
L
E
C
T
c
u
r
r
e
n
t
_
s
e
t
t
i
n
g
(
’
b
l
o
c
k
_
s
i
z
e
’
)
:
:
n
u
m
e
r
i
c
A
S
b
s
,
2
3
AS
h
d
r
,
4
A
S
m
a
-
)
,
b
l
o
a
t
_
i
n
f
o
A
S
(
-
S
E
L
E
C
T
5
ma
,
b
s
,
s
c
h
e
m
a
n
a
m
e
,
t
a
b
l
e
n
a
m
e
,
-
(
d
a
t
a
w
i
d
t
h
+
(
h
d
r+
m
a
-
(
c
a
s
e
w
h
e
n
h
d
r
%
m
a
=
0
T
H
E
N
m
a
EL
SE
h
d
r%
m
a
E
N
D
)
)
)
:
:
n
u
m
e
r
i
c
A
S
d
a
t
a
h
d
r
,
-
(
m
a
x
f
r
a
c
s
u
m
*
(
n
u
l
l
h
d
r
+
ma
-
(
c
a
s
e
w
h
e
n
n
u
l
l
h
d
r%
m
a
=
0
T
H
E
N
m
a
E
LS
E
n
u
l
l
h
d
r%
m
a
E
N
D
)
)
)
AS
n
u
l
l
h
d
r
2
-
F
R
O
M
(
-
S
E
L
E
C
T
10
s
c
h
e
m
a
n
a
m
e
,
t
a
b
l
e
n
a
m
e
,
h
d
r
,
m
a
,
b
s
,
-
S
U
M
(
(
1
-
n
u
l
l
_
f
r
a
c
)
*
a
v
g
_
w
i
d
t
h
)
A
S
d
a
t
a
w
i
d
t
h
,
-
M
A
X
(
n
u
l
l
_
f
r
a
c
)
AS
m
a
x
f
r
a
c
s
u
m
,
-
h
d
r
+(
-
S
E
L
E
C
T
1
+
c
o
u
n
t
(
*
)
/
8
15
F
R
O
M
p
g
_
s
t
a
t
s
s
2
-
W
H
E
R
E
n
u
l
l
_
f
r
a
c
<
>
0
A
N
D
s
2
.
s
c
h
e
m
a
n
a
m
e
=
s
.
s
c
h
e
m
a
n
a
m
e
A
N
D
s
2
.
t
a
b
l
e
n
a
m
e
=
s
.
t
a
b
l
e
n
a
m
e
-
)
AS
n
u
l
l
h
d
r
-
F
R
O
M
p
g
_
s
t
a
t
s
s
,
c
o
n
s
t
a
n
t
s
297
14.2.
Мелочи
-
G
R
O
U
P
B
Y
1
,
2
,
3
,
4
,
5
20
)
AS
f
o
o
-
)
,
t
a
b
l
e
_
b
l
o
a
t
A
S
(
-
S
E
L
E
C
T
-
s
c
h
e
m
a
n
a
m
e
,
t
a
b
l
e
n
a
m
e
,
c
c
.
r
e
l
p
a
g
e
s
,
b
s
,
-
CEIL
(
(
c
c
.
r
e
l
t
u
p
l
e
s
*
(
(
d
a
t
a
h
d
r+
m
a
-
25
(
C
A
S
E
W
H
E
N
d
a
t
a
h
d
r%
m
a
=0
T
H
E
N
m
a
EL
SE
d
a
t
a
h
d
r%
m
a
E
N
D
)
)
+
n
u
l
l
h
d
r
2
+
4
)
)
/
(
b
s
-
2
0
:
:
f
l
o
a
t
)
)
A
S
o
t
t
a
-
F
R
O
M
b
l
o
a
t
_
i
n
f
o
-
JOIN
p
g
_
c
l
a
s
s
c
c
O
N
c
c
.
r
e
l
n
a
m
e
=
b
l
o
a
t
_
i
n
f
o
.
t
a
b
l
e
n
a
m
e
-
JOIN
p
g
_
n
a
m
e
s
p
a
c
e
n
n
O
N
c
c
.
r
e
l
n
a
m
e
s
p
a
c
e
=
n
n
.
o
i
d
A
N
D
n
n
.
n
s
p
n
a
m
e
=
b
l
o
a
t
_
i
n
f
o
.
s
c
h
e
m
a
n
a
m
e
A
N
D
n
n
.
n
s
p
n
a
m
e <
>
’
i
n
f
o
r
m
a
t
i
o
n
_
s
c
h
e
m
a
’
-
)
,
i
n
d
e
x
_
b
l
o
a
t
A
S
(
30
S
E
L
E
C
T
-
s
c
h
e
m
a
n
a
m
e
,
t
a
b
l
e
n
a
m
e
,
b
s
,
-
C
O
A
L
E
S
C
E
(
c
2
.
r
e
l
n
a
m
e
,
’
?
’
)
AS
i
n
a
m
e
,
C
O
A
L
E
S
C
E
(
c
2
.
r
e
l
t
u
p
l
e
s
,
0
)
AS
i
t
u
p
l
e
s
,
C
O
A
L
E
S
C
E
(
c
2
.
r
e
l
p
a
g
e
s
,
0
)
A
S
i
p
a
g
e
s
,
-
C
O
A
L
E
S
C
E
(
C
EIL
(
(
c
2
.
r
e
l
t
u
p
l
e
s
*
(
d
a
t
a
h
d
r
-
1
2
)
)
/
(
b
s
-
2
0
:
:
f
l
o
a
t
)
)
,
0
)
A
S
i
o
t
t
a
-
-
v
e
r
y
r
o
u
g
h
a
p
p
r
o
x
i
m
a
t
i
o
n
,
a
s
s
u
m
e
s
a
l
l
c
o
l
s
-
F
R
O
M
b
l
o
a
t
_
i
n
f
o
35
JOIN
p
g
_
c
l
a
s
s
c
c
O
N
c
c
.
r
e
l
n
a
m
e
=
b
l
o
a
t
_
i
n
f
o
.
t
a
b
l
e
n
a
m
e
-
JOIN
p
g
_
n
a
m
e
s
p
a
c
e
n
n
O
N
c
c
.
r
e
l
n
a
m
e
s
p
a
c
e
=
n
n
.
o
i
d
A
N
D
n
n
.
n
s
p
n
a
m
e
=
b
l
o
a
t
_
i
n
f
o
.
s
c
h
e
m
a
n
a
m
e
A
N
D
n
n
.
n
s
p
n
a
m
e <
>
’
i
n
f
o
r
m
a
t
i
o
n
_
s
c
h
e
m
a
’
-
JOIN
p
g
_
i
n
d
e
x
i
O
N
i
n
d
r
e
l
i
d
=
c
c
.
o
i
d
-
JOIN
p
g
_
c
l
a
s
s
c
2
O
N
c
2
.
o
i
d
=
i
.
i
n
d
e
x
r
e
l
i
d
-
)
40
S
E
L
E
C
T
-
t
y
p
e
,
s
c
h
e
m
a
n
a
m
e
,
o
b
j
e
c
t
_
n
a
m
e
,
b
l
o
a
t
,
p
g
_
s
i
z
e
_
p
r
e
t
t
y
(
r
a
w
_
w
a
s
t
e
)
a
s
w
a
s
t
e
-
F
R
O
M
-
(
S
E
L
E
C
T
-
’
t
a
b
l
e
’
a
s
t
y
p
e
,
45
s
c
h
e
m
a
n
a
m
e
,
-
t
a
b
l
e
n
a
m
e
a
s
o
b
j
e
c
t
_
n
a
m
e
,
-
R
O
U
N
D
(
C
A
S
E
W
H
E
N
o
t
t
a
=0
T
H
E
N
0
.
0
E
LS
E
t
a
b
l
e
_
b
l
o
a
t
.
r
e
l
p
a
g
e
s
/
o
t
t
a
:
:
n
u
m
e
r
i
c
E
N
D
,
1
)
AS
b
l
o
a
t
,
-
C
A
S
E
W
H
E
N
r
e
l
p
a
g
e
s
<
o
t
t
a
T
H
E
N
’
0
’
E
LS
E
(
b
s
*
(
t
a
b
l
e
_
b
l
o
a
t
.
r
e
l
p
a
g
e
s
-
o
t
t
a
)
:
:
b
i
g
i
n
t
)
:
:
b
i
g
i
n
t
E
N
D
AS
r
a
w
_
w
a
s
t
e
-
F
R
O
M
50
t
a
b
l
e
_
b
l
o
a
t
-
U
N
I
O
N
-
S
E
L
E
C
T
-
’
i
n
d
e
x
’
a
s
t
y
p
e
,
-
s
c
h
e
m
a
n
a
m
e
,
298
14.2.
Мелочи
55
t
a
b
l
e
n
a
m
e
|
|
’
:
:
’
|
|
i
n
a
m
e
a
s
o
b
j
e
c
t
_
n
a
m
e
,
-
R
O
U
N
D
(
C
A
S
E
W
H
E
N
i
o
t
t
a
=
0
O
R
i
p
a
g
e
s
=0
T
H
E
N
0
.
0
EL
S
E
i
p
a
g
e
s
/
i
o
t
t
a
:
:
n
u
m
e
r
i
c
E
N
D
,
1
)
A
S
b
l
o
a
t
,
-
C
A
S
E
W
H
E
N
i
p
a
g
e
s
<
i
o
t
t
a
T
H
E
N
’
0
’
E
LS
E
(
b
s
*
(
i
p
a
g
e
s
-
i
o
t
t
a
)
)
:
:
b
i
g
i
n
t
E
N
D A
S
r
a
w
_
w
a
s
t
e
-
F
R
O
M
-
i
n
d
e
x
_
b
l
o
a
t
)
b
l
o
a
t
_
s
u
m
m
a
r
y
60
O
R
D
E
R
B
Y
r
a
w
_
w
a
s
t
e
D
E
S
C
,
b
l
o
a
t
D
E
S
C
299
Литература
[1] Алек
сей
Борзов
(Sad
Spirit)
b
orz_off@cs.msu.su
P
ostgreSQL:
настройк
а
произво
дительности
h
ttp://www.php
club.ru/detail/store/p
df/p
ostgresql-p
erformance.p
df
[2] Eugene
Kuzin
eugene@kuzin.net
Настройк
а реплик
ации в
P
ostgreSQL
с
помощью
системы
Slony-I
http://www.kuzin.net/w
ork/sloniki-
priv
et.html
[3] Sergey
Konoplev
gray
.ru@gmail.com
У
становк
а
Londiste
в
подробност
ях
h
ttp://gray-hemp.blogspot.com/2010/04/londiste.html
[4] Dmitry
Stasyuk
Учебное
руково
дство
по
pgpo
ol-I
I
h
ttp://undenied.ru/2009/03/04/uchebnoe-ruko
vodstvo-po-pgp
o
ol-ii/
[5] Чиркин
Дима
dmitry
.chirkin@gmail.com
Г
оризонталь-
ное
масшт
абирование
PostgreSQL
с
помощью
PL/Pro
xy
h
ttp://habrahabr.ru/blogs/p
ostgresql/45475/
[6] Иван
Блинков
wordpress@insigh
t-it.ru
Hado
op
h
ttp://www.insight-
it.ru/massh
tabiruemost/hado
op/
[7] P
adraig
O’Sulliv
an
Up
and
Running
with
Hado
opDB
h
ttp://p
osulliv.gith
ub.com/2010/05/10/hado
op
db-m
ysql.h
tml
[8] Иван
Золотухин
Масшт
абирование P
ostgreSQL: готовые
решения
от
Skyp
e
h
ttp://p
ostgresmen.ru/articles/view/25
[9] Streaming
Replication.
h
ttp://wiki.p
ostgresql.org/wiki/Streaming_Replication
[10] Den
Golot
yuk
Шардинг
,
партиционирование,
репликация
-
за-
чем
и
к
огда?
http://highload.com.ua/index.php/2009/05/06/шар
динг-
партиционирование-реплик
ац/
[11] P
ostgres-XC
—
A
P
ostgreSQL
Clustering
Solution
h
ttp://www.linuxforu.com/2012/01/postgres-xc-database-clustering-
solution/
300
Литература
[12] Введение
в
P
ostgreSQL
BDR
http://habrahabr.ru/post/227959/
[13] Попу
лярный
обзор
внутренностей
базы
данных.
Часть
пятая
h
ttp://zamotiv
ator.livejournal.com/332814.h
tml
[14] BRIN-индек
сы
в
PostgreSQL
http://langtoday
.com/?p=485
[15] Huge
P
ages
в
PostgreSQL
https://habrahabr.ru/post/228793/
[16] Greenplum
DB
h
ttps://habrahabr.ru/company/tink
off/blog/267733/
[17] Введение
в
P
ostGIS
https://liv
e.osgeo.org/ru/quic
kstart/p
ostgis_quic
kstart.h
tml
[18] Введение
в
полнотек
стовый
поиск
в
P
ostgreSQL
h
ttp://www.sai.msu.su/
megera/p
ostgres/talks/fts_pgsql_in
tro.html
[19] pg_arman
h
ttps://p
ostgrespro.ru/do
cs/p
ostgrespro/9.5/pg-arman.html
[20] It
Probably
W
orks
h
ttp://queue.acm.org/detail.cfm?id=2855183
[21] Кластер
P
ostgreSQL
высок
ой
надежности
на базе
Patroni,
Hapro
xy
,
Keepaliv
ed
https://habrahabr.ru/post/322036/
301