Внутреннее устройство MySQL
В этом разделе рассматривается многое из того, что необходимо знать при работе над кодом MySQL. Если вы намерены принять участие в разработке MySQL, желаете получить доступ к самому последнему промежуточному коду версий или просто хотите оставаться в курсе процесса разработки, необходимо выполнять инструкции из раздела Установка из экспериментального набора исходных кодов. Тем, кого интересует внутреннее устройство MySQL, следует подписаться на наш список рассылки internals . Активность этого списка сравнительно невысока. За подробностями относительно подписки, пожалуйста, обращайтесь к разделу Списки рассылки MySQL. Все разработчики из MySQL AB участвуют в списке internals , помогая другим людям, работающим над кодом MySQL. Не стесняйтесь использовать этот список как для того, чтобы задавать вопросы по коду, так и для посылки патчей, которые вы бы хотели приобщить к проекту MySQL!
Потоки MySQL
Сервер создает следующие потоки:
Поток TCP/IP-соединений обрабатывает все запросы подключения и создает новые выделенные потоки для проведения аутентификации и обработки SQL запросов для каждого соединения.
В Windows NT есть поток обслуживания именованного канала, который выполняет ту же работу, что и поток TCP/IP-соединений, но только по запросам на соединение именованного канала.
Поток сигналов обрабатывает все сигналы. Обычно этот поток также обрабатывает сигналы таймера и обращается к process_alarm() для принудительного объявления таймаутов на соединениях, которые слишком долго простаивали.
Если mysqld скомпилирован с -DUSE_ALARM_THREAD , то создается выделенный поток, обрабатывающий сигналы таймера. Используется только в некоторых системах, в которых возникают проблемы с sigwait() , или если есть необходимость использовать код thr_alarm() в приложении без выделенного потока обработки сигналов.
Если применяется опция --flush_time=# , то создается выделенный поток для периодического сбрасывания на диск всех таблиц с заданным интервалом.
Каждое соединение имеет свой поток.
Каждая отдельная таблица, на которой используется INSERT DELAYED , получает свой отдельный поток.
Если применяется --master-host , то запускается поток репликации подчиненного сервера для чтения и применения обновлений от головного.
mysqladmin processlist выводит только потоки соединений, INSERT DELAYED и поток репликации.
Пакет тестирования MySQL
До последнего времени наш основной всесторонний пакет для тестирования основывался на конфиденциальных данных заказчиков и по этой причине не был общедоступным. Процесс тестирования был открытым только частично - доступными являлись тест crash-me, содержащийся в каталоге 'sql-bench' код оценки производительности на Perl DBI/DBD, и различные тесты, расположенные в каталоге 'tests'. Из-за отсутствия стандартизованного доступного пакета как нашим пользователям, так и разработчикам было сложно выполнять регрессионные тесты кода MySQL. Чтобы решить эту проблему, мы создали новую систему тестирования, которая включается в поставку исходного кода и в двоичную поставку начиная с версии 3.23.29.
При помощи текущего набора контрольных тестов нельзя выполнить всестороннюю проверку MySQL, однако он позволяет обнаружить большинство очевидных ошибок в коде обработки SQL, проблемы ОС/библиотек, а также достаточно полно протестировать репликацию. Нашей конечной целью является создание тестов, охватывающих 100% кода. Мы приветствуем разработки, дополняющие наш тестовый пакет. Пользователи должны быть заинтересованы в том, чтобы добавить к этому пакету тесты, исследующие критические для их систем функциональные возможности, поскольку это будет гарантировать работу всех будущих версий MySQL с их собственными приложениями.
Выполнение тестового пакета MySQL
Система тестирования включает в себя интерпретатор языка тестирования (mysqltest ), shell-сценарий для выполнения всех тестов (mysql-test-run ), сами контрольные тесты, написанные на специальном языке тестирования, и ожидаемые для них результаты. Чтобы запустить тестовый пакет в системе после сборки, необходимо, находясь в корне каталога исходных текстов, ввести make test или mysql-test/mysql-test-run . Если же у вас установлена бинарная поставка, то следует перейти при помощи cd в корень инсталляции (например /usr/local/mysql ) и выполнить scripts/mysql-test-run . Все тесты должны пройти успешно. В противном случае следует попробовать отыскать причину неудачи и, если это ошибка MySQL, сообщить о ней. Обращайтесь к разделу Отчет об ошибках в тестовом пакете MySQL.
Если на машине, которую необходимо протестировать, работает экземпляр mysqld , то останавливать его не обязательно, лишь бы он не использовал порты 9306 и 9307 . Если один из этих портов занят, то нужно отредактировать mysql-test-run и изменить значения для порта головного и/или вспомогательного серверов на номер доступного порта.
Можно выполнить один отдельный контрольный тест посредством mysql-test/mysql-test-run test_name .
Если один из тестов окончился неуспешно, то чтобы узнать, как обстоит дело с оставшимися тестами, следует проводить тестирование, запуская mysql-test-run с опцией --force .
Расширение тестового пакета MySQL
Для создания собственных контрольных тестов можно использовать язык 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 . Мы, конечно, надеемся, что никому не придется редактировать вывод mysqltest -r , поскольку потребность в этом возникает только в случае обнаружения ошибки.
Чтобы получить соответствие нашей конфигурации, следует разместить файлы результатов в каталоге 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.3; для временной задержки в 1,3 секунды.
Чтобы для определенного контрольного теста запускать подчиненный сервер с дополнительными опциями, нужно поместить эти опции в формате командной строки в mysql-test/t/test_name-slave.opt . Для головного сервера опции помещаются в mysql-test/t/test_name-master.opt .
Если у вас возникнут вопросы по тестовому пакету или если вы хотите добавить контрольный тест, шлите e-mail на internals@lists.mysql.com. Поскольку в списке не допускаются присоединенные файлы, все нужные файлы следует положить на: ftp://support.mysql.com/pub/mysql/Incoming/
Отчет об ошибках в тестовом пакете MySQL
Если используемая версия 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 , чтобы выяснить, есть ли еще тесты, которые система не проходит.
Если вы компилировали MySQL собственноручно, сверьтесь с нашим руководством в той его части, где дается описание компиляции MySQL на используемой платформе или (что более предпочтительно) используйте одну из откомпилированных нами для вас бинарных поставок http://www.mysql.com/downloads/. Все наши стандартные бинарные дистрибутивы должны проходить тестовый пакет!
Если получена ошибка, подобная Result length mismatch или Result content mismatch , то это означает, что нет точного совпадения между выходными данными теста и контрольными выходными данными. Это может говорить об ошибке в MySQL или о том, что при некоторых обстоятельствах используемая версия mysqld выдает слегка отличающиеся результаты. Результаты неудачных тестов помещаются в файл с тем же именем, что и у файла результатов, но с расширением .reject . Если контрольный тест терпит неудачу, то по этим двум файлам следует выполнить diff . Если не удается обнаружить, в чем их отличия, исследуйте оба файла с помощью od -c , а также проверьте их размеры.
Если тест полностью потерпел фиаско, то для выяснения причины неполадок следует обратиться к файлам журналов в каталоге mysql-test/var/log .
Если MySQL был скомпилирован в отладочном режиме, то можно попробовать выполнить отладку, запустив mysql-test-run с опциями --gdb и/или -debug (см. раздел Создание трассировочных файлов). Если MySQL не был скомпилирован для отладки, то это стоит сделать - просто задайте опции --with-debug для configure ! Обращайтесь к разделу Установка исходного дистрибутива MySQL.
1 2 3
8 8 8
| |