Вообще, проблемы, описанные здесь, следуют из того факта, что двоичная регистрация происходит на уровне инструкции SQL. Будущие версии MySQL, как ожидается, выполнят уровень двоичной регистрации строки, которая определяет изменения для индивидуальных строк в результате выполняющихся инструкций SQL.
Если не отмечено иное, замечания здесь принимают, что Вы допустили двоичную регистрацию, запуская сервер с опцией --log-bin. Если двоичный файл регистрации не допускается, дублирование невозможно, так как отсутствует двоичный файл регистрации для восстановления данных.
Разработка регистрации сохраненной подпрограммы в MySQL 5.0 может быть получена в итоге следующим образом:
До MySQL 5.0.6: в начальной реализации регистрации сохраненной подпрограммы, инструкции, которые создают сохраненные подпрограммы, и инструкции CALL не регистрируются. Эти вычеркивания могут вызывать проблемы для восстановления данных и дублирования.
MySQL 5.0.6: инструкции, которые создают сохраненные подпрограммы, и инструкции CALL регистрируются. Сохраненные функциональные вызовы регистрируются, когда они происходят в инструкциях, которые модифицируют данные (потому что те инструкции регистрируются). Однако, функциональные вызовы не регистрируются, когда они происходят в инструкциях типа SELECT, которые не изменяют данные, даже если изменение данных происходит непосредственно внутри функции, это может вызвать проблемы. При некоторых обстоятельствах, функции и процедуры могут иметь различные эффекты если выполнено в разное время или на различных серверах (главном или подчиненном), и таким образом они могут быть опасны для восстановления данных или дублирования. Чтобы обрабатывать это, приняты меры, чтобы позволить идентификацию безопасных подпрограмм и предотвратить создание опасных подпрограмм (за исключением создаваемых пользователями с достаточными привилегиями).
MySQL 5.0.12: для сохраненных функций, когда функциональный вызов, который изменяет данные, происходит внутри не регистрируемой инструкции типа SELECT, сервер регистрирует инструкцию DO func_name(), которая вызывает функцию так, чтобы функция была выполнена в течение восстановления данных или дублирования на подчиненные серверы. Для сохраненных процедур, сервер не регистрирует инструкции CALL. Вместо этого, он регистрирует индивидуальные инструкции внутри процедуры, которые выполнены в результате CALL. Это устраняет проблемы, которые могут происходить, когда процедура выполнялась бы на подчиненном сервере иным способом, чем на главном.
MySQL 5.0.16: процедура, регистрирующая изменения, сделанные в 5.0.12, позволяет ослабить условия на опасных подпрограммах для сохраненных процедур. Следовательно, интерфейс пользователя для управления этими условиями пересмотрен, чтобы применить только к функциям. Создатели процедуры больше не связаны ими.
MySQL 5.0.17: регистрация сохраненных функций также, как и инструкции DO func_name() (для изменений, сделанных в 5.0.12), регистрируется как инструкции SELECT func_name() для лучшего контроля проверки ошибок.
Как следствие предшествующих изменений, следующие условия в настоящее время обращаются к созданию сохраненных функций, когда двоичная регистрация допускается. Эти условия не относятся к созданию сохраненных процедур.
Чтобы создавать или изменять сохраненную функцию, Вы должны иметь привилегию SUPER, в дополнение к привилегии CREATE ROUTINE или ALTER ROUTINE, которая обычно требуется.
Когда Вы создаете сохраненную функцию, Вы должны объявить, что это детерминировано или не изменяет данные. Иначе, это может быть опасно для восстановления данных или дублирования. Два набора функциональных характеристик применяются здесь:
Характеристики DETERMINISTIC и NOT DETERMINISTIC указывают, производит ли функция всегда тот же самый результат для входных данных. Значение по умолчанию: NOT DETERMINISTIC, если никакая характеристика не дана, так что Вы должны определить DETERMINISTIC явно, чтобы объявить, что функция детерминирована.
Использование функции NOW() (или синонимов) либо RAND() не обязательно делает функцию не детерминированной. Для NOW() двоичный файл регистрации включает timestamp и все копирует правильно. RAND() также копируется правильно, пока это вызывается только один раз внутри функции. Вы можете рассматривать функциональное выполнение timestamp и начальное значение случайного числа как неявные вводы, которые являются идентичными на главном и подчиненном серверах.