diff --git a/clustering/greenplum.tex b/clustering/greenplum.tex index da8f94d5..18e5deae 100644 --- a/clustering/greenplum.tex +++ b/clustering/greenplum.tex @@ -127,7 +127,7 @@ \subsection{Хранение данных} \subsection{Взаимодействие с клиентами} -В общем случае всё взаимодействие клиентов с кластером ведётся только через мастер~--- именно он отвечает клиентам, выдаёт им результат запроса и т.д. Обычные клиенты не имеют сетевого доступа к серверам-сегментам. +В общем случае всё взаимодействие клиентов с кластером ведётся только через мастер~--- именно он отвечает клиентам, выдаёт им результат запроса и~т.~д. Обычные клиенты не имеют сетевого доступа к серверам-сегментам. Для ускорения загрузки данных в кластер используется bulk load~--- параллельная загрузка данных с/на клиент одновременно с нескольких сегментов. Bulk load возможен только с клиентов, имеющих доступ в интерконнекты. Обычно в роли таких клиентов выступают ETL-сервера и другие системы, которым необходима загрузка большого объёма данных (на рис~\ref{fig:greenplum_arch1} они обозначены как ETL/Pro client). diff --git a/clustering/postgres_x2.tex b/clustering/postgres_x2.tex index f02af089..d03fd1e1 100644 --- a/clustering/postgres_x2.tex +++ b/clustering/postgres_x2.tex @@ -3,7 +3,7 @@ \section{Postgres-X2} Postgres-X2~-- система для создания мульти-мастер кластеров, работающих в синхронном режиме~-- все узлы всегда содержат актуальные данные. Postgres-X2 поддерживает опции для увеличения масштабирования кластера как при преобладании операций записи, так и при основной нагрузке на чтение данных: поддерживается выполнение транзакций с распараллеливанием на несколько узлов, за целостностью транзакций в пределах всего кластера отвечает специальный узел GTM (Global Transaction Manager). -Измерение производительности показало, что КПД кластера Postgres-X2 составляет примерно 64\%, т.е. кластер из 10 серверов позволяет добиться увеличения производительности системы в целом в 6.4 раза, относительно производительности одного сервера (цифры приблизительные). +Измерение производительности показало, что КПД кластера Postgres-X2 составляет примерно 64\%, т.~е. кластер из 10 серверов позволяет добиться увеличения производительности системы в целом в 6.4 раза, относительно производительности одного сервера (цифры приблизительные). Система не использует в своей работе триггеры и представляет собой набор дополнений и патчей к PostgreSQL, дающих возможность в прозрачном режиме обеспечить работу в кластере стандартных приложений, без их дополнительной модификации и адаптации (полная совместимость с PostgreSQL API). Кластер состоит из одного управляющего узла (GTM), предоставляющего информацию о состоянии транзакций, и произвольного набора рабочих узлов, каждый из которых в свою очередь состоит из координатора и обработчика данных (обычно эти элементы реализуются на одном сервере, но могут быть и разделены). diff --git a/extensions/cstore_fdw.tex b/extensions/cstore_fdw.tex index b0fcbbfc..624af323 100644 --- a/extensions/cstore_fdw.tex +++ b/extensions/cstore_fdw.tex @@ -126,4 +126,4 @@ \subsection{Установка и использование} \subsection{Заключение} -Более подробно о использовании расширения можно ознакомиться через \href{https://citusdata.github.io/cstore_fdw/}{официальную документацию}. +Более подробно об использовании расширения можно ознакомиться через \href{https://citusdata.github.io/cstore_fdw/}{официальную документацию}. diff --git a/extensions/hll.tex b/extensions/hll.tex index b501f99b..48a61015 100644 --- a/extensions/hll.tex +++ b/extensions/hll.tex @@ -11,11 +11,11 @@ \section{Postgresql-hll} \item вероятность того, что совместно произойдут два независимых случайных события $A$ и $B$, вычисляется по формуле $P(A)*P(B)$. Таким образом, если вероятность равенства единице одного любого бита случайного числа составляет 50\%, тогда вероятность равенства единице двух любых битов составляет 25\%, трех~--- 12,5\% и т.д; \end{itemize} -Вспомним еще одно базовое положение теории вероятностей, согласно которому ожидаемое количество испытаний, необходимое для наступления события, вычисляется по формуле $1/P(event)$. Следовательно, если $P(one\ specific\ bit\ set) = 50\%$, то ожидаемое количество испытаний равно 2. Для двух битов~--- 4, для трех битов~--- 8 и т.д. +Вспомним еще одно базовое положение теории вероятностей, согласно которому ожидаемое количество испытаний, необходимое для наступления события, вычисляется по формуле $1/P(event)$. Следовательно, если $P(one\ specific\ bit\ set) = 50\%$, то ожидаемое количество испытаний равно 2. Для двух битов~--- 4, для трех битов~--- 8 и~т.~д. -В общем случае входные значения не являются равномерно распределенными случайными числами, поэтому необходим способ преобразования входных значений к равномерному распределению, т.е. необходима хеш-функция. Обратите внимание, в некоторых случаях распределение, получаемое на выходе хеш-функции, не оказывает существенное влияние на точность системы. Однако HyperLogLog очень чувствителен в этом отношении. Если выход хеш-функции не соответствует равномерному распределению, алгоритм теряет точность, поскольку не выполняются базовые допущения, лежащие в его основе. +В общем случае входные значения не являются равномерно распределенными случайными числами, поэтому необходим способ преобразования входных значений к равномерному распределению, т.~е. необходима хеш-функция. Обратите внимание, в некоторых случаях распределение, получаемое на выходе хеш-функции, не оказывает существенное влияние на точность системы. Однако HyperLogLog очень чувствителен в этом отношении. Если выход хеш-функции не соответствует равномерному распределению, алгоритм теряет точность, поскольку не выполняются базовые допущения, лежащие в его основе. -Рассмотрим алгоритм подробно. Вначале необходимо хешировать все элементы исследуемого набора. Затем нужно подсчитать количество последовательных начальных битов, равных единице, в двоичном представлении каждого хеша и определить максимальное значение этого количества среди всех хешей. Если максимальное количество единиц обозначить $n$, тогда количество уникальных элементов в наборе можно оценить, как $2^n$. То есть, если максимум один начальный бит равен единице, тогда количество уникальных элементов, в среднем, равно 2; если максимум три начальных бита равны единице, в среднем, мы можем ожидать 8 уникальных элементов и т.д. +Рассмотрим алгоритм подробно. Вначале необходимо хешировать все элементы исследуемого набора. Затем нужно подсчитать количество последовательных начальных битов, равных единице, в двоичном представлении каждого хеша и определить максимальное значение этого количества среди всех хешей. Если максимальное количество единиц обозначить $n$, тогда количество уникальных элементов в наборе можно оценить, как $2^n$. То есть, если максимум один начальный бит равен единице, тогда количество уникальных элементов, в среднем, равно 2; если максимум три начальных бита равны единице, в среднем, мы можем ожидать 8 уникальных элементов и~т.~д. Подход, направленный на повышение точности оценки и являющийся одной из ключевых идей HyperLogLog, заключается в следующем: разделяем хеши на подгруппы на основании их конечных битов, определяем максимальное количество начальных единиц в каждой подгруппе, а затем находим среднее. Этот подход позволяет получить намного более точную оценку общего количества уникальных элементов. Если мы имеем $m$ подгрупп и $n$ уникальных элементов, тогда, в среднем, в каждой подгруппе будет $n/m$ уникальных элементов. Таким образом, нахождение среднего по всем подгруппам дает достаточно точную оценку величины $log_2{(n/m)}$, а отсюда легко можно получить необходимое нам значение. Более того, HyperLogLog позволяет обрабатывать по отдельности различные варианты группировок, а затем на основе этих данных находить итоговую оценку. Следует отметить, что для нахождения среднего HyperLogLog использует среднее гармоническое, которое обеспечивает лучшие результаты по сравнению со средним арифметическим (более подробную информацию можно найти в оригинальных публикациях, посвященных \href{http://www.ic.unicamp.br/~celio/peer2peer/math/bitmap-algorithms/durand03loglog.pdf}{LogLog} и \href{http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf}{HyperLogLog}). @@ -98,4 +98,4 @@ \subsection{Установка и использование} \subsection{Заключение} -Более подробно о использовании расширения можно ознакомиться через \href{https://github.com/aggregateknowledge/postgresql-hll/blob/master/README.markdown}{официальную документацию}. +Более подробно об использовании расширения можно ознакомиться через \href{https://github.com/aggregateknowledge/postgresql-hll/blob/master/README.markdown}{официальную документацию}. diff --git a/extensions/hstore.tex b/extensions/hstore.tex index 2e8677cd..1cb5b414 100644 --- a/extensions/hstore.tex +++ b/extensions/hstore.tex @@ -1,7 +1,7 @@ \section{HStore} \label{sec:hstore-extension} -\href{https://www.postgresql.org/docs/current/static/hstore.html}{HStore}~-- расширение, которое реализует тип данных для хранения ключ/значение в пределах одного значения в PostgreSQL (например, в одном текстовом поле). Это может быть полезно в различных ситуациях, таких как строки с многими атрибутами, которые редко выбираются, или полу-структурированные данные. Ключи и значения являются простыми текстовыми строками. +\href{https://www.postgresql.org/docs/current/static/hstore.html}{HStore}~-- расширение, которое реализует тип данных для хранения ключ/значение в пределах одного значения в PostgreSQL (например, в одном текстовом поле). Это может быть полезно в различных ситуациях, таких как строки со многими атрибутами, которые редко выбираются, или полу-структурированные данные. Ключи и значения являются простыми текстовыми строками. Начиная с версии 9.4 PostgreSQL был добавлен JSONB тип (бинарный JSON). Данный тип является объединением JSON структуры с возможностью использовать индексы, как у Hstore. JSONB лучше Hstore тем, что есть возможность сохранять вложеную структуру данных (nested) и хранить не только текстовые строки в значениях. Поэтому лучше использовать JSONB, если есть такая возможность. @@ -90,4 +90,4 @@ \subsection{Установка и использование} \subsection{Заключение} -HStore~--- расширение для удобного и индексируемого хранения слабоструктурированых данных в PostgreSQL, если нет возможности использовать версию базы 9.4 или выше, где для данной задачи есть встроеный \href{https://www.postgresql.org/docs/current/static/datatype-json.html}{JSONB} тип данных. +HStore~--- расширение для удобного и индексируемого хранения слабоструктурированых данных в PostgreSQL, если нет возможности использовать версию базы 9.4 или выше, где для данной задачи есть встроенный \href{https://www.postgresql.org/docs/current/static/datatype-json.html}{JSONB} тип данных. diff --git a/extensions/ltree.tex b/extensions/ltree.tex index 81798a5a..e14acf28 100644 --- a/extensions/ltree.tex +++ b/extensions/ltree.tex @@ -5,7 +5,7 @@ \section{Ltree} \subsection{Почему Ltree?} \begin{itemize} - \item Реализация алгоритма Materialized Path (достаточно быстрый как на запись, так и на чтение); + \item Реализация алгоритма Materialized Path (довольно быстра, как на запись, так и на чтение); \item Как правило данное решение будет быстрее, чем использование CTE (Common Table Expressions) или рекурсивной функции (постоянно будут пересчитываться ветвления); \item Встроены механизмы поиска по дереву; \item Индексы; diff --git a/extensions/multicorn.tex b/extensions/multicorn.tex index 1f26c58f..2e8805b5 100644 --- a/extensions/multicorn.tex +++ b/extensions/multicorn.tex @@ -1,6 +1,6 @@ \section{Multicorn} -\href{http://multicorn.org/}{Multicorn}~--- расширение для PostgreSQL версии 9.1 или выше, которое позволяет создавать собственные FDW (Foreign Data Wrapper), используя язык программирования \href{https://www.python.org/}{Python}. Foreign Data Wrapper позволяют подключиться к другим источникам данных (другая база, файловая система, REST API, прочее) в PostgreSQL и были представленны с версии 9.1. +\href{http://multicorn.org/}{Multicorn}~--- расширение для PostgreSQL версии 9.1 или выше, которое позволяет создавать собственные FDW (Foreign Data Wrapper), используя язык программирования \href{https://www.python.org/}{Python}. Foreign Data Wrapper позволяют подключиться к другим источникам данных (другая база, файловая система, REST API, прочее) в PostgreSQL и были представлены с версии 9.1. \subsection{Пример} @@ -275,7 +275,7 @@ \subsubsection{Собственный FDW} \subsection{PostgreSQL 9.3+} -В PostgreSQL 9.1 и 9.2 была представлена реализация FDW только на чтение. Начиная с версии 9.3, FDW может писать в внешние источники данных. Сейчас Multicorn поддерживает запись данных в другие источники, начиная с версии 1.0.0. +В PostgreSQL 9.1 и 9.2 была представлена реализация FDW только на чтение. Начиная с версии 9.3, FDW может писать во внешние источники данных. Сейчас Multicorn поддерживает запись данных в другие источники, начиная с версии 1.0.0. \subsection{Заключение} diff --git a/extensions/pg_cron.tex b/extensions/pg_cron.tex index 75f234b4..35cd6177 100644 --- a/extensions/pg_cron.tex +++ b/extensions/pg_cron.tex @@ -48,7 +48,7 @@ \subsection{Установка и использование} В целях безопасности cron задачи выполняются в базе данных, в которой \lstinline!cron.schedule! функция была вызвана с правами доступа текущего пользователя. -Поскольку \lstinline!pg_cron! использует libpq библиотеку, это позволят запускать cron задачи на других базах данных (даже на других серверах). С помощью суперпользователя возможно модифицировать \lstinline!cron.job! таблицу и добавить в нее параметры подключения к другой базе через \lstinline!nodename! и \lstinline!nodeport! поля: +Поскольку \lstinline!pg_cron! использует libpq библиотеку, это позволяет запускать cron задачи на других базах данных (даже на других серверах). С помощью суперпользователя возможно модифицировать \lstinline!cron.job! таблицу и добавить в нее параметры подключения к другой базе через \lstinline!nodename! и \lstinline!nodeport! поля: \begin{lstlisting}[language=SQL,label=lst:pgcron5,caption=Cron.job] INSERT INTO cron.job (schedule, command, nodename, nodeport, database, username) diff --git a/extensions/pg_repack.tex b/extensions/pg_repack.tex index 61c4ac10..4897c1c7 100644 --- a/extensions/pg_repack.tex +++ b/extensions/pg_repack.tex @@ -38,7 +38,7 @@ \subsection{Пример использования} \subsection{Pgcompact} -Существует еще одно решение для борьбы с раздуванием таблиц. При обновлении записи с помощью \lstinline!UPDATE!, если в таблице есть свободное место, то новая версия пойдет именно в свободное место, без выделения новых страниц. Предпочтение отдается свободному месту ближе к началу таблицы. Если обновлять таблицу с помощью <>(\lstinline!some_column = some_column!) с последней страницы, в какой-то момент все записи с последней страницы перейдут в свободное место в предшествующих страницах таблицы. Таким образом, после нескольких таких операций, последние страницы окажутся пустыми и обычный неблокирующий \lstinline!VACUUM! сможет отрезать их от таблицы, тем самым уменьшив размер. В итоге, с помощью такой техники можно максимально сжать таблицу, при этом не вызывая критичных блокировок, а значит без помех для других сессий и нормальной работы базы. Для автоматизации этой процедуры существует утилита \href{https://github.com/grayhemp/pgtoolkit}{pgcompactor}. +Существует еще одно решение для борьбы с раздуванием таблиц. При обновлении записи с помощью \lstinline!UPDATE!, если в таблице есть свободное место, то новая версия пойдет именно в свободное место, без выделения новых страниц. Предпочтение отдается свободному месту ближе к началу таблицы. Если обновлять таблицу с помощью <>(\lstinline!some_column = some_column!) с последней страницы, в какой-то момент все записи с последней страницы перейдут в свободное место в предшествующих страницах таблицы. Таким образом, после нескольких таких операций, последние страницы окажутся пустыми и обычный не блокирующий \lstinline!VACUUM! сможет отрезать их от таблицы, тем самым уменьшив размер. В итоге, с помощью такой техники можно максимально сжать таблицу, при этом не вызывая критичных блокировок, а значит без помех для других сессий и нормальной работы базы. Для автоматизации этой процедуры существует утилита \href{https://github.com/grayhemp/pgtoolkit}{pgcompactor}. Основные характеристики утилиты: @@ -50,7 +50,7 @@ \subsection{Pgcompact} \item анализ эффекта раздувания и обработка только тех таблиц, у которых он присутствует, для более точных расчетов рекомендуется установить расширение \href{https://www.postgresql.org/docs/current/static/pgstattuple.html}{pgstattuple}; \item анализ и перестроение индексов с эффектом раздувания; \item анализ и перестроение уникальных ограничений (unique constraints) и первичных ключей (primary keys) с эффектом раздувания; - \item инкрементальное использование, т.е. можно остановить процесс сжатия без ущерба чему-либо; + \item инкрементальное использование, т.~е. можно остановить процесс сжатия без ущерба чему-либо; \item динамическая подстройка под текущую нагрузку базы данных, чтобы не влиять на производительность пользовательских запросов (с возможностью регулировки при запуске); \item рекомендации администраторам, сопровождаемые готовым DDL, для перестроения объектов базы, которые не могут быть перестроены в автоматическом режиме; \end{itemize} diff --git a/extensions/pgsphere.tex b/extensions/pgsphere.tex index 6ef342d4..0959dc32 100644 --- a/extensions/pgsphere.tex +++ b/extensions/pgsphere.tex @@ -59,4 +59,4 @@ \subsection{Установка и использование} \subsection{Заключение} -Более подробно о использовании расширения можно ознакомиться через \href{http://pgsphere.projects.pgfoundry.org/}{официальную документацию}. +Более подробно об использовании расширения можно ознакомиться через \href{http://pgsphere.projects.pgfoundry.org/}{официальную документацию}. diff --git a/extensions/plv8.tex b/extensions/plv8.tex index b6b129c8..ebc1ad21 100644 --- a/extensions/plv8.tex +++ b/extensions/plv8.tex @@ -10,7 +10,7 @@ \subsection{Установка и использование} # CREATE extension plv8; \end{lstlisting} -\href{http://en.wikipedia.org/wiki/V8\_(JavaScript\_engine)}{V8} компилирует JavaScript код непосредственно в машинный код и с помощью этого достигается высокая скорость работы. Для примера расмотрим расчет числа Фибоначчи. Вот функция написана на plpgsql: +\href{http://en.wikipedia.org/wiki/V8\_(JavaScript\_engine)}{V8} компилирует JavaScript код непосредственно в машинный код и с помощью этого достигается высокая скорость работы. Для примера рассмотрим расчет числа Фибоначчи. Вот функция написана на plpgsql: \begin{lstlisting}[label=lst:plv8js1,caption=Фибоначчи на plpgsql] CREATE OR REPLACE FUNCTION @@ -104,7 +104,7 @@ \subsection{Установка и использование} Time: 1.202 ms \end{lstlisting} -Естественно эти измерения не имеют ничего общего с реальным миром (не нужно каждый день считать числа фибоначи в базе данных), но позволяет понять, как V8 может помочь ускорить функции, которые занимаются вычислением чего-либо в базе. +Естественно эти измерения не имеют ничего общего с реальным миром (не нужно каждый день считать числа Фибоначчи в базе данных), но позволяет понять, как V8 может помочь ускорить функции, которые занимаются вычислением чего-либо в базе. \subsection{NoSQL} @@ -115,7 +115,7 @@ \subsection{NoSQL} \item все данные (ключ и значение по ключу) это строка; \end{itemize} -Для хранения данных многие документоориентированные базы данных используют JSON (MongoDB, CouchDB, Couchbase и т.д.). Для этого, начиная с PostgreSQL 9.2, добавлен тип данных JSON, а с версии 9.4~--- JSONB. JSON тип можно добавить для PostgreSQL 9.1 и ниже используя PLV8 и \lstinline!DOMAIN!: +Для хранения данных многие документоориентированные базы данных используют JSON (MongoDB, CouchDB, Couchbase и~т.~д.). Для этого, начиная с PostgreSQL 9.2, добавлен тип данных JSON, а с версии 9.4~--- JSONB. JSON тип можно добавить для PostgreSQL 9.1 и ниже используя PLV8 и \lstinline!DOMAIN!: \begin{lstlisting}[label=lst:plv8js7,caption=Создание типа JSON] CREATE OR REPLACE FUNCTION @@ -250,4 +250,4 @@ \subsection{NoSQL} \subsection{Заключение} -PLV8 расширение предоставляет PostgreSQL процедурный язык с движком V8 JavaScript, с помощью которого можно работать с JavaScript билиотеками, индексировать JSON данные и использовать его как более быстрый язык для вычислений внутри базы. +PLV8 расширение предоставляет PostgreSQL процедурный язык с движком V8 JavaScript, с помощью которого можно работать с JavaScript библиотеками, индексировать JSON данные и использовать его как более быстрый язык для вычислений внутри базы. diff --git a/extensions/postgis.tex b/extensions/postgis.tex index 46f74fcb..4d19defb 100644 --- a/extensions/postgis.tex +++ b/extensions/postgis.tex @@ -18,7 +18,7 @@ \subsection{Установка и использование} # CREATE TABLE cities ( id int4 primary key, name varchar(50), the_geom geometry(POINT,4326) ); \end{lstlisting} -\lstinline!the_geom! поле указывает PostGIS, какой тип геометрии имеет каждый из объектов (точки, линии, полигоны и т.п.), какая размерность (т.к. возможны и 3-4 измерения~--- \lstinline!POINTZ!, \lstinline!POINTM!, \lstinline!POINTZM!) и какая система координат. Для данных по городам мы будем использовать систему координат EPSG:4326. Чтобы добавить данные геометрии в соответствующую колонку, используется функция PostGIS \lstinline!ST_GeomFromText!, чтобы сконвертировать координаты и идентификатор референсной системы из текстового формата: +\lstinline!the_geom! поле указывает PostGIS, какой тип геометрии имеет каждый из объектов (точки, линии, полигоны и~т.~п.), какая размерность (т.к. возможны и 3-4 измерения~--- \lstinline!POINTZ!, \lstinline!POINTM!, \lstinline!POINTZM!) и какая система координат. Для данных по городам мы будем использовать систему координат EPSG:4326. Чтобы добавить данные геометрии в соответствующую колонку, используется функция PostGIS \lstinline!ST_GeomFromText!, чтобы сконвертировать координаты и идентификатор референсной системы из текстового формата: \begin{lstlisting}[language=SQL,label=lst:postgisinsertcities,caption=Заполнение таблицы cities] # INSERT INTO cities (id, the_geom, name) VALUES (1,ST_GeomFromText('POINT(-0.1257 51.508)',4326),'London, England'); @@ -80,4 +80,4 @@ \subsection{Установка и использование} \subsection{Заключение} -В данной главе мы рассмотрели как начать работать с PostGIS. Более подробно о использовании расширения можно ознакомиться через \href{http://postgis.net/documentation/}{официальную документацию}. +В данной главе мы рассмотрели как начать работать с PostGIS. Более подробно об использовании расширения можно ознакомиться через \href{http://postgis.net/documentation/}{официальную документацию}. diff --git a/extensions/postpic.tex b/extensions/postpic.tex index 3f11fab3..4ff06f94 100644 --- a/extensions/postpic.tex +++ b/extensions/postpic.tex @@ -1,3 +1,3 @@ \section{PostPic} -\href{http://drotiro.github.io/postpic/}{PostPic} - расширение для PostgreSQL, которое позволяет обрабатывать изображения в базе данных, как PostGIS делает это с пространственными данными. Он добавляет новый типа поля \lstinline!image!, а также несколько функций для обработки изображений (обрезка краев, создание миниатюр, поворот и т.д.) и извлечений его атрибутов (размер, тип, разрешение). Более подробно о возможностях расширения можно ознакомиться на \href{https://github.com/drotiro/postpic/wiki/SQL-Functions-Guide}{официальной странице}. +\href{http://drotiro.github.io/postpic/}{PostPic} - расширение для PostgreSQL, которое позволяет обрабатывать изображения в базе данных, как PostGIS делает это с пространственными данными. Он добавляет новый типа поля \lstinline!image!, а также несколько функций для обработки изображений (обрезка краев, создание миниатюр, поворот и~т.~д.) и извлечений его атрибутов (размер, тип, разрешение). Более подробно о возможностях расширения можно ознакомиться на \href{https://github.com/drotiro/postpic/wiki/SQL-Functions-Guide}{официальной странице}. diff --git a/extensions/prefix.tex b/extensions/prefix.tex index e6e73850..8ca90a02 100644 --- a/extensions/prefix.tex +++ b/extensions/prefix.tex @@ -90,4 +90,4 @@ \subsection{Установка и использование} \subsection{Заключение} -Более подробно о использовании расширения можно ознакомиться через \href{https://github.com/dimitri/prefix/blob/master/README.md}{официальную документацию}. +Более подробно об использовании расширения можно ознакомиться через \href{https://github.com/dimitri/prefix/blob/master/README.md}{официальную документацию}. diff --git a/extensions/smlar.tex b/extensions/smlar.tex index cfdb54a9..252a7e94 100644 --- a/extensions/smlar.tex +++ b/extensions/smlar.tex @@ -1,10 +1,10 @@ \section{Smlar} -Поиск похожести в больших базах данных является важным вопросом в настоящее время для таких систем как блоги (похожие статьи), интернет-магазины (похожие продукты), хостинг изображений (похожие изображения, поиск дубликатов изображений) и т.д. PostgreSQL позволяет сделать такой поиск более легким. Прежде всего необходимо понять, как мы будем вычислять сходство двух объектов. +Поиск похожести в больших базах данных является важным вопросом в настоящее время для таких систем как блоги (похожие статьи), интернет-магазины (похожие продукты), хостинг изображений (похожие изображения, поиск дубликатов изображений) и~т.~д. PostgreSQL позволяет сделать такой поиск более легким. Прежде всего необходимо понять, как мы будем вычислять сходство двух объектов. \subsection{Похожесть} -Любой объект может быть описан как список характеристик. Например, статья в блоге может быть описана тегами, продукт в интернет-магазине может быть описан размером, весом, цветом и т.д. Это означает, что для каждого объекта можно создать цифровую подпись~--- массив чисел, описывающих объект (\href{http://en.wikipedia.org/wiki/Fingerprint}{отпечатки пальцев}, \href{http://en.wikipedia.org/wiki/N-gram}{n-grams}). То есть нужно создать массив из цифр для описания каждого объекта. +Любой объект может быть описан как список характеристик. Например, статья в блоге может быть описана тегами, продукт в интернет-магазине может быть описан размером, весом, цветом и~т.~д. Это означает, что для каждого объекта можно создать цифровую подпись~--- массив чисел, описывающих объект (\href{http://en.wikipedia.org/wiki/Fingerprint}{отпечатки пальцев}, \href{http://en.wikipedia.org/wiki/N-gram}{n-grams}). То есть нужно создать массив из цифр для описания каждого объекта. \subsection{Расчет похожести} @@ -55,7 +55,7 @@ \subsection{Расчет похожести} Но у обоих этих методов есть общие проблемы: \begin{itemize} - \item Если элементов мало, то разброс похожести не велик; + \item Если элементов мало, то разброс похожести невелик; \item Глобальная статистика: частые элементы ведут к тому, что вес ниже; \item Спамеры и недобросовестные пользователи могут разрушить работу алгоритма и он перестанет работать на Вас; \end{itemize} @@ -159,7 +159,7 @@ \subsection{Smlar} \subsection{Пример: поиск дубликатов картинок} -Рассмотрим простой пример поиска дубликатов картинок. Алгоритм помогает найти похожие изображения, которые, например, незначительно отличаются (изображение обесцветили, добавили водяные знаки, пропустили через фильтры). Но, поскольку точность мала, то у алгоритма есть и позитивная сторона~--- скорость работы. Как можно определить, что картинки похожи? Самый простой метод~--- сравнивать попиксельно два изображения. Но скорость такой работы будет не велика на больших разрешениях. Тем более, такой метод не учитывает, что могли изменять уровень света, насыщенность и прочие характеристики изображения. Нам нужно создать сигнатуру для картинок в виде массива цифр: +Рассмотрим простой пример поиска дубликатов картинок. Алгоритм помогает найти похожие изображения, которые, например, незначительно отличаются (изображение обесцветили, добавили водяные знаки, пропустили через фильтры). Но, поскольку точность мала, то у алгоритма есть и позитивная сторона~--- скорость работы. Как можно определить, что картинки похожи? Самый простой метод~--- сравнивать попиксельно два изображения. Но скорость такой работы будет невелика на больших разрешениях. Тем более, такой метод не учитывает, что могли изменять уровень света, насыщенность и прочие характеристики изображения. Нам нужно создать сигнатуру для картинок в виде массива цифр: \begin{figure}[ht!] \center{\includegraphics[width=1\textwidth]{smlar1.pdf}} @@ -168,7 +168,7 @@ \subsection{Пример: поиск дубликатов картинок} \end{figure} \begin{itemize} - \item Создаем пиксельную матрицу к изображению (изменения размера изображения к требуемоему размеру пиксельной матрице), например 15X15 пикселей(Рис.~\ref{fig:smlar1}); + \item Создаем пиксельную матрицу к изображению (изменения размера изображения к требуемому размеру пиксельной матрице), например 15X15 пикселей(Рис.~\ref{fig:smlar1}); \item Рассчитаем интенсивность каждого пикселя (интенсивность вычисляется по формуле $0.299 * \textup{красный} + 0.587 * \textup{зеленый} + 0.114 * \textup{синий}$). Интенсивность поможет нам находить похожие изображения, не обращая внимание на используемые цвета в них; \item Узнаем отношение интенсивности каждого пикселя к среднему значению интенсивности по всей матрице(Рис.~\ref{fig:smlar2}); \item Генерируем уникальное число для каждой ячейки (отношение интенсивности + координаты ячейки); diff --git a/partitioning/introduction.tex b/partitioning/introduction.tex index 23914004..a85aec2a 100644 --- a/partitioning/introduction.tex +++ b/partitioning/introduction.tex @@ -62,7 +62,7 @@ \subsection{Настройка} ) INHERITS (my_logs); \end{lstlisting} -Данными командами мы создаем таблицы \lstinline!my_logs2010m10!, \lstinline!my_logs2010m11! и т.д., которые копируют структуру с <<мастер>> таблицы (кроме индексов). Также с помощью <> мы задаем диапазон значений, который будет попадать в эту партицию (хочу опять напомнить, что диапазоны значений партиций не должны пересекаться!). Поскольку партиционирование будет работать по полю \lstinline!logdate!, мы создадим индекс на это поле на всех партициях: +Данными командами мы создаем таблицы \lstinline!my_logs2010m10!, \lstinline!my_logs2010m11! и~т.~д., которые копируют структуру с <<мастер>> таблицы (кроме индексов). Также с помощью <> мы задаем диапазон значений, который будет попадать в эту партицию (хочу опять напомнить, что диапазоны значений партиций не должны пересекаться!). Поскольку партиционирование будет работать по полю \lstinline!logdate!, мы создадим индекс на это поле на всех партициях: \begin{lstlisting}[language=SQL,label=lst:partitioning4,caption=Создание индексов] CREATE INDEX my_logs2010m10_logdate ON my_logs2010m10 (logdate); diff --git a/postgresql_clustering.tex b/postgresql_clustering.tex index deeba065..d800c10c 100644 --- a/postgresql_clustering.tex +++ b/postgresql_clustering.tex @@ -8,9 +8,9 @@ \section{Введение} Шардинг~--- разделение данных на уровне ресурсов. Концепция шардинга заключается в логическом разделении данных по различным ресурсам, исходя из требований к нагрузке. -Рассмотрим пример. Пусть у нас есть приложение с регистрацией пользователей, которое позволяет писать друг другу личные сообщения. Допустим оно очень популярно, и много людей им пользуются ежедневно. Естественно, что таблица с личными сообщениями будет намного больше всех остальных таблиц в базе (скажем, будет занимать 90\% всех ресурсов). Зная это, мы можем подготовить для этой (только одной!) таблицы выделенный сервер помощнее, а остальные оставить на другом (послабее). Теперь мы можем идеально подстроить сервер для работы с одной специфической таблицей, постараться уместить ее в память, возможно, дополнительно партиционировать ее и т.д. Такое распределение называется вертикальным шардингом. +Рассмотрим пример. Пусть у нас есть приложение с регистрацией пользователей, которое позволяет писать друг другу личные сообщения. Допустим оно очень популярно, и много людей им пользуются ежедневно. Естественно, что таблица с личными сообщениями будет намного больше всех остальных таблиц в базе (скажем, будет занимать 90\% всех ресурсов). Зная это, мы можем подготовить для этой (только одной!) таблицы выделенный сервер помощнее, а остальные оставить на другом (послабее). Теперь мы можем идеально подстроить сервер для работы с одной специфической таблицей, постараться уместить ее в память, возможно, дополнительно партиционировать ее и~т.~д. Такое распределение называется вертикальным шардингом. -Что делать, если наша таблица с сообщениями стала настолько большой, что даже выделенный сервер под нее одну уже не спасает? Необходимо делать горизонтальный шардинг~--- т.е. разделение одной таблицы по разным ресурсам. Как это выглядит на практике? На разных серверах у нас будет таблица с одинаковой структурой, но разными данными. Для нашего случая с сообщениями, мы можем хранить первые 10 миллионов сообщений на одном сервере, вторые 10 - на втором и т.д. Т.е. необходимо иметь критерий шардинга~--- какой-то параметр, который позволит определить, на каком именно сервере лежат те или иные данные. +Что делать, если наша таблица с сообщениями стала настолько большой, что даже выделенный сервер под нее одну уже не спасает? Необходимо делать горизонтальный шардинг~--- т.~е. разделение одной таблицы по разным ресурсам. Как это выглядит на практике? На разных серверах у нас будет таблица с одинаковой структурой, но разными данными. Для нашего случая с сообщениями, мы можем хранить первые 10 миллионов сообщений на одном сервере, вторые 10 - на втором и~т.~д. Т.~е. необходимо иметь критерий шардинга~--- какой-то параметр, который позволит определить, на каком именно сервере лежат те или иные данные. Обычно, в качестве параметра шардинга выбирают ID пользователя (\lstinline!user_id!)~--- это позволяет делить данные по серверам равномерно и просто. Т.о. при получении личных сообщений пользователей алгоритм работы будет такой: diff --git a/postgresql_indexes.tex b/postgresql_indexes.tex index 45d9d3be..e30feea2 100644 --- a/postgresql_indexes.tex +++ b/postgresql_indexes.tex @@ -6,7 +6,7 @@ \chapter{Индексы} Что такое таблица в реляционной СУБД? Это такой список из кортежей (tuple). Каждый кортеж состоит из ячеек (row). Количество ячеек в кортеже и их тип совпадают со схемой колонки, нескольких колонок. Этот список имеет сквозную нумерацию RowId~--- порядковый номер. Таким образом, таблицы можно осознавать как список пар (RowId, Кортеж). -Индексы~--- это обратные отношения (Кортеж, RowId). Кортеж обязан содержать хотя бы одну ячейку (т.е. быть построенным минимум по одной колонке). Для индексов, которые индексируют более одной колонки~--- они ещё называются составными, и участвуют в отношениях вида <<многие-ко-многим>>~--- всё написанное верно в равной степени. Очевидно, если кортеж~--- не уникален (в колонке существует два одинаковых кортежа), то эти отношения выглядят как (Кортеж, Список RowId)~--- т.е. кортежу сопоставляется список RowId. +Индексы~--- это обратные отношения (Кортеж, RowId). Кортеж обязан содержать хотя бы одну ячейку (т.~е. быть построенным минимум по одной колонке). Для индексов, которые индексируют более одной колонки~--- они ещё называются составными, и участвуют в отношениях вида <<многие-ко-многим>>~--- всё написанное верно в равной степени. Очевидно, если кортеж~--- не уникален (в колонке существует два одинаковых кортежа), то эти отношения выглядят как (Кортеж, Список RowId)~--- т.~е. кортежу сопоставляется список RowId. Индексы могут использоваться для таких операций в базе данных: @@ -91,7 +91,7 @@ \subsection{R-Tree} \subsection{Hash индекс} -Hash индекс по сути является ассоциативным хеш-контейнером. Хеш-контейнер~--- это массив из разряженных значений. Адресуются отдельные элементы этого массива некоторой хеш-функцией которая отображает каждое значение в некоторое целое число. Т.е. результат хеш-функции является порядковым номером элемента в массиве. Элементы массива в хеш-конейтнере называются букетами (bucket). Обычно один букет~--- одна странца. Хеш-функция отображает более мощное множество в менее мощное, возникают так называемые коллизии~--- ситуация, когда одному значению хеш-функции соответствует несколько разных значений. В букете хранятся значения, образующие коллизию. Разрешение коллизий происходит посредством поиска среди значений, сохранённых в букете. +Hash индекс по сути является ассоциативным хеш-контейнером. Хеш-контейнер~--- это массив из разряженных значений. Адресуются отдельные элементы этого массива некоторой хеш-функцией которая отображает каждое значение в некоторое целое число. Т.~е. результат хеш-функции является порядковым номером элемента в массиве. Элементы массива в хеш-конейтнере называются букетами (bucket). Обычно один букет~--- одна странца. Хеш-функция отображает более мощное множество в менее мощное, возникают так называемые коллизии~--- ситуация, когда одному значению хеш-функции соответствует несколько разных значений. В букете хранятся значения, образующие коллизию. Разрешение коллизий происходит посредством поиска среди значений, сохранённых в букете. \begin{figure}[ht!] \center{\includegraphics[width=1\textwidth]{hash_index.pdf}} @@ -241,4 +241,4 @@ \subsection{Уникальный индекс (unique index)} \subsection{Индекс нескольких столбцов (multi-column index)} -В PostgreSQL возможно создавать индексы на несколько столбцов, но нам главное нужно понять когда имеет смысл создавать такой индекс, поскольку планировщик запросов PostgreSQL может комбинировать и использовать несколько индексов в запросе путем создания битового индекса (<<\ref{sec:indexes-bitmap-index}~\nameref{sec:indexes-bitmap-index}>>). Можно, конечно, создать индексы, которые охватят все возможные запросы, но за это придется платить производительностью (индексы нужно перестраивать при запросах на модификацию данных). Нужно также помнить, что индексы на несколько столбцов могут использоваться только запросами, которые ссылаются на эти столбцы в индексе в том же порядке. Индекс по столбцам \lstinline!(a, b)! может быть использован в запросах, которые содержат \lstinline!a = x and b = y! или \lstinline!a = x!, но не будет использоваться в запросе вида \lstinline!b = y!. Если это подходит под запросы вашего приложения, то данный индекс может быть полезен. В таком случае создание индекса на поле \lstinline!a! было бы излишним. Индекс нескольких столбцов с указанием уникальности (\lstinline!unique!) может быть также полезен для сохранения целосности данных (т.е. когда набор данных в этих стобцах должен быть уникальным). +В PostgreSQL возможно создавать индексы на несколько столбцов, но нам главное нужно понять когда имеет смысл создавать такой индекс, поскольку планировщик запросов PostgreSQL может комбинировать и использовать несколько индексов в запросе путем создания битового индекса (<<\ref{sec:indexes-bitmap-index}~\nameref{sec:indexes-bitmap-index}>>). Можно, конечно, создать индексы, которые охватят все возможные запросы, но за это придется платить производительностью (индексы нужно перестраивать при запросах на модификацию данных). Нужно также помнить, что индексы на несколько столбцов могут использоваться только запросами, которые ссылаются на эти столбцы в индексе в том же порядке. Индекс по столбцам \lstinline!(a, b)! может быть использован в запросах, которые содержат \lstinline!a = x and b = y! или \lstinline!a = x!, но не будет использоваться в запросе вида \lstinline!b = y!. Если это подходит под запросы вашего приложения, то данный индекс может быть полезен. В таком случае создание индекса на поле \lstinline!a! было бы излишним. Индекс нескольких столбцов с указанием уникальности (\lstinline!unique!) может быть также полезен для сохранения целосности данных (т.~е. когда набор данных в этих стобцах должен быть уникальным). diff --git a/postgresql_partitioning.tex b/postgresql_partitioning.tex index 4ba6da00..30addf5a 100644 --- a/postgresql_partitioning.tex +++ b/postgresql_partitioning.tex @@ -10,7 +10,7 @@ \section{Введение} Партиционирование (partitioning, секционирование)~--- это разбиение больших структур баз данных (таблицы, индексы) на меньшие кусочки. Звучит сложно, но на практике все просто. -Скорее всего у Вас есть несколько огромных таблиц (обычно всю нагрузку обеспечивают всего несколько таблиц СУБД из всех имеющихся). Причем чтение в большинстве случаев приходится только на самую последнюю их часть (т.е. активно читаются те данные, которые недавно появились). Примером тому может служить блог~--- на первую страницу (это последние 5\dots10 постов) приходится 40\dots50\% всей нагрузки, или новостной портал (суть одна и та же), или системы личных сообщений, впрочем понятно. Партиционирование таблицы позволяет базе данных делать интеллектуальную выборку~--- сначала СУБД уточнит, какой партиции соответствует Ваш запрос (если это реально) и только потом сделает этот запрос, применительно к нужной партиции (или нескольким партициям). Таким образом, в рассмотренном случае, Вы распределите нагрузку на таблицу по ее партициям. Следовательно выборка типа \lstinline!SELECT * FROM articles ORDER BY id DESC LIMIT 10! будет выполняться только над последней партицией, которая значительно меньше всей таблицы. +Скорее всего у Вас есть несколько огромных таблиц (обычно всю нагрузку обеспечивают всего несколько таблиц СУБД из всех имеющихся). Причем чтение в большинстве случаев приходится только на самую последнюю их часть (т.~е. активно читаются те данные, которые недавно появились). Примером тому может служить блог~--- на первую страницу (это последние 5\dots10 постов) приходится 40\dots50\% всей нагрузки, или новостной портал (суть одна и та же), или системы личных сообщений, впрочем понятно. Партиционирование таблицы позволяет базе данных делать интеллектуальную выборку~--- сначала СУБД уточнит, какой партиции соответствует Ваш запрос (если это реально) и только потом сделает этот запрос, применительно к нужной партиции (или нескольким партициям). Таким образом, в рассмотренном случае, Вы распределите нагрузку на таблицу по ее партициям. Следовательно выборка типа \lstinline!SELECT * FROM articles ORDER BY id DESC LIMIT 10! будет выполняться только над последней партицией, которая значительно меньше всей таблицы. Итак, партиционирование дает ряд преимуществ: diff --git a/postgresql_pgpool.tex b/postgresql_pgpool.tex index b97f61c0..4d96ecd0 100644 --- a/postgresql_pgpool.tex +++ b/postgresql_pgpool.tex @@ -12,7 +12,7 @@ \section{Введение} \item \textbf{Объединение соединений} -Pgpool-II сохраняет соединения с серверами PostgreSQL и использует их повторно в случае если новое соединение устанавливается с теми же параметрами (т.е. имя пользователя, база данных, версия протокола). Это уменьшает накладные расходы на соединения и увеличивает производительность системы в целом; +Pgpool-II сохраняет соединения с серверами PostgreSQL и использует их повторно в случае если новое соединение устанавливается с теми же параметрами (т.~е. имя пользователя, база данных, версия протокола). Это уменьшает накладные расходы на соединения и увеличивает производительность системы в целом; \item \textbf{Репликация} @@ -290,7 +290,7 @@ \subsubsection{Создание таблицы replicate\_def} \subsection{Установка правил распределения данных} -В данном примере будут определены правила распределения данных, созданных программой pgbench, на три узла базы данных. Тестовые данные будут созданы командой \lstinline!pgbench -i -s 3! (т.е. масштабный коэффициент равен 3). Для этого раздела мы создадим новую базу данных с именем \lstinline!bench_parallel!. В каталоге sample исходного кода pgpool-II вы можете найти файл \lstinline!dist_def_pgbench.sql!. Будем использоваться этот файл с примером для создания правил распределения для pgbench. Выполним следующую команду в каталоге с распакованным исходным кодом pgpool-II: +В данном примере будут определены правила распределения данных, созданных программой pgbench, на три узла базы данных. Тестовые данные будут созданы командой \lstinline!pgbench -i -s 3! (т.~е. масштабный коэффициент равен 3). Для этого раздела мы создадим новую базу данных с именем \lstinline!bench_parallel!. В каталоге sample исходного кода pgpool-II вы можете найти файл \lstinline!dist_def_pgbench.sql!. Будем использоваться этот файл с примером для создания правил распределения для pgbench. Выполним следующую команду в каталоге с распакованным исходным кодом pgpool-II: \begin{lstlisting}[language=Bash,label=lst:pgpool32,caption=Установка правил распределения данных] $ psql -f sample/dist_def_pgbench.sql -p 5432 pgpool diff --git a/postgresql_strategy.tex b/postgresql_strategy.tex index 40bd9c9d..8c0054c2 100644 --- a/postgresql_strategy.tex +++ b/postgresql_strategy.tex @@ -8,7 +8,7 @@ \section{Введение} Многие разработчики крупных проектов сталкиваются с проблемой, когда один-единственный сервер базы данных никак не может справиться с нагрузками. Очень часто такие проблемы происходят из-за неверного проектирования приложения (плохая структура БД для приложения, отсутствие кеширования). Но в данном случае пусть у нас есть <<идеальное>> приложение, для которого оптимизированы все SQL запросы, используется кеширование, PostgreSQL настроен, но все равно не справляется с нагрузкой. Такая проблема может возникнуть как на этапе проектирования, так и на этапе роста приложения. И тут возникает вопрос: какую стратегию выбрать при возникновении подобной ситуации? -Если Ваш заказчик готов купить супер сервер за несколько тысяч долларов (а по мере роста~--- десятков тысяч и т.д.), чтобы сэкономить время разработчиков, но сделать все быстро, можете дальше эту главу не читать. Но такой заказчик~--- мифическое существо и, в основном, такая проблема ложится на плечи разработчиков. +Если Ваш заказчик готов купить супер сервер за несколько тысяч долларов (а по мере роста~--- десятков тысяч и~т.~д.), чтобы сэкономить время разработчиков, но сделать все быстро, можете дальше эту главу не читать. Но такой заказчик~--- мифическое существо и, в основном, такая проблема ложится на плечи разработчиков. \subsection{Суть проблемы} diff --git a/postgresql_tips.tex b/postgresql_tips.tex index e0e207be..ca44dabd 100644 --- a/postgresql_tips.tex +++ b/postgresql_tips.tex @@ -137,7 +137,7 @@ \subsection{Выборка и сортировка по данному набо Выбор данных по определенному набору данных можно сделать с помощью обыкновенного \lstinline!IN!. Но как сделать подобную выборку и отсортировать данные в том же порядке, в котором передан набор данных? Например: -Дан набор: (2,6,4,10,25,7,9). Нужно получить найденные данные в таком же порядке т.е. 2 2 2 6 6 4 4 +Дан набор: (2,6,4,10,25,7,9). Нужно получить найденные данные в таком же порядке т.~е. 2 2 2 6 6 4 4 \lstinputlisting[language=SQL,label=lst:snippets12,title=snippets/order\_like\_in.sql]{example_code/snippets/order_like_in.sql} diff --git a/replication/bdr.tex b/replication/bdr.tex index d73fad00..a21bb733 100644 --- a/replication/bdr.tex +++ b/replication/bdr.tex @@ -5,13 +5,13 @@ \section{PostgreSQL Bi-Directional Replication (BDR)} BDR не является инструментом для кластеризации, т.к. здесь нет каких-либо глобальных менеджеров блокировок или координаторов транзакций. Каждый узел не зависит от других, что было бы невозможно в случае использования менеджеров блокировки. Каждый из узлов содержит локальную копию данных идентичную данным на других узлах. Запросы также выполняются только локально. При этом каждый из узлов внутренне консистентен в любое время, целиком же группа серверов является согласованной в конечном счете (eventually consistent). Уникальность BDR заключается в том что она непохожа ни на встроенную потоковую репликацию, ни на существующие trigger-based решения (Londiste, Slony, Bucardo). -Самым заметным отличием от потоковой репликации является то, что BDR (LLSR) оперирует базами (per-database replication), а классическая PLSR реплицирует целиком инстанс (per-cluster replication), т.е. все базы внутри инстанса. Существующие ограничения и особенности: +Самым заметным отличием от потоковой репликации является то, что BDR (LLSR) оперирует базами (per-database replication), а классическая PLSR реплицирует целиком инстанс (per-cluster replication), т.~е. все базы внутри инстанса. Существующие ограничения и особенности: \begin{itemize} \item Все изменения данных вызываемые \lstinline!INSERT/DELETE/UPDATE! реплицируются (\lstinline!TRUNCATE! на момент написания статьи пока не реализован); \item Большинство операции изменения схемы (DDL) реплицируются успешно. Неподдерживаемые DDL фиксируются модулем репликации и отклоняются с выдачей ошибкой (на момент написания не работал \lstinline!CREATE TABLE ... AS!); - \item Определения таблиц, типов, расширений и т.п. должны быть идентичными между upstream и downstream мастерами; - \item Действия которые отражаются в WAL, но непредставляются в виде логических изменений не реплицируются на другой узел (запись полных страниц, вакуумация таблиц и т.п.). Таким образом логическая потоковая репликация (LLSR) избавлена от некоторой части накладных расходов которые присутствуют в физической потоковой репликации PLSR (тем не менее это не означает что LLSR требуется меньшая пропускная способность сети чем для PLSR); + \item Определения таблиц, типов, расширений и~т.~п. должны быть идентичными между upstream и downstream мастерами; + \item Действия которые отражаются в WAL, но непредставляются в виде логических изменений не реплицируются на другой узел (запись полных страниц, вакуумация таблиц и~т.~п.). Таким образом логическая потоковая репликация (LLSR) избавлена от некоторой части накладных расходов которые присутствуют в физической потоковой репликации PLSR (тем не менее это не означает что LLSR требуется меньшая пропускная способность сети чем для PLSR); \end{itemize} Небольшое примечание: временная остановка репликации осуществляется выключением downstream мастера. Однако стоит отметить что остановленная реплика приводит к тому что upstream мастер продолжит накапливать WAL журналы что в свою очередь может привести к неконтролируемому расходу пространства на диске. Поэтому крайне не рекомендуется надолго выключать реплику. Удаление реплики навсегда осуществляется через удаление конфигурации BDR на downstream сервере с последующим перезапуском downstream мастера. Затем нужно удалить соответствующий слот репликации на upstream мастере с помощью функции \lstinline!pg_drop_replication_slot('slotname')!. Доступные слоты можно просмотреть с помощью функции \lstinline!pg_get_replication_slots!. diff --git a/replication/londiste.tex b/replication/londiste.tex index 454c1219..c471fa57 100644 --- a/replication/londiste.tex +++ b/replication/londiste.tex @@ -295,7 +295,7 @@ \subsubsection{Создаём конфигурацию для PgQ ticker} \begin{itemize} \item x - количество таблиц в состоянии <> (replicated). На master базе указывает, что она в норме, а на slave базах - таблица синхронизирована с master базой; \item y - количество таблиц в состоянии half (initial copy, not finnished), у master должно быть 0, а у slave базах это указывает количество таблиц в процессе копирования; - \item z - количество таблиц в состоянии ignored (table not replicated locally), у master должно быть 0, а у slave базах это количество таблиц, которые не добавлены для репликации с мастера (т.е. master отдает на репликацию эту таблицу, но slave их просто не забирает). + \item z - количество таблиц в состоянии ignored (table not replicated locally), у master должно быть 0, а у slave базах это количество таблиц, которые не добавлены для репликации с мастера (т.~е. master отдает на репликацию эту таблицу, но slave их просто не забирает). \end{itemize} Через небольшой интервал времени все таблицы должны синхронизироватся: diff --git a/strategy/read.tex b/strategy/read.tex index 7db81d33..b88321bc 100644 --- a/strategy/read.tex +++ b/strategy/read.tex @@ -1,6 +1,6 @@ \section{Проблема чтения данных} -Проблема с чтением данных обычно начинается, когда СУБД не в состоянии обеспечить то количество выборок, которое требуется. В основном такое происходит в блогах, новостных лентах и т.д. Хочу сразу отметить, что подобную проблему лучше решать внедрением кеширования, а потом уже думать как масштабировать СУБД. +Проблема с чтением данных обычно начинается, когда СУБД не в состоянии обеспечить то количество выборок, которое требуется. В основном такое происходит в блогах, новостных лентах и~т.~д. Хочу сразу отметить, что подобную проблему лучше решать внедрением кеширования, а потом уже думать как масштабировать СУБД. \subsection{Методы решения}