| |
Есть два способа добавить новую функцию в MySQL:
CREATE FUNCTION
и DROP FUNCTION
.
Подробности в разделе "3.1.1 Синтаксис
CREATE FUNCTION/DROP FUNCTION
".
mysqld
и становятся
доступными на постоянной основе.Каждый метод имеет свои проблемы:
Независимо от метода, который Вы используете, чтобы добавить новые
функции, они могут использоваться точно так же как местные функции типа
ABS()
или SOUNDEX()
.
CREATE FUNCTION/DROP FUNCTION
CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|REAL|INTEGER} SONAME shared_library_name DROP FUNCTION function_name
Определяемые пользователем функции (user-definable function, UDF)
представляют собой способ расширить MySQL новой функцией, которая работает
подобно местным (встроенным) функциям MySQL типа ABS()
или
CONCAT()
.
AGGREGATE
новая опция для MySQL Version 3.23. Функция с
AGGREGATE
работает точно так же, как и встроенная функция
GROUP
, подобно SUM
или COUNT()
.
CREATE FUNCTION
сохраняет имя функции, тип и общедоступное
библиотечное имя в таблице mysql.func
системы. Вы должны иметь
привилегии insert и delete для базы данных
mysql
, чтобы создавать и удалять функции.
Все активные функции перезагружаются при каждом запуске сервера, если Вы
не запускаете mysqld
с опцией --skip-grant-tables
.
В этом случае инициализация пропущена, и UDF станут недоступны. Активная
функция представляет собой такую функцию, которая была загружена с помощью
CREATE FUNCTION
, но не была удалена через
вызов DROP FUNCTION
.
По поводу правил написания определяемых пользователем функций отсылаю Вас
к разделу "3.1 Добавление новой
функции, определяемой пользователем в MySQL". Для работы механизма UDF
функции должны быть написаны на C или C++, Ваша операционная система должна
поддерживать динамическую загрузку, и mysqld
должен быть
откомпилирован динамически (не статически).
Для работы механизма UDF функции должны быть написаны на C или C++, а Ваша операционная система должна поддерживать динамическую загрузку. Дистрибутив исходников MySQL включает файл sql/udf_example.cc, который определяет 5 новых функций. Консультируйтесь с этим файлом, чтобы видеть, как работают соглашения о вызовах UDF.
Чтобы mysqld
мог использовать UDF, Вы должны конфигурировать
MySQL с опцией --with-mysqld-ldflags=-rdynamic
. Причина этого
в том, что на многих платформах (включая Linux) Вы можете загружать
динамическую библиотеку (вызовом dlopen()
) из статически
скомпонованной программы, которая собрана с опцией
--with-mysqld-ldflags=-all-static
, но если Вы хотите
использовать UDF, который должен обратиться к символам из
mysqld
(подобно примеру methaphone
в
sql/udf_example.cc, который использует
default_charset_info
), Вы должны компоновать программу с
-rdynamic
. Подробности на man dlopen
.
Для каждой функции, которую Вы хотите использовать в инструкциях SQL, Вы
должны определить соответствующую функцию на C или на C++. В обсуждении ниже
имя ``xxx'' используется для имени функции примера. Здесь XXX()
(верхний регистр) указывает SQL-обращение к функции, и xxx()
(нижний регистр) указывает C/C++-обращение к функции.
Функции, которые Вы пишете на C/C++ для реализации интерфейса с
XXX()
:
xxx()
(обязательна)
SQL-тип | C/C++-тип |
STRING | char * |
INTEGER | long long |
REAL | double |
xxx_init()
(опциональна)
xxx()
. Это может использоваться
для:
XXX()
.
REAL
) максимального количества
десятичных чисел.
NULL
.xxx_deinit()
(опционально)
xxx()
. Это должно освободить
любую память, распределенную функцией инициализации.Когда инструкция SQL вызывает XXX()
, MySQL вызывает функцию
инициализации xxx_init()
, чтобы позволить ей выполнить любую
требуемую настройку, типа проверки параметра или распределения памяти. Если
xxx_init()
возвращает ошибку, инструкция SQL будет прервана с
сообщением об ошибке, причем главная и деинициализационная функции не будут
вызваны, что стоит иметь в виду при распределении памяти. Иначе основная
функция xxx()
будет вызвана один раз для каждой строки. После
того, как все строки были обработаны, вызывается функция
xxx_deinit()
, так что она может выполнить требуемую очистку.
Все функции должны быть безопасны для потоков (не только основная функция,
но и остальные: инициализация и деинициализация идут в поточном режиме!). Это
означает, что Вам не позволят распределить любые глобальные или менять
статические переменные! Если Вы нуждаетесь в памяти, Вы должны распределить
ее в xxx_init()
и непременно освободить в
xxx_deinit()
.
Основная функция должна быть объявлена как показано ниже. Обратите
внимание, что тип возврата и параметры отличаются в зависимости от того,
объявите ли Вы тип возврата функции SQL XXX()
как
STRING
, INTEGER
или REAL
в
вызове CREATE FUNCTION
:
Для функций типа STRING
:
char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);
Для функций типа INTEGER
:
long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
Для функций типа REAL
:
double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
Функции инициализации и деинициализации объявлены подобно этому:
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void xxx_deinit(UDF_INIT *initid);
Параметр initid
передан всем трем функциям. Он указывает на
структуру UDF_INIT
, которая используется, чтобы передать
информацию между функциями. Члены структуры UDF_INIT
перечислены
ниже. Функция инициализации должна заполнить любые члены, которые она желает
изменить. Чтобы использовать значение по умолчанию для члена, оставьте его
неизменным. Перейдем к описанию:
my_bool maybe_null
xxx_init()
должна установить maybe_null
в
1
, если xxx()
может возвращать NULL
.
Значение по умолчанию 1
, если любой из параметров объявлен
как maybe_null
.
unsigned int decimals
1.34
, 1.345
и 1.3
,
значением по умолчанию будет 3, поскольку 1.345
имеет 3 десятичных цифры.
unsigned int max_length
initid->decimals
. Для числовых функций длина включает любой
знак или десятичные символы отметки.
char *ptr
initid->ptr
, чтобы
передать распределенную память между функциями. В xxx_init()
как
обычно распределите память и назначьте ее этому указателю:
initid->ptr=allocated_memory;В
xxx()
и xxx_deinit()
обратитесь к
initid->ptr
, чтобы использовать или освободить память.Параметр args
указывает на структуру UDF_ARGS
,
члены которой приведены ниже:
unsigned int arg_count
if (args->arg_count != 2) { strcpy(message,"XXX() requires two arguments"); return 1; }
enum Item_result *arg_type
STRING_RESULT
, INT_RESULT
и
REAL_RESULT
. Чтобы удостовериться, что параметры имеют данный
тип и возвращают ошибку, если они к нему не принадлежат, проверьте массив
arg_type
в функции инициализации. Например:
if (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT) { strcpy(message,"XXX() requires a string and an integer"); return 1; }Вы можете использовать функцию инициализации, чтобы установить элементы
arg_type
к типам, которые Вы хотите получить. Это заставляет
MySQL привести параметры к тем типам для каждого обращения к
xxx()
. Например, чтобы определить первые два элемента как строку
и число, сделайте следующее в xxx_init()
:
args->arg_type[0] = STRING_RESULT; args->arg_type[1] = INT_RESULT;
char **args
args->args
сообщает информацию функции инициализации
относительно общего характера параметров, с которыми Ваша функция была
вызвана. Для постоянного параметра (константы) i
args->args[i]
указывает на значение параметра. Для
непостоянного параметра args->args[i]
равно 0
.
Постоянный параметр представляет собой выражение, которое использует только
константы, типа 3
, 4*7-2
или
SIN(3.14)
. Непостоянный параметр представляет собой выражение,
которое обращается к значениям, которые могут изменяться, типа имени столбца
или функций, которые вызваны с непостоянными параметрами. Для каждого
обращения основной функции args->args
хранит фактические
параметры, которые переданы для в настоящее время обрабатываемой строки.
Функции могут обратиться к параметру i
следующим образом:
STRING_RESULT
, данный как указатель строки
плюс длина, позволяет обработку двоичных данных или данных произвольной
длины. Содержание строки доступно как args->args[i]
, а длина
строки как args->lengths[i]
. Вы не должны считать, что
строка завершается нулевым символом.
INT_RESULT
Вы должны привести
args->args[i]
к типу long long
:
long long int_val; int_val = *((long long*) args->args[i]);
REAL_RESULT
Вы должны привести
args->args[i]
к типу double
:
double real_val; real_val = *((double*) args->args[i]);
unsigned long *lengths
lengths
указывает
максимальную длину строки для каждого параметра. Для каждого обращения к
основной функции lengths
хранит фактические длины любых
строковых параметров, которые переданы для строки, обрабатываемой в настоящее
время. Для параметров типов INT_RESULT
или
REAL_RESULT
lengths
хранит максимальную длину
параметра (как для функции инициализации).Функция инициализации возвратит 0
, если никакая ошибка не
произошла, и 1
в противном случае. Если ошибка происходит,
xxx_init()
должна сохранить сообщение об ошибке с нулевым
символом в конце в параметре message
. Сообщение будет возвращено
пользователю. Буфер сообщений имеет длину в MYSQL_ERRMSG_SIZE
символов, но Вы должны попробовать сохранить сообщение в 80 символах так,
чтобы это удовлетворило ширине стандартного экрана терминала.
Значение возврата основной функции xxx()
зависит от типа. Для
функций типов long long
и double
оно представляет
собой собственно функциональное значение. Строковые функции должны возвратить
указатель на результат и сохранить длину строки в параметрах
length
. Здесь result
представляет собой буфер
длиной в 255 байт. Установите их к содержанию и длине значения. Например:
memcpy(result, "result string", 13); *length=13;
Если Ваши функции строки должны возвратить строку длиннее, чем 255 байт,
распределите память для результата через malloc()
в функции
xxx_init()
или в xxx()
, а затем освободите память в
xxx_deinit()
. Вы можете сохранять распределенную память в слоте
ptr
структуры UDF_INIT
для повторного использования
в будущем обращении xxx()
. Подробности в разделе
"3.1.2.1 Соглашения о вызове UDF
".
Чтобы указывать значение возврата NULL
в основной функции,
установите is_null
в 1
:
*is_null=1;
Чтобы указать возврат ошибки в основной функции, установите параметр
ошибки (error
) в значение 1
:
*error=1;
Если xxx()
устанавливает *error
в 1
для любой строки, функциональное значение NULL
для текущей
строки и для любых последующих строк, обработанных инструкцией, в которой
вызывалась XXX()
. Причем, xxx()
не будет даже
запрашиваться для последующих строк. ПРИМЕЧАНИЕ: В MySQL до
версии 3.22.10 Вы должны установить
*error
и *is_null
:
*error=1; *is_null=1;
Файлы, выполняющие UDF, должны компилироваться и устанавливаться на сервере. Этот процесс описан ниже для примерного UDF-файла udf_example.cc, который включен в дистрибутив исходников MySQL. Этот файл содержит следующие функции:
metaphon()
возвращает мета-строку для строкового
параметра. Это похоже на soundex, но больше заточено под английский.
myfunc_double()
возвращает сумму ASCII-значений символов в
параметрах, поделенную на сумму длин этих параметров.
myfunc_int()
возвращает сумму длин параметров.
sequence([const int])
возвратит последовательность,
начинающуюся с заданного числа или с 1, если никакого числа задано не было.
lookup()
возвращает IP-адрес.
reverse_lookup()
возвращает hostname для IP-адреса. Функция
может быть вызвана со строкой "xxx.xxx.xxx.xxx"
или с 4 числами.
Динамически загружаемый файл должен компилироваться как разделяемый объектный файл, используя команду:
shell> gcc -shared -o udf_example.so myfunc.cc
Вы можете легко выяснять правильные параметры компилятора для Вашей системы, запуская такую команду в каталоге sql Вашего дерева исходных текстов MySQL:
shell> make udf_example.o
Вы должны выполнить команду компиляции, подобную одной из тех, что
отображает make
, за исключением того, что Вы должны удалить
опцию -c
близко к концу строки и добавить
-o udf_example.so
в самый конец строки. На некоторых системах
удалять -c
не надо, пробуйте.
Как только Вы скомпилируете общедоступный объект, содержащий UDF, Вы
должны установить его и сообщить MySQL о расширении функциональности.
Компиляция общедоступного объекта из udf_example.cc производит файл
с именем udf_example.so (точное имя может изменяться от платформы к
платформе). Скопируйте этот файл в некоторый каталог, где ищет файлы
ld
, например, в /usr/lib. На многих системах Вы можете
устанавливать системную переменную LD_LIBRARY
или
LD_LIBRARY_PATH
, чтобы указать каталог, где Вы имеете Ваши файлы
функции UDF. Руководство на dlopen
сообщает Вам, которую
переменную Вы должны использовать на Вашей системе. Вы должны установить это
в mysql.server
или в safe_mysqld
и перезапустить
mysqld
.
После того, как библиотека установлена, сообщите mysqld
относительно новых функций этими командами:
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so"; mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so"; mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so"; mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";
Функции могут быть удалены, используя DROP FUNCTION
:
mysql> DROP FUNCTION metaphon; mysql> DROP FUNCTION myfunc_double; mysql> DROP FUNCTION myfunc_int; mysql> DROP FUNCTION lookup; mysql> DROP FUNCTION reverse_lookup;
Инструкции CREATE FUNCTION
и DROP FUNCTION
модифицируют системную таблицу func
в базе данных
mysql
. Имя функции, тип и общедоступное библиотечное имя будут
сохранено в таблице. Вы должны иметь привилегии insert и
delete для базы данных mysql
, чтобы создавать и
удалять свои функции.
Вы не должны использовать CREATE FUNCTION
, чтобы добавить
функцию, которая уже была создана. Если Вы должны повторно установить
функцию, сначала удалите ее через вызов DROP FUNCTION
и затем
повторно установите ее с помощью CREATE FUNCTION
. Вы должны
сделать это, например, если Вы откомпилировали новую версию Вашей функции,
чтобы mysqld
обновил используемую им версию. Иначе сервер
продолжит применять старую версию.
Активные функции будут перезагружены при каждом перезапуске сервера, если
Вы не запускаете mysqld
с опцей --skip-grant-tables
.
В этом случае инициализация UDF будет пропущена, а UDF-функции станут
недоступными. Активная функция представляет собой функцию, загруженную через
CREATE FUNCTION
, но не удаленную DROP FUNCTION
.
Процедура для добавления новой встроенной функции описана ниже. Обратите внимание, что Вы не можете добавлять встроенные функции к двоичному дистрибутиву потому, что процедура включает изменение исходного текста MySQL. Вы должны скомпилировать MySQL самостоятельно из исходников. Также обратите внимание, что, если Вы мигрируете на другую версию MySQL (например, когда новая версия выпущена), Вы будете должны повторить процедуру с новой версией.
Чтобы добавить новую встроенную функцию MySQL, нужно:
sql_functions[]
.
sql_functions[]
и добавить
функцию, которая создает функциональный объект, в item_create.cc.
Смотрите "ABS"
и create_funcs_abs()
как пример.
Если функциональный прототип усложнен (например, берет переменное число
параметров), Вы должны добавить две строки к sql_yacc.yy. Каждая
указывает символ препроцессора, который yacc
должен определить
(это должно быть добавлено в начале файла). Затем определите функциональные
параметры и добавьте элемент с этими параметрами для правила синтаксического
анализа simple_expr
. Для примера, проверьте все местонахождения
ATAN
в sql_yacc.yy, чтобы увидеть, как это выполнено.
Item_num_func
или Item_str_func
, в зависимости от
того, возвращает ли Ваша функция число или строку.
double Item_func_newname::val() longlong Item_func_newname::val_int() String *Item_func_newname::Str(String *str)Если Вы наследуете Ваш объект от любого из стандартных элементов (подобно
Item_num_func
, Вы, вероятно, должны только определить одну из
вышеупомянутых функций и позволить родительскому объекту заботиться о других
функциях. Например, класс Item_str_func
определяет функцию
val()
, которая выполняет atof()
на значении,
возвращенном ::str()
.
void Item_func_newname::fix_length_and_dec()Эта функция должна по крайней мере вычислить
max_length
, исходя
из данных параметров. max_length
задает максимальное число
символов, которое функция может возвращать. Эта функция должна также
установить maybe_null=0
, если основная функция не может
возвращать значение NULL
. Функция может проверить, способен ли
любой из параметров возвращать NULL
, проверяя переменную
параметров maybe_null
. Вы можете изучить
Item_func_mod::fix_length_and_dec
в качестве типичного примера
того, как все это сделать.Все функции должны быть поточно-безопасными (другими словами, не используйте любые глобальные или статические переменные в функциях без того, чтобы защитить их через mutex).
Если Вы хотите возвращать NULL
из ::val()
,
::val_int()
или ::str()
Вы должны установить
null_value
в 1 и вернуть из функции 0.
Для объектной функции ::str()
имеются некоторые
дополнительные хитрости, которые надо знать:
String *str
обеспечивает буфер строки, который
может использоваться, чтобы хранить результат. Для получения большего
количества информации относительно типа String
обратитесь к
файлу sql_string.h.
::str()
должна возвратить строку, которая хранит
результат, или (char*) 0
, если результатом является
NULL
.
В MySQL Вы можете определять процедуру на C++, которая может обращаться и
изменять данные в запросе прежде, чем они отправятся к пользователю.
Модификация может быть выполнена на уровне строки или GROUP BY
.
Авторы пакета создали процедуру примера в MySQL Version 3.23, чтобы показать Вам, что там может быть выполнено.
Дополнительно авторы рекомендуют Вам посмотреть файл mylua, который Вы
можете найти в каталоге Contrib. Вы можете использовать язык LUA, чтобы
загрузить процедуру в mysqld
прямо во время выполнения.
analyse([max elements,[max memory]])
Эта процедура определена в sql/sql_analyse.cc. Она исследует результат, полученный из Вашего запроса, и возвращает анализ результатов:
max elements
(по умолчанию 256) задает максимальное
число разных значений, которые analyse
заметит в столбце. Это
используется, чтобы проверить оптимальность применения типа ENUM
.
max memory
(по умолчанию 8192) задает максимум памяти,
которую analyse
должен распределить на столбец при попытке найти
все отличные значения.SELECT ... FROM ... WHERE ... PROCEDURE ANALYSE([max elements,[max memory]])
На сегодняшний день единственной документацией для этого является исходный код пакета.
Вы можете найти всю информацию относительно процедур, исследуя файлы:
Эта глава описывает много вещей, которые Вы должны знать при работе на коде MySQL. Если Вы планируете способствовать MySQL разработке, иметь доступ к коду отлаживаемых версий или хотите только следить за разработкой, следуйте командам в разделе " 2.3.4 Установка из дерева исходников для разработки". Если Вы заинтересованы внутренней организацией MySQL, Вы должны также подписаться на специальный список рассылки internals@lists.mysql.com.
Сервер MySQL создает следующие потоки:
process_alarm()
, чтобы завершить подключения,
которые были неактивны слишком долго.
mysqld
компилируется с -DUSE_ALARM_THREAD
,
специализированный поток, который обрабатывает тревоги, будет создан. Это
используется только на некоторых системах, где имеются проблемы с
sigwait()
, или если есть недостатки в применении кода
thr_alarm()
в прикладной программе без специализированного
потока обработки сигнала.
--flush_time=#
, будет создан еще
один специализированный поток, который сбрасывает таблицы на диск.
INSERT
DELAYED
, получает собственный поток.
--master-host
, будет запущен поток
репликации, чтобы читать и применять модификации с главного сервера.mysqladmin processlist
показывает только подключения, потоки
репликации и INSERT DELAYED
.
До недавнего времени основной набор теста был основан на составляющих
собственность данных заказчика и по этой причине не был публично доступен.
Единственный публично доступная часть процесса тестирования состояла из теста
crash-me
, эталонного теста Perl DBI/DBD, находящегося в каталоге
sql-bench
, и разнообразных тестов, размещенных в каталоге
tests
. Отсутствие стандартизированного публично доступного
набора тестов сделало трудным для пользователей и разработчиков тестирование
кода MySQL. Чтобы исправить эту ситуацию, авторы пакета создали совершенно
новую систему тестов, которая теперь включена в исходные и двоичные
дистрибутивы, начиная с Version 3.23.23.
Текущий набор тестов не проверяет все в MySQL, но должен охватить наиболее очевидные ошибки в обработка кода SQL, OS/library проблемы и тестирование репликации. Конечная цель состоит в том, чтобы иметь тесты, покрывающие 100% кода. Вы можете предоставить тесты, которые исследуют функциональные возможности, критичные для Вашей системы, поскольку это гарантирует, что все будущие выпуски MySQL будут хорошо работать с Вашими прикладными программами.
Система теста состоит из интерпретатора языков тестов
(mysqltest
), скрипта оболочки, чтобы выполнить все тесты
(mysql-test-run
), фактических случаев тестов, написанных на
специальном языке тестов и их ожидаемых результатов. Чтобы выполнить набор
теста на Вашей системе после построения, введите make test
или
mysql-test/mysql-test-run
из корневого каталога исходных
текстов. Если Вы установили двоичный дистрибутив, перейдите в корень
установки (например, /usr/local/mysql
) и скомандуйте
scripts/mysql-test-run
. Все тесты должны выполниться. Если этого
не произошло, пропобуйте выяснить почему и сообщите о проблеме, если это
ошибка в пакете MySQL. Подробности в разделе
"3.3.2.3 Как сообщать о проблемах и ошибках в
наборе тестов MySQL".
Если Вы имеете копию mysqld
на машине, где Вы хотите
выполнить набор тестов, Вы не должны останавливать ее, если она не использует
порты 9306
и 9307
. Если один из этих портов
применяется, Вы должны отредактировать mysql-test-run
и изменить
значения главного или подчиненного порта к тому, которое является доступным.
Вы можете запустить индивидуально каждый тест командой
mysql-test/mysql-test-run test_name
.
Если один тест свалился, проверьте работу mysql-test-run
с
опцией --force
, чтобы проверить, сбоят ли любые другие тесты.
Вы можете использовать язык mysqltest
, чтобы писать Ваши
собственные случаи теста. К сожалению, авторы пакета еще не написали полную
документацию для него. Вы можете, однако, рассматривать текущие случаи теста
и использовать их как пример. Следующие пункты должны помочь Вам:
mysql-test/t/*.test
;
)
инструкции и подобен вводу клиента командной строки mysql
.
Инструкция по умолчанию: запрос, который будет послан серверу MySQL, если он
не распознан как внутренняя команда (например, sleep
).
SELECT
, SHOW
, EXPLAIN
и прочие, нужно
предварить указанием @/path/to/result/file
. Файл должен
содержать ожидаемые результаты. Простой способ генерировать файл результата
состоит в том, чтобы выполнить mysqltest -r <
t/test-case-name.test
из каталога mysql-test
, а затем
отредактировать сгенерированные файлы результата, если необходимо
скорректировать их к ожидаемому выводу. В этом случае будьте очень осторожны
относительно добавления или удаления любых невидимых символов. Если Вы должны
вставить строку, удостоверьтесь, что поля отделяются позициями табуляции, и
имеется табуляция в конце. Вы можете использовать od -c
, чтобы
удостовериться, что Ваш текстовый редактор не добавляет что-нибудь
неожиданное в течение процесса редактирования.
mysql-test/r
и назвать их как
test_name.result
. Если тест производит больше, чем один
результат, Вы должны использовать test_name.a.result
,
test_name.b.result
и так далее.
--error error-number
. Здесь error-number может быть списком
возможных кодов ошибок, отделяемых запятыми (,
).
source include/master-slave.inc;
. Чтобы
переключаться между главной и подчиненной системами, используйте
connection master;
и connection slave;
. Если Вы
должны делать что-то на альтернативном подключении, Вы можете сделать
подключение connection master1;
для главной и
connection slave1;
для подчиненной системы.
let $1=1000; while ($1) { # Выполняем здесь запрос. dec $1; }
sleep
. Она поддерживает доли секунды, так что Вы можете указать
sleep 1.5;
, например, чтобы бездействовать 1.5 секунды.
mysql-test/t/test_name-slave.opt
. Для главной системы поместите
их в файл mysql-test/t/test_name-master.opt
.
Если Ваша версия MySQL не выполняет набор тестов, Вы должны сделать так:
mysqlbug
, чтобы
разработчики могли получить информацию относительно Вашей
системы и версии MySQL.
mysql-test-run
и
содержание всех .reject
файлов в каталоге
mysql-test/r
.
cd mysql-test mysql-test-run --local test-nameЕсли это терпит неудачу, то сконфигурируйте MySQL с опцией
--with-debug
и выполните mysql-test-run
с опцией
--debug
. Если это также терпит неудачу, закачайте файл
трассировки var/tmp/master.trace на
ftp://support.mysql.com/pub/mysql/secret, чтобы авторы могли исследовать это.
Пожалуйста, не забудьте также включить полное описание Вашей системы, версию
mysqld и параметры компиляции.
mysql-test-run
с опцией
--force
, чтобы увидеть, имеется ли любой другой тест, который
тоже терпит неудачу.
Result length mismatch
или
Result content mismatch
, это означает, что вывод теста не
соответствовал точно ожидаемому выводу. Это может быть ошибкой в MySQL, или
дело в том, что Ваша версия mysqld производит малость иные результаты при
некоторых обстоятельствах. Неудачные результаты теста будут помещены в файл с
тем же самым основным именем, что и файл результата, но с расширением
.reject
. Если Ваш случай теста терпит неудачу, Вы должны
сравнить два файла. Если Вы не можете увидеть, чем они отличаются, исследуйте
их с помощью od -c
и проверьте их длины.
mysql-test/var/log
для выяснения того, что не так.
mysql-test-run
с опциями --gdb
и/или
--debug
. Подробности в разделе
"6.1.2 Создание файлов трассировки
".
Если Вы не компилировали MySQL для отладки, вероятно, стоит сделать это.
Только определите параметр --with-debug
для вызова
configure
! Подробности в разделе
"2.3 Установка исходников MySQL".
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |