# Главная
# О библиотеке

# Выбор дистрибутива
преимущества Linux/UNIX | основные дистрибутивы | серверный Linux | BSD | LiveCDs | прочее

# Установка и удаление программ
общие вопросы | каталоги софта | специальные случаи

# Настройка и работа
установка, загрузчики | настройка Linux | консоль | файловые системы | процессы | шеллы, русификация, коммандеры | виртуальные машины, эмуляторы

# X Window и оконные менеджеры
настройка X Window | GNOME | KDE | IceWM и др.

# Работа с текстами
редакторы | офис | шрифты, кодировки и русификация | преобразования текстовых файлов | LaTeX, SGML и др. | словари

# Графика
GIMP | фото | обработка изображений | форматы графических файлов

# Сети, администрирование
общие вопросы | Dialup & PPP | брандмауэры | маршрутизация | работа в Windows-сетях | веб-серверы | Apache | прокси-серверы | сетевая печать | прочее

# Программирование
GCC & GNU make | программирование в UNIX | графические библиотеки | Tcl | Perl | PHP | Java & C# | СУБД | CVS | прочее

# Ядро
# Мультимедиа
# Интернет
# Почта
# Безопасность
# Железо
# Разное

# Linux HowTo (как сделать)
# Книги и руководства
# Материалы на английском языке


MySQL The World's Most Popular Open Source Database # Online shop | Site map |  
CompanyProductsSupport & ConsultingTraining & CertificationDownloadsDocumentation
  BooksArticlesMailing ListsPresentationsOther Sites  
Search the MySQL manual:
MySQL Manual
  • 4 Администрирование баз данных
    • 4.10 Репликация в MySQL
      • 4.10.1 Введение
      • 4.10.2 Как реализована репликация: обзор
      • 4.10.3 Как настроить репликацию
      • 4.10.4 Возможности репликации и известные проблемы
      • 4.10.5 Опции репликации в файле `my.cnf'
      • 4.10.6 SQL-команды, относящиеся к репликации
      • 4.10.7 Часто задаваемые вопросы по репликации
      • 4.10.8 Поиск неисправностей репликации

Buy this Reference Manual in softcover from Barnes & Noble!

MySQL Reference Manual
Previous / Next / Up / Table of Contents

4.10.4 Возможности репликации и известные проблемы

Ниже приводится список поддерживаемых и не поддерживаемых при репликации функций:

  • Реплицирование будет выполнено правильно при использовании значений AUTO_INCREMENT, LAST_INSERT_ID() и TIMESTAMP.
  • Если в обновлениях присутствует функция RAND(), реплицирование будет выполнено некорректно. При реплицировании обновлений с функцией RAND() применяйте RAND(some_non_rand_expr). В качестве аргумента (some_non_rand_expr - некоторое не случайное выражение) для функции RAND() можно, например, использовать функцию UNIX_TIMESTAMP().
  • На головном и подчиненном серверах следует использовать одинаковый набор символов (--default-character-set). В противном случае могут возникать ошибки дублирующихся ключей на подчиненном сервере, поскольку ключ, который считается уникальным на головном сервере, может не быть таковым при использовании другого набора символов.
  • В MySQL 3.23 команда LOAD DATA INFILE будет выполнена корректно, если файл во время выполнения обновления будет находиться на головном сервере. Команда LOAD LOCAL DATA INFILE будет проигнорирована. В MySQL 4.0 это ограничение не присутствует - все разновидности команды LOAD DATA INFILE реплицируются правильно.
  • Запросы на обновление, в которых используются пользовательские переменные, являются не безопасными для репликации (пока).
  • Команды FLUSH не записываются в двоичный журнал и поэтому не копируются на подчиненный сервер. Проблем при этом не возникает, поскольку команды FLUSH ничего не изменяют. Однако это означает, что при непосредственном, без использования оператора GRANT, обновлении таблиц привилегий MySQL и при последующем реплицировании базы данных привилегий mysql нужно выполнить команду FLUSH PRIVILEGES на подчиненных серверах, чтобы новые привилегии вступили в силу.
  • Временные таблицы, начиная с версии 3.23.29, реплицируются корректно, за исключением случая, когда при прекращении работы подчиненного сервера (не только потока подчиненного сервера) некоторые временные таблицы остаются открытыми и используются в последующих обновлениях. Для решения этой проблемы перед прекращением работы подчиненного сервера выполните команду SLAVE STOP, проверьте, чтобы переменная Slave_open_temp_tables содержала значение 0, затем выполните mysqladmin shutdown. Если значение переменной Slave_open_temp_tables не 0, перезапустите поток подчиненного сервера при помощи команды SLAVE START и проверьте, не улучшилась ли ситуация теперь. Эта проблема будет решаться более изящно, но придется подождать MySQL 4.0. В более ранних версиях при использовании временных таблиц репликации не выполняются должным образом - в таких случаях мы рекомендуем либо обновить версию MySQL, либо перед выполнением запросов, использующих временные таблицы, выполнить команду SET SQL_LOG_BIN=0 на своих клиентах.
  • MySQL поддерживает лишь один головной и много подчиненных серверов. В 4.x будет добавлен алгоритм голосования, обеспечивающий автоматическое изменение головного сервера, если что-либо будет выполняться неправильно при текущем головном сервере. Будут также введены процессы 'агента', которые помогут выполнять распределение нагрузки путем посылки запросов на выборки различным подчиненным серверам.
  • Начиная с версии 3.23.26 стало безопасно соединять серверы циклическими соединениями головной-подчиненный с включенной опцией log-slave-updates. Однако обратите внимание: при таком способе установки многие запросы не будут выполняться корректно, если только в коде вашего клиента не предусмотрена обработка потенциальных проблем, которые могут случаться при обновлениях, происходящих в различной последовательности на различных серверах. Это означает, что если вы сделаете установку следующим образом:
    A - > B > - C - > A
    
    то такая установка будет работать только в том случае, если выполняются непротиворечивые обновления между таблицами. Другими словами, при вставке данных на серверах A и C нельзя вставлять на сервере A строку, которая может иметь ключ, противоречащий строке, вставляемой на сервере C. Также нельзя обновлять одинаковые строки на двух серверах, если имеет значение порядок обновлений. Обратите внимание: в версии 3.23.26 изменился формат журнала. Таким образом, если версия подчиненного сервера меньше 3.23.26, сервер не сможет считывать записи из журнала.
  • Если запрос на подчиненном сервере вызывает ошибку, поток подчиненного сервера завершится, и в файле `.err' появится соответствующее сообщение. После этого нужно будет вручную установить соединение с подчиненным сервером, исправить причину ошибки (например обращение к несуществующей таблице) и затем выполнять SQL-команду SLAVE START (доступна в версии 3.23.16). При использовании версии 3.23.15 потребуется перезапустить сервер.
  • Если соединение с головным сервером прервется, подчиненный сервер попытается сразу же восстановить его, и затем в случае неудачи будет повторять попытки через установленное в опции master-connect-retry количество секунд (по умолчанию 60). По этой причине безопасно выключить головной сервер и после этого перезапустить его через некоторое время. Подчиненный сервер будет также разрешать проблемы, возникающие при аварийных отключениях электричества в узлах сети.
  • Завершение работы подчиненного сервера (корректное) также является безопасным, поскольку при этом отслеживаются события начиная от момента остановки сервера. Но в случае некорректного отключения сервера могут возникать проблемы, особенно, если дисковый кэш не был синхронизирован перед ``смертью'' системы. Для того чтобы значительно повысить эффективность своей системы обеспечения отказоустойчивости, целесообразно приобрести хороший UPS (источник бесперебойного питания).
  • Если головной сервер слушает нестандартный порт, это нужно будет указать также в параметре master-port в файле `my.cnf'.
  • В версии 3.23.15 все таблицы и базы данных могут быть реплицированы. Начиная с версии 3.23.16 появилась возможность ограничить репликацию набором баз данных при помощи директив replicate-do-db в файле `my.cnf'; можно также исключить набор баз данных из репликации при помощи директив replicate-ignore-db. Обратите внимание,: в версиях MySQL до 3.23.23, имелась ошибка, из-за которой команда LOAD DATA INFILE выполнялась некорректно, если она применялась к базе данных, исключенной из репликации.
  • Начиная с версии 3.23.16 команда SET SQL_LOG_BIN = 0 будет выключать ведение записей о репликации в журналах (двоичных) на головном сервере, а команда SET SQL_LOG_BIN = 1 - включать такое ведение записей. Для выполнения этих команд нужно иметь привилегию SUPER (в MySQL 4.0.2 и выше) или PROCESS (в более ранних версиях MySQL).
  • Начиная с версии 3.23.19 можно убрать мусор, оставшийся после неоконченной репликации (если ее выполнение пошло не должным образом), и начать все сначала, используя команды FLUSH MASTER и FLUSH SLAVE. В версии 3.23.26 эти команды переименованы в RESET MASTER и RESET SLAVE соответственно - чтобы сделать понятным их назначение. Тем не менее, старые варианты FLUSH все еще работают - для обеспечения совместимости.
  • Начиная с версии 3.23.23 можно заменять головные серверы и корректировать точку положения в журнале репликации при помощи команды CHANGE MASTER TO.
  • Начиная с версии 3.23.23 можно при помощи опции binlog-ignore-db уведомлять головной сервер о том, что обновления в некоторых базах данных не должны отражаться в двоичном журнале.
  • Начиная с версии 3.23.26, можно использовать опцию replicate-rewrite-db для уведомления подчиненного сервера о том, что он должен применить обновления базы данных на головном сервере к базе данных с другим именем на подчиненном сервере.
  • Начиная с версии 3.23.28 можно использовать команду PURGE MASTER LOGS TO 'имя-журнала', чтобы избавиться от старых журналов без завершения работы подчиненного сервера.
  • Из-за того, что по своей природе таблицы MyISAM являются нетранзакционными, может случиться так, что запрос обновит таблицу только частично и возвратит код ошибки. Это может произойти, например, при вставке нескольких строк, одна из которых нарушает ограничение ключа, или в случае, когда длинный запрос обновления ``убивается'' после обновления некоторых строк. Если такое случится на головном сервере, поток подчиненного сервера завершит работу и будет ждать, пока администратор базы данных не примет решение о том, что делать в этом случае (если только код ошибки не является легитимным и в результате выполнения запроса не будет сгенерирована ошибка с тем же кодом). Если такой способ проверки правильности кода ошибки нежелателен, начиная с версии 3.23.47, некоторые (или все) ошибки могут быть замаскированы при помощи опции slave-skip-errors.
  • Отдельные таблицы могут исключаться из репликации при помощи опции replicate-do-table/replicate-ignore-tab или опции replicate-wild-do-table/replicate-wild-ignore-table. Однако в настоящее время наличие определенных конструктивных неточностей в некоторых довольно редких случаях может приводить к неожиданным результатам. Протокол репликации явно не уведомляет подчиненный сервер о том, какие таблицы должны быть изменены запросом, поэтому подчиненному серверу требуется анализировать запрос, чтобы узнать это. Чтобы избежать лишнего синтаксического анализа, для которого требуется прерывать выполнение запросов, исключение таблицы в настоящее время реализуется путем посылки запроса к стандартному анализатору MySQL для упрощенного синтаксического анализа. Если анализатор обнаружит, что таблица должна игнорироваться, выполнение запроса будет остановлено и выдано сообщение об успехе. Этот подход несколько неэффективен, при его применении чаще возникают ошибки и, кроме того, имеются две известные ошибки в версии 3.23.49. Первая может возникнуть из-за того, что поскольку анализатор автоматически открывает таблицу при анализе некоторых запросов, игнорируемая таблица должна существовать на подчиненном сервере. Другая ошибка заключается в том, что при частичном обновлении игнорируемой таблицы поток подчиненного сервера не заметит, что таблица должна игнорироваться, и приостановит процесс репликации. Несмотря на то что вышеупомянутые ошибки концептуально очень просто исправить, для этого придется изменить достаточно много кода, что поставит под угрозу состояние стабильности ветви 3.23. Если описанные случаи непосредственно имеют отношение к вашему приложению (а это довольно редкий случай) - используйте опцию slave-skip-errors, чтобы дать указание серверу продолжать репликации, игнорируя эти ошибки.

User Comments

Posted by [name withheld] on Wednesday December 18 2002, @5:28pm[Delete] [Edit]

FYI

I could not get replication to work between
3.23.53 (master) and 3.23.41 (slave)

The symptons where:
Very very slow replication. Like 30 seconds
before a simple update got replicated.

About every 30 seconds, I got these entries in the
replication slave's log file:
020820 13:46:51 Error reading packet from server:
(server_errno=1159)
020820 13:47:51 Slave: Failed reading log event,
reconnecting to retry, log 'dragon-mount-bin.004'
position 137
020820 13:47:51 Slave: reconnected to master
'[email protected]:3306',replication resumed in
log 'dragon-mount-bin.004' at position 137

By simply upgrading to 3.23.53(latest) for the
slave it worked just fine

Posted by [name withheld] on Tuesday September 10 2002, @2:05pm[Delete] [Edit]

Got exactly the same error as above (error reading
packet every 30 sec), using v3.23.51 for both
master and slave.

Switching to v3.23.52 (latest for Solaris) solved
the problem.

Posted by [name withheld] on Wednesday November 13 2002, @5:43pm[Delete] [Edit]

I created a table, loaded part of it from local
files, and part of it from update statements.
When I looked at what was replicated, of course,
only the lines that were manually inserted
propigated. There were about 130 rows from
load, and 4 from insert. When I read the
limitations, I realized what was going on - I had
used local files and not copied the files into the
mysql directory. So I created a second table
manually, and I populated it with an insert into
xxx (f1, f2) select * from oldtable;

And the same lines were replicated. The 4 rows
that were propagated were the same ones. I
can only assume that the update / select was
propagated as a command and not the data.

I tried altering the data (integer+0, string concat
(field,'')) - again, the propagation was via
command, and not via value, so the same 4 lines
ended up in the target table.

I ended up having to propagate the data via a
file dump from source/ftp(scp)/restore via piping
the dump into mysql.

I did not actually try it, but it is possible that I
could have fixed the issue simply by dumping
and restoring the tables (and recreating the
data) on the source machine. Recreating the
data with update statements should have
worked.

Add your own comment.

Top / Previous / Next / Up / Table of Contents
# MySQL.com home | Site map | Contact us | Press | Jobs | Privacy policy | Trademark info | © 1995-2003 MySQL AB. All rights reserved.